@hivelore/cli 0.44.0 → 0.46.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-W7EPRKOZ.js} +37 -9
- package/dist/chunk-W7EPRKOZ.js.map +1 -0
- package/dist/index.js +85 -17
- package/dist/index.js.map +1 -1
- package/dist/{server-MCNCAFJN.js → server-V3ZGBTAG.js} +2 -2
- package/package.json +4 -4
- package/dist/chunk-6KRXMDLC.js.map +0 -1
- /package/dist/{server-MCNCAFJN.js.map → server-V3ZGBTAG.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-W7EPRKOZ.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.46.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-V3ZGBTAG.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.46.0"));
|
|
9317
|
+
findings.push(...await collectMcpRuntimeFindings(paths, "0.46.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.46.0";
|
|
9307
9326
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
9308
9327
|
findings.push({
|
|
9309
9328
|
severity: "warn",
|
|
@@ -9560,6 +9579,33 @@ 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
|
+
const more = cov.uncoveredAreas.length > 4 ? `
|
|
9595
|
+
# +${cov.uncoveredAreas.length - 4} more area(s)` : "";
|
|
9596
|
+
fix = "Scaffold a behavioural oracle for each uncovered area:\n " + lines.join("\n ") + more;
|
|
9597
|
+
} else if (cov.armedOracles < cov.totalOracles || cov.redProvenOracles < cov.armedOracles) {
|
|
9598
|
+
fix = "Arm warn-only oracles to `block` and re-propose with `--red-ref` so each substantiates its incident.";
|
|
9599
|
+
}
|
|
9600
|
+
return [{
|
|
9601
|
+
severity: "info",
|
|
9602
|
+
code: "behaviour-coverage",
|
|
9603
|
+
section: "Protection",
|
|
9604
|
+
coverage_percent: Math.round(cov.areasWithOracle.length / cov.mainAreas.length * 100),
|
|
9605
|
+
message: `Behaviour harness: ${renderBehaviourCoverageLine2(cov)}.` + uncoveredHint,
|
|
9606
|
+
fix
|
|
9607
|
+
}];
|
|
9608
|
+
}
|
|
9563
9609
|
async function collectSemanticIndexFindings(paths, config, memoryCount, codeMap) {
|
|
9564
9610
|
const findings = [];
|
|
9565
9611
|
const autoWantsCodeSearch = Boolean(config.autopilot || config.autoRepair?.codeSearch);
|
|
@@ -10085,7 +10131,7 @@ import {
|
|
|
10085
10131
|
detectSensorWeakening,
|
|
10086
10132
|
isSensorScannablePath,
|
|
10087
10133
|
findProjectRoot as findProjectRoot37,
|
|
10088
|
-
loadCodeMap as
|
|
10134
|
+
loadCodeMap as loadCodeMap8,
|
|
10089
10135
|
renderBootstrapChecklist,
|
|
10090
10136
|
findUncapturedFailures,
|
|
10091
10137
|
handoffAgeMs,
|
|
@@ -11018,7 +11064,7 @@ async function checkBootstrapComplete(paths, config, productionCodeChanged) {
|
|
|
11018
11064
|
} catch {
|
|
11019
11065
|
}
|
|
11020
11066
|
const memories = existsSync42(paths.memoriesDir) ? await loadMemoriesFromDir15(paths.memoriesDir) : [];
|
|
11021
|
-
const codeMap = await
|
|
11067
|
+
const codeMap = await loadCodeMap8(paths);
|
|
11022
11068
|
const codeFiles = codeMap ? Object.keys(codeMap.files).filter((file) => existsSync42(path40.join(paths.root, file))) : [];
|
|
11023
11069
|
let existingModules = [];
|
|
11024
11070
|
try {
|
|
@@ -11083,7 +11129,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
11083
11129
|
findings: [{ severity: "info", code: "enforcement-off", message: "Hivelore enforcement is disabled." }]
|
|
11084
11130
|
});
|
|
11085
11131
|
}
|
|
11086
|
-
findings.push(...await inspectIntegrationVersions(root, "0.
|
|
11132
|
+
findings.push(...await inspectIntegrationVersions(root, "0.46.0"));
|
|
11087
11133
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
11088
11134
|
const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
|
|
11089
11135
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent Hivelore briefing marker exists." } : {
|
|
@@ -11403,6 +11449,7 @@ async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
|
11403
11449
|
} catch {
|
|
11404
11450
|
}
|
|
11405
11451
|
}
|
|
11452
|
+
const noticeFinding = result.notice ? [{ severity: "info", code: "precommit-policy-notice", message: result.notice }] : [];
|
|
11406
11453
|
if (!result.should_block) {
|
|
11407
11454
|
return [
|
|
11408
11455
|
{
|
|
@@ -11410,6 +11457,7 @@ async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
|
11410
11457
|
code: "precommit-policy-pass",
|
|
11411
11458
|
message: `${stage === "ci" ? "CI" : "Pre-commit"} policy passed for ${touchedPaths.length} changed file(s).`
|
|
11412
11459
|
},
|
|
11460
|
+
...noticeFinding,
|
|
11413
11461
|
...reviewFinding,
|
|
11414
11462
|
...sensorFindings,
|
|
11415
11463
|
...weakeningFindings
|
|
@@ -11426,6 +11474,7 @@ async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
|
11426
11474
|
memory_ids: blockingWarnings.slice(0, 10).map((w) => w.id),
|
|
11427
11475
|
impact: 45
|
|
11428
11476
|
},
|
|
11477
|
+
...noticeFinding,
|
|
11429
11478
|
...reviewFinding,
|
|
11430
11479
|
...sensorFindings,
|
|
11431
11480
|
...weakeningFindings
|
|
@@ -12720,6 +12769,7 @@ import {
|
|
|
12720
12769
|
addedLineNumbersFromDiff as addedLineNumbersFromDiff2,
|
|
12721
12770
|
buildProposeCommand,
|
|
12722
12771
|
scaffoldPostIncidentTest,
|
|
12772
|
+
incidentHintsFromDiff,
|
|
12723
12773
|
selectCommandSensors as selectCommandSensors2,
|
|
12724
12774
|
TEST_FRAMEWORKS,
|
|
12725
12775
|
sensorPatternBrittleness as sensorPatternBrittleness2,
|
|
@@ -13051,7 +13101,7 @@ function registerSensors(program2) {
|
|
|
13051
13101
|
}
|
|
13052
13102
|
}
|
|
13053
13103
|
const root2 = findProjectRoot39(opts.dir);
|
|
13054
|
-
const { proposeSensor } = await import("./server-
|
|
13104
|
+
const { proposeSensor } = await import("./server-V3ZGBTAG.js");
|
|
13055
13105
|
const out = await proposeSensor(
|
|
13056
13106
|
{
|
|
13057
13107
|
memory_id: id,
|
|
@@ -13175,7 +13225,10 @@ function registerSensors(program2) {
|
|
|
13175
13225
|
});
|
|
13176
13226
|
sensors.command("scaffold").description(
|
|
13177
13227
|
"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(
|
|
13228
|
+
).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(
|
|
13229
|
+
"--red-ref <ref>",
|
|
13230
|
+
"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"
|
|
13231
|
+
).option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
13179
13232
|
const root = findProjectRoot39(opts.dir);
|
|
13180
13233
|
const paths = resolveHaivePaths36(root);
|
|
13181
13234
|
const loaded = existsSync44(paths.memoriesDir) ? await loadMemoriesFromDir16(paths.memoriesDir) : [];
|
|
@@ -13195,13 +13248,28 @@ function registerSensors(program2) {
|
|
|
13195
13248
|
const allGroups = await detectTestFrameworksForAnchors(root, fm.anchor.paths ?? []);
|
|
13196
13249
|
const groups = opts.out ? allGroups.slice(0, 1) : allGroups;
|
|
13197
13250
|
const fields = parseLessonFields(found.memory.body);
|
|
13251
|
+
let incidentHints;
|
|
13252
|
+
if (opts.redRef) {
|
|
13253
|
+
try {
|
|
13254
|
+
const args = ["diff", `${opts.redRef}`, "HEAD", "--", ...fm.anchor.paths ?? []];
|
|
13255
|
+
const { stdout } = await exec5("git", args, { cwd: root, maxBuffer: 64 * 1024 * 1024 });
|
|
13256
|
+
incidentHints = incidentHintsFromDiff(stdout, { redRef: opts.redRef });
|
|
13257
|
+
if (incidentHints.changedSymbols.length === 0 && incidentHints.changedFiles.length === 0) {
|
|
13258
|
+
ui.warn(`--red-ref ${opts.redRef}: no changed symbols found in the anchor scope \u2014 using the generic template.`);
|
|
13259
|
+
incidentHints = void 0;
|
|
13260
|
+
}
|
|
13261
|
+
} catch (err) {
|
|
13262
|
+
ui.warn(`--red-ref ${opts.redRef}: could not read the fix diff (${err instanceof Error ? err.message : String(err)}) \u2014 using the generic template.`);
|
|
13263
|
+
}
|
|
13264
|
+
}
|
|
13198
13265
|
const lesson = {
|
|
13199
13266
|
memoryId: id,
|
|
13200
13267
|
title: fields.title || id,
|
|
13201
13268
|
whyFailed: fields.whyFailed,
|
|
13202
13269
|
instead: fields.instead,
|
|
13203
13270
|
incident: fm.sensor?.incident,
|
|
13204
|
-
paths: fm.anchor.paths
|
|
13271
|
+
paths: fm.anchor.paths,
|
|
13272
|
+
incidentHints
|
|
13205
13273
|
};
|
|
13206
13274
|
let scaffolds = groups.map(
|
|
13207
13275
|
(g) => scaffoldPostIncidentTest(lesson, { framework: forced ?? g.framework, outPath: opts.out, baseDir: g.baseDir })
|
|
@@ -13304,7 +13372,7 @@ async function runnableSensorMemories(paths, regexOnly = true) {
|
|
|
13304
13372
|
}
|
|
13305
13373
|
async function stagedDiff(root) {
|
|
13306
13374
|
try {
|
|
13307
|
-
const { stdout } = await exec5("git", ["diff", "--cached"], { cwd: root });
|
|
13375
|
+
const { stdout } = await exec5("git", ["diff", "--cached"], { cwd: root, maxBuffer: 256 * 1024 * 1024 });
|
|
13308
13376
|
return stdout;
|
|
13309
13377
|
} catch (err) {
|
|
13310
13378
|
throw new Error(`git diff --cached failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -14082,7 +14150,7 @@ function registerBridges(program2) {
|
|
|
14082
14150
|
|
|
14083
14151
|
// src/index.ts
|
|
14084
14152
|
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.
|
|
14153
|
+
program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.46.0").option("--advanced", "show maintenance and experimental commands in help").showSuggestionAfterError(true);
|
|
14086
14154
|
registerInit(program);
|
|
14087
14155
|
registerResolveProject(program);
|
|
14088
14156
|
registerEnforce(program);
|
|
@@ -14172,7 +14240,7 @@ program.parseAsync(process.argv).catch((err) => {
|
|
|
14172
14240
|
console.error(`\x1B[31m\u2717\x1B[0m ${field}${issue.message}`);
|
|
14173
14241
|
}
|
|
14174
14242
|
} else {
|
|
14175
|
-
console.error(err instanceof Error ? err.message : err);
|
|
14243
|
+
console.error(err instanceof Error ? process.env.HIVELORE_DEBUG ? err.stack ?? err.message : err.message : err);
|
|
14176
14244
|
}
|
|
14177
14245
|
process.exit(1);
|
|
14178
14246
|
});
|