@hivelore/cli 0.43.2 → 0.44.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/README.md +7 -6
- package/dist/{chunk-FXDGOBPT.js → chunk-6KRXMDLC.js} +41 -9
- package/dist/chunk-6KRXMDLC.js.map +1 -0
- package/dist/index.js +175 -54
- package/dist/index.js.map +1 -1
- package/dist/{server-WW6JHBYY.js → server-MCNCAFJN.js} +6 -4
- package/package.json +16 -5
- package/dist/chunk-FXDGOBPT.js.map +0 -1
- /package/dist/{server-WW6JHBYY.js.map → server-MCNCAFJN.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-6KRXMDLC.js";
|
|
17
17
|
import {
|
|
18
18
|
registerMemoryPending
|
|
19
19
|
} from "./chunk-OYJKHD22.js";
|
|
@@ -1299,7 +1299,7 @@ function attachSemanticCommands(embeddings, naming) {
|
|
|
1299
1299
|
minScore: Number(opts.minScore ?? 0)
|
|
1300
1300
|
});
|
|
1301
1301
|
if (!result) {
|
|
1302
|
-
ui.error("No embeddings index found. Run `hivelore
|
|
1302
|
+
ui.error("No embeddings index found. Run `hivelore index memories` first.");
|
|
1303
1303
|
process.exitCode = 1;
|
|
1304
1304
|
return;
|
|
1305
1305
|
}
|
|
@@ -1319,7 +1319,7 @@ function attachSemanticCommands(embeddings, naming) {
|
|
|
1319
1319
|
const { indexStat } = await loadEmbeddings();
|
|
1320
1320
|
const stat2 = await indexStat(paths);
|
|
1321
1321
|
if (!stat2.exists) {
|
|
1322
|
-
ui.warn("No embeddings index. Run `hivelore
|
|
1322
|
+
ui.warn("No embeddings index. Run `hivelore index memories` to create one.");
|
|
1323
1323
|
return;
|
|
1324
1324
|
}
|
|
1325
1325
|
console.log(`${ui.bold("entries:")} ${stat2.count}`);
|
|
@@ -1393,7 +1393,7 @@ function registerIndexCode(program2) {
|
|
|
1393
1393
|
mod = await import("@hivelore/embeddings");
|
|
1394
1394
|
} catch {
|
|
1395
1395
|
ui.error(
|
|
1396
|
-
"@hivelore/embeddings is not installed. Install it (`pnpm add @hivelore/embeddings`)
|
|
1396
|
+
"@hivelore/embeddings is not installed. Install it (`pnpm add @hivelore/embeddings`) then run `hivelore index code-search`."
|
|
1397
1397
|
);
|
|
1398
1398
|
process.exit(1);
|
|
1399
1399
|
}
|
|
@@ -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.44.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,
|
|
@@ -5259,7 +5259,7 @@ Wait for **explicit confirmation** before acting.
|
|
|
5259
5259
|
)
|
|
5260
5260
|
);
|
|
5261
5261
|
} catch {
|
|
5262
|
-
ui.warn("--embed: @hivelore/embeddings not available or index build failed.
|
|
5262
|
+
ui.warn("--embed: @hivelore/embeddings not available or index build failed. Install it, then run `hivelore index memories`.");
|
|
5263
5263
|
}
|
|
5264
5264
|
}
|
|
5265
5265
|
});
|
|
@@ -6974,6 +6974,7 @@ import {
|
|
|
6974
6974
|
loadConfig as loadConfig6,
|
|
6975
6975
|
loadMemoriesFromDir as loadMemoriesFromDir10,
|
|
6976
6976
|
loadPreventionEvents,
|
|
6977
|
+
readUsageEvents,
|
|
6977
6978
|
loadUsageIndex as loadUsageIndex11,
|
|
6978
6979
|
memoryFilePath as memoryFilePath5,
|
|
6979
6980
|
renderCaughtForYou,
|
|
@@ -7226,6 +7227,14 @@ async function observationStart(paths) {
|
|
|
7226
7227
|
}
|
|
7227
7228
|
return first;
|
|
7228
7229
|
}
|
|
7230
|
+
async function manualSessionStart(paths) {
|
|
7231
|
+
const events = await readUsageEvents(paths);
|
|
7232
|
+
for (let index = events.length - 1; index >= 0; index--) {
|
|
7233
|
+
const event = events[index];
|
|
7234
|
+
if (["get_briefing", "briefing", "session_start", "enforce_session_start"].includes(event.tool)) return event.at;
|
|
7235
|
+
}
|
|
7236
|
+
return null;
|
|
7237
|
+
}
|
|
7229
7238
|
async function printCaughtForYou(paths, since, quiet) {
|
|
7230
7239
|
if (quiet) return;
|
|
7231
7240
|
const memories = existsSync32(paths.memoriesDir) ? await loadMemoriesFromDir10(paths.memoriesDir) : [];
|
|
@@ -7275,7 +7284,7 @@ function registerSessionEnd(session2) {
|
|
|
7275
7284
|
let resolvedFiles = opts.files;
|
|
7276
7285
|
let goal = opts.goal;
|
|
7277
7286
|
let accomplished = opts.accomplished ?? opts.summary;
|
|
7278
|
-
const caughtSince = opts.auto ? await observationStart(paths) :
|
|
7287
|
+
const caughtSince = opts.auto ? await observationStart(paths) : await manualSessionStart(paths);
|
|
7279
7288
|
if (opts.auto) {
|
|
7280
7289
|
const autoCaptured = await autoCaptureFailureLessons(paths, root, await readObservationList(paths)).catch(() => ({ written: 0, ids: [] }));
|
|
7281
7290
|
const synth = await buildAutoRecap(paths);
|
|
@@ -7416,7 +7425,7 @@ import {
|
|
|
7416
7425
|
loadUsageIndex as loadUsageIndex12,
|
|
7417
7426
|
loadPreventionEvents as loadPreventionEvents2,
|
|
7418
7427
|
parseSince,
|
|
7419
|
-
readUsageEvents,
|
|
7428
|
+
readUsageEvents as readUsageEvents2,
|
|
7420
7429
|
renderPreventionReceiptShare,
|
|
7421
7430
|
resolveHaivePaths as resolveHaivePaths27,
|
|
7422
7431
|
usageLogSize
|
|
@@ -7465,7 +7474,7 @@ function registerStats(program2) {
|
|
|
7465
7474
|
);
|
|
7466
7475
|
return;
|
|
7467
7476
|
}
|
|
7468
|
-
const events = await
|
|
7477
|
+
const events = await readUsageEvents2(paths);
|
|
7469
7478
|
const since = parseSince(opts.since);
|
|
7470
7479
|
const aggregate = aggregateUsage(events, since ?? void 0);
|
|
7471
7480
|
if (opts.json) {
|
|
@@ -7501,7 +7510,7 @@ function registerStats(program2) {
|
|
|
7501
7510
|
async function writeRoiReport(paths, root, sinceRaw, outRelative) {
|
|
7502
7511
|
const outAbs = path30.isAbsolute(outRelative) ? path30.resolve(outRelative) : path30.resolve(root, outRelative);
|
|
7503
7512
|
const size = await usageLogSize(paths);
|
|
7504
|
-
let events = await
|
|
7513
|
+
let events = await readUsageEvents2(paths);
|
|
7505
7514
|
let memoryCount = { team: 0, personal: 0, total_skipped_session: 0 };
|
|
7506
7515
|
if (existsSync33(paths.memoriesDir)) {
|
|
7507
7516
|
const mems = await loadMemoriesFromDir11(paths.memoriesDir);
|
|
@@ -7666,7 +7675,7 @@ function registerBench(program2) {
|
|
|
7666
7675
|
},
|
|
7667
7676
|
async () => {
|
|
7668
7677
|
const t0 = performance.now();
|
|
7669
|
-
const out = await antiPatternsCheck({ diff: task, paths: [], limit: 5, semantic: true }, ctx);
|
|
7678
|
+
const out = await antiPatternsCheck({ diff: task, paths: [], limit: 5, semantic: true, track: false }, ctx);
|
|
7670
7679
|
return summarize("anti_patterns_check", t0, out, [
|
|
7671
7680
|
`${out.warnings.length}/${out.scanned} warn`
|
|
7672
7681
|
]);
|
|
@@ -7757,7 +7766,7 @@ function registerBenchmark(program2) {
|
|
|
7757
7766
|
" - Hivelore agents must run `hivelore briefing --files ... --task ...` first.",
|
|
7758
7767
|
" - Plain agents must not read `.ai` or call Hivelore.",
|
|
7759
7768
|
"5. Require every agent to write `BENCHMARK_AGENT_REPORT.md`.",
|
|
7760
|
-
" Its `## Outcome` section must include: Task completed, Tests passed, Policy violations, Duration seconds, Total tokens.",
|
|
7769
|
+
" Its `## Outcome` section must include: Task completed, Tests passed, Policy violations, Duration seconds, Total tokens, Runner ID, Evaluator ID, Independent evaluation.",
|
|
7761
7770
|
"6. Run `hivelore benchmark report --dir <benchmark-root> --out RESULTS.md`.",
|
|
7762
7771
|
"7. Do not make comparative claims until evidence_grade=decision-ready (>=10 paired tasks with complete outcomes).",
|
|
7763
7772
|
"",
|
|
@@ -7802,7 +7811,10 @@ function parseAgentReport(fixture, report) {
|
|
|
7802
7811
|
tests_passed: reportBoolean(report, "Tests passed"),
|
|
7803
7812
|
policy_violations: reportNumber(report, "Policy violations"),
|
|
7804
7813
|
duration_seconds: reportNumber(report, "Duration seconds"),
|
|
7805
|
-
total_tokens: reportNumber(report, "Total tokens")
|
|
7814
|
+
total_tokens: reportNumber(report, "Total tokens"),
|
|
7815
|
+
runner_id: reportValue(report, "Runner ID"),
|
|
7816
|
+
evaluator_id: reportValue(report, "Evaluator ID"),
|
|
7817
|
+
independent_evaluation: reportBoolean(report, "Independent evaluation")
|
|
7806
7818
|
};
|
|
7807
7819
|
}
|
|
7808
7820
|
function summarizeRows(rows) {
|
|
@@ -7813,14 +7825,14 @@ function summarizeRows(rows) {
|
|
|
7813
7825
|
const plainTasks = new Set(plainRows.map((row) => taskName(row.fixture)));
|
|
7814
7826
|
const pairedTasks = new Set(haiveRows.map((row) => taskName(row.fixture)).filter((name) => plainTasks.has(name))).size;
|
|
7815
7827
|
const outcomeComplete = rows.length > 0 && rows.every(
|
|
7816
|
-
(row) => row.task_completed !== null && row.tests_passed !== null && row.policy_violations !== null && row.duration_seconds !== null && row.total_tokens !== null
|
|
7828
|
+
(row) => row.task_completed !== null && row.tests_passed !== null && row.policy_violations !== null && row.duration_seconds !== null && row.total_tokens !== null && row.runner_id !== null && row.evaluator_id !== null && row.evaluator_id !== row.runner_id && row.independent_evaluation === true
|
|
7817
7829
|
);
|
|
7818
7830
|
const decisionReady = pairedTasks >= 10 && outcomeComplete;
|
|
7819
7831
|
return {
|
|
7820
7832
|
fixtures: rows.length,
|
|
7821
7833
|
paired_tasks: pairedTasks,
|
|
7822
7834
|
evidence_grade: decisionReady ? "decision-ready" : "insufficient",
|
|
7823
|
-
evidence_reason: decisionReady ? "At least 10 paired tasks with complete
|
|
7835
|
+
evidence_reason: decisionReady ? "At least 10 paired tasks with complete outcomes reviewed by an evaluator distinct from the runner." : `Need >=10 paired tasks, complete Outcome fields, and independent evaluator attestations; found ${pairedTasks} pair(s), outcome_complete=${outcomeComplete}.`,
|
|
7824
7836
|
haive: summarizeGroup(haiveRows),
|
|
7825
7837
|
plain: summarizeGroup(plainRows)
|
|
7826
7838
|
};
|
|
@@ -7941,7 +7953,7 @@ import {
|
|
|
7941
7953
|
function registerEval(program2) {
|
|
7942
7954
|
program2.command("eval").description(
|
|
7943
7955
|
"Rigorous, repeatable quality eval: do the right memories surface (retrieval) and do the right sensors fire (catch-rate)? Emits a numeric 0\u2013100 score. Uses .ai/eval cases via --spec, or auto-synthesizes cases from anchored memories."
|
|
7944
|
-
).option("--spec <file>", "JSON eval spec ({ retrieval: [...], sensors: [...] })").option("--semantic-only", "self-eval probes by title alone (no anchor files) \u2014 harder retrieval", false).option("-k, --top <n>", "briefing top-k considered a hit", "8").option("--json", "emit JSON", false).option("--out <file>", "write a Markdown report").option("--fail-under <score>", "exit non-zero if the overall score is below this (0\u2013100) \u2014 for CI gates").option("--fail-under-catch-rate <pct>", "exit non-zero if sensor catch-rate is below this percentage").option("--fail-under-gate-precision <pct>", "exit non-zero if gate precision is below this percentage").option("--baseline", "save this run as the baseline (.ai/eval/baseline.json) for future --compare", false).option("--compare", "diff this run against the saved baseline and print the delta", false).option("--baseline-file <path>", "baseline file to read/write (default: .ai/eval/baseline.json)").option("--fail-on-regression", "with --compare, exit non-zero if the score dropped vs the baseline", false).option("--regression-gate", "CI-safe gate: compare against the baseline IF one exists (fail on regression), else no-op", false).option("--approve-cases", "approve every proposed golden case (gate-miss labeled) into the scored retrieval set, then exit", false).option("--record", "append this run's score to .ai/.cache/eval-history.jsonl (trend the harness over time)", false).option("--trend", "print the recorded score trend (sparkline + latest/best/delta) and exit", false).option("--ref <ref>", "version/commit label stored with a --record run").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
7956
|
+
).option("--spec <file>", "JSON eval spec ({ retrieval: [...], sensors: [...] })").option("--semantic-only", "self-eval probes by title alone (no anchor files) \u2014 harder retrieval", false).option("--semantic-ranking", "run the real embeddings-backed ranking lane; fails if embeddings/index are unavailable", false).option("-k, --top <n>", "briefing top-k considered a hit", "8").option("--json", "emit JSON", false).option("--out <file>", "write a Markdown report").option("--fail-under <score>", "exit non-zero if the overall score is below this (0\u2013100) \u2014 for CI gates").option("--fail-under-catch-rate <pct>", "exit non-zero if sensor catch-rate is below this percentage").option("--fail-under-gate-precision <pct>", "exit non-zero if gate precision is below this percentage").option("--baseline", "save this run as the baseline (.ai/eval/baseline.json) for future --compare", false).option("--compare", "diff this run against the saved baseline and print the delta", false).option("--baseline-file <path>", "baseline file to read/write (default: .ai/eval/baseline.json)").option("--fail-on-regression", "with --compare, exit non-zero if the score dropped vs the baseline", false).option("--regression-gate", "CI-safe gate: compare against the baseline IF one exists (fail on regression), else no-op", false).option("--approve-cases", "approve every proposed golden case (gate-miss labeled) into the scored retrieval set, then exit", false).option("--record", "append this run's score to .ai/.cache/eval-history.jsonl (trend the harness over time)", false).option("--trend", "print the recorded score trend (sparkline + latest/best/delta) and exit", false).option("--ref <ref>", "version/commit label stored with a --record run").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
7945
7957
|
const root = findProjectRoot31(opts.dir);
|
|
7946
7958
|
const paths = resolveHaivePaths29(root);
|
|
7947
7959
|
if (!existsSync35(paths.memoriesDir)) {
|
|
@@ -8003,8 +8015,15 @@ function registerEval(program2) {
|
|
|
8003
8015
|
if (spec.retrieval && spec.retrieval.length > 0) {
|
|
8004
8016
|
const results = [];
|
|
8005
8017
|
for (const c of spec.retrieval) {
|
|
8006
|
-
const
|
|
8007
|
-
|
|
8018
|
+
const retrieval = await runRetrieval(c, k, ctx, opts.semanticRanking === true);
|
|
8019
|
+
if (opts.semanticRanking && retrieval.searchMode !== "semantic") {
|
|
8020
|
+
ui.error(
|
|
8021
|
+
"Semantic eval requested, but the embeddings package/index is unavailable. Install @hivelore/embeddings and run `hivelore index memories` first."
|
|
8022
|
+
);
|
|
8023
|
+
process.exitCode = 1;
|
|
8024
|
+
return;
|
|
8025
|
+
}
|
|
8026
|
+
results.push(scoreRetrievalCase(c.name, c.expect_ids, retrieval.ids));
|
|
8008
8027
|
}
|
|
8009
8028
|
retrievalAgg = aggregateRetrieval(results);
|
|
8010
8029
|
}
|
|
@@ -8044,7 +8063,7 @@ function registerEval(program2) {
|
|
|
8044
8063
|
});
|
|
8045
8064
|
if (!opts.json) ui.success(`Recorded eval score ${report.score}/100 to history.`);
|
|
8046
8065
|
}
|
|
8047
|
-
const baselineFile = opts.baselineFile ? path32.isAbsolute(opts.baselineFile) ? opts.baselineFile : path32.join(root, opts.baselineFile) : path32.join(root, ".ai", "eval", "baseline.json");
|
|
8066
|
+
const baselineFile = opts.baselineFile ? path32.isAbsolute(opts.baselineFile) ? opts.baselineFile : path32.join(root, opts.baselineFile) : path32.join(root, ".ai", "eval", opts.semanticRanking ? "semantic-baseline.json" : "baseline.json");
|
|
8048
8067
|
if (opts.baseline) {
|
|
8049
8068
|
const snapshot = {
|
|
8050
8069
|
saved_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -8081,6 +8100,7 @@ function registerEval(program2) {
|
|
|
8081
8100
|
console.log(JSON.stringify({
|
|
8082
8101
|
root,
|
|
8083
8102
|
k,
|
|
8103
|
+
ranking_mode: opts.semanticRanking ? "semantic" : "deterministic",
|
|
8084
8104
|
spec_source: resolvedSpec.source,
|
|
8085
8105
|
provenance: {
|
|
8086
8106
|
synthesized: resolvedSpec.synthesized,
|
|
@@ -8240,7 +8260,7 @@ async function resolveSpec(opts, root, memoriesDir) {
|
|
|
8240
8260
|
authored: 0
|
|
8241
8261
|
};
|
|
8242
8262
|
}
|
|
8243
|
-
async function runRetrieval(c, k, ctx) {
|
|
8263
|
+
async function runRetrieval(c, k, ctx, semanticRanking = false) {
|
|
8244
8264
|
const out = await getBriefing(
|
|
8245
8265
|
{
|
|
8246
8266
|
task: c.task,
|
|
@@ -8254,17 +8274,17 @@ async function runRetrieval(c, k, ctx) {
|
|
|
8254
8274
|
include_stale: false,
|
|
8255
8275
|
track: false,
|
|
8256
8276
|
memory_scopes: ["team", "module"],
|
|
8257
|
-
deterministic:
|
|
8277
|
+
deterministic: !semanticRanking,
|
|
8258
8278
|
format: "compact",
|
|
8259
8279
|
min_semantic_score: 0
|
|
8260
8280
|
},
|
|
8261
8281
|
ctx
|
|
8262
8282
|
);
|
|
8263
|
-
return out.memories.map((m) => m.id);
|
|
8283
|
+
return { ids: out.memories.map((m) => m.id), searchMode: out.search_mode };
|
|
8264
8284
|
}
|
|
8265
8285
|
async function runSensorCase(c, ctx) {
|
|
8266
8286
|
const out = await antiPatternsCheck(
|
|
8267
|
-
{ diff: c.diff, paths: c.paths ?? [], limit: 50, semantic: false },
|
|
8287
|
+
{ diff: c.diff, paths: c.paths ?? [], limit: 50, semantic: false, track: false },
|
|
8268
8288
|
ctx
|
|
8269
8289
|
);
|
|
8270
8290
|
return out.warnings.filter((w) => w.reasons.includes("sensor")).map((w) => w.id);
|
|
@@ -8357,7 +8377,7 @@ import {
|
|
|
8357
8377
|
loadMemoriesFromDir as loadMemoriesFromDir12,
|
|
8358
8378
|
memoryFilePath as memoryFilePath6,
|
|
8359
8379
|
parseSince as parseSince2,
|
|
8360
|
-
readUsageEvents as
|
|
8380
|
+
readUsageEvents as readUsageEvents3,
|
|
8361
8381
|
resolveHaivePaths as resolveHaivePaths30,
|
|
8362
8382
|
serializeMemory as serializeMemory13,
|
|
8363
8383
|
suggestTopicKey
|
|
@@ -8388,7 +8408,7 @@ function registerMemorySuggest(memory2) {
|
|
|
8388
8408
|
}
|
|
8389
8409
|
const root = findProjectRoot32(opts.dir);
|
|
8390
8410
|
const paths = resolveHaivePaths30(root);
|
|
8391
|
-
const events = await
|
|
8411
|
+
const events = await readUsageEvents3(paths);
|
|
8392
8412
|
if (events.length === 0) {
|
|
8393
8413
|
if (opts.json) {
|
|
8394
8414
|
console.log(JSON.stringify({ suggestions: [] }));
|
|
@@ -8778,7 +8798,7 @@ import {
|
|
|
8778
8798
|
loadMemoriesFromDirDetailed,
|
|
8779
8799
|
loadSensorLedger as loadSensorLedger2,
|
|
8780
8800
|
loadUsageIndex as loadUsageIndex15,
|
|
8781
|
-
readUsageEvents as
|
|
8801
|
+
readUsageEvents as readUsageEvents4,
|
|
8782
8802
|
resolveHaivePaths as resolveHaivePaths33
|
|
8783
8803
|
} from "@hivelore/core";
|
|
8784
8804
|
|
|
@@ -9027,14 +9047,15 @@ function registerDoctor(program2) {
|
|
|
9027
9047
|
}
|
|
9028
9048
|
}
|
|
9029
9049
|
const lintReport = await lintMemoriesAsync(root);
|
|
9030
|
-
|
|
9050
|
+
const actionableLintFindings = lintReport.findings.filter((finding) => finding.severity !== "info");
|
|
9051
|
+
if (actionableLintFindings.length > 0) {
|
|
9031
9052
|
const warnCount = lintReport.findings.filter((finding) => finding.severity === "warn").length;
|
|
9032
9053
|
const errorCount = lintReport.findings.filter((finding) => finding.severity === "error").length;
|
|
9033
9054
|
const severity = errorCount > 0 ? "error" : warnCount > 0 ? "warn" : "info";
|
|
9034
9055
|
findings.push({
|
|
9035
9056
|
severity,
|
|
9036
9057
|
code: "memory-lint-findings",
|
|
9037
|
-
message: `memory lint reports ${
|
|
9058
|
+
message: `memory lint reports ${actionableLintFindings.length} actionable finding${actionableLintFindings.length === 1 ? "" : "s"} (${errorCount} error, ${warnCount} warn).`,
|
|
9038
9059
|
fix: "hivelore memory lint --fix --apply"
|
|
9039
9060
|
});
|
|
9040
9061
|
}
|
|
@@ -9103,7 +9124,7 @@ function registerDoctor(program2) {
|
|
|
9103
9124
|
}
|
|
9104
9125
|
const astSensorCount = sensorMemories.filter((m) => m.memory.frontmatter.sensor?.kind === "ast").length;
|
|
9105
9126
|
if (astSensorCount > 0) {
|
|
9106
|
-
const { astEngineAvailable: astEngineAvailable2 } = await import("./server-
|
|
9127
|
+
const { astEngineAvailable: astEngineAvailable2 } = await import("./server-MCNCAFJN.js");
|
|
9107
9128
|
if (!await astEngineAvailable2()) {
|
|
9108
9129
|
findings.push({
|
|
9109
9130
|
severity: "warn",
|
|
@@ -9186,7 +9207,7 @@ function registerDoctor(program2) {
|
|
|
9186
9207
|
});
|
|
9187
9208
|
}
|
|
9188
9209
|
const onDisk = await countSourceFilesOnDisk(root);
|
|
9189
|
-
if (
|
|
9210
|
+
if (isCodeMapNearEmpty(indexedCount, onDisk)) {
|
|
9190
9211
|
findings.push({
|
|
9191
9212
|
severity: "warn",
|
|
9192
9213
|
code: "code-map-near-empty",
|
|
@@ -9209,7 +9230,7 @@ function registerDoctor(program2) {
|
|
|
9209
9230
|
}
|
|
9210
9231
|
} catch {
|
|
9211
9232
|
}
|
|
9212
|
-
const events = await
|
|
9233
|
+
const events = await readUsageEvents4(paths);
|
|
9213
9234
|
if (events.length === 0) {
|
|
9214
9235
|
findings.push({
|
|
9215
9236
|
severity: "info",
|
|
@@ -9273,7 +9294,8 @@ function registerDoctor(program2) {
|
|
|
9273
9294
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `hivelore init` without --manual)."
|
|
9274
9295
|
});
|
|
9275
9296
|
}
|
|
9276
|
-
findings.push(...await collectInstallFindings(root, "0.
|
|
9297
|
+
findings.push(...await collectInstallFindings(root, "0.44.0"));
|
|
9298
|
+
findings.push(...await collectMcpRuntimeFindings(paths, "0.44.0"));
|
|
9277
9299
|
findings.push(...await collectToolchainFindings(root));
|
|
9278
9300
|
try {
|
|
9279
9301
|
const legacyRaw = execSync("haive-mcp --version", {
|
|
@@ -9281,7 +9303,7 @@ function registerDoctor(program2) {
|
|
|
9281
9303
|
timeout: 3e3,
|
|
9282
9304
|
stdio: ["ignore", "pipe", "ignore"]
|
|
9283
9305
|
}).trim();
|
|
9284
|
-
const cliVersion = "0.
|
|
9306
|
+
const cliVersion = "0.44.0";
|
|
9285
9307
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
9286
9308
|
findings.push({
|
|
9287
9309
|
severity: "warn",
|
|
@@ -9337,6 +9359,39 @@ npm uninstall -g @hivelore/mcp`
|
|
|
9337
9359
|
emit(findings, opts, repairs);
|
|
9338
9360
|
});
|
|
9339
9361
|
}
|
|
9362
|
+
function isCodeMapNearEmpty(indexedCount, sourceFilesOnDisk) {
|
|
9363
|
+
return sourceFilesOnDisk >= 20 && indexedCount < sourceFilesOnDisk * 0.05;
|
|
9364
|
+
}
|
|
9365
|
+
function mcpRuntimeVersionFinding(marker, expectedVersion, processAlive) {
|
|
9366
|
+
if (!processAlive || !marker.version || marker.version === expectedVersion) return null;
|
|
9367
|
+
return {
|
|
9368
|
+
severity: "warn",
|
|
9369
|
+
code: "active-mcp-server-stale",
|
|
9370
|
+
message: `An active MCP server is still v${marker.version} while the installed CLI is v${expectedVersion}. MCP clients keep server processes alive across package upgrades.`,
|
|
9371
|
+
fix: "Restart the IDE/agent MCP client, then confirm get_briefing.server_version matches `hivelore --version`.",
|
|
9372
|
+
section: "Agent coverage"
|
|
9373
|
+
};
|
|
9374
|
+
}
|
|
9375
|
+
async function collectMcpRuntimeFindings(paths, expectedVersion) {
|
|
9376
|
+
const markerFile = path37.join(paths.runtimeDir, "mcp-server.json");
|
|
9377
|
+
if (!existsSync40(markerFile)) return [];
|
|
9378
|
+
try {
|
|
9379
|
+
const marker = JSON.parse(await readFile16(markerFile, "utf8"));
|
|
9380
|
+
let alive = false;
|
|
9381
|
+
if (typeof marker.pid === "number") {
|
|
9382
|
+
try {
|
|
9383
|
+
process.kill(marker.pid, 0);
|
|
9384
|
+
alive = true;
|
|
9385
|
+
} catch {
|
|
9386
|
+
alive = false;
|
|
9387
|
+
}
|
|
9388
|
+
}
|
|
9389
|
+
const finding = mcpRuntimeVersionFinding(marker, expectedVersion, alive);
|
|
9390
|
+
return finding ? [finding] : [];
|
|
9391
|
+
} catch {
|
|
9392
|
+
return [];
|
|
9393
|
+
}
|
|
9394
|
+
}
|
|
9340
9395
|
function emit(findings, opts, repairs = []) {
|
|
9341
9396
|
const classified = findings.map((finding) => ({
|
|
9342
9397
|
...finding,
|
|
@@ -9516,7 +9571,7 @@ async function collectSemanticIndexFindings(paths, config, memoryCount, codeMap)
|
|
|
9516
9571
|
severity: autoWantsCodeSearch ? "warn" : "info",
|
|
9517
9572
|
code: "embeddings-unavailable",
|
|
9518
9573
|
message: "@hivelore/embeddings is not available, so get_briefing falls back to lexical ranking and code_search cannot run.",
|
|
9519
|
-
fix: "npm install -g @hivelore/
|
|
9574
|
+
fix: "npm install -g @hivelore/embeddings@latest\nhivelore index status",
|
|
9520
9575
|
section: "Index health"
|
|
9521
9576
|
});
|
|
9522
9577
|
return findings;
|
|
@@ -9528,7 +9583,7 @@ async function collectSemanticIndexFindings(paths, config, memoryCount, codeMap)
|
|
|
9528
9583
|
severity: "warn",
|
|
9529
9584
|
code: "semantic-memory-index-missing",
|
|
9530
9585
|
message: "Memory embeddings index is missing or empty; get_briefing will report literal_fallback instead of semantic ranking.",
|
|
9531
|
-
fix: "hivelore
|
|
9586
|
+
fix: "hivelore index memories",
|
|
9532
9587
|
section: "Index health"
|
|
9533
9588
|
});
|
|
9534
9589
|
}
|
|
@@ -11028,7 +11083,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
11028
11083
|
findings: [{ severity: "info", code: "enforcement-off", message: "Hivelore enforcement is disabled." }]
|
|
11029
11084
|
});
|
|
11030
11085
|
}
|
|
11031
|
-
findings.push(...await inspectIntegrationVersions(root, "0.
|
|
11086
|
+
findings.push(...await inspectIntegrationVersions(root, "0.44.0"));
|
|
11032
11087
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
11033
11088
|
const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
|
|
11034
11089
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent Hivelore briefing marker exists." } : {
|
|
@@ -11271,15 +11326,26 @@ async function verifyDecisionCoverage(paths, stage, sessionId) {
|
|
|
11271
11326
|
}
|
|
11272
11327
|
async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
11273
11328
|
const snapshot = await getPolicyDiffSnapshot(paths.root, stage);
|
|
11274
|
-
const
|
|
11329
|
+
const weakeningApprovals = await resolveSensorWeakeningApprovals(paths.root, stage);
|
|
11330
|
+
const detectedWeakenings = detectSensorWeakening(snapshot.diff);
|
|
11331
|
+
const weakenings = detectedWeakenings.filter((weakening) => !weakeningApprovals.has(weakening.memory_id));
|
|
11332
|
+
const approvedWeakenings = detectedWeakenings.filter((weakening) => weakeningApprovals.has(weakening.memory_id));
|
|
11275
11333
|
const weakeningFindings = weakenings.length > 0 ? [{
|
|
11276
11334
|
severity: config.enforcement?.sensorWeakeningGate === "block" ? "error" : "warn",
|
|
11277
11335
|
code: "sensor-weakened",
|
|
11278
11336
|
message: `This diff weakens the enforcement surface \u2014 ${weakenings.length} sensor change(s) need review: ` + weakenings.slice(0, 5).map((w) => `${w.memory_id} (${w.change}: ${w.detail})`).join(", ") + (weakenings.length > 5 ? ", \u2026" : "") + ".",
|
|
11279
|
-
fix: "If
|
|
11337
|
+
fix: "If intentional, add `Hivelore-Sensor-Change: <memory-id>` to the commit message and set `HIVELORE_SENSOR_WEAKENING_APPROVALS=<memory-id>` for the local commit hook; otherwise restore the sensor.",
|
|
11280
11338
|
memory_ids: [...new Set(weakenings.map((w) => w.memory_id))].slice(0, 10),
|
|
11281
11339
|
impact: config.enforcement?.sensorWeakeningGate === "block" ? 30 : 8
|
|
11282
11340
|
}] : [];
|
|
11341
|
+
if (approvedWeakenings.length > 0) {
|
|
11342
|
+
weakeningFindings.push({
|
|
11343
|
+
severity: "ok",
|
|
11344
|
+
code: "sensor-weakening-approved",
|
|
11345
|
+
message: `Reviewed sensor change(s) approved for ${[...new Set(approvedWeakenings.map((w) => w.memory_id))].join(", ")}.`,
|
|
11346
|
+
memory_ids: [...new Set(approvedWeakenings.map((w) => w.memory_id))]
|
|
11347
|
+
});
|
|
11348
|
+
}
|
|
11283
11349
|
if (gate === "off") {
|
|
11284
11350
|
return [
|
|
11285
11351
|
{ severity: "info", code: "precommit-policy-off", message: "Anti-pattern gate is disabled (enforcement.antiPatternGate=off)." },
|
|
@@ -11365,6 +11431,28 @@ async function runPrecommitPolicy(paths, gate, stage, config) {
|
|
|
11365
11431
|
...weakeningFindings
|
|
11366
11432
|
];
|
|
11367
11433
|
}
|
|
11434
|
+
function parseSensorWeakeningApprovals(text) {
|
|
11435
|
+
const approved = /* @__PURE__ */ new Set();
|
|
11436
|
+
if (!text) return approved;
|
|
11437
|
+
const trailer = /^Hivelore-Sensor-Change:\s*(.+)$/gmi;
|
|
11438
|
+
for (const match of text.matchAll(trailer)) {
|
|
11439
|
+
for (const id of (match[1] ?? "").split(/[\s,]+/)) if (id) approved.add(id);
|
|
11440
|
+
}
|
|
11441
|
+
if (!text.includes("Hivelore-Sensor-Change:")) {
|
|
11442
|
+
for (const id of text.split(/[\s,]+/)) if (id) approved.add(id);
|
|
11443
|
+
}
|
|
11444
|
+
return approved;
|
|
11445
|
+
}
|
|
11446
|
+
async function resolveSensorWeakeningApprovals(root, stage) {
|
|
11447
|
+
const approved = parseSensorWeakeningApprovals(process.env["HIVELORE_SENSOR_WEAKENING_APPROVALS"]);
|
|
11448
|
+
if (stage !== "ci") return approved;
|
|
11449
|
+
try {
|
|
11450
|
+
const { stdout } = await execFileAsync2("git", ["log", "-1", "--pretty=%B"], { cwd: root });
|
|
11451
|
+
for (const id of parseSensorWeakeningApprovals(stdout)) approved.add(id);
|
|
11452
|
+
} catch {
|
|
11453
|
+
}
|
|
11454
|
+
return approved;
|
|
11455
|
+
}
|
|
11368
11456
|
async function stagedFileContent(root, rel) {
|
|
11369
11457
|
try {
|
|
11370
11458
|
return await runCommand2("git", ["show", `:${rel}`], root);
|
|
@@ -12642,6 +12730,14 @@ import {
|
|
|
12642
12730
|
withoutQuarantineNote
|
|
12643
12731
|
} from "@hivelore/core";
|
|
12644
12732
|
var exec5 = promisify7(execFile7);
|
|
12733
|
+
function rejectProposal(opts, reason, guidance) {
|
|
12734
|
+
if (opts.json) console.log(JSON.stringify({ accepted: false, reason, guidance }, null, 2));
|
|
12735
|
+
else {
|
|
12736
|
+
ui.error(`Rejected (${reason}).`);
|
|
12737
|
+
ui.warn(guidance);
|
|
12738
|
+
}
|
|
12739
|
+
process.exitCode = 1;
|
|
12740
|
+
}
|
|
12645
12741
|
function registerSensors(program2) {
|
|
12646
12742
|
const sensors = program2.command("sensors").description("Operate executable sensors derived from Hivelore memories");
|
|
12647
12743
|
sensors.command("list").description("List memories carrying executable sensors").option("--json", "emit JSON", false).option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
@@ -12682,7 +12778,10 @@ function registerSensors(program2) {
|
|
|
12682
12778
|
const targets = scannableSensorTargets(diff);
|
|
12683
12779
|
const hits = runSensors2(memories, targets);
|
|
12684
12780
|
const astMemories = (await runnableSensorMemories(paths, false)).filter(
|
|
12685
|
-
(m) =>
|
|
12781
|
+
(m) => {
|
|
12782
|
+
const sensor = m.frontmatter.sensor;
|
|
12783
|
+
return sensor?.kind === "ast" && Boolean(sensor.pattern || sensor.rule);
|
|
12784
|
+
}
|
|
12686
12785
|
);
|
|
12687
12786
|
const astHits = [];
|
|
12688
12787
|
let astUnrunnable = 0;
|
|
@@ -12930,16 +13029,14 @@ function registerSensors(program2) {
|
|
|
12930
13029
|
});
|
|
12931
13030
|
sensors.command("propose").description(
|
|
12932
13031
|
"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 })'"
|
|
12933
|
-
).argument("<memory-id>", "memory id to attach the sensor to").option("--kind <kind>", "regex (default) | ast (structural \u2014 comments/strings can't false-positive) | shell | test (route the team's own oracle)", "regex").option("--pattern <regex>", "kind=regex: regex matching the FAULTY usage").option("--rule <json>", "kind=ast: full ast-grep Rule JSON (kind/inside/has/not/all/any)").option("--language <name>", "kind=ast: explicit language for non-standard extensions").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("--red-ref <ref>", "kind=shell|test: pre-fix commit/ref \u2014 validation replays it in a scratch worktree and requires the oracle to FAIL there (records red_proven)").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) => {
|
|
13032
|
+
).argument("<memory-id>", "memory id to attach the sensor to").option("--kind <kind>", "regex (default) | ast (structural \u2014 comments/strings can't false-positive) | shell | test (route the team's own oracle)", "regex").option("--pattern <regex>", "kind=regex: regex matching the FAULTY usage").option("--rule <json>", "kind=ast: full ast-grep Rule JSON (kind/inside/has/not/all/any)").option("--language <name>", "kind=ast: explicit language for non-standard extensions").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("--red-ref <ref>", "kind=shell|test: pre-fix commit/ref \u2014 validation replays it in a scratch worktree and requires the oracle to FAIL there (records red_proven)").option("--flags <flags>", "regex flags (e.g. i)").option("--paths <csv>", "override scope paths (defaults to the memory anchors)").option("--json", "emit a machine-readable proposal verdict", false).option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
12934
13033
|
if (opts.kind === "shell" || opts.kind === "test" || opts.kind === "ast") {
|
|
12935
13034
|
if ((opts.kind === "shell" || opts.kind === "test") && !opts.command?.trim()) {
|
|
12936
|
-
|
|
12937
|
-
process.exitCode = 1;
|
|
13035
|
+
rejectProposal(opts, "missing-command", "--kind shell|test requires --command.");
|
|
12938
13036
|
return;
|
|
12939
13037
|
}
|
|
12940
13038
|
if (opts.kind === "ast" && !opts.pattern?.trim() && !opts.rule?.trim()) {
|
|
12941
|
-
|
|
12942
|
-
process.exitCode = 1;
|
|
13039
|
+
rejectProposal(opts, "missing-ast-rule", "--kind ast requires --pattern or --rule <json>.");
|
|
12943
13040
|
return;
|
|
12944
13041
|
}
|
|
12945
13042
|
let astRule;
|
|
@@ -12949,13 +13046,12 @@ function registerSensors(program2) {
|
|
|
12949
13046
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error("rule must be a JSON object");
|
|
12950
13047
|
astRule = parsed;
|
|
12951
13048
|
} catch (err) {
|
|
12952
|
-
|
|
12953
|
-
process.exitCode = 1;
|
|
13049
|
+
rejectProposal(opts, "invalid-ast-rule", `--rule must be valid ast-grep Rule JSON: ${err instanceof Error ? err.message : String(err)}`);
|
|
12954
13050
|
return;
|
|
12955
13051
|
}
|
|
12956
13052
|
}
|
|
12957
13053
|
const root2 = findProjectRoot39(opts.dir);
|
|
12958
|
-
const { proposeSensor } = await import("./server-
|
|
13054
|
+
const { proposeSensor } = await import("./server-MCNCAFJN.js");
|
|
12959
13055
|
const out = await proposeSensor(
|
|
12960
13056
|
{
|
|
12961
13057
|
memory_id: id,
|
|
@@ -12976,6 +13072,11 @@ function registerSensors(program2) {
|
|
|
12976
13072
|
},
|
|
12977
13073
|
{ paths: resolveHaivePaths36(root2) }
|
|
12978
13074
|
);
|
|
13075
|
+
if (opts.json) {
|
|
13076
|
+
console.log(JSON.stringify(out, null, 2));
|
|
13077
|
+
if (!out.accepted) process.exitCode = 1;
|
|
13078
|
+
return;
|
|
13079
|
+
}
|
|
12979
13080
|
if (out.accepted) {
|
|
12980
13081
|
ui.success(`${opts.kind === "ast" ? "AST" : "Command"} sensor accepted (${out.severity}) on ${id}`);
|
|
12981
13082
|
ui.info(` ${out.guidance}`);
|
|
@@ -12987,8 +13088,7 @@ function registerSensors(program2) {
|
|
|
12987
13088
|
return;
|
|
12988
13089
|
}
|
|
12989
13090
|
if (!opts.pattern?.trim()) {
|
|
12990
|
-
|
|
12991
|
-
process.exitCode = 1;
|
|
13091
|
+
rejectProposal(opts, "missing-pattern", "kind=regex requires --pattern.");
|
|
12992
13092
|
return;
|
|
12993
13093
|
}
|
|
12994
13094
|
const severity = opts.severity === "warn" ? "warn" : "block";
|
|
@@ -12996,8 +13096,7 @@ function registerSensors(program2) {
|
|
|
12996
13096
|
new RegExp(opts.pattern, opts.flags ?? "");
|
|
12997
13097
|
if (opts.absent) new RegExp(opts.absent, opts.flags ?? "");
|
|
12998
13098
|
} catch (err) {
|
|
12999
|
-
|
|
13000
|
-
process.exitCode = 1;
|
|
13099
|
+
rejectProposal(opts, "invalid-regex", `Invalid regex: ${String(err)}`);
|
|
13001
13100
|
return;
|
|
13002
13101
|
}
|
|
13003
13102
|
const root = findProjectRoot39(opts.dir);
|
|
@@ -13005,8 +13104,7 @@ function registerSensors(program2) {
|
|
|
13005
13104
|
const loaded = existsSync44(paths.memoriesDir) ? await loadMemoriesFromDir16(paths.memoriesDir) : [];
|
|
13006
13105
|
const found = loaded.find(({ memory: memory2 }) => memory2.frontmatter.id === id);
|
|
13007
13106
|
if (!found) {
|
|
13008
|
-
|
|
13009
|
-
process.exitCode = 1;
|
|
13107
|
+
rejectProposal(opts, "memory-not-found", `No memory found with id ${id}`);
|
|
13010
13108
|
return;
|
|
13011
13109
|
}
|
|
13012
13110
|
const anchorPaths = opts.paths ? opts.paths.split(",").map((s) => s.trim()).filter(Boolean) : found.memory.frontmatter.anchor.paths;
|
|
@@ -13028,6 +13126,18 @@ function registerSensors(program2) {
|
|
|
13028
13126
|
last_fired: null
|
|
13029
13127
|
};
|
|
13030
13128
|
const verdict = judgeProposedSensor(sensor, { currentTargets, badExamples });
|
|
13129
|
+
if (opts.json && !verdict.accepted) {
|
|
13130
|
+
console.log(JSON.stringify({
|
|
13131
|
+
accepted: verdict.accepted,
|
|
13132
|
+
reason: verdict.reason ?? null,
|
|
13133
|
+
severity,
|
|
13134
|
+
memory_id: id,
|
|
13135
|
+
self_check: verdict.self_check,
|
|
13136
|
+
brittle: verdict.brittle
|
|
13137
|
+
}, null, 2));
|
|
13138
|
+
if (!verdict.accepted) process.exitCode = 1;
|
|
13139
|
+
return;
|
|
13140
|
+
}
|
|
13031
13141
|
if (!verdict.accepted) {
|
|
13032
13142
|
ui.error(`Rejected (${verdict.reason}).`);
|
|
13033
13143
|
if (verdict.reason === "fires-on-current") {
|
|
@@ -13041,6 +13151,17 @@ function registerSensors(program2) {
|
|
|
13041
13151
|
return;
|
|
13042
13152
|
}
|
|
13043
13153
|
await writeFile27(found.filePath, serializeMemory15({ frontmatter: { ...found.memory.frontmatter, sensor }, body: found.memory.body }), "utf8");
|
|
13154
|
+
if (opts.json) {
|
|
13155
|
+
console.log(JSON.stringify({
|
|
13156
|
+
accepted: true,
|
|
13157
|
+
reason: null,
|
|
13158
|
+
severity,
|
|
13159
|
+
memory_id: id,
|
|
13160
|
+
self_check: verdict.self_check,
|
|
13161
|
+
brittle: verdict.brittle
|
|
13162
|
+
}, null, 2));
|
|
13163
|
+
return;
|
|
13164
|
+
}
|
|
13044
13165
|
ui.success(`Sensor accepted (${severity}) on ${id}`);
|
|
13045
13166
|
ui.info(`pattern=${JSON.stringify(opts.pattern)}${opts.absent ? ` absent=${JSON.stringify(opts.absent)}` : ""}`);
|
|
13046
13167
|
ui.info(
|
|
@@ -13961,7 +14082,7 @@ function registerBridges(program2) {
|
|
|
13961
14082
|
|
|
13962
14083
|
// src/index.ts
|
|
13963
14084
|
var program = new Command48();
|
|
13964
|
-
program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.
|
|
14085
|
+
program.name("hivelore").description("Hivelore - the deterministic policy gate for agent-written code (rules live as repo-native team memory)").version("0.44.0").option("--advanced", "show maintenance and experimental commands in help").showSuggestionAfterError(true);
|
|
13965
14086
|
registerInit(program);
|
|
13966
14087
|
registerResolveProject(program);
|
|
13967
14088
|
registerEnforce(program);
|