-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathdetect.test.ts
More file actions
77 lines (61 loc) · 2.47 KB
/
Copy pathdetect.test.ts
File metadata and controls
77 lines (61 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import which from 'which';
import { detectInstalledAgents, isInsideAgent } from './detect.js';
import { AgentDefinition } from './types.js';
vi.mock('which');
const whichMock = vi.mocked(which);
function createDefinition(overrides: Partial<AgentDefinition>): AgentDefinition {
return {
id: 'claude-code',
displayName: 'Claude Code',
binaryNames: ['claude'],
buildInteractive: () => ({ args: [] }),
...overrides,
};
}
describe('detectInstalledAgents', () => {
beforeEach(() => {
vi.resetAllMocks();
});
it('should detect an agent found on the PATH', async () => {
whichMock.mockResolvedValue('/usr/local/bin/claude');
const installed = await detectInstalledAgents([createDefinition({})]);
expect(installed).toHaveLength(1);
expect(installed[0].binaryPath).toBe('/usr/local/bin/claude');
expect(whichMock).toHaveBeenCalledWith('claude', { nothrow: true });
});
it('should return an empty list when nothing is installed', async () => {
// @ts-expect-error - the nothrow overload returns string | null which the mocked union cannot infer
whichMock.mockResolvedValue(null);
const installed = await detectInstalledAgents([createDefinition({})]);
expect(installed).toEqual([]);
});
it('should preserve definition order even when probes resolve out of order', async () => {
whichMock.mockImplementation((binaryName) => {
if (binaryName === 'claude') {
return new Promise((resolve) => {
setTimeout(() => resolve('/usr/local/bin/claude'), 20);
});
}
return Promise.resolve('/usr/local/bin/codex');
});
const installed = await detectInstalledAgents([
createDefinition({}),
createDefinition({ id: 'codex', displayName: 'OpenAI Codex', binaryNames: ['codex'] }),
]);
expect(installed.map((agent) => agent.definition.id)).toEqual(['claude-code', 'codex']);
});
});
describe('isInsideAgent', () => {
it.each(['CLAUDECODE', 'CURSOR_TRACE_ID', 'OPENCODE', 'CODEX_THREAD_ID', 'GEMINI_CLI', 'VSCODE_AGENT', 'REPL_ID'])(
'should return true when %s is set',
(envVar) => {
expect(isInsideAgent({ [envVar]: '1' })).toBe(true);
}
);
it('should return false when no agent environment variables are set', () => {
expect(isInsideAgent({ PATH: '/usr/bin', TERM: 'xterm-256color' })).toBe(false);
});
it('should return false when an agent environment variable is set but empty', () => {
expect(isInsideAgent({ CLAUDECODE: '' })).toBe(false);
});
});