Repository navigation
Conversation
session/new saves the session right away, and session/close only detached it, so every client that opens a session and never prompts leaves an empty "New session" behind. IDE integrations do this on every startup, and the stubs pile up in the session list. Close now removes a session this process created with session/new when it was never prompted here and the server has no messages for it. Loaded, resumed and forked sessions, and anything with messages, are left alone.
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
Looks good. I ran the reproduction from #55293 from source. On the base, three session/new + session/close runs left 3 empty New session - <ISO> sessions. With this change, a fresh session/list returns none. The new test fails on the base and passes here, the existing ACP session and prompt tests pass, and tsgo -b reports no errors in packages/cli.
Public API: unchanged. session/close still returns {}; the only change is that an unused session created by this process is removed on the server.
The guards look right: only sessions created with session/new in this process are removed; prompt and delete take them out of the set; the server is asked for messages first, so a session used by another client is kept; loaded, resumed and forked sessions are never touched; and if removal fails, the close still succeeds. The limitation you describe (a process killed without session/close) seems reasonable to leave for a follow-up.
Related: #54478
Issue for this PR
Closes #55293
Type of change
What does this PR do?
newSessioninpackages/cli/src/acp/service.tssaves the session right away, andcloseSessiononly stopped and detached it. A client that opens a session and closes it without prompting leaves an emptyNew session - <ISO>behind, and IDE integrations do this on every startup.closeSessionnow removes the session when all of these hold:session/newLoaded, resumed and forked sessions are never removed, and neither is anything with messages. If removing fails, it logs a warning and the close still succeeds.
This covers the bot's reproduction and any client that closes what it opens. It doesn't cover a process that is killed without
session/close. That needs either a sweep beforeopencode acpexits (the handler currently callsprocess.exitwithout closing scopes) or deferring persistence until the first prompt, as the issue suggests. I kept this to the close path. Happy to do either as a follow-up if you want one.How did you verify your code works?
packages/cli/test/acp/session.test.ts: aftersession/close, an unprompted new session is gone, while a prompted one, one with messages from elsewhere and a loaded one are kept. It fails ondev. The existing close/delete test inprompt.test.tsstill passes.opencode acpfrom source, in a container with no network:session/newthensession/closethree times, thensession/listfrom a newopencode acpprocess.dev: 3 sessions (New session - 2026-10-16T13:51:07.727Z, …)bun testinpackages/cli: 323 pass, 8 fail. The same 8 fail on cleandevin my container (the service and acp lifecycle subprocess tests).tsgo -binpackages/cliis clean. Prettier is clean.Checklist
Added by the opencode bot (AI-generated).
Related: #54478