fix(web): invalidate catalog availability when the owning parent is removed
A removed session can no longer be the delivery owner of its continuable children, but the `host/session-removed` handler only reconciled the removed row's own activity. `parentAvailable` was updated exclusively from `refreshSubagents` success, and removal schedules no catalog refresh — so after the parent's Activation detaches, an addressed child kept a writable editor against a dead continuation owner until an unrelated refresh (or forever, for a closed menu). Flip `parentAvailable` to false on the owned catalog and push `handleSubagentParentAvailable(false)` to every addressed child Session at removal time, matching the refresh path's notification. New Session instances already read `parentAvailable` from the catalog, so they inherit the invalidated state. Adds a regression test: removing the catalog's owning parent flips the snapshot's `parentAvailable` and notifies the addressed child instance.
This commit is contained in:
@@ -587,6 +587,30 @@ describe('subagent catalogs', () => {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('invalidates catalog availability when the owning parent is removed', async () => {
|
||||
const api = new FakeApiClient()
|
||||
const root = 'fk-root' as SessionId
|
||||
api.onSubagentList = () => Promise.resolve(ok({
|
||||
entries: [{
|
||||
kind: 'child', id: S2, mode: 'continuable', label: 'worker',
|
||||
activity: 'inactive', hasChildren: false,
|
||||
}] as never[],
|
||||
parentAvailable: true,
|
||||
}))
|
||||
const manager = new SessionManager(api)
|
||||
await manager.refreshSubagents(root)
|
||||
manager.selectSubagent({ parentSessionId: root, childSessionId: S2, mode: 'continuable' })
|
||||
expect(manager.get(S2).getSnapshot().subagent).toMatchObject({ parentAvailable: true })
|
||||
|
||||
manager.handleHostEnvelope({
|
||||
rpcId: 'parent-removed' as never,
|
||||
payload: { type: 'host/session-removed', sessionId: root },
|
||||
})
|
||||
|
||||
expect(manager.getListSnapshot().subagentsByParent[root]?.parentAvailable).toBe(false)
|
||||
expect(manager.get(S2).getSnapshot().subagent).toMatchObject({ parentAvailable: false })
|
||||
})
|
||||
})
|
||||
|
||||
describe('remaining branches', () => {
|
||||
|
||||
Reference in New Issue
Block a user