@hiveai/cli 0.9.25 → 0.9.26
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 +147 -39
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -4907,7 +4907,12 @@ async function memSessionEnd(input, ctx) {
|
|
|
4907
4907
|
}
|
|
4908
4908
|
const body = buildBody(input);
|
|
4909
4909
|
const topic = recapTopic(input.scope, input.module);
|
|
4910
|
-
const
|
|
4910
|
+
const normalizedFiles = input.files_touched.map((p) => {
|
|
4911
|
+
if (!p || !path82.isAbsolute(p)) return p;
|
|
4912
|
+
const rel = path82.relative(ctx.paths.root, p);
|
|
4913
|
+
return rel.startsWith("..") ? p : rel;
|
|
4914
|
+
});
|
|
4915
|
+
const invalidPaths = normalizedFiles.filter(
|
|
4911
4916
|
(p) => !existsSync17(path82.resolve(ctx.paths.root, p))
|
|
4912
4917
|
);
|
|
4913
4918
|
if (invalidPaths.length > 0) {
|
|
@@ -4926,7 +4931,7 @@ async function memSessionEnd(input, ctx) {
|
|
|
4926
4931
|
revision_count: revisionCount,
|
|
4927
4932
|
anchor: {
|
|
4928
4933
|
...fm.anchor,
|
|
4929
|
-
paths:
|
|
4934
|
+
paths: normalizedFiles.length ? normalizedFiles : fm.anchor.paths
|
|
4930
4935
|
}
|
|
4931
4936
|
};
|
|
4932
4937
|
await writeFile10(
|
|
@@ -4949,7 +4954,7 @@ async function memSessionEnd(input, ctx) {
|
|
|
4949
4954
|
scope: input.scope,
|
|
4950
4955
|
module: input.module,
|
|
4951
4956
|
tags: ["session", "recap"],
|
|
4952
|
-
paths:
|
|
4957
|
+
paths: normalizedFiles,
|
|
4953
4958
|
topic,
|
|
4954
4959
|
status: "validated"
|
|
4955
4960
|
});
|
|
@@ -6558,7 +6563,9 @@ function isDocLikePath(file) {
|
|
|
6558
6563
|
}
|
|
6559
6564
|
function isPackageOrConfigPath(file) {
|
|
6560
6565
|
const lower = file.toLowerCase();
|
|
6561
|
-
|
|
6566
|
+
const base = lower.split("/").pop() ?? lower;
|
|
6567
|
+
return lower.endsWith("package.json") || lower.endsWith("package-lock.json") || lower.endsWith("pnpm-lock.yaml") || lower.endsWith("yarn.lock") || lower.endsWith("bun.lockb") || lower.endsWith(".config.ts") || lower.endsWith(".config.js") || lower.endsWith(".json") || lower.endsWith(".yml") || lower.endsWith(".yaml") || lower.endsWith(".toml") || lower.startsWith(".github/workflows/") || lower.startsWith(".github/") && lower.endsWith(".yml") || // Dotfiles that are pure configuration/tooling — never trigger runtime gotchas
|
|
6568
|
+
base === ".gitignore" || base === ".gitattributes" || base === ".gitmodules" || base === ".editorconfig" || base === ".nvmrc" || base === ".node-version" || base === ".npmrc" || base === ".yarnrc" || base === ".yarnrc.yml" || base === ".dockerignore" || base === "dockerfile" || base.startsWith("dockerfile.") || base === ".env.example" || base === ".env.template" || lower.endsWith(".prettierrc") || lower.endsWith(".eslintrc") || lower.endsWith(".eslintignore") || lower.endsWith(".prettierignore") || lower.endsWith(".stylelintrc") || lower.endsWith(".browserslistrc");
|
|
6562
6569
|
}
|
|
6563
6570
|
function repairCommandForWarning(warning, paths) {
|
|
6564
6571
|
const firstPath = paths[0];
|
|
@@ -7095,7 +7102,7 @@ When done, respond with: "Imported N memories: [list of IDs]" or "Nothing action
|
|
|
7095
7102
|
};
|
|
7096
7103
|
}
|
|
7097
7104
|
var SERVER_NAME = "haive";
|
|
7098
|
-
var SERVER_VERSION = "0.9.
|
|
7105
|
+
var SERVER_VERSION = "0.9.26";
|
|
7099
7106
|
function jsonResult(data) {
|
|
7100
7107
|
return {
|
|
7101
7108
|
content: [
|
|
@@ -10285,18 +10292,37 @@ async function buildAutoRecap(paths) {
|
|
|
10285
10292
|
}
|
|
10286
10293
|
if (obs.length === 0) return await buildGitAutoRecap(paths);
|
|
10287
10294
|
const toolCounts = /* @__PURE__ */ new Map();
|
|
10288
|
-
const
|
|
10289
|
-
const
|
|
10295
|
+
const writeFiles = /* @__PURE__ */ new Set();
|
|
10296
|
+
const readFiles = /* @__PURE__ */ new Set();
|
|
10290
10297
|
for (const o of obs) {
|
|
10291
10298
|
toolCounts.set(o.tool, (toolCounts.get(o.tool) ?? 0) + 1);
|
|
10292
|
-
|
|
10293
|
-
|
|
10299
|
+
const isWrite = ["Edit", "Write", "NotebookEdit"].includes(o.tool);
|
|
10300
|
+
for (const f of o.files ?? []) {
|
|
10301
|
+
const rel = normalizeAnchorPath(paths.root, f);
|
|
10302
|
+
if (isWrite) writeFiles.add(rel);
|
|
10303
|
+
else readFiles.add(rel);
|
|
10304
|
+
}
|
|
10294
10305
|
}
|
|
10306
|
+
for (const f of writeFiles) readFiles.delete(f);
|
|
10295
10307
|
const topTools = [...toolCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([t, c]) => `${t} \xD7${c}`).join(", ");
|
|
10296
|
-
const
|
|
10297
|
-
const
|
|
10298
|
-
|
|
10299
|
-
|
|
10308
|
+
const recentCommits = await runGit(paths.root, ["log", "--oneline", "-5"]).catch(() => "");
|
|
10309
|
+
const accomplishedParts = [];
|
|
10310
|
+
if (writeFiles.size > 0) {
|
|
10311
|
+
accomplishedParts.push(
|
|
10312
|
+
`**Files modified (${writeFiles.size}):**`,
|
|
10313
|
+
...[...writeFiles].slice(0, 10).map((f) => `- \`${f}\``),
|
|
10314
|
+
...writeFiles.size > 10 ? [`- ...and ${writeFiles.size - 10} more`] : []
|
|
10315
|
+
);
|
|
10316
|
+
}
|
|
10317
|
+
if (recentCommits.trim()) {
|
|
10318
|
+
accomplishedParts.push("", "**Recent commits:**");
|
|
10319
|
+
for (const line of recentCommits.trim().split("\n").slice(0, 5)) {
|
|
10320
|
+
accomplishedParts.push(`- ${line}`);
|
|
10321
|
+
}
|
|
10322
|
+
}
|
|
10323
|
+
if (accomplishedParts.length === 0) {
|
|
10324
|
+
accomplishedParts.push(`${obs.length} tool calls (${topTools}) \u2014 no file writes detected.`);
|
|
10325
|
+
}
|
|
10300
10326
|
const failures = obs.filter((o) => o.failure_hint);
|
|
10301
10327
|
const discoveriesParts = [];
|
|
10302
10328
|
if (failures.length > 0) {
|
|
@@ -10305,37 +10331,75 @@ ${summaries.join("\n")}` : `Activity captured but no parseable summaries.`;
|
|
|
10305
10331
|
...failures.slice(0, 8).map((o) => `- ${o.summary.slice(0, 180)}`)
|
|
10306
10332
|
);
|
|
10307
10333
|
}
|
|
10334
|
+
const goal = writeFiles.size > 0 ? `Edited ${writeFiles.size} file${writeFiles.size === 1 ? "" : "s"} across ${obs.length} tool calls` : `Session with ${obs.length} tool calls (${topTools}) \u2014 read-only or no writes captured`;
|
|
10308
10335
|
return {
|
|
10309
10336
|
goal,
|
|
10310
|
-
accomplished,
|
|
10337
|
+
accomplished: accomplishedParts.join("\n"),
|
|
10311
10338
|
...discoveriesParts.length > 0 ? { discoveries: discoveriesParts.join("\n") } : {},
|
|
10312
|
-
files:
|
|
10339
|
+
files: [...writeFiles].slice(0, 12),
|
|
10313
10340
|
rawCount: obs.length
|
|
10314
10341
|
};
|
|
10315
10342
|
}
|
|
10316
10343
|
async function buildGitAutoRecap(paths) {
|
|
10317
10344
|
const changed = await runGit(paths.root, ["diff", "--name-only"]).catch(() => "");
|
|
10318
10345
|
const staged = await runGit(paths.root, ["diff", "--cached", "--name-only"]).catch(() => "");
|
|
10319
|
-
const
|
|
10346
|
+
const statusRaw = await runGit(paths.root, ["status", "--porcelain"]).catch(() => "");
|
|
10347
|
+
const recentLog = await runGit(paths.root, ["log", "--oneline", "-5"]).catch(() => "");
|
|
10348
|
+
const diffStat = await runGit(paths.root, ["diff", "--stat", "HEAD"]).catch(() => "");
|
|
10320
10349
|
const files = Array.from(new Set(
|
|
10321
10350
|
[
|
|
10322
10351
|
...changed.split("\n"),
|
|
10323
10352
|
...staged.split("\n"),
|
|
10324
|
-
...
|
|
10353
|
+
...statusRaw.split("\n").map((line) => line.replace(/^[ MADRCU?!]{1,2}\s+/, ""))
|
|
10325
10354
|
].map((s) => s.trim()).filter(Boolean).filter((file) => !file.startsWith(".ai/.runtime/") && !file.startsWith(".ai/.cache/"))
|
|
10326
10355
|
)).sort();
|
|
10327
|
-
|
|
10328
|
-
const
|
|
10356
|
+
const modified = [];
|
|
10357
|
+
const added = [];
|
|
10358
|
+
const deleted = [];
|
|
10359
|
+
for (const line of statusRaw.split("\n")) {
|
|
10360
|
+
const code = line.substring(0, 2).trim();
|
|
10361
|
+
const file = line.substring(3).trim().replace(/".+"/g, (m) => m.slice(1, -1));
|
|
10362
|
+
if (!file || file.startsWith(".ai/.runtime/") || file.startsWith(".ai/.cache/")) continue;
|
|
10363
|
+
if (code === "D" || code === "DD") deleted.push(file);
|
|
10364
|
+
else if (code === "A" || code === "??") added.push(file);
|
|
10365
|
+
else if (file) modified.push(file);
|
|
10366
|
+
}
|
|
10367
|
+
const accomplishedParts = [];
|
|
10368
|
+
if (modified.length > 0) {
|
|
10369
|
+
accomplishedParts.push(`**Modified (${modified.length}):**`);
|
|
10370
|
+
for (const f of modified.slice(0, 8)) accomplishedParts.push(`- \`${f}\``);
|
|
10371
|
+
if (modified.length > 8) accomplishedParts.push(`- ...and ${modified.length - 8} more`);
|
|
10372
|
+
}
|
|
10373
|
+
if (added.length > 0) {
|
|
10374
|
+
accomplishedParts.push(`
|
|
10375
|
+
**Added (${added.length}):**`);
|
|
10376
|
+
for (const f of added.slice(0, 5)) accomplishedParts.push(`- \`${f}\``);
|
|
10377
|
+
if (added.length > 5) accomplishedParts.push(`- ...and ${added.length - 5} more`);
|
|
10378
|
+
}
|
|
10379
|
+
if (deleted.length > 0) {
|
|
10380
|
+
accomplishedParts.push(`
|
|
10381
|
+
**Deleted (${deleted.length}):**`);
|
|
10382
|
+
for (const f of deleted.slice(0, 5)) accomplishedParts.push(`- \`${f}\``);
|
|
10383
|
+
}
|
|
10384
|
+
if (recentLog.trim()) {
|
|
10385
|
+
accomplishedParts.push("\n**Recent commits:**");
|
|
10386
|
+
for (const line of recentLog.trim().split("\n").slice(0, 5)) {
|
|
10387
|
+
accomplishedParts.push(`- ${line}`);
|
|
10388
|
+
}
|
|
10389
|
+
}
|
|
10390
|
+
if (accomplishedParts.length === 0 && files.length === 0) return null;
|
|
10391
|
+
if (accomplishedParts.length === 0) {
|
|
10392
|
+
accomplishedParts.push(...files.slice(0, 12).map((f) => `- \`${f}\``));
|
|
10393
|
+
if (files.length > 12) accomplishedParts.push(`- ...and ${files.length - 12} more`);
|
|
10394
|
+
}
|
|
10329
10395
|
return {
|
|
10330
|
-
goal: `
|
|
10331
|
-
accomplished:
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
${diffStat.trim()}` : void 0,
|
|
10338
|
-
files,
|
|
10396
|
+
goal: files.length > 0 ? `Session with ${files.length} changed file${files.length === 1 ? "" : "s"}` : `Session with recent commits (no uncommitted changes)`,
|
|
10397
|
+
accomplished: accomplishedParts.join("\n"),
|
|
10398
|
+
discoveries: diffStat.trim() ? `Git diff stat:
|
|
10399
|
+
\`\`\`
|
|
10400
|
+
${diffStat.trim()}
|
|
10401
|
+
\`\`\`` : void 0,
|
|
10402
|
+
files: files.slice(0, 12),
|
|
10339
10403
|
rawCount: files.length
|
|
10340
10404
|
};
|
|
10341
10405
|
}
|
|
@@ -10438,7 +10502,7 @@ function registerSessionEnd(session2) {
|
|
|
10438
10502
|
next: opts.next
|
|
10439
10503
|
});
|
|
10440
10504
|
const topic = recapTopic2(scope, opts.module);
|
|
10441
|
-
const filesTouched = parseCsv5(resolvedFiles);
|
|
10505
|
+
const filesTouched = parseCsv5(resolvedFiles).map((p) => normalizeAnchorPath(root, p));
|
|
10442
10506
|
const missingPaths = filesTouched.filter((p) => !existsSync53(path36.resolve(root, p)));
|
|
10443
10507
|
if (missingPaths.length > 0 && !opts.quiet) {
|
|
10444
10508
|
ui.warn(`Anchor path${missingPaths.length > 1 ? "s" : ""} not found in project (will be stale):`);
|
|
@@ -10503,6 +10567,13 @@ function parseCsv5(value) {
|
|
|
10503
10567
|
if (!value) return [];
|
|
10504
10568
|
return value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
10505
10569
|
}
|
|
10570
|
+
function normalizeAnchorPath(root, filePath) {
|
|
10571
|
+
if (!filePath) return filePath;
|
|
10572
|
+
if (!path36.isAbsolute(filePath)) return filePath;
|
|
10573
|
+
const rel = path36.relative(root, filePath);
|
|
10574
|
+
if (rel.startsWith("..")) return filePath;
|
|
10575
|
+
return rel;
|
|
10576
|
+
}
|
|
10506
10577
|
|
|
10507
10578
|
// src/commands/snapshot.ts
|
|
10508
10579
|
import { existsSync as existsSync54 } from "fs";
|
|
@@ -11691,7 +11762,7 @@ function parseDays(input) {
|
|
|
11691
11762
|
}
|
|
11692
11763
|
|
|
11693
11764
|
// src/commands/doctor.ts
|
|
11694
|
-
import { existsSync as existsSync60 } from "fs";
|
|
11765
|
+
import { existsSync as existsSync60, statSync } from "fs";
|
|
11695
11766
|
import { readFile as readFile19, stat } from "fs/promises";
|
|
11696
11767
|
import path44 from "path";
|
|
11697
11768
|
import { execFileSync, execSync as execSync3 } from "child_process";
|
|
@@ -11795,6 +11866,22 @@ function registerDoctor(program2) {
|
|
|
11795
11866
|
fix: "haive memory pending # list them\nhaive memory auto-promote # promote those with high read_count"
|
|
11796
11867
|
});
|
|
11797
11868
|
}
|
|
11869
|
+
const OLD_DRAFT_DAYS = 30;
|
|
11870
|
+
const oldDrafts = memories.filter((m) => {
|
|
11871
|
+
if (m.memory.frontmatter.status !== "draft") return false;
|
|
11872
|
+
const age = (now - Date.parse(m.memory.frontmatter.created_at)) / MS_PER_DAY3;
|
|
11873
|
+
return age > OLD_DRAFT_DAYS;
|
|
11874
|
+
});
|
|
11875
|
+
if (oldDrafts.length > 0) {
|
|
11876
|
+
const ids = oldDrafts.slice(0, 4).map((m) => m.memory.frontmatter.id).join(", ");
|
|
11877
|
+
const more = oldDrafts.length > 4 ? ` (+${oldDrafts.length - 4} more)` : "";
|
|
11878
|
+
findings.push({
|
|
11879
|
+
severity: "warn",
|
|
11880
|
+
code: "stale-draft-memories",
|
|
11881
|
+
message: `${oldDrafts.length} draft memor${oldDrafts.length === 1 ? "y has" : "ies have"} been in draft status for 30+ days: ${ids}${more}`,
|
|
11882
|
+
fix: "haive memory approve <id> # activate\nhaive memory rm <id> # or delete if obsolete"
|
|
11883
|
+
});
|
|
11884
|
+
}
|
|
11798
11885
|
const anchorless = memories.filter(
|
|
11799
11886
|
(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"
|
|
11800
11887
|
);
|
|
@@ -11920,14 +12007,14 @@ function registerDoctor(program2) {
|
|
|
11920
12007
|
fix: "Edit .ai/haive.config.json: set autoSessionEnd: true (or re-run `haive init` without --manual)."
|
|
11921
12008
|
});
|
|
11922
12009
|
}
|
|
11923
|
-
findings.push(...await collectInstallFindings(root, "0.9.
|
|
12010
|
+
findings.push(...await collectInstallFindings(root, "0.9.26"));
|
|
11924
12011
|
try {
|
|
11925
12012
|
const legacyRaw = execSync3("haive-mcp --version", {
|
|
11926
12013
|
encoding: "utf8",
|
|
11927
12014
|
timeout: 3e3,
|
|
11928
12015
|
stdio: ["ignore", "pipe", "ignore"]
|
|
11929
12016
|
}).trim();
|
|
11930
|
-
const cliVersion = "0.9.
|
|
12017
|
+
const cliVersion = "0.9.26";
|
|
11931
12018
|
if (legacyRaw && legacyRaw !== cliVersion) {
|
|
11932
12019
|
findings.push({
|
|
11933
12020
|
severity: "warn",
|
|
@@ -12084,13 +12171,22 @@ async function collectHarnessCoverageFindings(codeMap, memories) {
|
|
|
12084
12171
|
}
|
|
12085
12172
|
const covered = coveredFiles.size;
|
|
12086
12173
|
const pct = Math.round(covered / total * 100);
|
|
12174
|
+
const uncovered = codeFiles.filter((f) => !coveredFiles.has(f)).sort((a, b) => {
|
|
12175
|
+
const depthA = a.split("/").length;
|
|
12176
|
+
const depthB = b.split("/").length;
|
|
12177
|
+
if (depthA !== depthB) return depthA - depthB;
|
|
12178
|
+
return a.localeCompare(b);
|
|
12179
|
+
}).slice(0, 5);
|
|
12180
|
+
const coverageDesc = pct < 10 && total > 10 ? "Low coverage \u2014 add memory anchors on key modules to improve harness enforcement." : pct < 50 ? "Partial coverage \u2014 useful but not yet broad enough to call the harness mature." : pct < 80 ? "Good coverage \u2014 critical modules are increasingly protected." : "Good harness coverage.";
|
|
12181
|
+
const uncoveredHint = uncovered.length > 0 ? `
|
|
12182
|
+
Top uncovered: ${uncovered.map((f) => `\`${f}\``).join(", ")}` : "";
|
|
12087
12183
|
const findings = [];
|
|
12088
12184
|
findings.push({
|
|
12089
12185
|
severity: "info",
|
|
12090
12186
|
code: "harness-coverage",
|
|
12091
12187
|
coverage_percent: pct,
|
|
12092
|
-
message: `${covered}/${total} code-map files have validated memory anchors (${pct}%). ` +
|
|
12093
|
-
fix: pct < 50 && total > 10 ?
|
|
12188
|
+
message: `${covered}/${total} code-map files have validated memory anchors (${pct}%). ` + coverageDesc + uncoveredHint,
|
|
12189
|
+
fix: pct < 50 && total > 10 ? `haive memory add --type gotcha|convention|architecture --paths <key-file> --scope team` : void 0,
|
|
12094
12190
|
section: "Harness coverage"
|
|
12095
12191
|
});
|
|
12096
12192
|
return findings;
|
|
@@ -12322,7 +12418,13 @@ function extractAbsoluteHaiveBins(text) {
|
|
|
12322
12418
|
const re = /(["'\s])((?:\/[^"'\s]+)*\/haive)\b/g;
|
|
12323
12419
|
let match;
|
|
12324
12420
|
while (match = re.exec(text)) {
|
|
12325
|
-
|
|
12421
|
+
const p = match[2];
|
|
12422
|
+
if (!p) continue;
|
|
12423
|
+
try {
|
|
12424
|
+
if (statSync(p).isDirectory()) continue;
|
|
12425
|
+
} catch {
|
|
12426
|
+
}
|
|
12427
|
+
out.add(p);
|
|
12326
12428
|
}
|
|
12327
12429
|
return [...out].sort();
|
|
12328
12430
|
}
|
|
@@ -12823,7 +12925,7 @@ function registerMemoryConflictCandidates(memory2) {
|
|
|
12823
12925
|
|
|
12824
12926
|
// src/commands/enforce.ts
|
|
12825
12927
|
import { execFileSync as execFileSync2, spawn as spawn6 } from "child_process";
|
|
12826
|
-
import { existsSync as existsSync67 } from "fs";
|
|
12928
|
+
import { existsSync as existsSync67, statSync as statSync2 } from "fs";
|
|
12827
12929
|
import { chmod as chmod2, mkdir as mkdir19, readFile as readFile20, readdir as readdir6, rm as rm3, writeFile as writeFile31 } from "fs/promises";
|
|
12828
12930
|
import path49 from "path";
|
|
12829
12931
|
import "commander";
|
|
@@ -13155,7 +13257,7 @@ async function buildEnforcementReport(dir, stage, sessionId) {
|
|
|
13155
13257
|
findings: [{ severity: "info", code: "enforcement-off", message: "hAIve enforcement is disabled." }]
|
|
13156
13258
|
});
|
|
13157
13259
|
}
|
|
13158
|
-
findings.push(...await inspectIntegrationVersions(root, "0.9.
|
|
13260
|
+
findings.push(...await inspectIntegrationVersions(root, "0.9.26"));
|
|
13159
13261
|
if (config.enforcement?.requireBriefingFirst !== false && stage !== "ci") {
|
|
13160
13262
|
const hasBriefing = await hasRecentBriefingMarker(paths, sessionId);
|
|
13161
13263
|
findings.push(hasBriefing ? { severity: "ok", code: "briefing-loaded", message: "A recent hAIve briefing marker exists." } : {
|
|
@@ -13458,7 +13560,13 @@ function extractAbsoluteHaiveBins2(text) {
|
|
|
13458
13560
|
const re = /(["'\s])((?:\/[^"'\s]+)*\/haive)\b/g;
|
|
13459
13561
|
let match;
|
|
13460
13562
|
while (match = re.exec(text)) {
|
|
13461
|
-
|
|
13563
|
+
const p = match[2];
|
|
13564
|
+
if (!p) continue;
|
|
13565
|
+
try {
|
|
13566
|
+
if (statSync2(p).isDirectory()) continue;
|
|
13567
|
+
} catch {
|
|
13568
|
+
}
|
|
13569
|
+
out.add(p);
|
|
13462
13570
|
}
|
|
13463
13571
|
return [...out].sort();
|
|
13464
13572
|
}
|
|
@@ -13756,7 +13864,7 @@ function registerRun(program2) {
|
|
|
13756
13864
|
|
|
13757
13865
|
// src/index.ts
|
|
13758
13866
|
var program = new Command51();
|
|
13759
|
-
program.name("haive").description("hAIve \u2014 the memory and enforcement layer of your agent harness").version("0.9.
|
|
13867
|
+
program.name("haive").description("hAIve \u2014 the memory and enforcement layer of your agent harness").version("0.9.26").option("--advanced", "show maintenance and experimental commands in help");
|
|
13760
13868
|
registerInit(program);
|
|
13761
13869
|
registerWelcome(program);
|
|
13762
13870
|
registerResolveProject(program);
|