@stackmemoryai/stackmemory 1.10.5 → 1.14.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 (225) hide show
  1. package/LICENSE +131 -64
  2. package/README.md +107 -24
  3. package/bin/claude-sm +16 -1
  4. package/bin/claude-smd +16 -1
  5. package/bin/codex-smd +16 -1
  6. package/bin/gemini-sm +16 -1
  7. package/bin/hermes-sm +21 -0
  8. package/bin/hermes-smd +21 -0
  9. package/bin/opencode-sm +16 -1
  10. package/dist/src/cli/claude-sm.js +266 -84
  11. package/dist/src/cli/codex-sm.js +225 -33
  12. package/dist/src/cli/commands/bench.js +209 -2
  13. package/dist/src/cli/commands/brain.js +206 -0
  14. package/dist/src/cli/commands/cache.js +126 -0
  15. package/dist/src/cli/commands/company-os.js +184 -0
  16. package/dist/src/cli/commands/context.js +5 -0
  17. package/dist/src/cli/commands/daemon.js +41 -0
  18. package/dist/src/cli/commands/handoff.js +40 -9
  19. package/dist/src/cli/commands/onboard.js +70 -3
  20. package/dist/src/cli/commands/operator.js +127 -0
  21. package/dist/src/cli/commands/optimize.js +117 -0
  22. package/dist/src/cli/commands/orchestrate.js +232 -5
  23. package/dist/src/cli/commands/orchestrator.js +315 -26
  24. package/dist/src/cli/commands/pack.js +322 -0
  25. package/dist/src/cli/commands/patterns.js +254 -0
  26. package/dist/src/cli/commands/portal.js +161 -0
  27. package/dist/src/cli/commands/scaffold.js +92 -0
  28. package/dist/src/cli/commands/search.js +40 -1
  29. package/dist/src/cli/commands/setup.js +178 -11
  30. package/dist/src/cli/commands/skills.js +10 -1
  31. package/dist/src/cli/commands/state.js +265 -0
  32. package/dist/src/cli/commands/sync.js +253 -0
  33. package/dist/src/cli/commands/tasks.js +130 -1
  34. package/dist/src/cli/commands/vision.js +221 -0
  35. package/dist/src/cli/gemini-sm.js +19 -29
  36. package/dist/src/cli/hermes-sm.js +224 -0
  37. package/dist/src/cli/index.js +105 -39
  38. package/dist/src/cli/opencode-sm.js +38 -21
  39. package/dist/src/cli/utils/determinism-watcher.js +66 -0
  40. package/dist/src/cli/utils/real-cli-bin.js +116 -0
  41. package/dist/src/core/brain/brain-store.js +187 -0
  42. package/dist/src/core/brain/brain-sync.js +193 -0
  43. package/dist/src/core/brain/index.js +78 -0
  44. package/dist/src/core/brain/types.js +10 -0
  45. package/dist/src/core/cache/content-cache.js +238 -0
  46. package/dist/src/{integrations/diffmem → core/cache}/index.js +5 -5
  47. package/dist/src/core/cache/token-estimator.js +39 -0
  48. package/dist/src/core/config/feature-flags.js +2 -6
  49. package/dist/src/core/context/frame-database.js +79 -27
  50. package/dist/src/core/context/recursive-context-manager.js +1 -1
  51. package/dist/src/core/context/rehydration.js +2 -1
  52. package/dist/src/core/cross-search/cross-project-search.js +269 -0
  53. package/dist/src/core/cross-search/index.js +10 -0
  54. package/dist/src/core/database/sqlite-adapter.js +14 -84
  55. package/dist/src/core/extensions/provider-adapter.js +5 -0
  56. package/dist/src/core/models/model-router.js +54 -2
  57. package/dist/src/core/models/provider-pricing.js +58 -4
  58. package/dist/src/core/monitoring/logger.js +2 -1
  59. package/dist/src/core/optimization/trace-optimizer.js +413 -0
  60. package/dist/src/core/patterns/index.js +22 -0
  61. package/dist/src/core/patterns/pattern-applier.js +39 -0
  62. package/dist/src/core/patterns/pattern-observer.js +157 -0
  63. package/dist/src/core/patterns/pattern-store.js +259 -0
  64. package/dist/src/core/patterns/types.js +19 -0
  65. package/dist/src/core/provenance/confidence-scorer.js +128 -0
  66. package/dist/src/core/provenance/index.js +40 -0
  67. package/dist/src/core/provenance/provenance-store.js +194 -0
  68. package/dist/src/core/provenance/types.js +82 -0
  69. package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
  70. package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
  71. package/dist/src/core/session/project-handoff.js +64 -0
  72. package/dist/src/core/session/session-manager.js +28 -0
  73. package/dist/src/core/shared-state/canonical-store.js +564 -0
  74. package/dist/src/core/skill-packs/index.js +18 -0
  75. package/dist/src/core/skill-packs/parser.js +42 -0
  76. package/dist/src/core/skill-packs/registry.js +224 -0
  77. package/dist/src/core/skill-packs/types.js +79 -0
  78. package/dist/src/core/storage/cloud-sync-manager.js +116 -0
  79. package/dist/src/core/storage/cloud-sync.js +574 -0
  80. package/dist/src/core/storage/two-tier-storage.js +5 -1
  81. package/dist/src/core/tasks/master-tasks-template.js +43 -0
  82. package/dist/src/core/tasks/md-task-parser.js +138 -0
  83. package/dist/src/core/trace/trace-event-store.js +282 -0
  84. package/dist/src/core/vision/index.js +27 -0
  85. package/dist/src/core/vision/signals.js +79 -0
  86. package/dist/src/core/vision/types.js +22 -0
  87. package/dist/src/core/vision/vision-file.js +146 -0
  88. package/dist/src/core/vision/vision-loop.js +220 -0
  89. package/dist/src/core/wiki/wiki-compiler.js +103 -1
  90. package/dist/src/daemon/daemon-config.js +52 -0
  91. package/dist/src/daemon/services/desire-path-service.js +566 -0
  92. package/dist/src/daemon/services/github-service.js +126 -0
  93. package/dist/src/daemon/services/research-stream-service.js +320 -0
  94. package/dist/src/daemon/services/telemetry-service.js +192 -0
  95. package/dist/src/daemon/unified-daemon.js +58 -1
  96. package/dist/src/features/browser/cli-browser-agent.js +417 -0
  97. package/dist/src/features/browser/stagehand-workflows.js +578 -0
  98. package/dist/src/features/operator/adapter-factory.js +62 -0
  99. package/dist/src/features/operator/browser-adapter.js +109 -0
  100. package/dist/src/features/operator/desktop-adapter.js +125 -0
  101. package/dist/src/features/operator/index.js +39 -0
  102. package/dist/src/features/operator/llm-decision.js +137 -0
  103. package/dist/src/features/operator/operator-logger.js +92 -0
  104. package/dist/src/features/operator/overnight-runner.js +327 -0
  105. package/dist/src/features/operator/screen-adapter.js +91 -0
  106. package/dist/src/features/operator/session-manager.js +127 -0
  107. package/dist/src/features/operator/state-machine.js +227 -0
  108. package/dist/src/features/operator/task-queue.js +81 -0
  109. package/dist/src/features/portal/index.js +26 -0
  110. package/dist/src/features/portal/server.js +240 -0
  111. package/dist/src/features/portal/types.js +14 -0
  112. package/dist/src/features/portal/ui.js +195 -0
  113. package/dist/src/features/sweep/pty-wrapper.js +13 -5
  114. package/dist/src/features/tasks/task-aware-context.js +2 -1
  115. package/dist/src/features/tui/simple-monitor.js +0 -23
  116. package/dist/src/features/tui/swarm-monitor.js +8 -66
  117. package/dist/src/features/web/client/hooks/use-socket.js +12 -0
  118. package/dist/src/{core/merge/index.js → features/web/client/lib/utils.js} +8 -4
  119. package/dist/src/features/web/client/next-env.d.js +4 -0
  120. package/dist/src/features/web/client/stores/session-store.js +12 -0
  121. package/dist/src/features/web/server/gcp-billing.js +76 -0
  122. package/dist/src/features/web/server/index.js +10 -0
  123. package/dist/src/features/web/server/spend-calculator.js +228 -0
  124. package/dist/src/hooks/schemas.js +6 -1
  125. package/dist/src/integrations/anthropic/client.js +3 -2
  126. package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
  127. package/dist/src/integrations/claude-code/subagent-client.js +307 -11
  128. package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
  129. package/dist/src/integrations/github/pr-state.js +158 -0
  130. package/dist/src/integrations/linear/client.js +4 -1
  131. package/dist/src/integrations/linear/webhook-retry.js +196 -0
  132. package/dist/src/integrations/linear/webhook-server.js +18 -22
  133. package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
  134. package/dist/src/integrations/mcp/handlers/index.js +40 -84
  135. package/dist/src/integrations/mcp/server.js +542 -641
  136. package/dist/src/integrations/mcp/tool-alias-registry.js +297 -0
  137. package/dist/src/integrations/mcp/tool-definitions.js +152 -682
  138. package/dist/src/mcp/stackmemory-mcp-server.js +571 -231
  139. package/dist/src/orchestrators/multimodal/determinism.js +244 -0
  140. package/dist/src/orchestrators/multimodal/harness.js +149 -78
  141. package/dist/src/orchestrators/multimodal/providers.js +44 -3
  142. package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
  143. package/dist/src/utils/hook-installer.js +0 -8
  144. package/dist/src/utils/process-cleanup.js +1 -7
  145. package/docs/README.md +42 -0
  146. package/docs/guides/README_INSTALL.md +208 -0
  147. package/package.json +27 -9
  148. package/packs/coding/python-fastapi/instructions.md +60 -0
  149. package/packs/coding/python-fastapi/pack.yaml +28 -0
  150. package/packs/coding/typescript-react/instructions.md +47 -0
  151. package/packs/coding/typescript-react/pack.yaml +28 -0
  152. package/packs/core/commands/capture.md +32 -0
  153. package/packs/core/commands/learn.md +73 -0
  154. package/packs/core/commands/next.md +36 -0
  155. package/packs/core/commands/restart.md +58 -0
  156. package/packs/core/commands/restore.md +29 -0
  157. package/packs/core/commands/start.md +57 -0
  158. package/packs/core/commands/stop.md +65 -0
  159. package/packs/core/commands/summary.md +40 -0
  160. package/packs/core/manifest.json +24 -0
  161. package/packs/ops/decision-recovery/instructions.md +65 -0
  162. package/packs/ops/decision-recovery/pack.yaml +89 -0
  163. package/scripts/claude-code-wrapper.sh +11 -0
  164. package/scripts/claude-sm-setup.sh +12 -1
  165. package/scripts/codex-wrapper.sh +11 -0
  166. package/scripts/git-hooks/branch-context-manager.sh +11 -0
  167. package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
  168. package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
  169. package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
  170. package/scripts/hooks/cleanup-shell.sh +12 -1
  171. package/scripts/hooks/task-complete.sh +12 -1
  172. package/scripts/install-code-execution-hooks.sh +12 -1
  173. package/scripts/install-sweep-hook.sh +12 -0
  174. package/scripts/install.sh +11 -0
  175. package/scripts/opencode-wrapper.sh +11 -0
  176. package/scripts/portal/cloud-init.yaml +69 -0
  177. package/scripts/portal/setup.sh +69 -0
  178. package/scripts/portal/stackmemory-portal.service +34 -0
  179. package/scripts/setup-claude-integration.sh +12 -1
  180. package/scripts/smoke-init-db.sh +23 -0
  181. package/scripts/stackmemory-daemon.sh +11 -0
  182. package/scripts/verify-dist.cjs +11 -4
  183. package/dist/src/cli/commands/ralph.js +0 -1053
  184. package/dist/src/cli/commands/team.js +0 -168
  185. package/dist/src/core/context/shared-context-layer.js +0 -620
  186. package/dist/src/core/context/stack-merge-resolver.js +0 -748
  187. package/dist/src/core/merge/conflict-detector.js +0 -430
  188. package/dist/src/core/merge/resolution-engine.js +0 -557
  189. package/dist/src/core/merge/stack-diff.js +0 -531
  190. package/dist/src/core/merge/unified-merge-resolver.js +0 -302
  191. package/dist/src/hooks/diffmem-hooks.js +0 -376
  192. package/dist/src/integrations/diffmem/client.js +0 -208
  193. package/dist/src/integrations/diffmem/config.js +0 -14
  194. package/dist/src/integrations/greptile/client.js +0 -101
  195. package/dist/src/integrations/greptile/config.js +0 -14
  196. package/dist/src/integrations/greptile/index.js +0 -11
  197. package/dist/src/integrations/mcp/handlers/cord-handlers.js +0 -397
  198. package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
  199. package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
  200. package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
  201. package/dist/src/integrations/mcp/handlers/team-handlers.js +0 -211
  202. package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
  203. package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
  204. package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -391
  205. package/dist/src/integrations/ralph/index.js +0 -17
  206. package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -435
  207. package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
  208. package/dist/src/integrations/ralph/loopmax.js +0 -488
  209. package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
  210. package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
  211. package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
  212. package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
  213. package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
  214. package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
  215. package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
  216. package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
  217. package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
  218. package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
  219. package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1007
  220. package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
  221. package/scripts/ralph-loop-implementation.js +0 -404
  222. /package/dist/src/core/{merge → cache}/types.js +0 -0
  223. /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
  224. /package/dist/src/{integrations/greptile/types.js → core/trace/trace-event.js} +0 -0
  225. /package/dist/src/{integrations/ralph → features/operator}/types.js +0 -0
@@ -1,508 +0,0 @@
1
- import { fileURLToPath as __fileURLToPath } from 'url';
2
- import { dirname as __pathDirname } from 'path';
3
- const __filename = __fileURLToPath(import.meta.url);
4
- const __dirname = __pathDirname(__filename);
5
- import { v4 as uuidv4 } from "uuid";
6
- import { logger } from "../../../core/monitoring/logger.js";
7
- import { FrameManager } from "../../../core/context/index.js";
8
- import { sessionManager } from "../../../core/session/index.js";
9
- import { RalphStackMemoryBridge } from "../bridge/ralph-stackmemory-bridge.js";
10
- class MultiLoopOrchestrator {
11
- frameManager;
12
- activeTasks = /* @__PURE__ */ new Map();
13
- activeLoops = /* @__PURE__ */ new Map();
14
- config;
15
- constructor(config) {
16
- this.config = {
17
- maxConcurrentLoops: 3,
18
- dependencyResolutionTimeout: 3e4,
19
- // 30 seconds
20
- enableAdaptivePlanning: true,
21
- sharedContextEnabled: true,
22
- fallbackStrategy: "sequential",
23
- ...config
24
- };
25
- logger.info("Multi-loop orchestrator initialized", this.config);
26
- }
27
- async initialize() {
28
- try {
29
- await sessionManager.initialize();
30
- const session = await sessionManager.getOrCreateSession({});
31
- if (session.database) {
32
- this.frameManager = new FrameManager(
33
- session.database,
34
- session.projectId
35
- );
36
- }
37
- logger.info("Orchestrator initialized successfully");
38
- } catch (error) {
39
- logger.error("Failed to initialize orchestrator", error);
40
- throw error;
41
- }
42
- }
43
- /**
44
- * Break down complex task into manageable loops
45
- */
46
- async orchestrateComplexTask(description, criteria, options) {
47
- logger.info("Orchestrating complex task", {
48
- task: description.substring(0, 100),
49
- criteriaCount: criteria.length,
50
- maxLoops: options?.maxLoops || this.config.maxConcurrentLoops
51
- });
52
- const orchestrationId = uuidv4();
53
- try {
54
- const breakdown = options?.customBreakdown || await this.analyzeAndBreakdownTask(description, criteria);
55
- const executionPlan = await this.createExecutionPlan(breakdown, options);
56
- const dependencyErrors = this.validateDependencies(executionPlan);
57
- if (dependencyErrors.length > 0) {
58
- throw new Error(`Dependency errors: ${dependencyErrors.join(", ")}`);
59
- }
60
- const orchestratedTask = {
61
- id: orchestrationId,
62
- description,
63
- breakdown,
64
- executionPlan,
65
- status: "planning",
66
- startTime: Date.now(),
67
- loops: /* @__PURE__ */ new Map(),
68
- sharedContext: {}
69
- };
70
- this.activeTasks.set(orchestrationId, orchestratedTask);
71
- const result = await this.executeOrchestration(orchestratedTask);
72
- logger.info("Complex task orchestration completed", {
73
- orchestrationId,
74
- status: result.success ? "success" : "failure",
75
- loopsExecuted: result.completedLoops.length,
76
- duration: Date.now() - orchestratedTask.startTime
77
- });
78
- return result;
79
- } catch (error) {
80
- logger.error("Orchestration failed", error);
81
- throw error;
82
- } finally {
83
- this.activeTasks.delete(orchestrationId);
84
- }
85
- }
86
- /**
87
- * Execute coordinated parallel loops
88
- */
89
- async executeParallelLoops(tasks, coordination) {
90
- logger.info(`Executing ${tasks.length} parallel loops`);
91
- const execution = {
92
- id: uuidv4(),
93
- tasks,
94
- startTime: Date.now(),
95
- results: /* @__PURE__ */ new Map(),
96
- sharedState: coordination?.sharedState || {}
97
- };
98
- const promises = tasks.map(
99
- (task) => this.executeParallelTask(task, execution)
100
- );
101
- try {
102
- await Promise.allSettled(promises);
103
- execution.endTime = Date.now();
104
- execution.status = Array.from(execution.results.values()).every(
105
- (r) => r.success
106
- ) ? "success" : "partial";
107
- return execution;
108
- } catch (error) {
109
- logger.error("Parallel execution failed", error);
110
- execution.status = "failed";
111
- execution.error = error.message;
112
- return execution;
113
- }
114
- }
115
- /**
116
- * Analyze and break down complex task
117
- */
118
- async analyzeAndBreakdownTask(description, criteria) {
119
- const complexity = this.assessTaskComplexity(description);
120
- if (complexity.score < 5) {
121
- return [
122
- {
123
- id: uuidv4(),
124
- title: description,
125
- description,
126
- criteria,
127
- priority: 1,
128
- estimatedIterations: 3,
129
- dependencies: [],
130
- type: "single"
131
- }
132
- ];
133
- }
134
- const subtasks = [];
135
- if (this.needsSetup(description)) {
136
- subtasks.push({
137
- id: uuidv4(),
138
- title: "Project Setup",
139
- description: "Set up project structure and dependencies",
140
- criteria: ["Project structure created", "Dependencies installed"],
141
- priority: 1,
142
- estimatedIterations: 2,
143
- dependencies: [],
144
- type: "setup"
145
- });
146
- }
147
- const coreTask = this.extractCoreTask(description);
148
- if (coreTask) {
149
- subtasks.push({
150
- id: uuidv4(),
151
- title: "Core Implementation",
152
- description: coreTask,
153
- criteria: criteria.filter(
154
- (c) => c.toLowerCase().includes("function") || c.toLowerCase().includes("implement")
155
- ),
156
- priority: 2,
157
- estimatedIterations: 5,
158
- dependencies: subtasks.length > 0 ? [subtasks[0].id] : [],
159
- type: "implementation"
160
- });
161
- }
162
- if (this.needsTesting(criteria)) {
163
- subtasks.push({
164
- id: uuidv4(),
165
- title: "Testing Implementation",
166
- description: "Create comprehensive tests",
167
- criteria: criteria.filter((c) => c.toLowerCase().includes("test")),
168
- priority: 3,
169
- estimatedIterations: 3,
170
- dependencies: subtasks.length > 0 ? [subtasks[subtasks.length - 1].id] : [],
171
- type: "testing"
172
- });
173
- }
174
- if (this.needsDocumentation(criteria)) {
175
- subtasks.push({
176
- id: uuidv4(),
177
- title: "Documentation",
178
- description: "Create documentation and examples",
179
- criteria: criteria.filter((c) => c.toLowerCase().includes("doc")),
180
- priority: 4,
181
- estimatedIterations: 2,
182
- dependencies: [],
183
- type: "documentation"
184
- });
185
- }
186
- return subtasks.length > 0 ? subtasks : [
187
- {
188
- id: uuidv4(),
189
- title: description,
190
- description,
191
- criteria,
192
- priority: 1,
193
- estimatedIterations: Math.min(8, Math.max(3, complexity.score)),
194
- dependencies: [],
195
- type: "single"
196
- }
197
- ];
198
- }
199
- /**
200
- * Create execution plan from breakdown
201
- */
202
- async createExecutionPlan(breakdown, options) {
203
- const plan = {
204
- phases: [],
205
- totalEstimatedTime: 0,
206
- parallelizable: !options?.forceSequential && breakdown.length > 1
207
- };
208
- if (options?.forceSequential || !this.canExecuteInParallel(breakdown)) {
209
- plan.phases = breakdown.map((task, index) => ({
210
- id: `phase-${index + 1}`,
211
- tasks: [task],
212
- dependencies: index > 0 ? [`phase-${index}`] : [],
213
- parallelExecution: false
214
- }));
215
- } else {
216
- const phases = this.groupTasksByDependencies(breakdown);
217
- plan.phases = phases;
218
- }
219
- plan.totalEstimatedTime = plan.phases.reduce(
220
- (sum, phase) => sum + Math.max(...phase.tasks.map((t) => t.estimatedIterations)) * 3e4,
221
- // 30s per iteration
222
- 0
223
- );
224
- return plan;
225
- }
226
- /**
227
- * Execute the orchestration plan
228
- */
229
- async executeOrchestration(task) {
230
- const result = {
231
- orchestrationId: task.id,
232
- success: false,
233
- completedLoops: [],
234
- failedLoops: [],
235
- totalDuration: 0,
236
- insights: []
237
- };
238
- try {
239
- task.status = "executing";
240
- for (const phase of task.executionPlan.phases) {
241
- logger.info(
242
- `Executing phase ${phase.id} with ${phase.tasks.length} tasks`
243
- );
244
- if (phase.parallelExecution && phase.tasks.length > 1) {
245
- const parallelResult = await this.executeParallelLoops(phase.tasks);
246
- for (const [_taskId, taskResult] of parallelResult.results) {
247
- if (taskResult.success) {
248
- result.completedLoops.push(taskResult.loopId);
249
- } else {
250
- result.failedLoops.push({
251
- loopId: taskResult.loopId,
252
- error: taskResult.error || "Unknown error"
253
- });
254
- }
255
- }
256
- } else {
257
- for (const phaseTask of phase.tasks) {
258
- const loopResult = await this.executeTaskLoop(phaseTask, task);
259
- if (loopResult.success) {
260
- result.completedLoops.push(loopResult.loopId);
261
- if (this.config.sharedContextEnabled) {
262
- await this.updateSharedContext(task, loopResult);
263
- }
264
- } else {
265
- result.failedLoops.push({
266
- loopId: loopResult.loopId,
267
- error: loopResult.error || "Unknown error"
268
- });
269
- if (this.config.fallbackStrategy === "abort") {
270
- throw new Error(`Task failed: ${loopResult.error}`);
271
- }
272
- }
273
- }
274
- }
275
- }
276
- task.status = "completed";
277
- result.success = result.failedLoops.length === 0;
278
- result.totalDuration = Date.now() - task.startTime;
279
- result.insights = this.generateOrchestrationInsights(task, result);
280
- return result;
281
- } catch (error) {
282
- task.status = "failed";
283
- result.success = false;
284
- result.error = error.message;
285
- return result;
286
- }
287
- }
288
- /**
289
- * Execute a single task as a Ralph loop
290
- */
291
- async executeTaskLoop(taskBreakdown, orchestratedTask) {
292
- try {
293
- const bridge = new RalphStackMemoryBridge({
294
- baseDir: `.ralph-${taskBreakdown.id}`,
295
- maxIterations: taskBreakdown.estimatedIterations * 2,
296
- // Allow extra iterations
297
- useStackMemory: true
298
- });
299
- await bridge.initialize({
300
- task: taskBreakdown.description,
301
- criteria: taskBreakdown.criteria.join("\n")
302
- });
303
- this.activeLoops.set(taskBreakdown.id, bridge);
304
- orchestratedTask.loops.set(taskBreakdown.id, {
305
- bridge,
306
- status: "running",
307
- startTime: Date.now()
308
- });
309
- await bridge.run();
310
- const loopInfo = orchestratedTask.loops.get(taskBreakdown.id);
311
- if (loopInfo) {
312
- loopInfo.status = "completed";
313
- loopInfo.endTime = Date.now();
314
- }
315
- this.activeLoops.delete(taskBreakdown.id);
316
- return { success: true, loopId: taskBreakdown.id };
317
- } catch (error) {
318
- logger.error(`Task loop failed: ${taskBreakdown.title}`, error);
319
- const loopInfo = orchestratedTask.loops.get(taskBreakdown.id);
320
- if (loopInfo) {
321
- loopInfo.status = "failed";
322
- loopInfo.error = error.message;
323
- loopInfo.endTime = Date.now();
324
- }
325
- this.activeLoops.delete(taskBreakdown.id);
326
- return {
327
- success: false,
328
- loopId: taskBreakdown.id,
329
- error: error.message
330
- };
331
- }
332
- }
333
- /**
334
- * Execute a task in parallel context
335
- */
336
- async executeParallelTask(task, execution) {
337
- try {
338
- const result = await this.executeTaskLoop(task, {
339
- id: execution.id,
340
- description: `Parallel task: ${task.title}`,
341
- breakdown: [task],
342
- executionPlan: {
343
- phases: [],
344
- totalEstimatedTime: 0,
345
- parallelizable: false
346
- },
347
- status: "executing",
348
- startTime: execution.startTime,
349
- loops: /* @__PURE__ */ new Map(),
350
- sharedContext: execution.sharedState
351
- });
352
- execution.results.set(task.id, result);
353
- } catch (error) {
354
- execution.results.set(task.id, {
355
- success: false,
356
- loopId: task.id,
357
- error: error.message
358
- });
359
- }
360
- }
361
- /**
362
- * Update shared context between tasks
363
- */
364
- async updateSharedContext(orchestratedTask, loopResult) {
365
- logger.debug("Updating shared context", {
366
- orchestrationId: orchestratedTask.id,
367
- loopId: loopResult.loopId
368
- });
369
- }
370
- /**
371
- * Generate insights from orchestration
372
- */
373
- generateOrchestrationInsights(task, result) {
374
- const insights = [];
375
- const avgLoopDuration = Array.from(task.loops.values()).filter((l) => l.endTime && l.startTime).map((l) => l.endTime - l.startTime).reduce((sum, duration) => sum + duration, 0) / task.loops.size;
376
- if (avgLoopDuration > 0) {
377
- insights.push(
378
- `Average loop duration: ${Math.round(avgLoopDuration / 1e3)}s`
379
- );
380
- }
381
- const successRate = result.completedLoops.length / (result.completedLoops.length + result.failedLoops.length);
382
- insights.push(`Success rate: ${Math.round(successRate * 100)}%`);
383
- if (task.breakdown.length > 3) {
384
- insights.push(
385
- "Complex task benefited from breakdown into multiple loops"
386
- );
387
- }
388
- return insights;
389
- }
390
- // Helper methods for task analysis
391
- assessTaskComplexity(description) {
392
- const factors = [];
393
- let score = 1;
394
- if (description.length > 200) {
395
- score += 2;
396
- factors.push("long description");
397
- }
398
- if (description.includes("and")) {
399
- score += 1;
400
- factors.push("multiple requirements");
401
- }
402
- if (description.toLowerCase().includes("test")) {
403
- score += 2;
404
- factors.push("testing required");
405
- }
406
- if (description.toLowerCase().includes("document")) {
407
- score += 1;
408
- factors.push("documentation needed");
409
- }
410
- if (description.toLowerCase().includes("refactor")) {
411
- score += 3;
412
- factors.push("refactoring complexity");
413
- }
414
- return { score, factors };
415
- }
416
- needsSetup(description) {
417
- const setupKeywords = [
418
- "project",
419
- "initialize",
420
- "setup",
421
- "scaffold",
422
- "create structure"
423
- ];
424
- return setupKeywords.some(
425
- (keyword) => description.toLowerCase().includes(keyword)
426
- );
427
- }
428
- needsTesting(criteria) {
429
- return criteria.some((c) => c.toLowerCase().includes("test"));
430
- }
431
- needsDocumentation(criteria) {
432
- return criteria.some((c) => c.toLowerCase().includes("doc"));
433
- }
434
- extractCoreTask(description) {
435
- const sentences = description.split(".");
436
- return sentences.find(
437
- (s) => s.toLowerCase().includes("implement") || s.toLowerCase().includes("create") || s.toLowerCase().includes("add")
438
- ) || null;
439
- }
440
- canExecuteInParallel(breakdown) {
441
- return breakdown.some((task) => task.dependencies.length === 0);
442
- }
443
- groupTasksByDependencies(breakdown) {
444
- const phases = [];
445
- const processed = /* @__PURE__ */ new Set();
446
- while (processed.size < breakdown.length) {
447
- const readyTasks = breakdown.filter(
448
- (task) => !processed.has(task.id) && task.dependencies.every((dep) => processed.has(dep))
449
- );
450
- if (readyTasks.length === 0) break;
451
- phases.push({
452
- id: `phase-${phases.length + 1}`,
453
- tasks: readyTasks,
454
- dependencies: phases.length > 0 ? [`phase-${phases.length}`] : [],
455
- parallelExecution: readyTasks.length > 1
456
- });
457
- readyTasks.forEach((task) => processed.add(task.id));
458
- }
459
- return phases;
460
- }
461
- validateDependencies(plan) {
462
- const errors = [];
463
- const allTaskIds = new Set(
464
- plan.phases.flatMap((phase) => phase.tasks.map((task) => task.id))
465
- );
466
- for (const phase of plan.phases) {
467
- for (const task of phase.tasks) {
468
- for (const dep of task.dependencies) {
469
- if (!allTaskIds.has(dep)) {
470
- errors.push(`Task ${task.id} depends on non-existent task ${dep}`);
471
- }
472
- }
473
- }
474
- }
475
- return errors;
476
- }
477
- /**
478
- * Monitor orchestration progress
479
- */
480
- getOrchestrationStatus(orchestrationId) {
481
- return this.activeTasks.get(orchestrationId) || null;
482
- }
483
- /**
484
- * Stop orchestration
485
- */
486
- async stopOrchestration(orchestrationId) {
487
- const task = this.activeTasks.get(orchestrationId);
488
- if (!task) return;
489
- for (const [loopId, loopInfo] of task.loops) {
490
- if (loopInfo.status === "running") {
491
- try {
492
- loopInfo.status = "stopped";
493
- this.activeLoops.delete(loopId);
494
- } catch (error) {
495
- logger.error(`Failed to stop loop ${loopId}`, error);
496
- }
497
- }
498
- }
499
- task.status = "stopped";
500
- this.activeTasks.delete(orchestrationId);
501
- logger.info("Orchestration stopped", { orchestrationId });
502
- }
503
- }
504
- const multiLoopOrchestrator = new MultiLoopOrchestrator();
505
- export {
506
- MultiLoopOrchestrator,
507
- multiLoopOrchestrator
508
- };