@hivelore/cli 0.44.0 → 0.47.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/{chunk-6KRXMDLC.js → chunk-HBS7PNNY.js} +37 -9
- package/dist/chunk-HBS7PNNY.js.map +1 -0
- package/dist/index.js +84 -17
- package/dist/index.js.map +1 -1
- package/dist/{server-MCNCAFJN.js → server-LNSXYVVW.js} +2 -2
- package/package.json +4 -4
- package/dist/chunk-6KRXMDLC.js.map +0 -1
- /package/dist/{server-MCNCAFJN.js.map → server-LNSXYVVW.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
readPresumedCorrectTargets,
|
|
14
14
|
runAstSensorOnContent,
|
|
15
15
|
runHaiveMcpStdio
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-HBS7PNNY.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.
|
|
3761
|
+
var HAIVE_GITHUB_ACTION_REF = `v${"0.47.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,
|
|
@@ -7418,7 +7418,10 @@ import { mkdir as mkdir12, writeFile as writeFile18 } from "fs/promises";
|
|
|
7418
7418
|
import path30 from "path";
|
|
7419
7419
|
import {
|
|
7420
7420
|
aggregateUsage,
|
|
7421
|
+
assessBehaviourCoverage,
|
|
7421
7422
|
buildPreventionReceipt,
|
|
7423
|
+
loadCodeMap as loadCodeMap6,
|
|
7424
|
+
renderBehaviourCoverageLine,
|
|
7422
7425
|
renderPreventionReceipt,
|
|
7423
7426
|
findProjectRoot as findProjectRoot28,
|
|
7424
7427
|
loadMemoriesFromDir as loadMemoriesFromDir11,
|
|
@@ -7447,6 +7450,19 @@ function registerStats(program2) {
|
|
|
7447
7450
|
const receipt = buildPreventionReceipt(events, memories, usage, { since });
|
|
7448
7451
|
const output = sub.share ? renderPreventionReceiptShare(receipt) : opts.json ? JSON.stringify(receipt, null, 2) : renderPreventionReceipt(receipt);
|
|
7449
7452
|
console.log(output);
|
|
7453
|
+
if (!opts.json && !sub.share) {
|
|
7454
|
+
try {
|
|
7455
|
+
const codeMap = await loadCodeMap6(paths);
|
|
7456
|
+
if (codeMap) {
|
|
7457
|
+
const cov = assessBehaviourCoverage({ memories, codeFiles: Object.keys(codeMap.files) });
|
|
7458
|
+
if (cov.mainAreas.length > 0) {
|
|
7459
|
+
console.log(`
|
|
7460
|
+
Behaviour harness: ${renderBehaviourCoverageLine(cov)}.`);
|
|
7461
|
+
}
|
|
7462
|
+
}
|
|
7463
|
+
} catch {
|
|
7464
|
+
}
|
|
7465
|
+
}
|
|
7450
7466
|
});
|
|
7451
7467
|
stats.option("--since <window>", "ISO date or relative (e.g. '7d', '24h', '30m')", "30d").option("--json", "emit JSON instead of human-readable output", false).option("--memory-hits", "show top-read memories (which mems are actually being used)", false).option(
|
|
7452
7468
|
"--export-report <path>",
|
|
@@ -8785,6 +8801,8 @@ import "commander";
|
|
|
8785
8801
|
import {
|
|
8786
8802
|
codeMapPath as codeMapPath2,
|
|
8787
8803
|
assessSensorHealth as assessSensorHealth2,
|
|
8804
|
+
assessBehaviourCoverage as assessBehaviourCoverage2,
|
|
8805
|
+
renderBehaviourCoverageLine as renderBehaviourCoverageLine2,
|
|
8788
8806
|
sensorPromotedAtMap as sensorPromotedAtMap2,
|
|
8789
8807
|
countSourceFilesOnDisk,
|
|
8790
8808
|
extractReferencedPaths,
|
|
@@ -8793,7 +8811,7 @@ import {
|
|
|
8793
8811
|
findProjectRoot as findProjectRoot35,
|
|
8794
8812
|
getUsage as getUsage9,
|
|
8795
8813
|
isStackPackSeed as isStackPackSeed2,
|
|
8796
|
-
loadCodeMap as
|
|
8814
|
+
loadCodeMap as loadCodeMap7,
|
|
8797
8815
|
loadConfig as loadConfig10,
|
|
8798
8816
|
loadMemoriesFromDirDetailed,
|
|
8799
8817
|
loadSensorLedger as loadSensorLedger2,
|
|
@@ -9124,7 +9142,7 @@ function registerDoctor(program2) {
|
|
|
9124
9142
|
}
|
|
9125
9143
|
const astSensorCount = sensorMemories.filter((m) => m.memory.frontmatter.sensor?.kind === "ast").length;
|
|
9126
9144
|
if (astSensorCount > 0) {
|
|
9127
|
-
const { astEngineAvailable: astEngineAvailable2 } = await import("./server-
|
|
9145
|
+
const { astEngineAvailable: astEngineAvailable2 } = await import("./server-LNSXYVVW.js");
|
|
9128
9146
|
if (!await astEngineAvailable2()) {
|
|
9129
9147
|
findings.push({
|
|
9130
9148
|
severity: "warn",
|
|
@@ -9185,7 +9203,7 @@ function registerDoctor(program2) {
|
|
|
9185
9203
|
fix: "Review the sensor manually; no automatic delete/retire command is provided."
|
|
9186
9204
|
});
|
|
9187
9205
|
}
|
|
9188
|
-
const codeMap = await
|
|
9206
|
+
const codeMap = await loadCodeMap7(paths);
|
|
9189
9207
|
if (!codeMap) {
|
|
9190
9208
|
findings.push({
|
|
9191
9209
|
severity: "warn",
|
|
@@ -9217,6 +9235,7 @@ function registerDoctor(program2) {
|
|
|
9217
9235
|
}
|
|
9218
9236
|
}
|
|
9219
9237
|
findings.push(...await collectHarnessCoverageFindings(codeMap, memories));
|
|
9238
|
+
findings.push(...collectBehaviourCoverageFindings(codeMap, memories));
|
|
9220
9239
|
findings.push(...await collectSemanticIndexFindings(paths, config, memories.length, codeMap));
|
|
9221
9240
|
try {
|
|
9222
9241
|
const scaffoldGaps = await collectScaffoldLoopGaps(paths);
|
|
@@ -9294,8 +9313,8 @@ function registerDoctor(program2) {
|
|
|
9294
9313
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `hivelore init` without --manual)."
|
|
9295
9314
|
});
|
|
9296
9315
|
}
|
|
9297
|
-
findings.push(...await collectInstallFindings(root, "0.
|
|
9298
|
-
findings.push(...await collectMcpRuntimeFindings(paths, "0.
|
|
9316
|
+
findings.push(...await collectInstallFindings(root, "0.47.0"));
|
|
9317
|
+
findings.push(...await collectMcpRuntimeFindings(paths, "0.47.0"));
|
|
9299
9318
|
findings.push(...await collectToolchainFindings(root));
|
|
9300
9319
|
try {
|
|
9301
9320
|
const legacyRaw = execSync("haive-mcp --version", {
|
|
@@ -9303,7 +9322,7 @@ function registerDoctor(program2) {
|
|
|
9303
9322
|
timeout: 3e3,
|
|
9304
9323
|
stdio: ["ignore", "pipe", "ignore"]
|
|
9305
9324
|
}).trim();
|
|
9306
|
-
const cliVersion = "0.
|
|
9325
|
+
const cliVersion = "0.47.0";
|
|
9307
9326
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
9308
9327
|
findings.push({
|
|
9309
9328
|
severity: "warn",
|
|
@@ -9560,6 +9579,32 @@ async function collectHarnessCoverageFindings(codeMap, memories) {
|
|
|
9560
9579
|
});
|
|
9561
9580
|
return findings;
|
|
9562
9581
|
}
|
|
9582
|
+
function collectBehaviourCoverageFindings(codeMap, memories) {
|
|
9583
|
+
if (!codeMap) return [];
|
|
9584
|
+
const codeFiles = Object.keys(codeMap.files);
|
|
9585
|
+
const cov = assessBehaviourCoverage2({ memories, codeFiles });
|
|
9586
|
+
if (cov.mainAreas.length === 0) return [];
|
|
9587
|
+
const uncoveredHint = cov.uncoveredAreas.length > 0 && cov.totalOracles > 0 ? `
|
|
9588
|
+
No behavioural oracle: ${cov.uncoveredAreas.slice(0, 5).map((a) => `\`${a}\``).join(", ")}` + (cov.uncoveredAreas.length > 5 ? `, +${cov.uncoveredAreas.length - 5} more` : "") : "";
|
|
9589
|
+
let fix;
|
|
9590
|
+
if (cov.uncoveredAreas.length > 0) {
|
|
9591
|
+
const lines = cov.uncoveredAreaSuggestions.slice(0, 4).map(
|
|
9592
|
+
(s) => s.candidateLessonId ? `hivelore sensors scaffold ${s.candidateLessonId} --red-ref <pre-fix-commit> # guard ${s.area}` : `hivelore memory tried --paths ${s.area}/ --what "<incident>" --why-failed "<why>" # then scaffold --red-ref for ${s.area}`
|
|
9593
|
+
);
|
|
9594
|
+
if (cov.uncoveredAreas.length > 4) lines.push(`# +${cov.uncoveredAreas.length - 4} more uncovered area(s) \u2014 run doctor after guarding these`);
|
|
9595
|
+
fix = lines.join("\n");
|
|
9596
|
+
} else if (cov.armedOracles < cov.totalOracles || cov.redProvenOracles < cov.armedOracles) {
|
|
9597
|
+
fix = "Arm warn-only oracles to `block` and re-propose with `--red-ref` so each substantiates its incident.";
|
|
9598
|
+
}
|
|
9599
|
+
return [{
|
|
9600
|
+
severity: "info",
|
|
9601
|
+
code: "behaviour-coverage",
|
|
9602
|
+
section: "Protection",
|
|
9603
|
+
coverage_percent: Math.round(cov.areasWithOracle.length / cov.mainAreas.length * 100),
|
|
9604
|
+
message: `Behaviour harness: ${renderBehaviourCoverageLine2(cov)}.` + uncoveredHint,
|
|
9605
|
+
fix
|
|
9606
|
+
}];
|
|
9607
|
+
}
|
|
9563
9608
|
async function collectSemanticIndexFindings(paths, config, memoryCount, codeMap) {
|
|
9564
9609
|
const findings = [];
|
|
9565
9610
|
const autoWantsCodeSearch = Boolean(config.autopilot || config.autoRepair?.codeSearch);
|
|
@@ -10085,7 +10130,7 @@ import {
|
|
|
10085
10130
|
detectSensorWeakening,
|
|
10086
10131
|
isSensorScannablePath,
|
|
10087
10132
|
findProjectRoot as findProjectRoot37,
|
|
10088
|
-
loadCodeMap as
|
|
10133
|
+
loadCodeMap as loadCodeMap8,
|
|
10089
10134
|
renderBootstrapChecklist,
|
|
10090
10135
|
findUncapturedFailures,
|
|
10091
10136
|
handoffAgeMs,
|
|
@@ -11018,7 +11063,7 @@ async function checkBootstrapComplete(paths, config, productionCodeChanged) {
|
|
|
11018
11063
|
} catch {
|
|
11019
11064
|
}
|
|
11020
11065
|
const memories = existsSync42(paths.memoriesDir) ? await loadMemoriesFromDir15(paths.memoriesDir) : [];
|
|
11021
|
-
const codeMap = await
|
|
11066
|
+
const codeMap = await loadCodeMap8(paths);
|
|
11022
11067
|
const codeFiles = codeMap ? Object.keys(codeMap.files).filter((file) => existsSync42(path40.join(paths.root, file))) : [];
|
|
11023
11068
|
let existingModules = [];
|
|
11024
11069
|
try {
|
|
@@ -11083,7 +11128,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
11083
11128
|
findings: [{ severity: "info", code: "enforcement-off", message: "Hivelore enforcement is disabled." }]
|
|
11084
11129
|
});
|
|
11085
11130
|
}
|
|
11086
|
-
findings.push(...await inspectIntegrationVersions(root, "0.
|
|
11131
|
+
findings.push(...await inspectIntegrationVersions(root, "0.47.0"));
|
|
11087
11132
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
11088
11133
|
const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
|
|
11089
11134
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent Hivelore briefing marker exists." } : {
|
|
@@ -11403,6 +11448,7 @@ async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
|
11403
11448
|
} catch {
|
|
11404
11449
|
}
|
|
11405
11450
|
}
|
|
11451
|
+
const noticeFinding = result.notice ? [{ severity: "info", code: "precommit-policy-notice", message: result.notice }] : [];
|
|
11406
11452
|
if (!result.should_block) {
|
|
11407
11453
|
return [
|
|
11408
11454
|
{
|
|
@@ -11410,6 +11456,7 @@ async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
|
11410
11456
|
code: "precommit-policy-pass",
|
|
11411
11457
|
message: `${stage === "ci" ? "CI" : "Pre-commit"} policy passed for ${touchedPaths.length} changed file(s).`
|
|
11412
11458
|
},
|
|
11459
|
+
...noticeFinding,
|
|
11413
11460
|
...reviewFinding,
|
|
11414
11461
|
...sensorFindings,
|
|
11415
11462
|
...weakeningFindings
|
|
@@ -11426,6 +11473,7 @@ async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
|
11426
11473
|
memory_ids: blockingWarnings.slice(0, 10).map((w) => w.id),
|
|
11427
11474
|
impact: 45
|
|
11428
11475
|
},
|
|
11476
|
+
...noticeFinding,
|
|
11429
11477
|
...reviewFinding,
|
|
11430
11478
|
...sensorFindings,
|
|
11431
11479
|
...weakeningFindings
|
|
@@ -12720,6 +12768,7 @@ import {
|
|
|
12720
12768
|
addedLineNumbersFromDiff as addedLineNumbersFromDiff2,
|
|
12721
12769
|
buildProposeCommand,
|
|
12722
12770
|
scaffoldPostIncidentTest,
|
|
12771
|
+
incidentHintsFromDiff,
|
|
12723
12772
|
selectCommandSensors as selectCommandSensors2,
|
|
12724
12773
|
TEST_FRAMEWORKS,
|
|
12725
12774
|
sensorPatternBrittleness as sensorPatternBrittleness2,
|
|
@@ -13051,7 +13100,7 @@ function registerSensors(program2) {
|
|
|
13051
13100
|
}
|
|
13052
13101
|
}
|
|
13053
13102
|
const root2 = findProjectRoot39(opts.dir);
|
|
13054
|
-
const { proposeSensor } = await import("./server-
|
|
13103
|
+
const { proposeSensor } = await import("./server-LNSXYVVW.js");
|
|
13055
13104
|
const out = await proposeSensor(
|
|
13056
13105
|
{
|
|
13057
13106
|
memory_id: id,
|
|
@@ -13175,7 +13224,10 @@ function registerSensors(program2) {
|
|
|
13175
13224
|
});
|
|
13176
13225
|
sensors.command("scaffold").description(
|
|
13177
13226
|
"Generate a PENDING post-incident test from a lesson (mem_tried/attempt/gotcha) \u2014 the on-ramp to\n a command sensor. Writes a test stub carrying the incident's provenance, then prints the exact\n `sensors propose --kind test` line to arm it once you've written the assertion. It never arms a\n sensor itself \u2014 propose_sensor stays the sole validated writer.\n\n Example:\n hivelore sensors scaffold 2026-07-03-attempt-refund-exceeds-capture --framework vitest"
|
|
13178
|
-
).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(
|
|
13227
|
+
).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
|
+
"--red-ref <ref>",
|
|
13229
|
+
"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"
|
|
13230
|
+
).option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
13179
13231
|
const root = findProjectRoot39(opts.dir);
|
|
13180
13232
|
const paths = resolveHaivePaths36(root);
|
|
13181
13233
|
const loaded = existsSync44(paths.memoriesDir) ? await loadMemoriesFromDir16(paths.memoriesDir) : [];
|
|
@@ -13195,13 +13247,28 @@ function registerSensors(program2) {
|
|
|
13195
13247
|
const allGroups = await detectTestFrameworksForAnchors(root, fm.anchor.paths ?? []);
|
|
13196
13248
|
const groups = opts.out ? allGroups.slice(0, 1) : allGroups;
|
|
13197
13249
|
const fields = parseLessonFields(found.memory.body);
|
|
13250
|
+
let incidentHints;
|
|
13251
|
+
if (opts.redRef) {
|
|
13252
|
+
try {
|
|
13253
|
+
const args = ["diff", `${opts.redRef}`, "HEAD", "--", ...fm.anchor.paths ?? []];
|
|
13254
|
+
const { stdout } = await exec5("git", args, { cwd: root, maxBuffer: 64 * 1024 * 1024 });
|
|
13255
|
+
incidentHints = incidentHintsFromDiff(stdout, { redRef: opts.redRef });
|
|
13256
|
+
if (incidentHints.changedSymbols.length === 0 && incidentHints.changedFiles.length === 0) {
|
|
13257
|
+
ui.warn(`--red-ref ${opts.redRef}: no changed symbols found in the anchor scope \u2014 using the generic template.`);
|
|
13258
|
+
incidentHints = void 0;
|
|
13259
|
+
}
|
|
13260
|
+
} catch (err) {
|
|
13261
|
+
ui.warn(`--red-ref ${opts.redRef}: could not read the fix diff (${err instanceof Error ? err.message : String(err)}) \u2014 using the generic template.`);
|
|
13262
|
+
}
|
|
13263
|
+
}
|
|
13198
13264
|
const lesson = {
|
|
13199
13265
|
memoryId: id,
|
|
13200
13266
|
title: fields.title || id,
|
|
13201
13267
|
whyFailed: fields.whyFailed,
|
|
13202
13268
|
instead: fields.instead,
|
|
13203
13269
|
incident: fm.sensor?.incident,
|
|
13204
|
-
paths: fm.anchor.paths
|
|
13270
|
+
paths: fm.anchor.paths,
|
|
13271
|
+
incidentHints
|
|
13205
13272
|
};
|
|
13206
13273
|
let scaffolds = groups.map(
|
|
13207
13274
|
(g) => scaffoldPostIncidentTest(lesson, { framework: forced ?? g.framework, outPath: opts.out, baseDir: g.baseDir })
|
|
@@ -13304,7 +13371,7 @@ async function runnableSensorMemories(paths, regexOnly = true) {
|
|
|
13304
13371
|
}
|
|
13305
13372
|
async function stagedDiff(root) {
|
|
13306
13373
|
try {
|
|
13307
|
-
const { stdout } = await exec5("git", ["diff", "--cached"], { cwd: root });
|
|
13374
|
+
const { stdout } = await exec5("git", ["diff", "--cached"], { cwd: root, maxBuffer: 256 * 1024 * 1024 });
|
|
13308
13375
|
return stdout;
|
|
13309
13376
|
} catch (err) {
|
|
13310
13377
|
throw new Error(`git diff --cached failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -14082,7 +14149,7 @@ function registerBridges(program2) {
|
|
|
14082
14149
|
|
|
14083
14150
|
// src/index.ts
|
|
14084
14151
|
var program = new Command48();
|
|
14085
|
-
program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.
|
|
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);
|
|
14086
14153
|
registerInit(program);
|
|
14087
14154
|
registerResolveProject(program);
|
|
14088
14155
|
registerEnforce(program);
|
|
@@ -14172,7 +14239,7 @@ program.parseAsync(process.argv).catch((err) => {
|
|
|
14172
14239
|
console.error(`\x1B[31m\u2717\x1B[0m ${field}${issue.message}`);
|
|
14173
14240
|
}
|
|
14174
14241
|
} else {
|
|
14175
|
-
console.error(err instanceof Error ? err.message : err);
|
|
14242
|
+
console.error(err instanceof Error ? process.env.HIVELORE_DEBUG ? err.stack ?? err.message : err.message : err);
|
|
14176
14243
|
}
|
|
14177
14244
|
process.exit(1);
|
|
14178
14245
|
});
|