fix(commands): harden registry and UI ordering

This commit is contained in:
Tianyi Cui
2026-07-20 11:24:02 +08:00
parent 38abe7cac6
commit 2dd3b1dfba
67 changed files with 284 additions and 101 deletions

View File

@@ -41,13 +41,15 @@ describe('ACP plugin commands', () => {
await harness.client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} })
const { sessionId } = await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] })
expect(commandUpdates(harness, sessionId).at(-1)?.update).toEqual({
sessionUpdate: 'available_commands_update',
availableCommands: [{
name: 'inspect',
description: 'Inspect the session',
input: { hint: '<target>' },
}],
await vi.waitFor(() => {
expect(commandUpdates(harness!, sessionId).at(-1)?.update).toEqual({
sessionUpdate: 'available_commands_update',
availableCommands: [{
name: 'inspect',
description: 'Inspect the session',
input: { hint: '<target>' },
}],
})
})
const dispose = harness.ctx.commands.register({
@@ -88,6 +90,23 @@ describe('ACP plugin commands', () => {
})
})
it('coalesces registry changes before a new session command snapshot is announced', async () => {
harness = await makeBridgeHarness({ storageDir })
await harness.client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} })
const { sessionId } = await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] })
harness.ctx.commands.register({
name: 'raced', description: 'Registered after the response', handler: () => ({ kind: 'success' }),
})
await vi.waitFor(() => {
expect(commandUpdates(harness!, sessionId)).toHaveLength(1)
expect(commandUpdates(harness!, sessionId)[0]?.update).toMatchObject({
availableCommands: [{ name: 'raced' }],
})
})
})
it('executes a known single-text command directly and never sends it to the model', async () => {
harness = await makeBridgeHarness({ storageDir })
const seen = vi.fn(() => ({ kind: 'success' as const, text: 'DIRECT RESULT' }))

View File

@@ -1,4 +1,4 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mkdtemp, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
@@ -24,6 +24,9 @@ describe('acp bridge — demux & config edges', () => {
harness = await makeBridgeHarness({ storageDir, script: [textResponse('foreign')] })
await harness.client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} })
await harness.client.newSession({ cwd: process.cwd(), mcpServers: [] })
await vi.waitFor(() => {
expect(harness!.updates.some(update => update.sessionUpdate === 'available_commands_update')).toBe(true)
})
const before = harness.updates.length
const { agent: foreign } = await harness.ctx.agents.create({ sessionId: SessionId('foreign-session'), agentOptions: { provider: 'mock', model: 'mock' } })