claude-mycelium 2.0.0 → 2.1.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 (189) hide show
  1. package/.agent-meta/_inhibitors.ndjson +1287 -0
  2. package/.agent-meta/_quarantine.json +45 -0
  3. package/.agent-meta/config.json +9 -0
  4. package/.claude/memory.db +0 -0
  5. package/.claude/settings.local.json +4 -1
  6. package/README.md +81 -235
  7. package/SECURITY.md +145 -0
  8. package/dist/agent/worker.d.ts +8 -0
  9. package/dist/agent/worker.d.ts.map +1 -0
  10. package/dist/agent/worker.js +97 -0
  11. package/dist/agent/worker.js.map +1 -0
  12. package/dist/bin.d.ts +7 -0
  13. package/dist/bin.d.ts.map +1 -0
  14. package/dist/bin.js +11 -0
  15. package/dist/bin.js.map +1 -0
  16. package/dist/cli/cost.d.ts +10 -0
  17. package/dist/cli/cost.d.ts.map +1 -0
  18. package/dist/cli/cost.js +163 -0
  19. package/dist/cli/cost.js.map +1 -0
  20. package/dist/cli/gc.d.ts +10 -0
  21. package/dist/cli/gc.d.ts.map +1 -0
  22. package/dist/cli/gc.js +108 -0
  23. package/dist/cli/gc.js.map +1 -0
  24. package/dist/cli/gradients.d.ts +10 -0
  25. package/dist/cli/gradients.d.ts.map +1 -0
  26. package/dist/cli/gradients.js +69 -0
  27. package/dist/cli/gradients.js.map +1 -0
  28. package/dist/cli/index.d.ts +17 -0
  29. package/dist/cli/index.d.ts.map +1 -0
  30. package/dist/cli/index.js +72 -0
  31. package/dist/cli/index.js.map +1 -0
  32. package/dist/cli/init.d.ts +11 -0
  33. package/dist/cli/init.d.ts.map +1 -0
  34. package/dist/cli/init.js +97 -0
  35. package/dist/cli/init.js.map +1 -0
  36. package/dist/cli/status.d.ts +10 -0
  37. package/dist/cli/status.d.ts.map +1 -0
  38. package/dist/cli/status.js +191 -0
  39. package/dist/cli/status.js.map +1 -0
  40. package/dist/coordination/file-locks.d.ts +42 -0
  41. package/dist/coordination/file-locks.d.ts.map +1 -0
  42. package/dist/coordination/file-locks.js +269 -0
  43. package/dist/coordination/file-locks.js.map +1 -0
  44. package/dist/coordination/index.d.ts +4 -0
  45. package/dist/coordination/index.d.ts.map +1 -1
  46. package/dist/coordination/index.js +4 -0
  47. package/dist/coordination/index.js.map +1 -1
  48. package/dist/coordination/inhibitors.d.ts +84 -0
  49. package/dist/coordination/inhibitors.d.ts.map +1 -0
  50. package/dist/coordination/inhibitors.js +290 -0
  51. package/dist/coordination/inhibitors.js.map +1 -0
  52. package/dist/coordination/process-manager.d.ts +73 -0
  53. package/dist/coordination/process-manager.d.ts.map +1 -0
  54. package/dist/coordination/process-manager.js +144 -0
  55. package/dist/coordination/process-manager.js.map +1 -0
  56. package/dist/core/agent-executor.d.ts.map +1 -1
  57. package/dist/core/agent-executor.js +28 -10
  58. package/dist/core/agent-executor.js.map +1 -1
  59. package/dist/core/change-applier.d.ts +29 -5
  60. package/dist/core/change-applier.d.ts.map +1 -1
  61. package/dist/core/change-applier.js +254 -24
  62. package/dist/core/change-applier.js.map +1 -1
  63. package/dist/core/signals/churn.d.ts.map +1 -1
  64. package/dist/core/signals/churn.js +6 -4
  65. package/dist/core/signals/churn.js.map +1 -1
  66. package/dist/core/signals/debt.d.ts.map +1 -1
  67. package/dist/core/signals/debt.js +4 -3
  68. package/dist/core/signals/debt.js.map +1 -1
  69. package/dist/cost/cost-tracker.d.ts.map +1 -1
  70. package/dist/cost/cost-tracker.js +2 -0
  71. package/dist/cost/cost-tracker.js.map +1 -1
  72. package/dist/gc/index.d.ts +17 -0
  73. package/dist/gc/index.d.ts.map +1 -0
  74. package/dist/gc/index.js +17 -0
  75. package/dist/gc/index.js.map +1 -0
  76. package/dist/gc/runner.d.ts +39 -0
  77. package/dist/gc/runner.d.ts.map +1 -0
  78. package/dist/gc/runner.js +277 -0
  79. package/dist/gc/runner.js.map +1 -0
  80. package/dist/gc/trace-compactor.d.ts +31 -0
  81. package/dist/gc/trace-compactor.d.ts.map +1 -0
  82. package/dist/gc/trace-compactor.js +162 -0
  83. package/dist/gc/trace-compactor.js.map +1 -0
  84. package/dist/index.d.ts +5 -1
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +6 -1
  87. package/dist/index.js.map +1 -1
  88. package/dist/prompts/index.d.ts +2 -1
  89. package/dist/prompts/index.d.ts.map +1 -1
  90. package/dist/prompts/index.js.map +1 -1
  91. package/dist/quarantine/explorer.d.ts +65 -0
  92. package/dist/quarantine/explorer.d.ts.map +1 -0
  93. package/dist/quarantine/explorer.js +175 -0
  94. package/dist/quarantine/explorer.js.map +1 -0
  95. package/dist/quarantine/index.d.ts +7 -0
  96. package/dist/quarantine/index.d.ts.map +1 -0
  97. package/dist/quarantine/index.js +7 -0
  98. package/dist/quarantine/index.js.map +1 -0
  99. package/dist/quarantine/manager.d.ts +75 -0
  100. package/dist/quarantine/manager.d.ts.map +1 -0
  101. package/dist/quarantine/manager.js +275 -0
  102. package/dist/quarantine/manager.js.map +1 -0
  103. package/dist/task/acceptance.d.ts +29 -0
  104. package/dist/task/acceptance.d.ts.map +1 -0
  105. package/dist/task/acceptance.js +228 -0
  106. package/dist/task/acceptance.js.map +1 -0
  107. package/dist/task/executor.d.ts +30 -0
  108. package/dist/task/executor.d.ts.map +1 -0
  109. package/dist/task/executor.js +429 -0
  110. package/dist/task/executor.js.map +1 -0
  111. package/dist/task/index.d.ts +12 -0
  112. package/dist/task/index.d.ts.map +1 -0
  113. package/dist/task/index.js +12 -0
  114. package/dist/task/index.js.map +1 -0
  115. package/dist/task/planner.d.ts +21 -0
  116. package/dist/task/planner.d.ts.map +1 -0
  117. package/dist/task/planner.js +253 -0
  118. package/dist/task/planner.js.map +1 -0
  119. package/dist/task/storage.d.ts +46 -0
  120. package/dist/task/storage.d.ts.map +1 -0
  121. package/dist/task/storage.js +266 -0
  122. package/dist/task/storage.js.map +1 -0
  123. package/dist/trace/trace-event.d.ts +2 -18
  124. package/dist/trace/trace-event.d.ts.map +1 -1
  125. package/dist/trace/trace-event.js +6 -6
  126. package/dist/trace/trace-event.js.map +1 -1
  127. package/dist/utils/file-utils.d.ts.map +1 -1
  128. package/dist/utils/file-utils.js +54 -15
  129. package/dist/utils/file-utils.js.map +1 -1
  130. package/docs/PHASE5_IMPLEMENTATION.md +237 -0
  131. package/docs/PHASES-3-7-COMPLETE.md +177 -0
  132. package/docs/PHASE_4_COMPLETE.md +135 -0
  133. package/docs/PHASE_7_DELIVERABLES.md +295 -0
  134. package/docs/PHASE_7_IMPLEMENTATION.md +306 -0
  135. package/docs/PHASE_7_SUMMARY.txt +195 -0
  136. package/docs/RELEASE-NOTES-v2.1.md +213 -0
  137. package/docs/ROADMAP.md +64 -57
  138. package/docs/SECURITY-AUDIT.md +387 -0
  139. package/docs/SNAPSHOT.md +59 -32
  140. package/docs/implementation/phase3-summary.md +220 -0
  141. package/package.json +19 -11
  142. package/src/agent/worker.ts +111 -0
  143. package/src/bin.ts +13 -0
  144. package/src/cli/cost.ts +210 -0
  145. package/src/cli/gc.ts +138 -0
  146. package/src/cli/gradients.ts +95 -0
  147. package/src/cli/index.ts +79 -0
  148. package/src/cli/init.ts +139 -0
  149. package/src/cli/status.ts +218 -0
  150. package/src/coordination/file-locks.ts +300 -0
  151. package/src/coordination/index.ts +4 -0
  152. package/src/coordination/inhibitors.ts +345 -0
  153. package/src/coordination/process-manager.ts +199 -0
  154. package/src/core/agent-executor.ts +20 -4
  155. package/src/core/signals/churn.ts +8 -5
  156. package/src/core/signals/debt.ts +4 -3
  157. package/src/cost/cost-tracker.ts +2 -0
  158. package/src/gc/index.ts +17 -0
  159. package/src/gc/runner.ts +314 -0
  160. package/src/gc/trace-compactor.ts +187 -0
  161. package/src/index.ts +7 -1
  162. package/src/prompts/index.ts +2 -1
  163. package/src/quarantine/explorer.ts +234 -0
  164. package/src/quarantine/index.ts +7 -0
  165. package/src/quarantine/manager.ts +336 -0
  166. package/src/task/acceptance.ts +267 -0
  167. package/src/task/executor.ts +538 -0
  168. package/src/task/index.ts +38 -0
  169. package/src/task/planner.ts +294 -0
  170. package/src/task/storage.ts +332 -0
  171. package/src/trace/trace-event.ts +7 -26
  172. package/src/utils/file-utils.ts +61 -15
  173. package/tests/cli/gc.test.ts +206 -0
  174. package/tests/cli/init.test.ts +181 -0
  175. package/tests/cli/status.test.ts +282 -0
  176. package/tests/coordination/file-locks.test.ts +196 -0
  177. package/tests/coordination/inhibitors.test.ts +459 -0
  178. package/tests/coordination/integration.test.ts +195 -0
  179. package/tests/coordination/process-manager.test.ts +165 -0
  180. package/tests/gc/trace-compactor.test.ts +245 -0
  181. package/tests/integration/phase-7.test.ts +145 -0
  182. package/tests/quarantine/explorer.test.ts +381 -0
  183. package/tests/quarantine/manager.test.ts +399 -0
  184. package/tests/security/command-injection.test.ts +88 -0
  185. package/tests/security/path-traversal.test.ts +103 -0
  186. package/tests/task/acceptance.test.ts +411 -0
  187. package/tests/task/executor.test.ts +421 -0
  188. package/tests/task/planner.test.ts +359 -0
  189. package/tsconfig.json +2 -2
@@ -0,0 +1,359 @@
1
+ /**
2
+ * Tests for Task Planner
3
+ * Validates task decomposition and dependency analysis
4
+ */
5
+
6
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
7
+ import { planTask, analyzeDependencies, identifyRisks } from '../../src/task/planner.js';
8
+ import { Task, TaskPlan, TaskStep } from '../../src/types/index.js';
9
+ import * as llm from '../../src/llm/anthropic-client.js';
10
+
11
+ // Mock LLM client
12
+ vi.mock('../../src/llm/anthropic-client.js', () => ({
13
+ callLLM: vi.fn(),
14
+ }));
15
+
16
+ // Mock fast-glob
17
+ vi.mock('fast-glob', () => ({
18
+ default: vi.fn(() => Promise.resolve(['src/auth.ts', 'src/api.ts'])),
19
+ }));
20
+
21
+ describe('Task Planner', () => {
22
+ beforeEach(() => {
23
+ vi.clearAllMocks();
24
+ });
25
+
26
+ describe('planTask', () => {
27
+ it('should generate a task plan for adding health check endpoint', async () => {
28
+ // Mock LLM response
29
+ const mockPlan: TaskPlan = {
30
+ summary: 'Add health check endpoint to API',
31
+ steps: [
32
+ {
33
+ order: 1,
34
+ description: 'Create health check handler',
35
+ target_file: 'src/api/health.ts',
36
+ mode: 'create',
37
+ depends_on: [],
38
+ completed: false,
39
+ },
40
+ {
41
+ order: 2,
42
+ description: 'Add route to main router',
43
+ target_file: 'src/api/index.ts',
44
+ mode: 'stabilizer',
45
+ depends_on: [1],
46
+ completed: false,
47
+ },
48
+ {
49
+ order: 3,
50
+ description: 'Add health check test',
51
+ target_file: 'src/api/health.test.ts',
52
+ mode: 'create',
53
+ depends_on: [1],
54
+ completed: false,
55
+ },
56
+ {
57
+ order: 4,
58
+ description: 'Update API documentation',
59
+ target_file: 'src/api/docs.ts',
60
+ mode: 'debt_payer',
61
+ depends_on: [2],
62
+ completed: false,
63
+ },
64
+ ],
65
+ estimated_complexity: 'small',
66
+ risks: ['May need to update deployment config'],
67
+ };
68
+
69
+ vi.mocked(llm.callLLM).mockResolvedValue({
70
+ content: JSON.stringify(mockPlan),
71
+ usage: { inputTokens: 100, outputTokens: 200 },
72
+ model: 'claude-sonnet-4-5-20250929',
73
+ });
74
+
75
+ const task: Task = {
76
+ id: 'test-123',
77
+ description: 'Add health check endpoint',
78
+ status: 'pending',
79
+ created_at: new Date().toISOString(),
80
+ acceptance_criteria: [],
81
+ steps_completed: 0,
82
+ steps_total: 0,
83
+ files_created: [],
84
+ files_modified: [],
85
+ traces: [],
86
+ };
87
+
88
+ const plan = await planTask(task);
89
+
90
+ expect(plan.steps.length).toBe(4);
91
+ expect(plan.steps[0].mode).toBe('create');
92
+ expect(plan.steps[0].target_file).toContain('health.ts');
93
+ expect(plan.estimated_complexity).toBe('small');
94
+ expect(llm.callLLM).toHaveBeenCalledOnce();
95
+ });
96
+
97
+ it('should handle complex task with multiple dependencies', async () => {
98
+ const mockPlan: TaskPlan = {
99
+ summary: 'Add JWT authentication',
100
+ steps: [
101
+ {
102
+ order: 1,
103
+ description: 'Create JWT utility',
104
+ target_file: 'src/auth/jwt.ts',
105
+ mode: 'create',
106
+ depends_on: [],
107
+ completed: false,
108
+ },
109
+ {
110
+ order: 2,
111
+ description: 'Create auth middleware',
112
+ target_file: 'src/auth/middleware.ts',
113
+ mode: 'create',
114
+ depends_on: [1],
115
+ completed: false,
116
+ },
117
+ {
118
+ order: 3,
119
+ description: 'Update user routes',
120
+ target_file: 'src/api/user.ts',
121
+ mode: 'stabilizer',
122
+ depends_on: [2],
123
+ completed: false,
124
+ },
125
+ ],
126
+ estimated_complexity: 'medium',
127
+ risks: ['Breaking change for existing API clients'],
128
+ };
129
+
130
+ vi.mocked(llm.callLLM).mockResolvedValue({
131
+ content: JSON.stringify(mockPlan),
132
+ usage: { inputTokens: 150, outputTokens: 300 },
133
+ model: 'claude-sonnet-4-5-20250929',
134
+ });
135
+
136
+ const task: Task = {
137
+ id: 'test-456',
138
+ description: 'Add JWT authentication',
139
+ status: 'pending',
140
+ created_at: new Date().toISOString(),
141
+ acceptance_criteria: [],
142
+ steps_completed: 0,
143
+ steps_total: 0,
144
+ files_created: [],
145
+ files_modified: [],
146
+ traces: [],
147
+ };
148
+
149
+ const plan = await planTask(task);
150
+
151
+ expect(plan.steps.length).toBe(3);
152
+ expect(plan.steps[1].depends_on).toContain(1);
153
+ expect(plan.steps[2].depends_on).toContain(2);
154
+ });
155
+
156
+ it('should throw error if LLM returns invalid JSON', async () => {
157
+ vi.mocked(llm.callLLM).mockResolvedValue({
158
+ content: 'This is not JSON',
159
+ usage: { inputTokens: 100, outputTokens: 50 },
160
+ model: 'claude-sonnet-4-5-20250929',
161
+ });
162
+
163
+ const task: Task = {
164
+ id: 'test-789',
165
+ description: 'Invalid task',
166
+ status: 'pending',
167
+ created_at: new Date().toISOString(),
168
+ acceptance_criteria: [],
169
+ steps_completed: 0,
170
+ steps_total: 0,
171
+ files_created: [],
172
+ files_modified: [],
173
+ traces: [],
174
+ };
175
+
176
+ await expect(planTask(task)).rejects.toThrow('Failed to parse task plan');
177
+ });
178
+ });
179
+
180
+ describe('analyzeDependencies', () => {
181
+ it('should identify direct dependencies', () => {
182
+ const steps: TaskStep[] = [
183
+ {
184
+ order: 1,
185
+ description: 'Step 1',
186
+ target_file: 'src/a.ts',
187
+ mode: 'create',
188
+ depends_on: [],
189
+ completed: false,
190
+ },
191
+ {
192
+ order: 2,
193
+ description: 'Step 2',
194
+ target_file: 'src/b.ts',
195
+ mode: 'create',
196
+ depends_on: [1],
197
+ completed: false,
198
+ },
199
+ {
200
+ order: 3,
201
+ description: 'Step 3',
202
+ target_file: 'src/c.ts',
203
+ mode: 'create',
204
+ depends_on: [1, 2],
205
+ completed: false,
206
+ },
207
+ ];
208
+
209
+ const deps = analyzeDependencies(steps);
210
+
211
+ expect(deps.get(1)).toEqual([]);
212
+ expect(deps.get(2)).toContain(1);
213
+ expect(deps.get(3)).toContain(1);
214
+ expect(deps.get(3)).toContain(2);
215
+ });
216
+
217
+ it('should detect implicit dependencies for modify steps', () => {
218
+ const steps: TaskStep[] = [
219
+ {
220
+ order: 1,
221
+ description: 'Create file',
222
+ target_file: 'src/auth.ts',
223
+ mode: 'create',
224
+ depends_on: [],
225
+ completed: false,
226
+ },
227
+ {
228
+ order: 2,
229
+ description: 'Modify file',
230
+ target_file: 'src/auth.ts',
231
+ mode: 'error_reducer',
232
+ depends_on: [],
233
+ completed: false,
234
+ },
235
+ ];
236
+
237
+ const deps = analyzeDependencies(steps);
238
+
239
+ // Step 2 should implicitly depend on step 1
240
+ expect(deps.get(2)).toContain(1);
241
+ });
242
+
243
+ it('should detect test file dependencies', () => {
244
+ const steps: TaskStep[] = [
245
+ {
246
+ order: 1,
247
+ description: 'Create implementation',
248
+ target_file: 'src/auth.ts',
249
+ mode: 'create',
250
+ depends_on: [],
251
+ completed: false,
252
+ },
253
+ {
254
+ order: 2,
255
+ description: 'Create test',
256
+ target_file: 'src/auth.test.ts',
257
+ mode: 'create',
258
+ depends_on: [],
259
+ completed: false,
260
+ },
261
+ ];
262
+
263
+ const deps = analyzeDependencies(steps);
264
+
265
+ // Test file should implicitly depend on implementation
266
+ expect(deps.get(2)).toContain(1);
267
+ });
268
+ });
269
+
270
+ describe('identifyRisks', () => {
271
+ it('should identify circular dependencies', () => {
272
+ const plan: TaskPlan = {
273
+ summary: 'Test plan',
274
+ steps: [
275
+ {
276
+ order: 1,
277
+ description: 'Step 1',
278
+ target_file: 'src/a.ts',
279
+ mode: 'create',
280
+ depends_on: [2],
281
+ completed: false,
282
+ },
283
+ {
284
+ order: 2,
285
+ description: 'Step 2',
286
+ target_file: 'src/b.ts',
287
+ mode: 'create',
288
+ depends_on: [1],
289
+ completed: false,
290
+ },
291
+ ],
292
+ estimated_complexity: 'small',
293
+ risks: [],
294
+ };
295
+
296
+ const risks = identifyRisks(plan);
297
+
298
+ expect(risks).toContain('Circular dependency detected in task steps');
299
+ });
300
+
301
+ it('should identify steps with many dependencies', () => {
302
+ const plan: TaskPlan = {
303
+ summary: 'Test plan',
304
+ steps: [
305
+ {
306
+ order: 1,
307
+ description: 'Step 1',
308
+ target_file: 'src/a.ts',
309
+ mode: 'create',
310
+ depends_on: [2, 3, 4, 5],
311
+ completed: false,
312
+ },
313
+ ],
314
+ estimated_complexity: 'small',
315
+ risks: [],
316
+ };
317
+
318
+ const risks = identifyRisks(plan);
319
+
320
+ expect(risks.some(r => r.includes('complex dependencies'))).toBe(true);
321
+ });
322
+
323
+ it('should identify large tasks with many steps', () => {
324
+ const steps: TaskStep[] = Array.from({ length: 12 }, (_, i) => ({
325
+ order: i + 1,
326
+ description: `Step ${i + 1}`,
327
+ target_file: `src/file${i + 1}.ts`,
328
+ mode: 'create' as const,
329
+ depends_on: [],
330
+ completed: false,
331
+ }));
332
+
333
+ const plan: TaskPlan = {
334
+ summary: 'Large task',
335
+ steps,
336
+ estimated_complexity: 'large',
337
+ risks: [],
338
+ };
339
+
340
+ const risks = identifyRisks(plan);
341
+
342
+ expect(risks.some(r => r.includes('Large task'))).toBe(true);
343
+ });
344
+
345
+ it('should keep existing risks from plan', () => {
346
+ const plan: TaskPlan = {
347
+ summary: 'Test plan',
348
+ steps: [],
349
+ estimated_complexity: 'small',
350
+ risks: ['Existing risk 1', 'Existing risk 2'],
351
+ };
352
+
353
+ const risks = identifyRisks(plan);
354
+
355
+ expect(risks).toContain('Existing risk 1');
356
+ expect(risks).toContain('Existing risk 2');
357
+ });
358
+ });
359
+ });
package/tsconfig.json CHANGED
@@ -14,8 +14,8 @@
14
14
  "declaration": true,
15
15
  "declarationMap": true,
16
16
  "sourceMap": true,
17
- "noUnusedLocals": true,
18
- "noUnusedParameters": true,
17
+ "noUnusedLocals": false,
18
+ "noUnusedParameters": false,
19
19
  "noImplicitReturns": true,
20
20
  "noFallthroughCasesInSwitch": true
21
21
  },