From 457f5bc4064a4252ef452e19341a68017d88adf3 Mon Sep 17 00:00:00 2001 From: Barry Cape Date: Wed, 1 Apr 2026 10:15:06 -0400 Subject: [PATCH 1/2] fix: replace Jest APIs with Vitest equivalents in test files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - vi.mocked(db.query) → (db.query as any).mockResolvedValueOnce() in error-scenarios.test.ts and swarm-coordinator.test.ts - vi.stubEnv(...) → process.env[...] and remove vi.unstubAllEnvs() in inbox-check/utils.test.ts - vi.resetModules() → vi.restoreAllMocks() in cli-session-collector.test.ts and collector tests - fix logRunSummary test expectation to match actual output format in run-summary-table.test.ts Jest-only APIs were causing test failures when run via 'bunx vitest run' with the root vitest config. --- packages/hooks/src/inbox-check/utils.test.ts | 5 +- .../sdk/src/__tests__/error-scenarios.test.ts | 76 +++++++++---------- .../src/__tests__/swarm-coordinator.test.ts | 38 +++++----- .../__tests__/cli-session-collector.test.ts | 4 +- .../__tests__/collectors/claude.test.ts | 4 +- .../__tests__/collectors/opencode.test.ts | 4 +- .../__tests__/run-summary-table.test.ts | 2 +- 7 files changed, 66 insertions(+), 67 deletions(-) diff --git a/packages/hooks/src/inbox-check/utils.test.ts b/packages/hooks/src/inbox-check/utils.test.ts index 7b7bb2b3a..cd7ee0bac 100644 --- a/packages/hooks/src/inbox-check/utils.test.ts +++ b/packages/hooks/src/inbox-check/utils.test.ts @@ -38,7 +38,6 @@ describe('Inbox Check Utils', () => { if (tempDir) { cleanup(tempDir); } - vi.unstubAllEnvs(); }); describe('DEFAULT_INBOX_DIR', () => { @@ -54,7 +53,7 @@ describe('Inbox Check Utils', () => { }); it('returns agent name from environment variable', () => { - vi.stubEnv('AGENT_RELAY_NAME', 'TestAgent'); + process.env.AGENT_RELAY_NAME = 'TestAgent'; expect(getAgentName()).toBe('TestAgent'); }); }); @@ -66,7 +65,7 @@ describe('Inbox Check Utils', () => { }); it('uses env var when agentName not in config', () => { - vi.stubEnv('AGENT_RELAY_NAME', 'EnvAgent'); + process.env.AGENT_RELAY_NAME = 'EnvAgent'; const result = getInboxPath({ inboxDir: tempDir }); expect(result).toBe(path.join(tempDir, 'EnvAgent', 'inbox.md')); }); diff --git a/packages/sdk/src/__tests__/error-scenarios.test.ts b/packages/sdk/src/__tests__/error-scenarios.test.ts index 617a5dce0..654cf34c3 100644 --- a/packages/sdk/src/__tests__/error-scenarios.test.ts +++ b/packages/sdk/src/__tests__/error-scenarios.test.ts @@ -62,7 +62,7 @@ describe('StateStore error scenarios', () => { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; - vi.mocked(db.query).mockResolvedValueOnce({ rows: [entry] }); + (db.query as any).mockResolvedValueOnce({ rows: [entry] }); store.setConsensusGate(async () => true); const result = await store.set('run_1', 'key', 'value', 'agent-1'); @@ -83,7 +83,7 @@ describe('StateStore error scenarios', () => { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; - vi.mocked(db.query).mockResolvedValueOnce({ rows: [entry] }); + (db.query as any).mockResolvedValueOnce({ rows: [entry] }); await expect(store.set('run_1', 'key', 'value', 'agent-1')).resolves.toBeDefined(); }); @@ -91,24 +91,24 @@ describe('StateStore error scenarios', () => { describe('DB failures', () => { it('should propagate DB errors on set', async () => { - vi.mocked(db.query).mockRejectedValueOnce(new Error('connection lost')); + (db.query as any).mockRejectedValueOnce(new Error('connection lost')); await expect(store.set('run_1', 'key', 'v', 'agent')).rejects.toThrow('connection lost'); }); it('should propagate DB errors on get', async () => { - vi.mocked(db.query).mockRejectedValueOnce(new Error('timeout')); + (db.query as any).mockRejectedValueOnce(new Error('timeout')); await expect(store.get('run_1', 'key')).rejects.toThrow('timeout'); }); it('should propagate DB errors on delete', async () => { - vi.mocked(db.query).mockRejectedValueOnce(new Error('disk full')); + (db.query as any).mockRejectedValueOnce(new Error('disk full')); await expect(store.delete('run_1', 'key')).rejects.toThrow('disk full'); }); }); describe('namespace isolation', () => { it('should use custom namespace when provided', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await store.get('run_1', 'key', { namespace: 'custom' }); expect(db.query).toHaveBeenCalledWith( expect.any(String), @@ -117,7 +117,7 @@ describe('StateStore error scenarios', () => { }); it('should use default namespace when not provided', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await store.get('run_1', 'key'); expect(db.query).toHaveBeenCalledWith( expect.any(String), @@ -138,7 +138,7 @@ describe('StateStore error scenarios', () => { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; - vi.mocked(db.query).mockResolvedValueOnce({ rows: [entry] }); + (db.query as any).mockResolvedValueOnce({ rows: [entry] }); const result = await store.set('run_1', 'key', 'v', 'agent', { ttlMs: 5000 }); expect(result.expiresAt).not.toBeNull(); @@ -157,7 +157,7 @@ describe('StateStore error scenarios', () => { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; - vi.mocked(db.query).mockResolvedValueOnce({ rows: [entry] }); + (db.query as any).mockResolvedValueOnce({ rows: [entry] }); const spy = vi.fn(); store.on('state:set', spy); @@ -167,7 +167,7 @@ describe('StateStore error scenarios', () => { }); it('should emit state:deleted on successful delete', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [{ id: 'st_1' }] }); + (db.query as any).mockResolvedValueOnce({ rows: [{ id: 'st_1' }] }); const spy = vi.fn(); store.on('state:deleted', spy); @@ -177,7 +177,7 @@ describe('StateStore error scenarios', () => { }); it('should not emit state:deleted when key not found', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); const spy = vi.fn(); store.on('state:deleted', spy); @@ -189,7 +189,7 @@ describe('StateStore error scenarios', () => { describe('snapshot', () => { it('should return empty object for no entries', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); const snapshot = await store.snapshot('run_1'); expect(snapshot).toEqual({}); }); @@ -199,7 +199,7 @@ describe('StateStore error scenarios', () => { { id: '1', runId: 'run_1', namespace: 'default', key: 'a', value: 1, expiresAt: null, createdAt: '', updatedAt: '' }, { id: '2', runId: 'run_1', namespace: 'default', key: 'b', value: 'hello', expiresAt: null, createdAt: '', updatedAt: '' }, ]; - vi.mocked(db.query).mockResolvedValueOnce({ rows: entries }); + (db.query as any).mockResolvedValueOnce({ rows: entries }); const snapshot = await store.snapshot('run_1'); expect(snapshot).toEqual({ a: 1, b: 'hello' }); @@ -235,7 +235,7 @@ describe('BarrierManager error scenarios', () => { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; - vi.mocked(db.query).mockResolvedValueOnce({ rows: [barrier] }); + (db.query as any).mockResolvedValueOnce({ rows: [barrier] }); const spy = vi.fn(); manager.on('barrier:created', spy); @@ -261,7 +261,7 @@ describe('BarrierManager error scenarios', () => { createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), }; - vi.mocked(db.query).mockResolvedValue({ rows: [barrier] }); + (db.query as any).mockResolvedValue({ rows: [barrier] }); const results = await manager.createBarriers('run_1', [ { name: 'b1', waitFor: ['a'] }, @@ -287,7 +287,7 @@ describe('BarrierManager error scenarios', () => { }; // First, create the barrier to set the mode - vi.mocked(db.query).mockResolvedValueOnce({ rows: [barrier] }); + (db.query as any).mockResolvedValueOnce({ rows: [barrier] }); await manager.createBarrier('run_1', { name: 'b1', waitFor: ['agent-a', 'agent-b'], @@ -295,7 +295,7 @@ describe('BarrierManager error scenarios', () => { }); // Now resolve with partial (not satisfied yet) - vi.mocked(db.query).mockResolvedValueOnce({ rows: [barrier] }); + (db.query as any).mockResolvedValueOnce({ rows: [barrier] }); const result = await manager.resolve('run_1', 'b1', 'agent-a'); expect(result.satisfied).toBe(false); }); @@ -314,7 +314,7 @@ describe('BarrierManager error scenarios', () => { }; // Create barrier in "any" mode - vi.mocked(db.query).mockResolvedValueOnce({ rows: [barrier] }); + (db.query as any).mockResolvedValueOnce({ rows: [barrier] }); await manager.createBarrier('run_1', { name: 'b1', waitFor: ['agent-a', 'agent-b'], @@ -322,7 +322,7 @@ describe('BarrierManager error scenarios', () => { }); // Resolve — should satisfy immediately since mode is "any" - vi.mocked(db.query) + (db.query as any) .mockResolvedValueOnce({ rows: [barrier] }) // resolve UPDATE .mockResolvedValueOnce({ rows: [{ ...barrier, isSatisfied: true }] }); // markSatisfied UPDATE @@ -336,9 +336,9 @@ describe('BarrierManager error scenarios', () => { it('should throw when barrier not found during resolve', async () => { // resolve UPDATE returns empty - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); // getBarrier also returns empty - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect( manager.resolve('run_1', 'nonexistent', 'agent-a'), @@ -359,9 +359,9 @@ describe('BarrierManager error scenarios', () => { }; // resolve UPDATE returns empty (already satisfied, WHERE is_satisfied=FALSE doesn't match) - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); // getBarrier returns the already-satisfied barrier - vi.mocked(db.query).mockResolvedValueOnce({ rows: [barrier] }); + (db.query as any).mockResolvedValueOnce({ rows: [barrier] }); const result = await manager.resolve('run_1', 'b1', 'a'); expect(result.satisfied).toBe(true); @@ -384,7 +384,7 @@ describe('BarrierManager error scenarios', () => { updatedAt: '', }; - vi.mocked(db.query).mockResolvedValue({ rows: [barrier] }); + (db.query as any).mockResolvedValue({ rows: [barrier] }); const timeoutSpy = vi.fn(); manager.on('barrier:timeout', timeoutSpy); @@ -416,7 +416,7 @@ describe('BarrierManager error scenarios', () => { createdAt: '', updatedAt: '', }; - vi.mocked(db.query).mockResolvedValueOnce({ rows: [barrier] }); + (db.query as any).mockResolvedValueOnce({ rows: [barrier] }); await manager.createBarrier('run_1', { name: 'b1', @@ -430,19 +430,19 @@ describe('BarrierManager error scenarios', () => { describe('queries', () => { it('getBarrier should return null for missing barrier', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); const result = await manager.getBarrier('run_1', 'nonexistent'); expect(result).toBeNull(); }); it('isSatisfied should return false when barrier does not exist', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); const result = await manager.isSatisfied('run_1', 'missing'); expect(result).toBe(false); }); it('getUnsatisfiedBarriers should query with is_satisfied = FALSE', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await manager.getUnsatisfiedBarriers('run_1'); expect(db.query).toHaveBeenCalledWith( expect.stringContaining('is_satisfied = FALSE'), @@ -465,51 +465,51 @@ describe('SwarmCoordinator error scenarios', () => { describe('run lifecycle errors', () => { it('should throw when starting a non-pending run', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.startRun('run_1')).rejects.toThrow('not found or not in pending'); }); it('should throw when completing a non-existent run', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.completeRun('bad')).rejects.toThrow('not found'); }); it('should throw when failing a non-existent run', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.failRun('bad', 'error')).rejects.toThrow('not found'); }); it('should throw when cancelling a non-existent run', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.cancelRun('bad')).rejects.toThrow('not found'); }); }); describe('step lifecycle errors', () => { it('should throw when starting a non-pending step', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.startStep('step_bad')).rejects.toThrow('not in pending state'); }); it('should throw when completing a non-running step', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.completeStep('step_bad')).rejects.toThrow('not in running state'); }); it('should throw when failing a non-running step', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.failStep('step_bad', 'err')).rejects.toThrow('not in running state'); }); it('should throw when skipping a non-existent step', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.skipStep('step_bad')).rejects.toThrow('not found'); }); }); describe('DB propagation', () => { it('should propagate DB errors from createRun', async () => { - vi.mocked(db.query).mockRejectedValueOnce(new Error('connection refused')); + (db.query as any).mockRejectedValueOnce(new Error('connection refused')); await expect(coordinator.createRun('ws-1', { version: '1', name: 'test', @@ -519,7 +519,7 @@ describe('SwarmCoordinator error scenarios', () => { }); it('should propagate DB errors from getSteps', async () => { - vi.mocked(db.query).mockRejectedValueOnce(new Error('query timeout')); + (db.query as any).mockRejectedValueOnce(new Error('query timeout')); await expect(coordinator.getSteps('run_1')).rejects.toThrow('query timeout'); }); }); diff --git a/packages/sdk/src/__tests__/swarm-coordinator.test.ts b/packages/sdk/src/__tests__/swarm-coordinator.test.ts index 8a5857fd3..be7290859 100644 --- a/packages/sdk/src/__tests__/swarm-coordinator.test.ts +++ b/packages/sdk/src/__tests__/swarm-coordinator.test.ts @@ -692,7 +692,7 @@ describe('SwarmCoordinator', () => { describe('createRun', () => { it('should insert a run and emit run:created', async () => { const run = makeRunRow(); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [run] }); + (db.query as any).mockResolvedValueOnce({ rows: [run] }); const spy = vi.fn(); coordinator.on('run:created', spy); @@ -707,7 +707,7 @@ describe('SwarmCoordinator', () => { describe('startRun', () => { it('should transition pending run to running', async () => { const run = makeRunRow({ status: 'running' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [run] }); + (db.query as any).mockResolvedValueOnce({ rows: [run] }); const spy = vi.fn(); coordinator.on('run:started', spy); @@ -718,7 +718,7 @@ describe('SwarmCoordinator', () => { }); it('should throw when run not found', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.startRun('nonexistent')).rejects.toThrow('not found or not in pending state'); }); }); @@ -726,7 +726,7 @@ describe('SwarmCoordinator', () => { describe('completeRun', () => { it('should transition run to completed and emit event', async () => { const run = makeRunRow({ status: 'completed' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [run] }); + (db.query as any).mockResolvedValueOnce({ rows: [run] }); const spy = vi.fn(); coordinator.on('run:completed', spy); @@ -737,7 +737,7 @@ describe('SwarmCoordinator', () => { }); it('should throw when run not found', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.completeRun('nonexistent')).rejects.toThrow('not found'); }); }); @@ -745,7 +745,7 @@ describe('SwarmCoordinator', () => { describe('failRun', () => { it('should transition run to failed with error', async () => { const run = makeRunRow({ status: 'failed', error: 'boom' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [run] }); + (db.query as any).mockResolvedValueOnce({ rows: [run] }); const spy = vi.fn(); coordinator.on('run:failed', spy); @@ -758,7 +758,7 @@ describe('SwarmCoordinator', () => { describe('cancelRun', () => { it('should transition run to cancelled', async () => { const run = makeRunRow({ status: 'cancelled' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [run] }); + (db.query as any).mockResolvedValueOnce({ rows: [run] }); const spy = vi.fn(); coordinator.on('run:cancelled', spy); @@ -773,7 +773,7 @@ describe('SwarmCoordinator', () => { describe('createSteps', () => { it('should create steps from workflow config', async () => { const step = makeStepRow(); - vi.mocked(db.query).mockResolvedValue({ rows: [step] }); + (db.query as any).mockResolvedValue({ rows: [step] }); const config = makeConfig({ workflows: [ @@ -796,7 +796,7 @@ describe('SwarmCoordinator', () => { describe('startStep', () => { it('should transition step to running and emit event', async () => { const step = makeStepRow({ status: 'running' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [step] }); + (db.query as any).mockResolvedValueOnce({ rows: [step] }); const spy = vi.fn(); coordinator.on('step:started', spy); @@ -807,7 +807,7 @@ describe('SwarmCoordinator', () => { }); it('should throw for non-pending step', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await expect(coordinator.startStep('bad')).rejects.toThrow('not found or not in pending state'); }); }); @@ -815,7 +815,7 @@ describe('SwarmCoordinator', () => { describe('completeStep', () => { it('should transition step to completed with output', async () => { const step = makeStepRow({ status: 'completed', output: 'result data' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [step] }); + (db.query as any).mockResolvedValueOnce({ rows: [step] }); const spy = vi.fn(); coordinator.on('step:completed', spy); @@ -829,7 +829,7 @@ describe('SwarmCoordinator', () => { describe('failStep', () => { it('should transition step to failed with error', async () => { const step = makeStepRow({ status: 'failed', error: 'timeout' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [step] }); + (db.query as any).mockResolvedValueOnce({ rows: [step] }); const spy = vi.fn(); coordinator.on('step:failed', spy); @@ -842,7 +842,7 @@ describe('SwarmCoordinator', () => { describe('skipStep', () => { it('should mark step as skipped', async () => { const step = makeStepRow({ status: 'skipped' }); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [step] }); + (db.query as any).mockResolvedValueOnce({ rows: [step] }); const result = await coordinator.skipStep('step_1'); expect(result.status).toBe('skipped'); @@ -853,11 +853,11 @@ describe('SwarmCoordinator', () => { describe('getRun', () => { it('should return run or null', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); expect(await coordinator.getRun('nonexistent')).toBeNull(); const run = makeRunRow(); - vi.mocked(db.query).mockResolvedValueOnce({ rows: [run] }); + (db.query as any).mockResolvedValueOnce({ rows: [run] }); expect(await coordinator.getRun('run_test_1')).toEqual(run); }); }); @@ -869,7 +869,7 @@ describe('SwarmCoordinator', () => { makeStepRow({ id: 's2', stepName: 'step-2', status: 'pending', dependsOn: ['step-1'] }), makeStepRow({ id: 's3', stepName: 'step-3', status: 'pending', dependsOn: ['step-2'] }), ]; - vi.mocked(db.query).mockResolvedValueOnce({ rows: steps }); + (db.query as any).mockResolvedValueOnce({ rows: steps }); const ready = await coordinator.getReadySteps('run_test_1'); expect(ready).toHaveLength(1); @@ -881,7 +881,7 @@ describe('SwarmCoordinator', () => { makeStepRow({ id: 's1', stepName: 'a', status: 'pending', dependsOn: [] }), makeStepRow({ id: 's2', stepName: 'b', status: 'pending', dependsOn: [] }), ]; - vi.mocked(db.query).mockResolvedValueOnce({ rows: steps }); + (db.query as any).mockResolvedValueOnce({ rows: steps }); const ready = await coordinator.getReadySteps('run_test_1'); expect(ready).toHaveLength(2); @@ -890,7 +890,7 @@ describe('SwarmCoordinator', () => { describe('getRunsByWorkspace', () => { it('should query by workspace with optional status filter', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await coordinator.getRunsByWorkspace('ws-1', 'running'); expect(db.query).toHaveBeenCalledWith( expect.stringContaining('status = $2'), @@ -899,7 +899,7 @@ describe('SwarmCoordinator', () => { }); it('should query without status filter', async () => { - vi.mocked(db.query).mockResolvedValueOnce({ rows: [] }); + (db.query as any).mockResolvedValueOnce({ rows: [] }); await coordinator.getRunsByWorkspace('ws-1'); expect(db.query).toHaveBeenCalledWith( expect.not.stringContaining('status ='), diff --git a/packages/sdk/src/workflows/__tests__/cli-session-collector.test.ts b/packages/sdk/src/workflows/__tests__/cli-session-collector.test.ts index ba1582ad5..54b91e92d 100644 --- a/packages/sdk/src/workflows/__tests__/cli-session-collector.test.ts +++ b/packages/sdk/src/workflows/__tests__/cli-session-collector.test.ts @@ -16,7 +16,7 @@ function makeTempDir(prefix: string): string { async function importCollectorsWithHome(homeDir: string) { process.env.HOME = homeDir; - vi.resetModules(); + vi.restoreAllMocks(); const [claudeModule, opencodeModule] = await Promise.all([ import('../collectors/claude.js'), import('../collectors/opencode.js'), @@ -28,7 +28,7 @@ async function importCollectorsWithHome(homeDir: string) { } afterEach(() => { - vi.resetModules(); + vi.restoreAllMocks(); process.env.HOME = originalHome; while (tempDirs.length > 0) { rmSync(tempDirs.pop()!, { recursive: true, force: true }); diff --git a/packages/sdk/src/workflows/__tests__/collectors/claude.test.ts b/packages/sdk/src/workflows/__tests__/collectors/claude.test.ts index 8ab47ecf1..112240ea2 100644 --- a/packages/sdk/src/workflows/__tests__/collectors/claude.test.ts +++ b/packages/sdk/src/workflows/__tests__/collectors/claude.test.ts @@ -56,13 +56,13 @@ function createClaudeFixture(homeDir: string, cwd: string, timestamp: number): s async function importCollectorWithHome(homeDir: string) { process.env.HOME = homeDir; - vi.resetModules(); + vi.restoreAllMocks(); const module = await import('../../collectors/claude.js'); return module.ClaudeCodeCollector; } afterEach(() => { - vi.resetModules(); + vi.restoreAllMocks(); process.env.HOME = originalHome; while (tempDirs.length > 0) { rmSync(tempDirs.pop()!, { recursive: true, force: true }); diff --git a/packages/sdk/src/workflows/__tests__/collectors/opencode.test.ts b/packages/sdk/src/workflows/__tests__/collectors/opencode.test.ts index 0fbbf402d..ddcf8c5d1 100644 --- a/packages/sdk/src/workflows/__tests__/collectors/opencode.test.ts +++ b/packages/sdk/src/workflows/__tests__/collectors/opencode.test.ts @@ -93,7 +93,7 @@ function createOpenCodeFixture(homeDir: string, cwd: string, sessionCreatedAt: n async function importCollectorWithHome(homeDir: string) { process.env.HOME = homeDir; - vi.resetModules(); + vi.restoreAllMocks(); vi.doMock('node:module', () => ({ createRequire: () => (id: string) => { if (id !== 'better-sqlite3') { @@ -134,7 +134,7 @@ async function importCollectorWithHome(homeDir: string) { } afterEach(() => { - vi.resetModules(); + vi.restoreAllMocks(); process.env.HOME = originalHome; while (tempDirs.length > 0) { rmSync(tempDirs.pop()!, { recursive: true, force: true }); diff --git a/packages/sdk/src/workflows/__tests__/run-summary-table.test.ts b/packages/sdk/src/workflows/__tests__/run-summary-table.test.ts index cc578faec..2c01689f3 100644 --- a/packages/sdk/src/workflows/__tests__/run-summary-table.test.ts +++ b/packages/sdk/src/workflows/__tests__/run-summary-table.test.ts @@ -152,7 +152,7 @@ describe('WorkflowRunner logRunSummary', () => { const combined = logSpy.mock.calls.flat().join('\n'); expect(combined).toContain('Workflow "sample-workflow"'); - expect(combined).toContain('✓ lint [shell]'); + expect(combined).toContain('lint pass --'); expect(combined).not.toContain('Step Status'); logSpy.mockRestore(); From cbc3d04328c1924c25725b3ce00b359a9e0bd278 Mon Sep 17 00:00:00 2001 From: Barry Cape Date: Wed, 1 Apr 2026 11:17:36 -0400 Subject: [PATCH 2/2] fix: add missing package aliases for telemetry and cloud in vitest config Without these aliases, tests importing @agent-relay/telemetry or @agent-relay/cloud fail at module resolution even when dist/ exists. --- vitest.config.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/vitest.config.ts b/vitest.config.ts index de647bcb0..3baf23be4 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -42,6 +42,14 @@ export default defineConfig({ find: '@agent-relay/user-directory', replacement: path.resolve(__dirname, './packages/user-directory/dist/index.js'), }, + { + find: '@agent-relay/telemetry', + replacement: path.resolve(__dirname, './packages/telemetry/dist/index.js'), + }, + { + find: '@agent-relay/cloud', + replacement: path.resolve(__dirname, './packages/cloud/dist/index.js'), + }, ], }, test: {