@stackmemoryai/stackmemory 1.2.2 → 1.2.4

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 (63) hide show
  1. package/dist/src/cli/codex-sm.js +6 -8
  2. package/dist/src/cli/commands/config.js +0 -81
  3. package/dist/src/cli/commands/context-rehydrate.js +133 -47
  4. package/dist/src/cli/commands/db.js +35 -8
  5. package/dist/src/cli/commands/handoff.js +1 -1
  6. package/dist/src/cli/commands/linear.js +9 -0
  7. package/dist/src/cli/commands/ralph.js +2 -2
  8. package/dist/src/cli/commands/setup.js +2 -2
  9. package/dist/src/cli/commands/signup.js +3 -1
  10. package/dist/src/cli/commands/storage-tier.js +26 -8
  11. package/dist/src/cli/index.js +1 -57
  12. package/dist/src/core/config/feature-flags.js +0 -4
  13. package/dist/src/core/context/dual-stack-manager.js +10 -3
  14. package/dist/src/core/context/frame-database.js +32 -0
  15. package/dist/src/core/context/frame-handoff-manager.js +2 -2
  16. package/dist/src/core/context/{refactored-frame-manager.js → frame-manager.js} +3 -3
  17. package/dist/src/core/context/index.js +2 -2
  18. package/dist/src/core/database/sqlite-adapter.js +161 -1
  19. package/dist/src/core/digest/frame-digest-integration.js +1 -1
  20. package/dist/src/core/digest/index.js +1 -1
  21. package/dist/src/core/execution/parallel-executor.js +5 -1
  22. package/dist/src/core/projects/project-isolation.js +18 -4
  23. package/dist/src/core/security/index.js +2 -0
  24. package/dist/src/core/security/input-sanitizer.js +23 -0
  25. package/dist/src/core/utils/update-checker.js +10 -6
  26. package/dist/src/daemon/daemon-config.js +2 -1
  27. package/dist/src/daemon/services/auto-save-service.js +121 -0
  28. package/dist/src/daemon/services/maintenance-service.js +76 -1
  29. package/dist/src/features/sweep/prompt-builder.js +2 -2
  30. package/dist/src/integrations/linear/config.js +3 -1
  31. package/dist/src/integrations/linear/sync.js +18 -5
  32. package/dist/src/integrations/mcp/handlers/code-execution-handlers.js +33 -7
  33. package/dist/src/integrations/mcp/handlers/cord-handlers.js +397 -0
  34. package/dist/src/integrations/mcp/handlers/index.js +55 -1
  35. package/dist/src/integrations/mcp/handlers/task-handlers.js +55 -12
  36. package/dist/src/integrations/mcp/handlers/team-handlers.js +211 -0
  37. package/dist/src/integrations/mcp/handlers/trace-handlers.js +25 -9
  38. package/dist/src/integrations/mcp/index.js +2 -2
  39. package/dist/src/integrations/mcp/refactored-server.js +31 -10
  40. package/dist/src/integrations/mcp/tool-definitions.js +215 -1
  41. package/dist/src/integrations/ralph/context/context-budget-manager.js +10 -2
  42. package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +54 -22
  43. package/dist/src/integrations/ralph/learning/pattern-learner.js +59 -24
  44. package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +81 -35
  45. package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +12 -4
  46. package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +32 -9
  47. package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +25 -8
  48. package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +17 -5
  49. package/dist/src/integrations/ralph/visualization/ralph-debugger.js +73 -22
  50. package/dist/src/skills/claude-skills.js +0 -102
  51. package/dist/src/utils/hook-installer.js +8 -0
  52. package/package.json +5 -5
  53. package/scripts/install-claude-hooks-auto.js +8 -0
  54. package/templates/claude-hooks/cord-trace.js +225 -0
  55. package/dist/src/core/config/storage-config.js +0 -114
  56. package/dist/src/core/storage/chromadb-adapter.js +0 -379
  57. package/dist/src/integrations/claude-code/enhanced-pre-clear-hooks.js +0 -458
  58. package/dist/src/integrations/ralph/coordination/enhanced-coordination.js +0 -409
  59. package/dist/src/skills/repo-ingestion-skill.js +0 -631
  60. package/templates/claude-hooks/chromadb-wrapper +0 -21
  61. /package/dist/src/core/context/{enhanced-rehydration.js → rehydration.js} +0 -0
  62. /package/dist/src/core/digest/{enhanced-hybrid-digest.js → hybrid-digest.js} +0 -0
  63. /package/dist/src/core/session/{enhanced-handoff.js → handoff.js} +0 -0
@@ -1,458 +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 { EventEmitter } from "events";
6
- import * as fs from "fs/promises";
7
- import * as path from "path";
8
- import { execSync } from "child_process";
9
- class EnhancedPreClearHooks extends EventEmitter {
10
- frameManager;
11
- dbManager;
12
- clearSurvival;
13
- handoffGenerator;
14
- projectRoot;
15
- constructor(frameManager, dbManager, clearSurvival, handoffGenerator, projectRoot) {
16
- super();
17
- this.frameManager = frameManager;
18
- this.dbManager = dbManager;
19
- this.clearSurvival = clearSurvival;
20
- this.handoffGenerator = handoffGenerator;
21
- this.projectRoot = projectRoot;
22
- }
23
- /**
24
- * Comprehensive pre-clear context capture
25
- */
26
- async capturePreClearContext(trigger) {
27
- console.log("\u{1F50D} Capturing comprehensive session context...");
28
- const context = {
29
- sessionId: await this.dbManager.getCurrentSessionId(),
30
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
31
- trigger,
32
- contextUsage: await this.analyzeContextUsage(),
33
- workingState: await this.captureWorkingState(),
34
- conversationState: await this.captureConversationState(),
35
- codeContext: await this.captureCodeContext(),
36
- cognitiveState: await this.captureCognitiveState(),
37
- environment: await this.captureEnvironment()
38
- };
39
- await this.saveEnhancedContext(context);
40
- this.emit("context:captured", context);
41
- console.log("\u2705 Comprehensive context captured");
42
- return context;
43
- }
44
- /**
45
- * Analyze current context usage with detailed breakdown
46
- */
47
- async analyzeContextUsage() {
48
- const sessionId = await this.dbManager.getCurrentSessionId();
49
- const frames = await this.dbManager.getRecentFrames(sessionId, 1e3);
50
- const traces = await this.dbManager.getRecentTraces(sessionId, 1e3);
51
- const frameTokens = frames.length * 200;
52
- const traceTokens = traces.length * 100;
53
- const conversationTokens = await this.estimateConversationTokens();
54
- const codeBlockTokens = await this.estimateCodeBlockTokens();
55
- const estimatedTokens = frameTokens + traceTokens + conversationTokens + codeBlockTokens;
56
- const maxTokens = 1e5;
57
- return {
58
- estimatedTokens,
59
- maxTokens,
60
- percentage: estimatedTokens / maxTokens,
61
- components: {
62
- frames: frameTokens,
63
- traces: traceTokens,
64
- conversations: conversationTokens,
65
- codeBlocks: codeBlockTokens
66
- }
67
- };
68
- }
69
- /**
70
- * Capture current working state
71
- */
72
- async captureWorkingState() {
73
- const activeFrame = await this.getCurrentActiveFrame();
74
- const recentTraces = await this.dbManager.getRecentTraces(
75
- await this.dbManager.getCurrentSessionId(),
76
- 50
77
- );
78
- const activeFiles = this.extractActiveFiles(recentTraces);
79
- const recentCommands = recentTraces.filter((t) => t.type === "bash" || t.type === "command").map((t) => t.content.command).slice(0, 10);
80
- const pendingActions = this.extractPendingActions(activeFrame);
81
- const blockers = this.extractBlockers(recentTraces);
82
- return {
83
- currentTask: activeFrame?.description || "No active task",
84
- activeFiles,
85
- recentCommands,
86
- pendingActions,
87
- blockers
88
- };
89
- }
90
- /**
91
- * Capture conversation state and recent context
92
- */
93
- async captureConversationState() {
94
- const sessionId = await this.dbManager.getCurrentSessionId();
95
- const recentTraces = await this.dbManager.getRecentTraces(sessionId, 100);
96
- const userMessages = recentTraces.filter((t) => t.type === "user_message" || t.type === "input").slice(0, 5);
97
- const assistantMessages = recentTraces.filter((t) => t.type === "assistant_message" || t.type === "response").slice(0, 5);
98
- const conversationTopic = this.inferConversationTopic(recentTraces);
99
- const recentContext = this.buildRecentContextSummary(recentTraces);
100
- return {
101
- lastUserMessage: userMessages[0]?.content.message || "No recent user message",
102
- lastAssistantMessage: assistantMessages[0]?.content.message || "No recent assistant message",
103
- conversationTopic,
104
- messageCount: userMessages.length + assistantMessages.length,
105
- recentContext
106
- };
107
- }
108
- /**
109
- * Capture comprehensive code context
110
- */
111
- async captureCodeContext() {
112
- const gitStatus = await this.captureGitStatus();
113
- const modifiedFiles = await this.captureModifiedFiles();
114
- const testResults = await this.captureTestResults();
115
- const buildStatus = await this.captureBuildStatus();
116
- const dependencies = await this.captureDependencies();
117
- return {
118
- modifiedFiles,
119
- gitStatus,
120
- testResults,
121
- buildStatus,
122
- dependencies
123
- };
124
- }
125
- /**
126
- * Capture cognitive state and mental model
127
- */
128
- async captureCognitiveState() {
129
- const sessionId = await this.dbManager.getCurrentSessionId();
130
- const recentTraces = await this.dbManager.getRecentTraces(sessionId, 100);
131
- const currentFocus = await this.extractCurrentFocus();
132
- const mentalModel = this.extractMentalModel(recentTraces);
133
- const assumptions = this.extractAssumptions(recentTraces);
134
- const hypotheses = this.extractHypotheses(recentTraces);
135
- const explorationPaths = this.extractExplorationPaths(recentTraces);
136
- return {
137
- currentFocus,
138
- mentalModel,
139
- assumptions,
140
- hypotheses,
141
- explorationPaths
142
- };
143
- }
144
- /**
145
- * Capture environment snapshot
146
- */
147
- async captureEnvironment() {
148
- const gitBranch = await this.getCurrentGitBranch();
149
- const packageJson = await this.getPackageJson();
150
- const environmentVars = this.getRelevantEnvVars();
151
- return {
152
- workingDirectory: this.projectRoot,
153
- gitBranch,
154
- nodeVersion: process.version,
155
- packageJson,
156
- environmentVars
157
- };
158
- }
159
- /**
160
- * Save enhanced context to multiple locations for reliability
161
- */
162
- async saveEnhancedContext(context) {
163
- const timestamp = context.timestamp.replace(/[:.]/g, "-");
164
- const primaryPath = path.join(
165
- this.projectRoot,
166
- ".stackmemory",
167
- "pre-clear",
168
- `context-${timestamp}.json`
169
- );
170
- const backupPath = path.join(
171
- this.projectRoot,
172
- ".stackmemory",
173
- "pre-clear",
174
- "latest-context.json"
175
- );
176
- const markdownPath = path.join(
177
- this.projectRoot,
178
- ".stackmemory",
179
- "pre-clear",
180
- `context-${timestamp}.md`
181
- );
182
- await fs.mkdir(path.dirname(primaryPath), { recursive: true });
183
- await fs.writeFile(primaryPath, JSON.stringify(context, null, 2), "utf-8");
184
- await fs.writeFile(backupPath, JSON.stringify(context, null, 2), "utf-8");
185
- const markdown = this.generateMarkdownSummary(context);
186
- await fs.writeFile(markdownPath, markdown, "utf-8");
187
- console.log(
188
- `\u{1F4C1} Context saved to ${path.relative(this.projectRoot, primaryPath)}`
189
- );
190
- }
191
- /**
192
- * Generate human-readable markdown summary
193
- */
194
- generateMarkdownSummary(context) {
195
- const lines = [
196
- `# Pre-Clear Context Snapshot`,
197
- `**Timestamp**: ${new Date(context.timestamp).toLocaleString()}`,
198
- `**Trigger**: ${context.trigger}`,
199
- `**Session ID**: ${context.sessionId}`,
200
- "",
201
- `## \u{1F4CA} Context Usage`,
202
- `- **Total Tokens**: ${context.contextUsage.estimatedTokens.toLocaleString()} / ${context.contextUsage.maxTokens.toLocaleString()} (${Math.round(context.contextUsage.percentage * 100)}%)`,
203
- `- **Frames**: ${context.contextUsage.components.frames} tokens`,
204
- `- **Traces**: ${context.contextUsage.components.traces} tokens`,
205
- `- **Conversations**: ${context.contextUsage.components.conversations} tokens`,
206
- `- **Code Blocks**: ${context.contextUsage.components.codeBlocks} tokens`,
207
- "",
208
- `## \u{1F3AF} Current Work State`,
209
- `**Task**: ${context.workingState.currentTask}`,
210
- `**Active Files** (${context.workingState.activeFiles.length}):`,
211
- ...context.workingState.activeFiles.slice(0, 10).map((f) => `- ${f}`),
212
- "",
213
- `**Recent Commands**:`,
214
- ...context.workingState.recentCommands.slice(0, 5).map((c) => `- \`${c}\``),
215
- "",
216
- `## \u{1F4AC} Conversation State`,
217
- `**Topic**: ${context.conversationState.conversationTopic}`,
218
- `**Messages**: ${context.conversationState.messageCount}`,
219
- `**Last User**: ${context.conversationState.lastUserMessage.substring(0, 100)}...`,
220
- "",
221
- `## \u{1F4DD} Code Context`,
222
- `**Git Branch**: ${context.codeContext.gitStatus.branch}`,
223
- `**Modified Files**: ${context.codeContext.modifiedFiles.length}`,
224
- `**Staged**: ${context.codeContext.gitStatus.staged.length}`,
225
- `**Unstaged**: ${context.codeContext.gitStatus.unstaged.length}`,
226
- "",
227
- `## \u{1F9E0} Cognitive State`,
228
- `**Current Focus**: ${context.cognitiveState.currentFocus}`,
229
- `**Mental Model**:`,
230
- ...context.cognitiveState.mentalModel.slice(0, 5).map((m) => `- ${m}`),
231
- "",
232
- `## \u{1F30D} Environment`,
233
- `**Directory**: ${context.environment.workingDirectory}`,
234
- `**Node Version**: ${context.environment.nodeVersion}`,
235
- `**Git Branch**: ${context.environment.gitBranch}`,
236
- ""
237
- ];
238
- return lines.filter((l) => l !== void 0).join("\n");
239
- }
240
- // Helper methods (simplified implementations)
241
- async estimateConversationTokens() {
242
- return 15e3;
243
- }
244
- async estimateCodeBlockTokens() {
245
- return 8e3;
246
- }
247
- async getCurrentActiveFrame() {
248
- const stack = await this.frameManager.getStack();
249
- return stack.frames.find((f) => f.status === "open");
250
- }
251
- extractActiveFiles(traces) {
252
- const files = /* @__PURE__ */ new Set();
253
- traces.forEach((trace) => {
254
- if (trace.content?.file_path) files.add(trace.content.file_path);
255
- if (trace.content?.path) files.add(trace.content.path);
256
- });
257
- return Array.from(files).slice(0, 20);
258
- }
259
- extractPendingActions(frame) {
260
- if (!frame?.metadata?.pendingActions) return [];
261
- return frame.metadata.pendingActions;
262
- }
263
- extractBlockers(traces) {
264
- return traces.filter((t) => t.type === "error" && !t.metadata?.resolved).map((t) => t.content.error || "Unknown error").slice(0, 5);
265
- }
266
- inferConversationTopic(traces) {
267
- return "Code implementation and debugging";
268
- }
269
- buildRecentContextSummary(traces) {
270
- return traces.slice(0, 10).map(
271
- (t) => `${t.type}: ${t.content.summary || t.content.description || "No description"}`
272
- ).filter((s) => s.length > 10);
273
- }
274
- async captureGitStatus() {
275
- try {
276
- const branch = execSync("git branch --show-current", {
277
- encoding: "utf-8",
278
- cwd: this.projectRoot
279
- }).trim();
280
- const staged = execSync("git diff --cached --name-only", {
281
- encoding: "utf-8",
282
- cwd: this.projectRoot
283
- }).trim().split("\n").filter(Boolean);
284
- const unstaged = execSync("git diff --name-only", {
285
- encoding: "utf-8",
286
- cwd: this.projectRoot
287
- }).trim().split("\n").filter(Boolean);
288
- const untracked = execSync("git ls-files --others --exclude-standard", {
289
- encoding: "utf-8",
290
- cwd: this.projectRoot
291
- }).trim().split("\n").filter(Boolean);
292
- return {
293
- branch,
294
- ahead: 0,
295
- // Would implement git status parsing
296
- behind: 0,
297
- staged,
298
- unstaged,
299
- untracked,
300
- lastCommit: {
301
- hash: "abc123",
302
- // Would get from git log
303
- message: "Recent commit",
304
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
305
- }
306
- };
307
- } catch (error) {
308
- return {
309
- branch: "unknown",
310
- ahead: 0,
311
- behind: 0,
312
- staged: [],
313
- unstaged: [],
314
- untracked: [],
315
- lastCommit: { hash: "", message: "", timestamp: "" }
316
- };
317
- }
318
- }
319
- async captureModifiedFiles() {
320
- try {
321
- const output = execSync("git diff --name-status", {
322
- encoding: "utf-8",
323
- cwd: this.projectRoot
324
- });
325
- return output.trim().split("\n").filter(Boolean).map((line) => {
326
- const [status, path2] = line.split(" ");
327
- return {
328
- path: path2,
329
- lastModified: (/* @__PURE__ */ new Date()).toISOString(),
330
- changeType: status === "A" ? "created" : status === "D" ? "deleted" : "modified",
331
- lineChanges: { added: 0, removed: 0 },
332
- // Would get from git diff --stat
333
- purpose: "Code changes",
334
- relatedFiles: []
335
- };
336
- });
337
- } catch (error) {
338
- return [];
339
- }
340
- }
341
- async captureTestResults() {
342
- return void 0;
343
- }
344
- async captureBuildStatus() {
345
- return void 0;
346
- }
347
- async captureDependencies() {
348
- try {
349
- const packageJsonPath = path.join(this.projectRoot, "package.json");
350
- const content = await fs.readFile(packageJsonPath, "utf-8");
351
- const packageJson = JSON.parse(content);
352
- const deps = [];
353
- Object.entries(packageJson.dependencies || {}).forEach(
354
- ([name, version]) => {
355
- deps.push({
356
- name,
357
- version,
358
- type: "dependency",
359
- critical: ["react", "express", "next"].includes(name)
360
- });
361
- }
362
- );
363
- return deps;
364
- } catch (error) {
365
- return [];
366
- }
367
- }
368
- async extractCurrentFocus() {
369
- const activeFrame = await this.getCurrentActiveFrame();
370
- return activeFrame?.description || "No current focus";
371
- }
372
- extractMentalModel(traces) {
373
- return [
374
- "Component architecture",
375
- "Data flow patterns",
376
- "Error handling strategy"
377
- ];
378
- }
379
- extractAssumptions(traces) {
380
- return [
381
- "User input is validated",
382
- "Database is available",
383
- "Network is stable"
384
- ];
385
- }
386
- extractHypotheses(traces) {
387
- return [
388
- "Bug is in validation logic",
389
- "Performance issue is database-related"
390
- ];
391
- }
392
- extractExplorationPaths(traces) {
393
- return [
394
- "Try different algorithm",
395
- "Refactor data structure",
396
- "Add caching layer"
397
- ];
398
- }
399
- async getCurrentGitBranch() {
400
- try {
401
- return execSync("git branch --show-current", {
402
- encoding: "utf-8",
403
- cwd: this.projectRoot
404
- }).trim();
405
- } catch (error) {
406
- return "unknown";
407
- }
408
- }
409
- async getPackageJson() {
410
- try {
411
- const content = await fs.readFile(
412
- path.join(this.projectRoot, "package.json"),
413
- "utf-8"
414
- );
415
- return JSON.parse(content);
416
- } catch (error) {
417
- return null;
418
- }
419
- }
420
- getRelevantEnvVars() {
421
- const relevantVars = ["NODE_ENV", "DEBUG", "PORT", "DATABASE_URL"];
422
- const result = {};
423
- relevantVars.forEach((varName) => {
424
- if (process.env[varName]) {
425
- result[varName] = process.env[varName];
426
- }
427
- });
428
- return result;
429
- }
430
- /**
431
- * Restore context after /clear
432
- */
433
- async restoreFromEnhancedContext() {
434
- const latestPath = path.join(
435
- this.projectRoot,
436
- ".stackmemory",
437
- "pre-clear",
438
- "latest-context.json"
439
- );
440
- try {
441
- const content = await fs.readFile(latestPath, "utf-8");
442
- const context = JSON.parse(content);
443
- console.log("\u{1F4DA} Restoring enhanced context...");
444
- console.log(` Session: ${context.sessionId}`);
445
- console.log(` Task: ${context.workingState.currentTask}`);
446
- console.log(` Files: ${context.workingState.activeFiles.length}`);
447
- console.log(` Focus: ${context.cognitiveState.currentFocus}`);
448
- await this.clearSurvival.restoreFromLedger();
449
- return true;
450
- } catch (error) {
451
- console.error("Failed to restore enhanced context:", error);
452
- return false;
453
- }
454
- }
455
- }
456
- export {
457
- EnhancedPreClearHooks
458
- };