Add companion reconnect state recovery and handoff helper

This commit is contained in:
William Valentin
2026-02-26 17:01:16 -08:00
parent e9873ad22b
commit 184dc2c688
8 changed files with 602 additions and 4 deletions
+29
View File
@@ -12,6 +12,7 @@ const {
connect: ReturnType<typeof vi.fn>;
registerNode: ReturnType<typeof vi.fn>;
setNodeStatus: ReturnType<typeof vi.fn>;
sendAgentMessage: ReturnType<typeof vi.fn>;
subscribeAgentStream: ReturnType<typeof vi.fn>;
subscribeAgentTyping: ReturnType<typeof vi.fn>;
subscribeConnectionEvents: ReturnType<typeof vi.fn>;
@@ -58,6 +59,7 @@ vi.mock('../companion/index.js', () => ({
capabilities: { declared: capabilities, enabled: capabilities },
}));
setNodeStatus = vi.fn(async () => ({ updated: true, node: { id: 'n', role: 'companion' } }));
sendAgentMessage = vi.fn(async () => ({ content: 'handoff response' }));
subscribeAgentStream = vi.fn(() => () => undefined);
subscribeAgentTyping = vi.fn(() => () => undefined);
subscribeConnectionEvents = vi.fn((handler: (event: { status: string }) => void) => {
@@ -146,6 +148,33 @@ describe('companion command', () => {
errSpy.mockRestore();
});
it('executes optional message handoff after registration', async () => {
const logSpy = vi.spyOn(console, 'log').mockImplementation(() => undefined);
const errSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
const program = new Command();
const { registerCompanionCommand } = await import('./companion.js');
registerCompanionCommand(program);
await program.parseAsync([
'node',
'test',
'companion',
'--once',
'--handoff',
'status update?',
'--handoff-timeout',
'5000',
]);
expect(mockRuntimeInstances[0]?.sendAgentMessage).toHaveBeenCalledWith({
message: 'status update?',
timeoutMs: 5000,
});
expect(errSpy).not.toHaveBeenCalled();
logSpy.mockRestore();
errSpy.mockRestore();
});
it('sets process exit code when options are invalid', async () => {
const errSpy = vi.spyOn(console, 'error').mockImplementation(() => undefined);
const program = new Command();