@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,404 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import fs from 'fs';
4
- import path from 'path';
5
- import { execSync } from 'child_process';
6
- import { fileURLToPath } from 'url';
7
-
8
- class RalphLoop {
9
- constructor(options = {}) {
10
- this.baseDir = options.baseDir || '.ralph';
11
- this.maxIterations = options.maxIterations || 50;
12
- this.verbose = options.verbose || false;
13
-
14
- this.paths = {
15
- task: path.join(this.baseDir, 'task.md'),
16
- criteria: path.join(this.baseDir, 'completion-criteria.md'),
17
- iteration: path.join(this.baseDir, 'iteration.txt'),
18
- feedback: path.join(this.baseDir, 'feedback.txt'),
19
- state: path.join(this.baseDir, 'state.json'),
20
- complete: path.join(this.baseDir, 'work-complete.txt'),
21
- progress: path.join(this.baseDir, 'progress.jsonl'),
22
- history: path.join(this.baseDir, 'history')
23
- };
24
- }
25
-
26
- async initialize(task, criteria) {
27
- // Create directory structure
28
- fs.mkdirSync(this.baseDir, { recursive: true });
29
- fs.mkdirSync(this.paths.history, { recursive: true });
30
-
31
- // Initialize files
32
- fs.writeFileSync(this.paths.task, task);
33
- fs.writeFileSync(this.paths.criteria, criteria);
34
- fs.writeFileSync(this.paths.iteration, '0');
35
- fs.writeFileSync(this.paths.feedback, '');
36
-
37
- // Initial state
38
- const state = {
39
- startTime: Date.now(),
40
- task: task.substring(0, 100),
41
- status: 'initialized'
42
- };
43
- fs.writeFileSync(this.paths.state, JSON.stringify(state, null, 2));
44
-
45
- this.log('Ralph Loop initialized');
46
- }
47
-
48
- async runWorkerIteration() {
49
- const iteration = this.getCurrentIteration();
50
- const task = fs.readFileSync(this.paths.task, 'utf8');
51
- const feedback = this.getFeedback();
52
-
53
- this.log(`Worker iteration ${iteration} starting...`);
54
-
55
- // Step 1: Analyze current state (fresh context)
56
- const analysis = await this.analyzeCurrentState();
57
-
58
- // Step 2: Plan based on task and feedback
59
- const plan = await this.createPlan(task, feedback, analysis);
60
-
61
- // Step 3: Execute changes
62
- const changes = await this.executeChanges(plan);
63
-
64
- // Step 4: Validate changes
65
- const validation = await this.validateChanges();
66
-
67
- // Step 5: Save iteration artifacts
68
- await this.saveIterationArtifacts(iteration, {
69
- analysis,
70
- plan,
71
- changes,
72
- validation
73
- });
74
-
75
- // Step 6: Commit changes
76
- this.commitChanges(iteration, plan.summary);
77
-
78
- return {
79
- iteration,
80
- changes: changes.length,
81
- validation
82
- };
83
- }
84
-
85
- async runReviewerIteration() {
86
- const iteration = this.getCurrentIteration();
87
- const task = fs.readFileSync(this.paths.task, 'utf8');
88
- const criteria = fs.readFileSync(this.paths.criteria, 'utf8');
89
-
90
- this.log(`Reviewer iteration ${iteration} evaluating...`);
91
-
92
- // Fresh evaluation of current state
93
- const evaluation = await this.evaluateAgainstCriteria(criteria);
94
-
95
- if (evaluation.complete) {
96
- fs.writeFileSync(this.paths.complete, 'true');
97
- this.log('Task completed successfully!');
98
- return { complete: true };
99
- }
100
-
101
- // Generate feedback for next iteration
102
- const feedback = this.generateFeedback(evaluation);
103
- fs.writeFileSync(this.paths.feedback, feedback);
104
-
105
- // Increment iteration
106
- this.incrementIteration();
107
-
108
- return {
109
- complete: false,
110
- feedback: feedback.substring(0, 200)
111
- };
112
- }
113
-
114
- async analyzeCurrentState() {
115
- // Simulate fresh analysis of codebase
116
- const files = this.scanRelevantFiles();
117
- const tests = this.getTestStatus();
118
- const lastCommit = this.getLastCommit();
119
-
120
- return {
121
- filesCount: files.length,
122
- testsPass: tests.passing,
123
- testsFail: tests.failing,
124
- lastChange: lastCommit
125
- };
126
- }
127
-
128
- async createPlan(_task, feedback, _analysis) {
129
- // In real implementation, this would use an LLM
130
- // Here we simulate planning based on feedback
131
- const needsWork = feedback.includes('failing') ||
132
- feedback.includes('incomplete') ||
133
- feedback === '';
134
-
135
- return {
136
- summary: `Iteration work based on: ${feedback.substring(0, 50)}`,
137
- steps: needsWork ? ['Fix issues', 'Add features', 'Update tests'] : ['Polish'],
138
- priority: needsWork ? 'high' : 'low'
139
- };
140
- }
141
-
142
- async executeChanges(plan) {
143
- // Simulate making code changes
144
- const changes = [];
145
-
146
- for (const step of plan.steps) {
147
- changes.push({
148
- step,
149
- timestamp: Date.now(),
150
- result: 'simulated'
151
- });
152
- }
153
-
154
- return changes;
155
- }
156
-
157
- async validateChanges() {
158
- // Run tests and checks
159
- try {
160
- const testResult = this.runTests();
161
- const lintResult = this.runLint();
162
-
163
- return {
164
- testsPass: testResult.passing > 0,
165
- lintClean: lintResult.clean,
166
- errors: [...testResult.errors, ...lintResult.errors]
167
- };
168
- } catch (error) {
169
- return {
170
- testsPass: false,
171
- lintClean: false,
172
- errors: [error.message]
173
- };
174
- }
175
- }
176
-
177
- async evaluateAgainstCriteria(criteria) {
178
- // Parse criteria and check each
179
- const criteriaLines = criteria.split('\n').filter(l => l.trim().startsWith('-'));
180
- const results = {};
181
-
182
- for (const criterion of criteriaLines) {
183
- const key = criterion.replace('-', '').trim().substring(0, 20);
184
- // Simulate checking (in reality would analyze code)
185
- results[key] = Math.random() > 0.3; // 70% chance of meeting each criterion
186
- }
187
-
188
- const complete = Object.values(results).every(v => v === true);
189
-
190
- return {
191
- complete,
192
- criteria: results,
193
- unmet: Object.entries(results)
194
- .filter(([_, v]) => !v)
195
- .map(([k]) => k)
196
- };
197
- }
198
-
199
- generateFeedback(evaluation) {
200
- if (evaluation.unmet.length === 0) {
201
- return 'All criteria met';
202
- }
203
-
204
- return `Still need to address:\n${evaluation.unmet.map(c => `- ${c}`).join('\n')}`;
205
- }
206
-
207
- async saveIterationArtifacts(iteration, artifacts) {
208
- const iterDir = path.join(this.paths.history, `iteration-${String(iteration).padStart(3, '0')}`);
209
- fs.mkdirSync(iterDir, { recursive: true });
210
-
211
- fs.writeFileSync(
212
- path.join(iterDir, 'artifacts.json'),
213
- JSON.stringify(artifacts, null, 2)
214
- );
215
-
216
- // Log progress
217
- const progress = {
218
- iteration,
219
- timestamp: Date.now(),
220
- changes: artifacts.changes.length,
221
- validation: artifacts.validation.testsPass,
222
- errors: artifacts.validation.errors.length
223
- };
224
-
225
- fs.appendFileSync(this.paths.progress, JSON.stringify(progress) + '\n');
226
- }
227
-
228
- commitChanges(iteration, summary) {
229
- try {
230
- execSync('git add -A', { stdio: 'pipe' });
231
- execSync(`git commit -m "Ralph iteration ${iteration}: ${summary}" --allow-empty`, { stdio: 'pipe' });
232
- this.log(`Committed iteration ${iteration}`);
233
- } catch (error) {
234
- this.log(`Commit failed: ${error.message}`);
235
- }
236
- }
237
-
238
- scanRelevantFiles() {
239
- // Simulate file scanning
240
- return ['index.js', 'auth.js', 'test.js'];
241
- }
242
-
243
- getTestStatus() {
244
- try {
245
- execSync('npm test', { stdio: 'pipe' });
246
- return { passing: 5, failing: 0 };
247
- } catch {
248
- return { passing: 3, failing: 2 };
249
- }
250
- }
251
-
252
- runTests() {
253
- const status = this.getTestStatus();
254
- return {
255
- passing: status.passing,
256
- failing: status.failing,
257
- errors: status.failing > 0 ? ['Some tests failed'] : []
258
- };
259
- }
260
-
261
- runLint() {
262
- try {
263
- execSync('npm run lint', { stdio: 'pipe' });
264
- return { clean: true, errors: [] };
265
- } catch {
266
- return { clean: false, errors: ['Lint issues found'] };
267
- }
268
- }
269
-
270
- getLastCommit() {
271
- try {
272
- return execSync('git log -1 --oneline', { encoding: 'utf8' }).trim();
273
- } catch {
274
- return 'No commits yet';
275
- }
276
- }
277
-
278
- getCurrentIteration() {
279
- try {
280
- return parseInt(fs.readFileSync(this.paths.iteration, 'utf8'));
281
- } catch {
282
- return 0;
283
- }
284
- }
285
-
286
- incrementIteration() {
287
- const current = this.getCurrentIteration();
288
- fs.writeFileSync(this.paths.iteration, String(current + 1));
289
- }
290
-
291
- getFeedback() {
292
- try {
293
- return fs.readFileSync(this.paths.feedback, 'utf8');
294
- } catch {
295
- return '';
296
- }
297
- }
298
-
299
- isComplete() {
300
- return fs.existsSync(this.paths.complete);
301
- }
302
-
303
- log(message) {
304
- if (this.verbose) {
305
- console.log(`[Ralph] ${message}`);
306
- }
307
- }
308
-
309
- async run() {
310
- while (!this.isComplete()) {
311
- const iteration = this.getCurrentIteration();
312
-
313
- if (iteration >= this.maxIterations) {
314
- console.log('Max iterations reached!');
315
- break;
316
- }
317
-
318
- // Worker phase
319
- await this.runWorkerIteration();
320
-
321
- // Reviewer phase
322
- const review = await this.runReviewerIteration();
323
-
324
- if (review.complete) {
325
- console.log('Task completed!');
326
- break;
327
- }
328
-
329
- // Brief pause between iterations
330
- await new Promise(resolve => setTimeout(resolve, 1000));
331
- }
332
-
333
- // Final summary
334
- this.printSummary();
335
- }
336
-
337
- printSummary() {
338
- const iterations = this.getCurrentIteration();
339
- const progress = fs.readFileSync(this.paths.progress, 'utf8')
340
- .split('\n')
341
- .filter(Boolean)
342
- .map(line => JSON.parse(line));
343
-
344
- console.log('\n=== Ralph Loop Summary ===');
345
- console.log(`Total iterations: ${iterations}`);
346
- console.log(`Total changes: ${progress.reduce((sum, p) => sum + p.changes, 0)}`);
347
- console.log(`Final status: ${this.isComplete() ? 'COMPLETE' : 'INCOMPLETE'}`);
348
- }
349
- }
350
-
351
- // CLI Interface
352
- async function main() {
353
- const args = process.argv.slice(2);
354
- const command = args[0];
355
-
356
- if (command === 'init') {
357
- const task = args[1] || 'Implement a feature';
358
- const criteria = args[2] || '- Tests pass\n- Code works\n- No errors';
359
-
360
- const loop = new RalphLoop({ verbose: true });
361
- await loop.initialize(task, criteria);
362
- console.log('Ralph Loop initialized. Run with: node ralph-loop-implementation.js run');
363
-
364
- } else if (command === 'run') {
365
- const loop = new RalphLoop({ verbose: true });
366
-
367
- if (!fs.existsSync(loop.paths.task)) {
368
- console.error('No task found. Initialize first with: node ralph-loop-implementation.js init');
369
- process.exit(1);
370
- }
371
-
372
- await loop.run();
373
-
374
- } else if (command === 'status') {
375
- const loop = new RalphLoop();
376
- const iteration = loop.getCurrentIteration();
377
- const complete = loop.isComplete();
378
- const feedback = loop.getFeedback();
379
-
380
- console.log(`Iteration: ${iteration}`);
381
- console.log(`Status: ${complete ? 'COMPLETE' : 'IN PROGRESS'}`);
382
- console.log(`Last feedback: ${feedback.substring(0, 100)}`);
383
-
384
- } else {
385
- console.log(`
386
- Ralph Loop Implementation
387
-
388
- Usage:
389
- node ralph-loop-implementation.js init [task] [criteria] - Initialize a new loop
390
- node ralph-loop-implementation.js run - Run the loop
391
- node ralph-loop-implementation.js status - Check current status
392
-
393
- Example:
394
- node ralph-loop-implementation.js init "Add login feature" "- Tests pass\\n- JWT works\\n- Error handling"
395
- node ralph-loop-implementation.js run
396
- `);
397
- }
398
- }
399
-
400
- if (import.meta.url === `file://${process.argv[1]}`) {
401
- main().catch(console.error);
402
- }
403
-
404
- export { RalphLoop };
File without changes