@vedtechsolutions/engram-mcp 1.0.9 → 1.0.11

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 (2) hide show
  1. package/dist/hook.js +84 -31
  2. package/package.json +1 -1
package/dist/hook.js CHANGED
@@ -3211,6 +3211,7 @@ function loadWatcherState() {
3211
3211
  };
3212
3212
  }
3213
3213
  function saveWatcherState(state) {
3214
+ sanitizeCognitiveState(state);
3214
3215
  const watcherPath = getWatcherPath(activeSessionId);
3215
3216
  try {
3216
3217
  const tmpPath = watcherPath + ".tmp";
@@ -3219,6 +3220,46 @@ function saveWatcherState(state) {
3219
3220
  } catch {
3220
3221
  }
3221
3222
  }
3223
+ function sanitizeCognitiveState(state) {
3224
+ const cog = state.cognitive_state;
3225
+ if (!cog) return;
3226
+ const placeholders = ["X", "X.", "Y", "Y.", "Z", "Z."];
3227
+ if (cog.current_approach && placeholders.includes(cog.current_approach)) {
3228
+ cog.current_approach = null;
3229
+ }
3230
+ if (cog.active_hypothesis && placeholders.includes(cog.active_hypothesis)) {
3231
+ cog.active_hypothesis = null;
3232
+ }
3233
+ if (cog.recent_discovery && placeholders.includes(cog.recent_discovery)) {
3234
+ cog.recent_discovery = null;
3235
+ }
3236
+ if (cog.active_hypothesis && cog.active_hypothesis.startsWith("/")) {
3237
+ cog.active_hypothesis = null;
3238
+ }
3239
+ if (cog.search_intent && cog.search_intent.startsWith("/")) {
3240
+ cog.search_intent = null;
3241
+ }
3242
+ if (cog.current_approach && cog.current_approach.length < 5) {
3243
+ cog.current_approach = null;
3244
+ }
3245
+ if (cog.current_approach && cog.current_approach.startsWith("Pre-compaction")) {
3246
+ cog.current_approach = null;
3247
+ }
3248
+ if (cog.recent_discovery && cog.recent_discovery.startsWith("Pre-compaction")) {
3249
+ cog.recent_discovery = null;
3250
+ }
3251
+ if (!state.active_task || state.active_task === "unknown task") {
3252
+ const editedFiles = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write").map((a) => a.target.split(/[/\\]/).pop() ?? a.target);
3253
+ const uniqueFiles = [...new Set(editedFiles)].slice(-5);
3254
+ if (uniqueFiles.length > 0) {
3255
+ if (cog.current_approach && cog.current_approach.length >= 10) {
3256
+ state.active_task = cog.current_approach.slice(0, 150);
3257
+ } else {
3258
+ state.active_task = `Working on ${uniqueFiles.join(", ")}`;
3259
+ }
3260
+ }
3261
+ }
3262
+ }
3222
3263
  function deleteSessionState() {
3223
3264
  const watcherPath = getWatcherPath(activeSessionId);
3224
3265
  try {
@@ -5588,24 +5629,39 @@ function buildContinuationBrief(state) {
5588
5629
  const cog = state.cognitive_state;
5589
5630
  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");
5590
5631
  const lastActions = state.recent_actions.slice(-8).map((a) => {
5632
+ if (a.tool === "Edit" || a.tool === "Write") {
5633
+ const shortPath = a.target.length > 60 ? "..." + a.target.slice(-57) : a.target;
5634
+ return `${a.tool}: ${shortPath}`;
5635
+ }
5636
+ if (a.tool === "Bash") {
5637
+ return `Bash: ${truncate(a.target, 100)}`;
5638
+ }
5591
5639
  const fileName = a.target.includes("/") ? a.target.split(/[/\\]/).pop() ?? a.target : a.target;
5592
5640
  return `${a.tool}: ${truncate(fileName, 80)}`;
5593
5641
  });
5594
5642
  const nextSteps = [];
5643
+ if (cog.recent_discovery && cog.recent_discovery.length > 10) {
5644
+ nextSteps.push(`Act on finding: ${truncate(cog.recent_discovery, 120)}`);
5645
+ }
5595
5646
  if (cog.search_intent && !nextSteps.some((s) => s.includes(cog.search_intent))) {
5596
5647
  nextSteps.push(`Investigate: ${cog.search_intent}`);
5597
5648
  }
5598
5649
  const lastAction = state.recent_actions[state.recent_actions.length - 1];
5599
5650
  if (lastAction && nextSteps.length === 0) {
5600
5651
  if (lastAction.tool === "Edit" || lastAction.tool === "Write") {
5601
- nextSteps.push("Run tests to verify changes");
5652
+ nextSteps.push(`Continue editing ${lastAction.target.split(/[/\\]/).pop() ?? lastAction.target}, then run tests`);
5602
5653
  } else if (lastAction.tool === "Bash" && lastAction.target.includes("test")) {
5603
5654
  nextSteps.push("Review test results and commit if passing");
5655
+ } else if (lastAction.tool === "Bash" && lastAction.target.includes("push")) {
5656
+ nextSteps.push("Verify push succeeded, publish if needed");
5604
5657
  }
5605
5658
  }
5606
5659
  if (state.recent_errors.length > 0 && nextSteps.length < 3) {
5607
5660
  nextSteps.push(`Fix: ${truncate(state.recent_errors[state.recent_errors.length - 1], 120)}`);
5608
5661
  }
5662
+ if (cog.active_hypothesis && cog.active_hypothesis.length > 5) {
5663
+ nextSteps.push(`Testing hypothesis: ${truncate(cog.active_hypothesis, 120)}`);
5664
+ }
5609
5665
  const decisions = [];
5610
5666
  for (const id of state.decision_memory_ids.slice(-5)) {
5611
5667
  try {
@@ -5617,6 +5673,15 @@ function buildContinuationBrief(state) {
5617
5673
  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));
5618
5674
  const editActions = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write");
5619
5675
  const keyFiles = [...new Set(editActions.map((a) => a.target))].slice(-10);
5676
+ const recentBash = state.recent_commands?.slice(-5) ?? [];
5677
+ if (recentBash.length > 0) {
5678
+ const bashSummary = recentBash.map((c) => truncate(c.cmd, 80));
5679
+ for (const cmd of bashSummary) {
5680
+ if (lastActions.length < 12) {
5681
+ lastActions.push(`Ran: ${cmd}`);
5682
+ }
5683
+ }
5684
+ }
5620
5685
  return {
5621
5686
  task: truncate(task, 300),
5622
5687
  phase: cog.session_phase ?? "unknown",
@@ -6215,32 +6280,7 @@ ${distillLines}`
6215
6280
  }
6216
6281
  }
6217
6282
  }
6218
- if (!state.active_task || state.active_task === "write a comprehensive report") {
6219
- const editedFiles = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write").map((a) => a.target.split(/[/\\]/).pop() ?? a.target);
6220
- const uniqueFiles = [...new Set(editedFiles)].slice(-5);
6221
- if (uniqueFiles.length > 0) {
6222
- const cog = state.cognitive_state;
6223
- if (cog.current_approach && cog.current_approach.length > 5 && cog.current_approach !== "X") {
6224
- state.active_task = truncate(cog.current_approach, 150);
6225
- } else {
6226
- state.active_task = `Working on ${uniqueFiles.join(", ")}`;
6227
- }
6228
- }
6229
- }
6230
6283
  try {
6231
- const cog = state.cognitive_state;
6232
- if (cog.current_approach === "X" || cog.current_approach === "X.") {
6233
- state.cognitive_state.current_approach = null;
6234
- }
6235
- if (cog.active_hypothesis === "Y" || cog.active_hypothesis === "Y.") {
6236
- state.cognitive_state.active_hypothesis = null;
6237
- }
6238
- if (cog.recent_discovery === "Z" || cog.recent_discovery === "Z.") {
6239
- state.cognitive_state.recent_discovery = null;
6240
- }
6241
- if (cog.active_hypothesis && cog.active_hypothesis.startsWith("/")) {
6242
- state.cognitive_state.active_hypothesis = null;
6243
- }
6244
6284
  if (content.length >= 20 && !state.cognitive_state.current_approach) {
6245
6285
  const approach = extractApproachFromPrompt(content);
6246
6286
  if (approach) {
@@ -6395,6 +6435,7 @@ ${distillLines}`
6395
6435
  if (isRecallNoise(m.memory.content, m.memory.type, m.memory.tags)) continue;
6396
6436
  if (m.memory.tags.includes("pre-compact")) continue;
6397
6437
  if (m.memory.tags.includes("session-narrative")) continue;
6438
+ if (m.memory.tags.includes("milestone") || m.memory.content.startsWith("Session milestone")) continue;
6398
6439
  const isFailure = m.memory.type === "episodic" && isEpisodicData(m.memory.type_data) && m.memory.type_data.outcome === "negative";
6399
6440
  const prefix = m.somatic_marker ? "[ENGRAM GUT]" : isFailure ? "[ENGRAM CAUTION]" : "[ENGRAM CONTEXT]";
6400
6441
  const outcomeHint = m.memory.type === "episodic" && (m.somatic_marker || isFailure) ? getEpisodicOutcomeHint(m.memory) : "";
@@ -6540,6 +6581,8 @@ ${distillLines}`
6540
6581
  if (contextOutputIds.has(mem.id)) continue;
6541
6582
  if (isRecallNoise(mem.content, mem.type, mem.tags)) continue;
6542
6583
  if (mem.tags.includes("pre-compact")) continue;
6584
+ if (mem.tags.includes("session-narrative")) continue;
6585
+ if (mem.tags.includes("milestone") || mem.content.startsWith("Session milestone")) continue;
6543
6586
  if (state.active_project && mem.encoding_context?.project && mem.encoding_context.project !== state.active_project && (mem.type === "episodic" || mem.type === "semantic" && mem.domains.length > 0)) continue;
6544
6587
  const lastTurn = state.proactive_injection_turns[mem.id];
6545
6588
  if (lastTurn !== void 0 && state.total_turns - lastTurn < PROACTIVE_RECALL.MIN_TURNS_BETWEEN_SAME) continue;
@@ -7129,11 +7172,21 @@ function handlePostCompact(stdinJson) {
7129
7172
  }
7130
7173
  const cogCtx2 = recovery.working_state?.cognitive_context;
7131
7174
  const queryParts = [];
7132
- if (state.active_task) queryParts.push(state.active_task.split(/[.;!\n]/)[0] ?? "");
7133
- if (cogCtx2?.current_approach) queryParts.push(cogCtx2.current_approach);
7134
- if (cogCtx2?.active_hypothesis) queryParts.push(cogCtx2.active_hypothesis);
7135
- if (cogCtx2?.recent_discovery) queryParts.push(cogCtx2.recent_discovery);
7136
- if (queryParts.length < 2) {
7175
+ if (brief?.task && brief.task !== "unknown task") {
7176
+ queryParts.push(brief.task.split(/[.;!\n]/)[0] ?? "");
7177
+ } else if (state.active_task) {
7178
+ queryParts.push(state.active_task.split(/[.;!\n]/)[0] ?? "");
7179
+ }
7180
+ if (cogCtx2?.current_approach && !queryParts.some((q) => q.includes(cogCtx2.current_approach.slice(0, 20)))) {
7181
+ queryParts.push(cogCtx2.current_approach);
7182
+ }
7183
+ if (brief?.key_files && brief.key_files.length > 0) {
7184
+ const fileNames = brief.key_files.slice(-3).map((f) => f.split(/[/\\]/).pop() ?? f).filter((f) => f.length > 2);
7185
+ if (fileNames.length > 0) {
7186
+ queryParts.push(fileNames.join(" "));
7187
+ }
7188
+ }
7189
+ if (queryParts.length < 1) {
7137
7190
  queryParts.push(...recovery.high_value_topics.slice(0, 6));
7138
7191
  }
7139
7192
  const query = queryParts.join(" ");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vedtechsolutions/engram-mcp",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Cognitive memory system for AI — persistent, cross-session learning via MCP",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",