claude-mycelium 2.0.0 → 2.2.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 (208) 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/.agent-meta/tasks/_active.json +4 -0
  5. package/.agent-meta/tasks/task_0657b028-05a0-4b0c-b0b9-a4eae3d66cd9.json +168 -0
  6. package/.claude/memory.db +0 -0
  7. package/.claude/settings.local.json +4 -1
  8. package/README.md +85 -233
  9. package/SECURITY.md +145 -0
  10. package/dist/agent/task-worker.d.ts +11 -0
  11. package/dist/agent/task-worker.d.ts.map +1 -0
  12. package/dist/agent/task-worker.js +173 -0
  13. package/dist/agent/task-worker.js.map +1 -0
  14. package/dist/agent/worker.d.ts +8 -0
  15. package/dist/agent/worker.d.ts.map +1 -0
  16. package/dist/agent/worker.js +97 -0
  17. package/dist/agent/worker.js.map +1 -0
  18. package/dist/bin.d.ts +7 -0
  19. package/dist/bin.d.ts.map +1 -0
  20. package/dist/bin.js +11 -0
  21. package/dist/bin.js.map +1 -0
  22. package/dist/cli/cost.d.ts +10 -0
  23. package/dist/cli/cost.d.ts.map +1 -0
  24. package/dist/cli/cost.js +163 -0
  25. package/dist/cli/cost.js.map +1 -0
  26. package/dist/cli/gc.d.ts +10 -0
  27. package/dist/cli/gc.d.ts.map +1 -0
  28. package/dist/cli/gc.js +108 -0
  29. package/dist/cli/gc.js.map +1 -0
  30. package/dist/cli/gradients.d.ts +10 -0
  31. package/dist/cli/gradients.d.ts.map +1 -0
  32. package/dist/cli/gradients.js +70 -0
  33. package/dist/cli/gradients.js.map +1 -0
  34. package/dist/cli/grow.d.ts +17 -0
  35. package/dist/cli/grow.d.ts.map +1 -0
  36. package/dist/cli/grow.js +373 -0
  37. package/dist/cli/grow.js.map +1 -0
  38. package/dist/cli/index.d.ts +17 -0
  39. package/dist/cli/index.d.ts.map +1 -0
  40. package/dist/cli/index.js +74 -0
  41. package/dist/cli/index.js.map +1 -0
  42. package/dist/cli/init.d.ts +11 -0
  43. package/dist/cli/init.d.ts.map +1 -0
  44. package/dist/cli/init.js +97 -0
  45. package/dist/cli/init.js.map +1 -0
  46. package/dist/cli/status.d.ts +10 -0
  47. package/dist/cli/status.d.ts.map +1 -0
  48. package/dist/cli/status.js +191 -0
  49. package/dist/cli/status.js.map +1 -0
  50. package/dist/coordination/file-locks.d.ts +42 -0
  51. package/dist/coordination/file-locks.d.ts.map +1 -0
  52. package/dist/coordination/file-locks.js +269 -0
  53. package/dist/coordination/file-locks.js.map +1 -0
  54. package/dist/coordination/index.d.ts +4 -0
  55. package/dist/coordination/index.d.ts.map +1 -1
  56. package/dist/coordination/index.js +4 -0
  57. package/dist/coordination/index.js.map +1 -1
  58. package/dist/coordination/inhibitors.d.ts +84 -0
  59. package/dist/coordination/inhibitors.d.ts.map +1 -0
  60. package/dist/coordination/inhibitors.js +290 -0
  61. package/dist/coordination/inhibitors.js.map +1 -0
  62. package/dist/coordination/process-manager.d.ts +73 -0
  63. package/dist/coordination/process-manager.d.ts.map +1 -0
  64. package/dist/coordination/process-manager.js +144 -0
  65. package/dist/coordination/process-manager.js.map +1 -0
  66. package/dist/core/agent-executor.d.ts +4 -1
  67. package/dist/core/agent-executor.d.ts.map +1 -1
  68. package/dist/core/agent-executor.js +38 -12
  69. package/dist/core/agent-executor.js.map +1 -1
  70. package/dist/core/change-applier.d.ts +29 -5
  71. package/dist/core/change-applier.d.ts.map +1 -1
  72. package/dist/core/change-applier.js +254 -24
  73. package/dist/core/change-applier.js.map +1 -1
  74. package/dist/core/signals/churn.d.ts.map +1 -1
  75. package/dist/core/signals/churn.js +6 -4
  76. package/dist/core/signals/churn.js.map +1 -1
  77. package/dist/core/signals/debt.d.ts.map +1 -1
  78. package/dist/core/signals/debt.js +4 -3
  79. package/dist/core/signals/debt.js.map +1 -1
  80. package/dist/cost/cost-tracker.d.ts.map +1 -1
  81. package/dist/cost/cost-tracker.js +2 -0
  82. package/dist/cost/cost-tracker.js.map +1 -1
  83. package/dist/gc/index.d.ts +17 -0
  84. package/dist/gc/index.d.ts.map +1 -0
  85. package/dist/gc/index.js +17 -0
  86. package/dist/gc/index.js.map +1 -0
  87. package/dist/gc/runner.d.ts +39 -0
  88. package/dist/gc/runner.d.ts.map +1 -0
  89. package/dist/gc/runner.js +277 -0
  90. package/dist/gc/runner.js.map +1 -0
  91. package/dist/gc/trace-compactor.d.ts +31 -0
  92. package/dist/gc/trace-compactor.d.ts.map +1 -0
  93. package/dist/gc/trace-compactor.js +162 -0
  94. package/dist/gc/trace-compactor.js.map +1 -0
  95. package/dist/index.d.ts +5 -1
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +6 -1
  98. package/dist/index.js.map +1 -1
  99. package/dist/prompts/index.d.ts +2 -1
  100. package/dist/prompts/index.d.ts.map +1 -1
  101. package/dist/prompts/index.js.map +1 -1
  102. package/dist/quarantine/explorer.d.ts +65 -0
  103. package/dist/quarantine/explorer.d.ts.map +1 -0
  104. package/dist/quarantine/explorer.js +175 -0
  105. package/dist/quarantine/explorer.js.map +1 -0
  106. package/dist/quarantine/index.d.ts +7 -0
  107. package/dist/quarantine/index.d.ts.map +1 -0
  108. package/dist/quarantine/index.js +7 -0
  109. package/dist/quarantine/index.js.map +1 -0
  110. package/dist/quarantine/manager.d.ts +75 -0
  111. package/dist/quarantine/manager.d.ts.map +1 -0
  112. package/dist/quarantine/manager.js +275 -0
  113. package/dist/quarantine/manager.js.map +1 -0
  114. package/dist/task/acceptance.d.ts +29 -0
  115. package/dist/task/acceptance.d.ts.map +1 -0
  116. package/dist/task/acceptance.js +228 -0
  117. package/dist/task/acceptance.js.map +1 -0
  118. package/dist/task/agent-coordinator.d.ts +40 -0
  119. package/dist/task/agent-coordinator.d.ts.map +1 -0
  120. package/dist/task/agent-coordinator.js +168 -0
  121. package/dist/task/agent-coordinator.js.map +1 -0
  122. package/dist/task/executor.d.ts +37 -0
  123. package/dist/task/executor.d.ts.map +1 -0
  124. package/dist/task/executor.js +462 -0
  125. package/dist/task/executor.js.map +1 -0
  126. package/dist/task/index.d.ts +12 -0
  127. package/dist/task/index.d.ts.map +1 -0
  128. package/dist/task/index.js +12 -0
  129. package/dist/task/index.js.map +1 -0
  130. package/dist/task/planner.d.ts +21 -0
  131. package/dist/task/planner.d.ts.map +1 -0
  132. package/dist/task/planner.js +253 -0
  133. package/dist/task/planner.js.map +1 -0
  134. package/dist/task/storage.d.ts +46 -0
  135. package/dist/task/storage.d.ts.map +1 -0
  136. package/dist/task/storage.js +266 -0
  137. package/dist/task/storage.js.map +1 -0
  138. package/dist/trace/trace-event.d.ts +2 -18
  139. package/dist/trace/trace-event.d.ts.map +1 -1
  140. package/dist/trace/trace-event.js +6 -6
  141. package/dist/trace/trace-event.js.map +1 -1
  142. package/dist/utils/file-utils.d.ts.map +1 -1
  143. package/dist/utils/file-utils.js +54 -15
  144. package/dist/utils/file-utils.js.map +1 -1
  145. package/docs/PHASE5_IMPLEMENTATION.md +237 -0
  146. package/docs/PHASES-3-7-COMPLETE.md +177 -0
  147. package/docs/PHASE_4_COMPLETE.md +135 -0
  148. package/docs/PHASE_7_DELIVERABLES.md +295 -0
  149. package/docs/PHASE_7_IMPLEMENTATION.md +306 -0
  150. package/docs/PHASE_7_SUMMARY.txt +195 -0
  151. package/docs/RELEASE-NOTES-v2.1.md +213 -0
  152. package/docs/ROADMAP.md +194 -107
  153. package/docs/SECURITY-AUDIT.md +387 -0
  154. package/docs/SNAPSHOT.md +59 -32
  155. package/docs/implementation/phase3-summary.md +220 -0
  156. package/package.json +27 -11
  157. package/src/agent/task-worker.ts +196 -0
  158. package/src/agent/worker.ts +111 -0
  159. package/src/bin.ts +13 -0
  160. package/src/cli/cost.ts +210 -0
  161. package/src/cli/gc.ts +138 -0
  162. package/src/cli/gradients.ts +97 -0
  163. package/src/cli/grow.ts +416 -0
  164. package/src/cli/index.ts +81 -0
  165. package/src/cli/init.ts +139 -0
  166. package/src/cli/status.ts +218 -0
  167. package/src/coordination/file-locks.ts +300 -0
  168. package/src/coordination/index.ts +4 -0
  169. package/src/coordination/inhibitors.ts +345 -0
  170. package/src/coordination/process-manager.ts +199 -0
  171. package/src/core/agent-executor.ts +37 -8
  172. package/src/core/signals/churn.ts +8 -5
  173. package/src/core/signals/debt.ts +4 -3
  174. package/src/cost/cost-tracker.ts +2 -0
  175. package/src/gc/index.ts +17 -0
  176. package/src/gc/runner.ts +314 -0
  177. package/src/gc/trace-compactor.ts +187 -0
  178. package/src/index.ts +7 -1
  179. package/src/prompts/index.ts +2 -1
  180. package/src/quarantine/explorer.ts +234 -0
  181. package/src/quarantine/index.ts +7 -0
  182. package/src/quarantine/manager.ts +336 -0
  183. package/src/task/acceptance.ts +267 -0
  184. package/src/task/agent-coordinator.ts +220 -0
  185. package/src/task/executor.ts +543 -0
  186. package/src/task/index.ts +38 -0
  187. package/src/task/planner.ts +294 -0
  188. package/src/task/storage.ts +332 -0
  189. package/src/trace/trace-event.ts +7 -26
  190. package/src/utils/file-utils.ts +61 -15
  191. package/tests/cli/gc.test.ts +206 -0
  192. package/tests/cli/init.test.ts +181 -0
  193. package/tests/cli/status.test.ts +282 -0
  194. package/tests/coordination/file-locks.test.ts +196 -0
  195. package/tests/coordination/inhibitors.test.ts +459 -0
  196. package/tests/coordination/integration.test.ts +195 -0
  197. package/tests/coordination/process-manager.test.ts +165 -0
  198. package/tests/gc/trace-compactor.test.ts +245 -0
  199. package/tests/integration/phase-7.test.ts +145 -0
  200. package/tests/quarantine/explorer.test.ts +381 -0
  201. package/tests/quarantine/manager.test.ts +399 -0
  202. package/tests/security/command-injection.test.ts +88 -0
  203. package/tests/security/path-traversal.test.ts +103 -0
  204. package/tests/task/acceptance.test.ts +411 -0
  205. package/tests/task/executor.test.ts +421 -0
  206. package/tests/task/planner.test.ts +359 -0
  207. package/tests/trace/trace-event.test.ts +62 -20
  208. package/tsconfig.json +2 -2
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Task Agent Coordinator
3
+ *
4
+ * Coordinates multi-agent execution of task steps using the mycelium
5
+ * process spawning system (Phase 3) for true RALPH-style parallelization.
6
+ *
7
+ * This replaces the simple Promise.all() approach with real agent processes
8
+ * that use file locks, inhibitors, and the full executeAgent() cycle.
9
+ */
10
+ import { fork } from 'child_process';
11
+ import { logDebug, logError, logInfo } from '../utils/logger.js';
12
+ import { randomUUID } from 'crypto';
13
+ import * as path from 'path';
14
+ import { fileURLToPath } from 'url';
15
+ import { dirname } from 'path';
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+ /**
19
+ * Spawn an agent for a specific task step
20
+ * Each agent runs as an independent process via child_process.fork()
21
+ */
22
+ export function spawnAgentForStep(task, step) {
23
+ return new Promise((resolve) => {
24
+ const agentId = `agent-${randomUUID().substring(0, 8)}`;
25
+ logDebug('Spawning agent for task step', {
26
+ agentId,
27
+ taskId: task.id,
28
+ stepOrder: step.order,
29
+ targetFile: step.target_file,
30
+ mode: step.mode,
31
+ });
32
+ // Path to the compiled task worker file
33
+ const workerPath = path.join(__dirname, '../agent/task-worker.js');
34
+ // Spawn agent process with task context
35
+ const child = fork(workerPath, [], {
36
+ env: {
37
+ ...process.env,
38
+ AGENT_ID: agentId,
39
+ TASK_ID: task.id,
40
+ STEP_ORDER: String(step.order),
41
+ TARGET_FILE: step.target_file,
42
+ MODE: step.mode,
43
+ STEP_DESCRIPTION: step.description,
44
+ },
45
+ stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
46
+ });
47
+ let result = {
48
+ stepOrder: step.order,
49
+ success: false,
50
+ exitCode: null,
51
+ };
52
+ // Set timeout (5 minutes)
53
+ const timeout = setTimeout(() => {
54
+ logError('Agent timeout', new Error('Agent timed out'), {
55
+ agentId,
56
+ stepOrder: step.order,
57
+ });
58
+ child.kill('SIGTERM');
59
+ result.error = 'Agent timed out after 5 minutes';
60
+ result.exitCode = -1;
61
+ resolve(result);
62
+ }, 300_000);
63
+ // Handle IPC messages from agent
64
+ child.on('message', (message) => {
65
+ if (message.type === 'result') {
66
+ logDebug('Agent result received', {
67
+ agentId,
68
+ stepOrder: step.order,
69
+ success: message.success,
70
+ });
71
+ result = {
72
+ stepOrder: step.order,
73
+ success: message.success,
74
+ traceId: message.traceId,
75
+ error: message.error,
76
+ exitCode: 0,
77
+ };
78
+ }
79
+ else if (message.type === 'progress') {
80
+ logInfo('Agent progress', {
81
+ agentId,
82
+ stepOrder: step.order,
83
+ message: message.message,
84
+ });
85
+ }
86
+ });
87
+ // Handle agent exit
88
+ child.on('exit', (code, signal) => {
89
+ clearTimeout(timeout);
90
+ result.exitCode = code;
91
+ logInfo('Agent exited', {
92
+ agentId,
93
+ stepOrder: step.order,
94
+ code,
95
+ signal,
96
+ success: result.success,
97
+ });
98
+ // If we didn't receive a result message, mark as failure
99
+ if (!result.success && !result.error) {
100
+ result.error = `Agent exited with code ${code}`;
101
+ }
102
+ resolve(result);
103
+ });
104
+ // Handle errors
105
+ child.on('error', (error) => {
106
+ clearTimeout(timeout);
107
+ logError('Agent error', error, {
108
+ agentId,
109
+ stepOrder: step.order,
110
+ });
111
+ result.error = error.message;
112
+ result.exitCode = -1;
113
+ resolve(result);
114
+ });
115
+ // Forward stderr for debugging
116
+ if (child.stderr) {
117
+ child.stderr.on('data', (data) => {
118
+ logDebug('Agent stderr', {
119
+ agentId,
120
+ stepOrder: step.order,
121
+ output: data.toString(),
122
+ });
123
+ });
124
+ }
125
+ });
126
+ }
127
+ /**
128
+ * Execute a wave of task steps in parallel using agent processes
129
+ * This is the true mycelium multi-agent coordination
130
+ */
131
+ export async function executeWaveWithAgents(task, wave) {
132
+ logInfo('Executing wave with agent processes', {
133
+ taskId: task.id,
134
+ waveSize: wave.length,
135
+ steps: wave.map(s => s.order),
136
+ });
137
+ // Spawn all agents in parallel
138
+ const agentPromises = wave.map(step => spawnAgentForStep(task, step));
139
+ // Wait for all agents to complete
140
+ const results = await Promise.all(agentPromises);
141
+ logInfo('Wave execution complete', {
142
+ taskId: task.id,
143
+ total: results.length,
144
+ successful: results.filter(r => r.success).length,
145
+ failed: results.filter(r => !r.success).length,
146
+ });
147
+ return results;
148
+ }
149
+ /**
150
+ * Get parallelizable steps grouped by dependency waves
151
+ * Same logic as before, but now we spawn agents for each wave
152
+ */
153
+ export function getParallelizableSteps(steps) {
154
+ const waves = [];
155
+ const completed = new Set();
156
+ while (completed.size < steps.length) {
157
+ // Find steps whose dependencies are all completed
158
+ const ready = steps.filter(step => !completed.has(step.order) &&
159
+ step.depends_on.every(dep => completed.has(dep)));
160
+ if (ready.length === 0) {
161
+ throw new Error('Circular dependency detected in task steps');
162
+ }
163
+ waves.push(ready);
164
+ ready.forEach(step => completed.add(step.order));
165
+ }
166
+ return waves;
167
+ }
168
+ //# sourceMappingURL=agent-coordinator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-coordinator.js","sourceRoot":"","sources":["../../src/task/agent-coordinator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Task Execution Implementation
3
+ * Per second-spec §12.2: Task Step Execution
4
+ *
5
+ * Executes task steps using the mycelium multi-agent system.
6
+ * Each step spawns an independent agent process that uses file locks,
7
+ * inhibitors, and the full RALPH-style executeAgent() cycle.
8
+ *
9
+ * This is TRUE multi-agent coordination as per ADR-004.
10
+ */
11
+ import { Task, TaskStep } from '../types/index.js';
12
+ /**
13
+ * Execute a complete task by running all steps in dependency order
14
+ *
15
+ * This spawns independent agent processes for each step, coordinated
16
+ * via file locks. Multiple agents can work in parallel on different
17
+ * files, implementing true RALPH-style multi-agent coordination.
18
+ */
19
+ export declare function executeTask(task: Task): Promise<Task>;
20
+ /**
21
+ * Execute a single task step
22
+ */
23
+ export declare function executeStep(task: Task, step: TaskStep): Promise<{
24
+ success: boolean;
25
+ trace_id?: string;
26
+ error?: string;
27
+ }>;
28
+ /**
29
+ * Track progress of task execution
30
+ */
31
+ export declare function trackProgress(task: Task): {
32
+ percentage: number;
33
+ completed: number;
34
+ total: number;
35
+ status: string;
36
+ };
37
+ //# sourceMappingURL=executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/task/executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAQnD;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAqF3D;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,QAAQ,GACb,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBlE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAWA"}
@@ -0,0 +1,462 @@
1
+ /**
2
+ * Task Execution Implementation
3
+ * Per second-spec §12.2: Task Step Execution
4
+ *
5
+ * Executes task steps using the mycelium multi-agent system.
6
+ * Each step spawns an independent agent process that uses file locks,
7
+ * inhibitors, and the full RALPH-style executeAgent() cycle.
8
+ *
9
+ * This is TRUE multi-agent coordination as per ADR-004.
10
+ */
11
+ import { logDebug, logError, logInfo } from '../utils/logger.js';
12
+ import { executeWaveWithAgents, } from './agent-coordinator.js';
13
+ /**
14
+ * Execute a complete task by running all steps in dependency order
15
+ *
16
+ * This spawns independent agent processes for each step, coordinated
17
+ * via file locks. Multiple agents can work in parallel on different
18
+ * files, implementing true RALPH-style multi-agent coordination.
19
+ */
20
+ export async function executeTask(task) {
21
+ logInfo('Executing task with multi-agent coordination', {
22
+ taskId: task.id,
23
+ steps: task.plan?.steps.length,
24
+ });
25
+ if (!task.plan) {
26
+ throw new Error('Cannot execute task without a plan');
27
+ }
28
+ const waves = getParallelizableSteps(task.plan.steps);
29
+ logInfo('Task execution plan', {
30
+ taskId: task.id,
31
+ totalSteps: task.plan.steps.length,
32
+ waves: waves.length,
33
+ waveSizes: waves.map(w => w.length),
34
+ });
35
+ for (let waveIndex = 0; waveIndex < waves.length; waveIndex++) {
36
+ const wave = waves[waveIndex];
37
+ logInfo('Executing wave', {
38
+ taskId: task.id,
39
+ wave: waveIndex + 1,
40
+ totalWaves: waves.length,
41
+ stepsInWave: wave.length,
42
+ });
43
+ // Execute all steps in this wave using agent processes
44
+ // Each agent runs in its own process with file locks
45
+ const results = await executeWaveWithAgents(task, wave);
46
+ // Check for failures
47
+ const failed = results.find(r => !r.success);
48
+ if (failed) {
49
+ task.status = 'failed';
50
+ task.error = failed.error || 'Agent execution failed';
51
+ logError('Task wave failed', new Error(task.error), {
52
+ taskId: task.id,
53
+ wave: waveIndex + 1,
54
+ failedStep: failed.stepOrder,
55
+ });
56
+ return task;
57
+ }
58
+ // Update completed steps
59
+ for (let i = 0; i < wave.length; i++) {
60
+ const result = results.find(r => r.stepOrder === wave[i].order);
61
+ if (result && result.success) {
62
+ wave[i].completed = true;
63
+ wave[i].trace_id = result.traceId;
64
+ task.steps_completed++;
65
+ // Track file changes
66
+ if (wave[i].mode === 'create') {
67
+ task.files_created.push(wave[i].target_file);
68
+ }
69
+ else {
70
+ if (!task.files_modified.includes(wave[i].target_file)) {
71
+ task.files_modified.push(wave[i].target_file);
72
+ }
73
+ }
74
+ if (result.traceId) {
75
+ task.traces.push(result.traceId);
76
+ }
77
+ }
78
+ }
79
+ logInfo('Wave complete', {
80
+ taskId: task.id,
81
+ wave: waveIndex + 1,
82
+ successCount: results.filter(r => r.success).length,
83
+ failureCount: results.filter(r => !r.success).length,
84
+ });
85
+ }
86
+ task.status = 'completed';
87
+ logInfo('Task execution completed', {
88
+ taskId: task.id,
89
+ stepsCompleted: task.steps_completed,
90
+ filesCreated: task.files_created.length,
91
+ filesModified: task.files_modified.length,
92
+ });
93
+ return task;
94
+ }
95
+ /**
96
+ * Execute a single task step
97
+ */
98
+ export async function executeStep(task, step) {
99
+ logDebug('Executing step', {
100
+ taskId: task.id,
101
+ stepOrder: step.order,
102
+ mode: step.mode,
103
+ file: step.target_file,
104
+ });
105
+ try {
106
+ if (step.mode === 'create') {
107
+ return await executeCreateStep(task, step);
108
+ }
109
+ else {
110
+ return await executeModifyStep(task, step);
111
+ }
112
+ }
113
+ catch (error) {
114
+ const errorMsg = error instanceof Error ? error.message : 'Unknown error';
115
+ const errorObj = error instanceof Error ? error : new Error(String(error));
116
+ logError('Step execution failed', errorObj, {
117
+ taskId: task.id,
118
+ stepOrder: step.order,
119
+ });
120
+ return { success: false, error: errorMsg };
121
+ }
122
+ }
123
+ /**
124
+ * Track progress of task execution
125
+ */
126
+ export function trackProgress(task) {
127
+ const percentage = task.steps_total > 0
128
+ ? Math.round((task.steps_completed / task.steps_total) * 100)
129
+ : 0;
130
+ return {
131
+ percentage,
132
+ completed: task.steps_completed,
133
+ total: task.steps_total,
134
+ status: task.status,
135
+ };
136
+ }
137
+ /**
138
+ * Execute a create mode step (new file)
139
+ */
140
+ async function executeCreateStep(task, step) {
141
+ // Check if file already exists
142
+ if (fileExists(step.target_file)) {
143
+ return {
144
+ success: false,
145
+ error: `Cannot create file ${step.target_file} - already exists`,
146
+ };
147
+ }
148
+ // Build prompt for file creation
149
+ const systemPrompt = buildCreateSystemPrompt();
150
+ const userPrompt = buildCreateUserPrompt(task, step);
151
+ // Call LLM to generate file content
152
+ const response = await callLLM({
153
+ prompt: userPrompt,
154
+ systemPrompt,
155
+ temperature: 0.5,
156
+ maxTokens: 4000,
157
+ });
158
+ // Extract code from response
159
+ const fileContent = extractCodeFromResponse(response.content);
160
+ if (!fileContent) {
161
+ return {
162
+ success: false,
163
+ error: 'Failed to extract code from LLM response',
164
+ };
165
+ }
166
+ // Write the file
167
+ writeFile(step.target_file, fileContent);
168
+ // Run CI to validate
169
+ const ciResult = await ciProvider.run({
170
+ additions: fileContent.split('\n').length,
171
+ deletions: 0,
172
+ files_touched: [step.target_file],
173
+ });
174
+ if (!ciResult.passed) {
175
+ // Revert - delete the file
176
+ try {
177
+ const fs = await import('fs');
178
+ fs.unlinkSync(step.target_file);
179
+ }
180
+ catch { }
181
+ return {
182
+ success: false,
183
+ error: `CI failed: ${ciResult.output}`,
184
+ };
185
+ }
186
+ // Record trace
187
+ const traceId = await recordCreateTrace(step.target_file, fileContent, response.usage, response.model, task.id);
188
+ logDebug('Create step completed', {
189
+ file: step.target_file,
190
+ lines: fileContent.split('\n').length,
191
+ traceId,
192
+ });
193
+ return { success: true, trace_id: traceId };
194
+ }
195
+ /**
196
+ * Execute a modify mode step (existing file)
197
+ */
198
+ async function executeModifyStep(task, step) {
199
+ if (!fileExists(step.target_file)) {
200
+ return {
201
+ success: false,
202
+ error: `Cannot modify file ${step.target_file} - does not exist`,
203
+ };
204
+ }
205
+ const originalContent = readFile(step.target_file);
206
+ const gradientBefore = await calculateGradient(step.target_file);
207
+ // Build prompt for modification
208
+ const systemPrompt = buildModifySystemPrompt(step.mode);
209
+ const userPrompt = buildModifyUserPrompt(task, step, originalContent);
210
+ // Call LLM to generate changes
211
+ const response = await callLLM({
212
+ prompt: userPrompt,
213
+ systemPrompt,
214
+ temperature: 0.5,
215
+ maxTokens: 4000,
216
+ });
217
+ // Extract modified content
218
+ const modifiedContent = extractCodeFromResponse(response.content);
219
+ if (!modifiedContent) {
220
+ return {
221
+ success: false,
222
+ error: 'Failed to extract modified code from LLM response',
223
+ };
224
+ }
225
+ // Apply changes
226
+ writeFile(step.target_file, modifiedContent);
227
+ // Calculate change stats
228
+ const changeSet = calculateChanges(originalContent, modifiedContent, step.target_file);
229
+ // Run CI
230
+ const ciResult = await ciProvider.run(changeSet);
231
+ if (!ciResult.passed) {
232
+ // Revert changes
233
+ writeFile(step.target_file, originalContent);
234
+ return {
235
+ success: false,
236
+ error: `CI failed: ${ciResult.output}`,
237
+ };
238
+ }
239
+ // Calculate metrics after
240
+ const gradientAfter = await calculateGradient(step.target_file);
241
+ // Record trace
242
+ const traceId = await recordModifyTrace(step.target_file, step.mode, gradientBefore, gradientAfter, changeSet, response.usage, response.model, task.id);
243
+ logDebug('Modify step completed', {
244
+ file: step.target_file,
245
+ mode: step.mode,
246
+ gradientDelta: gradientBefore.score - gradientAfter.score,
247
+ traceId,
248
+ });
249
+ return { success: true, trace_id: traceId };
250
+ }
251
+ /**
252
+ * Helper to calculate file metrics (not used in current implementation)
253
+ */
254
+ /*
255
+ async function calculateFileMetrics(filePath: string, allFiles: string[]): Promise<FileMetrics> {
256
+ const [complexity, churn, errorRate, debt, centrality] = await Promise.all([
257
+ calculateComplexity(filePath),
258
+ calculateChurn(filePath),
259
+ calculateErrorRate(filePath),
260
+ calculateDebt(filePath),
261
+ calculateCentrality(filePath),
262
+ ]);
263
+
264
+ return {
265
+ path: filePath,
266
+ complexity: complexity.normalized,
267
+ churn: churn.normalized,
268
+ error_rate: errorRate.normalized,
269
+ debt: debt.normalized,
270
+ centrality: centrality.normalized,
271
+ loc: getLineCount(filePath),
272
+ };
273
+ }
274
+ */
275
+ /**
276
+ * Get steps grouped by waves (parallelizable groups)
277
+ */
278
+ function getParallelizableSteps(steps) {
279
+ const waves = [];
280
+ const completed = new Set();
281
+ while (completed.size < steps.length) {
282
+ // Find steps whose dependencies are all completed
283
+ const ready = steps.filter(step => !completed.has(step.order) &&
284
+ step.depends_on.every(dep => completed.has(dep)));
285
+ if (ready.length === 0) {
286
+ throw new Error('Circular dependency detected in task steps');
287
+ }
288
+ waves.push(ready);
289
+ ready.forEach(step => completed.add(step.order));
290
+ }
291
+ return waves;
292
+ }
293
+ /**
294
+ * Build system prompt for create mode
295
+ */
296
+ function buildCreateSystemPrompt() {
297
+ return `You are creating a new file as part of a larger task.
298
+
299
+ Output the complete file content wrapped in triple backticks with the language identifier.
300
+
301
+ Example:
302
+ \`\`\`typescript
303
+ // File content here
304
+ \`\`\`
305
+
306
+ Requirements:
307
+ - Include all necessary imports
308
+ - Add appropriate error handling
309
+ - Include JSDoc comments for exported functions
310
+ - Follow TypeScript best practices`;
311
+ }
312
+ /**
313
+ * Build user prompt for create mode
314
+ */
315
+ function buildCreateUserPrompt(task, step) {
316
+ return `## Overall Task
317
+ ${task.description}
318
+
319
+ ## This Step
320
+ ${step.description}
321
+
322
+ ## File to Create
323
+ ${step.target_file}
324
+
325
+ ## Requirements
326
+ - Create a working implementation
327
+ - Include basic error handling
328
+ - Add type annotations
329
+ - Follow existing project patterns
330
+
331
+ Generate the complete file content.`;
332
+ }
333
+ /**
334
+ * Build system prompt for modify mode
335
+ */
336
+ function buildModifySystemPrompt(mode) {
337
+ const modeInstructions = {
338
+ error_reducer: 'Focus on fixing bugs and adding error handling. Do not refactor for style.',
339
+ complexity_reducer: 'Focus on simplifying code structure. Extract functions, reduce nesting.',
340
+ debt_payer: 'Focus on fixing lint issues and improving types. Do not change logic.',
341
+ stabilizer: 'Focus on adding tests and documentation. Do not change implementation.',
342
+ explorer: 'You may challenge assumptions and propose larger changes within constraints.',
343
+ };
344
+ return `You are modifying an existing file in ${mode} mode.
345
+
346
+ ${modeInstructions[mode]}
347
+
348
+ Output the complete modified file content wrapped in triple backticks.`;
349
+ }
350
+ /**
351
+ * Build user prompt for modify mode
352
+ */
353
+ function buildModifyUserPrompt(task, step, currentContent) {
354
+ return `## Overall Task
355
+ ${task.description}
356
+
357
+ ## This Step
358
+ ${step.description}
359
+
360
+ ## Current File Content
361
+ \`\`\`typescript
362
+ ${currentContent}
363
+ \`\`\`
364
+
365
+ Modify the file according to the step description and mode constraints.
366
+ Output the complete modified file.`;
367
+ }
368
+ /**
369
+ * Extract code from LLM response (handle markdown code blocks)
370
+ */
371
+ function extractCodeFromResponse(content) {
372
+ // Try to find code in triple backticks
373
+ const codeBlockMatch = content.match(/```(?:typescript|ts|javascript|js)?\n([\s\S]*?)\n```/);
374
+ if (codeBlockMatch) {
375
+ return codeBlockMatch[1];
376
+ }
377
+ // If no code block found, check if entire content looks like code
378
+ if (content.includes('import') || content.includes('export') || content.includes('function')) {
379
+ return content.trim();
380
+ }
381
+ return null;
382
+ }
383
+ /**
384
+ * Calculate changes between original and modified content
385
+ */
386
+ function calculateChanges(original, modified, filePath) {
387
+ const originalLines = original.split('\n');
388
+ const modifiedLines = modified.split('\n');
389
+ // Simple diff: count added and removed lines
390
+ const additions = modifiedLines.length > originalLines.length
391
+ ? modifiedLines.length - originalLines.length
392
+ : 0;
393
+ const deletions = originalLines.length > modifiedLines.length
394
+ ? originalLines.length - modifiedLines.length
395
+ : 0;
396
+ return {
397
+ additions,
398
+ deletions,
399
+ files_touched: [filePath],
400
+ };
401
+ }
402
+ /**
403
+ * Record trace for create step
404
+ */
405
+ async function recordCreateTrace(filePath, content, usage, model, taskId) {
406
+ const cost = {
407
+ tokens_in: usage.inputTokens,
408
+ tokens_out: usage.outputTokens,
409
+ model,
410
+ estimated_usd: calculateCost(model, usage.inputTokens, usage.outputTokens),
411
+ };
412
+ // For create mode, gradient goes from 0 to 0 (no improvement measured)
413
+ const trace = createTraceEvent({
414
+ filePath,
415
+ mode: 'debt_payer', // Create is treated as debt_payer for metrics
416
+ gradientBefore: 0,
417
+ gradientAfter: 0,
418
+ metabolicCost: cost.estimated_usd * 100, // Normalize
419
+ efficiency: 0,
420
+ ciPassed: true,
421
+ changes: {
422
+ additions: content.split('\n').length,
423
+ deletions: 0,
424
+ files_touched: [filePath],
425
+ },
426
+ costRecord: cost,
427
+ notes: ['File created as part of task'],
428
+ taskId,
429
+ });
430
+ await recordTraceEvent(trace);
431
+ return trace.id;
432
+ }
433
+ /**
434
+ * Record trace for modify step
435
+ */
436
+ async function recordModifyTrace(filePath, mode, gradientBefore, gradientAfter, changes, usage, model, taskId) {
437
+ const cost = {
438
+ tokens_in: usage.inputTokens,
439
+ tokens_out: usage.outputTokens,
440
+ model,
441
+ estimated_usd: calculateCost(model, usage.inputTokens, usage.outputTokens),
442
+ };
443
+ const gradientDelta = gradientBefore.score - gradientAfter.score;
444
+ const metabolicCost = cost.estimated_usd * 100; // Normalize
445
+ const efficiency = metabolicCost > 0 ? gradientDelta / metabolicCost : 0;
446
+ const trace = createTraceEvent({
447
+ filePath,
448
+ mode,
449
+ gradientBefore: gradientBefore.score,
450
+ gradientAfter: gradientAfter.score,
451
+ metabolicCost,
452
+ efficiency,
453
+ ciPassed: true,
454
+ changes,
455
+ costRecord: cost,
456
+ notes: ['Modified as part of task'],
457
+ taskId,
458
+ });
459
+ await recordTraceEvent(trace);
460
+ return trace.id;
461
+ }
462
+ //# sourceMappingURL=executor.js.map