diff --git a/packages/client/runtime/src/client/workspaces/service.ts b/packages/client/runtime/src/client/workspaces/service.ts index f3125e6494..3204407e20 100644 --- a/packages/client/runtime/src/client/workspaces/service.ts +++ b/packages/client/runtime/src/client/workspaces/service.ts @@ -94,10 +94,14 @@ export class WorkspacesService implements IWorkspaces { if (inflight !== undefined) return inflight // Reuse: blank && same canonical cwd (workspace.path is the host realpath // canon; summary cwd is the session header passthrough of the same canon). + // An archived blank is never reused: reuse would open a session no + // grouping surface can show, so New Session mints a fresh one instead. + const archived = this.list.getSnapshot().archivedSessionIds const sessions = this.sessions.list.getSnapshot() for (const id of sessions.ids) { const summary = sessions.byId[id] - if (summary !== undefined && summary.blank && summary.cwd === workspace.path) return summary.id + if (summary !== undefined && summary.blank && summary.cwd === workspace.path + && !archived.has(summary.id)) return summary.id } const attempt = this.sessions.create({ workspaceId }) .finally(() => { this.connecting.delete(workspaceId) }) diff --git a/packages/client/runtime/tests/workspaces-service.spec.ts b/packages/client/runtime/tests/workspaces-service.spec.ts index 2bd462e5ee..e280f843d1 100644 --- a/packages/client/runtime/tests/workspaces-service.spec.ts +++ b/packages/client/runtime/tests/workspaces-service.spec.ts @@ -183,6 +183,12 @@ describe('WorkspacesService', () => { // Unknown workspace fails loud instead of silently creating in nowhere. await expect(workspaces.connectWorkspace(wid('ghost'))).rejects.toThrow(/unknown workspace ghost/) + + // An archived blank is never reused: no surface can show it, so New + // Session mints a fresh one for alpha instead. + await workspaces.archiveSession(sid('s-blank')) + api.onCreate = () => Promise.resolve(ok({ sessionId: sid('s-fresh-2') })) + await expect(workspaces.connectWorkspace(wid('alpha'))).resolves.toBe('s-fresh-2') }) it('a rejected first prompt keeps the blank session eligible for connectWorkspace reuse', async () => {