@hiveai/mcp 0.11.0 → 0.12.1

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/server.d.ts CHANGED
@@ -361,6 +361,13 @@ interface AntiPatternsWarning {
361
361
  confidence: string;
362
362
  body_preview: string;
363
363
  reasons: Array<"anchor" | "literal" | "semantic" | "sensor">;
364
+ /**
365
+ * True when the LITERAL overlap includes a token that is *distinctive* to this memory
366
+ * (rare across the gotcha corpus) — e.g. `BigInt`, `open-in-view`. Only a distinctive
367
+ * literal overlap is precise enough to hard-block; a shared common word ("memory",
368
+ * "scope", "version") sets only the `literal` reason for review. Powers the gate.
369
+ */
370
+ distinctive_literal?: boolean;
364
371
  semantic_score?: number;
365
372
  /** When a regex sensor fired: its self-correction message and severity. */
366
373
  sensor_message?: string;
package/dist/server.js CHANGED
@@ -1495,6 +1495,7 @@ import {
1495
1495
  loadMemoriesFromDir as loadMemoriesFromDir14,
1496
1496
  loadUsageIndex as loadUsageIndex8,
1497
1497
  memoryMatchesAnchorPaths as memoryMatchesAnchorPaths2,
1498
+ rankMemoriesLexical as rankMemoriesLexical2,
1498
1499
  queryCodeMap,
1499
1500
  resolveBriefingBudget,
1500
1501
  serializeMemory as serializeMemory9,
@@ -1814,13 +1815,25 @@ async function getBriefing(input, ctx) {
1814
1815
  }
1815
1816
  if (act.applicable && act.activated) activatedSkills.add(id);
1816
1817
  }
1818
+ const lexNorm = /* @__PURE__ */ new Map();
1819
+ if (input.task) {
1820
+ const candidates = [...seen.keys()].map((id) => byId.get(id)).filter((x) => Boolean(x));
1821
+ const lex = rankMemoriesLexical2(candidates, input.task, candidates.length);
1822
+ const maxScore = lex.scores.reduce((m, s) => s > m ? s : m, 0);
1823
+ if (maxScore > 0) {
1824
+ lex.ranked.forEach((loaded, i) => {
1825
+ lexNorm.set(loaded.memory.frontmatter.id, (lex.scores[i] ?? 0) / maxScore);
1826
+ });
1827
+ }
1828
+ }
1817
1829
  const ranked = [...seen.values()].sort((a, b) => {
1818
1830
  const reasonScore = (m) => (m.type === "attempt" ? 3 : 0) + (m.reasons.includes("anchor") ? 4 : 0) + (m.reasons.includes("symbol") ? 4 : 0) + (m.reasons.includes("module") ? 2 : 0) + (m.reasons.includes("semantic") ? 2 : 0) + (m.reasons.includes("domain") ? 1 : 0);
1819
1831
  const confidenceScore = (m) => m.confidence === "authoritative" ? 4 : m.confidence === "trusted" ? 3 : m.confidence === "low" ? 1 : m.confidence === "stale" ? -2 : 0;
1820
1832
  const impactScore = (m) => (m.impact_score ?? 0) * 3;
1821
1833
  const activationBoost = (m) => activatedSkills.has(m.id) ? 5 : 0;
1822
- const sa = priorityRank(classifyMemoryPriority(a, byId.get(a.id), input.files, input.symbols)) * 100 + reasonScore(a) + confidenceScore(a) + impactScore(a) + activationBoost(a) + (a.semantic_score ?? 0);
1823
- const sb = priorityRank(classifyMemoryPriority(b, byId.get(b.id), input.files, input.symbols)) * 100 + reasonScore(b) + confidenceScore(b) + impactScore(b) + activationBoost(b) + (b.semantic_score ?? 0);
1834
+ const lexScore = (m) => 12 * (lexNorm.get(m.id) ?? 0);
1835
+ const sa = priorityRank(classifyMemoryPriority(a, byId.get(a.id), input.files, input.symbols)) * 100 + reasonScore(a) + confidenceScore(a) + impactScore(a) + activationBoost(a) + lexScore(a) + (a.semantic_score ?? 0);
1836
+ const sb = priorityRank(classifyMemoryPriority(b, byId.get(b.id), input.files, input.symbols)) * 100 + reasonScore(b) + confidenceScore(b) + impactScore(b) + activationBoost(b) + lexScore(b) + (b.semantic_score ?? 0);
1824
1837
  return sb - sa;
1825
1838
  });
1826
1839
  for (const mem of ranked.slice(0, briefingMaxMemories)) {
@@ -2514,7 +2527,10 @@ function runCommand(cmd, args, cwd) {
2514
2527
  import { existsSync as existsSync24 } from "fs";
2515
2528
  import {
2516
2529
  addedLinesFromDiff,
2530
+ buildDocFrequency,
2531
+ CODE_STOPWORDS,
2517
2532
  deriveConfidence as deriveConfidence6,
2533
+ diffHasDistinctiveOverlap,
2518
2534
  getUsage as getUsage8,
2519
2535
  isRetiredMemory as isRetiredMemory2,
2520
2536
  loadMemoriesFromDir as loadMemoriesFromDir18,
@@ -2541,53 +2557,6 @@ var AntiPatternsCheckInputSchema = {
2541
2557
  "Minimum cosine score for semantic-only anti-pattern hits. Anchor/literal matches still surface. Default 0.45 keeps broad, weakly-related memories out of review noise."
2542
2558
  )
2543
2559
  };
2544
- var CODE_STOPWORDS = /* @__PURE__ */ new Set([
2545
- "import",
2546
- "export",
2547
- "function",
2548
- "return",
2549
- "const",
2550
- "let",
2551
- "var",
2552
- "class",
2553
- "public",
2554
- "private",
2555
- "protected",
2556
- "static",
2557
- "this",
2558
- "true",
2559
- "false",
2560
- "null",
2561
- "undefined",
2562
- "void",
2563
- "async",
2564
- "await",
2565
- "from",
2566
- "type",
2567
- "interface",
2568
- "extends",
2569
- "implements",
2570
- "number",
2571
- "string",
2572
- "boolean",
2573
- "value",
2574
- "default",
2575
- "case",
2576
- "break",
2577
- "continue",
2578
- "throw",
2579
- "catch",
2580
- "finally",
2581
- "else",
2582
- "while",
2583
- "for",
2584
- "new",
2585
- "super",
2586
- "yield",
2587
- "module",
2588
- "require",
2589
- "console"
2590
- ]);
2591
2560
  function tokenizeDiffForLiteral(diff) {
2592
2561
  const lines = diff.split("\n");
2593
2562
  const looksLikeDiff = lines.some((l) => /^[+-]/.test(l));
@@ -2620,6 +2589,7 @@ async function antiPatternsCheck(input, ctx) {
2620
2589
  return { scanned: 0, warnings: [], notice: "No attempt/gotcha memories found yet." };
2621
2590
  }
2622
2591
  const usage = await loadUsageIndex10(ctx.paths);
2592
+ const docFreq = buildDocFrequency(negative.map(({ memory }) => memory.body));
2623
2593
  const seen = /* @__PURE__ */ new Map();
2624
2594
  const upsert = (fm, body, reason, score) => {
2625
2595
  const existing = seen.get(fm.id);
@@ -2653,10 +2623,16 @@ async function antiPatternsCheck(input, ctx) {
2653
2623
  }
2654
2624
  if (input.diff) {
2655
2625
  const tokens = tokenizeDiffForLiteral(input.diff);
2626
+ const added = addedLinesFromDiff(input.diff);
2627
+ const addedText = added.trim().length > 0 ? added : input.diff;
2656
2628
  if (tokens.length > 0) {
2657
2629
  for (const { memory } of negative) {
2658
2630
  if (literalMatchesAnyToken3(memory, tokens)) {
2659
2631
  upsert(memory.frontmatter, memory.body, "literal");
2632
+ if (diffHasDistinctiveOverlap(addedText, memory.body, docFreq)) {
2633
+ const w = seen.get(memory.frontmatter.id);
2634
+ if (w) w.distinctive_literal = true;
2635
+ }
2660
2636
  }
2661
2637
  }
2662
2638
  }
@@ -3289,7 +3265,12 @@ function classifyWarning(warning, paths, anchoredBlocks = false) {
3289
3265
  const hasSemantic = warning.reasons.includes("semantic");
3290
3266
  const semanticScore = warning.semantic_score ?? 0;
3291
3267
  const highConfidence = warning.confidence === "authoritative" || warning.confidence === "trusted";
3292
- if (anchoredBlocks && highConfidence && warning.scope !== "personal" && warning.reasons.includes("anchor") && (warning.reasons.includes("literal") || hasSemantic && semanticScore >= 0.45)) {
3268
+ if (anchoredBlocks && highConfidence && warning.scope !== "personal" && warning.reasons.includes("anchor") && // A literal overlap only corroborates a BLOCK when it is on a token *distinctive*
3269
+ // to this gotcha (rare in the corpus). Sharing a common domain word ("memory",
3270
+ // "scope", "version") — or a version-bump diff — no longer hard-blocks; it falls
3271
+ // through to `review` below. This kills the incidental-token false positives that
3272
+ // made agents work for nothing. A moderate semantic match still corroborates.
3273
+ (warning.distinctive_literal === true || hasSemantic && semanticScore >= 0.45)) {
3293
3274
  if (warning.has_sensor && !warning.reasons.includes("sensor")) {
3294
3275
  return {
3295
3276
  ...warning,
@@ -4036,7 +4017,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
4036
4017
  // src/server.ts
4037
4018
  import { hasRecentBriefingMarker, loadConfigSync } from "@hiveai/core";
4038
4019
  var SERVER_NAME = "haive";
4039
- var SERVER_VERSION = "0.11.0";
4020
+ var SERVER_VERSION = "0.12.1";
4040
4021
  function jsonResult(data) {
4041
4022
  return {
4042
4023
  content: [