@vedtechsolutions/engram-mcp 1.0.20 → 1.0.22
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/hook.js +86 -11
- package/package.json +1 -1
package/dist/hook.js
CHANGED
|
@@ -3250,13 +3250,29 @@ function sanitizeCognitiveState(state) {
|
|
|
3250
3250
|
const cog = state.cognitive_state;
|
|
3251
3251
|
if (!cog) return;
|
|
3252
3252
|
const placeholders = ["X", "X.", "Y", "Y.", "Z", "Z."];
|
|
3253
|
-
|
|
3253
|
+
const templatePatterns = [
|
|
3254
|
+
/^X[\.\s]/,
|
|
3255
|
+
// Starts with X. or X<space>
|
|
3256
|
+
/^Approach:\s*X/i,
|
|
3257
|
+
// "Approach: X..."
|
|
3258
|
+
/Hypothesis:\s*[XYZ][\.\s]/,
|
|
3259
|
+
// Contains "Hypothesis: X."
|
|
3260
|
+
/Discovery:\s*[XYZ][\.\s]/,
|
|
3261
|
+
// Contains "Discovery: Z."
|
|
3262
|
+
/^[XYZ]\.\s+(?:Hypothesis|Discovery|Approach):/i
|
|
3263
|
+
// "X. Hypothesis: Y..."
|
|
3264
|
+
];
|
|
3265
|
+
const isPlaceholderValue = (val) => {
|
|
3266
|
+
if (placeholders.includes(val)) return true;
|
|
3267
|
+
return templatePatterns.some((p) => p.test(val));
|
|
3268
|
+
};
|
|
3269
|
+
if (cog.current_approach && isPlaceholderValue(cog.current_approach)) {
|
|
3254
3270
|
cog.current_approach = null;
|
|
3255
3271
|
}
|
|
3256
|
-
if (cog.active_hypothesis &&
|
|
3272
|
+
if (cog.active_hypothesis && isPlaceholderValue(cog.active_hypothesis)) {
|
|
3257
3273
|
cog.active_hypothesis = null;
|
|
3258
3274
|
}
|
|
3259
|
-
if (cog.recent_discovery &&
|
|
3275
|
+
if (cog.recent_discovery && isPlaceholderValue(cog.recent_discovery)) {
|
|
3260
3276
|
cog.recent_discovery = null;
|
|
3261
3277
|
}
|
|
3262
3278
|
if (cog.active_hypothesis && cog.active_hypothesis.startsWith("/")) {
|
|
@@ -3285,11 +3301,35 @@ function sanitizeCognitiveState(state) {
|
|
|
3285
3301
|
}
|
|
3286
3302
|
}
|
|
3287
3303
|
}
|
|
3304
|
+
if (cog.recent_discovery && cog.recent_discovery.length < 15 && !cog.recent_discovery.includes(" ")) {
|
|
3305
|
+
cog.recent_discovery = null;
|
|
3306
|
+
}
|
|
3307
|
+
if (cog.recent_discovery && /^that\s/i.test(cog.recent_discovery) && cog.recent_discovery.length < 40) {
|
|
3308
|
+
cog.recent_discovery = null;
|
|
3309
|
+
}
|
|
3288
3310
|
if (state.active_task && state.active_task.startsWith("<")) {
|
|
3289
3311
|
state.active_task = null;
|
|
3290
3312
|
}
|
|
3313
|
+
if (state.active_task) {
|
|
3314
|
+
const conversationalPatterns = [
|
|
3315
|
+
/^i have another/i,
|
|
3316
|
+
/^just letting you/i,
|
|
3317
|
+
/^just a quick/i,
|
|
3318
|
+
/^now tell me/i,
|
|
3319
|
+
/^do another final/i,
|
|
3320
|
+
/^reviewing$/i
|
|
3321
|
+
// Generic tool-inferred task, not specific
|
|
3322
|
+
];
|
|
3323
|
+
if (conversationalPatterns.some((p) => p.test(state.active_task))) {
|
|
3324
|
+
state.active_task = null;
|
|
3325
|
+
}
|
|
3326
|
+
}
|
|
3291
3327
|
if (!state.active_task || state.active_task === "unknown task") {
|
|
3292
|
-
const editedFiles = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write").map((a) =>
|
|
3328
|
+
const editedFiles = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write").map((a) => {
|
|
3329
|
+
const arrowIdx = a.target.indexOf(" \u2192");
|
|
3330
|
+
const path = arrowIdx > 0 ? a.target.slice(0, arrowIdx) : a.target;
|
|
3331
|
+
return path.split(/[/\\]/).pop() ?? path;
|
|
3332
|
+
});
|
|
3293
3333
|
const uniqueFiles = [...new Set(editedFiles)].slice(-5);
|
|
3294
3334
|
if (uniqueFiles.length > 0) {
|
|
3295
3335
|
if (cog.current_approach && cog.current_approach.length >= 10) {
|
|
@@ -3298,6 +3338,27 @@ function sanitizeCognitiveState(state) {
|
|
|
3298
3338
|
state.active_task = `Working on ${uniqueFiles.join(", ")}`;
|
|
3299
3339
|
}
|
|
3300
3340
|
}
|
|
3341
|
+
if (!state.active_task && state.recent_prompts && state.recent_prompts.length > 0) {
|
|
3342
|
+
const taskVerbs = /^(fix|add|create|update|implement|remove|refactor|build|change|move|write|make|set|run|deploy|test|commit|push|install|configure|debug|solve|enable|disable|start|stop|check|verify|analyze|review|audit|optimize|clean|delete|migrate|upgrade|publish|get|do|finish)/i;
|
|
3343
|
+
for (let i = state.recent_prompts.length - 1; i >= 0; i--) {
|
|
3344
|
+
const prompt = state.recent_prompts[i];
|
|
3345
|
+
const first = prompt.split(/[.!?\n]/)[0]?.trim();
|
|
3346
|
+
if (first && first.length >= 15 && first.length <= 200 && taskVerbs.test(first)) {
|
|
3347
|
+
state.active_task = first;
|
|
3348
|
+
break;
|
|
3349
|
+
}
|
|
3350
|
+
}
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3353
|
+
if (state.session_files.length > 0) {
|
|
3354
|
+
state.session_files = state.session_files.filter((f) => {
|
|
3355
|
+
if (f.length < 3 || f.length > 500) return false;
|
|
3356
|
+
if (!f.includes("/") && !f.includes("\\")) return false;
|
|
3357
|
+
if (f.includes("/../") || f.startsWith("../")) return false;
|
|
3358
|
+
if (/^\/?\d+\.\d+/.test(f)) return false;
|
|
3359
|
+
if (f === "/root/.ssh" || f.includes("/etc/cron")) return false;
|
|
3360
|
+
return true;
|
|
3361
|
+
});
|
|
3301
3362
|
}
|
|
3302
3363
|
}
|
|
3303
3364
|
function deleteSessionState() {
|
|
@@ -5449,6 +5510,9 @@ function handleSubagentStop(stdinJson) {
|
|
|
5449
5510
|
const fileMatches = lastMessage.match(/(?:\/[\w./+-]+\.\w+|[\w./+-]+\.(?:ts|js|py|xml|json|css|scss|md))/g);
|
|
5450
5511
|
if (fileMatches) {
|
|
5451
5512
|
for (const f of fileMatches) {
|
|
5513
|
+
if (!f.includes("/")) continue;
|
|
5514
|
+
if (f.includes("/../") || f.startsWith("../") || /^\/?\d+\.\d+/.test(f)) continue;
|
|
5515
|
+
if (f === "/root/.ssh" || f.includes("/etc/cron")) continue;
|
|
5452
5516
|
if (!state.session_files.includes(f)) {
|
|
5453
5517
|
state.session_files.push(f);
|
|
5454
5518
|
}
|
|
@@ -5457,7 +5521,7 @@ function handleSubagentStop(stdinJson) {
|
|
|
5457
5521
|
state.session_files = state.session_files.slice(-50);
|
|
5458
5522
|
}
|
|
5459
5523
|
}
|
|
5460
|
-
const isMetaAnalysis = lastMessage.startsWith("<analysis>") || lastMessage.startsWith("<summary>") || /^#+\s/.test(lastMessage) || lastMessage.startsWith("Based on ");
|
|
5524
|
+
const isMetaAnalysis = lastMessage.startsWith("<analysis>") || lastMessage.startsWith("<summary>") || /^#+\s/.test(lastMessage) || lastMessage.startsWith("Based on ") || /^(I now have|Perfect!|I have (sufficient|enough|comprehensive))/i.test(lastMessage) || /^(Here('s| is) (the|my|a) (comprehensive|complete|detailed|full))/i.test(lastMessage) || lastMessage.includes("## ") && lastMessage.length > 500;
|
|
5461
5525
|
const hasError = !isMetaAnalysis && containsError(lastMessage);
|
|
5462
5526
|
if (hasError) {
|
|
5463
5527
|
state.recent_errors.push(truncate(lastMessage, 200));
|
|
@@ -5696,13 +5760,20 @@ function buildContinuationBrief(state) {
|
|
|
5696
5760
|
for (const id of state.decision_memory_ids.slice(-5)) {
|
|
5697
5761
|
try {
|
|
5698
5762
|
const mem = getMemory(id);
|
|
5699
|
-
if (mem)
|
|
5763
|
+
if (mem) {
|
|
5764
|
+
const content = mem.content;
|
|
5765
|
+
if (/^Delegated:|^Decision:\s*Delegated/i.test(content)) continue;
|
|
5766
|
+
decisions.push(truncate(content, 150));
|
|
5767
|
+
}
|
|
5700
5768
|
} catch {
|
|
5701
5769
|
}
|
|
5702
5770
|
}
|
|
5703
5771
|
const triedFailed = (state.session_outcomes ?? []).filter((o) => o.includes("\u2192 fail") || o.includes("\u2192 dead end") || o.includes("\u2192 blocked")).slice(-5).map((o) => truncate(o, 120));
|
|
5704
5772
|
const editActions = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write");
|
|
5705
|
-
const keyFiles = [...new Set(editActions.map((a) =>
|
|
5773
|
+
const keyFiles = [...new Set(editActions.map((a) => {
|
|
5774
|
+
const arrowIdx = a.target.indexOf(" \u2192");
|
|
5775
|
+
return arrowIdx > 0 ? a.target.slice(0, arrowIdx) : a.target;
|
|
5776
|
+
}))].slice(-10);
|
|
5706
5777
|
const recentBash = state.recent_commands?.slice(-5) ?? [];
|
|
5707
5778
|
if (recentBash.length > 0) {
|
|
5708
5779
|
const bashSummary = recentBash.map((c) => truncate(c.cmd, 80));
|
|
@@ -6334,7 +6405,7 @@ ${distillLines}`
|
|
|
6334
6405
|
}
|
|
6335
6406
|
if (content.length >= 30 && content.length <= 500 && !content.startsWith("<")) {
|
|
6336
6407
|
const firstSentence = content.split(/[.!?\n]/)[0]?.trim();
|
|
6337
|
-
const isTaskLike = firstSentence && /^(fix|add|create|update|implement|remove|refactor|build|change|move|write|make|set|run|deploy|test|commit|push|install|configure|debug|solve|close|merge|release)/i.test(firstSentence);
|
|
6408
|
+
const isTaskLike = firstSentence && /^(fix|add|create|update|implement|remove|refactor|build|change|move|write|make|set|run|deploy|test|commit|push|install|configure|debug|solve|close|merge|release|enable|disable|start|stop|check|verify|analyze|review|audit|optimize|clean|delete|migrate|upgrade|publish|get|do|finish)/i.test(firstSentence);
|
|
6338
6409
|
if (isTaskLike && firstSentence.length >= 15 && firstSentence.length <= 200) {
|
|
6339
6410
|
state.active_task = firstSentence;
|
|
6340
6411
|
}
|
|
@@ -7131,10 +7202,14 @@ function handlePostCompact(stdinJson) {
|
|
|
7131
7202
|
if (!recovery) return;
|
|
7132
7203
|
const budget = new OutputBudget(OUTPUT_BUDGET.POST_COMPACT_MAX_BYTES);
|
|
7133
7204
|
const lines = [];
|
|
7134
|
-
|
|
7135
|
-
|
|
7205
|
+
sanitizeCognitiveState(state);
|
|
7206
|
+
const brief = buildContinuationBrief(state);
|
|
7207
|
+
const briefUsable = brief.task !== "unknown task" || brief.last_actions.length > 0;
|
|
7208
|
+
if (briefUsable) {
|
|
7136
7209
|
const mindLines = ["[Engram] Continue from where you left off:"];
|
|
7137
|
-
|
|
7210
|
+
if (brief.task !== "unknown task") {
|
|
7211
|
+
mindLines.push(` Task: ${brief.task}`);
|
|
7212
|
+
}
|
|
7138
7213
|
mindLines.push(` Phase: ${brief.phase}`);
|
|
7139
7214
|
if (brief.last_actions.length > 0) {
|
|
7140
7215
|
mindLines.push(` Last actions:`);
|