@vedtechsolutions/engram-mcp 1.0.27 → 1.0.29

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.
@@ -11227,7 +11227,13 @@ function composeBridgeContent(options) {
11227
11227
  task: options.task,
11228
11228
  files_modified: 0,
11229
11229
  recent_files: options.recent_files?.slice(0, 10) ?? [],
11230
- recent_errors: options.recent_errors?.slice(0, 3) ?? []
11230
+ // GAP 26: Filter false-positive errors before display (git log with "error" in commit msg, etc.)
11231
+ recent_errors: (options.recent_errors ?? []).filter((err) => {
11232
+ const lower = err.toLowerCase();
11233
+ if (/^git (log|show|diff|shortlog)\b/.test(err)) return false;
11234
+ if (/^\{"stdout"/.test(err)) return false;
11235
+ return true;
11236
+ }).slice(0, 3)
11231
11237
  },
11232
11238
  cognitive: {
11233
11239
  approach: options.cognitive?.approach ?? null,
@@ -11276,6 +11282,7 @@ function composeBridgeContent(options) {
11276
11282
  const cutoffIso = cutoffDate.toISOString();
11277
11283
  const candidates = getRecentMemories(50).filter(
11278
11284
  (m) => m.confidence >= 0.6 && m.created_at >= cutoffIso && m.type !== "antipattern" && // antipatterns already in warnings
11285
+ !m.tags.includes("synthesis") && // GAP 24: skip stored synthesis (step 6 generates live)
11279
11286
  !isRecallNoise(m.content, m.type, m.tags)
11280
11287
  );
11281
11288
  const prioritized = candidates.sort((a, b) => {
@@ -11291,6 +11298,8 @@ function composeBridgeContent(options) {
11291
11298
  return b.confidence - a.confidence;
11292
11299
  });
11293
11300
  for (const m of prioritized.slice(0, CURATOR.MAX_BRIDGE_INSIGHTS)) {
11301
+ if (/Claude needs your permission/i.test(m.content)) continue;
11302
+ if (/^(Tool |Permission |Approval )/i.test(m.content)) continue;
11294
11303
  content.insights.push({
11295
11304
  text: m.content.substring(0, 200),
11296
11305
  type: m.type,
@@ -11302,13 +11311,26 @@ function composeBridgeContent(options) {
11302
11311
  }
11303
11312
  try {
11304
11313
  if (options.domain) {
11305
- const decisions = getDecisionMemoriesForDomain(options.domain, 5);
11314
+ const decisions = getDecisionMemoriesForDomain(options.domain, 10);
11315
+ const delegationPatterns = [
11316
+ /^Delegated:/i,
11317
+ /^Very thorough/i,
11318
+ /^Perform a comprehensive/i,
11319
+ /^Thoroughly (review|analyze|examine)/i,
11320
+ /^Explore (the |how |\/)/i,
11321
+ /^Design an? (implementation|phased)/i,
11322
+ /^Research how/i
11323
+ ];
11306
11324
  for (const m of decisions) {
11325
+ if (content.active_decisions.length >= 5) break;
11307
11326
  const td = m.type_data;
11308
11327
  if (td && "kind" in td && td.kind === "decision") {
11309
11328
  const d = td;
11329
+ const chosen = d.chosen ?? "";
11330
+ if (delegationPatterns.some((p) => p.test(chosen))) continue;
11331
+ if (chosen.length < 10) continue;
11310
11332
  content.active_decisions.push({
11311
- chosen: d.chosen?.substring(0, 150) ?? "",
11333
+ chosen: chosen.substring(0, 150),
11312
11334
  rationale: d.rationale?.substring(0, 150) ?? "",
11313
11335
  type: d.decision_type ?? "approach"
11314
11336
  });
@@ -11322,8 +11344,17 @@ function composeBridgeContent(options) {
11322
11344
  const recentWithLessons = getRecentMemories(50).filter(
11323
11345
  (m) => m.type === "episodic" && m.tags.includes("has_lesson") && m.confidence >= 0.5 && !isRecallNoise(m.content, m.type, m.tags)
11324
11346
  ).slice(0, 5);
11347
+ const isNoisyLesson = (lesson) => {
11348
+ if (lesson.length < 15) return true;
11349
+ if (/^[:\.]/.test(lesson)) return true;
11350
+ if (/\[\/\\/.test(lesson) && /\(\?/.test(lesson)) return true;
11351
+ if (/^(const |let |var |if \(|return )/.test(lesson)) return true;
11352
+ if (/^\w+_\w+:/.test(lesson)) return true;
11353
+ return false;
11354
+ };
11325
11355
  for (const m of recentWithLessons) {
11326
11356
  if (isEpisodicData(m.type_data) && m.type_data.lesson) {
11357
+ if (isNoisyLesson(m.type_data.lesson)) continue;
11327
11358
  content.lessons.push({
11328
11359
  text: m.type_data.lesson.substring(0, 200),
11329
11360
  confidence: m.confidence
@@ -12675,4 +12706,4 @@ export {
12675
12706
  composeProjectUnderstanding,
12676
12707
  formatMentalModelInjection
12677
12708
  };
12678
- //# sourceMappingURL=chunk-O3ZP4K3T.js.map
12709
+ //# sourceMappingURL=chunk-RCPTLHMM.js.map
package/dist/hook.js CHANGED
@@ -174,7 +174,7 @@ import {
174
174
  updateReasoningChain,
175
175
  updateSelfModelFromSession,
176
176
  updateTask
177
- } from "./chunk-O3ZP4K3T.js";
177
+ } from "./chunk-RCPTLHMM.js";
178
178
 
179
179
  // src/hook.ts
180
180
  import { readFileSync, writeFileSync, existsSync, renameSync, statSync, readdirSync, unlinkSync, openSync, readSync, closeSync } from "fs";
@@ -3268,6 +3268,7 @@ function sanitizeCognitiveState(state) {
3268
3268
  };
3269
3269
  const isCodeFragment = (val) => {
3270
3270
  if (/^(&{1,2}|[|]{1,2}|\+{1,2}|-{1,2}|={1,3}|!={0,2}|<|>|=>)\s/.test(val)) return true;
3271
+ if (/^\?\s*[\(a-z_]/.test(val)) return true;
3271
3272
  if (/^(const |let |var |if \(|else |return |function |for \(|while \()/.test(val)) return true;
3272
3273
  if (/^[a-z_]+\.[a-z_]+(\.[a-z_]+)?$/i.test(val) && val.length < 60) return true;
3273
3274
  return false;
@@ -3389,7 +3390,7 @@ function sanitizeCognitiveState(state) {
3389
3390
  const parts = f.split("/").filter(Boolean);
3390
3391
  if (parts.length < 2 && f.startsWith("/")) return false;
3391
3392
  const lastPart = parts[parts.length - 1];
3392
- if (lastPart && f.startsWith("/") && parts.length <= 3) {
3393
+ if (lastPart) {
3393
3394
  if (lastPart.startsWith(".") && !lastPart.includes(".", 1)) return false;
3394
3395
  if (!lastPart.includes(".")) return false;
3395
3396
  }
@@ -7595,7 +7596,9 @@ function extractFilePath(command2) {
7595
7596
  }
7596
7597
  function containsError(output) {
7597
7598
  const lower = output.toLowerCase();
7598
- return lower.includes("error") || lower.includes("exception") || lower.includes("traceback") || lower.includes("failed") || lower.includes("fatal") || lower.includes("panic");
7599
+ if (!/error|exception|traceback|failed|fatal|panic/.test(lower)) return false;
7600
+ const stripped = lower.replace(/corrected.*?errors?/g, "").replace(/no\s+errors?\b/g, "").replace(/\b0\s+errors?\b/g, "").replace(/errors?\s+corrected/g, "").replace(/grep.*?error[^\n]*/g, "").replace(/warn\b[^\n]*/g, "").replace(/contains?error\w*/g, "").replace(/handles?error\w*/g, "").replace(/is_?error\w*/g, "").replace(/\berror[_-]\w+/g, "").replace(/"stdout":\s*"[^"]*"/g, "").replace(/\bgap\s+\d+[:\s][^\n]*/g, "");
7601
+ return stripped.includes("error") || stripped.includes("exception") || stripped.includes("traceback") || stripped.includes("failed") || stripped.includes("fatal") || stripped.includes("panic");
7599
7602
  }
7600
7603
  export {
7601
7604
  OutputBudget,
package/dist/index.js CHANGED
@@ -154,7 +154,7 @@ import {
154
154
  vaccinate,
155
155
  vacuumDatabase,
156
156
  validateMultiPerspective
157
- } from "./chunk-O3ZP4K3T.js";
157
+ } from "./chunk-RCPTLHMM.js";
158
158
 
159
159
  // src/index.ts
160
160
  import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vedtechsolutions/engram-mcp",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "Cognitive memory system for AI — persistent, cross-session learning via MCP",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",