@hiveai/cli 0.15.0 → 0.17.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/index.js +96 -49
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -9,9 +9,10 @@ import { mkdir, readFile as readFile2 } from "fs/promises";
|
|
|
9
9
|
import path3 from "path";
|
|
10
10
|
import "commander";
|
|
11
11
|
import {
|
|
12
|
+
classifyMemoryPriority,
|
|
13
|
+
compactAutoRecapBody,
|
|
12
14
|
extractActionsBriefBody,
|
|
13
15
|
findProjectRoot as findProjectRoot2,
|
|
14
|
-
isStackPackSeed,
|
|
15
16
|
literalMatchesAllTokens,
|
|
16
17
|
literalMatchesAnyToken,
|
|
17
18
|
loadCodeMap as loadCodeMap3,
|
|
@@ -954,7 +955,7 @@ function registerBriefing(program2) {
|
|
|
954
955
|
out(`${ui.bold("=== Last Session Recap ===")}
|
|
955
956
|
`);
|
|
956
957
|
out(ui.dim(`${fm.id} (${fm.scope}${rev})`));
|
|
957
|
-
out(recap.memory.body.trim());
|
|
958
|
+
out(compactAutoRecapBody(recap.memory.body).trim());
|
|
958
959
|
out("");
|
|
959
960
|
}
|
|
960
961
|
if (existsSync3(paths.projectContext) && !stopped()) {
|
|
@@ -1124,12 +1125,19 @@ ${ui.bold("=== Symbol Locations ===")}
|
|
|
1124
1125
|
function classifyCliPriority(item, filePaths, tokens, exactTaskHit, partialTaskHit) {
|
|
1125
1126
|
const fm = item.memory.frontmatter;
|
|
1126
1127
|
const anchored = filePaths.length > 0 && memoryMatchesAnchorPaths(item.memory, filePaths);
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1128
|
+
return classifyMemoryPriority({
|
|
1129
|
+
type: fm.type,
|
|
1130
|
+
tags: fm.tags,
|
|
1131
|
+
requiresHumanApproval: Boolean(fm.requires_human_approval),
|
|
1132
|
+
directAnchor: anchored,
|
|
1133
|
+
directSymbol: false,
|
|
1134
|
+
// symbol lookup is rendered separately in the CLI, not via anchor priority
|
|
1135
|
+
exactTaskMatch: exactTaskHit,
|
|
1136
|
+
strongSemantic: false,
|
|
1137
|
+
usefulSemantic: partialTaskHit || item.score >= 4,
|
|
1138
|
+
moduleOrDomainMatch: false,
|
|
1139
|
+
tagTaskMatch: Boolean(tokens && fm.tags.some((tag) => tokens.includes(tag)))
|
|
1140
|
+
});
|
|
1133
1141
|
}
|
|
1134
1142
|
function priorityBadge(priority) {
|
|
1135
1143
|
if (priority === "must_read") return ui.red("[must_read]");
|
|
@@ -3019,7 +3027,7 @@ ${SEED_FOOTER(stack)}` });
|
|
|
3019
3027
|
}
|
|
3020
3028
|
|
|
3021
3029
|
// src/commands/init.ts
|
|
3022
|
-
var HAIVE_GITHUB_ACTION_REF = `v${"0.
|
|
3030
|
+
var HAIVE_GITHUB_ACTION_REF = `v${"0.17.0"}`;
|
|
3023
3031
|
var PROJECT_CONTEXT_TEMPLATE = `# Project context
|
|
3024
3032
|
|
|
3025
3033
|
> Generated by \`haive init\`. Run \`haive init --bootstrap\` to auto-fill from your codebase,
|
|
@@ -3834,14 +3842,21 @@ async function readStdin(maxBytes) {
|
|
|
3834
3842
|
setTimeout(finish, 2e3);
|
|
3835
3843
|
});
|
|
3836
3844
|
}
|
|
3845
|
+
function isExpectedNonzeroExit(command) {
|
|
3846
|
+
if (!command) return false;
|
|
3847
|
+
if (command.includes("|")) return true;
|
|
3848
|
+
if (/\|\|\s*true\b/.test(command)) return true;
|
|
3849
|
+
return /(^|\s|;|&&)(grep|egrep|fgrep|rg|ag|find|test|diff|\[\[?)\b/.test(command);
|
|
3850
|
+
}
|
|
3837
3851
|
function detectFailure(payload) {
|
|
3838
3852
|
const response = payload.tool_response;
|
|
3839
3853
|
if (!response) return false;
|
|
3840
3854
|
const responseText = typeof response === "string" ? response : JSON.stringify(response);
|
|
3841
3855
|
if (payload.tool_name === "Bash") {
|
|
3856
|
+
const command = typeof payload.tool_input?.["command"] === "string" ? payload.tool_input["command"] : "";
|
|
3842
3857
|
if (typeof response === "object") {
|
|
3843
3858
|
const code = response["exit_code"] ?? response["exitCode"];
|
|
3844
|
-
if (typeof code === "number" && code !== 0) return true;
|
|
3859
|
+
if (typeof code === "number" && code !== 0 && !isExpectedNonzeroExit(command)) return true;
|
|
3845
3860
|
}
|
|
3846
3861
|
if (/\b(command not found|No such file or directory|ERR_MODULE_NOT_FOUND|ENOENT|EACCES)\b/.test(responseText)) return true;
|
|
3847
3862
|
if (/\berror TS\d+:/i.test(responseText)) return true;
|
|
@@ -4083,6 +4098,7 @@ import {
|
|
|
4083
4098
|
deriveConfidence as deriveConfidence4,
|
|
4084
4099
|
estimateTokens,
|
|
4085
4100
|
evaluateSkillActivation,
|
|
4101
|
+
compactAutoRecapBody as compactAutoRecapBody2,
|
|
4086
4102
|
extractActionsBriefBody as extractActionsBriefBody2,
|
|
4087
4103
|
getUsage as getUsage6,
|
|
4088
4104
|
inferModulesFromPaths as inferModulesFromPaths2,
|
|
@@ -4114,7 +4130,12 @@ import { z as z19 } from "zod";
|
|
|
4114
4130
|
import { readdir as readdir3, readFile as readFile42 } from "fs/promises";
|
|
4115
4131
|
import { existsSync as existsSync20 } from "fs";
|
|
4116
4132
|
import path102 from "path";
|
|
4117
|
-
import {
|
|
4133
|
+
import {
|
|
4134
|
+
classifyMemoryPriority as coreClassifyPriority,
|
|
4135
|
+
isGlobPath,
|
|
4136
|
+
pathsOverlap,
|
|
4137
|
+
priorityRank as corePriorityRank
|
|
4138
|
+
} from "@hiveai/core";
|
|
4118
4139
|
import { estimateTokens as estimateTokens2, loadCodeMap as loadCodeMap22, queryCodeMap as queryCodeMap22 } from "@hiveai/core";
|
|
4119
4140
|
import { z as z20 } from "zod";
|
|
4120
4141
|
import { existsSync as existsSync222 } from "fs";
|
|
@@ -5577,7 +5598,7 @@ function compactSummary(body) {
|
|
|
5577
5598
|
}
|
|
5578
5599
|
return body.slice(0, 120);
|
|
5579
5600
|
}
|
|
5580
|
-
function
|
|
5601
|
+
function classifyMemoryPriority2(memory2, loaded, inputFiles, inputSymbols) {
|
|
5581
5602
|
const fm = loaded?.memory.frontmatter;
|
|
5582
5603
|
const directAnchor = Boolean(
|
|
5583
5604
|
fm && inputFiles.length > 0 && fm.anchor.paths.some((p) => inputFiles.some((file) => pathsOverlap(p, file)))
|
|
@@ -5587,21 +5608,23 @@ function classifyMemoryPriority(memory2, loaded, inputFiles, inputSymbols) {
|
|
|
5587
5608
|
(sym) => inputSymbols.some((wanted) => wanted.toLowerCase() === sym.toLowerCase())
|
|
5588
5609
|
)
|
|
5589
5610
|
);
|
|
5590
|
-
const
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5611
|
+
const semantic = memory2.semantic_score ?? 0;
|
|
5612
|
+
return coreClassifyPriority({
|
|
5613
|
+
type: memory2.type,
|
|
5614
|
+
tags: fm?.tags ?? memory2.tags ?? [],
|
|
5615
|
+
requiresHumanApproval: Boolean(fm?.requires_human_approval),
|
|
5616
|
+
directAnchor,
|
|
5617
|
+
directSymbol,
|
|
5618
|
+
exactTaskMatch: memory2.match_quality === "exact",
|
|
5619
|
+
strongSemantic: semantic >= 0.65,
|
|
5620
|
+
usefulSemantic: semantic >= 0.35,
|
|
5621
|
+
moduleOrDomainMatch: memory2.reasons.includes("module") || memory2.reasons.includes("domain"),
|
|
5622
|
+
tagTaskMatch: false
|
|
5623
|
+
// MCP ranking doesn't use a separate tag-token signal
|
|
5624
|
+
});
|
|
5602
5625
|
}
|
|
5603
5626
|
function priorityRank(priority) {
|
|
5604
|
-
return priority
|
|
5627
|
+
return corePriorityRank(priority);
|
|
5605
5628
|
}
|
|
5606
5629
|
function classifyBriefingQuality(memories, context) {
|
|
5607
5630
|
const mustRead = memories.filter((m) => m.priority === "must_read").length;
|
|
@@ -5768,7 +5791,9 @@ async function getBriefing(input, ctx) {
|
|
|
5768
5791
|
id: fm.id,
|
|
5769
5792
|
scope: fm.scope,
|
|
5770
5793
|
revision_count: fm.revision_count ?? 0,
|
|
5771
|
-
|
|
5794
|
+
// Auto-generated recaps are low-signal tool dumps — compact them so they inform without
|
|
5795
|
+
// dominating the briefing head. Human/post_task recaps pass through unchanged.
|
|
5796
|
+
body: compactAutoRecapBody2(r.memory.body)
|
|
5772
5797
|
};
|
|
5773
5798
|
}
|
|
5774
5799
|
const allMemories = allLoaded.filter(({ memory: memory2 }) => {
|
|
@@ -5890,8 +5915,8 @@ async function getBriefing(input, ctx) {
|
|
|
5890
5915
|
const impactScore = (m) => (m.impact_score ?? 0) * 3;
|
|
5891
5916
|
const activationBoost = (m) => activatedSkills.has(m.id) ? 5 : 0;
|
|
5892
5917
|
const lexScore = (m) => 12 * (lexNorm.get(m.id) ?? 0);
|
|
5893
|
-
const sa = priorityRank(
|
|
5894
|
-
const sb = priorityRank(
|
|
5918
|
+
const sa = priorityRank(classifyMemoryPriority2(a, byId.get(a.id), input.files, input.symbols)) * 100 + reasonScore(a) + confidenceScore(a) + impactScore(a) + activationBoost(a) + lexScore(a) + (a.semantic_score ?? 0);
|
|
5919
|
+
const sb = priorityRank(classifyMemoryPriority2(b, byId.get(b.id), input.files, input.symbols)) * 100 + reasonScore(b) + confidenceScore(b) + impactScore(b) + activationBoost(b) + lexScore(b) + (b.semantic_score ?? 0);
|
|
5895
5920
|
return sb - sa;
|
|
5896
5921
|
});
|
|
5897
5922
|
for (const mem of ranked.slice(0, briefingMaxMemories)) {
|
|
@@ -6047,7 +6072,7 @@ ${m.content}`).join("\n\n---\n\n"),
|
|
|
6047
6072
|
const formattedMemories = input.format === "compact" ? trimmedMemories.map((m) => ({ ...m, body: compactSummary(m.body) })) : input.format === "actions" ? trimmedMemories.map((m) => ({ ...m, body: extractActionsBriefBody2(m.body) })) : trimmedMemories;
|
|
6048
6073
|
const outputMemories = formattedMemories.map((m) => ({
|
|
6049
6074
|
...m,
|
|
6050
|
-
priority:
|
|
6075
|
+
priority: classifyMemoryPriority2(m, byId.get(m.id), input.files, input.symbols),
|
|
6051
6076
|
why: explainWhySurfaced(m, byId.get(m.id), input.files, inferred)
|
|
6052
6077
|
}));
|
|
6053
6078
|
const briefingQuality = classifyBriefingQuality(outputMemories, {
|
|
@@ -6584,6 +6609,27 @@ function tokenizeDiffForLiteral(diff) {
|
|
|
6584
6609
|
const wordTokens = source.toLowerCase().split(/[^a-z0-9]+/).filter((t) => t.length >= 4 && !CODE_STOPWORDS.has(t));
|
|
6585
6610
|
return [.../* @__PURE__ */ new Set([...wsTokens, ...wordTokens])];
|
|
6586
6611
|
}
|
|
6612
|
+
function stripAiDirHunks(diff) {
|
|
6613
|
+
if (!diff.includes("diff --git")) return diff;
|
|
6614
|
+
const out = [];
|
|
6615
|
+
let block = [];
|
|
6616
|
+
let keep = true;
|
|
6617
|
+
const flush = () => {
|
|
6618
|
+
if (keep) out.push(...block);
|
|
6619
|
+
block = [];
|
|
6620
|
+
keep = true;
|
|
6621
|
+
};
|
|
6622
|
+
for (const line of diff.split("\n")) {
|
|
6623
|
+
if (line.startsWith("diff --git ")) {
|
|
6624
|
+
flush();
|
|
6625
|
+
const target = line.match(/ b\/(.+)$/)?.[1] ?? "";
|
|
6626
|
+
keep = !target.startsWith(".ai/");
|
|
6627
|
+
}
|
|
6628
|
+
block.push(line);
|
|
6629
|
+
}
|
|
6630
|
+
flush();
|
|
6631
|
+
return out.join("\n");
|
|
6632
|
+
}
|
|
6587
6633
|
async function antiPatternsCheck(input, ctx) {
|
|
6588
6634
|
if (!input.diff && input.paths.length === 0) {
|
|
6589
6635
|
return {
|
|
@@ -6639,10 +6685,11 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
6639
6685
|
}
|
|
6640
6686
|
}
|
|
6641
6687
|
}
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
const
|
|
6645
|
-
const
|
|
6688
|
+
const scanDiff = input.diff ? stripAiDirHunks(input.diff) : input.diff;
|
|
6689
|
+
if (scanDiff) {
|
|
6690
|
+
const tokens = tokenizeDiffForLiteral(scanDiff);
|
|
6691
|
+
const added = addedLinesFromDiff(scanDiff);
|
|
6692
|
+
const addedText = added.trim().length > 0 ? added : scanDiff;
|
|
6646
6693
|
if (tokens.length > 0) {
|
|
6647
6694
|
for (const { memory: memory2 } of negative) {
|
|
6648
6695
|
if (literalMatchesAnyToken3(memory2, tokens)) {
|
|
@@ -6672,10 +6719,10 @@ async function antiPatternsCheck(input, ctx) {
|
|
|
6672
6719
|
}
|
|
6673
6720
|
}
|
|
6674
6721
|
}
|
|
6675
|
-
if (input.semantic &&
|
|
6722
|
+
if (input.semantic && scanDiff) {
|
|
6676
6723
|
try {
|
|
6677
6724
|
const mod = await import("@hiveai/embeddings");
|
|
6678
|
-
const result = await mod.semanticSearch(ctx.paths,
|
|
6725
|
+
const result = await mod.semanticSearch(ctx.paths, scanDiff, { limit: input.limit * 2 });
|
|
6679
6726
|
if (result) {
|
|
6680
6727
|
const negativeIds = new Set(negative.map(({ memory: memory2 }) => memory2.frontmatter.id));
|
|
6681
6728
|
for (const hit of result.hits) {
|
|
@@ -7962,7 +8009,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
7962
8009
|
};
|
|
7963
8010
|
}
|
|
7964
8011
|
var SERVER_NAME = "haive";
|
|
7965
|
-
var SERVER_VERSION = "0.
|
|
8012
|
+
var SERVER_VERSION = "0.17.0";
|
|
7966
8013
|
function jsonResult(data) {
|
|
7967
8014
|
return {
|
|
7968
8015
|
content: [
|
|
@@ -9005,7 +9052,7 @@ import {
|
|
|
9005
9052
|
getUsage as getUsage11,
|
|
9006
9053
|
isAutoPromoteEligible as isAutoPromoteEligible2,
|
|
9007
9054
|
isDecaying as isDecaying2,
|
|
9008
|
-
isStackPackSeed
|
|
9055
|
+
isStackPackSeed,
|
|
9009
9056
|
loadCodeMap as loadCodeMap6,
|
|
9010
9057
|
loadConfig as loadConfig4,
|
|
9011
9058
|
loadMemoriesFromDir as loadMemoriesFromDir25,
|
|
@@ -9470,7 +9517,7 @@ async function injectBridge(bridgeFile, memoriesDir, maxMemories, root, quiet) {
|
|
|
9470
9517
|
const top = all.filter(({ memory: memory2 }) => {
|
|
9471
9518
|
const s = memory2.frontmatter.status;
|
|
9472
9519
|
if (memory2.frontmatter.type === "session_recap") return false;
|
|
9473
|
-
if (
|
|
9520
|
+
if (isStackPackSeed(memory2.frontmatter)) return false;
|
|
9474
9521
|
return s === "validated" || s === "proposed";
|
|
9475
9522
|
}).sort((a, b) => {
|
|
9476
9523
|
const score = (m) => {
|
|
@@ -13317,7 +13364,7 @@ import {
|
|
|
13317
13364
|
codeMapPath as codeMapPath2,
|
|
13318
13365
|
findProjectRoot as findProjectRoot45,
|
|
13319
13366
|
getUsage as getUsage23,
|
|
13320
|
-
isStackPackSeed as
|
|
13367
|
+
isStackPackSeed as isStackPackSeed2,
|
|
13321
13368
|
loadCodeMap as loadCodeMap7,
|
|
13322
13369
|
loadConfig as loadConfig11,
|
|
13323
13370
|
loadMemoriesFromDir as loadMemoriesFromDir35,
|
|
@@ -13429,11 +13476,11 @@ function registerDoctor(program2) {
|
|
|
13429
13476
|
fix: "haive memory approve <id> # activate\nhaive memory delete <id> # or delete if obsolete"
|
|
13430
13477
|
});
|
|
13431
13478
|
}
|
|
13432
|
-
const policyMemories = memories.filter((m) => !
|
|
13479
|
+
const policyMemories = memories.filter((m) => !isStackPackSeed2(m.memory.frontmatter));
|
|
13433
13480
|
const anchorless = policyMemories.filter(
|
|
13434
13481
|
(m) => m.memory.frontmatter.anchor.paths.length === 0 && m.memory.frontmatter.anchor.symbols.length === 0 && m.memory.frontmatter.type !== "session_recap" && m.memory.frontmatter.type !== "glossary" && m.memory.frontmatter.type !== "skill"
|
|
13435
13482
|
);
|
|
13436
|
-
const stackSeeds = memories.filter((m) =>
|
|
13483
|
+
const stackSeeds = memories.filter((m) => isStackPackSeed2(m.memory.frontmatter));
|
|
13437
13484
|
if (anchorless.length / Math.max(policyMemories.length, 1) > 0.3) {
|
|
13438
13485
|
findings.push({
|
|
13439
13486
|
severity: "warn",
|
|
@@ -13563,7 +13610,7 @@ function registerDoctor(program2) {
|
|
|
13563
13610
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
|
|
13564
13611
|
});
|
|
13565
13612
|
}
|
|
13566
|
-
findings.push(...await collectInstallFindings(root, "0.
|
|
13613
|
+
findings.push(...await collectInstallFindings(root, "0.17.0"));
|
|
13567
13614
|
findings.push(...await collectToolchainFindings(root));
|
|
13568
13615
|
try {
|
|
13569
13616
|
const legacyRaw = execSync3("haive-mcp --version", {
|
|
@@ -13571,7 +13618,7 @@ function registerDoctor(program2) {
|
|
|
13571
13618
|
timeout: 3e3,
|
|
13572
13619
|
stdio: ["ignore", "pipe", "ignore"]
|
|
13573
13620
|
}).trim();
|
|
13574
|
-
const cliVersion = "0.
|
|
13621
|
+
const cliVersion = "0.17.0";
|
|
13575
13622
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
13576
13623
|
findings.push({
|
|
13577
13624
|
severity: "warn",
|
|
@@ -14913,7 +14960,7 @@ async function buildFinishReport(dir) {
|
|
|
14913
14960
|
severity: "error",
|
|
14914
14961
|
code: shippableDirty.length > 0 ? "git-sync-uncommitted-shippable" : "git-sync-uncommitted-changes",
|
|
14915
14962
|
message: shippableDirty.length > 0 ? `${shippableDirty.length} shippable file(s) are modified but not committed.` : `${status.dirtyFiles.length} file(s) are modified but not committed.`,
|
|
14916
|
-
fix: shippableDirty.length > 0 ? "Bump the lockstep package version if needed, then `git add`, `git commit`, `git tag vX.Y.Z`, `git push && git push
|
|
14963
|
+
fix: shippableDirty.length > 0 ? "Bump the lockstep package version if needed, then `git add`, `git commit`, `git tag vX.Y.Z`, `git push && git push origin vX.Y.Z` (not `--tags`)." : "Commit and push these changes before reporting the task done.",
|
|
14917
14964
|
reason: "The multi-agent git-sync decision requires agents to leave completed work committed and pushed, not as a local diff.",
|
|
14918
14965
|
affected_files: status.dirtyFiles.slice(0, 12),
|
|
14919
14966
|
impact: 100
|
|
@@ -15038,7 +15085,7 @@ async function buildFinishReport(dir) {
|
|
|
15038
15085
|
severity: "error",
|
|
15039
15086
|
code: "release-tag-unpushed",
|
|
15040
15087
|
message: `Tag ${tag} is not present on the remote.`,
|
|
15041
|
-
fix:
|
|
15088
|
+
fix: `Run \`git push origin ${tag}\` (avoid \`git push --tags\` \u2014 it fails on pre-existing divergent tags).`,
|
|
15042
15089
|
impact: 50
|
|
15043
15090
|
});
|
|
15044
15091
|
} else if (remoteTag === true) {
|
|
@@ -15052,7 +15099,7 @@ async function buildFinishReport(dir) {
|
|
|
15052
15099
|
severity: "warn",
|
|
15053
15100
|
code: "release-tag-remote-unverified",
|
|
15054
15101
|
message: `Could not verify whether tag ${tag} exists on the remote.`,
|
|
15055
|
-
fix:
|
|
15102
|
+
fix: `Run \`git push origin ${tag}\` if you have not already (avoid \`git push --tags\`).`,
|
|
15056
15103
|
impact: 10
|
|
15057
15104
|
});
|
|
15058
15105
|
}
|
|
@@ -15244,7 +15291,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
15244
15291
|
findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
|
|
15245
15292
|
});
|
|
15246
15293
|
}
|
|
15247
|
-
findings.push(...await inspectIntegrationVersions(root, "0.
|
|
15294
|
+
findings.push(...await inspectIntegrationVersions(root, "0.17.0"));
|
|
15248
15295
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
15249
15296
|
const hasBriefing = await hasRecentBriefingMarker2(paths, sessionId);
|
|
15250
15297
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
|
|
@@ -15404,7 +15451,7 @@ async function verifyDecisionCoverage(paths, stage, sessionId) {
|
|
|
15404
15451
|
severity: stage === "local" ? "warn" : "error",
|
|
15405
15452
|
code: "decision-coverage-missing",
|
|
15406
15453
|
message: `${missing.length}/${relevant.length} relevant anchored decisions/policies were not present in the latest briefing: ${missing.slice(0, 6).map((m) => m.frontmatter.id).join(", ")}`,
|
|
15407
|
-
fix: `Run \`haive briefing --files "${changedFiles.slice(0,
|
|
15454
|
+
fix: `Run \`haive briefing --files "${changedFiles.slice(0, 12).join(",")}" --max-memories 60 --task "..."\` before committing (briefings now accumulate, so several smaller briefings also work).`,
|
|
15408
15455
|
reason: "Changed files overlap validated anchored policy memories that were not recorded in the latest briefing marker.",
|
|
15409
15456
|
affected_files: changedFiles.slice(0, 10),
|
|
15410
15457
|
memory_ids: missing.slice(0, 10).map((m) => m.frontmatter.id),
|
|
@@ -17138,7 +17185,7 @@ async function readCommits(root, days) {
|
|
|
17138
17185
|
|
|
17139
17186
|
// src/index.ts
|
|
17140
17187
|
var program = new Command63();
|
|
17141
|
-
program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.
|
|
17188
|
+
program.name("haive").description("hAIve - repo-native memory and context policy for coding-agent harnesses").version("0.17.0").option("--advanced", "show maintenance and experimental commands in help");
|
|
17142
17189
|
registerInit(program);
|
|
17143
17190
|
registerWelcome(program);
|
|
17144
17191
|
registerResolveProject(program);
|