@stackmemoryai/stackmemory 1.2.1 → 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.
- package/dist/src/cli/codex-sm.js +6 -8
- package/dist/src/cli/commands/config.js +0 -81
- package/dist/src/cli/commands/context-rehydrate.js +133 -47
- package/dist/src/cli/commands/db.js +35 -8
- package/dist/src/cli/commands/handoff.js +1 -1
- package/dist/src/cli/commands/linear.js +9 -0
- package/dist/src/cli/commands/ralph.js +2 -2
- package/dist/src/cli/commands/setup.js +2 -2
- package/dist/src/cli/commands/signup.js +3 -1
- package/dist/src/cli/commands/skills.js +123 -1
- package/dist/src/cli/commands/storage-tier.js +26 -8
- package/dist/src/cli/index.js +1 -57
- package/dist/src/core/config/feature-flags.js +0 -4
- package/dist/src/core/context/dual-stack-manager.js +10 -3
- package/dist/src/core/context/frame-database.js +32 -0
- package/dist/src/core/context/frame-handoff-manager.js +2 -2
- package/dist/src/core/context/{refactored-frame-manager.js → frame-manager.js} +3 -3
- package/dist/src/core/context/index.js +2 -2
- package/dist/src/core/database/sqlite-adapter.js +161 -1
- package/dist/src/core/digest/frame-digest-integration.js +1 -1
- package/dist/src/core/digest/index.js +1 -1
- package/dist/src/core/execution/parallel-executor.js +5 -1
- package/dist/src/core/projects/project-isolation.js +18 -4
- package/dist/src/core/security/index.js +2 -0
- package/dist/src/core/security/input-sanitizer.js +23 -0
- package/dist/src/core/utils/update-checker.js +10 -6
- package/dist/src/daemon/daemon-config.js +2 -1
- package/dist/src/daemon/services/auto-save-service.js +121 -0
- package/dist/src/daemon/services/maintenance-service.js +76 -1
- package/dist/src/features/sweep/prompt-builder.js +2 -2
- package/dist/src/hooks/graphiti-hooks.js +149 -0
- package/dist/src/hooks/session-summary.js +30 -0
- package/dist/src/integrations/graphiti/linear-graphiti-bridge.js +115 -0
- package/dist/src/integrations/greptile/client.js +101 -0
- package/dist/src/integrations/greptile/config.js +14 -0
- package/dist/src/integrations/greptile/index.js +11 -0
- package/dist/src/integrations/greptile/types.js +4 -0
- package/dist/src/integrations/linear/config.js +3 -1
- package/dist/src/integrations/linear/sync.js +18 -5
- package/dist/src/integrations/linear/webhook.js +16 -0
- package/dist/src/integrations/mcp/handlers/code-execution-handlers.js +33 -7
- package/dist/src/integrations/mcp/handlers/cord-handlers.js +397 -0
- package/dist/src/integrations/mcp/handlers/greptile-handlers.js +456 -0
- package/dist/src/integrations/mcp/handlers/index.js +55 -1
- package/dist/src/integrations/mcp/handlers/task-handlers.js +55 -12
- package/dist/src/integrations/mcp/handlers/team-handlers.js +211 -0
- package/dist/src/integrations/mcp/handlers/trace-handlers.js +25 -9
- package/dist/src/integrations/mcp/index.js +2 -2
- package/dist/src/integrations/mcp/refactored-server.js +31 -10
- package/dist/src/integrations/mcp/server.js +27 -0
- package/dist/src/integrations/mcp/tool-definitions.js +215 -1
- package/dist/src/integrations/ralph/context/context-budget-manager.js +10 -2
- package/dist/src/integrations/ralph/context/stackmemory-context-loader.js +54 -22
- package/dist/src/integrations/ralph/learning/pattern-learner.js +59 -24
- package/dist/src/integrations/ralph/orchestration/multi-loop-orchestrator.js +81 -35
- package/dist/src/integrations/ralph/patterns/compounding-engineering-pattern.js +12 -4
- package/dist/src/integrations/ralph/patterns/extended-coherence-sessions.js +32 -9
- package/dist/src/integrations/ralph/swarm/git-workflow-manager.js +25 -8
- package/dist/src/integrations/ralph/swarm/swarm-coordinator.js +17 -5
- package/dist/src/integrations/ralph/visualization/ralph-debugger.js +73 -22
- package/dist/src/skills/claude-skills.js +46 -103
- package/dist/src/skills/parallel-agent-skill.js +514 -0
- package/dist/src/utils/hook-installer.js +8 -0
- package/package.json +5 -5
- package/scripts/gepa/.before-optimize.md +140 -159
- package/scripts/gepa/config.json +7 -1
- package/scripts/gepa/evals/fixtures/api-endpoint.ts +31 -0
- package/scripts/gepa/evals/fixtures/brittle-integration.ts +38 -0
- package/scripts/gepa/evals/fixtures/fts5-triggers.sql +23 -0
- package/scripts/gepa/evals/fixtures/leaky-service.ts +70 -0
- package/scripts/gepa/evals/fixtures/mcp-dispatch-stub.ts +39 -0
- package/scripts/gepa/evals/fixtures/pr-diff.txt +24 -0
- package/scripts/gepa/evals/fixtures/unsafe-webhook.ts +34 -0
- package/scripts/gepa/evals/fixtures/unwrapped-db-op.ts +42 -0
- package/scripts/gepa/evals/stackmemory-tasks.jsonl +8 -0
- package/scripts/gepa/generations/gen-000/baseline.md +172 -159
- package/scripts/gepa/generations/gen-001/baseline.md +172 -159
- package/scripts/gepa/generations/gen-001/variant-a.md +156 -146
- package/scripts/gepa/generations/gen-001/variant-b.md +199 -170
- package/scripts/gepa/generations/gen-001/variant-c.md +127 -46
- package/scripts/gepa/generations/gen-001/variant-d.md +160 -107
- package/scripts/gepa/hooks/reflect.js +44 -5
- package/scripts/gepa/optimize.js +281 -39
- package/scripts/gepa/results/eval-1-baseline.json +187 -10
- package/scripts/gepa/results/eval-1-variant-a.json +188 -11
- package/scripts/gepa/results/eval-1-variant-b.json +188 -11
- package/scripts/gepa/results/eval-1-variant-c.json +168 -11
- package/scripts/gepa/results/eval-1-variant-d.json +169 -12
- package/scripts/gepa/state.json +18 -18
- package/scripts/install-claude-hooks-auto.js +8 -0
- package/templates/claude-hooks/cord-trace.js +225 -0
- package/dist/src/core/config/storage-config.js +0 -114
- package/dist/src/core/storage/chromadb-adapter.js +0 -379
- package/dist/src/integrations/claude-code/enhanced-pre-clear-hooks.js +0 -458
- package/dist/src/integrations/ralph/coordination/enhanced-coordination.js +0 -409
- package/dist/src/skills/repo-ingestion-skill.js +0 -631
- package/templates/claude-hooks/chromadb-wrapper +0 -21
- /package/dist/src/core/context/{enhanced-rehydration.js → rehydration.js} +0 -0
- /package/dist/src/core/digest/{enhanced-hybrid-digest.js → hybrid-digest.js} +0 -0
- /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
|
-
};
|