fix pre-step lifecycle regressions

This commit is contained in:
_Kerman
2026-07-31 19:40:59 +08:00
parent fcc2b5e282
commit 8e88b17c9f
37 changed files with 331 additions and 265 deletions

View File

@@ -262,11 +262,11 @@ describe('hooks-claude bridge — SessionStart', () => {
const adapter = new MockAdapter([textResponse('ok')])
const ctx = await harness(dir, adapter)
const agent = ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' })
// session-start fires async (detached .then → agent.inject); wait for the
// injected user/message to actually land before sending, rather than a
// fixed sleep that flakes under load.
await waitFor(() => events(agent).some(e => e.type === 'user/message'
&& e.data.content.some(b => b.type === 'text' && b.text.includes('project uses tabs'))))
// session-start fires async (detached .then → agent.inject); injection now
// enters the next-step inbox directly and becomes a user/message only after
// step entry, so synchronize on the pending inbox item before sending.
await waitFor(() => agent.inbox.nextStep.some(message =>
message.content.some(block => block.type === 'text' && block.text.includes('project uses tabs'))))
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } }))
await waitForIdle(ctx, agent)

View File

@@ -207,8 +207,8 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro
const adapter = new MockAdapter([textResponse('ok')])
const ctx = await harness(join(d, 'hooks.json'), adapter)
const agent = ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' })
await waitFor(() => events(agent).some(e => e.type === 'user/message'
&& e.data.content.some(b => b.type === 'text' && b.text.includes('start-ctx'))))
await waitFor(() => agent.inbox.nextStep.some(message =>
message.content.some(block => block.type === 'text' && block.text.includes('start-ctx'))))
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })); await waitForIdle(ctx, agent)
expect(JSON.stringify(adapter.requests[0]!.messages)).toContain('start-ctx')
})
@@ -547,8 +547,8 @@ export function defineCoverageCases(groups: CoverageGroup | readonly CoverageGro
const adapter = new MockAdapter([textResponse('ok')])
const ctx = await harness(join(d, 'hooks.json'), adapter)
const agent = ctx.agentLoop.create(SessionId('a1'), { provider: 'mock', model: 'mock' })
await waitFor(() => events(agent).some(e => e.type === 'user/message'
&& e.data.content.some(b => b.type === 'text' && b.text.includes('session preamble'))))
await waitFor(() => agent.inbox.nextStep.some(message =>
message.content.some(block => block.type === 'text' && block.text.includes('session preamble'))))
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'go' }], source: { kind: 'user' } })); await waitForIdle(ctx, agent)
expect(JSON.stringify(adapter.requests[0]!.messages)).toContain('session preamble')
})