@hiveai/cli 0.13.0 → 0.13.5

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
@@ -3012,7 +3012,7 @@ ${SEED_FOOTER(stack)}` });
3012
3012
  }
3013
3013
 
3014
3014
  // src/commands/init.ts
3015
- var HAIVE_GITHUB_ACTION_REF = `v${"0.13.0"}`;
3015
+ var HAIVE_GITHUB_ACTION_REF = `v${"0.13.5"}`;
3016
3016
  var PROJECT_CONTEXT_TEMPLATE = `# Project context
3017
3017
 
3018
3018
  > Generated by \`haive init\`. Run \`haive init --bootstrap\` to auto-fill from your codebase,
@@ -3176,6 +3176,27 @@ jobs:
3176
3176
  # post-if-empty: 'true' # uncomment to always post (even when no memories found)
3177
3177
  # max-memories: '5' # limit memories per file in the comment
3178
3178
 
3179
+ # On pull request: fail if the harness quality score regressed vs the committed baseline.
3180
+ # Measures whether the right memories still surface and the right sensors still fire.
3181
+ # No-op (passes) when no .ai/eval/baseline.json exists \u2014 safe to keep enabled before you
3182
+ # ever create one. To turn the gate on: run \`haive eval --baseline\` locally and commit
3183
+ # .ai/eval/baseline.json. Needs nothing external \u2014 no secrets, no services.
3184
+ pr-eval-gate:
3185
+ if: github.event_name == 'pull_request'
3186
+ runs-on: ubuntu-latest
3187
+ steps:
3188
+ - uses: actions/checkout@v4
3189
+
3190
+ - uses: actions/setup-node@v4
3191
+ with:
3192
+ node-version: '20'
3193
+
3194
+ - name: install haive
3195
+ run: npm install -g @hiveai/cli
3196
+
3197
+ - name: harness quality regression gate
3198
+ run: haive eval --regression-gate
3199
+
3179
3200
  # On push to main: push shared memories to the hub (if hubPath is configured)
3180
3201
  # Uncomment and configure hubPath in .ai/haive.config.json to enable.
3181
3202
  # hub-push:
@@ -3728,7 +3749,7 @@ async function installClaudeHooks(opts) {
3728
3749
  }
3729
3750
  function registerInstallHooks(program2) {
3730
3751
  program2.command("install-hooks [target]").description(
3731
- "Install hAIve hooks. Targets:\n\n git (default) post-merge / post-rewrite / pre-push for haive sync + precommit\n claude SessionStart + PreToolUse + PostToolUse + SessionEnd hooks\n for briefing injection, pre-edit blocking, and capture (Claude Code only)\n\n Examples:\n haive install-hooks # git hooks (legacy default)\n haive install-hooks git\n haive install-hooks claude\n haive install-hooks claude --scope project\n haive install-hooks claude --uninstall\n"
3752
+ "Install hAIve hooks (same effect as `haive enforce install`, kept for back-compat). Targets:\n\n git (default) post-merge / post-rewrite / pre-push for haive sync + precommit\n claude SessionStart + PreToolUse + PostToolUse + SessionEnd hooks\n for briefing injection, pre-edit blocking, and capture (Claude Code only)\n\n Examples:\n haive install-hooks # git hooks (legacy default)\n haive install-hooks git\n haive install-hooks claude\n haive install-hooks claude --scope project\n haive install-hooks claude --uninstall\n"
3732
3753
  ).option("-d, --dir <dir>", "project root").option("--force", "overwrite existing hooks (git target only)").option("--scope <scope>", "claude target: 'user' (~/.claude) or 'project' (.claude/)", "user").option("--uninstall", "remove previously installed hAIve hooks (claude target only)").option("--settings <path>", "explicit path to settings.json (claude target only)").action(async (target, opts) => {
3733
3754
  const t = (target ?? "git").toLowerCase();
3734
3755
  if (t === "git") {
@@ -7891,7 +7912,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
7891
7912
  };
7892
7913
  }
7893
7914
  var SERVER_NAME = "haive";
7894
- var SERVER_VERSION = "0.13.0";
7915
+ var SERVER_VERSION = "0.13.5";
7895
7916
  function jsonResult(data) {
7896
7917
  return {
7897
7918
  content: [
@@ -9287,7 +9308,7 @@ Attends une **confirmation explicite** avant d'agir.
9287
9308
 
9288
9309
  **Prochaines \xE9tapes (si confirm\xE9) :**
9289
9310
  - Rechercher les usages : \`haive memory for-files <fichiers concern\xE9s>\`
9290
- - V\xE9rifier les m\xE9moires li\xE9es : \`haive memory query ${diff.contract}\``;
9311
+ - V\xE9rifier les m\xE9moires li\xE9es : \`haive memory search ${diff.contract}\``;
9291
9312
  const fm = buildFrontmatter6({
9292
9313
  type: "gotcha",
9293
9314
  slug,
@@ -9484,8 +9505,8 @@ import {
9484
9505
  suggestSensorFromMemory as suggestSensorFromMemory3
9485
9506
  } from "@hiveai/core";
9486
9507
  function registerMemoryAdd(memory2) {
9487
- memory2.command("add").description(
9488
- `Save a piece of knowledge as a persistent memory.
9508
+ memory2.command("save").alias("add").description(
9509
+ `Save a piece of knowledge as a persistent memory. Mirrors MCP mem_save. Alias: add.
9489
9510
 
9490
9511
  Memory types:
9491
9512
  skill \u2014 reusable procedure/playbook agents follow for a recurring task (e.g. deploy, review)
@@ -10534,7 +10555,7 @@ function registerMemoryPending(memory2) {
10534
10555
  const pending = all.filter(filterFn);
10535
10556
  if (pending.length === 0) {
10536
10557
  ui.info("No draft or proposed memories awaiting review.");
10537
- ui.info("Drafts are created by `haive memory add` without `--status validated`.");
10558
+ ui.info("Drafts are created by `haive memory save` without `--status validated`.");
10538
10559
  return;
10539
10560
  }
10540
10561
  pending.sort(
@@ -10591,7 +10612,7 @@ import {
10591
10612
  trackReads as trackReads4
10592
10613
  } from "@hiveai/core";
10593
10614
  function registerMemoryQuery(memory2) {
10594
- memory2.command("query <text>").alias("search").description("Search memories by id, tag, or substring (AND, OR fallback). Alias: search").option("-d, --dir <dir>", "project root").option("--limit <n>", "max results", "20").option("--scope <scope>", "personal | team | module").option("--status <csv>", "filter by status (draft,proposed,validated,stale,rejected)").option("--show-rejected", "include rejected memories (hidden by default)").action(async (text, opts) => {
10615
+ memory2.command("search <text>").alias("query").description("Search memories by id, tag, or substring (AND, OR fallback). Mirrors MCP mem_search. Alias: query").option("-d, --dir <dir>", "project root").option("--limit <n>", "max results", "20").option("--scope <scope>", "personal | team | module").option("--status <csv>", "filter by status (draft,proposed,validated,stale,rejected)").option("--show-rejected", "include rejected memories (hidden by default)").action(async (text, opts) => {
10595
10616
  const root = findProjectRoot25(opts.dir);
10596
10617
  const paths = resolveHaivePaths22(root);
10597
10618
  if (!existsSync47(paths.memoriesDir)) {
@@ -10715,7 +10736,7 @@ import {
10715
10736
  saveUsageIndex as saveUsageIndex5
10716
10737
  } from "@hiveai/core";
10717
10738
  function registerMemoryRm(memory2) {
10718
- memory2.command("rm <id>").description("Delete a memory file (and its usage entry by default)").option("-y, --yes", "skip the confirmation prompt").option("--keep-usage", "do not remove the usage.json entry").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
10739
+ memory2.command("delete <id>").alias("rm").description("Delete a memory file (and its usage entry by default). Mirrors MCP mem_delete. Alias: rm").option("-y, --yes", "skip the confirmation prompt").option("--keep-usage", "do not remove the usage.json entry").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
10719
10740
  const root = findProjectRoot27(opts.dir);
10720
10741
  const paths = resolveHaivePaths24(root);
10721
10742
  if (!existsSync49(paths.memoriesDir)) {
@@ -10766,7 +10787,7 @@ import {
10766
10787
  resolveHaivePaths as resolveHaivePaths25
10767
10788
  } from "@hiveai/core";
10768
10789
  function registerMemoryShow(memory2) {
10769
- memory2.command("show <id>").description("Print a memory's frontmatter, body, and confidence/usage").option("--raw", "print the raw file contents instead of a summary").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
10790
+ memory2.command("get <id>").alias("show").description("Print a memory's frontmatter, body, and confidence/usage. Mirrors MCP mem_get. Alias: show").option("--raw", "print the raw file contents instead of a summary").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
10770
10791
  const root = findProjectRoot28(opts.dir);
10771
10792
  const paths = resolveHaivePaths25(root);
10772
10793
  if (!existsSync50(paths.memoriesDir)) {
@@ -12334,7 +12355,7 @@ async function renderMemoryHits(paths, opts) {
12334
12355
  console.log(ui.bold(`Memory hits (${window})`));
12335
12356
  if (entries.length === 0) {
12336
12357
  ui.info(
12337
- `No memory reads recorded in window. Reads are logged when \`haive briefing\` or \`haive memory query\` surface a memory.`
12358
+ `No memory reads recorded in window. Reads are logged when \`haive briefing\` or \`haive memory search\` surface a memory.`
12338
12359
  );
12339
12360
  return;
12340
12361
  }
@@ -12367,7 +12388,7 @@ import {
12367
12388
  resolveHaivePaths as resolveHaivePaths37
12368
12389
  } from "@hiveai/core";
12369
12390
  function registerBench(program2) {
12370
- program2.command("bench").description("Self-test the local hAIve setup: runs core MCP tools against this project and reports latency + payload size.").option("-t, --task <task>", "task description for ranking-aware tools", "audit dependencies for security risks").option("--json", "emit JSON instead of a table", false).option("-d, --dir <dir>", "project root").action(async (opts) => {
12391
+ program2.command("selftest").alias("bench").description("Self-test the LOCAL hAIve install: runs core MCP tools against this project and reports latency + payload size. Different from `benchmark` (which measures hAIve-vs-plain agent value). Alias: bench").option("-t, --task <task>", "task description for ranking-aware tools", "audit dependencies for security risks").option("--json", "emit JSON instead of a table", false).option("-d, --dir <dir>", "project root").action(async (opts) => {
12371
12392
  const root = findProjectRoot40(opts.dir);
12372
12393
  const paths = resolveHaivePaths37(root);
12373
12394
  const ctx = { paths };
@@ -12494,7 +12515,7 @@ import path41 from "path";
12494
12515
  import "commander";
12495
12516
  import { estimateTokens as estimateTokens4, findProjectRoot as findProjectRoot41 } from "@hiveai/core";
12496
12517
  function registerBenchmark(program2) {
12497
- const benchmark = program2.command("benchmark").description("Official hAIve benchmark/demo utilities for measuring agent enforcement value.");
12518
+ const benchmark = program2.command("benchmark").description("Measure hAIve's VALUE: paired hAIve-vs-plain agent runs (correctness, tokens, tools). Different from `selftest` (which only checks local install latency).");
12498
12519
  benchmark.command("report").description("Summarize BENCHMARK_AGENT_REPORT.md files from a paired hAIve/plain agent benchmark.").option("-d, --dir <dir>", "benchmark root", "benchmarks/agent-benchmark").option("--out <file>", "write a Markdown report").option("--json", "emit JSON", false).action(async (opts) => {
12499
12520
  const root = resolveBenchmarkRoot(opts.dir);
12500
12521
  const rows = await collectRows(root);
@@ -13323,7 +13344,7 @@ function registerDoctor(program2) {
13323
13344
  severity: "warn",
13324
13345
  code: "stale-draft-memories",
13325
13346
  message: `${oldDrafts.length} draft memor${oldDrafts.length === 1 ? "y has" : "ies have"} been in draft status for 30+ days: ${ids}${more}`,
13326
- fix: "haive memory approve <id> # activate\nhaive memory rm <id> # or delete if obsolete"
13347
+ fix: "haive memory approve <id> # activate\nhaive memory delete <id> # or delete if obsolete"
13327
13348
  });
13328
13349
  }
13329
13350
  const policyMemories = memories.filter((m) => !isStackPackSeed4(m.memory.frontmatter));
@@ -13460,7 +13481,7 @@ function registerDoctor(program2) {
13460
13481
  fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
13461
13482
  });
13462
13483
  }
13463
- findings.push(...await collectInstallFindings(root, "0.13.0"));
13484
+ findings.push(...await collectInstallFindings(root, "0.13.5"));
13464
13485
  findings.push(...await collectToolchainFindings(root));
13465
13486
  try {
13466
13487
  const legacyRaw = execSync3("haive-mcp --version", {
@@ -13468,7 +13489,7 @@ function registerDoctor(program2) {
13468
13489
  timeout: 3e3,
13469
13490
  stdio: ["ignore", "pipe", "ignore"]
13470
13491
  }).trim();
13471
- const cliVersion = "0.13.0";
13492
+ const cliVersion = "0.13.5";
13472
13493
  if (legacyRaw && legacyRaw !== cliVersion) {
13473
13494
  findings.push({
13474
13495
  severity: "warn",
@@ -13684,7 +13705,7 @@ async function collectHarnessCoverageFindings(codeMap, memories) {
13684
13705
  code: "harness-coverage",
13685
13706
  coverage_percent: pct2,
13686
13707
  message: `${covered}/${total} code-map files have validated memory anchors (${pct2}%). ` + coverageDesc + uncoveredHint,
13687
- fix: pct2 < 50 && total > 10 ? `haive memory add --type gotcha|convention|architecture --paths <key-file> --scope team` : void 0,
13708
+ fix: pct2 < 50 && total > 10 ? `haive memory save --type gotcha|convention|architecture --paths <key-file> --scope team` : void 0,
13688
13709
  section: "Harness coverage"
13689
13710
  });
13690
13711
  return findings;
@@ -14145,7 +14166,7 @@ import {
14145
14166
  } from "@hiveai/core";
14146
14167
  function registerPrecommit(program2) {
14147
14168
  program2.command("precommit").description(
14148
- "Run a pre-commit safety check: scans `git diff --cached` against known anti-patterns,\n surfaces conventions/decisions anchored to touched files, and warns about stale anchored memories.\n\n Wire it into git as: `.git/hooks/pre-commit` running `haive precommit` (exit 1 = block).\n\n Examples:\n haive precommit # auto-detects staged diff\n haive precommit --block-on any # block on any warning, not just high-confidence\n haive precommit --paths src/auth.ts src/db.ts # explicit paths instead of git diff"
14169
+ "Run a pre-commit safety check (manual variant of `haive enforce check --stage pre-commit`):\n scans `git diff --cached` against known anti-patterns,\n surfaces conventions/decisions anchored to touched files, and warns about stale anchored memories.\n\n Wire it into git as: `.git/hooks/pre-commit` running `haive precommit` (exit 1 = block).\n\n Examples:\n haive precommit # auto-detects staged diff\n haive precommit --block-on any # block on any warning, not just high-confidence\n haive precommit --paths src/auth.ts src/db.ts # explicit paths instead of git diff"
14149
14170
  ).option(
14150
14171
  "--block-on <mode>",
14151
14172
  "'any' | 'high-confidence' | 'never' (report only). Default: derived from enforcement.antiPatternGate."
@@ -14335,7 +14356,7 @@ function registerWelcome(program2) {
14335
14356
  console.log(ui.bold(`hAIve welcome \u2014 ${pick.length} team memories (${root})`));
14336
14357
  console.log(ui.dim(`Next: invoke get_briefing with your task or run 'haive briefing --task "\u2026"'`));
14337
14358
  if (pick.length === 0) {
14338
- ui.warn("No team memories yet \u2014 add some with 'haive memory add' or promote personal ones.");
14359
+ ui.warn("No team memories yet \u2014 add some with 'haive memory save' or promote personal ones.");
14339
14360
  return;
14340
14361
  }
14341
14362
  let i = 1;
@@ -15032,7 +15053,10 @@ async function buildEnforcementReport(dir, stage, sessionId) {
15032
15053
  const paths = resolveHaivePaths48(root);
15033
15054
  const initialized = existsSync75(paths.haiveDir);
15034
15055
  const config = initialized ? await loadConfig13(paths) : {};
15035
- if (initialized) await applyLightweightRepairs(root, paths);
15056
+ if (initialized) {
15057
+ await applyLightweightRepairs(root, paths);
15058
+ if (stage === "pre-commit") await stageResyncedArtifacts(root, paths);
15059
+ }
15036
15060
  const mode = config.enforcement?.mode ?? "strict";
15037
15061
  const findings = [];
15038
15062
  if (!initialized) {
@@ -15061,7 +15085,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
15061
15085
  findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
15062
15086
  });
15063
15087
  }
15064
- findings.push(...await inspectIntegrationVersions(root, "0.13.0"));
15088
+ findings.push(...await inspectIntegrationVersions(root, "0.13.5"));
15065
15089
  if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
15066
15090
  const hasBriefing = await hasRecentBriefingMarker2(paths, sessionId);
15067
15091
  findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
@@ -15950,6 +15974,15 @@ async function readStdin2(maxBytes) {
15950
15974
  setTimeout(finish, 2e3);
15951
15975
  });
15952
15976
  }
15977
+ async function stageResyncedArtifacts(root, paths) {
15978
+ const rel = path51.relative(root, paths.projectContext);
15979
+ const tracked = await runCommand4("git", ["ls-files", "--error-unmatch", "--", rel], root).then(() => true).catch(() => false);
15980
+ if (!tracked) return;
15981
+ const unchanged = await runCommand4("git", ["diff", "--quiet", "--", rel], root).then(() => true).catch(() => false);
15982
+ if (unchanged) return;
15983
+ await runCommand4("git", ["add", "--", rel], root).catch(() => {
15984
+ });
15985
+ }
15953
15986
  function runCommand4(cmd, args, cwd) {
15954
15987
  return new Promise((resolve, reject) => {
15955
15988
  const proc = spawn6(cmd, args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
@@ -16467,7 +16500,7 @@ function warnNum(n) {
16467
16500
 
16468
16501
  // src/index.ts
16469
16502
  var program = new Command58();
16470
- program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.13.0").option("--advanced", "show maintenance and experimental commands in help");
16503
+ program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.13.5").option("--advanced", "show maintenance and experimental commands in help");
16471
16504
  registerInit(program);
16472
16505
  registerWelcome(program);
16473
16506
  registerResolveProject(program);
@@ -16543,14 +16576,14 @@ var CORE_ROOT_COMMANDS = /* @__PURE__ */ new Set([
16543
16576
  "session"
16544
16577
  ]);
16545
16578
  var CORE_MEMORY_COMMANDS = /* @__PURE__ */ new Set([
16546
- "add",
16579
+ "save",
16547
16580
  "list",
16548
- "query",
16549
- "show",
16581
+ "search",
16582
+ "get",
16550
16583
  "verify",
16551
16584
  "lint",
16552
16585
  "tried",
16553
- "rm"
16586
+ "delete"
16554
16587
  ]);
16555
16588
  var CORE_SESSION_COMMANDS = /* @__PURE__ */ new Set(["end"]);
16556
16589
  applySurfaceVisibility(program);
@@ -16568,12 +16601,24 @@ program.parseAsync(process.argv).catch((err) => {
16568
16601
  function applySurfaceVisibility(root) {
16569
16602
  const showAdvanced = process.argv.includes("--advanced") || process.env.HAIVE_SHOW_ADVANCED === "1";
16570
16603
  if (!showAdvanced) hideNonCoreCommands(root);
16604
+ const familiesBlock = showAdvanced ? [
16605
+ "",
16606
+ "Advanced surface, by family:",
16607
+ " reports: dashboard \xB7 stats \xB7 playback eval: eval \xB7 benchmark \xB7 selftest (alias: bench)",
16608
+ " index: index \xB7 code-search \xB7 embeddings runtime: runtime \xB7 observe \xB7 snapshot",
16609
+ " ops: memory <sub> \xB7 sensors \xB7 ingest \xB7 hub \xB7 sync \xB7 install-hooks (= enforce install) \xB7 precommit (= enforce check)"
16610
+ ] : [];
16571
16611
  root.addHelpText(
16572
16612
  "after",
16573
16613
  [
16574
16614
  "",
16575
- "Default help shows the core harness workflow: init, doctor, agent setup, briefing, enforcement,",
16576
- "sync, session recaps, and high-signal memory commands.",
16615
+ "Golden path (what you type day to day):",
16616
+ " init \u2192 doctor \u2192 agent setup \u2192 briefing \u2192 memory save/tried \u2192 sensors check \u2192 enforce finish \u2192 sync \u2192 session end",
16617
+ "",
16618
+ "Memory verbs mirror the MCP tools: memory save/search/get/delete <-> mem_save/mem_search/mem_get/mem_delete",
16619
+ "(old verbs add/query/show/rm still work as aliases).",
16620
+ ...familiesBlock,
16621
+ "",
16577
16622
  "Run `haive --advanced --help` or set HAIVE_SHOW_ADVANCED=1 to show maintenance and experimental commands."
16578
16623
  ].join("\n")
16579
16624
  );