Merge remote-tracking branch 'origin/master' into session-query-tool

# Conflicts:
#	docs/architecture.i18n.yaml
This commit is contained in:
Hypatia May
2026-07-24 20:59:18 +08:00
265 changed files with 5709 additions and 1503 deletions

View File

@@ -383,7 +383,7 @@ describe('acp bridge', () => {
},
}],
})
expect(target.events.some(event => event.type === 'context/message')).toBe(false)
expect(target.events.some(event => event.type === 'user/message' && event.data.source.kind !== 'user')).toBe(false)
const request = JSON.stringify(harness.adapter.requests[0]?.messages)
expect(request).toContain('untrusted, read-only snapshot')
expect(request).toContain('source background')

View File

@@ -264,7 +264,7 @@ describe('acp bridge — disposal & HMR safety', () => {
const handle = await harness.ctx.agents.create({
sessionId: SessionId('guard-a'), agentOptions: { provider: 'mock', model: 'mock' },
})
handle.agent.send([{ type: 'text', text: 'go' }])
handle.agent.followup([{ type: 'text', text: 'go' }])
await handle.agent.whenIdle()
expect(harness.ctx.sessions.get(SessionId('guard-a'))).toBeDefined()
@@ -288,7 +288,7 @@ describe('acp bridge — disposal & HMR safety', () => {
// Drive a turn that hangs in the model stream, so the loop is mid-turn when
// disposed — its exit runs a final session/flush we can gate to hold the
// teardown observably in-flight.
handle.agent.send([{ type: 'text', text: 'go' }])
handle.agent.followup([{ type: 'text', text: 'go' }])
await new Promise(r => setTimeout(r, 30))
expect(handle.agent.status).toBe('running')
let releaseFlush!: () => void

View File

@@ -30,7 +30,7 @@ describe('acp bridge — demux & config edges', () => {
const before = harness.updates.length
const { agent: foreign } = await harness.ctx.agents.create({ sessionId: SessionId('foreign-session'), agentOptions: { provider: 'mock', model: 'mock' } })
foreign.send([{ type: 'text', text: 'hi' }])
foreign.followup([{ type: 'text', text: 'hi' }])
await foreign.whenIdle()
await new Promise(r => setTimeout(r, 10))

View File

@@ -285,10 +285,10 @@ describe('acp bridge — turn outcomes', () => {
const sessionId = await newSession(harness)
const agent = harness.ctx.agents.get(SessionId(sessionId))!
// On the queued prompt, synchronously inject a one-shot context turn (idle
// inject writes turn/start{injection} → context/message → turn/end). Fire
// inject writes turn/start{injection} → user/message → turn/end). Fire
// once so it lands between install and the prompt turn.
let injected = false
harness.ctx.on('agent/queued', (subject) => {
harness.ctx.on('agent/inbox/enqueue', (subject) => {
if (subject === agent && !injected) {
injected = true
agent.inject([{ type: 'text', text: 'ctx note' }], { source: { kind: 'plugin', plugin: 'test' } })