@hiveai/cli 0.9.22 → 0.9.23

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
@@ -4385,6 +4385,7 @@ function toMatch(loaded, reason, usage) {
4385
4385
  confidence: deriveConfidence2(fm, u),
4386
4386
  read_count: u.read_count,
4387
4387
  reason,
4388
+ anchor_paths: fm.anchor.paths,
4388
4389
  file_path: loaded.filePath,
4389
4390
  body: loaded.memory.body
4390
4391
  };
@@ -6436,12 +6437,17 @@ async function preCommitCheck(input, ctx) {
6436
6437
  },
6437
6438
  warnings: classifiedWarnings,
6438
6439
  relevant_memories,
6439
- stale_anchors: staleHits.map((r) => ({
6440
- id: r.id,
6441
- // The matching `relevantMatches` entry tells us which paths overlap.
6442
- paths: relevantMatches.find((m) => m.id === r.id) ? input.paths.filter((p) => relevantMatches.some((m) => m.id === r.id)) : [],
6443
- body_preview: r.reason ?? "anchored code drifted; verify before relying on this memory"
6444
- }))
6440
+ stale_anchors: staleHits.map((r) => {
6441
+ const match = relevantMatches.find((m) => m.id === r.id);
6442
+ const overlapping = match ? input.paths.filter(
6443
+ (p) => match.anchor_paths.some((ap) => ap === p || p.startsWith(ap + "/") || ap.startsWith(p + "/"))
6444
+ ) : [];
6445
+ return {
6446
+ id: r.id,
6447
+ paths: overlapping.length > 0 ? overlapping : match ? input.paths : [],
6448
+ body_preview: r.reason ?? "anchored code drifted; verify before relying on this memory"
6449
+ };
6450
+ })
6445
6451
  };
6446
6452
  }
6447
6453
  function classifyWarning(warning, paths) {
@@ -6461,7 +6467,7 @@ function classifyWarning(warning, paths) {
6461
6467
  return {
6462
6468
  ...warning,
6463
6469
  level: "blocking",
6464
- rationale: "authoritative/trusted memory plus strong semantic match to the diff (score >= 0.65)",
6470
+ rationale: "authoritative/trusted memory plus very strong semantic match to the diff (score >= 0.75)",
6465
6471
  affected_files: affectedFiles,
6466
6472
  repair_command: repairCommand
6467
6473
  };
@@ -6489,7 +6495,8 @@ function classifyWarning(warning, paths) {
6489
6495
  function isBlockingWarning(warning) {
6490
6496
  const highConfidence = warning.confidence === "authoritative" || warning.confidence === "trusted";
6491
6497
  if (!highConfidence) return false;
6492
- return warning.reasons.includes("semantic") && (warning.semantic_score ?? 0) >= 0.65;
6498
+ if (!warning.reasons.includes("semantic")) return false;
6499
+ return (warning.semantic_score ?? 0) >= 0.75;
6493
6500
  }
6494
6501
  function fileTypeDowngradeReason(warning, paths) {
6495
6502
  if (paths.length === 0) return null;
@@ -6501,8 +6508,8 @@ function fileTypeDowngradeReason(warning, paths) {
6501
6508
  return "docs/changelog-only change; anti-pattern is downgraded unless semantic evidence is strong.";
6502
6509
  }
6503
6510
  const configOnly = paths.every(isPackageOrConfigPath);
6504
- if (configOnly && looksRuntimeSpecific(warning) && !warning.reasons.includes("anchor") && !hasStrongSemantic(warning)) {
6505
- return "package/config-only change; runtime-specific gotcha is not anchored or semantically strong.";
6511
+ if (configOnly && !warning.reasons.includes("anchor") && !hasStrongSemantic(warning)) {
6512
+ return "package/config-only change; warning has no anchor on these files and no strong semantic match \u2014 downgraded to info.";
6506
6513
  }
6507
6514
  return null;
6508
6515
  }
@@ -6517,10 +6524,6 @@ function isPackageOrConfigPath(file) {
6517
6524
  const lower = file.toLowerCase();
6518
6525
  return lower.endsWith("package.json") || lower.endsWith("package-lock.json") || lower.endsWith("pnpm-lock.yaml") || lower.endsWith("yarn.lock") || lower.endsWith("bun.lockb") || lower.endsWith(".config.ts") || lower.endsWith(".config.js") || lower.endsWith(".json") || lower.endsWith(".yml") || lower.endsWith(".yaml") || lower.startsWith(".github/workflows/");
6519
6526
  }
6520
- function looksRuntimeSpecific(warning) {
6521
- const text = `${warning.body_preview} ${warning.id}`.toLowerCase();
6522
- return /\b(runtime|controller|request|response|database|transaction|auth|cache|production|service|api|endpoint)\b/.test(text);
6523
- }
6524
6527
  function repairCommandForWarning(warning, paths) {
6525
6528
  const firstPath = paths[0];
6526
6529
  return firstPath ? `haive briefing --files "${firstPath}" --task "review ${warning.id}"` : `haive memory show ${warning.id}`;
@@ -7056,7 +7059,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
7056
7059
  };
7057
7060
  }
7058
7061
  var SERVER_NAME = "haive";
7059
- var SERVER_VERSION = "0.9.22";
7062
+ var SERVER_VERSION = "0.9.23";
7060
7063
  function jsonResult(data) {
7061
7064
  return {
7062
7065
  content: [
@@ -11810,14 +11813,14 @@ function registerDoctor(program2) {
11810
11813
  fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
11811
11814
  });
11812
11815
  }
11813
- findings.push(...await collectInstallFindings(root, "0.9.22"));
11816
+ findings.push(...await collectInstallFindings(root, "0.9.23"));
11814
11817
  try {
11815
11818
  const legacyRaw = execSync3("haive-mcp --version", {
11816
11819
  encoding: "utf8",
11817
11820
  timeout: 3e3,
11818
11821
  stdio: ["ignore", "pipe", "ignore"]
11819
11822
  }).trim();
11820
- const cliVersion = "0.9.22";
11823
+ const cliVersion = "0.9.23";
11821
11824
  if (legacyRaw && legacyRaw !== cliVersion) {
11822
11825
  findings.push({
11823
11826
  severity: "warn",
@@ -12768,16 +12771,12 @@ function registerEnforce(program2) {
12768
12771
  enforce.command("cleanup").description("Remove generated hAIve runtime/cache artifacts that should not appear in commits.").option("-d, --dir <dir>", "project root").option("--dry-run", "print what would be removed without deleting", false).action(async (opts) => {
12769
12772
  const root = findProjectRoot48(opts.dir);
12770
12773
  const paths = resolveHaivePaths44(root);
12771
- const targets = [
12772
- path49.join(paths.haiveDir, ".cache")
12773
- ];
12774
- for (const target of targets) {
12775
- if (!existsSync67(target)) continue;
12776
- const rel = path49.relative(root, target);
12777
- if (opts.dryRun) ui.info(`would remove ${rel}`);
12774
+ const cacheDir = path49.join(paths.haiveDir, ".cache");
12775
+ if (existsSync67(cacheDir)) {
12776
+ if (opts.dryRun) ui.info(`would clean ${path49.relative(root, cacheDir)} (preserving .gitignore)`);
12778
12777
  else {
12779
- await rm3(target, { recursive: true, force: true });
12780
- ui.success(`removed ${rel}`);
12778
+ const removed = await cleanupCacheDir(cacheDir);
12779
+ ui.success(`cleaned ${path49.relative(root, cacheDir)}${removed > 0 ? ` (${removed} item${removed === 1 ? "" : "s"} removed)` : ""}`);
12781
12780
  }
12782
12781
  }
12783
12782
  if (existsSync67(paths.runtimeDir)) {
@@ -13008,7 +13007,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
13008
13007
  findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
13009
13008
  });
13010
13009
  }
13011
- findings.push(...await inspectIntegrationVersions(root, "0.9.22"));
13010
+ findings.push(...await inspectIntegrationVersions(root, "0.9.23"));
13012
13011
  if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
13013
13012
  const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
13014
13013
  findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
@@ -13237,6 +13236,18 @@ async function cleanupRuntimeDir(runtimeDir) {
13237
13236
  }
13238
13237
  return removed;
13239
13238
  }
13239
+ async function cleanupCacheDir(cacheDir) {
13240
+ let removed = 0;
13241
+ await mkdir19(cacheDir, { recursive: true });
13242
+ const entries = await readdir6(cacheDir, { withFileTypes: true }).catch(() => []);
13243
+ for (const entry of entries) {
13244
+ if (entry.name === ".gitignore") continue;
13245
+ await rm3(path49.join(cacheDir, entry.name), { recursive: true, force: true });
13246
+ removed++;
13247
+ }
13248
+ await writeFile31(path49.join(cacheDir, ".gitignore"), "*\n!.gitignore\n", "utf8");
13249
+ return removed;
13250
+ }
13240
13251
  async function cleanupEnforcementDir(enforcementDir) {
13241
13252
  let removed = 0;
13242
13253
  const entries = await readdir6(enforcementDir, { withFileTypes: true }).catch(() => []);
@@ -13536,7 +13547,7 @@ function registerRun(program2) {
13536
13547
 
13537
13548
  // src/index.ts
13538
13549
  var program = new Command51();
13539
- program.name("haive").description("hAIve \u2014 the memory and enforcement layer of your agent harness").version("0.9.22").option("--advanced", "show maintenance and experimental commands in help");
13550
+ program.name("haive").description("hAIve \u2014 the memory and enforcement layer of your agent harness").version("0.9.23").option("--advanced", "show maintenance and experimental commands in help");
13540
13551
  registerInit(program);
13541
13552
  registerWelcome(program);
13542
13553
  registerResolveProject(program);