(opts: {
metadata?: Record<string, unknown>;
updateAgentState?: ReturnType<typeof vi.fn>;
registerHandler?: ReturnType<typeof vi.fn>;
} = {})
| 110 | } |
| 111 | |
| 112 | async function startRemoteRunClaudeHarness(opts: { |
| 113 | metadata?: Record<string, unknown>; |
| 114 | updateAgentState?: ReturnType<typeof vi.fn>; |
| 115 | registerHandler?: ReturnType<typeof vi.fn>; |
| 116 | } = {}) { |
| 117 | let metadata = opts.metadata ?? { |
| 118 | claudeSessionId: 'claude-session-1', |
| 119 | slashCommands: ['goal'], |
| 120 | }; |
| 121 | const updateAgentState = opts.updateAgentState ?? vi.fn(); |
| 122 | const registerHandler = opts.registerHandler ?? vi.fn(); |
| 123 | const sessionClient = { |
| 124 | sessionId: 'happy-session-1', |
| 125 | suppressNextArchiveSignal: vi.fn(), |
| 126 | skipExistingMessages: vi.fn(), |
| 127 | updateMetadata: vi.fn((updater: (current: Record<string, unknown>) => Record<string, unknown>) => { |
| 128 | metadata = updater(metadata); |
| 129 | }), |
| 130 | sendClaudeSessionMessage: vi.fn(), |
| 131 | onUserMessage: vi.fn(), |
| 132 | onFileEvent: vi.fn(), |
| 133 | on: vi.fn(), |
| 134 | trackAttachmentDownload: vi.fn(), |
| 135 | drainAttachmentsForUserMessage: vi.fn(async () => []), |
| 136 | downloadAndDecryptAttachment: vi.fn(), |
| 137 | getMetadata: vi.fn(() => metadata), |
| 138 | sendSessionEvent: vi.fn(), |
| 139 | updateAgentState, |
| 140 | rpcHandlerManager: { |
| 141 | registerHandler, |
| 142 | }, |
| 143 | sendSessionDeath: vi.fn(), |
| 144 | flush: vi.fn(async () => {}), |
| 145 | close: vi.fn(async () => {}), |
| 146 | }; |
| 147 | const api = { |
| 148 | getOrCreateMachine: vi.fn(async () => ({})), |
| 149 | getOrCreateSession: vi.fn(async () => ({ |
| 150 | id: 'happy-session-1', |
| 151 | seq: 0, |
| 152 | metadata: {}, |
| 153 | metadataVersion: 0, |
| 154 | agentState: {}, |
| 155 | agentStateVersion: 0, |
| 156 | encryptionKey: new Uint8Array(32), |
| 157 | encryptionVariant: 'legacy' as const, |
| 158 | })), |
| 159 | sessionSyncClient: vi.fn(() => sessionClient), |
| 160 | deactivateSession: vi.fn(async () => {}), |
| 161 | }; |
| 162 | mockApiClientCreate.mockResolvedValue(api); |
| 163 | |
| 164 | const loopDeferred = createDeferred<number>(); |
| 165 | mockLoop.mockReturnValue(loopDeferred.promise); |
| 166 | |
| 167 | const runPromise = runClaude({ |
| 168 | token: 'token', |
| 169 | encryption: { type: 'legacy', secret: new Uint8Array(32) }, |
no test coverage detected