@vedtechsolutions/engram-mcp 1.0.23 → 1.0.25

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 +69 -7
  2. package/package.json +1 -1
package/dist/hook.js CHANGED
@@ -3266,13 +3266,26 @@ function sanitizeCognitiveState(state) {
3266
3266
  if (placeholders.includes(val)) return true;
3267
3267
  return templatePatterns.some((p) => p.test(val));
3268
3268
  };
3269
- if (cog.current_approach && isPlaceholderValue(cog.current_approach)) {
3269
+ const isCodeFragment = (val) => {
3270
+ if (/^(&{1,2}|[|]{1,2}|\+{1,2}|-{1,2}|={1,3}|!={0,2}|<|>|=>)\s/.test(val)) return true;
3271
+ if (/^(const |let |var |if \(|else |return |function |for \(|while \()/.test(val)) return true;
3272
+ if (/^[a-z_]+\.[a-z_]+(\.[a-z_]+)?$/i.test(val) && val.length < 60) return true;
3273
+ return false;
3274
+ };
3275
+ const isSummaryArtifact = (val) => {
3276
+ if (/\*{2,}/.test(val) && val.length < 200) return true;
3277
+ if (/^[-*•]\s/.test(val)) return true;
3278
+ if (/^\d+\.\s/.test(val) && val.length < 100) return true;
3279
+ return false;
3280
+ };
3281
+ const isBadCogValue = (val) => isPlaceholderValue(val) || isCodeFragment(val) || isSummaryArtifact(val);
3282
+ if (cog.current_approach && isBadCogValue(cog.current_approach)) {
3270
3283
  cog.current_approach = null;
3271
3284
  }
3272
- if (cog.active_hypothesis && isPlaceholderValue(cog.active_hypothesis)) {
3285
+ if (cog.active_hypothesis && isBadCogValue(cog.active_hypothesis)) {
3273
3286
  cog.active_hypothesis = null;
3274
3287
  }
3275
- if (cog.recent_discovery && isPlaceholderValue(cog.recent_discovery)) {
3288
+ if (cog.recent_discovery && isBadCogValue(cog.recent_discovery)) {
3276
3289
  cog.recent_discovery = null;
3277
3290
  }
3278
3291
  if (cog.active_hypothesis && cog.active_hypothesis.startsWith("/")) {
@@ -3324,6 +3337,20 @@ function sanitizeCognitiveState(state) {
3324
3337
  state.active_task = null;
3325
3338
  }
3326
3339
  }
3340
+ if (state.active_task) {
3341
+ const agentTaskPatterns = [
3342
+ /^Very thorough/i,
3343
+ /^Perform a comprehensive/i,
3344
+ /^Thoroughly (review|analyze|examine|investigate)/i,
3345
+ /^Comprehensive (analysis|review|audit|examination)/i,
3346
+ /^Deeply (analyze|review|investigate)/i,
3347
+ /^Conduct a (thorough|comprehensive|detailed)/i,
3348
+ /^(Analyze|Review|Investigate|Examine) the (entire|full|complete|whole)/i
3349
+ ];
3350
+ if (agentTaskPatterns.some((p) => p.test(state.active_task))) {
3351
+ state.active_task = null;
3352
+ }
3353
+ }
3327
3354
  if (!state.active_task || state.active_task === "unknown task") {
3328
3355
  const editedFiles = state.recent_actions.filter((a) => a.tool === "Edit" || a.tool === "Write").map((a) => {
3329
3356
  const arrowIdx = a.target.indexOf(" \u2192");
@@ -3359,6 +3386,13 @@ function sanitizeCognitiveState(state) {
3359
3386
  if (f.includes("/../") || f.startsWith("../")) return false;
3360
3387
  if (/^\/?\d+\.\d+/.test(f)) return false;
3361
3388
  if (f === "/root/.ssh" || f.includes("/etc/cron")) return false;
3389
+ const parts = f.split("/").filter(Boolean);
3390
+ if (parts.length < 2 && f.startsWith("/")) return false;
3391
+ const lastPart = parts[parts.length - 1];
3392
+ if (lastPart && f.startsWith("/") && parts.length <= 3) {
3393
+ if (lastPart.startsWith(".") && !lastPart.includes(".", 1)) return false;
3394
+ if (!lastPart.includes(".")) return false;
3395
+ }
3362
3396
  return true;
3363
3397
  });
3364
3398
  }
@@ -3851,6 +3885,8 @@ Output: ${truncate(toolOutput, 500)}`,
3851
3885
  log.info("Auto-encoded test pass completion", { passed: testRun.passed, total: testRun.total });
3852
3886
  } catch {
3853
3887
  }
3888
+ state.session_outcomes.push(`Tests passed (${testRun.passed}/${testRun.total}) \u2192 success`);
3889
+ if (state.session_outcomes.length > 10) state.session_outcomes = state.session_outcomes.slice(-10);
3854
3890
  }
3855
3891
  if (testRun && testRun.outcome === "fail" && state.session_files.length > 0) {
3856
3892
  try {
@@ -3907,6 +3943,29 @@ Output: ${truncate(toolOutput, 500)}`,
3907
3943
  }
3908
3944
  } catch {
3909
3945
  }
3946
+ const failedCount2 = testRun.failed ?? testRun.total - testRun.passed;
3947
+ state.session_outcomes.push(`Tests failed (${failedCount2} failing) \u2192 fail`);
3948
+ if (state.session_outcomes.length > 10) state.session_outcomes = state.session_outcomes.slice(-10);
3949
+ }
3950
+ if (!testRun && /\bgit\s+(push|commit)\b/i.test(cmd)) {
3951
+ const gitAction = cmd.includes("push") ? "Push" : "Commit";
3952
+ if (!isError) {
3953
+ state.session_outcomes.push(`${gitAction} \u2192 success`);
3954
+ } else {
3955
+ state.session_outcomes.push(`${gitAction} \u2192 fail`);
3956
+ }
3957
+ if (state.session_outcomes.length > 10) state.session_outcomes = state.session_outcomes.slice(-10);
3958
+ }
3959
+ if (!testRun && /\b(tsup|tsc|build)\b/i.test(cmd)) {
3960
+ const buildSuccess = /Build success|Successfully compiled/i.test(toolOutput);
3961
+ const buildFail = isError || /error TS\d+|Build failed|compilation error/i.test(toolOutput);
3962
+ if (buildSuccess) {
3963
+ state.session_outcomes.push(`Build (${cmd.split(/\s+/)[1] ?? "build"}) \u2192 success`);
3964
+ if (state.session_outcomes.length > 10) state.session_outcomes = state.session_outcomes.slice(-10);
3965
+ } else if (buildFail) {
3966
+ state.session_outcomes.push(`Build (${cmd.split(/\s+/)[1] ?? "build"}) \u2192 fail`);
3967
+ if (state.session_outcomes.length > 10) state.session_outcomes = state.session_outcomes.slice(-10);
3968
+ }
3910
3969
  }
3911
3970
  if (!isError && toolOutput.length >= 100 && state.recalled_memory_ids.length > 0) {
3912
3971
  try {
@@ -5199,6 +5258,7 @@ function handleSessionStart(stdinJson, argFallback) {
5199
5258
  }
5200
5259
  }
5201
5260
  if (isPostCompact && prevState) {
5261
+ sanitizeCognitiveState(prevState);
5202
5262
  try {
5203
5263
  const compactParts = [];
5204
5264
  if (prevState.recovery_context) {
@@ -5739,7 +5799,8 @@ function handleEngramUsed(stdinJson, argFallback) {
5739
5799
  }
5740
5800
  function buildContinuationBrief(state) {
5741
5801
  const cog = state.cognitive_state;
5742
- 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");
5802
+ const approachFirstSentence = cog.current_approach ? cog.current_approach.split(/[.!?\n]/)[0]?.trim() ?? null : null;
5803
+ const task = state.active_task ?? (approachFirstSentence && approachFirstSentence.length >= 10 && approachFirstSentence.length <= 150 ? approachFirstSentence : null) ?? (state.session_files.length > 0 ? `Working on ${state.session_files.slice(-3).map((f) => f.split(/[/\\]/).pop() ?? f).join(", ")}` : "unknown task");
5743
5804
  const lastActions = state.recent_actions.slice(-8).map((a) => {
5744
5805
  if (a.tool === "Edit" || a.tool === "Write") {
5745
5806
  const shortPath = a.target.length > 60 ? "..." + a.target.slice(-57) : a.target;
@@ -6386,7 +6447,8 @@ ${distillLines}`
6386
6447
  } catch (e) {
6387
6448
  log.error("Teaching detection failed", { error: safeErrorStr(e) });
6388
6449
  }
6389
- const task = extractTask(content);
6450
+ const isCompactionSummary = content.length > 500 && (content.includes("This session is being continued") || content.includes("Summary:") && content.includes("Key Technical Concepts") || content.includes("Previous conversation") && content.includes("compaction") || content.includes("Pre-compaction") && content.includes("continuation"));
6451
+ const task = isCompactionSummary ? null : extractTask(content);
6390
6452
  const versionHint = extractVersion(content);
6391
6453
  if (task || versionHint) {
6392
6454
  if (task) state.active_task = task;
@@ -6401,14 +6463,14 @@ ${distillLines}`
6401
6463
  }
6402
6464
  }
6403
6465
  }
6404
- if (content.length >= 10 && !content.startsWith("<")) {
6466
+ if (content.length >= 10 && !content.startsWith("<") && !isCompactionSummary) {
6405
6467
  state.recent_prompts.push(truncate(content, 300));
6406
6468
  if (state.recent_prompts.length > 8) {
6407
6469
  state.recent_prompts = state.recent_prompts.slice(-8);
6408
6470
  }
6409
6471
  }
6410
6472
  try {
6411
- if (content.length >= 20 && !content.startsWith("<")) {
6473
+ if (content.length >= 20 && !content.startsWith("<") && !isCompactionSummary) {
6412
6474
  const approach = extractApproachFromPrompt(content);
6413
6475
  if (approach) {
6414
6476
  const currentLen = state.cognitive_state.current_approach?.length ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vedtechsolutions/engram-mcp",
3
- "version": "1.0.23",
3
+ "version": "1.0.25",
4
4
  "description": "Cognitive memory system for AI — persistent, cross-session learning via MCP",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",