fix(notifications): preserve stamped OSC repaints

This commit is contained in:
Brennan Benson
2026-08-14 17:26:09 -07:00
parent 1056bc4452
commit 0e1bd05b7c
3 changed files with 25 additions and 2 deletions
+22 -1
View File
@@ -8920,11 +8920,19 @@ describe('AgentHookServer ingestRemote', () => {
})
describe('AgentHookServer ingestTerminalStatus', () => {
it('preserves a hook turn stamp across an equivalent OSC repaint', () => {
it('preserves a hook turn stamp when an OSC repaint omits hook-only completion text', () => {
const server = new AgentHookServer()
const listener = vi.fn()
server.setListener(listener)
server.ingestRemote(
{
paneKey: PANE,
payload: { state: 'working', prompt: 'review the PR', agentType: 'claude' }
},
'conn-1'
)
listener.mockClear()
server.ingestRemote(
{
paneKey: PANE,
@@ -8932,6 +8940,7 @@ describe('AgentHookServer ingestTerminalStatus', () => {
state: 'working',
prompt: 'review the PR',
agentType: 'claude',
lastAssistantMessage: 'Review complete.',
turnCompletedAt: 1_700_000_005_000
}
},
@@ -8946,8 +8955,20 @@ describe('AgentHookServer ingestTerminalStatus', () => {
expect(listener).toHaveBeenCalledOnce()
expect(server.getStatusSnapshot()[0]).toMatchObject({
state: 'working',
lastAssistantMessage: 'Review complete.',
turnCompletedAt: 1_700_000_005_000
})
server.ingestTerminalStatus({
paneKey: PANE,
connectionId: 'conn-1',
payload: { state: 'done', prompt: 'review the PR', agentType: 'claude' }
})
expect(listener).toHaveBeenCalledTimes(2)
expect(listener).toHaveBeenLastCalledWith(
expect.objectContaining({ payload: expect.objectContaining({ state: 'done' }) })
)
})
it('accepts an identical-prompt hook boundary after a stamped turn', () => {
+2 -1
View File
@@ -426,7 +426,8 @@ function equivalentParsedAgentStatusPayload(
a.toolName === b.toolName &&
a.toolInput === b.toolInput &&
a.interactivePrompt === b.interactivePrompt &&
a.lastAssistantMessage === b.lastAssistantMessage &&
(a.lastAssistantMessage === b.lastAssistantMessage ||
(preserveActiveTurnStamp && b.lastAssistantMessage === undefined)) &&
a.interrupted === b.interrupted &&
// Why: a session-boundary done must never be deduped against a cached real done —
// the flag has to reach receivers deterministically (STA-3386).
@@ -1373,6 +1373,7 @@ describe('agent completion coordinator', () => {
state: 'working',
prompt: 'review the PR',
agentType: 'claude',
lastAssistantMessage: 'Review complete.',
stateStartedAt: 2_000,
turnCompletedAt: 2_500
})