@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.
Files changed (162) hide show
  1. package/LICENSE +131 -64
  2. package/README.md +3 -1
  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/codex-sm.js +51 -11
  11. package/dist/src/cli/commands/brain.js +206 -0
  12. package/dist/src/cli/commands/company-os.js +184 -0
  13. package/dist/src/cli/commands/context.js +5 -0
  14. package/dist/src/cli/commands/operator.js +127 -0
  15. package/dist/src/cli/commands/orchestrate.js +2 -0
  16. package/dist/src/cli/commands/orchestrator.js +3 -2
  17. package/dist/src/cli/commands/patterns.js +254 -0
  18. package/dist/src/cli/commands/portal.js +161 -0
  19. package/dist/src/cli/commands/scaffold.js +92 -0
  20. package/dist/src/cli/commands/setup.js +1 -4
  21. package/dist/src/cli/commands/sync.js +253 -0
  22. package/dist/src/cli/commands/tasks.js +130 -1
  23. package/dist/src/cli/commands/vision.js +221 -0
  24. package/dist/src/cli/hermes-sm.js +224 -0
  25. package/dist/src/cli/index.js +15 -10
  26. package/dist/src/cli/utils/real-cli-bin.js +72 -0
  27. package/dist/src/core/brain/brain-store.js +187 -0
  28. package/dist/src/core/brain/brain-sync.js +193 -0
  29. package/dist/src/core/brain/index.js +78 -0
  30. package/dist/src/core/brain/types.js +10 -0
  31. package/dist/src/core/cache/token-estimator.js +24 -1
  32. package/dist/src/core/config/feature-flags.js +2 -6
  33. package/dist/src/core/context/frame-database.js +44 -0
  34. package/dist/src/core/context/recursive-context-manager.js +1 -1
  35. package/dist/src/core/context/rehydration.js +2 -1
  36. package/dist/src/core/database/sqlite-adapter.js +14 -1
  37. package/dist/src/core/models/model-router.js +33 -1
  38. package/dist/src/core/models/provider-pricing.js +58 -4
  39. package/dist/src/core/patterns/index.js +22 -0
  40. package/dist/src/core/patterns/pattern-applier.js +39 -0
  41. package/dist/src/core/patterns/pattern-observer.js +157 -0
  42. package/dist/src/core/patterns/pattern-store.js +259 -0
  43. package/dist/src/core/patterns/types.js +19 -0
  44. package/dist/src/core/retrieval/llm-context-retrieval.js +5 -4
  45. package/dist/src/core/retrieval/unified-context-assembler.js +11 -66
  46. package/dist/src/core/skill-packs/types.js +14 -1
  47. package/dist/src/core/storage/cloud-sync-manager.js +116 -0
  48. package/dist/src/core/storage/cloud-sync.js +574 -0
  49. package/dist/src/core/storage/two-tier-storage.js +5 -1
  50. package/dist/src/core/tasks/master-tasks-template.js +43 -0
  51. package/dist/src/core/tasks/md-task-parser.js +138 -0
  52. package/dist/src/core/vision/index.js +27 -0
  53. package/dist/src/core/vision/signals.js +79 -0
  54. package/dist/src/core/vision/types.js +22 -0
  55. package/dist/src/core/vision/vision-file.js +146 -0
  56. package/dist/src/core/vision/vision-loop.js +220 -0
  57. package/dist/src/core/wiki/wiki-compiler.js +103 -1
  58. package/dist/src/daemon/daemon-config.js +45 -0
  59. package/dist/src/daemon/services/desire-path-service.js +566 -0
  60. package/dist/src/daemon/services/research-stream-service.js +320 -0
  61. package/dist/src/daemon/services/telemetry-service.js +192 -0
  62. package/dist/src/daemon/unified-daemon.js +28 -1
  63. package/dist/src/features/browser/cli-browser-agent.js +417 -0
  64. package/dist/src/features/browser/stagehand-workflows.js +578 -0
  65. package/dist/src/features/operator/adapter-factory.js +62 -0
  66. package/dist/src/features/operator/browser-adapter.js +109 -0
  67. package/dist/src/features/operator/desktop-adapter.js +125 -0
  68. package/dist/src/features/operator/index.js +39 -0
  69. package/dist/src/features/operator/llm-decision.js +137 -0
  70. package/dist/src/features/operator/operator-logger.js +92 -0
  71. package/dist/src/features/operator/overnight-runner.js +327 -0
  72. package/dist/src/features/operator/screen-adapter.js +91 -0
  73. package/dist/src/features/operator/session-manager.js +127 -0
  74. package/dist/src/features/operator/state-machine.js +227 -0
  75. package/dist/src/features/operator/task-queue.js +81 -0
  76. package/dist/src/features/portal/index.js +26 -0
  77. package/dist/src/features/portal/server.js +240 -0
  78. package/dist/src/features/portal/types.js +14 -0
  79. package/dist/src/features/portal/ui.js +195 -0
  80. package/dist/src/features/tasks/task-aware-context.js +2 -1
  81. package/dist/src/features/tui/simple-monitor.js +0 -23
  82. package/dist/src/features/tui/swarm-monitor.js +8 -66
  83. package/dist/src/{integrations/diffmem/index.js → features/web/client/hooks/use-socket.js} +6 -5
  84. package/dist/src/features/web/client/lib/utils.js +12 -0
  85. package/dist/src/features/web/client/stores/session-store.js +12 -0
  86. package/dist/src/features/web/server/gcp-billing.js +76 -0
  87. package/dist/src/features/web/server/index.js +10 -0
  88. package/dist/src/features/web/server/spend-calculator.js +228 -0
  89. package/dist/src/hooks/schemas.js +4 -1
  90. package/dist/src/integrations/anthropic/client.js +3 -2
  91. package/dist/src/integrations/claude-code/agent-bridge.js +0 -3
  92. package/dist/src/integrations/claude-code/subagent-client.js +218 -11
  93. package/dist/src/integrations/claude-code/task-coordinator.js +2 -1
  94. package/dist/src/integrations/linear/webhook-retry.js +196 -0
  95. package/dist/src/integrations/linear/webhook-server.js +18 -22
  96. package/dist/src/integrations/mcp/handlers/cloud-sync-handlers.js +101 -0
  97. package/dist/src/integrations/mcp/handlers/index.js +27 -52
  98. package/dist/src/integrations/mcp/server.js +122 -335
  99. package/dist/src/integrations/mcp/tool-alias-registry.js +0 -73
  100. package/dist/src/integrations/mcp/tool-definitions.js +111 -510
  101. package/dist/src/mcp/stackmemory-mcp-server.js +404 -379
  102. package/dist/src/orchestrators/multimodal/determinism.js +2 -1
  103. package/dist/src/orchestrators/multimodal/harness.js +2 -1
  104. package/dist/src/skills/recursive-agent-orchestrator.js +2 -4
  105. package/dist/src/utils/process-cleanup.js +1 -7
  106. package/docs/README.md +42 -0
  107. package/docs/guides/README_INSTALL.md +208 -0
  108. package/package.json +18 -9
  109. package/scripts/claude-code-wrapper.sh +11 -0
  110. package/scripts/claude-sm-setup.sh +12 -1
  111. package/scripts/codex-wrapper.sh +11 -0
  112. package/scripts/git-hooks/branch-context-manager.sh +11 -0
  113. package/scripts/git-hooks/post-checkout-stackmemory.sh +11 -0
  114. package/scripts/git-hooks/post-commit-stackmemory.sh +11 -0
  115. package/scripts/git-hooks/pre-commit-stackmemory.sh +11 -0
  116. package/scripts/hooks/cleanup-shell.sh +12 -1
  117. package/scripts/hooks/task-complete.sh +12 -1
  118. package/scripts/install-code-execution-hooks.sh +12 -1
  119. package/scripts/install-sweep-hook.sh +12 -0
  120. package/scripts/install.sh +11 -0
  121. package/scripts/opencode-wrapper.sh +11 -0
  122. package/scripts/portal/cloud-init.yaml +69 -0
  123. package/scripts/portal/setup.sh +69 -0
  124. package/scripts/portal/stackmemory-portal.service +34 -0
  125. package/scripts/setup-claude-integration.sh +12 -1
  126. package/scripts/smoke-init-db.sh +23 -0
  127. package/scripts/stackmemory-daemon.sh +11 -0
  128. package/scripts/verify-dist.cjs +11 -4
  129. package/dist/src/cli/commands/ralph.js +0 -1053
  130. package/dist/src/hooks/diffmem-hooks.js +0 -376
  131. package/dist/src/integrations/diffmem/client.js +0 -208
  132. package/dist/src/integrations/diffmem/config.js +0 -14
  133. package/dist/src/integrations/greptile/client.js +0 -101
  134. package/dist/src/integrations/greptile/config.js +0 -14
  135. package/dist/src/integrations/greptile/index.js +0 -11
  136. package/dist/src/integrations/mcp/handlers/cross-search-handlers.js +0 -188
  137. package/dist/src/integrations/mcp/handlers/diffmem-handlers.js +0 -455
  138. package/dist/src/integrations/mcp/handlers/greptile-handlers.js +0 -456
  139. package/dist/src/integrations/mcp/handlers/provider-handlers.js +0 -227
  140. package/dist/src/integrations/ralph/bridge/ralph-stackmemory-bridge.js +0 -863
  141. package/dist/src/integrations/ralph/context/context-budget-manager.js +0 -308
  142. package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +0 -354
  143. package/dist/src/integrations/ralph/index.js +0 -17
  144. package/dist/src/integrations/ralph/learning/pattern-learner.js +0 -416
  145. package/dist/src/integrations/ralph/lifecycle/iteration-lifecycle.js +0 -448
  146. package/dist/src/integrations/ralph/loopmax.js +0 -488
  147. package/dist/src/integrations/ralph/monitoring/swarm-dashboard.js +0 -293
  148. package/dist/src/integrations/ralph/monitoring/swarm-registry.js +0 -107
  149. package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +0 -508
  150. package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +0 -407
  151. package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +0 -495
  152. package/dist/src/integrations/ralph/patterns/oracle-worker-pattern.js +0 -387
  153. package/dist/src/integrations/ralph/performance/performance-optimizer.js +0 -357
  154. package/dist/src/integrations/ralph/recovery/crash-recovery.js +0 -461
  155. package/dist/src/integrations/ralph/state/state-reconciler.js +0 -420
  156. package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +0 -444
  157. package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +0 -1005
  158. package/dist/src/integrations/ralph/visualization/ralph-debugger.js +0 -635
  159. package/scripts/ralph-loop-implementation.js +0 -404
  160. /package/dist/src/{integrations/diffmem/types.js → core/storage/cloud-sync-types.js} +0 -0
  161. /package/dist/src/{integrations/greptile → features/operator}/types.js +0 -0
  162. /package/dist/src/{integrations/ralph/types.js → features/web/client/next-env.d.js} +0 -0
@@ -1,461 +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
- class CrashRecoverySystem {
9
- checkpoints = /* @__PURE__ */ new Map();
10
- crashReports = [];
11
- recoveryStrategies = [];
12
- swarmCoordinator;
13
- checkpointInterval;
14
- recoveryDir;
15
- constructor(swarmCoordinator, recoveryDir = ".swarm/recovery") {
16
- this.swarmCoordinator = swarmCoordinator;
17
- this.recoveryDir = recoveryDir;
18
- this.setupRecoveryStrategies();
19
- }
20
- /**
21
- * Initialize crash recovery system
22
- */
23
- async initialize() {
24
- await this.ensureRecoveryDirectory();
25
- await this.loadExistingCheckpoints();
26
- this.startPeriodicCheckpoints();
27
- process.on("unhandledRejection", (reason, promise) => {
28
- this.handleCrash(new Error(`Unhandled Rejection: ${reason}`), {
29
- type: "unhandled_rejection",
30
- promise: promise.toString()
31
- });
32
- });
33
- process.on("uncaughtException", (error) => {
34
- this.handleCrash(error, { type: "uncaught_exception" });
35
- });
36
- logger.info("Crash recovery system initialized");
37
- }
38
- /**
39
- * Create recovery checkpoint
40
- */
41
- async createCheckpoint(swarmId, reason = "periodic") {
42
- try {
43
- const swarmState = this.swarmCoordinator.swarmState;
44
- const agents = Array.from(
45
- this.swarmCoordinator.activeAgents.values()
46
- );
47
- const checkpoint = {
48
- id: this.generateId(),
49
- swarmId,
50
- timestamp: Date.now(),
51
- swarmState: { ...swarmState },
52
- agents: agents.map((agent) => ({ ...agent })),
53
- tasks: swarmState.tasks || [],
54
- errorLog: this.crashReports.slice(-10),
55
- // Last 10 errors
56
- gitState: await this.captureGitState()
57
- };
58
- const checkpointPath = path.join(
59
- this.recoveryDir,
60
- `checkpoint-${checkpoint.id}.json`
61
- );
62
- await fs.writeFile(checkpointPath, JSON.stringify(checkpoint, null, 2));
63
- this.checkpoints.set(checkpoint.id, checkpoint);
64
- logger.info(
65
- `Created checkpoint ${checkpoint.id} for swarm ${swarmId} (${reason})`
66
- );
67
- return checkpoint.id;
68
- } catch (error) {
69
- logger.error("Failed to create checkpoint:", error);
70
- throw error;
71
- }
72
- }
73
- /**
74
- * Handle crash or error
75
- */
76
- async handleCrash(error, context = {}) {
77
- const report = {
78
- id: this.generateId(),
79
- timestamp: Date.now(),
80
- agentId: context.agentId,
81
- errorType: this.classifyError(error, context),
82
- error,
83
- context,
84
- recoveryAction: "",
85
- severity: this.assessSeverity(error, context),
86
- resolved: false
87
- };
88
- this.crashReports.push(report);
89
- logger.error(`Crash detected [${report.id}]:`, error);
90
- const recovered = await this.attemptRecovery(report);
91
- if (recovered) {
92
- report.resolved = true;
93
- report.recoveryAction = "auto_recovered";
94
- logger.info(`Successfully recovered from crash ${report.id}`);
95
- } else {
96
- logger.error(`Failed to recover from crash ${report.id}`);
97
- if (report.severity === "critical") {
98
- await this.escalateCriticalFailure(report);
99
- }
100
- }
101
- await this.saveCrashReport(report);
102
- }
103
- /**
104
- * Restore from checkpoint
105
- */
106
- async restoreFromCheckpoint(checkpointId) {
107
- try {
108
- const checkpoint = this.checkpoints.get(checkpointId);
109
- if (!checkpoint) {
110
- logger.error(`Checkpoint ${checkpointId} not found`);
111
- return false;
112
- }
113
- logger.info(`Restoring from checkpoint ${checkpointId}`);
114
- await this.restoreGitState(checkpoint.gitState);
115
- if (checkpoint.databaseBackup) {
116
- await this.restoreDatabase(checkpoint.databaseBackup);
117
- }
118
- await this.restoreSwarmState(checkpoint);
119
- logger.info(`Successfully restored from checkpoint ${checkpointId}`);
120
- return true;
121
- } catch (error) {
122
- logger.error(
123
- `Failed to restore from checkpoint ${checkpointId}:`,
124
- error
125
- );
126
- return false;
127
- }
128
- }
129
- /**
130
- * Get recovery recommendations
131
- */
132
- getRecoveryRecommendations() {
133
- const recent = Date.now() - 36e5;
134
- const recentCheckpoints = Array.from(this.checkpoints.values()).filter((cp) => cp.timestamp > recent).sort((a, b) => b.timestamp - a.timestamp).slice(0, 5);
135
- const errorCounts = /* @__PURE__ */ new Map();
136
- const errorTimes = /* @__PURE__ */ new Map();
137
- for (const report of this.crashReports.filter(
138
- (r) => r.timestamp > recent
139
- )) {
140
- errorCounts.set(
141
- report.errorType,
142
- (errorCounts.get(report.errorType) || 0) + 1
143
- );
144
- errorTimes.set(
145
- report.errorType,
146
- Math.max(errorTimes.get(report.errorType) || 0, report.timestamp)
147
- );
148
- }
149
- const frequentErrors = Array.from(errorCounts.entries()).map(([type, count]) => ({
150
- type,
151
- count,
152
- lastOccurrence: errorTimes.get(type) || 0
153
- })).sort((a, b) => b.count - a.count);
154
- const criticalErrors = this.crashReports.filter(
155
- (r) => r.severity === "critical" && r.timestamp > recent && !r.resolved
156
- );
157
- const systemHealth = criticalErrors.length > 0 ? "critical" : frequentErrors.length > 3 ? "degraded" : "good";
158
- return {
159
- recentCheckpoints,
160
- frequentErrors,
161
- recoveryActions: this.generateRecoveryActions(frequentErrors),
162
- systemHealth
163
- };
164
- }
165
- /**
166
- * Auto-recovery from common failures
167
- */
168
- async attemptAutoRecovery(swarmId) {
169
- logger.info(`Attempting auto-recovery for swarm ${swarmId}`);
170
- try {
171
- const recentCheckpoint = this.findRecentCheckpoint(swarmId);
172
- if (recentCheckpoint) {
173
- logger.info(`Found recent checkpoint: ${recentCheckpoint.id}`);
174
- return await this.restoreFromCheckpoint(recentCheckpoint.id);
175
- }
176
- await this.swarmCoordinator.forceCleanup();
177
- await this.clearProblematicState();
178
- logger.info("Restarting swarm with minimal configuration");
179
- return true;
180
- } catch (error) {
181
- logger.error("Auto-recovery failed:", error);
182
- return false;
183
- }
184
- }
185
- async attemptRecovery(report) {
186
- for (const strategy of this.recoveryStrategies) {
187
- if (strategy.condition(report.error, report.context)) {
188
- logger.info(`Applying recovery strategy: ${strategy.errorType}`);
189
- let retries = 0;
190
- while (retries < strategy.maxRetries) {
191
- try {
192
- const success = await strategy.action(report, this);
193
- if (success) {
194
- report.recoveryAction = strategy.errorType;
195
- return true;
196
- }
197
- } catch (error) {
198
- logger.warn(
199
- `Recovery attempt ${retries + 1} failed:`,
200
- error
201
- );
202
- }
203
- retries++;
204
- if (retries < strategy.maxRetries) {
205
- await this.sleep(strategy.backoffMs * Math.pow(2, retries));
206
- }
207
- }
208
- }
209
- }
210
- return false;
211
- }
212
- classifyError(error, context) {
213
- const message = error.message.toLowerCase();
214
- if (message.includes("database") || message.includes("sqlite")) {
215
- return "database_failure";
216
- } else if (message.includes("git") || message.includes("branch")) {
217
- return "git_conflict";
218
- } else if (message.includes("timeout") || context.timeout) {
219
- return "agent_timeout";
220
- } else if (message.includes("memory") || message.includes("heap")) {
221
- return "memory_overflow";
222
- } else if (message.includes("network") || message.includes("connect")) {
223
- return "network_error";
224
- }
225
- return "database_failure";
226
- }
227
- assessSeverity(error, context) {
228
- if (context.type === "uncaught_exception") return "critical";
229
- if (error.message.includes("unhandled")) return "high";
230
- if (error.message.includes("database")) return "medium";
231
- return "low";
232
- }
233
- setupRecoveryStrategies() {
234
- this.recoveryStrategies = [
235
- {
236
- errorType: "database_failure",
237
- condition: (error) => error.message.includes("database") || error.message.includes("sqlite"),
238
- action: async (report, recovery) => {
239
- logger.info("Attempting database recovery");
240
- try {
241
- await recovery.clearProblematicState();
242
- return true;
243
- } catch {
244
- return false;
245
- }
246
- },
247
- maxRetries: 3,
248
- backoffMs: 1e3
249
- },
250
- {
251
- errorType: "git_conflict",
252
- condition: (error) => error.message.includes("git") || error.message.includes("branch"),
253
- action: async (_report, _recovery) => {
254
- logger.info("Attempting git conflict resolution");
255
- try {
256
- const { execSync } = await import("child_process");
257
- execSync("git checkout main", { stdio: "ignore" });
258
- execSync("git reset --hard HEAD", { stdio: "ignore" });
259
- return true;
260
- } catch {
261
- return false;
262
- }
263
- },
264
- maxRetries: 2,
265
- backoffMs: 500
266
- },
267
- {
268
- errorType: "agent_timeout",
269
- condition: (error, context) => error.message.includes("timeout") || context.timeout,
270
- action: async (report, recovery) => {
271
- logger.info("Attempting agent timeout recovery");
272
- await recovery.swarmCoordinator.forceCleanup();
273
- return true;
274
- },
275
- maxRetries: 1,
276
- backoffMs: 2e3
277
- },
278
- {
279
- errorType: "memory_overflow",
280
- condition: (error) => error.message.includes("memory") || error.message.includes("heap"),
281
- action: async (report, recovery) => {
282
- logger.info("Attempting memory recovery");
283
- if (global.gc) global.gc();
284
- await recovery.cleanupOldCheckpoints(5);
285
- return true;
286
- },
287
- maxRetries: 1,
288
- backoffMs: 5e3
289
- }
290
- ];
291
- }
292
- async captureGitState() {
293
- try {
294
- const { execSync } = await import("child_process");
295
- const currentBranch = execSync("git branch --show-current", {
296
- encoding: "utf8"
297
- }).trim();
298
- const statusOutput = execSync("git status --porcelain", {
299
- encoding: "utf8"
300
- });
301
- const uncommittedChanges = statusOutput.trim().split("\n").filter(Boolean);
302
- const branchesOutput = execSync("git branch", { encoding: "utf8" });
303
- const activeBranches = branchesOutput.split("\n").map((line) => line.trim().replace(/^\*?\s*/, "")).filter(Boolean);
304
- return {
305
- currentBranch,
306
- uncommittedChanges,
307
- activeBranches
308
- };
309
- } catch (error) {
310
- logger.warn("Failed to capture git state:", error);
311
- return {
312
- currentBranch: "unknown",
313
- uncommittedChanges: [],
314
- activeBranches: []
315
- };
316
- }
317
- }
318
- async restoreGitState(gitState) {
319
- try {
320
- const { execSync } = await import("child_process");
321
- execSync(`git checkout ${gitState.currentBranch}`, { stdio: "ignore" });
322
- logger.info(`Restored git branch: ${gitState.currentBranch}`);
323
- } catch (error) {
324
- logger.warn("Failed to restore git state:", error);
325
- }
326
- }
327
- async restoreDatabase(backupPath) {
328
- logger.info(`Restoring database from ${backupPath}`);
329
- }
330
- async restoreSwarmState(checkpoint) {
331
- logger.info(`Restoring swarm state from checkpoint ${checkpoint.id}`);
332
- }
333
- findRecentCheckpoint(swarmId) {
334
- const recent = Date.now() - 18e5;
335
- return Array.from(this.checkpoints.values()).filter((cp) => cp.swarmId === swarmId && cp.timestamp > recent).sort((a, b) => b.timestamp - a.timestamp)[0] || null;
336
- }
337
- async clearProblematicState() {
338
- try {
339
- await this.cleanupTempFiles();
340
- logger.info("Cleared problematic state");
341
- } catch (error) {
342
- logger.error("Failed to clear problematic state:", error);
343
- }
344
- }
345
- async cleanupTempFiles() {
346
- }
347
- async cleanupOldCheckpoints(keepCount) {
348
- const sorted = Array.from(this.checkpoints.values()).sort(
349
- (a, b) => b.timestamp - a.timestamp
350
- );
351
- const toDelete = sorted.slice(keepCount);
352
- for (const checkpoint of toDelete) {
353
- try {
354
- const checkpointPath = path.join(
355
- this.recoveryDir,
356
- `checkpoint-${checkpoint.id}.json`
357
- );
358
- await fs.unlink(checkpointPath);
359
- this.checkpoints.delete(checkpoint.id);
360
- } catch (error) {
361
- logger.warn(
362
- `Failed to delete checkpoint ${checkpoint.id}:`,
363
- error
364
- );
365
- }
366
- }
367
- logger.info(`Cleaned up ${toDelete.length} old checkpoints`);
368
- }
369
- async escalateCriticalFailure(report) {
370
- logger.error(`CRITICAL FAILURE [${report.id}]: ${report.error.message}`);
371
- try {
372
- const swarmState = this.swarmCoordinator.swarmState;
373
- if (swarmState?.id) {
374
- await this.createCheckpoint(swarmState.id, "critical_failure");
375
- }
376
- } catch {
377
- logger.error("Failed to create emergency checkpoint");
378
- }
379
- await this.swarmCoordinator.forceCleanup();
380
- }
381
- generateRecoveryActions(frequentErrors) {
382
- const actions = [];
383
- for (const { type, count } of frequentErrors) {
384
- if (count > 3) {
385
- switch (type) {
386
- case "database_failure":
387
- actions.push("Consider upgrading database configuration");
388
- break;
389
- case "git_conflict":
390
- actions.push("Review git workflow and branch strategy");
391
- break;
392
- case "agent_timeout":
393
- actions.push(
394
- "Increase agent timeout limits or reduce task complexity"
395
- );
396
- break;
397
- case "memory_overflow":
398
- actions.push("Monitor memory usage and consider increasing limits");
399
- break;
400
- }
401
- }
402
- }
403
- return actions;
404
- }
405
- startPeriodicCheckpoints() {
406
- this.checkpointInterval = setInterval(async () => {
407
- const swarmState = this.swarmCoordinator.swarmState;
408
- if (swarmState?.id && swarmState.status === "active") {
409
- await this.createCheckpoint(swarmState.id, "periodic");
410
- }
411
- }, 3e5);
412
- }
413
- async ensureRecoveryDirectory() {
414
- try {
415
- await fs.mkdir(this.recoveryDir, { recursive: true });
416
- } catch (error) {
417
- logger.error("Failed to create recovery directory:", error);
418
- }
419
- }
420
- async loadExistingCheckpoints() {
421
- try {
422
- const files = await fs.readdir(this.recoveryDir);
423
- for (const file of files) {
424
- if (file.startsWith("checkpoint-") && file.endsWith(".json")) {
425
- try {
426
- const content = await fs.readFile(
427
- path.join(this.recoveryDir, file),
428
- "utf8"
429
- );
430
- const checkpoint = JSON.parse(content);
431
- this.checkpoints.set(checkpoint.id, checkpoint);
432
- } catch (error) {
433
- logger.warn(`Failed to load checkpoint ${file}:`, error);
434
- }
435
- }
436
- }
437
- logger.info(`Loaded ${this.checkpoints.size} existing checkpoints`);
438
- } catch (error) {
439
- logger.warn("Failed to load existing checkpoints:", error);
440
- }
441
- }
442
- async saveCrashReport(report) {
443
- try {
444
- const reportPath = path.join(this.recoveryDir, `crash-${report.id}.json`);
445
- await fs.writeFile(reportPath, JSON.stringify(report, null, 2));
446
- } catch (error) {
447
- logger.error("Failed to save crash report:", error);
448
- }
449
- }
450
- sleep(ms) {
451
- return new Promise((resolve) => setTimeout(resolve, ms));
452
- }
453
- generateId() {
454
- return `recovery_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
455
- }
456
- }
457
- var crash_recovery_default = CrashRecoverySystem;
458
- export {
459
- CrashRecoverySystem,
460
- crash_recovery_default as default
461
- };