@hiveai/cli 0.13.7 → 0.13.8
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 +63 -10
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -3019,7 +3019,7 @@ ${SEED_FOOTER(stack)}` });
|
|
|
3019
3019
|
}
|
|
3020
3020
|
|
|
3021
3021
|
// src/commands/init.ts
|
|
3022
|
-
var HAIVE_GITHUB_ACTION_REF = `v${"0.13.
|
|
3022
|
+
var HAIVE_GITHUB_ACTION_REF = `v${"0.13.8"}`;
|
|
3023
3023
|
var PROJECT_CONTEXT_TEMPLATE = `# Project context
|
|
3024
3024
|
|
|
3025
3025
|
> Generated by \`haive init\`. Run \`haive init --bootstrap\` to auto-fill from your codebase,
|
|
@@ -7919,7 +7919,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
7919
7919
|
};
|
|
7920
7920
|
}
|
|
7921
7921
|
var SERVER_NAME = "haive";
|
|
7922
|
-
var SERVER_VERSION = "0.13.
|
|
7922
|
+
var SERVER_VERSION = "0.13.8";
|
|
7923
7923
|
function jsonResult(data) {
|
|
7924
7924
|
return {
|
|
7925
7925
|
content: [
|
|
@@ -13488,7 +13488,7 @@ function registerDoctor(program2) {
|
|
|
13488
13488
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
|
|
13489
13489
|
});
|
|
13490
13490
|
}
|
|
13491
|
-
findings.push(...await collectInstallFindings(root, "0.13.
|
|
13491
|
+
findings.push(...await collectInstallFindings(root, "0.13.8"));
|
|
13492
13492
|
findings.push(...await collectToolchainFindings(root));
|
|
13493
13493
|
try {
|
|
13494
13494
|
const legacyRaw = execSync3("haive-mcp --version", {
|
|
@@ -13496,7 +13496,7 @@ function registerDoctor(program2) {
|
|
|
13496
13496
|
timeout: 3e3,
|
|
13497
13497
|
stdio: ["ignore", "pipe", "ignore"]
|
|
13498
13498
|
}).trim();
|
|
13499
|
-
const cliVersion = "0.13.
|
|
13499
|
+
const cliVersion = "0.13.8";
|
|
13500
13500
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
13501
13501
|
findings.push({
|
|
13502
13502
|
severity: "warn",
|
|
@@ -14656,6 +14656,16 @@ function registerEnforce(program2) {
|
|
|
14656
14656
|
process.exit(2);
|
|
14657
14657
|
}
|
|
14658
14658
|
});
|
|
14659
|
+
enforce.command("commit-msg <msgfile>").description(
|
|
14660
|
+
"git commit-msg hook: block a CI-skip directive in a commit that also changes shippable code (GitHub scans the whole message and would skip CI for the entire push). `.ai/`-only sync commits are allowed."
|
|
14661
|
+
).option("-d, --dir <dir>", "project root").action(async (msgfile, opts) => {
|
|
14662
|
+
const root = findProjectRoot52(opts.dir);
|
|
14663
|
+
const verdict = await checkCommitMessageSkipCi(root, msgfile);
|
|
14664
|
+
if (verdict.block) {
|
|
14665
|
+
ui.error(verdict.message);
|
|
14666
|
+
process.exit(1);
|
|
14667
|
+
}
|
|
14668
|
+
});
|
|
14659
14669
|
enforce.command("session-start").description("Claude Code SessionStart hook: inject briefing and write a local briefing marker.").option("-d, --dir <dir>", "project root").option("--task <text>", "task text to rank memories").option("--source <name>", "marker source", "claude-session-start").option("--session-id <id>", "agent session id").action(async (opts) => {
|
|
14660
14670
|
const payload = await readHookPayload();
|
|
14661
14671
|
const root = resolveRoot(opts.dir, payload);
|
|
@@ -15095,7 +15105,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
15095
15105
|
findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
|
|
15096
15106
|
});
|
|
15097
15107
|
}
|
|
15098
|
-
findings.push(...await inspectIntegrationVersions(root, "0.13.
|
|
15108
|
+
findings.push(...await inspectIntegrationVersions(root, "0.13.8"));
|
|
15099
15109
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
15100
15110
|
const hasBriefing = await hasRecentBriefingMarker2(paths, sessionId);
|
|
15101
15111
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
|
|
@@ -15589,6 +15599,21 @@ var SHIPPABLE_PATH_PREFIXES = [
|
|
|
15589
15599
|
function isShippablePath(file) {
|
|
15590
15600
|
return SHIPPABLE_PATH_PREFIXES.some((prefix) => file.startsWith(prefix)) || VERSION_FILES.includes(file);
|
|
15591
15601
|
}
|
|
15602
|
+
var CI_SKIP_DIRECTIVE = /\[skip ci\]|\[ci skip\]|\[no ci\]|\[skip actions\]|\*\*\*NO_CI\*\*\*|skip-checks: *true/i;
|
|
15603
|
+
async function checkCommitMessageSkipCi(root, msgfile) {
|
|
15604
|
+
const file = path51.isAbsolute(msgfile) ? msgfile : path51.join(root, msgfile);
|
|
15605
|
+
const raw = await readFile23(file, "utf8").catch(() => "");
|
|
15606
|
+
const cleaned = raw.split("\n").filter((line) => !line.startsWith("#")).join("\n");
|
|
15607
|
+
if (!CI_SKIP_DIRECTIVE.test(cleaned)) return { block: false, message: "" };
|
|
15608
|
+
const staged = (await runCommand4("git", ["diff", "--cached", "--name-only"], root).catch(() => "")).split("\n").map((s) => s.trim()).filter(Boolean);
|
|
15609
|
+
const shippable = staged.filter(isShippablePath);
|
|
15610
|
+
if (shippable.length === 0) return { block: false, message: "" };
|
|
15611
|
+
return {
|
|
15612
|
+
block: true,
|
|
15613
|
+
message: "This commit message contains a CI-skip directive ([skip ci] / [ci skip] / [no ci]) but the commit changes shippable code:\n" + shippable.slice(0, 6).map((f) => ` - ${f}`).join("\n") + (shippable.length > 6 ? `
|
|
15614
|
+
\u2026and ${shippable.length - 6} more` : "") + "\nGitHub scans the whole commit message and would skip CI for the ENTIRE push \u2014 your code would land untested.\nFix: reword the message so it does not contain the literal directive (e.g. write 'skip-ci'), or move the\nskip-ci sync into a separate `.ai/`-only commit."
|
|
15615
|
+
};
|
|
15616
|
+
}
|
|
15592
15617
|
async function inspectReleaseVersionState(root, upstream) {
|
|
15593
15618
|
const localEntries = await Promise.all(VERSION_FILES.map(async (file) => [file, await readPackageVersion(root, file)]));
|
|
15594
15619
|
const localVersions = new Map(localEntries);
|
|
@@ -15812,6 +15837,13 @@ haive enforce check --stage pre-commit --dir . || exit $?
|
|
|
15812
15837
|
body: `#!/bin/sh
|
|
15813
15838
|
${ENFORCE_HOOK_MARKER}
|
|
15814
15839
|
haive enforce check --stage pre-push --dir . || exit $?
|
|
15840
|
+
`
|
|
15841
|
+
},
|
|
15842
|
+
{
|
|
15843
|
+
name: "commit-msg",
|
|
15844
|
+
body: `#!/bin/sh
|
|
15845
|
+
${ENFORCE_HOOK_MARKER}
|
|
15846
|
+
haive enforce commit-msg "$1" --dir . || exit $?
|
|
15815
15847
|
`
|
|
15816
15848
|
}
|
|
15817
15849
|
];
|
|
@@ -15831,7 +15863,7 @@ ${hook.body}`, "utf8");
|
|
|
15831
15863
|
}
|
|
15832
15864
|
await chmod2(file, 493);
|
|
15833
15865
|
}
|
|
15834
|
-
ui.success("Installed blocking git enforcement hooks: pre-commit, pre-push");
|
|
15866
|
+
ui.success("Installed blocking git enforcement hooks: pre-commit, pre-push, commit-msg");
|
|
15835
15867
|
}
|
|
15836
15868
|
async function installCiEnforcement(root) {
|
|
15837
15869
|
const workflowPath = path51.join(root, ".github", "workflows", "haive-enforcement.yml");
|
|
@@ -16067,8 +16099,11 @@ import {
|
|
|
16067
16099
|
findProjectRoot as findProjectRoot53,
|
|
16068
16100
|
isRetiredMemory as isRetiredMemory3,
|
|
16069
16101
|
loadMemoriesFromDir as loadMemoriesFromDir39,
|
|
16102
|
+
loadUsageIndex as loadUsageIndex29,
|
|
16103
|
+
recordPrevention,
|
|
16070
16104
|
resolveHaivePaths as resolveHaivePaths49,
|
|
16071
16105
|
runSensors as runSensors2,
|
|
16106
|
+
saveUsageIndex as saveUsageIndex7,
|
|
16072
16107
|
sensorTargetsFromDiff as sensorTargetsFromDiff2,
|
|
16073
16108
|
serializeMemory as serializeMemory27
|
|
16074
16109
|
} from "@hiveai/core";
|
|
@@ -16103,6 +16138,14 @@ function registerSensors(program2) {
|
|
|
16103
16138
|
const diff = opts.diffFile ? await readFile24(path53.resolve(root, opts.diffFile), "utf8") : await stagedDiff(root);
|
|
16104
16139
|
const targets = sensorTargetsFromDiff2(diff);
|
|
16105
16140
|
const hits = runSensors2(memories, targets.length > 0 ? targets : [{ path: "", content: diff }]);
|
|
16141
|
+
const firedIds = [...new Set(hits.map((hit) => hit.memory_id))];
|
|
16142
|
+
if (firedIds.length > 0) {
|
|
16143
|
+
const usage = await loadUsageIndex29(paths);
|
|
16144
|
+
let recorded = 0;
|
|
16145
|
+
for (const id of firedIds) if (recordPrevention(usage, id)) recorded++;
|
|
16146
|
+
if (recorded > 0) await saveUsageIndex7(paths, usage).catch(() => {
|
|
16147
|
+
});
|
|
16148
|
+
}
|
|
16106
16149
|
const output = {
|
|
16107
16150
|
scanned: memories.length,
|
|
16108
16151
|
hits: hits.map((hit) => ({
|
|
@@ -16446,7 +16489,7 @@ import {
|
|
|
16446
16489
|
buildDashboard,
|
|
16447
16490
|
findProjectRoot as findProjectRoot55,
|
|
16448
16491
|
loadMemoriesFromDir as loadMemoriesFromDir41,
|
|
16449
|
-
loadUsageIndex as
|
|
16492
|
+
loadUsageIndex as loadUsageIndex30,
|
|
16450
16493
|
resolveHaivePaths as resolveHaivePaths51
|
|
16451
16494
|
} from "@hiveai/core";
|
|
16452
16495
|
function registerDashboard(program2) {
|
|
@@ -16461,7 +16504,7 @@ function registerDashboard(program2) {
|
|
|
16461
16504
|
return;
|
|
16462
16505
|
}
|
|
16463
16506
|
const memories = existsSync78(paths.memoriesDir) ? await loadMemoriesFromDir41(paths.memoriesDir) : [];
|
|
16464
|
-
const usage = await
|
|
16507
|
+
const usage = await loadUsageIndex30(paths);
|
|
16465
16508
|
const top = Math.max(1, Number.parseInt(opts.top ?? "10", 10) || 10);
|
|
16466
16509
|
const dormantDays = opts.dormantDays ? Number.parseInt(opts.dormantDays, 10) : void 0;
|
|
16467
16510
|
const report = buildDashboard(memories, usage, {
|
|
@@ -16476,7 +16519,7 @@ function registerDashboard(program2) {
|
|
|
16476
16519
|
});
|
|
16477
16520
|
}
|
|
16478
16521
|
function renderDashboard(r) {
|
|
16479
|
-
const { inventory: inv, impact, sensors, health, decay, corpus } = r;
|
|
16522
|
+
const { inventory: inv, impact, sensors, health, decay, corpus, prevention } = r;
|
|
16480
16523
|
console.log(ui.bold("hAIve dashboard"));
|
|
16481
16524
|
console.log(
|
|
16482
16525
|
` ${ui.dim("corpus:")} ${inv.total} policy memor${inv.total === 1 ? "y" : "ies"} (${inv.active} active, ${inv.retired} retired) \xB7 ${inv.session_recaps} recap(s) \xB7 ~${corpus.est_tokens.toLocaleString()} tokens`
|
|
@@ -16506,6 +16549,16 @@ function renderDashboard(r) {
|
|
|
16506
16549
|
console.log(` ${marker} ${s.id} ${ui.dim(`last fired ${s.last_fired.slice(0, 10)}`)}`);
|
|
16507
16550
|
}
|
|
16508
16551
|
console.log();
|
|
16552
|
+
console.log(ui.bold("Prevention") + ui.dim(" (outcome: sensors that caught a real diff)"));
|
|
16553
|
+
console.log(
|
|
16554
|
+
` ${prevention.total_events > 0 ? ui.green(`${prevention.total_events} catch event(s)`) : "0 catch events"} \xB7 ${prevention.memories_with_catches} memor${prevention.memories_with_catches === 1 ? "y" : "ies"} with catches`
|
|
16555
|
+
);
|
|
16556
|
+
for (const p of prevention.top.slice(0, 5)) {
|
|
16557
|
+
console.log(
|
|
16558
|
+
` ${ui.green("\u2713")} ${p.prevented_count}\xD7 ${p.id}` + (p.last_prevented_at ? ui.dim(` last ${p.last_prevented_at.slice(0, 10)}`) : "")
|
|
16559
|
+
);
|
|
16560
|
+
}
|
|
16561
|
+
console.log();
|
|
16509
16562
|
console.log(ui.bold("Health"));
|
|
16510
16563
|
console.log(
|
|
16511
16564
|
` stale ${warnNum(health.stale)} \xB7 anchorless ${warnNum(health.anchorless)} \xB7 pending ${health.pending} \xB7 prune candidates ${warnNum(health.prune_candidates)}`
|
|
@@ -16542,7 +16595,7 @@ function warnNum(n) {
|
|
|
16542
16595
|
|
|
16543
16596
|
// src/index.ts
|
|
16544
16597
|
var program = new Command58();
|
|
16545
|
-
program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.13.
|
|
16598
|
+
program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.13.8").option("--advanced", "show maintenance and experimental commands in help");
|
|
16546
16599
|
registerInit(program);
|
|
16547
16600
|
registerWelcome(program);
|
|
16548
16601
|
registerResolveProject(program);
|