@hivelore/cli 0.47.0 → 0.49.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
@@ -13,7 +13,7 @@ import {
13
13
  readPresumedCorrectTargets,
14
14
  runAstSensorOnContent,
15
15
  runHaiveMcpStdio
16
- } from "./chunk-HBS7PNNY.js";
16
+ } from "./chunk-VW4U72ET.js";
17
17
  import {
18
18
  registerMemoryPending
19
19
  } from "./chunk-OYJKHD22.js";
@@ -3758,7 +3758,7 @@ ${SEED_FOOTER(stack)}` });
3758
3758
 
3759
3759
  // src/commands/init.ts
3760
3760
  var execFileAsync = promisify2(execFile2);
3761
- var HAIVE_GITHUB_ACTION_REF = `v${"0.47.0"}`;
3761
+ var HAIVE_GITHUB_ACTION_REF = `v${"0.49.0"}`;
3762
3762
  var PROJECT_CONTEXT_TEMPLATE = `# Project context
3763
3763
 
3764
3764
  > Generated by \`hivelore init\`. Run \`hivelore init --bootstrap\` to auto-fill from your codebase,
@@ -4170,7 +4170,11 @@ function registerInit(program2) {
4170
4170
  "!.ai/.cache/.gitignore",
4171
4171
  ".ai/.runtime/*",
4172
4172
  "!.ai/.runtime/.gitignore",
4173
- "!.ai/.runtime/README.md"
4173
+ "!.ai/.runtime/README.md",
4174
+ // Machine-local tool-usage telemetry — like .cache/.runtime, it changes on every invocation
4175
+ // and is never team truth (eval baselines exclude local usage counters). Committing it made the
4176
+ // working tree perpetually dirty and forced a stash before every release.
4177
+ ".ai/.usage/"
4174
4178
  ]);
4175
4179
  ui.success(`Hivelore initialized at ${root}${autopilot ? " (autopilot mode)" : ""}`);
4176
4180
  if (json) {
@@ -9142,7 +9146,7 @@ function registerDoctor(program2) {
9142
9146
  }
9143
9147
  const astSensorCount = sensorMemories.filter((m) => m.memory.frontmatter.sensor?.kind === "ast").length;
9144
9148
  if (astSensorCount > 0) {
9145
- const { astEngineAvailable: astEngineAvailable2 } = await import("./server-LNSXYVVW.js");
9149
+ const { astEngineAvailable: astEngineAvailable2 } = await import("./server-ZE5Y3Z4A.js");
9146
9150
  if (!await astEngineAvailable2()) {
9147
9151
  findings.push({
9148
9152
  severity: "warn",
@@ -9313,8 +9317,8 @@ function registerDoctor(program2) {
9313
9317
  fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `hivelore init` without --manual)."
9314
9318
  });
9315
9319
  }
9316
- findings.push(...await collectInstallFindings(root, "0.47.0"));
9317
- findings.push(...await collectMcpRuntimeFindings(paths, "0.47.0"));
9320
+ findings.push(...await collectInstallFindings(root, "0.49.0"));
9321
+ findings.push(...await collectMcpRuntimeFindings(paths, "0.49.0"));
9318
9322
  findings.push(...await collectToolchainFindings(root));
9319
9323
  try {
9320
9324
  const legacyRaw = execSync("haive-mcp --version", {
@@ -9322,7 +9326,7 @@ function registerDoctor(program2) {
9322
9326
  timeout: 3e3,
9323
9327
  stdio: ["ignore", "pipe", "ignore"]
9324
9328
  }).trim();
9325
- const cliVersion = "0.47.0";
9329
+ const cliVersion = "0.49.0";
9326
9330
  if (legacyRaw && legacyRaw !== cliVersion) {
9327
9331
  findings.push({
9328
9332
  severity: "warn",
@@ -10708,7 +10712,7 @@ async function buildFinishReport(dir) {
10708
10712
  }
10709
10713
  findings.push(...await checkFailureCapture(paths, config));
10710
10714
  findings.push(...await checkPostIncidentScaffolds(paths));
10711
- findings.push(...await checkBootstrapComplete(paths, config, true));
10715
+ findings.push(...await checkBootstrapComplete(paths, config, true, "pre-push"));
10712
10716
  const status = await getGitSyncStatus(root);
10713
10717
  if (!status.available) {
10714
10718
  findings.push({
@@ -11054,7 +11058,7 @@ function looksLikeProductionCode(file) {
11054
11058
  if (/(^|\/)(test|tests|__tests__|__mocks__|e2e|fixtures)(\/|$)/.test(f)) return false;
11055
11059
  return PRODUCTION_CODE_EXT.test(f);
11056
11060
  }
11057
- async function checkBootstrapComplete(paths, config, productionCodeChanged) {
11061
+ async function checkBootstrapComplete(paths, config, productionCodeChanged, stage) {
11058
11062
  const gate = config.enforcement?.bootstrapGate ?? "block";
11059
11063
  if (gate === "off") return [];
11060
11064
  let projectContextRaw = "";
@@ -11080,7 +11084,8 @@ async function checkBootstrapComplete(paths, config, productionCodeChanged) {
11080
11084
  }];
11081
11085
  }
11082
11086
  const hasCodeAreas = assessment.metrics.mainAreas > 0;
11083
- const blocking = gate === "block" && hasCodeAreas && productionCodeChanged;
11087
+ const enforcedStage = stage === "pre-push" || stage === "ci";
11088
+ const blocking = gate === "block" && hasCodeAreas && productionCodeChanged && enforcedStage;
11084
11089
  const severity = blocking ? "error" : hasCodeAreas ? "warn" : "info";
11085
11090
  return [{
11086
11091
  severity,
@@ -11128,7 +11133,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
11128
11133
  findings: [{ severity: "info", code: "enforcement-off", message: "Hivelore enforcement is disabled." }]
11129
11134
  });
11130
11135
  }
11131
- findings.push(...await inspectIntegrationVersions(root, "0.47.0"));
11136
+ findings.push(...await inspectIntegrationVersions(root, "0.49.0"));
11132
11137
  if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
11133
11138
  const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
11134
11139
  findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent Hivelore briefing marker exists." } : {
@@ -11176,7 +11181,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
11176
11181
  }
11177
11182
  {
11178
11183
  const changed = await getChangedFiles(root, stage).catch(() => []);
11179
- findings.push(...await checkBootstrapComplete(paths, config, changed.some(looksLikeProductionCode)));
11184
+ findings.push(...await checkBootstrapComplete(paths, config, changed.some(looksLikeProductionCode), stage));
11180
11185
  }
11181
11186
  const agentContext = detectAgentContext();
11182
11187
  const relaxForHuman = stage !== "ci" && !agentContext.agent && (config.enforcement?.humanCommits ?? "relaxed") === "relaxed";
@@ -12769,6 +12774,7 @@ import {
12769
12774
  buildProposeCommand,
12770
12775
  scaffoldPostIncidentTest,
12771
12776
  incidentHintsFromDiff,
12777
+ normalizeScaffoldStyle,
12772
12778
  selectCommandSensors as selectCommandSensors2,
12773
12779
  TEST_FRAMEWORKS,
12774
12780
  sensorPatternBrittleness as sensorPatternBrittleness2,
@@ -13100,7 +13106,7 @@ function registerSensors(program2) {
13100
13106
  }
13101
13107
  }
13102
13108
  const root2 = findProjectRoot39(opts.dir);
13103
- const { proposeSensor } = await import("./server-LNSXYVVW.js");
13109
+ const { proposeSensor } = await import("./server-ZE5Y3Z4A.js");
13104
13110
  const out = await proposeSensor(
13105
13111
  {
13106
13112
  memory_id: id,
@@ -13227,6 +13233,12 @@ function registerSensors(program2) {
13227
13233
  ).argument("<memory-id>", "lesson id to scaffold a test from").option("--framework <fw>", `test framework: ${TEST_FRAMEWORKS.join(" | ")} (auto-detected when omitted)`).option("--out <path>", "override the generated test file path (project-relative)").option("--stdout", "print the test to stdout instead of writing a file", false).option("--force", "overwrite an existing file at the target path", false).option(
13228
13234
  "--red-ref <ref>",
13229
13235
  "pre-fix incident commit/ref: the scaffold names the symbols the fix (<ref>..HEAD) touched and pre-fills the example around them, so the assertion is a targeted edit, not a blank page"
13236
+ ).option(
13237
+ "--style <style>",
13238
+ "test shape: example (default) | property (state the invariant once, checked over many inputs via fast-check/Hypothesis) | differential (assert the subject agrees with a --reference impl)"
13239
+ ).option(
13240
+ "--reference <import>",
13241
+ "differential style only: import specifier of the reference implementation to compare against (e.g. ../legacy/refund or a package name)"
13230
13242
  ).option("-d, --dir <dir>", "project root").action(async (id, opts) => {
13231
13243
  const root = findProjectRoot39(opts.dir);
13232
13244
  const paths = resolveHaivePaths36(root);
@@ -13244,6 +13256,17 @@ function registerSensors(program2) {
13244
13256
  process.exitCode = 1;
13245
13257
  return;
13246
13258
  }
13259
+ const style = opts.style ? normalizeScaffoldStyle(opts.style) : "example";
13260
+ if (opts.style && !style) {
13261
+ ui.error(`Unknown --style "${opts.style}". Use one of: example, property, differential.`);
13262
+ process.exitCode = 1;
13263
+ return;
13264
+ }
13265
+ if (style === "differential" && !opts.reference) {
13266
+ ui.error("--style differential requires --reference <import> (the reference implementation to compare against).");
13267
+ process.exitCode = 1;
13268
+ return;
13269
+ }
13247
13270
  const allGroups = await detectTestFrameworksForAnchors(root, fm.anchor.paths ?? []);
13248
13271
  const groups = opts.out ? allGroups.slice(0, 1) : allGroups;
13249
13272
  const fields = parseLessonFields(found.memory.body);
@@ -13270,14 +13293,15 @@ function registerSensors(program2) {
13270
13293
  paths: fm.anchor.paths,
13271
13294
  incidentHints
13272
13295
  };
13296
+ const styleOpts = { style: style ?? "example", reference: opts.reference };
13273
13297
  let scaffolds = groups.map(
13274
- (g) => scaffoldPostIncidentTest(lesson, { framework: forced ?? g.framework, outPath: opts.out, baseDir: g.baseDir })
13298
+ (g) => scaffoldPostIncidentTest(lesson, { framework: forced ?? g.framework, outPath: opts.out, baseDir: g.baseDir, ...styleOpts })
13275
13299
  );
13276
13300
  let proposeCmd = scaffolds[0].proposeCommand;
13277
13301
  if (scaffolds.length > 1) {
13278
13302
  proposeCmd = buildProposeCommand(lesson, scaffolds.map((s) => s.runCommand).join(" && "));
13279
13303
  scaffolds = groups.map(
13280
- (g) => scaffoldPostIncidentTest(lesson, { framework: forced ?? g.framework, baseDir: g.baseDir, proposeCommandOverride: proposeCmd })
13304
+ (g) => scaffoldPostIncidentTest(lesson, { framework: forced ?? g.framework, baseDir: g.baseDir, proposeCommandOverride: proposeCmd, ...styleOpts })
13281
13305
  );
13282
13306
  }
13283
13307
  if (opts.stdout) {
@@ -14149,7 +14173,7 @@ function registerBridges(program2) {
14149
14173
 
14150
14174
  // src/index.ts
14151
14175
  var program = new Command48();
14152
- program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.47.0").option("--advanced", "show maintenance and experimental commands in help").showSuggestionAfterError(true);
14176
+ program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.49.0").option("--advanced", "show maintenance and experimental commands in help").showSuggestionAfterError(true);
14153
14177
  registerInit(program);
14154
14178
  registerResolveProject(program);
14155
14179
  registerEnforce(program);