@hiveai/cli 0.9.18 → 0.9.19
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 +100 -22
- package/dist/index.js.map +1 -1
- package/package.json +4 -11
package/dist/index.js
CHANGED
|
@@ -6515,7 +6515,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
6515
6515
|
};
|
|
6516
6516
|
}
|
|
6517
6517
|
var SERVER_NAME = "haive";
|
|
6518
|
-
var SERVER_VERSION = "0.9.
|
|
6518
|
+
var SERVER_VERSION = "0.9.19";
|
|
6519
6519
|
function jsonResult(data) {
|
|
6520
6520
|
return {
|
|
6521
6521
|
content: [
|
|
@@ -6535,6 +6535,7 @@ var ENFORCEMENT_PROFILE_TOOLS = [
|
|
|
6535
6535
|
"mem_verify",
|
|
6536
6536
|
"mem_relevant_to",
|
|
6537
6537
|
"code_map",
|
|
6538
|
+
"code_search",
|
|
6538
6539
|
"pre_commit_check",
|
|
6539
6540
|
"mem_session_end"
|
|
6540
6541
|
];
|
|
@@ -11145,6 +11146,7 @@ import {
|
|
|
11145
11146
|
aggregateUsage as aggregateUsage2,
|
|
11146
11147
|
buildFrontmatter as buildFrontmatter11,
|
|
11147
11148
|
findProjectRoot as findProjectRoot39,
|
|
11149
|
+
loadConfig as loadConfig9,
|
|
11148
11150
|
loadMemoriesFromDir as loadMemoriesFromDir31,
|
|
11149
11151
|
memoryFilePath as memoryFilePath10,
|
|
11150
11152
|
parseSince as parseSince2,
|
|
@@ -11158,10 +11160,14 @@ var SEARCH_TOOLS = /* @__PURE__ */ new Set([
|
|
|
11158
11160
|
"mem_relevant_to",
|
|
11159
11161
|
"get_briefing"
|
|
11160
11162
|
]);
|
|
11163
|
+
var SYNTHETIC_QUERY_RE = /\b(auto-promote-marker|local enforcement smoke|cli-test-session)\b/i;
|
|
11164
|
+
function isSyntheticSuggestionQuery(query) {
|
|
11165
|
+
return SYNTHETIC_QUERY_RE.test(query);
|
|
11166
|
+
}
|
|
11161
11167
|
function registerMemorySuggest(memory2) {
|
|
11162
11168
|
memory2.command("suggest").description(
|
|
11163
|
-
"Suggest memories to create based on recurring search queries in the usage log.\n\n Use --auto-save to
|
|
11164
|
-
).option("--since <window>", "ISO date or relative (e.g. '7d', '24h')", "30d").option("--min <count>", "minimum repeat count to surface a query", "2").option("--top-n <n>", "with --auto-save, draft this many top suggestions", "3").option("--scope <scope>", "with --auto-save, scope of
|
|
11169
|
+
"Suggest memories to create based on recurring search queries in the usage log.\n\n Use --auto-save to save the top-N suggestions using the project defaults.\n In autopilot, suggestions land as validated team records; in manual mode they stay draft."
|
|
11170
|
+
).option("--since <window>", "ISO date or relative (e.g. '7d', '24h')", "30d").option("--min <count>", "minimum repeat count to surface a query", "2").option("--top-n <n>", "with --auto-save, draft this many top suggestions", "3").option("--scope <scope>", "with --auto-save, scope of saved memories (personal | team; default: config default)").option("--auto-save", "save top-N suggestions as memories on disk", false).option("--json", "emit JSON instead of human-readable output", false).option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
11165
11171
|
const root = findProjectRoot39(opts.dir);
|
|
11166
11172
|
const paths = resolveHaivePaths35(root);
|
|
11167
11173
|
const events = await readUsageEvents3(paths);
|
|
@@ -11182,6 +11188,7 @@ function registerMemorySuggest(memory2) {
|
|
|
11182
11188
|
if (!SEARCH_TOOLS.has(e.tool)) continue;
|
|
11183
11189
|
const key = (e.summary ?? "").toLowerCase().trim();
|
|
11184
11190
|
if (!key) continue;
|
|
11191
|
+
if (isSyntheticSuggestionQuery(key)) continue;
|
|
11185
11192
|
const prior = queries.get(key);
|
|
11186
11193
|
if (prior) {
|
|
11187
11194
|
prior.count++;
|
|
@@ -11200,11 +11207,13 @@ function registerMemorySuggest(memory2) {
|
|
|
11200
11207
|
inferred_type: inferType(v.tools, query)
|
|
11201
11208
|
})).sort((a, b) => b.count - a.count);
|
|
11202
11209
|
if (opts.autoSave) {
|
|
11210
|
+
const config = await loadConfig9(paths);
|
|
11203
11211
|
const topN = Math.max(1, parseInt(opts.topN ?? "3", 10));
|
|
11204
|
-
const scope = opts.scope === "
|
|
11212
|
+
const scope = opts.scope === "personal" || opts.scope === "team" ? opts.scope : config.defaultScope ?? "personal";
|
|
11213
|
+
const status = config.defaultStatus === "validated" ? "validated" : "draft";
|
|
11205
11214
|
const top = suggestions.slice(0, topN);
|
|
11206
11215
|
if (top.length === 0) {
|
|
11207
|
-
ui.warn(`No suggestions met --min=${minCount} \u2014 nothing to
|
|
11216
|
+
ui.warn(`No suggestions met --min=${minCount} \u2014 nothing to save.`);
|
|
11208
11217
|
return;
|
|
11209
11218
|
}
|
|
11210
11219
|
const created = [];
|
|
@@ -11227,10 +11236,10 @@ function registerMemorySuggest(memory2) {
|
|
|
11227
11236
|
scope,
|
|
11228
11237
|
tags: ["auto-suggested", ...s.tools],
|
|
11229
11238
|
paths: [],
|
|
11230
|
-
symbols: []
|
|
11239
|
+
symbols: [],
|
|
11240
|
+
status
|
|
11231
11241
|
});
|
|
11232
|
-
fm.status
|
|
11233
|
-
const body = renderTemplate(s);
|
|
11242
|
+
const body = renderTemplate(s, fm.id, status);
|
|
11234
11243
|
const file = memoryFilePath10(paths, fm.scope, fm.id, fm.module);
|
|
11235
11244
|
await mkdir18(path41.dirname(file), { recursive: true });
|
|
11236
11245
|
if (existsSync60(file)) {
|
|
@@ -11245,7 +11254,7 @@ function registerMemorySuggest(memory2) {
|
|
|
11245
11254
|
return;
|
|
11246
11255
|
}
|
|
11247
11256
|
for (const c of created) {
|
|
11248
|
-
ui.success(
|
|
11257
|
+
ui.success(`${status === "validated" ? "Saved" : "Drafted"} ${c.id} \u2192 ${c.file}`);
|
|
11249
11258
|
console.log(` ${ui.dim("from query:")} ${truncate2(c.query, 60)}`);
|
|
11250
11259
|
}
|
|
11251
11260
|
for (const s of skipped) {
|
|
@@ -11253,7 +11262,11 @@ function registerMemorySuggest(memory2) {
|
|
|
11253
11262
|
}
|
|
11254
11263
|
if (created.length > 0) {
|
|
11255
11264
|
console.log();
|
|
11256
|
-
|
|
11265
|
+
if (status === "validated") {
|
|
11266
|
+
ui.info("Autopilot defaults applied: suggestions are status=validated and active.");
|
|
11267
|
+
} else {
|
|
11268
|
+
ui.info("Drafts are status=draft \u2014 edit them, then run `haive memory promote <id>`.");
|
|
11269
|
+
}
|
|
11257
11270
|
}
|
|
11258
11271
|
return;
|
|
11259
11272
|
}
|
|
@@ -11278,7 +11291,7 @@ function registerMemorySuggest(memory2) {
|
|
|
11278
11291
|
console.log(` ${ui.dim("\u2192")} ${s.reason}`);
|
|
11279
11292
|
}
|
|
11280
11293
|
console.log();
|
|
11281
|
-
ui.info("Run with --auto-save to
|
|
11294
|
+
ui.info("Run with --auto-save to save the top-3 using the project defaults.");
|
|
11282
11295
|
});
|
|
11283
11296
|
}
|
|
11284
11297
|
function chooseReason(tools, count) {
|
|
@@ -11299,7 +11312,8 @@ function inferType(tools, query) {
|
|
|
11299
11312
|
}
|
|
11300
11313
|
return "convention";
|
|
11301
11314
|
}
|
|
11302
|
-
function renderTemplate(s) {
|
|
11315
|
+
function renderTemplate(s, id, status) {
|
|
11316
|
+
const nextStep = status === "validated" ? `This record is already active because project autopilot defaults set status=validated. Replace the template body with the actual answer when known.` : `Then run \`haive memory promote ${id}\` to move it into team review.`;
|
|
11303
11317
|
return [
|
|
11304
11318
|
`# Auto-drafted from recurring searches`,
|
|
11305
11319
|
``,
|
|
@@ -11319,7 +11333,7 @@ function renderTemplate(s) {
|
|
|
11319
11333
|
`- **Why** \u2014 the rationale or root cause`,
|
|
11320
11334
|
`- **How to apply** \u2014 what an agent should do when this comes up again`,
|
|
11321
11335
|
``,
|
|
11322
|
-
|
|
11336
|
+
nextStep
|
|
11323
11337
|
].join("\n");
|
|
11324
11338
|
}
|
|
11325
11339
|
function slugify(s) {
|
|
@@ -11455,7 +11469,7 @@ import {
|
|
|
11455
11469
|
findProjectRoot as findProjectRoot41,
|
|
11456
11470
|
getUsage as getUsage20,
|
|
11457
11471
|
loadCodeMap as loadCodeMap7,
|
|
11458
|
-
loadConfig as
|
|
11472
|
+
loadConfig as loadConfig10,
|
|
11459
11473
|
loadMemoriesFromDir as loadMemoriesFromDir33,
|
|
11460
11474
|
loadUsageIndex as loadUsageIndex26,
|
|
11461
11475
|
readUsageEvents as readUsageEvents4,
|
|
@@ -11470,6 +11484,7 @@ function registerDoctor(program2) {
|
|
|
11470
11484
|
const paths = resolveHaivePaths37(root);
|
|
11471
11485
|
const findings = [];
|
|
11472
11486
|
const repairs = [];
|
|
11487
|
+
const config = await loadConfig10(paths);
|
|
11473
11488
|
if (!existsSync63(paths.haiveDir)) {
|
|
11474
11489
|
findings.push({
|
|
11475
11490
|
severity: "error",
|
|
@@ -11573,6 +11588,18 @@ function registerDoctor(program2) {
|
|
|
11573
11588
|
});
|
|
11574
11589
|
}
|
|
11575
11590
|
}
|
|
11591
|
+
const lintReport = await lintMemoriesAsync(root);
|
|
11592
|
+
if (lintReport.findings.length > 0) {
|
|
11593
|
+
const warnCount = lintReport.findings.filter((finding) => finding.severity === "warn").length;
|
|
11594
|
+
const errorCount = lintReport.findings.filter((finding) => finding.severity === "error").length;
|
|
11595
|
+
const severity = errorCount > 0 ? "error" : warnCount > 0 ? "warn" : "info";
|
|
11596
|
+
findings.push({
|
|
11597
|
+
severity,
|
|
11598
|
+
code: "memory-lint-findings",
|
|
11599
|
+
message: `memory lint reports ${lintReport.findings.length} finding${lintReport.findings.length === 1 ? "" : "s"} (${errorCount} error, ${warnCount} warn, ${lintReport.findings.length - errorCount - warnCount} info).`,
|
|
11600
|
+
fix: "haive memory lint --fix --apply"
|
|
11601
|
+
});
|
|
11602
|
+
}
|
|
11576
11603
|
const codeMap = await loadCodeMap7(paths);
|
|
11577
11604
|
if (!codeMap) {
|
|
11578
11605
|
findings.push({
|
|
@@ -11594,6 +11621,7 @@ function registerDoctor(program2) {
|
|
|
11594
11621
|
});
|
|
11595
11622
|
}
|
|
11596
11623
|
}
|
|
11624
|
+
findings.push(...await collectSemanticIndexFindings(paths, config, memories.length, codeMap));
|
|
11597
11625
|
const events = await readUsageEvents4(paths);
|
|
11598
11626
|
if (events.length === 0) {
|
|
11599
11627
|
findings.push({
|
|
@@ -11607,6 +11635,7 @@ function registerDoctor(program2) {
|
|
|
11607
11635
|
if (!isSearchTool(e.tool)) continue;
|
|
11608
11636
|
const key = (e.summary ?? "").toLowerCase().trim();
|
|
11609
11637
|
if (!key) continue;
|
|
11638
|
+
if (isSyntheticSuggestionQuery(key)) continue;
|
|
11610
11639
|
queryRepeats.set(key, (queryRepeats.get(key) ?? 0) + 1);
|
|
11611
11640
|
}
|
|
11612
11641
|
const repeated = [...queryRepeats.entries()].filter(([, n]) => n >= 3);
|
|
@@ -11628,7 +11657,6 @@ function registerDoctor(program2) {
|
|
|
11628
11657
|
});
|
|
11629
11658
|
}
|
|
11630
11659
|
}
|
|
11631
|
-
const config = await loadConfig9(paths);
|
|
11632
11660
|
if (config.enforcement?.requireBriefingFirst) {
|
|
11633
11661
|
const claudeSettings = path44.join(root, ".claude", "settings.local.json");
|
|
11634
11662
|
let hasClaudeEnforcement = false;
|
|
@@ -11658,14 +11686,14 @@ function registerDoctor(program2) {
|
|
|
11658
11686
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
|
|
11659
11687
|
});
|
|
11660
11688
|
}
|
|
11661
|
-
findings.push(...await collectInstallFindings(root, "0.9.
|
|
11689
|
+
findings.push(...await collectInstallFindings(root, "0.9.19"));
|
|
11662
11690
|
try {
|
|
11663
11691
|
const legacyRaw = execSync3("haive-mcp --version", {
|
|
11664
11692
|
encoding: "utf8",
|
|
11665
11693
|
timeout: 3e3,
|
|
11666
11694
|
stdio: ["ignore", "pipe", "ignore"]
|
|
11667
11695
|
}).trim();
|
|
11668
|
-
const cliVersion = "0.9.
|
|
11696
|
+
const cliVersion = "0.9.19";
|
|
11669
11697
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
11670
11698
|
findings.push({
|
|
11671
11699
|
severity: "warn",
|
|
@@ -11795,6 +11823,56 @@ function groupBySection(findings) {
|
|
|
11795
11823
|
function nextActions(findings) {
|
|
11796
11824
|
return [...new Set(findings.flatMap((finding) => finding.fix ? finding.fix.split("\n") : []))].filter(Boolean);
|
|
11797
11825
|
}
|
|
11826
|
+
async function collectSemanticIndexFindings(paths, config, memoryCount, codeMap) {
|
|
11827
|
+
const findings = [];
|
|
11828
|
+
const autoWantsCodeSearch = Boolean(config.autopilot || config.autoRepair?.codeSearch);
|
|
11829
|
+
let mod;
|
|
11830
|
+
try {
|
|
11831
|
+
mod = await import("@hiveai/embeddings");
|
|
11832
|
+
} catch {
|
|
11833
|
+
findings.push({
|
|
11834
|
+
severity: autoWantsCodeSearch ? "warn" : "info",
|
|
11835
|
+
code: "embeddings-unavailable",
|
|
11836
|
+
message: "@hiveai/embeddings is not available, so get_briefing falls back to lexical ranking and code_search cannot run.",
|
|
11837
|
+
fix: "npm install -g @hiveai/cli@latest\nhaive embeddings status",
|
|
11838
|
+
section: "Index health"
|
|
11839
|
+
});
|
|
11840
|
+
return findings;
|
|
11841
|
+
}
|
|
11842
|
+
if (memoryCount > 0) {
|
|
11843
|
+
const stat2 = await mod.indexStat(paths).catch(() => ({ exists: false, count: 0 }));
|
|
11844
|
+
if (!stat2.exists || stat2.count === 0) {
|
|
11845
|
+
findings.push({
|
|
11846
|
+
severity: "warn",
|
|
11847
|
+
code: "semantic-memory-index-missing",
|
|
11848
|
+
message: "Memory embeddings index is missing or empty; get_briefing will report literal_fallback instead of semantic ranking.",
|
|
11849
|
+
fix: "haive embeddings index",
|
|
11850
|
+
section: "Index health"
|
|
11851
|
+
});
|
|
11852
|
+
}
|
|
11853
|
+
}
|
|
11854
|
+
if (autoWantsCodeSearch || codeMap) {
|
|
11855
|
+
const codeIndex = await mod.loadCodeIndex(paths).catch(() => null);
|
|
11856
|
+
if (!codeIndex || codeIndex.entries.length === 0) {
|
|
11857
|
+
findings.push({
|
|
11858
|
+
severity: autoWantsCodeSearch ? "warn" : "info",
|
|
11859
|
+
code: "code-search-index-missing",
|
|
11860
|
+
message: "Code-search embeddings index is missing or empty; MCP code_search is unavailable until it is built.",
|
|
11861
|
+
fix: "haive index code-search",
|
|
11862
|
+
section: "Index health"
|
|
11863
|
+
});
|
|
11864
|
+
} else if (codeMap && codeIndex.source_generated_at !== codeMap.generated_at) {
|
|
11865
|
+
findings.push({
|
|
11866
|
+
severity: "info",
|
|
11867
|
+
code: "code-search-index-outdated",
|
|
11868
|
+
message: "Code-search embeddings index was built from an older code-map; semantic code search may miss recent symbols.",
|
|
11869
|
+
fix: "haive index code-search",
|
|
11870
|
+
section: "Index health"
|
|
11871
|
+
});
|
|
11872
|
+
}
|
|
11873
|
+
}
|
|
11874
|
+
return findings;
|
|
11875
|
+
}
|
|
11798
11876
|
function isSearchTool(name) {
|
|
11799
11877
|
return ["mem_search", "code_search", "mem_relevant_to", "get_briefing"].includes(name);
|
|
11800
11878
|
}
|
|
@@ -12381,7 +12459,7 @@ import {
|
|
|
12381
12459
|
findProjectRoot as findProjectRoot48,
|
|
12382
12460
|
hasRecentBriefingMarker,
|
|
12383
12461
|
isFreshIsoDate,
|
|
12384
|
-
loadConfig as
|
|
12462
|
+
loadConfig as loadConfig11,
|
|
12385
12463
|
loadMemoriesFromDir as loadMemoriesFromDir36,
|
|
12386
12464
|
memoryMatchesAnchorPaths as memoryMatchesAnchorPaths6,
|
|
12387
12465
|
readRecentBriefingMarker,
|
|
@@ -12402,7 +12480,7 @@ function registerEnforce(program2) {
|
|
|
12402
12480
|
const root = findProjectRoot48(opts.dir);
|
|
12403
12481
|
const paths = resolveHaivePaths44(root);
|
|
12404
12482
|
await mkdir19(paths.haiveDir, { recursive: true });
|
|
12405
|
-
const current = await
|
|
12483
|
+
const current = await loadConfig11(paths);
|
|
12406
12484
|
await saveConfig4(paths, {
|
|
12407
12485
|
...current,
|
|
12408
12486
|
enforcement: {
|
|
@@ -12651,7 +12729,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
12651
12729
|
const root = findProjectRoot48(dir);
|
|
12652
12730
|
const paths = resolveHaivePaths44(root);
|
|
12653
12731
|
const initialized = existsSync69(paths.haiveDir);
|
|
12654
|
-
const config = initialized ? await
|
|
12732
|
+
const config = initialized ? await loadConfig11(paths) : {};
|
|
12655
12733
|
const mode = config.enforcement?.mode ?? "strict";
|
|
12656
12734
|
const findings = [];
|
|
12657
12735
|
if (!initialized) {
|
|
@@ -12680,7 +12758,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
12680
12758
|
findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
|
|
12681
12759
|
});
|
|
12682
12760
|
}
|
|
12683
|
-
findings.push(...await inspectIntegrationVersions(root, "0.9.
|
|
12761
|
+
findings.push(...await inspectIntegrationVersions(root, "0.9.19"));
|
|
12684
12762
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
12685
12763
|
const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
|
|
12686
12764
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
|
|
@@ -13168,7 +13246,7 @@ function registerRun(program2) {
|
|
|
13168
13246
|
|
|
13169
13247
|
// src/index.ts
|
|
13170
13248
|
var program = new Command51();
|
|
13171
|
-
program.name("haive").description("hAIve \u2014 policy enforcement layer for AI coding agents").version("0.9.
|
|
13249
|
+
program.name("haive").description("hAIve \u2014 policy enforcement layer for AI coding agents").version("0.9.19").option("--advanced", "show maintenance and experimental commands in help");
|
|
13172
13250
|
registerInit(program);
|
|
13173
13251
|
registerWelcome(program);
|
|
13174
13252
|
registerResolveProject(program);
|