@hivelore/cli 0.35.1 → 0.36.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-QQANGHJK.js → chunk-EWJQ3YE7.js} +10 -3
- package/dist/chunk-EWJQ3YE7.js.map +1 -0
- package/dist/index.js +51 -16
- package/dist/index.js.map +1 -1
- package/dist/{server-W5Q35K7Q.js → server-JFLUYWUB.js} +2 -2
- package/package.json +5 -5
- package/dist/chunk-QQANGHJK.js.map +0 -1
- /package/dist/{server-W5Q35K7Q.js.map → server-JFLUYWUB.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
preCommitCheck,
|
|
11
11
|
readPresumedCorrectTargets,
|
|
12
12
|
runHaiveMcpStdio
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-EWJQ3YE7.js";
|
|
14
14
|
import {
|
|
15
15
|
registerMemoryPending
|
|
16
16
|
} from "./chunk-OYJKHD22.js";
|
|
@@ -3755,7 +3755,7 @@ ${SEED_FOOTER(stack)}` });
|
|
|
3755
3755
|
|
|
3756
3756
|
// src/commands/init.ts
|
|
3757
3757
|
var execFileAsync = promisify2(execFile2);
|
|
3758
|
-
var HAIVE_GITHUB_ACTION_REF = `v${"0.
|
|
3758
|
+
var HAIVE_GITHUB_ACTION_REF = `v${"0.36.0"}`;
|
|
3759
3759
|
var PROJECT_CONTEXT_TEMPLATE = `# Project context
|
|
3760
3760
|
|
|
3761
3761
|
> Generated by \`hivelore init\`. Run \`hivelore init --bootstrap\` to auto-fill from your codebase,
|
|
@@ -7325,13 +7325,15 @@ import {
|
|
|
7325
7325
|
loadPreventionEvents as loadPreventionEvents2,
|
|
7326
7326
|
parseSince,
|
|
7327
7327
|
readUsageEvents,
|
|
7328
|
+
renderPreventionReceiptShare,
|
|
7328
7329
|
resolveHaivePaths as resolveHaivePaths27,
|
|
7329
7330
|
usageLogSize
|
|
7330
7331
|
} from "@hivelore/core";
|
|
7331
7332
|
function registerStats(program2) {
|
|
7332
7333
|
const stats = program2.command("stats").description("Show MCP tool-usage stats and prevention receipts.");
|
|
7333
|
-
stats.command("receipt").description("Show documented mistakes refused by the gate over a time window").addHelpText("after", "\nParent options also apply: --since <window> (default 7d here), --json, --dir <dir>.").action(async () => {
|
|
7334
|
+
const receiptCmd = stats.command("receipt").description("Show documented mistakes refused by the gate over a time window").option("--share", "emit a Markdown block ready to paste into Slack or a PR (with attribution)", false).addHelpText("after", "\nParent options also apply: --since <window> (default 7d here), --json, --dir <dir>.").action(async () => {
|
|
7334
7335
|
const opts = stats.opts();
|
|
7336
|
+
const sub = receiptCmd.opts();
|
|
7335
7337
|
const root = findProjectRoot28(opts.dir);
|
|
7336
7338
|
const paths = resolveHaivePaths27(root);
|
|
7337
7339
|
const sinceRaw = stats.getOptionValueSource("since") === "default" ? "7d" : opts.since ?? "7d";
|
|
@@ -7342,7 +7344,8 @@ function registerStats(program2) {
|
|
|
7342
7344
|
existsSync33(paths.memoriesDir) ? loadMemoriesFromDir11(paths.memoriesDir) : Promise.resolve([])
|
|
7343
7345
|
]);
|
|
7344
7346
|
const receipt = buildPreventionReceipt(events, memories, usage, { since });
|
|
7345
|
-
|
|
7347
|
+
const output = sub.share ? renderPreventionReceiptShare(receipt) : opts.json ? JSON.stringify(receipt, null, 2) : renderPreventionReceipt(receipt);
|
|
7348
|
+
console.log(output);
|
|
7346
7349
|
});
|
|
7347
7350
|
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(
|
|
7348
7351
|
"--export-report <path>",
|
|
@@ -8956,7 +8959,7 @@ function registerDoctor(program2) {
|
|
|
8956
8959
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `hivelore init` without --manual)."
|
|
8957
8960
|
});
|
|
8958
8961
|
}
|
|
8959
|
-
findings.push(...await collectInstallFindings(root, "0.
|
|
8962
|
+
findings.push(...await collectInstallFindings(root, "0.36.0"));
|
|
8960
8963
|
findings.push(...await collectToolchainFindings(root));
|
|
8961
8964
|
try {
|
|
8962
8965
|
const legacyRaw = execSync("haive-mcp --version", {
|
|
@@ -8964,7 +8967,7 @@ function registerDoctor(program2) {
|
|
|
8964
8967
|
timeout: 3e3,
|
|
8965
8968
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8966
8969
|
}).trim();
|
|
8967
|
-
const cliVersion = "0.
|
|
8970
|
+
const cliVersion = "0.36.0";
|
|
8968
8971
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
8969
8972
|
findings.push({
|
|
8970
8973
|
severity: "warn",
|
|
@@ -9723,6 +9726,7 @@ import {
|
|
|
9723
9726
|
readRecentBriefingMarker,
|
|
9724
9727
|
recordPreventionHits,
|
|
9725
9728
|
resolveBriefingBudget as resolveBriefingBudget2,
|
|
9729
|
+
incidentSuffix,
|
|
9726
9730
|
resolveHaivePaths as resolveHaivePaths35,
|
|
9727
9731
|
runSensors,
|
|
9728
9732
|
saveConfig as saveConfig3,
|
|
@@ -9872,7 +9876,8 @@ async function executeCommandSensor(spec, root) {
|
|
|
9872
9876
|
command: spec.command,
|
|
9873
9877
|
kind: spec.kind,
|
|
9874
9878
|
severity: spec.severity,
|
|
9875
|
-
message: spec.message
|
|
9879
|
+
message: spec.message,
|
|
9880
|
+
...spec.incident ? { incident: spec.incident } : {}
|
|
9876
9881
|
};
|
|
9877
9882
|
try {
|
|
9878
9883
|
const { stdout, stderr } = await exec2("bash", ["-c", spec.command], {
|
|
@@ -10665,7 +10670,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
10665
10670
|
findings: [{ severity: "info", code: "enforcement-off", message: "Hivelore enforcement is disabled." }]
|
|
10666
10671
|
});
|
|
10667
10672
|
}
|
|
10668
|
-
findings.push(...await inspectIntegrationVersions(root, "0.
|
|
10673
|
+
findings.push(...await inspectIntegrationVersions(root, "0.36.0"));
|
|
10669
10674
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
10670
10675
|
const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
|
|
10671
10676
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent Hivelore briefing marker exists." } : {
|
|
@@ -11020,7 +11025,7 @@ async function runSensorGate(paths, diff, stage) {
|
|
|
11020
11025
|
findings.push({
|
|
11021
11026
|
severity: "error",
|
|
11022
11027
|
code: "sensor-block",
|
|
11023
|
-
message: `Block sensor fired \u2014 ${hit.memory_id}: ${hit.message}${where}`,
|
|
11028
|
+
message: `Block sensor fired \u2014 ${hit.memory_id}: ${hit.message}${where}${incidentSuffix(hit.sensor.incident)}`,
|
|
11024
11029
|
fix: "Remove the flagged pattern, or run `hivelore sensors check` to inspect the match.",
|
|
11025
11030
|
impact: 45,
|
|
11026
11031
|
memory_ids: [hit.memory_id]
|
|
@@ -11029,7 +11034,7 @@ async function runSensorGate(paths, diff, stage) {
|
|
|
11029
11034
|
findings.push({
|
|
11030
11035
|
severity: "warn",
|
|
11031
11036
|
code: "sensor-warn",
|
|
11032
|
-
message: `Sensor flagged ${hit.memory_id}: ${hit.message}${where}`,
|
|
11037
|
+
message: `Sensor flagged ${hit.memory_id}: ${hit.message}${where}${incidentSuffix(hit.sensor.incident)}`,
|
|
11033
11038
|
fix: "Review the flagged line; `hivelore sensors check` shows the matched code.",
|
|
11034
11039
|
impact: 5,
|
|
11035
11040
|
memory_ids: [hit.memory_id]
|
|
@@ -11091,7 +11096,7 @@ ${run.output_tail}` : "";
|
|
|
11091
11096
|
findings.push({
|
|
11092
11097
|
severity: "error",
|
|
11093
11098
|
code: "sensor-block",
|
|
11094
|
-
message: `Block ${run.kind} sensor fired \u2014 ${run.memory_id}: ${run.message}
|
|
11099
|
+
message: `Block ${run.kind} sensor fired \u2014 ${run.memory_id}: ${run.message}${incidentSuffix(run.incident)}
|
|
11095
11100
|
command: ${run.command} (exit ${run.exit_code}, ${run.duration_ms}ms)${outputBlock}`,
|
|
11096
11101
|
fix: "Fix the behaviour the command checks, or run `hivelore sensors check --commands` to inspect it.",
|
|
11097
11102
|
impact: 45,
|
|
@@ -11101,7 +11106,7 @@ command: ${run.command} (exit ${run.exit_code}, ${run.duration_ms}ms)${outputBlo
|
|
|
11101
11106
|
findings.push({
|
|
11102
11107
|
severity: "warn",
|
|
11103
11108
|
code: "sensor-warn",
|
|
11104
|
-
message: `${run.kind} sensor flagged ${run.memory_id}: ${run.message} (exit ${run.exit_code})${outputBlock}`,
|
|
11109
|
+
message: `${run.kind} sensor flagged ${run.memory_id}: ${run.message}${incidentSuffix(run.incident)} (exit ${run.exit_code})${outputBlock}`,
|
|
11105
11110
|
fix: "Review the failing command; `hivelore sensors check --commands` re-runs it.",
|
|
11106
11111
|
impact: 5,
|
|
11107
11112
|
memory_ids: [run.memory_id]
|
|
@@ -11795,7 +11800,10 @@ jobs:
|
|
|
11795
11800
|
"
|
|
11796
11801
|
|
|
11797
11802
|
Weekly total: **" + ($receipt.total|tostring) + "** refused; previous window: **" +
|
|
11798
|
-
($receipt.previous_total|tostring) + "**."
|
|
11803
|
+
($receipt.previous_total|tostring) + "**." +
|
|
11804
|
+
"
|
|
11805
|
+
|
|
11806
|
+
<sub>\u{1F6E1}\uFE0F Generated by [Hivelore](https://github.com/Doucs91/hivelore) \u2014 the deterministic policy gate for agent-written code.</sub>"
|
|
11799
11807
|
')" || exit 0
|
|
11800
11808
|
comments="$(gh api "repos/$GITHUB_REPOSITORY/issues/$PR_NUMBER/comments" --paginate 2>/dev/null)" || exit 0
|
|
11801
11809
|
comment_id="$(printf '%s' "$comments" | jq -r '.[] | select(.body | contains("<!-- haive:prevention-receipt -->")) | .id' | head -1)"
|
|
@@ -11810,6 +11818,30 @@ Weekly total: **" + ($receipt.total|tostring) + "** refused; previous window: **
|
|
|
11810
11818
|
# haive:enforcement-workflow:end
|
|
11811
11819
|
`;
|
|
11812
11820
|
}
|
|
11821
|
+
var CONTENT_CATCH_CODES = /* @__PURE__ */ new Set(["sensor-block", "precommit-policy-block"]);
|
|
11822
|
+
var SETUP_GATE_CODES = /* @__PURE__ */ new Set([
|
|
11823
|
+
"briefing-missing",
|
|
11824
|
+
"session-recap-missing",
|
|
11825
|
+
"decision-coverage-missing",
|
|
11826
|
+
"bootstrap-incomplete",
|
|
11827
|
+
"enforcement-score-below-threshold"
|
|
11828
|
+
]);
|
|
11829
|
+
function printBlockHeadline(report) {
|
|
11830
|
+
const blocking = report.categories?.blocking ?? report.findings.filter((f) => f.severity === "error");
|
|
11831
|
+
if (blocking.length === 0) return;
|
|
11832
|
+
const catches = blocking.filter((f) => CONTENT_CATCH_CODES.has(f.code));
|
|
11833
|
+
console.log();
|
|
11834
|
+
if (catches.length > 0) {
|
|
11835
|
+
console.log(ui.red(ui.bold("\u{1F6E1}\uFE0F A documented lesson refused this commit \u2014 about the change you just made:")));
|
|
11836
|
+
for (const c of catches) {
|
|
11837
|
+
const id = c.memory_ids?.[0] ?? c.code;
|
|
11838
|
+
console.log(` ${ui.red("\u2022")} ${ui.bold(id)} ${c.message.split("\n")[0]}`);
|
|
11839
|
+
}
|
|
11840
|
+
} else if (blocking.every((f) => SETUP_GATE_CODES.has(f.code))) {
|
|
11841
|
+
console.log(ui.yellow(ui.bold("\u2699 Setup gate \u2014 about your repo's baseline, not the change you just made.")));
|
|
11842
|
+
console.log(ui.dim(" Fill the knowledge layer once (bootstrap / load a briefing); later commits pass silently."));
|
|
11843
|
+
}
|
|
11844
|
+
}
|
|
11813
11845
|
function printReport(report, json, explain = false) {
|
|
11814
11846
|
if (json) {
|
|
11815
11847
|
console.log(JSON.stringify(report, null, 2));
|
|
@@ -11818,6 +11850,7 @@ function printReport(report, json, explain = false) {
|
|
|
11818
11850
|
console.log(ui.bold(`Hivelore enforcement \u2014 ${report.mode}${report.actor ? ` \xB7 ${report.actor}` : ""}`));
|
|
11819
11851
|
console.log(ui.dim(` root: ${report.root}`));
|
|
11820
11852
|
console.log(ui.dim(` score: ${report.score.score}% / threshold ${report.score.threshold}%`));
|
|
11853
|
+
if (report.should_block) printBlockHeadline(report);
|
|
11821
11854
|
if (explain) {
|
|
11822
11855
|
printFindingGroup("Blocking", report.categories.blocking, "error");
|
|
11823
11856
|
printFindingGroup("Review", report.categories.review, "warn");
|
|
@@ -12364,7 +12397,7 @@ function registerSensors(program2) {
|
|
|
12364
12397
|
});
|
|
12365
12398
|
sensors.command("propose").description(
|
|
12366
12399
|
"Propose a discriminating sensor for a memory \u2014 you write the pattern, Hivelore validates it before\n trusting it to block. Mirrors the MCP `propose_sensor` tool (the agent-authored path).\n\n A `block` proposal is accepted ONLY if it is not brittle, stays SILENT on the current code,\n and FIRES on the bad example. Rejected proposals are not written \u2014 fix and re-run.\n\n Example:\n hivelore sensors propose <memory-id> \\\n --pattern 'stripe\\.paymentIntents\\.create' --absent 'idempotencyKey' \\\n --bad-example 'stripe.paymentIntents.create({ amount })'"
|
|
12367
|
-
).argument("<memory-id>", "memory id to attach the sensor to").option("--kind <kind>", "regex (default) | shell | test \u2014 command kinds route the team's own oracle to this lesson", "regex").option("--pattern <regex>", "kind=regex: regex matching the FAULTY usage").option("--command <cmd>", "kind=shell|test: command the gate runs when the diff touches the sensor's paths").option("--timeout <ms>", "kind=shell|test: max runtime in ms (default 120000)").option("--absent <regex>", "regex for the CORRECT-usage marker (makes it discriminate)").option("--bad-example <code>", "a snippet that SHOULD match (else examples are read from the lesson)").option("--severity <severity>", "block | warn", "block").option("--message <text>", "fix message shown when it fires").option("--flags <flags>", "regex flags (e.g. i)").option("--paths <csv>", "override scope paths (defaults to the memory anchors)").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
12400
|
+
).argument("<memory-id>", "memory id to attach the sensor to").option("--kind <kind>", "regex (default) | shell | test \u2014 command kinds route the team's own oracle to this lesson", "regex").option("--pattern <regex>", "kind=regex: regex matching the FAULTY usage").option("--command <cmd>", "kind=shell|test: command the gate runs when the diff touches the sensor's paths").option("--timeout <ms>", "kind=shell|test: max runtime in ms (default 120000)").option("--absent <regex>", "regex for the CORRECT-usage marker (makes it discriminate)").option("--bad-example <code>", "a snippet that SHOULD match (else examples are read from the lesson)").option("--severity <severity>", "block | warn", "block").option("--message <text>", "fix message shown when it fires").option("--incident <ref>", "provenance: the incident this sensor guards (e.g. 'prod #442') \u2014 shown when it fires and in the receipt").option("--flags <flags>", "regex flags (e.g. i)").option("--paths <csv>", "override scope paths (defaults to the memory anchors)").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
12368
12401
|
if (opts.kind === "shell" || opts.kind === "test") {
|
|
12369
12402
|
if (!opts.command?.trim()) {
|
|
12370
12403
|
ui.error("--kind shell|test requires --command.");
|
|
@@ -12372,7 +12405,7 @@ function registerSensors(program2) {
|
|
|
12372
12405
|
return;
|
|
12373
12406
|
}
|
|
12374
12407
|
const root2 = findProjectRoot39(opts.dir);
|
|
12375
|
-
const { proposeSensor } = await import("./server-
|
|
12408
|
+
const { proposeSensor } = await import("./server-JFLUYWUB.js");
|
|
12376
12409
|
const out = await proposeSensor(
|
|
12377
12410
|
{
|
|
12378
12411
|
memory_id: id,
|
|
@@ -12384,6 +12417,7 @@ function registerSensors(program2) {
|
|
|
12384
12417
|
bad_example: void 0,
|
|
12385
12418
|
severity: opts.severity === "warn" ? "warn" : "block",
|
|
12386
12419
|
message: opts.message,
|
|
12420
|
+
incident: opts.incident,
|
|
12387
12421
|
flags: void 0,
|
|
12388
12422
|
paths: opts.paths ? opts.paths.split(",").map((p) => p.trim()).filter(Boolean) : []
|
|
12389
12423
|
},
|
|
@@ -12435,6 +12469,7 @@ function registerSensors(program2) {
|
|
|
12435
12469
|
...opts.flags ? { flags: opts.flags } : {},
|
|
12436
12470
|
paths: anchorPaths,
|
|
12437
12471
|
message: opts.message?.trim() || deriveProposedMessage(found.memory.body, opts.pattern, opts.absent),
|
|
12472
|
+
...opts.incident?.trim() ? { incident: opts.incident.trim() } : {},
|
|
12438
12473
|
severity,
|
|
12439
12474
|
autogen: false,
|
|
12440
12475
|
last_fired: null
|
|
@@ -13209,7 +13244,7 @@ function registerBridges(program2) {
|
|
|
13209
13244
|
|
|
13210
13245
|
// src/index.ts
|
|
13211
13246
|
var program = new Command48();
|
|
13212
|
-
program.name("hivelore").description("Hivelore -
|
|
13247
|
+
program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.36.0").option("--advanced", "show maintenance and experimental commands in help").showSuggestionAfterError(true);
|
|
13213
13248
|
registerInit(program);
|
|
13214
13249
|
registerResolveProject(program);
|
|
13215
13250
|
registerEnforce(program);
|