@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,635 +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 * as fs from "fs/promises";
|
|
6
|
-
import * as path from "path";
|
|
7
|
-
import { logger } from "../../../core/monitoring/logger.js";
|
|
8
|
-
import { FrameManager } from "../../../core/context/index.js";
|
|
9
|
-
import { sessionManager } from "../../../core/session/index.js";
|
|
10
|
-
class RalphDebugger {
|
|
11
|
-
frameManager;
|
|
12
|
-
activeSessions = /* @__PURE__ */ new Map();
|
|
13
|
-
config;
|
|
14
|
-
constructor(config) {
|
|
15
|
-
this.config = {
|
|
16
|
-
enableRealTimeMonitoring: true,
|
|
17
|
-
captureDetailedTrace: true,
|
|
18
|
-
generateVisualization: true,
|
|
19
|
-
exportFormat: "html",
|
|
20
|
-
maxTraceDepth: 50,
|
|
21
|
-
...config
|
|
22
|
-
};
|
|
23
|
-
logger.info("Ralph debugger initialized", this.config);
|
|
24
|
-
}
|
|
25
|
-
async initialize() {
|
|
26
|
-
try {
|
|
27
|
-
await sessionManager.initialize();
|
|
28
|
-
const session = await sessionManager.getOrCreateSession({});
|
|
29
|
-
if (session.database) {
|
|
30
|
-
this.frameManager = new FrameManager(
|
|
31
|
-
session.database,
|
|
32
|
-
session.projectId
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
logger.info("Debugger initialized successfully");
|
|
36
|
-
} catch (error) {
|
|
37
|
-
logger.error("Failed to initialize debugger", error);
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Start debugging a Ralph loop
|
|
43
|
-
*/
|
|
44
|
-
async startDebugSession(loopId, ralphDir) {
|
|
45
|
-
logger.info("Starting debug session", { loopId, ralphDir });
|
|
46
|
-
const session = {
|
|
47
|
-
id: `debug-${Date.now()}`,
|
|
48
|
-
loopId,
|
|
49
|
-
ralphDir,
|
|
50
|
-
startTime: Date.now(),
|
|
51
|
-
iterations: [],
|
|
52
|
-
contextFlow: [],
|
|
53
|
-
performance: {
|
|
54
|
-
iterationTimes: [],
|
|
55
|
-
memoryUsage: [],
|
|
56
|
-
contextSizes: [],
|
|
57
|
-
averageIterationTime: 0,
|
|
58
|
-
peakMemory: 0,
|
|
59
|
-
contextEfficiency: 0
|
|
60
|
-
},
|
|
61
|
-
realTimeMonitoring: this.config.enableRealTimeMonitoring
|
|
62
|
-
};
|
|
63
|
-
this.activeSessions.set(loopId, session);
|
|
64
|
-
if (this.config.enableRealTimeMonitoring) {
|
|
65
|
-
await this.startRealTimeMonitoring(session);
|
|
66
|
-
}
|
|
67
|
-
return session;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Generate comprehensive debug report
|
|
71
|
-
*/
|
|
72
|
-
async generateDebugReport(loopId) {
|
|
73
|
-
const session = this.activeSessions.get(loopId);
|
|
74
|
-
if (!session) {
|
|
75
|
-
throw new Error(`No debug session found for loop ${loopId}`);
|
|
76
|
-
}
|
|
77
|
-
logger.info("Generating debug report", { loopId });
|
|
78
|
-
const report = {
|
|
79
|
-
sessionId: session.id,
|
|
80
|
-
loopId,
|
|
81
|
-
generatedAt: Date.now(),
|
|
82
|
-
summary: await this.generateSummary(session),
|
|
83
|
-
iterationAnalysis: await this.analyzeIterations(session),
|
|
84
|
-
contextAnalysis: await this.analyzeContextFlow(session),
|
|
85
|
-
performanceAnalysis: await this.analyzePerformance(session),
|
|
86
|
-
visualization: this.config.generateVisualization ? await this.generateVisualization(session) : void 0,
|
|
87
|
-
recommendations: await this.generateRecommendations(session),
|
|
88
|
-
exportPath: ""
|
|
89
|
-
};
|
|
90
|
-
const exportPath = await this.exportReport(report);
|
|
91
|
-
report.exportPath = exportPath;
|
|
92
|
-
logger.info("Debug report generated", { loopId, exportPath });
|
|
93
|
-
return report;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Create visual timeline of loop execution
|
|
97
|
-
*/
|
|
98
|
-
async generateLoopTimeline(loopId) {
|
|
99
|
-
const session = this.activeSessions.get(loopId);
|
|
100
|
-
if (!session) {
|
|
101
|
-
throw new Error(`No debug session found for loop ${loopId}`);
|
|
102
|
-
}
|
|
103
|
-
const timeline = {
|
|
104
|
-
title: `Ralph Loop Timeline: ${loopId}`,
|
|
105
|
-
startTime: session.startTime,
|
|
106
|
-
iterations: session.iterations.map((iter) => ({
|
|
107
|
-
iteration: iter.iteration,
|
|
108
|
-
startTime: iter.startTime,
|
|
109
|
-
endTime: iter.endTime,
|
|
110
|
-
duration: iter.endTime - iter.startTime,
|
|
111
|
-
success: iter.success,
|
|
112
|
-
changes: iter.changes?.length || 0,
|
|
113
|
-
errors: iter.errors?.length || 0,
|
|
114
|
-
contextSize: iter.contextSize,
|
|
115
|
-
phase: iter.phase
|
|
116
|
-
})),
|
|
117
|
-
totalDuration: session.performance.iterationTimes.reduce(
|
|
118
|
-
(sum, time) => sum + time,
|
|
119
|
-
0
|
|
120
|
-
)
|
|
121
|
-
};
|
|
122
|
-
const html = await this.generateTimelineHTML(timeline);
|
|
123
|
-
const timelinePath = path.join(".ralph-debug", `timeline-${loopId}.html`);
|
|
124
|
-
await fs.mkdir(path.dirname(timelinePath), { recursive: true });
|
|
125
|
-
await fs.writeFile(timelinePath, html);
|
|
126
|
-
return timelinePath;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Create context flow diagram
|
|
130
|
-
*/
|
|
131
|
-
async generateContextFlowDiagram(loopId) {
|
|
132
|
-
const session = this.activeSessions.get(loopId);
|
|
133
|
-
if (!session) {
|
|
134
|
-
throw new Error(`No debug session found for loop ${loopId}`);
|
|
135
|
-
}
|
|
136
|
-
const diagram = {
|
|
137
|
-
id: `context-flow-${loopId}`,
|
|
138
|
-
nodes: [],
|
|
139
|
-
edges: [],
|
|
140
|
-
metrics: {
|
|
141
|
-
totalNodes: 0,
|
|
142
|
-
totalEdges: 0,
|
|
143
|
-
avgContextSize: 0,
|
|
144
|
-
maxContextSize: 0
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
for (let i = 0; i < session.iterations.length; i++) {
|
|
148
|
-
const iteration = session.iterations[i];
|
|
149
|
-
diagram.nodes.push({
|
|
150
|
-
id: `iter-${iteration.iteration}`,
|
|
151
|
-
type: "iteration",
|
|
152
|
-
label: `Iteration ${iteration.iteration}`,
|
|
153
|
-
size: iteration.contextSize || 100,
|
|
154
|
-
color: iteration.success ? "#4CAF50" : "#F44336",
|
|
155
|
-
metadata: {
|
|
156
|
-
duration: iteration.endTime - iteration.startTime,
|
|
157
|
-
changes: iteration.changes?.length || 0,
|
|
158
|
-
errors: iteration.errors?.length || 0
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
if (i < session.iterations.length - 1) {
|
|
162
|
-
diagram.edges.push({
|
|
163
|
-
id: `edge-${i}-${i + 1}`,
|
|
164
|
-
from: `iter-${iteration.iteration}`,
|
|
165
|
-
to: `iter-${session.iterations[i + 1].iteration}`,
|
|
166
|
-
type: "sequence",
|
|
167
|
-
weight: iteration.contextSize || 1
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
diagram.metrics = {
|
|
172
|
-
totalNodes: diagram.nodes.length,
|
|
173
|
-
totalEdges: diagram.edges.length,
|
|
174
|
-
avgContextSize: session.performance.contextSizes.length > 0 ? session.performance.contextSizes.reduce(
|
|
175
|
-
(sum, size) => sum + size,
|
|
176
|
-
0
|
|
177
|
-
) / session.performance.contextSizes.length : 0,
|
|
178
|
-
maxContextSize: Math.max(...session.performance.contextSizes)
|
|
179
|
-
};
|
|
180
|
-
return diagram;
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Real-time monitoring of loop execution
|
|
184
|
-
*/
|
|
185
|
-
async startRealTimeMonitoring(session) {
|
|
186
|
-
const monitoringInterval = setInterval(async () => {
|
|
187
|
-
try {
|
|
188
|
-
await this.captureIterationTrace(session);
|
|
189
|
-
await this.updatePerformanceMetrics(session);
|
|
190
|
-
} catch (error) {
|
|
191
|
-
logger.error("Monitoring error", error);
|
|
192
|
-
}
|
|
193
|
-
}, 1e3);
|
|
194
|
-
session.monitoringInterval = monitoringInterval;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Capture detailed trace of current iteration
|
|
198
|
-
*/
|
|
199
|
-
async captureIterationTrace(session) {
|
|
200
|
-
try {
|
|
201
|
-
const statePath = path.join(session.ralphDir, "state.json");
|
|
202
|
-
const iterationPath = path.join(session.ralphDir, "iteration.txt");
|
|
203
|
-
let _currentState = {};
|
|
204
|
-
let currentIteration = 0;
|
|
205
|
-
try {
|
|
206
|
-
const stateData = await fs.readFile(statePath, "utf8");
|
|
207
|
-
_currentState = JSON.parse(stateData);
|
|
208
|
-
const iterData = await fs.readFile(iterationPath, "utf8");
|
|
209
|
-
currentIteration = parseInt(iterData.trim()) || 0;
|
|
210
|
-
} catch {
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
const lastTrace = session.iterations[session.iterations.length - 1];
|
|
214
|
-
if (lastTrace?.iteration === currentIteration) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
const trace = {
|
|
218
|
-
iteration: currentIteration,
|
|
219
|
-
startTime: Date.now(),
|
|
220
|
-
endTime: Date.now(),
|
|
221
|
-
// Will be updated when iteration completes
|
|
222
|
-
phase: this.determineIterationPhase(session.ralphDir),
|
|
223
|
-
contextSize: await this.calculateContextSize(session.ralphDir),
|
|
224
|
-
success: false,
|
|
225
|
-
// Will be updated
|
|
226
|
-
changes: [],
|
|
227
|
-
errors: [],
|
|
228
|
-
memoryUsage: process.memoryUsage().heapUsed,
|
|
229
|
-
stackTrace: this.captureStackTrace()
|
|
230
|
-
};
|
|
231
|
-
session.iterations.push(trace);
|
|
232
|
-
} catch (error) {
|
|
233
|
-
logger.debug("Failed to capture iteration trace", error);
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Update performance metrics
|
|
238
|
-
*/
|
|
239
|
-
async updatePerformanceMetrics(session) {
|
|
240
|
-
const currentMemory = process.memoryUsage().heapUsed;
|
|
241
|
-
session.performance.memoryUsage.push(currentMemory);
|
|
242
|
-
session.performance.peakMemory = Math.max(
|
|
243
|
-
session.performance.peakMemory,
|
|
244
|
-
currentMemory
|
|
245
|
-
);
|
|
246
|
-
const contextSize = await this.calculateContextSize(session.ralphDir);
|
|
247
|
-
session.performance.contextSizes.push(contextSize);
|
|
248
|
-
if (session.performance.iterationTimes.length > 0) {
|
|
249
|
-
session.performance.averageIterationTime = session.performance.iterationTimes.reduce(
|
|
250
|
-
(sum, time) => sum + time,
|
|
251
|
-
0
|
|
252
|
-
) / session.performance.iterationTimes.length;
|
|
253
|
-
}
|
|
254
|
-
if (session.performance.contextSizes.length > 0) {
|
|
255
|
-
const avgContextSize = session.performance.contextSizes.reduce((sum, size) => sum + size, 0) / session.performance.contextSizes.length;
|
|
256
|
-
session.performance.contextEfficiency = Math.max(
|
|
257
|
-
0,
|
|
258
|
-
1 - avgContextSize / 1e4
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Generate executive summary
|
|
264
|
-
*/
|
|
265
|
-
async generateSummary(session) {
|
|
266
|
-
const totalIterations = session.iterations.length;
|
|
267
|
-
const successfulIterations = session.iterations.filter(
|
|
268
|
-
(i) => i.success
|
|
269
|
-
).length;
|
|
270
|
-
const totalDuration = session.performance.iterationTimes.reduce(
|
|
271
|
-
(sum, time) => sum + time,
|
|
272
|
-
0
|
|
273
|
-
);
|
|
274
|
-
return {
|
|
275
|
-
loopId: session.loopId,
|
|
276
|
-
totalIterations,
|
|
277
|
-
successfulIterations,
|
|
278
|
-
successRate: totalIterations > 0 ? successfulIterations / totalIterations : 0,
|
|
279
|
-
totalDuration,
|
|
280
|
-
averageIterationTime: session.performance.averageIterationTime,
|
|
281
|
-
peakMemoryUsage: session.performance.peakMemory,
|
|
282
|
-
contextEfficiency: session.performance.contextEfficiency,
|
|
283
|
-
status: totalIterations > 0 && session.iterations[session.iterations.length - 1].success ? "completed" : "in_progress"
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
/**
|
|
287
|
-
* Analyze iteration patterns
|
|
288
|
-
*/
|
|
289
|
-
async analyzeIterations(session) {
|
|
290
|
-
if (session.iterations.length === 0) return { patterns: [], insights: [] };
|
|
291
|
-
const patterns = [];
|
|
292
|
-
const insights = [];
|
|
293
|
-
const durations = session.iterations.map((i) => i.endTime - i.startTime);
|
|
294
|
-
const avgDuration = durations.reduce((sum, d) => sum + d, 0) / durations.length;
|
|
295
|
-
if (durations.some((d) => d > avgDuration * 2)) {
|
|
296
|
-
patterns.push("Variable iteration times detected");
|
|
297
|
-
insights.push(
|
|
298
|
-
"Some iterations took significantly longer than average - investigate bottlenecks"
|
|
299
|
-
);
|
|
300
|
-
}
|
|
301
|
-
const consecutiveFailures = this.findConsecutiveFailures(
|
|
302
|
-
session.iterations
|
|
303
|
-
);
|
|
304
|
-
if (consecutiveFailures.length > 2) {
|
|
305
|
-
patterns.push("Multiple consecutive failures detected");
|
|
306
|
-
insights.push(
|
|
307
|
-
"Consider adjusting approach or criteria after consecutive failures"
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
if (session.performance.contextSizes.length > 1) {
|
|
311
|
-
const contextGrowth = session.performance.contextSizes[session.performance.contextSizes.length - 1] - session.performance.contextSizes[0];
|
|
312
|
-
if (contextGrowth > 1e3) {
|
|
313
|
-
patterns.push("Significant context growth");
|
|
314
|
-
insights.push(
|
|
315
|
-
"Context is growing rapidly - consider context pruning strategies"
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return { patterns, insights };
|
|
320
|
-
}
|
|
321
|
-
/**
|
|
322
|
-
* Analyze context flow
|
|
323
|
-
*/
|
|
324
|
-
async analyzeContextFlow(session) {
|
|
325
|
-
return {
|
|
326
|
-
avgContextSize: session.performance.contextSizes.length > 0 ? session.performance.contextSizes.reduce(
|
|
327
|
-
(sum, size) => sum + size,
|
|
328
|
-
0
|
|
329
|
-
) / session.performance.contextSizes.length : 0,
|
|
330
|
-
maxContextSize: Math.max(...session.performance.contextSizes),
|
|
331
|
-
contextGrowthRate: this.calculateGrowthRate(
|
|
332
|
-
session.performance.contextSizes
|
|
333
|
-
),
|
|
334
|
-
efficiency: session.performance.contextEfficiency
|
|
335
|
-
};
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Analyze performance metrics
|
|
339
|
-
*/
|
|
340
|
-
async analyzePerformance(session) {
|
|
341
|
-
return {
|
|
342
|
-
memoryEfficiency: this.calculateMemoryEfficiency(
|
|
343
|
-
session.performance.memoryUsage
|
|
344
|
-
),
|
|
345
|
-
iterationEfficiency: session.performance.averageIterationTime,
|
|
346
|
-
resourceUtilization: {
|
|
347
|
-
cpu: "N/A",
|
|
348
|
-
// Would need CPU monitoring
|
|
349
|
-
memory: session.performance.peakMemory,
|
|
350
|
-
context: session.performance.contextEfficiency
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
/**
|
|
355
|
-
* Generate visualization HTML
|
|
356
|
-
*/
|
|
357
|
-
async generateVisualization(session) {
|
|
358
|
-
const htmlContent = await this.generateVisualizationHTML(session);
|
|
359
|
-
const vizPath = path.join(
|
|
360
|
-
".ralph-debug",
|
|
361
|
-
`visualization-${session.loopId}.html`
|
|
362
|
-
);
|
|
363
|
-
await fs.mkdir(path.dirname(vizPath), { recursive: true });
|
|
364
|
-
await fs.writeFile(vizPath, htmlContent);
|
|
365
|
-
return {
|
|
366
|
-
id: `viz-${session.loopId}`,
|
|
367
|
-
type: "interactive_timeline",
|
|
368
|
-
htmlPath: vizPath,
|
|
369
|
-
data: {
|
|
370
|
-
iterations: session.iterations,
|
|
371
|
-
performance: session.performance,
|
|
372
|
-
contextFlow: session.contextFlow
|
|
373
|
-
},
|
|
374
|
-
metadata: {
|
|
375
|
-
generatedAt: Date.now(),
|
|
376
|
-
format: "html",
|
|
377
|
-
interactive: true
|
|
378
|
-
}
|
|
379
|
-
};
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Generate recommendations
|
|
383
|
-
*/
|
|
384
|
-
async generateRecommendations(session) {
|
|
385
|
-
const recommendations = [];
|
|
386
|
-
if (session.performance.averageIterationTime > 3e4) {
|
|
387
|
-
recommendations.push(
|
|
388
|
-
"Consider breaking down complex tasks into smaller iterations"
|
|
389
|
-
);
|
|
390
|
-
}
|
|
391
|
-
if (session.performance.contextEfficiency < 0.7) {
|
|
392
|
-
recommendations.push(
|
|
393
|
-
"Optimize context management - consider using context budgeting"
|
|
394
|
-
);
|
|
395
|
-
}
|
|
396
|
-
const successRate = session.iterations.filter((i) => i.success).length / Math.max(1, session.iterations.length);
|
|
397
|
-
if (successRate < 0.5) {
|
|
398
|
-
recommendations.push(
|
|
399
|
-
"Low success rate detected - review task criteria and approach"
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
if (session.performance.peakMemory > 500 * 1024 * 1024) {
|
|
403
|
-
recommendations.push(
|
|
404
|
-
"High memory usage detected - investigate memory leaks"
|
|
405
|
-
);
|
|
406
|
-
}
|
|
407
|
-
return recommendations;
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Export report in specified format
|
|
411
|
-
*/
|
|
412
|
-
async exportReport(report) {
|
|
413
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
414
|
-
const filename = `ralph-debug-${report.loopId}-${timestamp}`;
|
|
415
|
-
let content;
|
|
416
|
-
let extension;
|
|
417
|
-
switch (this.config.exportFormat) {
|
|
418
|
-
case "json":
|
|
419
|
-
content = JSON.stringify(report, null, 2);
|
|
420
|
-
extension = "json";
|
|
421
|
-
break;
|
|
422
|
-
case "markdown":
|
|
423
|
-
content = this.generateMarkdownReport(report);
|
|
424
|
-
extension = "md";
|
|
425
|
-
break;
|
|
426
|
-
case "html":
|
|
427
|
-
default:
|
|
428
|
-
content = this.generateHTMLReport(report);
|
|
429
|
-
extension = "html";
|
|
430
|
-
break;
|
|
431
|
-
}
|
|
432
|
-
const exportPath = path.join(".ralph-debug", `${filename}.${extension}`);
|
|
433
|
-
await fs.mkdir(path.dirname(exportPath), { recursive: true });
|
|
434
|
-
await fs.writeFile(exportPath, content);
|
|
435
|
-
return exportPath;
|
|
436
|
-
}
|
|
437
|
-
// Helper methods
|
|
438
|
-
determineIterationPhase(_ralphDir) {
|
|
439
|
-
return "working";
|
|
440
|
-
}
|
|
441
|
-
async calculateContextSize(ralphDir) {
|
|
442
|
-
try {
|
|
443
|
-
const feedbackPath = path.join(ralphDir, "feedback.txt");
|
|
444
|
-
const feedback = await fs.readFile(feedbackPath, "utf8");
|
|
445
|
-
return feedback.length;
|
|
446
|
-
} catch {
|
|
447
|
-
return 0;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
captureStackTrace() {
|
|
451
|
-
const stack = new Error().stack || "";
|
|
452
|
-
return stack.split("\n").slice(1, 6).join("\n");
|
|
453
|
-
}
|
|
454
|
-
findConsecutiveFailures(iterations) {
|
|
455
|
-
const failures = [];
|
|
456
|
-
let currentStreak = 0;
|
|
457
|
-
for (const iteration of iterations) {
|
|
458
|
-
if (!iteration.success) {
|
|
459
|
-
currentStreak++;
|
|
460
|
-
} else {
|
|
461
|
-
if (currentStreak > 0) {
|
|
462
|
-
failures.push(currentStreak);
|
|
463
|
-
}
|
|
464
|
-
currentStreak = 0;
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
if (currentStreak > 0) {
|
|
468
|
-
failures.push(currentStreak);
|
|
469
|
-
}
|
|
470
|
-
return failures;
|
|
471
|
-
}
|
|
472
|
-
calculateGrowthRate(sizes) {
|
|
473
|
-
if (sizes.length < 2) return 0;
|
|
474
|
-
const first = sizes[0];
|
|
475
|
-
const last = sizes[sizes.length - 1];
|
|
476
|
-
return first > 0 ? (last - first) / first : 0;
|
|
477
|
-
}
|
|
478
|
-
calculateMemoryEfficiency(memoryUsage) {
|
|
479
|
-
if (memoryUsage.length < 2) return 1;
|
|
480
|
-
const min = Math.min(...memoryUsage);
|
|
481
|
-
const max = Math.max(...memoryUsage);
|
|
482
|
-
return max > 0 ? min / max : 1;
|
|
483
|
-
}
|
|
484
|
-
generateTimelineHTML(timeline) {
|
|
485
|
-
return `
|
|
486
|
-
<!DOCTYPE html>
|
|
487
|
-
<html>
|
|
488
|
-
<head>
|
|
489
|
-
<title>${timeline.title}</title>
|
|
490
|
-
<script src="https://d3js.org/d3.v7.min.js"></script>
|
|
491
|
-
<style>
|
|
492
|
-
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
493
|
-
.timeline { margin: 20px 0; }
|
|
494
|
-
.iteration { margin: 10px 0; padding: 10px; border-left: 4px solid #ccc; }
|
|
495
|
-
.success { border-left-color: #4CAF50; }
|
|
496
|
-
.failure { border-left-color: #F44336; }
|
|
497
|
-
</style>
|
|
498
|
-
</head>
|
|
499
|
-
<body>
|
|
500
|
-
<h1>${timeline.title}</h1>
|
|
501
|
-
<div class="timeline">
|
|
502
|
-
${timeline.iterations.map(
|
|
503
|
-
(iter) => `
|
|
504
|
-
<div class="iteration ${iter.success ? "success" : "failure"}">
|
|
505
|
-
<h3>Iteration ${iter.iteration}</h3>
|
|
506
|
-
<p>Duration: ${iter.duration}ms</p>
|
|
507
|
-
<p>Changes: ${iter.changes} | Errors: ${iter.errors}</p>
|
|
508
|
-
<p>Context Size: ${iter.contextSize}</p>
|
|
509
|
-
</div>
|
|
510
|
-
`
|
|
511
|
-
).join("")}
|
|
512
|
-
</div>
|
|
513
|
-
</body>
|
|
514
|
-
</html>
|
|
515
|
-
`;
|
|
516
|
-
}
|
|
517
|
-
generateVisualizationHTML(session) {
|
|
518
|
-
return `
|
|
519
|
-
<!DOCTYPE html>
|
|
520
|
-
<html>
|
|
521
|
-
<head>
|
|
522
|
-
<title>Ralph Loop Visualization - ${session.loopId}</title>
|
|
523
|
-
<script src="https://d3js.org/d3.v7.min.js"></script>
|
|
524
|
-
<style>
|
|
525
|
-
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
526
|
-
.chart { margin: 20px 0; }
|
|
527
|
-
.metric { display: inline-block; margin: 10px; padding: 10px; border: 1px solid #ccc; }
|
|
528
|
-
</style>
|
|
529
|
-
</head>
|
|
530
|
-
<body>
|
|
531
|
-
<h1>Ralph Loop Debug Visualization</h1>
|
|
532
|
-
<div id="metrics">
|
|
533
|
-
<div class="metric">
|
|
534
|
-
<h3>Iterations</h3>
|
|
535
|
-
<p>${session.iterations.length}</p>
|
|
536
|
-
</div>
|
|
537
|
-
<div class="metric">
|
|
538
|
-
<h3>Avg Time</h3>
|
|
539
|
-
<p>${Math.round(session.performance.averageIterationTime)}ms</p>
|
|
540
|
-
</div>
|
|
541
|
-
<div class="metric">
|
|
542
|
-
<h3>Context Efficiency</h3>
|
|
543
|
-
<p>${Math.round(session.performance.contextEfficiency * 100)}%</p>
|
|
544
|
-
</div>
|
|
545
|
-
</div>
|
|
546
|
-
<div id="timeline" class="chart"></div>
|
|
547
|
-
<script>
|
|
548
|
-
// D3.js visualization code would go here
|
|
549
|
-
console.log('Visualization data:', ${JSON.stringify(session)});
|
|
550
|
-
</script>
|
|
551
|
-
</body>
|
|
552
|
-
</html>
|
|
553
|
-
`;
|
|
554
|
-
}
|
|
555
|
-
generateMarkdownReport(report) {
|
|
556
|
-
return `
|
|
557
|
-
# Ralph Loop Debug Report
|
|
558
|
-
|
|
559
|
-
**Loop ID:** ${report.loopId}
|
|
560
|
-
**Generated:** ${new Date(report.generatedAt).toLocaleString()}
|
|
561
|
-
|
|
562
|
-
## Summary
|
|
563
|
-
- **Total Iterations:** ${report.summary.totalIterations}
|
|
564
|
-
- **Success Rate:** ${Math.round(report.summary.successRate * 100)}%
|
|
565
|
-
- **Total Duration:** ${report.summary.totalDuration}ms
|
|
566
|
-
- **Average Iteration Time:** ${Math.round(report.summary.averageIterationTime)}ms
|
|
567
|
-
|
|
568
|
-
## Performance Analysis
|
|
569
|
-
- **Peak Memory:** ${Math.round(report.performanceAnalysis.resourceUtilization.memory / 1024 / 1024)}MB
|
|
570
|
-
- **Context Efficiency:** ${Math.round(report.performanceAnalysis.resourceUtilization.context * 100)}%
|
|
571
|
-
|
|
572
|
-
## Recommendations
|
|
573
|
-
${report.recommendations.map((r) => `- ${r}`).join("\n")}
|
|
574
|
-
`;
|
|
575
|
-
}
|
|
576
|
-
generateHTMLReport(report) {
|
|
577
|
-
return `
|
|
578
|
-
<!DOCTYPE html>
|
|
579
|
-
<html>
|
|
580
|
-
<head>
|
|
581
|
-
<title>Ralph Debug Report - ${report.loopId}</title>
|
|
582
|
-
<style>
|
|
583
|
-
body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; }
|
|
584
|
-
.summary { background: #f5f5f5; padding: 20px; border-radius: 8px; margin: 20px 0; }
|
|
585
|
-
.metric { display: inline-block; margin: 10px; padding: 15px; background: white; border-radius: 4px; }
|
|
586
|
-
.recommendations { background: #e3f2fd; padding: 15px; border-radius: 4px; }
|
|
587
|
-
</style>
|
|
588
|
-
</head>
|
|
589
|
-
<body>
|
|
590
|
-
<h1>Ralph Loop Debug Report</h1>
|
|
591
|
-
<div class="summary">
|
|
592
|
-
<h2>Executive Summary</h2>
|
|
593
|
-
<div class="metric">
|
|
594
|
-
<h3>${report.summary.totalIterations}</h3>
|
|
595
|
-
<p>Total Iterations</p>
|
|
596
|
-
</div>
|
|
597
|
-
<div class="metric">
|
|
598
|
-
<h3>${Math.round(report.summary.successRate * 100)}%</h3>
|
|
599
|
-
<p>Success Rate</p>
|
|
600
|
-
</div>
|
|
601
|
-
<div class="metric">
|
|
602
|
-
<h3>${Math.round(report.summary.averageIterationTime)}ms</h3>
|
|
603
|
-
<p>Avg Iteration Time</p>
|
|
604
|
-
</div>
|
|
605
|
-
</div>
|
|
606
|
-
|
|
607
|
-
<div class="recommendations">
|
|
608
|
-
<h2>Recommendations</h2>
|
|
609
|
-
<ul>
|
|
610
|
-
${report.recommendations.map((r) => `<li>${r}</li>`).join("")}
|
|
611
|
-
</ul>
|
|
612
|
-
</div>
|
|
613
|
-
</body>
|
|
614
|
-
</html>
|
|
615
|
-
`;
|
|
616
|
-
}
|
|
617
|
-
/**
|
|
618
|
-
* Stop debug session and cleanup
|
|
619
|
-
*/
|
|
620
|
-
async stopDebugSession(loopId) {
|
|
621
|
-
const session = this.activeSessions.get(loopId);
|
|
622
|
-
if (!session) return;
|
|
623
|
-
if (session.monitoringInterval) {
|
|
624
|
-
clearInterval(session.monitoringInterval);
|
|
625
|
-
}
|
|
626
|
-
await this.generateDebugReport(loopId);
|
|
627
|
-
this.activeSessions.delete(loopId);
|
|
628
|
-
logger.info("Debug session stopped", { loopId });
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
const ralphDebugger = new RalphDebugger();
|
|
632
|
-
export {
|
|
633
|
-
RalphDebugger,
|
|
634
|
-
ralphDebugger
|
|
635
|
-
};
|