@stackmemoryai/stackmemory 1.0.1 → 1.2.1

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 (51) hide show
  1. package/dist/src/cli/claude-sm.js +65 -0
  2. package/dist/src/cli/commands/audit.js +134 -0
  3. package/dist/src/cli/commands/bench.js +252 -0
  4. package/dist/src/cli/commands/dashboard.js +2 -1
  5. package/dist/src/cli/commands/stats.js +118 -0
  6. package/dist/src/cli/index.js +6 -0
  7. package/dist/src/core/config/feature-flags.js +7 -1
  8. package/dist/src/core/context/enhanced-rehydration.js +24 -5
  9. package/dist/src/core/extensions/cerebras-adapter.js +28 -0
  10. package/dist/src/core/extensions/deepinfra-adapter.js +32 -0
  11. package/dist/src/core/extensions/provider-adapter.js +33 -240
  12. package/dist/src/core/models/complexity-scorer.js +154 -0
  13. package/dist/src/core/models/model-router.js +230 -36
  14. package/dist/src/core/models/provider-pricing.js +63 -0
  15. package/dist/src/core/models/sensitive-guard.js +112 -0
  16. package/dist/src/core/monitoring/feedback-loops.js +88 -0
  17. package/dist/src/hooks/schemas.js +12 -1
  18. package/dist/src/integrations/anthropic/batch-client.js +256 -0
  19. package/dist/src/integrations/anthropic/client.js +87 -72
  20. package/dist/src/integrations/claude-code/subagent-client.js +133 -12
  21. package/dist/src/integrations/graphiti/client.js +16 -4
  22. package/dist/src/integrations/mcp/handlers/index.js +25 -1
  23. package/dist/src/integrations/mcp/handlers/provider-handlers.js +227 -0
  24. package/dist/src/integrations/mcp/server.js +316 -1
  25. package/dist/src/integrations/mcp/tool-definitions.js +90 -1
  26. package/dist/src/orchestrators/multimodal/baselines.js +128 -0
  27. package/dist/src/orchestrators/multimodal/constants.js +9 -1
  28. package/dist/src/orchestrators/multimodal/harness.js +86 -6
  29. package/dist/src/orchestrators/multimodal/providers.js +113 -2
  30. package/dist/src/skills/recursive-agent-orchestrator.js +15 -10
  31. package/dist/src/utils/fuzzy-edit.js +162 -0
  32. package/dist/src/utils/hook-installer.js +155 -0
  33. package/package.json +6 -2
  34. package/scripts/gepa/.before-optimize.md +159 -0
  35. package/scripts/gepa/generations/gen-000/baseline.md +159 -124
  36. package/scripts/gepa/generations/gen-001/baseline.md +159 -0
  37. package/scripts/gepa/generations/gen-001/variant-a.md +166 -0
  38. package/scripts/gepa/generations/gen-001/variant-b.md +237 -0
  39. package/scripts/gepa/generations/gen-001/variant-c.md +61 -0
  40. package/scripts/gepa/generations/gen-001/variant-d.md +119 -0
  41. package/scripts/gepa/results/eval-1-baseline.json +41 -0
  42. package/scripts/gepa/results/eval-1-variant-a.json +41 -0
  43. package/scripts/gepa/results/eval-1-variant-b.json +41 -0
  44. package/scripts/gepa/results/eval-1-variant-c.json +41 -0
  45. package/scripts/gepa/results/eval-1-variant-d.json +41 -0
  46. package/scripts/gepa/state.json +41 -2
  47. package/scripts/install-claude-hooks-auto.js +176 -44
  48. package/templates/claude-hooks/auto-checkpoint.js +174 -0
  49. package/templates/claude-hooks/chime-on-stop.sh +22 -0
  50. package/templates/claude-hooks/session-rescue.sh +15 -0
  51. package/templates/claude-hooks/stop-checkpoint.js +120 -0
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Stop-Checkpoint Hook
5
+ *
6
+ * Fires on session stop. Reads checkpoint state for current project.
7
+ * If 3+ checkpoints accumulated, outputs a "context heavy" message.
8
+ * Writes a final checkpoint with session stop metadata.
9
+ *
10
+ * State is keyed per-session (process.ppid) to avoid race conditions
11
+ * when multiple Claude instances run concurrently.
12
+ */
13
+
14
+ const fs = require('fs');
15
+ const path = require('path');
16
+ const crypto = require('crypto');
17
+
18
+ const HOME = process.env.HOME || '/tmp';
19
+ const SESSION_ID = process.env.CLAUDE_INSTANCE_ID || String(process.ppid);
20
+ const STATE_FILE = path.join(
21
+ HOME,
22
+ '.stackmemory',
23
+ `checkpoint-state-${SESSION_ID}.json`
24
+ );
25
+ const MAX_FILES_TRACKED = 50;
26
+ const MAX_RECENT_TOOLS = 20;
27
+
28
+ function projectHash(cwd) {
29
+ return crypto.createHash('md5').update(cwd).digest('hex').slice(0, 12);
30
+ }
31
+
32
+ function ensureDir(dir) {
33
+ if (!fs.existsSync(dir)) {
34
+ fs.mkdirSync(dir, { recursive: true });
35
+ }
36
+ }
37
+
38
+ function safeWriteFile(filePath, content) {
39
+ const tmp = filePath + '.tmp';
40
+ fs.writeFileSync(tmp, content);
41
+ fs.renameSync(tmp, filePath);
42
+ }
43
+
44
+ function loadState() {
45
+ try {
46
+ if (fs.existsSync(STATE_FILE)) {
47
+ const state = JSON.parse(fs.readFileSync(STATE_FILE, 'utf-8'));
48
+ const cutoff = Date.now() - 24 * 60 * 60 * 1000;
49
+ for (const [cwd, proj] of Object.entries(state.projects)) {
50
+ if (
51
+ proj.sessionStart &&
52
+ new Date(proj.sessionStart).getTime() < cutoff
53
+ ) {
54
+ delete state.projects[cwd];
55
+ }
56
+ }
57
+ return state;
58
+ }
59
+ } catch {
60
+ // Corrupted state, start fresh
61
+ }
62
+ return { projects: {} };
63
+ }
64
+
65
+ function main() {
66
+ try {
67
+ const cwd = process.cwd();
68
+ const state = loadState();
69
+ const proj = state.projects?.[cwd];
70
+
71
+ if (!proj) return;
72
+
73
+ const { toolCount, checkpointCount, sessionStart, filesModified } = proj;
74
+
75
+ // Write final checkpoint
76
+ const hash = projectHash(cwd);
77
+ const cpDir = path.join(HOME, '.stackmemory', 'checkpoints', hash);
78
+ ensureDir(cpDir);
79
+
80
+ // NaN duration guard
81
+ const startMs = sessionStart ? new Date(sessionStart).getTime() : 0;
82
+ const duration =
83
+ startMs > 0 ? Math.round((Date.now() - startMs) / 1000) : 0;
84
+
85
+ const finalCheckpoint = {
86
+ reason: 'session_stop',
87
+ toolCount,
88
+ checkpointNumber: checkpointCount,
89
+ totalFiles: filesModified?.length || 0,
90
+ duration,
91
+ timestamp: new Date().toISOString(),
92
+ filesModified: (filesModified || []).slice(-MAX_FILES_TRACKED),
93
+ recentTools: (proj.recentTools || []).slice(-MAX_RECENT_TOOLS),
94
+ cwd,
95
+ };
96
+
97
+ safeWriteFile(
98
+ path.join(cpDir, 'latest.json'),
99
+ JSON.stringify(finalCheckpoint, null, 2)
100
+ );
101
+
102
+ // Output context-heavy message if 3+ checkpoints
103
+ if (checkpointCount >= 3) {
104
+ console.error(
105
+ `\nContext heavy (${checkpointCount} checkpoints, ${toolCount} tool calls). State saved. Consider /clear to reload from checkpoint.\n`
106
+ );
107
+ }
108
+
109
+ // Clean up session state file since session is ending
110
+ try {
111
+ fs.unlinkSync(STATE_FILE);
112
+ } catch {
113
+ // Best-effort cleanup
114
+ }
115
+ } catch {
116
+ // Silent fail -- never block the agent
117
+ }
118
+ }
119
+
120
+ main();