@hivelore/cli 0.36.0 → 0.37.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-EWJQ3YE7.js → chunk-VLRQ4MRO.js} +3 -3
- package/dist/index.js +86 -7
- package/dist/index.js.map +1 -1
- package/dist/{server-JFLUYWUB.js → server-J6TDFG2C.js} +2 -2
- package/package.json +4 -4
- /package/dist/{chunk-EWJQ3YE7.js.map → chunk-VLRQ4MRO.js.map} +0 -0
- /package/dist/{server-JFLUYWUB.js.map → server-J6TDFG2C.js.map} +0 -0
|
@@ -2730,7 +2730,7 @@ function oneLine(value) {
|
|
|
2730
2730
|
return value.replace(/\s+/g, " ").replace(/"/g, '\\"').trim().slice(0, 120);
|
|
2731
2731
|
}
|
|
2732
2732
|
function serverVersion() {
|
|
2733
|
-
return true ? "0.
|
|
2733
|
+
return true ? "0.37.0" : "dev";
|
|
2734
2734
|
}
|
|
2735
2735
|
var CodeMapInputSchema = {
|
|
2736
2736
|
file: z20.string().optional().describe("Filter to files whose path contains this substring"),
|
|
@@ -4057,7 +4057,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
4057
4057
|
};
|
|
4058
4058
|
}
|
|
4059
4059
|
var SERVER_NAME = "hivelore";
|
|
4060
|
-
var SERVER_VERSION = "0.
|
|
4060
|
+
var SERVER_VERSION = "0.37.0";
|
|
4061
4061
|
function jsonResult(data) {
|
|
4062
4062
|
return {
|
|
4063
4063
|
content: [
|
|
@@ -5000,4 +5000,4 @@ export {
|
|
|
5000
5000
|
printHaiveMcpVersion,
|
|
5001
5001
|
runHaiveMcpStdio
|
|
5002
5002
|
};
|
|
5003
|
-
//# sourceMappingURL=chunk-
|
|
5003
|
+
//# sourceMappingURL=chunk-VLRQ4MRO.js.map
|
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-VLRQ4MRO.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.37.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,
|
|
@@ -6090,6 +6090,7 @@ function registerMemoryTried(memory2) {
|
|
|
6090
6090
|
} else if (result.hint) {
|
|
6091
6091
|
ui.warn(result.hint);
|
|
6092
6092
|
}
|
|
6093
|
+
ui.info(` Prefer a real test? \`hivelore sensors scaffold ${result.id}\` generates a pending test + the wiring command.`);
|
|
6093
6094
|
});
|
|
6094
6095
|
}
|
|
6095
6096
|
|
|
@@ -8959,7 +8960,7 @@ function registerDoctor(program2) {
|
|
|
8959
8960
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `hivelore init` without --manual)."
|
|
8960
8961
|
});
|
|
8961
8962
|
}
|
|
8962
|
-
findings.push(...await collectInstallFindings(root, "0.
|
|
8963
|
+
findings.push(...await collectInstallFindings(root, "0.37.0"));
|
|
8963
8964
|
findings.push(...await collectToolchainFindings(root));
|
|
8964
8965
|
try {
|
|
8965
8966
|
const legacyRaw = execSync("haive-mcp --version", {
|
|
@@ -8967,7 +8968,7 @@ function registerDoctor(program2) {
|
|
|
8967
8968
|
timeout: 3e3,
|
|
8968
8969
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8969
8970
|
}).trim();
|
|
8970
|
-
const cliVersion = "0.
|
|
8971
|
+
const cliVersion = "0.37.0";
|
|
8971
8972
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
8972
8973
|
findings.push({
|
|
8973
8974
|
severity: "warn",
|
|
@@ -10670,7 +10671,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
10670
10671
|
findings: [{ severity: "info", code: "enforcement-off", message: "Hivelore enforcement is disabled." }]
|
|
10671
10672
|
});
|
|
10672
10673
|
}
|
|
10673
|
-
findings.push(...await inspectIntegrationVersions(root, "0.
|
|
10674
|
+
findings.push(...await inspectIntegrationVersions(root, "0.37.0"));
|
|
10674
10675
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
10675
10676
|
const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
|
|
10676
10677
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent Hivelore briefing marker exists." } : {
|
|
@@ -12159,10 +12160,13 @@ import {
|
|
|
12159
12160
|
loadConfig as loadConfig13,
|
|
12160
12161
|
loadSensorLedger as loadSensorLedger4,
|
|
12161
12162
|
loadMemoriesFromDir as loadMemoriesFromDir15,
|
|
12163
|
+
parseLessonFields,
|
|
12162
12164
|
recordPreventionHits as recordPreventionHits2,
|
|
12163
12165
|
resolveHaivePaths as resolveHaivePaths36,
|
|
12164
12166
|
runSensors as runSensors2,
|
|
12167
|
+
scaffoldPostIncidentTest,
|
|
12165
12168
|
selectCommandSensors as selectCommandSensors2,
|
|
12169
|
+
TEST_FRAMEWORKS,
|
|
12166
12170
|
sensorPatternBrittleness as sensorPatternBrittleness2,
|
|
12167
12171
|
sensorSelfCheck as sensorSelfCheck2,
|
|
12168
12172
|
sensorAppliesToPath as sensorAppliesToPath3,
|
|
@@ -12405,7 +12409,7 @@ function registerSensors(program2) {
|
|
|
12405
12409
|
return;
|
|
12406
12410
|
}
|
|
12407
12411
|
const root2 = findProjectRoot39(opts.dir);
|
|
12408
|
-
const { proposeSensor } = await import("./server-
|
|
12412
|
+
const { proposeSensor } = await import("./server-J6TDFG2C.js");
|
|
12409
12413
|
const out = await proposeSensor(
|
|
12410
12414
|
{
|
|
12411
12415
|
memory_id: id,
|
|
@@ -12494,6 +12498,56 @@ function registerSensors(program2) {
|
|
|
12494
12498
|
`self-check: silent on current=${verdict.self_check.silent_on_current}` + (verdict.self_check.fires_on_bad === null ? "; no bad example tested" : `; fires on bad=${verdict.self_check.fires_on_bad}`)
|
|
12495
12499
|
);
|
|
12496
12500
|
});
|
|
12501
|
+
sensors.command("scaffold").description(
|
|
12502
|
+
"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"
|
|
12503
|
+
).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("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
12504
|
+
const root = findProjectRoot39(opts.dir);
|
|
12505
|
+
const paths = resolveHaivePaths36(root);
|
|
12506
|
+
const loaded = existsSync43(paths.memoriesDir) ? await loadMemoriesFromDir15(paths.memoriesDir) : [];
|
|
12507
|
+
const found = loaded.find(({ memory: memory2 }) => memory2.frontmatter.id === id);
|
|
12508
|
+
if (!found) {
|
|
12509
|
+
ui.error(`No memory found with id ${id}`);
|
|
12510
|
+
process.exitCode = 1;
|
|
12511
|
+
return;
|
|
12512
|
+
}
|
|
12513
|
+
const framework = opts.framework ? normalizeFramework(opts.framework) : await detectTestFramework(root);
|
|
12514
|
+
if (!framework) {
|
|
12515
|
+
ui.error(`Unknown --framework "${opts.framework}". Use one of: ${TEST_FRAMEWORKS.join(", ")}.`);
|
|
12516
|
+
process.exitCode = 1;
|
|
12517
|
+
return;
|
|
12518
|
+
}
|
|
12519
|
+
const fields = parseLessonFields(found.memory.body);
|
|
12520
|
+
const fm = found.memory.frontmatter;
|
|
12521
|
+
const scaffold = scaffoldPostIncidentTest(
|
|
12522
|
+
{
|
|
12523
|
+
memoryId: id,
|
|
12524
|
+
title: fields.title || id,
|
|
12525
|
+
whyFailed: fields.whyFailed,
|
|
12526
|
+
instead: fields.instead,
|
|
12527
|
+
incident: fm.sensor?.incident,
|
|
12528
|
+
paths: fm.anchor.paths
|
|
12529
|
+
},
|
|
12530
|
+
{ framework, outPath: opts.out }
|
|
12531
|
+
);
|
|
12532
|
+
if (opts.stdout) {
|
|
12533
|
+
console.log(scaffold.content);
|
|
12534
|
+
ui.info(`Arm it once written: ${scaffold.proposeCommand}`);
|
|
12535
|
+
return;
|
|
12536
|
+
}
|
|
12537
|
+
const abs = path41.isAbsolute(scaffold.relPath) ? scaffold.relPath : path41.resolve(root, scaffold.relPath);
|
|
12538
|
+
if (existsSync43(abs) && !opts.force) {
|
|
12539
|
+
ui.error(`${scaffold.relPath} already exists \u2014 pass --force to overwrite, or --out <path> for a different file.`);
|
|
12540
|
+
process.exitCode = 1;
|
|
12541
|
+
return;
|
|
12542
|
+
}
|
|
12543
|
+
await mkdir17(path41.dirname(abs), { recursive: true });
|
|
12544
|
+
await writeFile27(abs, scaffold.content, "utf8");
|
|
12545
|
+
ui.success(`Wrote ${framework} post-incident test \u2192 ${scaffold.relPath}`);
|
|
12546
|
+
ui.info(" 1. Fill in the assertion (RED on the incident, GREEN once fixed).");
|
|
12547
|
+
ui.info(` 2. Run it: ${scaffold.runCommand}`);
|
|
12548
|
+
ui.info(" 3. Arm it as a deterministic gate:");
|
|
12549
|
+
console.log(` ${scaffold.proposeCommand}`);
|
|
12550
|
+
});
|
|
12497
12551
|
sensors.command("export").description("Export regex sensors into .ai/generated for external toolchains").option("--format <format>", "grep | eslint", "grep").option("--out-dir <dir>", "output directory", ".ai/generated").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
12498
12552
|
const format = opts.format ?? "grep";
|
|
12499
12553
|
if (format !== "grep" && format !== "eslint") {
|
|
@@ -12583,6 +12637,31 @@ function renderGrepScript(rows) {
|
|
|
12583
12637
|
function shellQuote(value) {
|
|
12584
12638
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
12585
12639
|
}
|
|
12640
|
+
function normalizeFramework(input) {
|
|
12641
|
+
const v = input.trim().toLowerCase();
|
|
12642
|
+
if (v === "vitest") return "vitest";
|
|
12643
|
+
if (v === "jest") return "jest";
|
|
12644
|
+
if (v === "pytest" || v === "py" || v === "python") return "pytest";
|
|
12645
|
+
if (v === "go" || v === "gotest" || v === "go-test") return "gotest";
|
|
12646
|
+
return null;
|
|
12647
|
+
}
|
|
12648
|
+
async function detectTestFramework(root) {
|
|
12649
|
+
try {
|
|
12650
|
+
const pkgPath = path41.join(root, "package.json");
|
|
12651
|
+
if (existsSync43(pkgPath)) {
|
|
12652
|
+
const pkg = JSON.parse(await readFile20(pkgPath, "utf8"));
|
|
12653
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
12654
|
+
if (deps.vitest) return "vitest";
|
|
12655
|
+
if (deps.jest || deps["ts-jest"]) return "jest";
|
|
12656
|
+
}
|
|
12657
|
+
} catch {
|
|
12658
|
+
}
|
|
12659
|
+
if (existsSync43(path41.join(root, "go.mod"))) return "gotest";
|
|
12660
|
+
for (const signal of ["pyproject.toml", "setup.py", "pytest.ini", "requirements.txt", "tox.ini"]) {
|
|
12661
|
+
if (existsSync43(path41.join(root, signal))) return "pytest";
|
|
12662
|
+
}
|
|
12663
|
+
return "vitest";
|
|
12664
|
+
}
|
|
12586
12665
|
|
|
12587
12666
|
// src/commands/ingest.ts
|
|
12588
12667
|
import { existsSync as existsSync44 } from "fs";
|
|
@@ -13244,7 +13323,7 @@ function registerBridges(program2) {
|
|
|
13244
13323
|
|
|
13245
13324
|
// src/index.ts
|
|
13246
13325
|
var program = new Command48();
|
|
13247
|
-
program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.
|
|
13326
|
+
program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.37.0").option("--advanced", "show maintenance and experimental commands in help").showSuggestionAfterError(true);
|
|
13248
13327
|
registerInit(program);
|
|
13249
13328
|
registerResolveProject(program);
|
|
13250
13329
|
registerEnforce(program);
|