@hivelore/mcp 0.44.0 → 0.46.0

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/index.js CHANGED
@@ -1795,15 +1795,24 @@ async function memTried(input, ctx) {
1795
1795
  import { existsSync as existsSync17, statSync } from "fs";
1796
1796
  import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile10 } from "fs/promises";
1797
1797
  import path8 from "path";
1798
+ import { execFile } from "child_process";
1799
+ import { promisify } from "util";
1798
1800
  import { z as z17 } from "zod";
1799
1801
  import {
1800
1802
  buildProposeCommand,
1803
+ incidentHintsFromDiff,
1801
1804
  loadMemoriesFromDir as loadMemoriesFromDir14,
1802
1805
  normalizeFramework,
1803
1806
  parseLessonFields,
1804
1807
  pickTestFramework,
1805
1808
  scaffoldPostIncidentTest
1806
1809
  } from "@hivelore/core";
1810
+ var execFileAsync = promisify(execFile);
1811
+ async function gitDiffText(root, redRef, paths) {
1812
+ const args = ["diff", redRef, "HEAD", "--", ...paths];
1813
+ const { stdout } = await execFileAsync("git", args, { cwd: root, maxBuffer: 64 * 1024 * 1024 });
1814
+ return stdout;
1815
+ }
1807
1816
  var PY_SIGNALS = ["pyproject.toml", "setup.py", "pytest.ini", "requirements.txt", "tox.ini"];
1808
1817
  async function detectForAnchor(root, rel) {
1809
1818
  let dir = path8.resolve(root, rel);
@@ -1850,6 +1859,9 @@ var ScaffoldTestInputSchema = {
1850
1859
  memory_id: z17.string().min(1).describe("Id of the attempt/gotcha lesson to scaffold a post-incident test from."),
1851
1860
  framework: z17.enum(["vitest", "jest", "pytest", "gotest"]).optional().describe("Test framework. Auto-detected from the package that owns the lesson's anchor paths when omitted."),
1852
1861
  out_path: z17.string().optional().describe("Override the generated test file path (repo-relative)."),
1862
+ red_ref: z17.string().optional().describe(
1863
+ "Pre-fix incident commit/ref. When set, the scaffold names the symbols the fix (<red_ref>..HEAD) touched within the lesson's anchor scope and pre-fills the example around them, so the assertion is a targeted edit rather than a blank page. A bad ref falls back to the generic template."
1864
+ ),
1853
1865
  write: z17.boolean().default(true).describe("Write the file to disk (default). false = return the content for preview without writing.")
1854
1866
  };
1855
1867
  async function scaffoldTest(input, ctx) {
@@ -1863,13 +1875,23 @@ async function scaffoldTest(input, ctx) {
1863
1875
  const groups = input.out_path ? allGroups.slice(0, 1) : allGroups;
1864
1876
  const frameworkFor = (detected) => input.framework ? normalizeFramework(input.framework) ?? detected : detected;
1865
1877
  const fields = parseLessonFields(found.memory.body);
1878
+ let incidentHints;
1879
+ if (input.red_ref) {
1880
+ try {
1881
+ const diff = await gitDiffText(ctx.paths.root, input.red_ref, anchorPaths);
1882
+ const hints = incidentHintsFromDiff(diff, { redRef: input.red_ref });
1883
+ if (hints.changedSymbols.length > 0 || hints.changedFiles.length > 0) incidentHints = hints;
1884
+ } catch {
1885
+ }
1886
+ }
1866
1887
  const lesson = {
1867
1888
  memoryId: input.memory_id,
1868
1889
  title: fields.title || input.memory_id,
1869
1890
  whyFailed: fields.whyFailed,
1870
1891
  instead: fields.instead,
1871
1892
  incident: found.memory.frontmatter.sensor?.incident,
1872
- paths: anchorPaths
1893
+ paths: anchorPaths,
1894
+ incidentHints
1873
1895
  };
1874
1896
  let scaffolds = groups.map(
1875
1897
  (g) => scaffoldPostIncidentTest(lesson, { framework: frameworkFor(g.framework), outPath: input.out_path, baseDir: g.baseDir })
@@ -3193,7 +3215,7 @@ function oneLine(value) {
3193
3215
  return value.replace(/\s+/g, " ").replace(/"/g, '\\"').trim().slice(0, 120);
3194
3216
  }
3195
3217
  function serverVersion() {
3196
- return true ? "0.44.0" : "dev";
3218
+ return true ? "0.46.0" : "dev";
3197
3219
  }
3198
3220
 
3199
3221
  // src/tools/code-map.ts
@@ -3508,6 +3530,7 @@ function isHaiveOwnedPath(p) {
3508
3530
  if (/^\.github\/workflows\/haive-.*\.ya?ml$/.test(p)) return true;
3509
3531
  return false;
3510
3532
  }
3533
+ var MAX_FUZZY_SCAN_LINES = 2e4;
3511
3534
  var TEST_PATH_RE = /(?:^|\/)(?:tests?|__tests__|__mocks__|e2e|fixtures)\/|\.(?:test|spec)\.[cm]?[jt]sx?$/i;
3512
3535
  function isTestPath(p) {
3513
3536
  return TEST_PATH_RE.test(p);
@@ -3518,7 +3541,7 @@ function stripTestHunks(diff) {
3518
3541
  let block = [];
3519
3542
  let keep = true;
3520
3543
  const flush = () => {
3521
- if (keep) out.push(...block);
3544
+ if (keep) for (const l of block) out.push(l);
3522
3545
  block = [];
3523
3546
  keep = true;
3524
3547
  };
@@ -3539,7 +3562,7 @@ function stripAiDirHunks(diff) {
3539
3562
  let block = [];
3540
3563
  let keep = true;
3541
3564
  const flush = () => {
3542
- if (keep) out.push(...block);
3565
+ if (keep) for (const l of block) out.push(l);
3543
3566
  block = [];
3544
3567
  keep = true;
3545
3568
  };
@@ -3610,7 +3633,10 @@ async function antiPatternsCheck(input, ctx) {
3610
3633
  }
3611
3634
  }
3612
3635
  const scanDiff = input.diff ? stripTestHunks(stripAiDirHunks(input.diff)) : input.diff;
3613
- if (scanDiff) {
3636
+ const scanAddedLineCount = scanDiff ? addedLinesFromDiff(scanDiff).split("\n").length : 0;
3637
+ const fuzzyScanTooLarge = scanAddedLineCount > MAX_FUZZY_SCAN_LINES;
3638
+ const notice = fuzzyScanTooLarge ? `Diff is very large (${scanAddedLineCount.toLocaleString()} added lines) \u2014 literal/semantic corroboration skipped for performance; anchored lessons and deterministic sensors were still evaluated in full. If this staged node_modules or a build artifact, unstage it.` : void 0;
3639
+ if (scanDiff && !fuzzyScanTooLarge) {
3614
3640
  const tokens = tokenizeDiffForLiteral(scanDiff);
3615
3641
  const added = addedLinesFromDiff(scanDiff);
3616
3642
  const addedText = added.trim().length > 0 ? added : scanDiff;
@@ -3645,7 +3671,7 @@ async function antiPatternsCheck(input, ctx) {
3645
3671
  }
3646
3672
  }
3647
3673
  }
3648
- if (input.semantic && scanDiff) {
3674
+ if (input.semantic && scanDiff && !fuzzyScanTooLarge) {
3649
3675
  try {
3650
3676
  const mod = await import("@hivelore/embeddings");
3651
3677
  const added = addedLinesFromDiff(scanDiff);
@@ -3678,7 +3704,8 @@ async function antiPatternsCheck(input, ctx) {
3678
3704
  }
3679
3705
  return {
3680
3706
  scanned: negative.length,
3681
- warnings
3707
+ warnings,
3708
+ ...notice ? { notice } : {}
3682
3709
  };
3683
3710
  }
3684
3711
 
@@ -3906,6 +3933,7 @@ async function preCommitCheck(input, ctx) {
3906
3933
  relevant_memories: relevant_memories.length,
3907
3934
  stale_anchors: staleHits.length
3908
3935
  },
3936
+ ...apResult.notice ? { notice: apResult.notice } : {},
3909
3937
  warnings: classifiedWarnings,
3910
3938
  relevant_memories,
3911
3939
  stale_anchors: staleHits.map((r) => {
@@ -4640,7 +4668,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
4640
4668
  // src/server.ts
4641
4669
  import { hasRecentBriefingMarker, loadConfigSync } from "@hivelore/core";
4642
4670
  var SERVER_NAME = "hivelore";
4643
- var SERVER_VERSION = "0.44.0";
4671
+ var SERVER_VERSION = "0.46.0";
4644
4672
  function jsonResult(data) {
4645
4673
  return {
4646
4674
  content: [