fix: notify inactive hook completions (#2408)
This commit is contained in:
parent
5ce01c8644
commit
58c1bb6be8
|
|
@ -11,6 +11,15 @@ type MockStoreState = {
|
|||
}
|
||||
}
|
||||
ptyIdsByTabId: Record<string, string[]>
|
||||
terminalLayoutsByTabId: Record<
|
||||
string,
|
||||
{
|
||||
root: { type: 'leaf'; leafId: string }
|
||||
activeLeafId: string
|
||||
expandedLeafId: string | null
|
||||
ptyIdsByLeafId?: Record<string, string>
|
||||
}
|
||||
>
|
||||
}
|
||||
|
||||
let mockStoreState: MockStoreState
|
||||
|
|
@ -49,7 +58,8 @@ describe('agent hook completion notifications', () => {
|
|||
},
|
||||
ptyIdsByTabId: {
|
||||
'tab-1': ['pty-1']
|
||||
}
|
||||
},
|
||||
terminalLayoutsByTabId: {}
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -90,4 +100,36 @@ describe('agent hook completion notifications', () => {
|
|||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('uses tab-level PTY liveness when an inactive pane leaf binding is temporarily missing', async () => {
|
||||
mockStoreState.terminalLayoutsByTabId = {
|
||||
'tab-1': {
|
||||
root: { type: 'leaf', leafId: '11111111-1111-4111-8111-111111111111' },
|
||||
activeLeafId: '11111111-1111-4111-8111-111111111111',
|
||||
expandedLeafId: null,
|
||||
ptyIdsByLeafId: {}
|
||||
}
|
||||
}
|
||||
const { observeAgentHookCompletionForNotification } =
|
||||
await import('./agent-hook-completion-notifications')
|
||||
|
||||
observeAgentHookCompletionForNotification({
|
||||
paneKey,
|
||||
worktreeId: 'wt-1',
|
||||
payload: hookStatus('working')
|
||||
})
|
||||
observeAgentHookCompletionForNotification({
|
||||
paneKey,
|
||||
worktreeId: 'wt-1',
|
||||
payload: hookStatus('done')
|
||||
})
|
||||
|
||||
expect(dispatchTerminalNotification).toHaveBeenCalledWith(
|
||||
'wt-1',
|
||||
expect.objectContaining({
|
||||
source: 'agent-task-complete',
|
||||
paneKey
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { createAgentCompletionCoordinator } from '@/components/terminal-pane/age
|
|||
import type { AgentCompletionCoordinator } from '@/components/terminal-pane/agent-completion-coordinator-types'
|
||||
import type { RuntimeTerminalProcessInspection } from '@/runtime/runtime-terminal-inspection'
|
||||
import { dispatchTerminalNotification } from '@/components/terminal-pane/use-notification-dispatch'
|
||||
import { collectLeafIdsInOrder } from '@/components/terminal-pane/layout-serialization'
|
||||
|
||||
type CoordinatorEntry = {
|
||||
worktreeId: string
|
||||
|
|
@ -49,10 +50,19 @@ function getPtyIdForPaneKey(paneKey: string): string | null {
|
|||
// 'done' hook event fire a spurious notification. Resolve liveness through
|
||||
// the leaf-keyed binding maintained by syncPanePtyLayoutBinding, which
|
||||
// deletes the entry when the leaf closes.
|
||||
const ptyIdsByLeafId = state.terminalLayoutsByTabId?.[parsed.tabId]?.ptyIdsByLeafId
|
||||
const layout = state.terminalLayoutsByTabId?.[parsed.tabId]
|
||||
const ptyIdsByLeafId = layout?.ptyIdsByLeafId
|
||||
if (ptyIdsByLeafId) {
|
||||
const leafPtyId = ptyIdsByLeafId[parsed.leafId]
|
||||
return leafPtyId && tabPtyIds.includes(leafPtyId) ? leafPtyId : null
|
||||
if (leafPtyId && tabPtyIds.includes(leafPtyId)) {
|
||||
return leafPtyId
|
||||
}
|
||||
// Why: switching worktrees can unmount the terminal pane and clear the
|
||||
// leaf binding before the hook completion arrives, while the tab PTY is
|
||||
// still live. Keep closed leaves suppressed by requiring the leaf in layout.
|
||||
return collectLeafIdsInOrder(layout.root).includes(parsed.leafId)
|
||||
? (tabPtyIds[0] ?? null)
|
||||
: null
|
||||
}
|
||||
return tabPtyIds[0] ?? null
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue