feat(client-runtime): project the archive set and the archiveSession action
WorkspaceListState gains archivedSessionIds (ReadonlySet, replaced only on membership change), installed as full snapshots from the list baseline, the unary echo, and the changed frame. Archiving the current session clears the selection into the New Session view state. Test doubles (test-runtime, fake APIs, fixture client) follow the widened IWorkspaces/IApiClient faces.
This commit is contained in:
@@ -969,6 +969,9 @@ export function createFixtureApi(options: FixtureOptions = {}): ApiProxy {
|
||||
updatedAt: fixtureEpoch,
|
||||
}]
|
||||
let nextWorkspace = 1
|
||||
// Registry-global archive set mirroring the host: archived sessions keep
|
||||
// their workspace accounting slot and only grouping surfaces hide them.
|
||||
const archivedSessionIds: SessionId[] = []
|
||||
|
||||
// In-memory browse tree behind the fixture's `browse` picker capability —
|
||||
// deterministic content mirroring the design mock so assembled Web tests
|
||||
@@ -1623,7 +1626,10 @@ export function createFixtureApi(options: FixtureOptions = {}): ApiProxy {
|
||||
openPath: request => ok(request, { opened: true as const }),
|
||||
},
|
||||
workspace: {
|
||||
list: request => ok(request, { items: workspaces.map(w => ({ ...w })) }),
|
||||
list: request => ok(request, {
|
||||
items: workspaces.map(w => ({ ...w })),
|
||||
archivedSessionIds: [...archivedSessionIds],
|
||||
}),
|
||||
create: (request) => {
|
||||
const { path, name } = request.payload
|
||||
const target = path ?? `/tmp/fixture-workspaces/${name ?? ''}`
|
||||
@@ -1709,6 +1715,16 @@ export function createFixtureApi(options: FixtureOptions = {}): ApiProxy {
|
||||
}
|
||||
return ok(request, { workspace: { ...workspace } })
|
||||
},
|
||||
archiveSession: (request) => {
|
||||
const missing = requireSession(request)
|
||||
if (missing !== undefined) return missing
|
||||
const { sessionId } = request.payload
|
||||
if (!archivedSessionIds.includes(sessionId)) {
|
||||
archivedSessionIds.push(sessionId)
|
||||
emitHost({ type: 'host/archived-sessions-changed', archivedSessionIds: [...archivedSessionIds] })
|
||||
}
|
||||
return ok(request, { archivedSessionIds: [...archivedSessionIds] })
|
||||
},
|
||||
},
|
||||
commands: {
|
||||
// The catalog mirrors one session's effective view (every fixture
|
||||
@@ -2089,6 +2105,7 @@ export class FixtureApiClient extends AbstractApiClient {
|
||||
case 'workspace.rename': return this.api.workspace.rename(request)
|
||||
case 'workspace.delete': return this.api.workspace.delete(request)
|
||||
case 'workspace.insertSessionBefore': return this.api.workspace.insertSessionBefore(request)
|
||||
case 'workspace.archiveSession': return this.api.workspace.archiveSession(request)
|
||||
case 'command.list': return this.api.commands.list(request)
|
||||
case 'command.execute': return this.api.commands.execute(request, signal)
|
||||
case 'skill.list': return this.api.skills.list(request)
|
||||
|
||||
@@ -122,7 +122,7 @@ export class FakeApiClient implements IApiClient {
|
||||
}
|
||||
|
||||
readonly workspace: IApiClient['workspace'] = {
|
||||
list: (payload: unknown) => this.record('workspace.list', payload, Promise.resolve(ok({ items: [] }))),
|
||||
list: (payload: unknown) => this.record('workspace.list', payload, Promise.resolve(ok({ items: [], archivedSessionIds: [] }))),
|
||||
create: (payload: unknown) => this.record('workspace.create', payload, Promise.resolve(ok({
|
||||
workspace: { workspaceId: 'fk-ws' as never, path: '/f/ws', title: 'ws', sessionIds: [], createdAt: '0', updatedAt: '0' },
|
||||
created: true,
|
||||
@@ -134,6 +134,9 @@ export class FakeApiClient implements IApiClient {
|
||||
insertSessionBefore: (payload: unknown) => this.record('workspace.insertSessionBefore', payload, Promise.resolve(ok({
|
||||
workspace: { workspaceId: 'fk-ws' as never, path: '/f/ws', title: 'ws', sessionIds: [], createdAt: '0', updatedAt: '0' },
|
||||
}))),
|
||||
archiveSession: (payload: unknown) => this.record('workspace.archiveSession', payload, Promise.resolve(ok({
|
||||
archivedSessionIds: [(payload as { sessionId: SessionId }).sessionId],
|
||||
}))),
|
||||
}
|
||||
|
||||
// Payloads stay `unknown` (lint-lane note above); response rows are the real
|
||||
|
||||
Reference in New Issue
Block a user