@hiveai/mcp 0.20.1 → 0.23.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
@@ -1151,7 +1151,15 @@ async function memTried(input, ctx) {
1151
1151
  throw new Error(`Memory already exists at ${file}`);
1152
1152
  }
1153
1153
  await writeFile8(file, serializeMemory7({ frontmatter, body }), "utf8");
1154
- return { id: frontmatter.id, scope: frontmatter.scope, file_path: file };
1154
+ const sensorGenerated = Boolean(sensor);
1155
+ const hint = sensorGenerated ? void 0 : input.paths.length === 0 ? "No sensor was generated (no `paths` given), so this lesson is feedforward-only \u2014 it will be briefed but the gate cannot block the repeat. Re-run with `paths` set to the file(s) where the mistake lives to close the loop." : "No sensor could be derived from the wording (no distinctive code token). The lesson is briefed but not enforced; add a concrete forbidden token/value, or attach a sensor manually, to make the gate block the repeat.";
1156
+ return {
1157
+ id: frontmatter.id,
1158
+ scope: frontmatter.scope,
1159
+ file_path: file,
1160
+ sensor_generated: sensorGenerated,
1161
+ ...hint ? { hint } : {}
1162
+ };
1155
1163
  }
1156
1164
 
1157
1165
  // src/tools/ingest-findings.ts
@@ -2667,7 +2675,6 @@ function runCommand(cmd, args, cwd) {
2667
2675
  import { existsSync as existsSync25 } from "fs";
2668
2676
  import {
2669
2677
  addedLinesFromDiff,
2670
- appendPreventionEvent,
2671
2678
  BRIDGE_TARGET_PATH,
2672
2679
  buildDocFrequency,
2673
2680
  CODE_STOPWORDS,
@@ -2679,9 +2686,8 @@ import {
2679
2686
  loadUsageIndex as loadUsageIndex10,
2680
2687
  literalMatchesAnyToken as literalMatchesAnyToken3,
2681
2688
  memoryMatchesAnchorPaths as memoryMatchesAnchorPaths4,
2682
- recordPrevention,
2689
+ recordPreventionHits,
2683
2690
  runSensors,
2684
- saveUsageIndex as saveUsageIndex4,
2685
2691
  sensorTargetsFromDiff,
2686
2692
  tokenizeQuery as tokenizeQuery3
2687
2693
  } from "@hiveai/core";
@@ -2866,19 +2872,7 @@ async function antiPatternsCheck(input, ctx) {
2866
2872
  const strongCatches = warnings.filter(
2867
2873
  (w) => w.reasons.includes("sensor") || w.reasons.includes("anchor") && w.reasons.includes("literal")
2868
2874
  );
2869
- if (strongCatches.length > 0) {
2870
- const recordedIds = [];
2871
- for (const w of strongCatches) if (recordPrevention(usage, w.id)) recordedIds.push(w.id);
2872
- if (recordedIds.length > 0) {
2873
- await saveUsageIndex4(ctx.paths, usage).catch(() => {
2874
- });
2875
- const at = (/* @__PURE__ */ new Date()).toISOString();
2876
- for (const id of recordedIds) {
2877
- await appendPreventionEvent(ctx.paths, { at, id, source: "anti-pattern" }).catch(() => {
2878
- });
2879
- }
2880
- }
2881
- }
2875
+ await recordPreventionHits(ctx.paths, strongCatches.map((w) => w.id), "anti-pattern");
2882
2876
  return {
2883
2877
  scanned: negative.length,
2884
2878
  warnings
@@ -3850,9 +3844,22 @@ import { existsSync as existsSync30 } from "fs";
3850
3844
  import {
3851
3845
  findLexicalConflictPairs,
3852
3846
  findTopicStatusConflictPairs,
3853
- loadMemoriesFromDir as loadMemoriesFromDir23
3847
+ loadMemoriesFromDir as loadMemoriesFromDir23,
3848
+ planConflictResolution
3854
3849
  } from "@hiveai/core";
3855
3850
  import { z as z32 } from "zod";
3851
+ function suggestResolution(byId, idA, idB) {
3852
+ const a = byId.get(idA);
3853
+ const b = byId.get(idB);
3854
+ if (!a || !b) return null;
3855
+ const plan = planConflictResolution(a, b);
3856
+ return {
3857
+ keep_id: plan.keep_id,
3858
+ supersede_id: plan.supersede_id,
3859
+ reason: plan.reason,
3860
+ command: `haive memory resolve-conflict ${plan.keep_id} ${plan.supersede_id} --yes`
3861
+ };
3862
+ }
3856
3863
  var MemConflictCandidatesInputSchema = {
3857
3864
  since_days: z32.number().int().positive().max(3650).default(365).describe("Only memories created since N days ago"),
3858
3865
  types: z32.array(z32.enum(["decision", "architecture", "convention", "gotcha"])).default(["decision", "architecture"]).describe("Memory types scanned for pairwise lexical overlap"),
@@ -3874,6 +3881,7 @@ async function memConflictCandidates(input, ctx) {
3874
3881
  };
3875
3882
  }
3876
3883
  const all = await loadMemoriesFromDir23(ctx.paths.memoriesDir);
3884
+ const byId = new Map(all.map((m) => [m.memory.frontmatter.id, m]));
3877
3885
  const { pairs, scanned, truncated } = findLexicalConflictPairs(all, {
3878
3886
  sinceDays: input.since_days,
3879
3887
  types: input.types,
@@ -3882,8 +3890,22 @@ async function memConflictCandidates(input, ctx) {
3882
3890
  maxScan: input.max_scan
3883
3891
  });
3884
3892
  const topicStatusPairs = findTopicStatusConflictPairs(all, input.max_topic_pairs);
3893
+ const enrichedPairs = pairs.map((p) => ({
3894
+ ...p,
3895
+ suggested_resolution: suggestResolution(byId, p.id_a, p.id_b)
3896
+ }));
3897
+ const enrichedTopicStatusPairs = topicStatusPairs.map((p) => ({
3898
+ ...p,
3899
+ suggested_resolution: suggestResolution(byId, p.id_a, p.id_b)
3900
+ }));
3885
3901
  const notice = pairs.length === 0 && topicStatusPairs.length === 0 ? "No lexical or topic-status candidates \u2014 widen since_days/types or lower min_jaccard." : void 0;
3886
- return { pairs, topic_status_pairs: topicStatusPairs, scanned, truncated, notice };
3902
+ return {
3903
+ pairs: enrichedPairs,
3904
+ topic_status_pairs: enrichedTopicStatusPairs,
3905
+ scanned,
3906
+ truncated,
3907
+ notice
3908
+ };
3887
3909
  }
3888
3910
 
3889
3911
  // src/tools/mem-resolve-project.ts
@@ -4230,7 +4252,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
4230
4252
  // src/server.ts
4231
4253
  import { hasRecentBriefingMarker, loadConfigSync } from "@hiveai/core";
4232
4254
  var SERVER_NAME = "haive";
4233
- var SERVER_VERSION = "0.20.1";
4255
+ var SERVER_VERSION = "0.23.0";
4234
4256
  function jsonResult(data) {
4235
4257
  return {
4236
4258
  content: [