@vedtechsolutions/engram-mcp 1.0.6 → 1.0.7
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 +139 -30
- package/package.json +1 -1
package/dist/hook.js
CHANGED
|
@@ -1793,8 +1793,18 @@ function extractGoal(params) {
|
|
|
1793
1793
|
const topFiles = params.session_files.slice(-3).map((f) => f.split(/[/\\]/).pop() ?? f).join(", ");
|
|
1794
1794
|
return `${params.cognitive_state.recent_discovery} (${topFiles})`;
|
|
1795
1795
|
}
|
|
1796
|
+
if (params.session_files && params.session_files.length > 0) {
|
|
1797
|
+
const topFiles = params.session_files.slice(-5).map((f) => f.split(/[/\\]/).pop() ?? f).join(", ");
|
|
1798
|
+
return `modifying ${topFiles}`;
|
|
1799
|
+
}
|
|
1796
1800
|
if (params.conversation.topic_history.length > 0) {
|
|
1797
|
-
|
|
1801
|
+
const topic = params.conversation.topic_history[0].topic;
|
|
1802
|
+
const commaCount = (topic.match(/,/g) || []).length;
|
|
1803
|
+
const wordCount = topic.split(/\s+/).length;
|
|
1804
|
+
const isVagueKeywordList = commaCount >= 2 && wordCount <= commaCount + 2;
|
|
1805
|
+
if (!isVagueKeywordList) {
|
|
1806
|
+
return topic;
|
|
1807
|
+
}
|
|
1798
1808
|
}
|
|
1799
1809
|
return null;
|
|
1800
1810
|
}
|
|
@@ -3127,7 +3137,9 @@ function loadWatcherState() {
|
|
|
3127
3137
|
offload_message_sent: raw.offload_message_sent ?? false,
|
|
3128
3138
|
summary_injection_mode: raw.summary_injection_mode ?? false,
|
|
3129
3139
|
recent_commands: raw.recent_commands ?? [],
|
|
3130
|
-
procedural_encoded_count: raw.procedural_encoded_count ?? 0
|
|
3140
|
+
procedural_encoded_count: raw.procedural_encoded_count ?? 0,
|
|
3141
|
+
recent_actions: raw.recent_actions ?? [],
|
|
3142
|
+
continuation_brief: raw.continuation_brief ?? null
|
|
3131
3143
|
};
|
|
3132
3144
|
}
|
|
3133
3145
|
} catch {
|
|
@@ -3191,7 +3203,9 @@ function loadWatcherState() {
|
|
|
3191
3203
|
offload_message_sent: false,
|
|
3192
3204
|
summary_injection_mode: false,
|
|
3193
3205
|
recent_commands: [],
|
|
3194
|
-
procedural_encoded_count: 0
|
|
3206
|
+
procedural_encoded_count: 0,
|
|
3207
|
+
recent_actions: [],
|
|
3208
|
+
continuation_brief: null
|
|
3195
3209
|
};
|
|
3196
3210
|
}
|
|
3197
3211
|
function saveWatcherState(state) {
|
|
@@ -3628,6 +3642,14 @@ Output: ${truncate(toolOutput, 500)}`,
|
|
|
3628
3642
|
if (state.recent_tool_names.length > 10) {
|
|
3629
3643
|
state.recent_tool_names = state.recent_tool_names.slice(-10);
|
|
3630
3644
|
}
|
|
3645
|
+
state.recent_actions.push({
|
|
3646
|
+
tool: "Bash",
|
|
3647
|
+
target: truncate(cmd, 120),
|
|
3648
|
+
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
3649
|
+
});
|
|
3650
|
+
if (state.recent_actions.length > 15) {
|
|
3651
|
+
state.recent_actions = state.recent_actions.slice(-15);
|
|
3652
|
+
}
|
|
3631
3653
|
stateChanged = true;
|
|
3632
3654
|
let testRun = null;
|
|
3633
3655
|
if (isTestCommand(cmd)) {
|
|
@@ -4111,6 +4133,14 @@ function handlePostWrite(toolInput, argFallback) {
|
|
|
4111
4133
|
const filePath = input?.file_path ?? input?.path ?? "";
|
|
4112
4134
|
if (!filePath) return;
|
|
4113
4135
|
const state = loadWatcherState();
|
|
4136
|
+
state.recent_actions.push({
|
|
4137
|
+
tool: "Edit",
|
|
4138
|
+
target: filePath,
|
|
4139
|
+
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
4140
|
+
});
|
|
4141
|
+
if (state.recent_actions.length > 15) {
|
|
4142
|
+
state.recent_actions = state.recent_actions.slice(-15);
|
|
4143
|
+
}
|
|
4114
4144
|
if (typeof filePath === "string" && !state.session_files.includes(filePath)) {
|
|
4115
4145
|
state.session_files.push(filePath);
|
|
4116
4146
|
if (state.session_files.length > 50) {
|
|
@@ -4254,6 +4284,16 @@ function handlePostToolGeneric(stdinJson) {
|
|
|
4254
4284
|
if (state.recent_tool_names.length > 10) {
|
|
4255
4285
|
state.recent_tool_names = state.recent_tool_names.slice(-10);
|
|
4256
4286
|
}
|
|
4287
|
+
if (toolName !== "Read" && toolName !== "Glob" && toolName !== "Grep") {
|
|
4288
|
+
state.recent_actions.push({
|
|
4289
|
+
tool: toolName,
|
|
4290
|
+
target: call.input_summary ?? "",
|
|
4291
|
+
time: (/* @__PURE__ */ new Date()).toISOString()
|
|
4292
|
+
});
|
|
4293
|
+
if (state.recent_actions.length > 15) {
|
|
4294
|
+
state.recent_actions = state.recent_actions.slice(-15);
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4257
4297
|
state.reasoning_buffer.push(call);
|
|
4258
4298
|
if (state.reasoning_buffer.length > REASONING_TRACE.MAX_BUFFER_SIZE) {
|
|
4259
4299
|
state.reasoning_buffer = state.reasoning_buffer.slice(-REASONING_TRACE.MAX_BUFFER_SIZE);
|
|
@@ -4940,7 +4980,9 @@ function handleSessionStart(stdinJson, argFallback) {
|
|
|
4940
4980
|
offload_message_sent: false,
|
|
4941
4981
|
summary_injection_mode: false,
|
|
4942
4982
|
recent_commands: isPostCompact ? prevState?.recent_commands ?? [] : [],
|
|
4943
|
-
procedural_encoded_count: isPostCompact ? prevState?.procedural_encoded_count ?? 0 : 0
|
|
4983
|
+
procedural_encoded_count: isPostCompact ? prevState?.procedural_encoded_count ?? 0 : 0,
|
|
4984
|
+
recent_actions: isPostCompact ? prevState?.recent_actions ?? [] : [],
|
|
4985
|
+
continuation_brief: isPostCompact ? prevState?.continuation_brief ?? null : null
|
|
4944
4986
|
});
|
|
4945
4987
|
const source = metadata.source;
|
|
4946
4988
|
if (!source || source === "startup") {
|
|
@@ -5540,6 +5582,50 @@ function handleEngramUsed(stdinJson, argFallback) {
|
|
|
5540
5582
|
}
|
|
5541
5583
|
saveWatcherState(state);
|
|
5542
5584
|
}
|
|
5585
|
+
function buildContinuationBrief(state) {
|
|
5586
|
+
const cog = state.cognitive_state;
|
|
5587
|
+
const task = state.active_task ?? cog.current_approach ?? (state.session_files.length > 0 ? `Working on ${state.session_files.slice(-3).map((f) => f.split(/[/\\]/).pop() ?? f).join(", ")}` : "unknown task");
|
|
5588
|
+
const lastActions = state.recent_actions.slice(-8).map((a) => {
|
|
5589
|
+
const fileName = a.target.includes("/") ? a.target.split(/[/\\]/).pop() ?? a.target : a.target;
|
|
5590
|
+
return `${a.tool}: ${truncate(fileName, 80)}`;
|
|
5591
|
+
});
|
|
5592
|
+
const nextSteps = [];
|
|
5593
|
+
if (cog.search_intent && !nextSteps.some((s) => s.includes(cog.search_intent))) {
|
|
5594
|
+
nextSteps.push(`Investigate: ${cog.search_intent}`);
|
|
5595
|
+
}
|
|
5596
|
+
const lastAction = state.recent_actions[state.recent_actions.length - 1];
|
|
5597
|
+
if (lastAction && nextSteps.length === 0) {
|
|
5598
|
+
if (lastAction.tool === "Edit" || lastAction.tool === "Write") {
|
|
5599
|
+
nextSteps.push("Run tests to verify changes");
|
|
5600
|
+
} else if (lastAction.tool === "Bash" && lastAction.target.includes("test")) {
|
|
5601
|
+
nextSteps.push("Review test results and commit if passing");
|
|
5602
|
+
}
|
|
5603
|
+
}
|
|
5604
|
+
if (state.recent_errors.length > 0 && nextSteps.length < 3) {
|
|
5605
|
+
nextSteps.push(`Fix: ${truncate(state.recent_errors[state.recent_errors.length - 1], 120)}`);
|
|
5606
|
+
}
|
|
5607
|
+
const decisions = [];
|
|
5608
|
+
for (const id of state.decision_memory_ids.slice(-5)) {
|
|
5609
|
+
try {
|
|
5610
|
+
const mem = getMemory(id);
|
|
5611
|
+
if (mem) decisions.push(truncate(mem.content, 150));
|
|
5612
|
+
} catch {
|
|
5613
|
+
}
|
|
5614
|
+
}
|
|
5615
|
+
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));
|
|
5616
|
+
const editActions = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write");
|
|
5617
|
+
const keyFiles = [...new Set(editActions.map((a) => a.target))].slice(-10);
|
|
5618
|
+
return {
|
|
5619
|
+
task: truncate(task, 300),
|
|
5620
|
+
phase: cog.session_phase ?? "unknown",
|
|
5621
|
+
last_actions: lastActions,
|
|
5622
|
+
next_steps: nextSteps.slice(0, 5),
|
|
5623
|
+
decisions,
|
|
5624
|
+
tried_failed: triedFailed,
|
|
5625
|
+
key_files: keyFiles.length > 0 ? keyFiles : state.session_files.slice(-10),
|
|
5626
|
+
blockers: state.recent_errors.slice(-3).map((e) => truncate(e, 150))
|
|
5627
|
+
};
|
|
5628
|
+
}
|
|
5543
5629
|
function handlePreCompact() {
|
|
5544
5630
|
const state = loadWatcherState();
|
|
5545
5631
|
if (!state.active_project) {
|
|
@@ -5782,6 +5868,10 @@ ${summaryParts.join(". ")}` : `Pre-compaction session summary: ${summaryParts.jo
|
|
|
5782
5868
|
});
|
|
5783
5869
|
process.stdout.write(output + "\n");
|
|
5784
5870
|
}
|
|
5871
|
+
try {
|
|
5872
|
+
state.continuation_brief = buildContinuationBrief(state);
|
|
5873
|
+
} catch {
|
|
5874
|
+
}
|
|
5785
5875
|
state.recovery_context = recovery;
|
|
5786
5876
|
state.understanding_snapshot = understanding;
|
|
5787
5877
|
saveWatcherState(state);
|
|
@@ -6173,6 +6263,7 @@ ${distillLines}`
|
|
|
6173
6263
|
budget.append("antipatterns", warnings);
|
|
6174
6264
|
state.pending_error_warnings = [];
|
|
6175
6265
|
}
|
|
6266
|
+
const surfacedIds = /* @__PURE__ */ new Set();
|
|
6176
6267
|
try {
|
|
6177
6268
|
const surfaceDomain = state.active_domain;
|
|
6178
6269
|
if (surfaceDomain && surfaceDomain.length >= MEMORY_SURFACE.MIN_DOMAIN_LENGTH) {
|
|
@@ -6205,6 +6296,7 @@ ${distillLines}`
|
|
|
6205
6296
|
}
|
|
6206
6297
|
state.surface_injection_turns[mem.id] = state.total_turns;
|
|
6207
6298
|
state.proactive_injection_turns[mem.id] = state.total_turns;
|
|
6299
|
+
surfacedIds.add(mem.id);
|
|
6208
6300
|
}
|
|
6209
6301
|
budget.append("surface", surfaceLines.join("\n"));
|
|
6210
6302
|
}
|
|
@@ -6272,6 +6364,7 @@ ${distillLines}`
|
|
|
6272
6364
|
);
|
|
6273
6365
|
for (const m of result.memories) {
|
|
6274
6366
|
if (somaticIds.has(m.memory.id)) continue;
|
|
6367
|
+
if (surfacedIds.has(m.memory.id)) continue;
|
|
6275
6368
|
if (isRecallNoise(m.memory.content, m.memory.type, m.memory.tags)) continue;
|
|
6276
6369
|
if (m.memory.tags.includes("pre-compact")) continue;
|
|
6277
6370
|
if (m.memory.tags.includes("session_narrative")) continue;
|
|
@@ -6919,38 +7012,54 @@ function handlePostCompact(stdinJson) {
|
|
|
6919
7012
|
if (!recovery) return;
|
|
6920
7013
|
const budget = new OutputBudget(OUTPUT_BUDGET.POST_COMPACT_MAX_BYTES);
|
|
6921
7014
|
const lines = [];
|
|
6922
|
-
const
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
if (
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
if (
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
if (
|
|
7015
|
+
const brief = state.continuation_brief;
|
|
7016
|
+
if (brief) {
|
|
7017
|
+
const mindLines = ["[Engram] Continue from where you left off:"];
|
|
7018
|
+
mindLines.push(` Task: ${brief.task}`);
|
|
7019
|
+
mindLines.push(` Phase: ${brief.phase}`);
|
|
7020
|
+
if (brief.last_actions.length > 0) {
|
|
7021
|
+
mindLines.push(` Last actions:`);
|
|
7022
|
+
for (const a of brief.last_actions.slice(-5)) mindLines.push(` - ${a}`);
|
|
7023
|
+
}
|
|
7024
|
+
if (brief.next_steps.length > 0) {
|
|
7025
|
+
mindLines.push(` Next steps:`);
|
|
7026
|
+
for (const s of brief.next_steps) mindLines.push(` - ${s}`);
|
|
7027
|
+
}
|
|
7028
|
+
if (brief.decisions.length > 0) {
|
|
7029
|
+
mindLines.push(` Decisions made:`);
|
|
7030
|
+
for (const d of brief.decisions) mindLines.push(` - ${d}`);
|
|
7031
|
+
}
|
|
7032
|
+
if (brief.tried_failed.length > 0) {
|
|
6936
7033
|
mindLines.push(` Already tried (didn't work):`);
|
|
6937
|
-
for (const
|
|
6938
|
-
}
|
|
6939
|
-
const blockers = recovery.working_state?.active_blockers ?? [];
|
|
6940
|
-
if (blockers.length > 0) {
|
|
6941
|
-
mindLines.push(` Blockers: ${blockers.slice(0, 3).map((b) => truncate(b, 100)).join("; ")}`);
|
|
7034
|
+
for (const t of brief.tried_failed) mindLines.push(` - ${t}`);
|
|
6942
7035
|
}
|
|
6943
|
-
if (
|
|
6944
|
-
mindLines.push(`
|
|
7036
|
+
if (brief.blockers.length > 0) {
|
|
7037
|
+
mindLines.push(` Blockers: ${brief.blockers.join("; ")}`);
|
|
6945
7038
|
}
|
|
6946
|
-
if (
|
|
6947
|
-
const files =
|
|
7039
|
+
if (brief.key_files.length > 0) {
|
|
7040
|
+
const files = brief.key_files.map((f) => f.split(/[/\\]/).pop() ?? f);
|
|
6948
7041
|
mindLines.push(` Files: ${files.join(", ")}`);
|
|
6949
7042
|
}
|
|
6950
|
-
if (recovery.continuation_hint) {
|
|
6951
|
-
mindLines.push(` Continue: ${truncate(recovery.continuation_hint, 300)}`);
|
|
6952
|
-
}
|
|
6953
7043
|
lines.push(mindLines.join("\n"));
|
|
7044
|
+
} else {
|
|
7045
|
+
const cog = state.cognitive_state;
|
|
7046
|
+
const cogCtx = recovery.working_state?.cognitive_context;
|
|
7047
|
+
const hasAnyCognitive = cog?.current_approach || cog?.active_hypothesis || cog?.recent_discovery || cogCtx?.planned_next_step || recovery.continuation_hint;
|
|
7048
|
+
if (hasAnyCognitive) {
|
|
7049
|
+
const mindLines = ["[Engram] Before compaction, you were:"];
|
|
7050
|
+
if (state.active_task) mindLines.push(` Task: ${truncate(state.active_task, 200)}`);
|
|
7051
|
+
if (cog?.session_phase) mindLines.push(` Phase: ${cog.session_phase}`);
|
|
7052
|
+
if (cog?.current_approach) mindLines.push(` Approach: ${truncate(cog.current_approach, 300)}`);
|
|
7053
|
+
if (cog?.active_hypothesis) mindLines.push(` Hypothesis: ${truncate(cog.active_hypothesis, 300)}`);
|
|
7054
|
+
if (cog?.recent_discovery) mindLines.push(` Discovery: ${truncate(cog.recent_discovery, 300)}`);
|
|
7055
|
+
if (cogCtx?.planned_next_step) mindLines.push(` Next step: ${truncate(cogCtx.planned_next_step, 200)}`);
|
|
7056
|
+
if (recovery.continuation_hint) mindLines.push(` Continue: ${truncate(recovery.continuation_hint, 300)}`);
|
|
7057
|
+
if (state.session_files.length > 0) {
|
|
7058
|
+
const files = state.session_files.slice(-8).map((f) => f.split(/[/\\]/).pop() ?? f);
|
|
7059
|
+
mindLines.push(` Files: ${files.join(", ")}`);
|
|
7060
|
+
}
|
|
7061
|
+
lines.push(mindLines.join("\n"));
|
|
7062
|
+
}
|
|
6954
7063
|
}
|
|
6955
7064
|
try {
|
|
6956
7065
|
const transcriptPath = stdinJson?.transcript_path ?? null;
|