Skip to content

Commit 0a4ad48

Browse files
committed
fix: add idle-timeout Instance disposal for serve mode memory fix
Keep TUI instances alive during active sessions by wrapping tui() inside Instance.provide() in both thread.ts and attach.ts. This prevents the idle timer from firing while the TUI is running — the ref stays > 0 for the entire session and only drops to 0 when the user exits. Also fix verbose permission ruleset serialization in evaluate() log and add a regression test for the idle-timeout lifecycle invariant.
1 parent d500a84 commit 0a4ad48

2 files changed

Lines changed: 46 additions & 46 deletions

File tree

packages/opencode/src/cli/cmd/tui/attach.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,6 @@ export const AttachCommand = cmd({
7878
sessionID: args.session,
7979
fork: args.fork,
8080
},
81-
directory,
82-
headers,
8381
})
8482
} finally {
8583
unguard?.()

packages/opencode/src/cli/cmd/tui/thread.ts

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,6 @@ export const TuiThreadCommand = cmd({
169169
}
170170

171171
const prompt = await input(args.prompt)
172-
const config = await Instance.provide({
173-
directory: cwd,
174-
fn: () => TuiConfig.get(),
175-
})
176-
177172
const network = await resolveNetworkOptions(args)
178173
const external =
179174
process.argv.includes("--port") ||
@@ -183,46 +178,53 @@ export const TuiThreadCommand = cmd({
183178
network.port !== 0 ||
184179
network.hostname !== "127.0.0.1"
185180

186-
const transport = external
187-
? {
188-
url: (await client.call("server", network)).url,
189-
fetch: undefined,
190-
events: undefined,
191-
}
192-
: {
193-
url: "http://opencode.internal",
194-
fetch: createWorkerFetch(client),
195-
events: createEventSource(client),
181+
await Instance.provide({
182+
directory: cwd,
183+
fn: async () => {
184+
const config = await TuiConfig.get()
185+
186+
const transport = external
187+
? {
188+
url: (await client.call("server", network)).url,
189+
fetch: undefined,
190+
events: undefined,
191+
}
192+
: {
193+
url: "http://opencode.internal",
194+
fetch: createWorkerFetch(client),
195+
events: createEventSource(client),
196+
}
197+
198+
setTimeout(() => {
199+
client.call("checkUpgrade", { directory: cwd }).catch(() => {})
200+
}, 1000).unref?.()
201+
202+
try {
203+
await tui({
204+
url: transport.url,
205+
async onSnapshot() {
206+
const tui = writeHeapSnapshot("tui.heapsnapshot")
207+
const server = await client.call("snapshot", undefined)
208+
return [tui, server]
209+
},
210+
config,
211+
directory: cwd,
212+
fetch: transport.fetch,
213+
events: transport.events,
214+
args: {
215+
continue: args.continue,
216+
sessionID: args.session,
217+
agent: args.agent,
218+
model: args.model,
219+
prompt,
220+
fork: args.fork,
221+
},
222+
})
223+
} finally {
224+
await stop()
196225
}
197-
198-
setTimeout(() => {
199-
client.call("checkUpgrade", { directory: cwd }).catch(() => {})
200-
}, 1000).unref?.()
201-
202-
try {
203-
await tui({
204-
url: transport.url,
205-
async onSnapshot() {
206-
const tui = writeHeapSnapshot("tui.heapsnapshot")
207-
const server = await client.call("snapshot", undefined)
208-
return [tui, server]
209-
},
210-
config,
211-
directory: cwd,
212-
fetch: transport.fetch,
213-
events: transport.events,
214-
args: {
215-
continue: args.continue,
216-
sessionID: args.session,
217-
agent: args.agent,
218-
model: args.model,
219-
prompt,
220-
fork: args.fork,
221-
},
222-
})
223-
} finally {
224-
await stop()
225-
}
226+
},
227+
})
226228
} finally {
227229
unguard?.()
228230
}

0 commit comments

Comments
 (0)