import assert from 'node:assert/strict'; import test from 'node:test'; import { isControlCommand, runControlCommand, } from '../src/channels/shared/control-command.mjs'; import { HarnessApprovalQueue } from '../src/channels/shared/harness-approval.mjs'; function fixture({ sessionId = 'session-one', stopped = true, steered = true } = {}) { const calls = []; const state = { sessionFor(key) { calls.push(['sessionFor', key]); return sessionId; }, }; const harness = { workspaceSession(id) { calls.push(['workspaceSession', id]); return { async stopActiveTurn(control, options) { calls.push(['stopActiveTurn', id, control, options]); return stopped; }, async steerActiveTurn(text, control, options) { calls.push(['steerActiveTurn', id, text, control, options]); return steered; }, }; }, }; return { calls, harness, state }; } test('isControlCommand reserves valid and malformed control command forms', () => { for (const value of [ '/stop', ' /STOP ', '/stop now', '/steer', '/StEeR do this', '/steer line one\nline two', ]) { assert.equal(isControlCommand(value), true, value); } for (const value of [null, '', 'stop', '/stopping', '/steering', 'hello /stop']) { assert.equal(isControlCommand(value), false, String(value)); } }); test('/stop is exact, text-only, and never creates a Session', async () => { const { calls, harness, state } = fixture(); assert.match((await runControlCommand('/stop later', harness, state, 'direct:one')).message, /用法/); assert.match((await runControlCommand('/stop', harness, state, 'direct:one', { hasImages: true, })).message, /纯文字/); assert.equal(calls.length, 0); }); test('/stop controls only the bound active turn and marks accepted cancellation', async () => { const active = fixture(); const signal = new AbortController().signal; const owner = {}; const control = { owner, key: 'direct:one' }; const result = await runControlCommand( '/STOP', active.harness, active.state, 'direct:one', { signal, pendingInteraction: true, control }, ); assert.deepEqual(result, { message: '已请求停止当前任务。', stopped: true }); assert.deepEqual(active.calls, [ ['sessionFor', 'direct:one'], ['workspaceSession', 'session-one'], ['stopActiveTurn', 'session-one', control, { signal }], ]); const inactive = fixture({ stopped: false }); const missing = await runControlCommand( '/stop', inactive.harness, inactive.state, 'direct:one', { control }, ); assert.match(missing.message, /没有正在运行/); assert.equal(missing.stopped, undefined); }); test('/stop and /steer return friendly no-session messages without creating one', async () => { const { harness, state, calls } = fixture({ sessionId: null }); assert.match( (await runControlCommand('/stop', harness, state, 'direct:one')).message, /没有正在运行/, ); assert.match( (await runControlCommand('/steer 补充', harness, state, 'direct:one')).message, /没有绑定会话/, ); assert.equal(calls.some(([method]) => method === 'workspaceSession'), false); }); test('/steer requires text, preserves multiple lines, and rejects images', async () => { const { harness, state, calls } = fixture(); assert.match((await runControlCommand('/steer', harness, state, 'direct:one')).message, /用法/); assert.match((await runControlCommand('/steer ', harness, state, 'direct:one')).message, /用法/); assert.match((await runControlCommand('/steer text', harness, state, 'direct:one', { hasImages: true, })).message, /纯文字/); assert.equal(calls.length, 0); const control = { owner: {}, key: 'direct:one' }; const result = await runControlCommand( '/steer first line\nsecond line', harness, state, 'direct:one', { control }, ); assert.match(result.message, /已提交/); assert.deepEqual(calls.find(([method]) => method === 'steerActiveTurn'), [ 'steerActiveTurn', 'session-one', 'first line\nsecond line', control, {}, ]); }); test('/steer never reaches Harness while an interaction is pending', async () => { const { harness, state, calls } = fixture(); const result = await runControlCommand('/steer continue', harness, state, 'direct:one', { pendingInteraction: true, control: { owner: {}, key: 'direct:one' }, }); assert.match(result.message, /等待你的回答或审批/); assert.equal(calls.length, 0); }); test('/steer reports a lost active-turn race instead of starting new work', async () => { const { harness, state, calls } = fixture({ steered: false }); const result = await runControlCommand('/steer continue', harness, state, 'direct:one', { control: { owner: {}, key: 'direct:one' }, }); assert.match(result.message, /没有正在运行/); assert.equal(calls.filter(([method]) => method === 'steerActiveTurn').length, 1); }); test('HarnessApprovalQueue exposes whether a route has a live approval', async () => { const queue = new HarnessApprovalQueue({ logger: { warn() {}, error() {} } }); const replies = []; const interaction = { kind: 'approval', rpcId: 'approval-rpc', sessionId: 'session-one', toolCall: { callId: 'call-one', name: 'bash', arguments: '{}' }, payload: { type: 'approval/requested', sessionId: 'session-one', approvalId: 'approval-one', toolName: 'bash', callId: 'call-one', }, async respond() {}, }; await queue.handleRequested(interaction, { key: 'direct:one', actor: 'user-one', send: async (text) => replies.push(text), }); assert.equal(queue.hasPending('direct:one'), true); assert.equal(queue.hasPending('direct:other'), false); await queue.closeRoute('direct:one'); assert.equal(queue.hasPending('direct:one'), false); });