@hiveai/cli 0.2.3 → 0.2.5
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/Dashboard-SRPCHP7Z.js +194 -0
- package/dist/Dashboard-SRPCHP7Z.js.map +1 -0
- package/dist/index.js +107 -61
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command25 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/briefing.ts
|
|
7
7
|
import { existsSync } from "fs";
|
|
@@ -52,9 +52,9 @@ function registerBriefing(program2) {
|
|
|
52
52
|
"Print project context + relevant memories in one shot \u2014 ideal for agent onboarding"
|
|
53
53
|
).option("--task <text>", "what you are about to do \u2014 filters memories by relevance").option("--files <csv>", "comma-separated file paths being worked on (anchors memories)").option("--max-memories <n>", "cap on memories surfaced", "10").option(
|
|
54
54
|
"--scope <scope>",
|
|
55
|
-
"personal | team | module (default: team
|
|
55
|
+
"personal | team | module | all (default: team)",
|
|
56
56
|
"team"
|
|
57
|
-
).option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
57
|
+
).option("--include-draft", "include draft memories (excluded by default)").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
58
58
|
const root = findProjectRoot(opts.dir);
|
|
59
59
|
const paths = resolveHaivePaths(root);
|
|
60
60
|
if (existsSync(paths.projectContext)) {
|
|
@@ -77,6 +77,7 @@ function registerBriefing(program2) {
|
|
|
77
77
|
const candidates = all.filter(({ memory: mem }) => {
|
|
78
78
|
const fm = mem.frontmatter;
|
|
79
79
|
if (fm.status === "rejected" || fm.status === "deprecated") return false;
|
|
80
|
+
if (!opts.includeDraft && fm.status === "draft") return false;
|
|
80
81
|
if (scopeFilter !== "all" && fm.scope !== scopeFilter) return false;
|
|
81
82
|
return true;
|
|
82
83
|
});
|
|
@@ -93,6 +94,12 @@ function registerBriefing(program2) {
|
|
|
93
94
|
const top = scored.slice(0, maxMemories);
|
|
94
95
|
if (top.length === 0) {
|
|
95
96
|
ui.info("No relevant memories found.");
|
|
97
|
+
const draftCount = all.filter(
|
|
98
|
+
(m) => m.memory.frontmatter.status === "draft" && (scopeFilter === "all" || m.memory.frontmatter.scope === scopeFilter)
|
|
99
|
+
).length;
|
|
100
|
+
if (draftCount > 0) {
|
|
101
|
+
ui.info(`(${draftCount} draft memories excluded \u2014 use --include-draft to show)`);
|
|
102
|
+
}
|
|
96
103
|
return;
|
|
97
104
|
}
|
|
98
105
|
console.log(`${ui.bold("=== Relevant Memories ===")}
|
|
@@ -100,8 +107,9 @@ function registerBriefing(program2) {
|
|
|
100
107
|
for (const { memory: mem } of top) {
|
|
101
108
|
const fm = mem.frontmatter;
|
|
102
109
|
const badge = ui.statusBadge(fm.status);
|
|
110
|
+
const draftMarker = fm.status === "draft" ? ui.yellow(" [DRAFT]") : "";
|
|
103
111
|
console.log(
|
|
104
|
-
`${ui.bold(fm.id)} ${ui.dim(fm.scope + "/" + fm.type)} ${badge}`
|
|
112
|
+
`${ui.bold(fm.id)} ${ui.dim(fm.scope + "/" + fm.type)} ${badge}${draftMarker}`
|
|
105
113
|
);
|
|
106
114
|
console.log(mem.body.trim());
|
|
107
115
|
console.log();
|
|
@@ -114,15 +122,34 @@ function parseCsv(value) {
|
|
|
114
122
|
return value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
115
123
|
}
|
|
116
124
|
|
|
125
|
+
// src/commands/tui.ts
|
|
126
|
+
import "commander";
|
|
127
|
+
import { findProjectRoot as findProjectRoot2 } from "@hiveai/core";
|
|
128
|
+
function registerTui(program2) {
|
|
129
|
+
program2.command("tui").description("Interactive TUI dashboard \u2014 browse, filter, and manage memories in the terminal").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
130
|
+
if (!process.stdout.isTTY) {
|
|
131
|
+
console.error("haive tui requires an interactive terminal (TTY).");
|
|
132
|
+
process.exitCode = 1;
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const root = findProjectRoot2(opts.dir);
|
|
136
|
+
const { render } = await import("ink");
|
|
137
|
+
const { createElement } = await import("react");
|
|
138
|
+
const { Dashboard } = await import("./Dashboard-SRPCHP7Z.js");
|
|
139
|
+
const { waitUntilExit } = render(createElement(Dashboard, { root }));
|
|
140
|
+
await waitUntilExit();
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
|
|
117
144
|
// src/commands/embeddings.ts
|
|
118
145
|
import { existsSync as existsSync2 } from "fs";
|
|
119
146
|
import path from "path";
|
|
120
147
|
import "commander";
|
|
121
|
-
import { findProjectRoot as
|
|
148
|
+
import { findProjectRoot as findProjectRoot3, resolveHaivePaths as resolveHaivePaths2 } from "@hiveai/core";
|
|
122
149
|
function registerEmbeddings(program2) {
|
|
123
150
|
const embeddings = program2.command("embeddings").description("Manage local embeddings index for semantic search");
|
|
124
151
|
embeddings.command("index").description("Generate or refresh the embeddings index for all memories").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
125
|
-
const root =
|
|
152
|
+
const root = findProjectRoot3(opts.dir);
|
|
126
153
|
const paths = resolveHaivePaths2(root);
|
|
127
154
|
if (!existsSync2(paths.memoriesDir)) {
|
|
128
155
|
ui.error(`No .ai/memories at ${root}. Run \`haive init\` first.`);
|
|
@@ -139,7 +166,7 @@ function registerEmbeddings(program2) {
|
|
|
139
166
|
);
|
|
140
167
|
});
|
|
141
168
|
embeddings.command("query <text>").description("Run a semantic search against the local embeddings index").option("-d, --dir <dir>", "project root").option("--limit <n>", "max results", "10").option("--min-score <n>", "minimum cosine similarity (0-1)", "0").action(async (text, opts) => {
|
|
142
|
-
const root =
|
|
169
|
+
const root = findProjectRoot3(opts.dir);
|
|
143
170
|
const paths = resolveHaivePaths2(root);
|
|
144
171
|
const { semanticSearch } = await loadEmbeddings();
|
|
145
172
|
const result = await semanticSearch(paths, text, {
|
|
@@ -162,7 +189,7 @@ function registerEmbeddings(program2) {
|
|
|
162
189
|
}
|
|
163
190
|
});
|
|
164
191
|
embeddings.command("status").description("Show the embeddings index status").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
165
|
-
const root =
|
|
192
|
+
const root = findProjectRoot3(opts.dir);
|
|
166
193
|
const paths = resolveHaivePaths2(root);
|
|
167
194
|
const { indexStat } = await loadEmbeddings();
|
|
168
195
|
const stat = await indexStat(paths);
|
|
@@ -193,7 +220,7 @@ import "commander";
|
|
|
193
220
|
import {
|
|
194
221
|
buildCodeMap,
|
|
195
222
|
codeMapPath,
|
|
196
|
-
findProjectRoot as
|
|
223
|
+
findProjectRoot as findProjectRoot4,
|
|
197
224
|
resolveHaivePaths as resolveHaivePaths3,
|
|
198
225
|
saveCodeMap
|
|
199
226
|
} from "@hiveai/core";
|
|
@@ -205,7 +232,7 @@ function registerIndexCode(program2) {
|
|
|
205
232
|
"extra directory names to skip (comma-separated)",
|
|
206
233
|
""
|
|
207
234
|
).action(async (opts) => {
|
|
208
|
-
const root =
|
|
235
|
+
const root = findProjectRoot4(opts.dir);
|
|
209
236
|
const paths = resolveHaivePaths3(root);
|
|
210
237
|
const extraExcludes = (opts.exclude ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
211
238
|
ui.info(`Indexing source files in ${root}\u2026`);
|
|
@@ -303,7 +330,7 @@ import { mkdir as mkdir2, writeFile as writeFile2, chmod, readFile as readFile2
|
|
|
303
330
|
import { existsSync as existsSync4 } from "fs";
|
|
304
331
|
import path4 from "path";
|
|
305
332
|
import "commander";
|
|
306
|
-
import { findProjectRoot as
|
|
333
|
+
import { findProjectRoot as findProjectRoot6 } from "@hiveai/core";
|
|
307
334
|
var HOOK_MARKER = "# hAIve auto-generated";
|
|
308
335
|
var HOOK_BODY = `#!/bin/sh
|
|
309
336
|
${HOOK_MARKER} \u2014 keep this block to allow upgrades. Hand-edit anything outside it.
|
|
@@ -319,7 +346,7 @@ fi
|
|
|
319
346
|
var HOOKS = ["post-merge", "post-rewrite"];
|
|
320
347
|
function registerInstallHooks(program2) {
|
|
321
348
|
program2.command("install-hooks").description("Install git hooks that run `haive sync` after pull/merge").option("-d, --dir <dir>", "project root").option("--force", "overwrite existing hooks").action(async (opts) => {
|
|
322
|
-
const root =
|
|
349
|
+
const root = findProjectRoot6(opts.dir);
|
|
323
350
|
const gitDir = path4.join(root, ".git");
|
|
324
351
|
if (!existsSync4(gitDir)) {
|
|
325
352
|
ui.error(`No .git directory at ${root}.`);
|
|
@@ -356,11 +383,11 @@ import { createRequire } from "module";
|
|
|
356
383
|
import path5 from "path";
|
|
357
384
|
import { fileURLToPath } from "url";
|
|
358
385
|
import "commander";
|
|
359
|
-
import { findProjectRoot as
|
|
386
|
+
import { findProjectRoot as findProjectRoot7 } from "@hiveai/core";
|
|
360
387
|
var require2 = createRequire(import.meta.url);
|
|
361
388
|
function registerMcp(program2) {
|
|
362
389
|
program2.command("mcp").description("Start the hAIve MCP server (stdio transport)").option("-d, --dir <dir>", "project root (defaults to nearest .ai/ or .git/)").action((opts) => {
|
|
363
|
-
const root =
|
|
390
|
+
const root = findProjectRoot7(opts.dir);
|
|
364
391
|
const bin = locateMcpBin();
|
|
365
392
|
if (!bin) {
|
|
366
393
|
ui.error(
|
|
@@ -397,7 +424,7 @@ import "path";
|
|
|
397
424
|
import "commander";
|
|
398
425
|
import {
|
|
399
426
|
DEFAULT_AUTO_PROMOTE_RULE,
|
|
400
|
-
findProjectRoot as
|
|
427
|
+
findProjectRoot as findProjectRoot8,
|
|
401
428
|
getUsage,
|
|
402
429
|
isAutoPromoteEligible,
|
|
403
430
|
loadMemoriesFromDir as loadMemoriesFromDir2,
|
|
@@ -411,7 +438,7 @@ function registerSync(program2) {
|
|
|
411
438
|
"--since <ref>",
|
|
412
439
|
"git ref/commit to compare against; report memories added/modified/removed since"
|
|
413
440
|
).option("--no-verify", "skip the anchor verification step").option("--no-promote", "skip the auto-promotion step").action(async (opts) => {
|
|
414
|
-
const root =
|
|
441
|
+
const root = findProjectRoot8(opts.dir);
|
|
415
442
|
const paths = resolveHaivePaths5(root);
|
|
416
443
|
if (!existsSync6(paths.memoriesDir)) {
|
|
417
444
|
if (!opts.quiet) ui.warn(`No .ai/memories at ${root}. Run \`haive init\` first.`);
|
|
@@ -544,7 +571,7 @@ import path7 from "path";
|
|
|
544
571
|
import "commander";
|
|
545
572
|
import {
|
|
546
573
|
buildFrontmatter,
|
|
547
|
-
findProjectRoot as
|
|
574
|
+
findProjectRoot as findProjectRoot9,
|
|
548
575
|
inferModulesFromPaths,
|
|
549
576
|
memoryFilePath,
|
|
550
577
|
resolveHaivePaths as resolveHaivePaths6,
|
|
@@ -552,7 +579,7 @@ import {
|
|
|
552
579
|
} from "@hiveai/core";
|
|
553
580
|
function registerMemoryAdd(memory2) {
|
|
554
581
|
memory2.command("add").description("Add a new memory (defaults to personal scope)").requiredOption("--type <type>", "convention | decision | gotcha | architecture | glossary").requiredOption("--slug <slug>", "short identifier used in the file name").option("--title <text>", "memory title \u2014 becomes the first heading of the body").option("--scope <scope>", "personal | team | module", "personal").option("--module <name>", "module name (required when scope=module)").option("--tags <csv>", "comma-separated tags").option("--domain <domain>", "domain (e.g. transactions)").option("--author <author>", "author email or handle").option("--paths <csv>", "anchor paths, comma-separated").option("--symbols <csv>", "anchor symbols, comma-separated").option("--commit <sha>", "anchor commit SHA").option("--body <text>", "memory body content (Markdown) \u2014 overrides --title default body").option("--no-auto-tag", "disable automatic tag suggestions inferred from anchor paths").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
555
|
-
const root =
|
|
582
|
+
const root = findProjectRoot9(opts.dir);
|
|
556
583
|
const paths = resolveHaivePaths6(root);
|
|
557
584
|
if (!existsSync7(paths.haiveDir)) {
|
|
558
585
|
ui.error(`No .ai/ found at ${root}. Run \`haive init\` first.`);
|
|
@@ -623,7 +650,7 @@ function parseCsv2(value) {
|
|
|
623
650
|
import { existsSync as existsSync8 } from "fs";
|
|
624
651
|
import path8 from "path";
|
|
625
652
|
import "commander";
|
|
626
|
-
import { findProjectRoot as
|
|
653
|
+
import { findProjectRoot as findProjectRoot10, resolveHaivePaths as resolveHaivePaths7 } from "@hiveai/core";
|
|
627
654
|
|
|
628
655
|
// src/utils/fs.ts
|
|
629
656
|
import {
|
|
@@ -635,7 +662,7 @@ import {
|
|
|
635
662
|
// src/commands/memory-list.ts
|
|
636
663
|
function registerMemoryList(memory2) {
|
|
637
664
|
memory2.command("list").description("List memories with optional filters").option("--scope <scope>", "personal | team | module").option("--type <type>", "filter by type").option("--tag <tag>", "filter by tag").option("--module <name>", "filter by module name").option("--status <csv>", "filter by status (draft,proposed,validated,stale,rejected,deprecated)").option("--show-rejected", "include rejected memories (hidden by default)").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
638
|
-
const root =
|
|
665
|
+
const root = findProjectRoot10(opts.dir);
|
|
639
666
|
const paths = resolveHaivePaths7(root);
|
|
640
667
|
if (!existsSync8(paths.memoriesDir)) {
|
|
641
668
|
ui.error(`No memories directory at ${paths.memoriesDir}. Run \`haive init\` first.`);
|
|
@@ -647,15 +674,17 @@ function registerMemoryList(memory2) {
|
|
|
647
674
|
const filtered = all.filter((m) => {
|
|
648
675
|
if (!matchesFilters(m, opts)) return false;
|
|
649
676
|
const status = m.memory.frontmatter.status;
|
|
650
|
-
if (!opts.showRejected && status === "rejected") return false;
|
|
677
|
+
if (!opts.showRejected && !statusFilter && status === "rejected") return false;
|
|
651
678
|
if (statusFilter && !statusFilter.includes(status)) return false;
|
|
652
679
|
return true;
|
|
653
680
|
});
|
|
681
|
+
const hiddenRejectedCount = !opts.showRejected && !statusFilter ? all.filter(
|
|
682
|
+
(m) => matchesFilters(m, opts) && m.memory.frontmatter.status === "rejected"
|
|
683
|
+
).length : 0;
|
|
654
684
|
if (filtered.length === 0) {
|
|
655
685
|
ui.info("No memories match the filters.");
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
ui.info(`(${rejectedCount} rejected hidden \u2014 use --show-rejected to include)`);
|
|
686
|
+
if (hiddenRejectedCount > 0) {
|
|
687
|
+
ui.info(`(${hiddenRejectedCount} rejected hidden \u2014 use --show-rejected to include)`);
|
|
659
688
|
}
|
|
660
689
|
return;
|
|
661
690
|
}
|
|
@@ -671,13 +700,24 @@ function registerMemoryList(memory2) {
|
|
|
671
700
|
}
|
|
672
701
|
console.log(ui.dim(`
|
|
673
702
|
${filtered.length} memor${filtered.length === 1 ? "y" : "ies"}`));
|
|
674
|
-
|
|
675
|
-
if (draftCount > 0) {
|
|
703
|
+
if (hiddenRejectedCount > 0) {
|
|
676
704
|
console.log(
|
|
677
|
-
ui.dim(
|
|
678
|
-
|
|
679
|
-
|
|
705
|
+
ui.dim(`(${hiddenRejectedCount} rejected hidden \u2014 use --show-rejected to include)`)
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
const draftItems = filtered.filter((m) => m.memory.frontmatter.status === "draft");
|
|
709
|
+
if (draftItems.length > 0) {
|
|
710
|
+
const hasPersonalDrafts = draftItems.some(
|
|
711
|
+
(m) => m.memory.frontmatter.scope === "personal"
|
|
680
712
|
);
|
|
713
|
+
const hasTeamDrafts = draftItems.some(
|
|
714
|
+
(m) => m.memory.frontmatter.scope !== "personal"
|
|
715
|
+
);
|
|
716
|
+
let hint = `\u2139 ${draftItems.length} in draft \u2014 use \`haive memory approve <id>\` to activate`;
|
|
717
|
+
if (hasPersonalDrafts && !hasTeamDrafts) {
|
|
718
|
+
hint += " or `haive memory promote <id>` to share with team";
|
|
719
|
+
}
|
|
720
|
+
console.log(ui.dim(hint));
|
|
681
721
|
}
|
|
682
722
|
});
|
|
683
723
|
}
|
|
@@ -696,14 +736,14 @@ import { existsSync as existsSync9 } from "fs";
|
|
|
696
736
|
import path9 from "path";
|
|
697
737
|
import "commander";
|
|
698
738
|
import {
|
|
699
|
-
findProjectRoot as
|
|
739
|
+
findProjectRoot as findProjectRoot11,
|
|
700
740
|
memoryFilePath as memoryFilePath2,
|
|
701
741
|
resolveHaivePaths as resolveHaivePaths8,
|
|
702
742
|
serializeMemory as serializeMemory3
|
|
703
743
|
} from "@hiveai/core";
|
|
704
744
|
function registerMemoryPromote(memory2) {
|
|
705
745
|
memory2.command("promote <id>").description("Promote a personal memory to team scope (status -> proposed)").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
706
|
-
const root =
|
|
746
|
+
const root = findProjectRoot11(opts.dir);
|
|
707
747
|
const paths = resolveHaivePaths8(root);
|
|
708
748
|
if (!existsSync9(paths.memoriesDir)) {
|
|
709
749
|
ui.error(`No memories directory at ${paths.memoriesDir}. Run \`haive init\` first.`);
|
|
@@ -755,13 +795,13 @@ import { writeFile as writeFile6 } from "fs/promises";
|
|
|
755
795
|
import path10 from "path";
|
|
756
796
|
import "commander";
|
|
757
797
|
import {
|
|
758
|
-
findProjectRoot as
|
|
798
|
+
findProjectRoot as findProjectRoot12,
|
|
759
799
|
resolveHaivePaths as resolveHaivePaths9,
|
|
760
800
|
serializeMemory as serializeMemory4
|
|
761
801
|
} from "@hiveai/core";
|
|
762
802
|
function registerMemoryApprove(memory2) {
|
|
763
803
|
memory2.command("approve [id]").description("Mark a memory as 'validated'. Use --all to bulk-approve all proposed/draft memories.").option("--all", "approve all proposed and draft memories at once").option("--pending", "approve all memories with status 'proposed'").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
764
|
-
const root =
|
|
804
|
+
const root = findProjectRoot12(opts.dir);
|
|
765
805
|
const paths = resolveHaivePaths9(root);
|
|
766
806
|
if (!existsSync10(paths.memoriesDir)) {
|
|
767
807
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -826,13 +866,13 @@ import { existsSync as existsSync11 } from "fs";
|
|
|
826
866
|
import path11 from "path";
|
|
827
867
|
import "commander";
|
|
828
868
|
import {
|
|
829
|
-
findProjectRoot as
|
|
869
|
+
findProjectRoot as findProjectRoot13,
|
|
830
870
|
resolveHaivePaths as resolveHaivePaths10,
|
|
831
871
|
serializeMemory as serializeMemory5
|
|
832
872
|
} from "@hiveai/core";
|
|
833
873
|
function registerMemoryUpdate(memory2) {
|
|
834
874
|
memory2.command("update <id>").description("Update body, tags, or anchor of an existing memory (preserves id and usage history)").option("--title <text>", "new title \u2014 replaces the first heading of the body").option("--body <text>", "new Markdown body \u2014 replaces the existing body").option("--tags <csv>", "new tags, comma-separated \u2014 fully replaces existing tags").option("--paths <csv>", "new anchor paths, comma-separated").option("--symbols <csv>", "new anchor symbols, comma-separated").option("--commit <sha>", "new anchor commit SHA").option("--domain <domain>", "new domain label").option("--author <author>", "new author handle or email").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
835
|
-
const root =
|
|
875
|
+
const root = findProjectRoot13(opts.dir);
|
|
836
876
|
const paths = resolveHaivePaths10(root);
|
|
837
877
|
if (!existsSync11(paths.memoriesDir)) {
|
|
838
878
|
ui.error(`No .ai/memories at ${root}. Run \`haive init\` first.`);
|
|
@@ -911,7 +951,7 @@ import path12 from "path";
|
|
|
911
951
|
import "commander";
|
|
912
952
|
import {
|
|
913
953
|
DEFAULT_AUTO_PROMOTE_RULE as DEFAULT_AUTO_PROMOTE_RULE2,
|
|
914
|
-
findProjectRoot as
|
|
954
|
+
findProjectRoot as findProjectRoot14,
|
|
915
955
|
getUsage as getUsage2,
|
|
916
956
|
isAutoPromoteEligible as isAutoPromoteEligible2,
|
|
917
957
|
loadUsageIndex as loadUsageIndex2,
|
|
@@ -924,7 +964,7 @@ function registerMemoryAutoPromote(memory2) {
|
|
|
924
964
|
"memories with more rejections than this are skipped",
|
|
925
965
|
String(DEFAULT_AUTO_PROMOTE_RULE2.maxRejections)
|
|
926
966
|
).option("--apply", "actually write status=validated to disk (default: dry-run)").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
927
|
-
const root =
|
|
967
|
+
const root = findProjectRoot14(opts.dir);
|
|
928
968
|
const paths = resolveHaivePaths11(root);
|
|
929
969
|
if (!existsSync12(paths.memoriesDir)) {
|
|
930
970
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -974,13 +1014,13 @@ import { readFile as readFile3 } from "fs/promises";
|
|
|
974
1014
|
import path13 from "path";
|
|
975
1015
|
import "commander";
|
|
976
1016
|
import {
|
|
977
|
-
findProjectRoot as
|
|
1017
|
+
findProjectRoot as findProjectRoot15,
|
|
978
1018
|
parseMemory,
|
|
979
1019
|
resolveHaivePaths as resolveHaivePaths12
|
|
980
1020
|
} from "@hiveai/core";
|
|
981
1021
|
function registerMemoryEdit(memory2) {
|
|
982
1022
|
memory2.command("edit <id>").description("Open a memory in $EDITOR and re-validate when you save").option("-e, --editor <cmd>", "editor command (defaults to $EDITOR or 'vi')").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
983
|
-
const root =
|
|
1023
|
+
const root = findProjectRoot15(opts.dir);
|
|
984
1024
|
const paths = resolveHaivePaths12(root);
|
|
985
1025
|
if (!existsSync13(paths.memoriesDir)) {
|
|
986
1026
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -1027,7 +1067,7 @@ import path14 from "path";
|
|
|
1027
1067
|
import "commander";
|
|
1028
1068
|
import {
|
|
1029
1069
|
deriveConfidence,
|
|
1030
|
-
findProjectRoot as
|
|
1070
|
+
findProjectRoot as findProjectRoot16,
|
|
1031
1071
|
getUsage as getUsage3,
|
|
1032
1072
|
inferModulesFromPaths as inferModulesFromPaths2,
|
|
1033
1073
|
loadUsageIndex as loadUsageIndex3,
|
|
@@ -1036,7 +1076,7 @@ import {
|
|
|
1036
1076
|
} from "@hiveai/core";
|
|
1037
1077
|
function registerMemoryForFiles(memory2) {
|
|
1038
1078
|
memory2.command("for-files <files...>").description("Show memories relevant to the given files (anchor overlap, module, domain)").option("-d, --dir <dir>", "project root").action(async (files, opts) => {
|
|
1039
|
-
const root =
|
|
1079
|
+
const root = findProjectRoot16(opts.dir);
|
|
1040
1080
|
const paths = resolveHaivePaths13(root);
|
|
1041
1081
|
if (!existsSync14(paths.memoriesDir)) {
|
|
1042
1082
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -1100,14 +1140,14 @@ import { existsSync as existsSync15 } from "fs";
|
|
|
1100
1140
|
import path15 from "path";
|
|
1101
1141
|
import "commander";
|
|
1102
1142
|
import {
|
|
1103
|
-
findProjectRoot as
|
|
1143
|
+
findProjectRoot as findProjectRoot17,
|
|
1104
1144
|
getUsage as getUsage4,
|
|
1105
1145
|
loadUsageIndex as loadUsageIndex4,
|
|
1106
1146
|
resolveHaivePaths as resolveHaivePaths14
|
|
1107
1147
|
} from "@hiveai/core";
|
|
1108
1148
|
function registerMemoryHot(memory2) {
|
|
1109
1149
|
memory2.command("hot").description("List memories actively used but not yet validated (good promotion candidates)").option("--threshold <n>", "minimum read_count to qualify", "3").option("--status <status>", "limit to one status (default: draft + proposed)").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
1110
|
-
const root =
|
|
1150
|
+
const root = findProjectRoot17(opts.dir);
|
|
1111
1151
|
const paths = resolveHaivePaths14(root);
|
|
1112
1152
|
if (!existsSync15(paths.memoriesDir)) {
|
|
1113
1153
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -1150,14 +1190,14 @@ import { existsSync as existsSync16 } from "fs";
|
|
|
1150
1190
|
import path16 from "path";
|
|
1151
1191
|
import "commander";
|
|
1152
1192
|
import {
|
|
1153
|
-
findProjectRoot as
|
|
1193
|
+
findProjectRoot as findProjectRoot18,
|
|
1154
1194
|
getUsage as getUsage5,
|
|
1155
1195
|
loadUsageIndex as loadUsageIndex5,
|
|
1156
1196
|
resolveHaivePaths as resolveHaivePaths15
|
|
1157
1197
|
} from "@hiveai/core";
|
|
1158
1198
|
function registerMemoryPending(memory2) {
|
|
1159
1199
|
memory2.command("pending").description("List 'proposed' memories awaiting review (sorted by reads desc)").option("--scope <scope>", "filter by scope (personal | team | module)").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
1160
|
-
const root =
|
|
1200
|
+
const root = findProjectRoot18(opts.dir);
|
|
1161
1201
|
const paths = resolveHaivePaths15(root);
|
|
1162
1202
|
if (!existsSync16(paths.memoriesDir)) {
|
|
1163
1203
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -1199,15 +1239,15 @@ import path17 from "path";
|
|
|
1199
1239
|
import "commander";
|
|
1200
1240
|
import {
|
|
1201
1241
|
extractSnippet,
|
|
1202
|
-
findProjectRoot as
|
|
1242
|
+
findProjectRoot as findProjectRoot19,
|
|
1203
1243
|
literalMatchesAllTokens as literalMatchesAllTokens2,
|
|
1204
1244
|
pickSnippetNeedle,
|
|
1205
1245
|
resolveHaivePaths as resolveHaivePaths16,
|
|
1206
1246
|
tokenizeQuery as tokenizeQuery2
|
|
1207
1247
|
} from "@hiveai/core";
|
|
1208
1248
|
function registerMemoryQuery(memory2) {
|
|
1209
|
-
memory2.command("query <text>").description("Search memories by id, tag, or substring (multi-word AND)").option("-d, --dir <dir>", "project root").option("--limit <n>", "max results", "20").option("--scope <scope>", "personal | team | module").option("--status <csv>", "filter by status (draft,proposed,validated,stale,rejected)").action(async (text, opts) => {
|
|
1210
|
-
const root =
|
|
1249
|
+
memory2.command("query <text>").description("Search memories by id, tag, or substring (multi-word AND)").option("-d, --dir <dir>", "project root").option("--limit <n>", "max results", "20").option("--scope <scope>", "personal | team | module").option("--status <csv>", "filter by status (draft,proposed,validated,stale,rejected)").option("--show-rejected", "include rejected memories (hidden by default)").action(async (text, opts) => {
|
|
1250
|
+
const root = findProjectRoot19(opts.dir);
|
|
1211
1251
|
const paths = resolveHaivePaths16(root);
|
|
1212
1252
|
if (!existsSync17(paths.memoriesDir)) {
|
|
1213
1253
|
ui.error(`No memories directory at ${paths.memoriesDir}. Run \`haive init\` first.`);
|
|
@@ -1220,6 +1260,7 @@ function registerMemoryQuery(memory2) {
|
|
|
1220
1260
|
const matches = all.filter(({ memory: mem }) => {
|
|
1221
1261
|
const fm = mem.frontmatter;
|
|
1222
1262
|
if (opts.scope && fm.scope !== opts.scope) return false;
|
|
1263
|
+
if (!opts.showRejected && !statusFilter && fm.status === "rejected") return false;
|
|
1223
1264
|
if (statusFilter && !statusFilter.includes(fm.status)) return false;
|
|
1224
1265
|
return literalMatchesAllTokens2(mem, tokens);
|
|
1225
1266
|
});
|
|
@@ -1250,7 +1291,7 @@ import { writeFile as writeFile9 } from "fs/promises";
|
|
|
1250
1291
|
import { existsSync as existsSync18 } from "fs";
|
|
1251
1292
|
import "commander";
|
|
1252
1293
|
import {
|
|
1253
|
-
findProjectRoot as
|
|
1294
|
+
findProjectRoot as findProjectRoot20,
|
|
1254
1295
|
loadUsageIndex as loadUsageIndex6,
|
|
1255
1296
|
recordRejection,
|
|
1256
1297
|
resolveHaivePaths as resolveHaivePaths17,
|
|
@@ -1259,7 +1300,7 @@ import {
|
|
|
1259
1300
|
} from "@hiveai/core";
|
|
1260
1301
|
function registerMemoryReject(memory2) {
|
|
1261
1302
|
memory2.command("reject <id>").description("Record a rejection (blocks auto-promotion and lowers confidence)").option("-r, --reason <reason>", "why this memory is being rejected").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
1262
|
-
const root =
|
|
1303
|
+
const root = findProjectRoot20(opts.dir);
|
|
1263
1304
|
const paths = resolveHaivePaths17(root);
|
|
1264
1305
|
if (!existsSync18(paths.memoriesDir)) {
|
|
1265
1306
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -1276,7 +1317,11 @@ function registerMemoryReject(memory2) {
|
|
|
1276
1317
|
await writeFile9(
|
|
1277
1318
|
loaded.filePath,
|
|
1278
1319
|
serializeMemory7({
|
|
1279
|
-
frontmatter: {
|
|
1320
|
+
frontmatter: {
|
|
1321
|
+
...loaded.memory.frontmatter,
|
|
1322
|
+
status: "rejected",
|
|
1323
|
+
stale_reason: opts.reason ?? loaded.memory.frontmatter.stale_reason ?? null
|
|
1324
|
+
},
|
|
1280
1325
|
body: loaded.memory.body
|
|
1281
1326
|
}),
|
|
1282
1327
|
"utf8"
|
|
@@ -1299,14 +1344,14 @@ import path18 from "path";
|
|
|
1299
1344
|
import { createInterface } from "readline/promises";
|
|
1300
1345
|
import "commander";
|
|
1301
1346
|
import {
|
|
1302
|
-
findProjectRoot as
|
|
1347
|
+
findProjectRoot as findProjectRoot21,
|
|
1303
1348
|
loadUsageIndex as loadUsageIndex7,
|
|
1304
1349
|
resolveHaivePaths as resolveHaivePaths18,
|
|
1305
1350
|
saveUsageIndex as saveUsageIndex2
|
|
1306
1351
|
} from "@hiveai/core";
|
|
1307
1352
|
function registerMemoryRm(memory2) {
|
|
1308
1353
|
memory2.command("rm <id>").description("Delete a memory file (and its usage entry by default)").option("-y, --yes", "skip the confirmation prompt").option("--keep-usage", "do not remove the usage.json entry").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
1309
|
-
const root =
|
|
1354
|
+
const root = findProjectRoot21(opts.dir);
|
|
1310
1355
|
const paths = resolveHaivePaths18(root);
|
|
1311
1356
|
if (!existsSync19(paths.memoriesDir)) {
|
|
1312
1357
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -1350,14 +1395,14 @@ import path19 from "path";
|
|
|
1350
1395
|
import "commander";
|
|
1351
1396
|
import {
|
|
1352
1397
|
deriveConfidence as deriveConfidence2,
|
|
1353
|
-
findProjectRoot as
|
|
1398
|
+
findProjectRoot as findProjectRoot22,
|
|
1354
1399
|
getUsage as getUsage6,
|
|
1355
1400
|
loadUsageIndex as loadUsageIndex8,
|
|
1356
1401
|
resolveHaivePaths as resolveHaivePaths19
|
|
1357
1402
|
} from "@hiveai/core";
|
|
1358
1403
|
function registerMemoryShow(memory2) {
|
|
1359
1404
|
memory2.command("show <id>").description("Print a memory's frontmatter, body, and confidence/usage").option("--raw", "print the raw file contents instead of a summary").option("-d, --dir <dir>", "project root").action(async (id, opts) => {
|
|
1360
|
-
const root =
|
|
1405
|
+
const root = findProjectRoot22(opts.dir);
|
|
1361
1406
|
const paths = resolveHaivePaths19(root);
|
|
1362
1407
|
if (!existsSync20(paths.memoriesDir)) {
|
|
1363
1408
|
ui.error(`No .ai/memories at ${root}.`);
|
|
@@ -1408,14 +1453,14 @@ import path20 from "path";
|
|
|
1408
1453
|
import "commander";
|
|
1409
1454
|
import {
|
|
1410
1455
|
deriveConfidence as deriveConfidence3,
|
|
1411
|
-
findProjectRoot as
|
|
1456
|
+
findProjectRoot as findProjectRoot23,
|
|
1412
1457
|
getUsage as getUsage7,
|
|
1413
1458
|
loadUsageIndex as loadUsageIndex9,
|
|
1414
1459
|
resolveHaivePaths as resolveHaivePaths20
|
|
1415
1460
|
} from "@hiveai/core";
|
|
1416
1461
|
function registerMemoryStats(memory2) {
|
|
1417
1462
|
memory2.command("stats").description("Show usage stats and confidence levels per memory").option("--id <id>", "show stats for a single memory id").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
1418
|
-
const root =
|
|
1463
|
+
const root = findProjectRoot23(opts.dir);
|
|
1419
1464
|
const paths = resolveHaivePaths20(root);
|
|
1420
1465
|
if (!existsSync21(paths.memoriesDir)) {
|
|
1421
1466
|
ui.error(`No .ai/memories at ${root}. Run \`haive init\` first.`);
|
|
@@ -1453,14 +1498,14 @@ import { existsSync as existsSync22 } from "fs";
|
|
|
1453
1498
|
import path21 from "path";
|
|
1454
1499
|
import "commander";
|
|
1455
1500
|
import {
|
|
1456
|
-
findProjectRoot as
|
|
1501
|
+
findProjectRoot as findProjectRoot24,
|
|
1457
1502
|
resolveHaivePaths as resolveHaivePaths21,
|
|
1458
1503
|
serializeMemory as serializeMemory8,
|
|
1459
1504
|
verifyAnchor as verifyAnchor2
|
|
1460
1505
|
} from "@hiveai/core";
|
|
1461
1506
|
function registerMemoryVerify(memory2) {
|
|
1462
1507
|
memory2.command("verify").description("Check memory anchors against current code, optionally marking stale ones").option("--id <id>", "verify a single memory by id").option("--all", "verify every memory (default if --id is omitted)").option("--update", "write status=stale (or status=validated for re-freshed) back to disk").option("-d, --dir <dir>", "project root").action(async (opts) => {
|
|
1463
|
-
const root =
|
|
1508
|
+
const root = findProjectRoot24(opts.dir);
|
|
1464
1509
|
const paths = resolveHaivePaths21(root);
|
|
1465
1510
|
if (!existsSync22(paths.memoriesDir)) {
|
|
1466
1511
|
ui.error(`No .ai/memories at ${root}. Run \`haive init\` first.`);
|
|
@@ -1536,11 +1581,12 @@ function applyVerification(mem, result) {
|
|
|
1536
1581
|
}
|
|
1537
1582
|
|
|
1538
1583
|
// src/index.ts
|
|
1539
|
-
var program = new
|
|
1540
|
-
program.name("haive").description("hAIve \u2014 team-first persistent memory layer for AI coding agents").version("0.2.
|
|
1584
|
+
var program = new Command25();
|
|
1585
|
+
program.name("haive").description("hAIve \u2014 team-first persistent memory layer for AI coding agents").version("0.2.5");
|
|
1541
1586
|
registerInit(program);
|
|
1542
1587
|
registerMcp(program);
|
|
1543
1588
|
registerBriefing(program);
|
|
1589
|
+
registerTui(program);
|
|
1544
1590
|
registerEmbeddings(program);
|
|
1545
1591
|
registerSync(program);
|
|
1546
1592
|
registerInstallHooks(program);
|