@stackmemoryai/stackmemory 1.12.0 → 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.
- package/LICENSE +131 -64
- package/README.md +3 -1
- package/bin/claude-sm +16 -1
- package/bin/claude-smd +16 -1
- package/bin/codex-smd +16 -1
- package/bin/gemini-sm +16 -1
- package/bin/hermes-sm +21 -0
- package/bin/hermes-smd +21 -0
- package/bin/opencode-sm +16 -1
- package/dist/src/cli/codex-sm.js +51 -11
- package/dist/src/cli/commands/brain.js +206 -0
- package/dist/src/cli/commands/company-os.js +184 -0
- package/dist/src/cli/commands/context.js +5 -0
- package/dist/src/cli/commands/operator.js +127 -0
- package/dist/src/cli/commands/orchestrate.js +2 -0
- package/dist/src/cli/commands/orchestrator.js +3 -2
- package/dist/src/cli/commands/patterns.js +254 -0
- package/dist/src/cli/commands/portal.js +161 -0
- package/dist/src/cli/commands/scaffold.js +92 -0
- package/dist/src/cli/commands/setup.js +1 -4
- package/dist/src/cli/commands/sync.js +253 -0
- package/dist/src/cli/commands/tasks.js +130 -1
- package/dist/src/cli/commands/vision.js +221 -0
- package/dist/src/cli/hermes-sm.js +224 -0
- package/dist/src/cli/index.js +15 -10
- package/dist/src/cli/utils/real-cli-bin.js +72 -0
- package/dist/src/core/brain/brain-store.js +187 -0
- package/dist/src/core/brain/brain-sync.js +193 -0
- package/dist/src/core/brain/index.js +78 -0
- package/dist/src/core/brain/types.js +10 -0
- package/dist/src/core/cache/token-estimator.js +24 -1
- package/dist/src/core/config/feature-flags.js +2 -6
- package/dist/src/core/context/frame-database.js +44 -0
- package/dist/src/core/context/recursive-context-manager.js +1 -1
- package/dist/src/core/context/rehydration.js +2 -1
- package/dist/src/core/database/sqlite-adapter.js +14 -1
- package/dist/src/core/models/model-router.js +33 -1
- package/dist/src/core/models/provider-pricing.js +58 -4
- package/dist/src/core/patterns/index.js +22 -0
- package/dist/src/core/patterns/pattern-applier.js +39 -0
- package/dist/src/core/patterns/pattern-observer.js +157 -0
- package/dist/src/core/patterns/pattern-store.js +259 -0
- package/dist/src/core/patterns/types.js +19 -0
- package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
- package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
- package/dist/src/core/skill-packs/types.js +14 -1
- package/dist/src/core/storage/cloud-sync-manager.js +116 -0
- package/dist/src/core/storage/cloud-sync.js +574 -0
- package/dist/src/core/storage/two-tier-storage.js +5 -1
- package/dist/src/core/tasks/master-tasks-template.js +43 -0
- package/dist/src/core/tasks/md-task-parser.js +138 -0
- package/dist/src/core/vision/index.js +27 -0
- package/dist/src/core/vision/signals.js +79 -0
- package/dist/src/core/vision/types.js +22 -0
- package/dist/src/core/vision/vision-file.js +146 -0
- package/dist/src/core/vision/vision-loop.js +220 -0
- package/dist/src/core/wiki/wiki-compiler.js +103 -1
- package/dist/src/daemon/daemon-config.js +45 -0
- package/dist/src/daemon/services/desire-path-service.js +566 -0
- package/dist/src/daemon/services/research-stream-service.js +320 -0
- package/dist/src/daemon/services/telemetry-service.js +192 -0
- package/dist/src/daemon/unified-daemon.js +28 -1
- package/dist/src/features/browser/cli-browser-agent.js +417 -0
- package/dist/src/features/browser/stagehand-workflows.js +578 -0
- package/dist/src/features/operator/adapter-factory.js +62 -0
- package/dist/src/features/operator/browser-adapter.js +109 -0
- package/dist/src/features/operator/desktop-adapter.js +125 -0
- package/dist/src/features/operator/index.js +39 -0
- package/dist/src/features/operator/llm-decision.js +137 -0
- package/dist/src/features/operator/operator-logger.js +92 -0
- package/dist/src/features/operator/overnight-runner.js +327 -0
- package/dist/src/features/operator/screen-adapter.js +91 -0
- package/dist/src/features/operator/session-manager.js +127 -0
- package/dist/src/features/operator/state-machine.js +227 -0
- package/dist/src/features/operator/task-queue.js +81 -0
- package/dist/src/features/portal/index.js +26 -0
- package/dist/src/features/portal/server.js +240 -0
- package/dist/src/features/portal/types.js +14 -0
- package/dist/src/features/portal/ui.js +195 -0
- package/dist/src/features/tasks/task-aware-context.js +2 -1
- package/dist/src/features/tui/simple-monitor.js +0 -23
- package/dist/src/features/tui/swarm-monitor.js +8 -66
- package/dist/src/{integrations/diffmem/index.js → features/web/client/hooks/use-socket.js} +6 -5
- package/dist/src/features/web/client/lib/utils.js +12 -0
- package/dist/src/features/web/client/stores/session-store.js +12 -0
- package/dist/src/features/web/server/gcp-billing.js +76 -0
- package/dist/src/features/web/server/index.js +10 -0
- package/dist/src/features/web/server/spend-calculator.js +228 -0
- package/dist/src/hooks/schemas.js +4 -1
- package/dist/src/integrations/anthropic/client.js +3 -2
- package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
- package/dist/src/integrations/claude-code/subagent-client.js +218 -11
- package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
- package/dist/src/integrations/linear/webhook-retry.js +196 -0
- package/dist/src/integrations/linear/webhook-server.js +18 -22
- package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
- package/dist/src/integrations/mcp/handlers/index.js +27 -52
- package/dist/src/integrations/mcp/server.js +122 -335
- package/dist/src/integrations/mcp/tool-alias-registry.js +0 -73
- package/dist/src/integrations/mcp/tool-definitions.js +111 -510
- package/dist/src/mcp/stackmemory-mcp-server.js +404 -379
- package/dist/src/orchestrators/multimodal/determinism.js +2 -1
- package/dist/src/orchestrators/multimodal/harness.js +2 -1
- package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
- package/dist/src/utils/process-cleanup.js +1 -7
- package/docs/README.md +42 -0
- package/docs/guides/README_INSTALL.md +208 -0
- package/package.json +18 -9
- package/scripts/claude-code-wrapper.sh +11 -0
- package/scripts/claude-sm-setup.sh +12 -1
- package/scripts/codex-wrapper.sh +11 -0
- package/scripts/git-hooks/branch-context-manager.sh +11 -0
- package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
- package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
- package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
- package/scripts/hooks/cleanup-shell.sh +12 -1
- package/scripts/hooks/task-complete.sh +12 -1
- package/scripts/install-code-execution-hooks.sh +12 -1
- package/scripts/install-sweep-hook.sh +12 -0
- package/scripts/install.sh +11 -0
- package/scripts/opencode-wrapper.sh +11 -0
- package/scripts/portal/cloud-init.yaml +69 -0
- package/scripts/portal/setup.sh +69 -0
- package/scripts/portal/stackmemory-portal.service +34 -0
- package/scripts/setup-claude-integration.sh +12 -1
- package/scripts/smoke-init-db.sh +23 -0
- package/scripts/stackmemory-daemon.sh +11 -0
- package/scripts/verify-dist.cjs +11 -4
- package/dist/src/cli/commands/ralph.js +0 -1053
- package/dist/src/hooks/diffmem-hooks.js +0 -376
- package/dist/src/integrations/diffmem/client.js +0 -208
- package/dist/src/integrations/diffmem/config.js +0 -14
- package/dist/src/integrations/greptile/client.js +0 -101
- package/dist/src/integrations/greptile/config.js +0 -14
- package/dist/src/integrations/greptile/index.js +0 -11
- package/dist/src/integrations/mcp/handlers/cross-search-handlers.js +0 -188
- package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
- package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
- package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
- package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
- package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -354
- package/dist/src/integrations/ralph/index.js +0 -17
- package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -416
- package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
- package/dist/src/integrations/ralph/loopmax.js +0 -488
- package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
- package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
- package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
- package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
- package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
- package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1005
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
- package/scripts/ralph-loop-implementation.js +0 -404
- /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
- /package/dist/src/{integrations/greptile → features/operator}/types.js +0 -0
- /package/dist/src/{integrations/ralph/types.js → features/web/client/next-env.d.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
|
-
};
|