daedalus-cli 0.5.25 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/AGENTS.md +12 -2
  2. package/CHANGELOG.md +32 -0
  3. package/CONTRIBUTING.md +3 -2
  4. package/dist/agents/orchestrator.js +7 -5
  5. package/dist/agents/orchestrator.js.map +1 -1
  6. package/dist/agents/orchestrator.test.d.ts +2 -0
  7. package/dist/agents/orchestrator.test.d.ts.map +1 -0
  8. package/dist/agents/orchestrator.test.js +48 -0
  9. package/dist/agents/orchestrator.test.js.map +1 -0
  10. package/dist/agents/roles.test.d.ts +2 -0
  11. package/dist/agents/roles.test.d.ts.map +1 -0
  12. package/dist/agents/roles.test.js +108 -0
  13. package/dist/agents/roles.test.js.map +1 -0
  14. package/dist/config/index.test.d.ts +2 -0
  15. package/dist/config/index.test.d.ts.map +1 -0
  16. package/dist/config/index.test.js +220 -0
  17. package/dist/config/index.test.js.map +1 -0
  18. package/dist/extraction.test.d.ts +2 -0
  19. package/dist/extraction.test.d.ts.map +1 -0
  20. package/dist/extraction.test.js +105 -0
  21. package/dist/extraction.test.js.map +1 -0
  22. package/dist/highlight.test.d.ts +2 -0
  23. package/dist/highlight.test.d.ts.map +1 -0
  24. package/dist/highlight.test.js +56 -0
  25. package/dist/highlight.test.js.map +1 -0
  26. package/dist/indexing/fts.test.d.ts +2 -0
  27. package/dist/indexing/fts.test.d.ts.map +1 -0
  28. package/dist/indexing/fts.test.js +104 -0
  29. package/dist/indexing/fts.test.js.map +1 -0
  30. package/dist/indexing/indexer.d.ts +21 -0
  31. package/dist/indexing/indexer.d.ts.map +1 -1
  32. package/dist/indexing/indexer.js +4 -4
  33. package/dist/indexing/indexer.js.map +1 -1
  34. package/dist/indexing/indexer.test.d.ts +2 -0
  35. package/dist/indexing/indexer.test.d.ts.map +1 -0
  36. package/dist/indexing/indexer.test.js +192 -0
  37. package/dist/indexing/indexer.test.js.map +1 -0
  38. package/dist/profile.d.ts.map +1 -1
  39. package/dist/profile.js +12 -7
  40. package/dist/profile.js.map +1 -1
  41. package/dist/profile.test.d.ts +2 -0
  42. package/dist/profile.test.d.ts.map +1 -0
  43. package/dist/profile.test.js +70 -0
  44. package/dist/profile.test.js.map +1 -0
  45. package/dist/router/health.test.d.ts +2 -0
  46. package/dist/router/health.test.d.ts.map +1 -0
  47. package/dist/router/health.test.js +87 -0
  48. package/dist/router/health.test.js.map +1 -0
  49. package/dist/router/index.test.d.ts +2 -0
  50. package/dist/router/index.test.d.ts.map +1 -0
  51. package/dist/router/index.test.js +136 -0
  52. package/dist/router/index.test.js.map +1 -0
  53. package/dist/router/rate-limiter.test.d.ts +2 -0
  54. package/dist/router/rate-limiter.test.d.ts.map +1 -0
  55. package/dist/router/rate-limiter.test.js +90 -0
  56. package/dist/router/rate-limiter.test.js.map +1 -0
  57. package/dist/session/jsonl.d.ts +0 -2
  58. package/dist/session/jsonl.d.ts.map +1 -1
  59. package/dist/session/jsonl.js +3 -7
  60. package/dist/session/jsonl.js.map +1 -1
  61. package/dist/session/jsonl.test.d.ts +2 -0
  62. package/dist/session/jsonl.test.d.ts.map +1 -0
  63. package/dist/session/jsonl.test.js +88 -0
  64. package/dist/session/jsonl.test.js.map +1 -0
  65. package/dist/session/manager.d.ts +2 -0
  66. package/dist/session/manager.d.ts.map +1 -1
  67. package/dist/session/manager.js +14 -0
  68. package/dist/session/manager.js.map +1 -1
  69. package/dist/session/manager.test.d.ts +2 -0
  70. package/dist/session/manager.test.d.ts.map +1 -0
  71. package/dist/session/manager.test.js +120 -0
  72. package/dist/session/manager.test.js.map +1 -0
  73. package/dist/session/memory.test.d.ts +2 -0
  74. package/dist/session/memory.test.d.ts.map +1 -0
  75. package/dist/session/memory.test.js +100 -0
  76. package/dist/session/memory.test.js.map +1 -0
  77. package/dist/session/sqlite.test.d.ts +2 -0
  78. package/dist/session/sqlite.test.d.ts.map +1 -0
  79. package/dist/session/sqlite.test.js +151 -0
  80. package/dist/session/sqlite.test.js.map +1 -0
  81. package/dist/tools/builtin/delegation.test.d.ts +2 -0
  82. package/dist/tools/builtin/delegation.test.d.ts.map +1 -0
  83. package/dist/tools/builtin/delegation.test.js +87 -0
  84. package/dist/tools/builtin/delegation.test.js.map +1 -0
  85. package/dist/tools/builtin/eval.test.d.ts +2 -0
  86. package/dist/tools/builtin/eval.test.d.ts.map +1 -0
  87. package/dist/tools/builtin/eval.test.js +24 -0
  88. package/dist/tools/builtin/eval.test.js.map +1 -0
  89. package/dist/tools/builtin/git.test.d.ts +2 -0
  90. package/dist/tools/builtin/git.test.d.ts.map +1 -0
  91. package/dist/tools/builtin/git.test.js +49 -0
  92. package/dist/tools/builtin/git.test.js.map +1 -0
  93. package/dist/tools/builtin/impact.test.d.ts +2 -0
  94. package/dist/tools/builtin/impact.test.d.ts.map +1 -0
  95. package/dist/tools/builtin/impact.test.js +50 -0
  96. package/dist/tools/builtin/impact.test.js.map +1 -0
  97. package/dist/tools/builtin/indexing.test.d.ts +2 -0
  98. package/dist/tools/builtin/indexing.test.d.ts.map +1 -0
  99. package/dist/tools/builtin/indexing.test.js +30 -0
  100. package/dist/tools/builtin/indexing.test.js.map +1 -0
  101. package/dist/tools/builtin/lsp.test.d.ts +2 -0
  102. package/dist/tools/builtin/lsp.test.d.ts.map +1 -0
  103. package/dist/tools/builtin/lsp.test.js +34 -0
  104. package/dist/tools/builtin/lsp.test.js.map +1 -0
  105. package/dist/tools/builtin/process-watcher.test.d.ts +2 -0
  106. package/dist/tools/builtin/process-watcher.test.d.ts.map +1 -0
  107. package/dist/tools/builtin/process-watcher.test.js +53 -0
  108. package/dist/tools/builtin/process-watcher.test.js.map +1 -0
  109. package/dist/tools/builtin/project-config.test.d.ts +2 -0
  110. package/dist/tools/builtin/project-config.test.d.ts.map +1 -0
  111. package/dist/tools/builtin/project-config.test.js +81 -0
  112. package/dist/tools/builtin/project-config.test.js.map +1 -0
  113. package/dist/tools/builtin/todo.test.d.ts +2 -0
  114. package/dist/tools/builtin/todo.test.d.ts.map +1 -0
  115. package/dist/tools/builtin/todo.test.js +66 -0
  116. package/dist/tools/builtin/todo.test.js.map +1 -0
  117. package/dist/tools/builtin/web.test.d.ts +2 -0
  118. package/dist/tools/builtin/web.test.d.ts.map +1 -0
  119. package/dist/tools/builtin/web.test.js +78 -0
  120. package/dist/tools/builtin/web.test.js.map +1 -0
  121. package/dist/tools/executor.test.d.ts +2 -0
  122. package/dist/tools/executor.test.d.ts.map +1 -0
  123. package/dist/tools/executor.test.js +79 -0
  124. package/dist/tools/executor.test.js.map +1 -0
  125. package/dist/tools/mcp/registry.test.d.ts +2 -0
  126. package/dist/tools/mcp/registry.test.d.ts.map +1 -0
  127. package/dist/tools/mcp/registry.test.js +18 -0
  128. package/dist/tools/mcp/registry.test.js.map +1 -0
  129. package/package.json +11 -1
  130. package/dist/manual-test.d.ts +0 -2
  131. package/dist/manual-test.d.ts.map +0 -1
  132. package/dist/manual-test.js.map +0 -1
@@ -0,0 +1,151 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { initIndexDb, initSessionDb, registerSession, listSessionsForProject, deleteSessionFromIndex, saveTurn, getTurns, clearTurns, saveActiveFiles, getActiveFiles, saveTodos, getTodos, saveState, getState, } from './sqlite.js';
6
+ describe('SQLite session database (index)', () => {
7
+ let db;
8
+ let dbPath;
9
+ beforeEach(() => {
10
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'daedalus-sqlite-test-'));
11
+ dbPath = path.join(dir, 'index.sqlite');
12
+ db = initIndexDb(dbPath);
13
+ });
14
+ afterEach(() => {
15
+ db.close();
16
+ fs.rmSync(path.dirname(dbPath), { recursive: true, force: true });
17
+ });
18
+ it('creates sessions table on init', () => {
19
+ const result = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='sessions'").get();
20
+ expect(result).toBeTruthy();
21
+ });
22
+ it('registers a session', () => {
23
+ registerSession(db, {
24
+ id: 'test-1', project_path: '/test', project_hash: 'abc123',
25
+ title: 'Test Session', created_at: 1000, updated_at: 1000,
26
+ });
27
+ const rows = db.prepare('SELECT * FROM sessions').all();
28
+ expect(rows).toHaveLength(1);
29
+ });
30
+ it('upserts session on duplicate id', () => {
31
+ registerSession(db, {
32
+ id: 'test-1', project_path: '/test', project_hash: 'abc123',
33
+ title: 'Original', created_at: 1000, updated_at: 1000,
34
+ });
35
+ registerSession(db, {
36
+ id: 'test-1', project_path: '/test', project_hash: 'abc123',
37
+ title: 'Updated', created_at: 1000, updated_at: 2000,
38
+ });
39
+ const rows = db.prepare('SELECT * FROM sessions').all();
40
+ expect(rows).toHaveLength(1);
41
+ expect(rows[0].title).toBe('Updated');
42
+ });
43
+ it('lists sessions for a project ordered by updated_at desc', () => {
44
+ registerSession(db, { id: 'a', project_path: '/p', project_hash: 'abc', title: 'A', created_at: 1, updated_at: 3 });
45
+ registerSession(db, { id: 'b', project_path: '/p', project_hash: 'abc', title: 'B', created_at: 2, updated_at: 1 });
46
+ registerSession(db, { id: 'c', project_path: '/p2', project_hash: 'xyz', title: 'C', created_at: 3, updated_at: 3 });
47
+ const result = listSessionsForProject(db, 'abc');
48
+ expect(result).toHaveLength(2);
49
+ expect(result[0].id).toBe('a');
50
+ expect(result[1].id).toBe('b');
51
+ });
52
+ it('deletes a session from index', () => {
53
+ registerSession(db, { id: 'del', project_path: '/p', project_hash: 'abc', title: 'Del', created_at: 1, updated_at: 1 });
54
+ deleteSessionFromIndex(db, 'del');
55
+ expect(listSessionsForProject(db, 'abc')).toHaveLength(0);
56
+ });
57
+ });
58
+ describe('SQLite session database (session)', () => {
59
+ let db;
60
+ let dbPath;
61
+ beforeEach(() => {
62
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'daedalus-sqlite-test-'));
63
+ dbPath = path.join(dir, 'session.sqlite');
64
+ db = initSessionDb(dbPath);
65
+ });
66
+ afterEach(() => {
67
+ db.close();
68
+ fs.rmSync(path.dirname(dbPath), { recursive: true, force: true });
69
+ });
70
+ it('creates all tables on init', () => {
71
+ const tables = db.prepare("SELECT name FROM sqlite_master WHERE type='table'").all().map((r) => r.name);
72
+ expect(tables).toContain('turns');
73
+ expect(tables).toContain('agent_state');
74
+ expect(tables).toContain('active_files');
75
+ expect(tables).toContain('todos');
76
+ });
77
+ it('saves and retrieves turns', () => {
78
+ saveTurn(db, { role: 'user', content: 'hello' });
79
+ saveTurn(db, { role: 'assistant', content: 'world' });
80
+ const turns = getTurns(db);
81
+ expect(turns).toHaveLength(2);
82
+ expect(turns[0].role).toBe('user');
83
+ expect(turns[1].content).toBe('world');
84
+ });
85
+ it('clearTurns removes all turns', () => {
86
+ saveTurn(db, { role: 'user', content: 'test' });
87
+ clearTurns(db);
88
+ expect(getTurns(db)).toHaveLength(0);
89
+ });
90
+ it('saves and retrieves active files', () => {
91
+ const files = new Map([
92
+ ['/path/to/file.ts', 'file.ts'],
93
+ ['/path/to/other.ts', 'other.ts'],
94
+ ]);
95
+ saveActiveFiles(db, files);
96
+ const loaded = getActiveFiles(db);
97
+ expect(loaded.size).toBe(2);
98
+ expect(loaded.get('/path/to/file.ts')).toBe('file.ts');
99
+ });
100
+ it('replaces active files on save', () => {
101
+ saveActiveFiles(db, new Map([['/a.ts', 'a.ts']]));
102
+ saveActiveFiles(db, new Map([['/b.ts', 'b.ts']]));
103
+ expect(getActiveFiles(db).size).toBe(1);
104
+ expect(getActiveFiles(db).get('/a.ts')).toBeUndefined();
105
+ });
106
+ it('saves and retrieves todos', () => {
107
+ const todos = [
108
+ { id: '1', content: 'Task 1', status: 'pending', created_at: 100, updated_at: 100 },
109
+ { id: '2', content: 'Task 2', status: 'completed', created_at: 200, updated_at: 200 },
110
+ ];
111
+ saveTodos(db, todos);
112
+ const loaded = getTodos(db);
113
+ expect(loaded).toHaveLength(2);
114
+ expect(loaded[0].status).toBe('pending');
115
+ });
116
+ it('replaces all todos on save', () => {
117
+ saveTodos(db, [{ id: '1', content: 'old', status: 'pending', created_at: 1, updated_at: 1 }]);
118
+ saveTodos(db, [{ id: '2', content: 'new', status: 'completed', created_at: 2, updated_at: 2 }]);
119
+ expect(getTodos(db)).toHaveLength(1);
120
+ });
121
+ it('saves and retrieves agent state', () => {
122
+ saveState(db, 'myKey', { nested: { value: 42 } });
123
+ expect(getState(db, 'myKey')).toEqual({ nested: { value: 42 } });
124
+ });
125
+ it('returns null for missing state key', () => {
126
+ expect(getState(db, 'nonexistent')).toBeNull();
127
+ });
128
+ it('overwrites existing state key', () => {
129
+ saveState(db, 'key', 'original');
130
+ saveState(db, 'key', 'updated');
131
+ expect(getState(db, 'key')).toBe('updated');
132
+ });
133
+ it('saves turn with all optional fields', () => {
134
+ saveTurn(db, {
135
+ role: 'assistant',
136
+ content: 'response',
137
+ tool_calls: JSON.stringify([{ id: 'call_1', type: 'function', function: { name: 'test', arguments: '{}' } }]),
138
+ tool_call_id: 'call_1',
139
+ name: 'test',
140
+ model: 'gpt-4',
141
+ tokens_input: 100,
142
+ tokens_output: 50,
143
+ latency_ms: 500,
144
+ });
145
+ const turns = getTurns(db);
146
+ expect(turns).toHaveLength(1);
147
+ expect(turns[0].tool_calls).toContain('call_1');
148
+ expect(turns[0].model).toBe('gpt-4');
149
+ });
150
+ });
151
+ //# sourceMappingURL=sqlite.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.test.js","sourceRoot":"","sources":["../../src/session/sqlite.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=delegation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegation.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/delegation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest';
2
+ import { manage, setRouterClient } from './delegation.js';
3
+ describe('Delegation tool', () => {
4
+ const mockContext = {
5
+ sessionId: 'test-session',
6
+ projectRoot: process.cwd(),
7
+ projectHash: 'testhash',
8
+ activeFiles: new Map(),
9
+ agentRole: 'coder',
10
+ abortSignal: new AbortController().signal,
11
+ autoApplyEdits: 'all',
12
+ patchHistory: [],
13
+ };
14
+ afterEach(() => {
15
+ vi.restoreAllMocks();
16
+ setRouterClient(null);
17
+ });
18
+ it('returns error when router client is not set', async () => {
19
+ setRouterClient(null);
20
+ const result = await manage({
21
+ goal: 'do something',
22
+ role: 'coder',
23
+ }, mockContext);
24
+ expect(result.success).toBe(false);
25
+ expect(result.error).toContain('not initialized');
26
+ });
27
+ it('delegates and returns sub-agent result', async () => {
28
+ const mockRouterClient = {
29
+ chat: {
30
+ completions: {
31
+ create: vi.fn()
32
+ .mockResolvedValueOnce({
33
+ choices: [{ message: { content: 'I will do the task', role: 'assistant', tool_calls: [] } }],
34
+ }),
35
+ },
36
+ },
37
+ };
38
+ setRouterClient(mockRouterClient);
39
+ const result = await manage({
40
+ goal: 'implement feature',
41
+ role: 'coder',
42
+ }, mockContext);
43
+ expect(result.success).toBe(true);
44
+ expect(mockRouterClient.chat.completions.create).toHaveBeenCalled();
45
+ });
46
+ it('reaches max turns for long-running agents', async () => {
47
+ const mockRouterClient = {
48
+ chat: {
49
+ completions: {
50
+ create: vi.fn().mockResolvedValue({
51
+ choices: [{
52
+ message: {
53
+ content: 'working...',
54
+ role: 'assistant',
55
+ tool_calls: [
56
+ { id: 'call_1', type: 'function', function: { name: 'read_file', arguments: '{"path": "test.ts"}' } },
57
+ ],
58
+ },
59
+ }],
60
+ }),
61
+ },
62
+ },
63
+ };
64
+ setRouterClient(mockRouterClient);
65
+ const result = await manage({
66
+ goal: 'do something',
67
+ role: 'coder',
68
+ }, mockContext);
69
+ expect(result.content).toContain('max turns');
70
+ });
71
+ it('handles router errors gracefully', async () => {
72
+ const mockRouterClient = {
73
+ chat: {
74
+ completions: {
75
+ create: vi.fn().mockRejectedValue(new Error('API error')),
76
+ },
77
+ },
78
+ };
79
+ setRouterClient(mockRouterClient);
80
+ const result = await manage({
81
+ goal: 'do something',
82
+ }, mockContext);
83
+ expect(result.success).toBe(false);
84
+ expect(result.error).toContain('Delegation failed');
85
+ });
86
+ });
87
+ //# sourceMappingURL=delegation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delegation.test.js","sourceRoot":"","sources":["../../../src/tools/builtin/delegation.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=eval.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/eval.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { evalCode } from './eval.js';
3
+ describe('eval_code tool', () => {
4
+ const mockContext = {
5
+ projectRoot: process.cwd(),
6
+ sessionId: 'test',
7
+ projectHash: 'test',
8
+ activeFiles: new Map(),
9
+ abortSignal: new AbortController().signal,
10
+ };
11
+ beforeEach(() => {
12
+ vi.restoreAllMocks();
13
+ Object.defineProperty(process.stdin, 'isTTY', { value: false, configurable: true, writable: true });
14
+ });
15
+ afterEach(() => {
16
+ vi.restoreAllMocks();
17
+ });
18
+ it('cancels when not approved (non-TTY)', async () => {
19
+ const result = await evalCode({ code: 'console.log("hi")' }, mockContext);
20
+ expect(result.success).toBe(false);
21
+ expect(result.error).toContain('cancelled');
22
+ });
23
+ });
24
+ //# sourceMappingURL=eval.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eval.test.js","sourceRoot":"","sources":["../../../src/tools/builtin/eval.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGrC,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAE9B,MAAM,WAAW,GAAgB;QAC/B,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE;QAC1B,SAAS,EAAE,MAAM;QACjB,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE,IAAI,GAAG,EAAE;QACtB,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM;KAC3B,CAAC;IAEjB,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,WAAW,CAAC,CAAC;QAC1E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=git.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/git.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { diff, status } from './git.js';
3
+ describe('Git tools', () => {
4
+ let tmpDir;
5
+ let context;
6
+ beforeEach(() => {
7
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'daedalus-git-test-'));
8
+ context = {
9
+ projectRoot: tmpDir,
10
+ };
11
+ execSync('git init', { cwd: tmpDir, stdio: 'ignore' });
12
+ execSync('git config user.email test@test.com', { cwd: tmpDir, stdio: 'ignore' });
13
+ execSync('git config user.name Test', { cwd: tmpDir, stdio: 'ignore' });
14
+ fs.writeFileSync(path.join(tmpDir, 'readme.md'), '# Test', 'utf8');
15
+ execSync('git add . && git commit -m "init"', { cwd: tmpDir, stdio: 'ignore' });
16
+ });
17
+ afterEach(() => {
18
+ fs.rmSync(tmpDir, { recursive: true, force: true });
19
+ });
20
+ it('git_status shows clean status', async () => {
21
+ const result = await status({}, context);
22
+ expect(result.success).toBe(true);
23
+ });
24
+ it('git_diff shows working tree changes', async () => {
25
+ fs.writeFileSync(path.join(tmpDir, 'readme.md'), '# Modified', 'utf8');
26
+ const result = await diff({}, context);
27
+ expect(result.success).toBe(true);
28
+ expect(result.content).toContain('Modified');
29
+ });
30
+ it('git_diff --staged shows staged changes', async () => {
31
+ fs.writeFileSync(path.join(tmpDir, 'new.txt'), 'content', 'utf8');
32
+ execSync('git add new.txt', { cwd: tmpDir, stdio: 'ignore' });
33
+ const result = await diff({ staged: true }, context);
34
+ expect(result.success).toBe(true);
35
+ expect(result.content).toContain('new.txt');
36
+ });
37
+ it('git_diff with path filters to that file', async () => {
38
+ fs.writeFileSync(path.join(tmpDir, 'readme.md'), 'Changed', 'utf8');
39
+ fs.writeFileSync(path.join(tmpDir, 'other.txt'), 'also changed', 'utf8');
40
+ const result = await diff({ path: 'readme.md' }, context);
41
+ expect(result.content).toContain('readme.md');
42
+ expect(result.content).not.toContain('other.txt');
43
+ });
44
+ });
45
+ import fs from 'fs';
46
+ import path from 'path';
47
+ import os from 'os';
48
+ import { execSync } from 'child_process';
49
+ //# sourceMappingURL=git.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.test.js","sourceRoot":"","sources":["../../../src/tools/builtin/git.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=impact.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/impact.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { getImpact } from './impact.js';
6
+ describe('Impact analysis tool', () => {
7
+ let tmpDir;
8
+ let context;
9
+ beforeEach(() => {
10
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'daedalus-impact-test-'));
11
+ context = {
12
+ projectRoot: tmpDir,
13
+ sessionId: 'test',
14
+ projectHash: 'test',
15
+ activeFiles: new Map(),
16
+ abortSignal: new AbortController().signal,
17
+ };
18
+ });
19
+ afterEach(() => {
20
+ fs.rmSync(tmpDir, { recursive: true, force: true });
21
+ });
22
+ it('returns no impact for isolated file', async () => {
23
+ fs.writeFileSync(path.join(tmpDir, 'isolated.ts'), 'export const x = 1;\n');
24
+ const result = await getImpact({ target: 'isolated.ts' }, context);
25
+ expect(result.success).toBe(true);
26
+ expect(result.content).toContain('No files import');
27
+ });
28
+ it('detects direct importers', async () => {
29
+ fs.writeFileSync(path.join(tmpDir, 'dep.ts'), 'export const helper = () => {};\n');
30
+ fs.writeFileSync(path.join(tmpDir, 'user.ts'), "import { helper } from './dep';\nhelper();\n");
31
+ const result = await getImpact({ target: 'dep.ts' }, context);
32
+ expect(result.success).toBe(true);
33
+ expect(result.content).toContain('user.ts');
34
+ });
35
+ it('detects transitive importers', async () => {
36
+ fs.writeFileSync(path.join(tmpDir, 'lib.ts'), 'export const util = () => {};\n');
37
+ fs.writeFileSync(path.join(tmpDir, 'middle.ts'), "import { util } from './lib';\nexport const mid = () => util();\n");
38
+ fs.writeFileSync(path.join(tmpDir, 'top.ts'), "import { mid } from './middle';\nmid();\n");
39
+ const result = await getImpact({ target: 'lib.ts' }, context);
40
+ expect(result.success).toBe(true);
41
+ expect(result.content).toContain('Depth 1');
42
+ expect(result.content).toContain('Depth 2');
43
+ });
44
+ it('returns error when project has no source files', async () => {
45
+ const result = await getImpact({ target: 'test.ts' }, context);
46
+ expect(result.success).toBe(false);
47
+ expect(result.error).toContain('No source files found');
48
+ });
49
+ });
50
+ //# sourceMappingURL=impact.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"impact.test.js","sourceRoot":"","sources":["../../../src/tools/builtin/impact.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=indexing.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexing.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/indexing.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getProjectHash, getIndexDbPath } from './indexing.js';
3
+ describe('Indexing tool helpers', () => {
4
+ it('getProjectHash returns consistent 12-char hash', () => {
5
+ const hash = getProjectHash('/some/project/path');
6
+ expect(hash).toHaveLength(12);
7
+ });
8
+ it('getProjectHash is deterministic for same path', () => {
9
+ const h1 = getProjectHash('/same/path');
10
+ const h2 = getProjectHash('/same/path');
11
+ expect(h1).toBe(h2);
12
+ });
13
+ it('getProjectHash differs for different paths', () => {
14
+ const h1 = getProjectHash('/path/a');
15
+ const h2 = getProjectHash('/path/b');
16
+ expect(h1).not.toBe(h2);
17
+ });
18
+ it('getIndexDbPath returns path ending with .sqlite', () => {
19
+ const result = getIndexDbPath('/some/project');
20
+ expect(result.endsWith('.sqlite')).toBe(true);
21
+ expect(result).toContain('.daedalus');
22
+ expect(result).toContain('indexing');
23
+ });
24
+ it('getIndexDbPath includes project hash in filename', () => {
25
+ const hash = getProjectHash('/my-project');
26
+ const path = getIndexDbPath('/my-project');
27
+ expect(path).toContain(hash);
28
+ });
29
+ });
30
+ //# sourceMappingURL=indexing.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexing.test.js","sourceRoot":"","sources":["../../../src/tools/builtin/indexing.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAA6B,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/D,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IAErC,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,IAAI,GAAG,cAAc,CAAC,oBAAoB,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,EAAE,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,EAAE,GAAG,cAAc,CAAC,YAAY,CAAC,CAAC;QACxC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,EAAE,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,EAAE,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACrC,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,MAAM,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;QAC/C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,IAAI,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=lsp.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/lsp.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,34 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { lspDiagnostics, lspHover, lspRename } from './lsp.js';
3
+ describe('LSP tools', () => {
4
+ let context;
5
+ beforeEach(() => {
6
+ context = {
7
+ projectRoot: process.cwd(),
8
+ sessionId: 'test',
9
+ projectHash: 'test',
10
+ activeFiles: new Map(),
11
+ abortSignal: new AbortController().signal,
12
+ };
13
+ });
14
+ afterEach(() => {
15
+ vi.restoreAllMocks();
16
+ });
17
+ it('lspDiagnostics returns error for nonexistent file', async () => {
18
+ const result = await lspDiagnostics({ path: '/nonexistent/file.ts' }, context);
19
+ expect(result.success).toBe(false);
20
+ });
21
+ it('lspDiagnostics succeeds without path argument', async () => {
22
+ const result = await lspDiagnostics({}, context);
23
+ expect(result.success).toBe(true);
24
+ });
25
+ it('lspHover returns error for nonexistent file', async () => {
26
+ const result = await lspHover({ path: '/nonexistent.ts', line: 1, col: 1 }, context);
27
+ expect(result.success).toBe(false);
28
+ });
29
+ it('lspRename returns error for nonexistent file', async () => {
30
+ const result = await lspRename({ path: '/nonexistent.ts', line: 1, col: 1, new_name: 'Foo' }, context);
31
+ expect(result.success).toBe(false);
32
+ });
33
+ });
34
+ //# sourceMappingURL=lsp.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.test.js","sourceRoot":"","sources":["../../../src/tools/builtin/lsp.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG/D,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAI,OAAoB,CAAC;IAEzB,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG;YACR,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE;YAC1B,SAAS,EAAE,MAAM;YACjB,WAAW,EAAE,MAAM;YACnB,WAAW,EAAE,IAAI,GAAG,EAAE;YACtB,WAAW,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM;SAC3B,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,EAAE,OAAO,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACrF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QACvG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=process-watcher.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-watcher.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/process-watcher.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,53 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { watchProcess, readProcess, killProcess, killAllWatchedProcesses } from './process-watcher.js';
3
+ describe('Process watcher tools', () => {
4
+ let context;
5
+ beforeEach(() => {
6
+ context = {
7
+ projectRoot: process.cwd(),
8
+ sessionId: 'test',
9
+ };
10
+ });
11
+ afterEach(() => {
12
+ killAllWatchedProcesses();
13
+ vi.restoreAllMocks();
14
+ });
15
+ it('watchProcess starts and returns an id', async () => {
16
+ const result = await watchProcess({ command: process.execPath + ' -e "setTimeout(() => {}, 10000)"' }, context);
17
+ expect(result.success).toBe(true);
18
+ expect(result.content).toContain('proc_');
19
+ });
20
+ it('readProcess returns error for nonexistent id', async () => {
21
+ const result = await readProcess({ id: 'proc_nonexistent' }, context);
22
+ expect(result.success).toBe(false);
23
+ expect(result.error).toContain('No watched process');
24
+ });
25
+ it('killProcess returns error for nonexistent id', async () => {
26
+ const result = await killProcess({ id: 'proc_nonexistent' }, context);
27
+ expect(result.success).toBe(false);
28
+ expect(result.error).toContain('No watched process');
29
+ });
30
+ it('readProcess returns output from running process', async () => {
31
+ const startResult = await watchProcess({ command: process.execPath + ' -e "console.log(\'hello from proc\'); setTimeout(()=>{},5000)"' }, context);
32
+ const idMatch = startResult.content.match(/proc_\d+/);
33
+ expect(idMatch).not.toBeNull();
34
+ await new Promise(r => setTimeout(r, 300));
35
+ const readResult = await readProcess({ id: idMatch[0] }, context);
36
+ expect(readResult.success).toBe(true);
37
+ expect(readResult.content).toContain('hello from proc');
38
+ });
39
+ it('killProcess terminates a running process', async () => {
40
+ const startResult = await watchProcess({ command: process.execPath + ' -e "setTimeout(() => {}, 60000)"' }, context);
41
+ const idMatch = startResult.content.match(/proc_\d+/);
42
+ expect(idMatch).not.toBeNull();
43
+ const killResult = await killProcess({ id: idMatch[0] }, context);
44
+ expect(killResult.success).toBe(true);
45
+ expect(killResult.content).toContain('killed');
46
+ });
47
+ it('killAllWatchedProcesses cleans up all processes', async () => {
48
+ await watchProcess({ command: process.execPath + ' -e "setTimeout(() => {}, 60000)"' }, context);
49
+ await watchProcess({ command: process.execPath + ' -e "setTimeout(() => {}, 60000)"' }, context);
50
+ expect(() => killAllWatchedProcesses()).not.toThrow();
51
+ });
52
+ });
53
+ //# sourceMappingURL=process-watcher.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process-watcher.test.js","sourceRoot":"","sources":["../../../src/tools/builtin/process-watcher.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=project-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-config.test.d.ts","sourceRoot":"","sources":["../../../src/tools/builtin/project-config.test.ts"],"names":[],"mappings":""}