@kage-core/kage-graph-mcp 1.3.0 → 2.0.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/cli.js CHANGED
@@ -2,18 +2,37 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const node_child_process_1 = require("node:child_process");
5
+ const node_fs_1 = require("node:fs");
6
+ const node_os_1 = require("node:os");
7
+ const node_path_1 = require("node:path");
5
8
  const promises_1 = require("node:readline/promises");
6
9
  const node_process_1 = require("node:process");
7
10
  const daemon_js_1 = require("./daemon.js");
8
11
  const kernel_js_1 = require("./kernel.js");
9
12
  const graph_registry_js_1 = require("./graph-registry.js");
10
- function usage() {
11
- console.log(`Kage repo memory and code graph
13
+ const CORE_USAGE = `Kage — code-grounded memory for coding agents
14
+
15
+ Core commands:
16
+ kage demo 30-second trust demo (temp dir)
17
+ kage scan --project <dir> 60-second truth report on any repo (zero setup)
18
+ kage init --project <dir> create repo memory (.agent_memory only)
19
+ kage index --project <dir> [--full] build/refresh code graph + indexes
20
+ kage recall "<query>" --project <dir> grounded recall from repo memory
21
+ kage learn --project <dir> ... capture a learning as a memory packet
22
+ kage gains --project <dir> what Kage saved you (tokens, cost, stale blocks)
23
+ kage verify --project <dir> check memory citations against code
24
+ kage setup <agent> --project <dir> --write wire your agent (claude-code, codex, cursor, ...)
25
+ kage doctor --project <dir> health check
26
+ kage viewer --project <dir> local dashboard
27
+
28
+ Run 'kage help --all' for the full command list (lifecycle, CI, benchmarks, daemon, workspace).`;
29
+ const FULL_USAGE = `Kage — full command reference
12
30
 
13
31
  Usage:
14
32
  kage index --project <dir>
33
+ kage scan --project <dir> [--json]
15
34
  kage demo [--project <dir>]
16
- kage init --project <dir>
35
+ kage init --project <dir> [--with-policy]
17
36
  kage policy --project <dir>
18
37
  kage doctor --project <dir>
19
38
  kage setup list
@@ -35,10 +54,13 @@ Usage:
35
54
  kage suppressed --project <dir> [--json]
36
55
  kage pr summarize --project <dir> [--json]
37
56
  kage pr check --project <dir> [--json]
57
+ kage staleguard --project <dir> [--json]
38
58
  kage upgrade [--dry-run]
39
59
  kage branch --project <dir> [--json]
40
60
  kage metrics --project <dir> [--json]
61
+ kage gains --project <dir> [--json]
41
62
  kage memory-access --project <dir> [--json]
63
+ kage activity --project <dir> [--json]
42
64
  kage memory-audit --project <dir> [--limit <n>] [--json]
43
65
  kage slots --project <dir> [--json]
44
66
  kage slots set --project <dir> --label <label> --content <text> [--description <text>] [--paths a,b] [--tags a,b] [--size-limit <n>] [--unpinned] [--json]
@@ -92,23 +114,30 @@ Usage:
92
114
  kage promote --project <dir> --public <packet-id>
93
115
  kage export-public --project <dir>
94
116
  kage registry --project <dir> [--json]
95
- kage marketplace --project <dir> [--json]
96
- kage org status --project <dir> --org <org> [--json]
97
- kage org upload --project <dir> --org <org> --packet <approved-packet-id>
98
- kage org review --project <dir> --org <org> --packet <org-packet-id> --approve|--reject
99
- kage org recall "<query>" --project <dir> --org <org> [--json]
100
- kage org export --project <dir> --org <org> [--json]
101
- kage layered-recall "<query>" --project <dir> [--org <org>] [--global] [--json]
102
- kage global build --project <dir> [--org <org>] [--json]
103
117
  kage changelog --project <dir> [--days <n>] [--json]
104
118
  kage review --project <dir>
105
119
  kage validate --project <dir>
106
120
 
107
121
  Types:
108
- ${kernel_js_1.MEMORY_TYPES.join(", ")}
109
- `);
122
+ ${kernel_js_1.MEMORY_TYPES.join(", ")}`;
123
+ function usage() {
124
+ console.log(CORE_USAGE);
110
125
  process.exit(1);
111
126
  }
127
+ // Stale-catch lines lead with color when attached to a terminal so the
128
+ // retention heartbeat is impossible to miss; plain text otherwise (CI, pipes).
129
+ function printStaleCatch(result) {
130
+ const useColor = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
131
+ const [headline, ...rest] = (0, kernel_js_1.formatStaleCatch)(result);
132
+ if (!useColor) {
133
+ console.log([headline, ...rest].join("\n"));
134
+ return;
135
+ }
136
+ const tint = result.invalidated.length ? "\u001b[33m" : "\u001b[32m";
137
+ console.log(`${tint}${headline}\u001b[0m`);
138
+ if (rest.length)
139
+ console.log(rest.join("\n"));
140
+ }
112
141
  function takeArg(args, name) {
113
142
  const index = args.indexOf(name);
114
143
  if (index === -1)
@@ -169,6 +198,11 @@ async function main() {
169
198
  const command = args[0];
170
199
  if (!command)
171
200
  usage();
201
+ if (command === "help") {
202
+ console.log(args.includes("--all") ? FULL_USAGE : CORE_USAGE);
203
+ return;
204
+ }
205
+ await (0, kernel_js_1.ensureTreeSitterLanguages)();
172
206
  if (command === "index") {
173
207
  const result = (0, kernel_js_1.indexProject)(projectArg(args));
174
208
  console.log(`Indexed ${result.projectDir}`);
@@ -179,15 +213,54 @@ async function main() {
179
213
  console.log(`Indexes:\n${result.indexes.map((path) => ` - ${path}`).join("\n")}`);
180
214
  return;
181
215
  }
216
+ if (command === "scan") {
217
+ const result = (0, kernel_js_1.truthReport)(projectArg(args));
218
+ if (args.includes("--json")) {
219
+ console.log(JSON.stringify(result, null, 2));
220
+ return;
221
+ }
222
+ console.log(`Kage Truth Report — ${result.project_dir}`);
223
+ console.log(`Scanned ${result.totals.files_scanned} files, ${result.totals.symbols_scanned} symbols${result.totals.docs_scanned ? `, ${result.totals.docs_scanned} doc file(s)` : ""}\n`);
224
+ console.log(` ${result.headline}\n`);
225
+ const sections = [
226
+ { kind: "duplicate_cluster", heading: "DUPLICATE IMPLEMENTATIONS", count: result.totals.duplicate_clusters },
227
+ { kind: "ghost_export", heading: "GHOST KNOWLEDGE — exported, never called", count: result.totals.ghost_exports },
228
+ { kind: "bus_factor", heading: "BUS FACTOR 1 — one head holds it all", count: result.totals.bus_factor_files },
229
+ { kind: "knowledge_void", heading: "KNOWLEDGE VOID — high churn, zero memory", count: result.totals.knowledge_voids },
230
+ { kind: "doc_lie", heading: "DOC LIES — the README vs reality", count: result.totals.doc_lies },
231
+ ];
232
+ for (const section of sections) {
233
+ const items = result.findings.filter((finding) => finding.kind === section.kind);
234
+ if (!items.length)
235
+ continue;
236
+ console.log(`■ ${section.heading} (${section.count}${section.count > items.length ? `, showing top ${items.length}` : ""})`);
237
+ for (const finding of items) {
238
+ console.log(` • ${finding.title}`);
239
+ console.log(` ${finding.detail}`);
240
+ for (const evidence of finding.evidence)
241
+ console.log(` ${evidence}`);
242
+ }
243
+ console.log("");
244
+ }
245
+ if (!result.findings.length)
246
+ console.log("No surprising findings — this repo's knowledge is unusually well distributed.\n");
247
+ if (result.warnings.length)
248
+ console.log(`Warnings:\n${result.warnings.map((warning) => ` - ${warning}`).join("\n")}\n`);
249
+ console.log("Fix the void:");
250
+ for (const action of result.next_actions)
251
+ console.log(` ${action}`);
252
+ return;
253
+ }
182
254
  if (command === "demo") {
183
- const demoDir = takeArg(args, "--project") ?? `${process.cwd()}/kage-demo`;
255
+ // Default to a temp dir: the demo must never write into the user's cwd uninvited.
256
+ const demoDir = takeArg(args, "--project") ?? (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "kage-demo-"));
184
257
  const result = (0, kernel_js_1.runDemo)(demoDir);
185
258
  if (args.includes("--json")) {
186
259
  console.log(JSON.stringify(result, null, 2));
187
260
  return;
188
261
  }
189
262
  console.log("Kage demo — can you trust your agent's memory?\n");
190
- console.log(`Seeded ${result.captured.length} grounded memories in ${result.project_dir}\n`);
263
+ console.log(`Seeded ${result.captured.length} grounded memories in a throwaway project (${result.project_dir})\n`);
191
264
  console.log("1. Hallucinated citation — REJECTED on write:");
192
265
  if (result.rejected_hallucination) {
193
266
  console.log(` ✗ "${result.rejected_hallucination.title}"`);
@@ -200,23 +273,40 @@ async function main() {
200
273
  for (const t of result.recalled)
201
274
  console.log(` ✓ ${t}`);
202
275
  console.log(`\nTrust score: ${result.trust_score}/100`);
203
- console.log(`\nSee it in the viewer: ${result.viewer_command}`);
276
+ console.log("\nNext, in your own repo:");
277
+ console.log(" kage init --project . create repo memory");
278
+ console.log(" kage setup <agent> --project . --write wire your agent (claude-code, codex, cursor, ...)");
279
+ console.log(" kage viewer --project . see the dashboard");
204
280
  return;
205
281
  }
206
282
  if (command === "init") {
207
- const result = (0, kernel_js_1.initProject)(projectArg(args));
283
+ const withPolicy = args.includes("--with-policy");
284
+ const result = (0, kernel_js_1.initProject)(projectArg(args), { policy: withPolicy });
208
285
  console.log(`Initialized Kage memory for ${result.index.projectDir}`);
209
- console.log(`Packets: ${result.index.packets}`);
210
- console.log(`Migrated legacy nodes: ${result.index.migrated}`);
211
- if (result.index.policyPath)
212
- console.log(`Agent policy: ${result.index.policyPath}`);
286
+ console.log("\nCreated:");
287
+ console.log(" .agent_memory/ memory packets + indexes (only directory Kage owns)");
288
+ if (result.policyInstalled) {
289
+ console.log(" AGENTS.md, CLAUDE.md agent policy (requested via --with-policy)");
290
+ console.log(" .claude/settings.json allowed kage tools (requested via --with-policy)");
291
+ }
292
+ console.log(`\nPackets: ${result.index.packets}`);
293
+ if (result.index.migrated)
294
+ console.log(`Migrated legacy nodes: ${result.index.migrated}`);
213
295
  console.log(result.validation.ok ? "Validation passed." : "Validation failed.");
214
296
  if (result.validation.errors.length)
215
297
  console.log(`Errors:\n${result.validation.errors.map((error) => ` - ${error}`).join("\n")}`);
216
298
  if (result.validation.warnings.length)
217
299
  console.log(`Warnings:\n${result.validation.warnings.map((warning) => ` - ${warning}`).join("\n")}`);
218
- console.log("\nFirst recall preview:\n");
219
- console.log(result.sampleRecall.context_block);
300
+ console.log("\nTip version control:");
301
+ console.log(" commit .agent_memory/packets/ (your team's reviewed memory)");
302
+ console.log(" ignore .agent_memory/indexes/ .agent_memory/reports/ (regenerated)");
303
+ if (!result.policyInstalled) {
304
+ console.log("\nNot written (opt-in): agent policy files. Add them with `kage policy --project .`");
305
+ console.log("or rerun `kage init --with-policy` when you're ready to commit them.");
306
+ }
307
+ console.log("\nNext:");
308
+ console.log(" kage setup <agent> --project . --write wire your agent (claude-code, codex, cursor, ...)");
309
+ console.log(" kage viewer --project . see the dashboard");
220
310
  if (!result.validation.ok)
221
311
  process.exit(2);
222
312
  return;
@@ -569,6 +659,10 @@ async function main() {
569
659
  process.exit(2);
570
660
  return;
571
661
  }
662
+ // The stale-catch moment comes first: the human-readable heartbeat that a
663
+ // change just invalidated team memory beats the mechanical check output.
664
+ printStaleCatch((0, kernel_js_1.staleCatch)(projectArg(args)));
665
+ console.log("");
572
666
  console.log(`PR memory check for ${result.project_dir}`);
573
667
  console.log(`Branch: ${result.branch ?? "(detached)"}`);
574
668
  console.log(`Changed files: ${result.changed_files.length}`);
@@ -587,6 +681,18 @@ async function main() {
587
681
  }
588
682
  usage();
589
683
  }
684
+ if (command === "staleguard") {
685
+ // Lightweight stale-catch for pre-commit/pre-push hooks: no graph builds,
686
+ // no validation — just "did this change invalidate team memory?". Advisory
687
+ // by design (exit 0) so it informs the commit instead of blocking it.
688
+ const result = (0, kernel_js_1.staleCatch)(projectArg(args));
689
+ if (args.includes("--json")) {
690
+ console.log(JSON.stringify(result, null, 2));
691
+ return;
692
+ }
693
+ printStaleCatch(result);
694
+ return;
695
+ }
590
696
  if (command === "upgrade") {
591
697
  const commandLine = "npm install -g @kage-core/kage-graph-mcp@latest";
592
698
  if (args.includes("--dry-run")) {
@@ -959,6 +1065,30 @@ async function main() {
959
1065
  }
960
1066
  return;
961
1067
  }
1068
+ if (command === "gains") {
1069
+ const summary = (0, kernel_js_1.valueSummary)(projectArg(args));
1070
+ if (args.includes("--json")) {
1071
+ console.log(JSON.stringify(summary, null, 2));
1072
+ return;
1073
+ }
1074
+ const plural = (count, singular, pluralForm) => (count === 1 ? singular : pluralForm);
1075
+ const week = summary.last_7d;
1076
+ if (!summary.all_time.recalls && !summary.all_time.stale_withheld && !summary.all_time.stale_caught && !summary.all_time.caller_answers) {
1077
+ console.log("No value events recorded yet. Run kage recall (or let your agent call kage_context) and check back.");
1078
+ return;
1079
+ }
1080
+ console.log(`This week Kage saved you ~${(0, kernel_js_1.formatTokenCount)(week.tokens_saved)} tokens (~$${week.estimated_dollars.toFixed(2)}), ` +
1081
+ `blocked ${week.stale_withheld} stale ${plural(week.stale_withheld, "memory", "memories")}, ` +
1082
+ `caught ${week.stale_caught} stale at change-time, ` +
1083
+ `answered ${week.recalls} ${plural(week.recalls, "recall", "recalls")}.`);
1084
+ const windowLine = (label, window) => ` ${label} ~${(0, kernel_js_1.formatTokenCount)(window.tokens_saved)} tokens (~$${window.estimated_dollars.toFixed(2)}) · ` +
1085
+ `${window.stale_withheld} stale blocked · ${window.stale_caught} stale caught at change-time · ` +
1086
+ `${window.recalls} ${plural(window.recalls, "recall", "recalls")} · ` +
1087
+ `${window.caller_answers} caller ${plural(window.caller_answers, "answer", "answers")}`;
1088
+ console.log(windowLine("Today: ", summary.today));
1089
+ console.log(windowLine("All time:", summary.all_time));
1090
+ return;
1091
+ }
962
1092
  if (command === "memory-access") {
963
1093
  const result = (0, kernel_js_1.kageMemoryAccess)(projectArg(args));
964
1094
  if (args.includes("--json")) {
@@ -983,6 +1113,19 @@ async function main() {
983
1113
  }
984
1114
  return;
985
1115
  }
1116
+ if (command === "activity") {
1117
+ const result = (0, kernel_js_1.kageActivity)(projectArg(args));
1118
+ if (args.includes("--json")) {
1119
+ console.log(JSON.stringify(result, null, 2));
1120
+ return;
1121
+ }
1122
+ console.log(`Kage activity: ${result.totals.events} events (${result.totals.recalls} recalls, ${result.totals.captures} captures); ${result.totals.recalls_7d} recalls in 7 days`);
1123
+ console.log("\nRecent:");
1124
+ for (const event of result.events.slice(0, 15)) {
1125
+ console.log(`- ${event.at.slice(0, 16).replace("T", " ")} ${event.kind.padEnd(9)} ${event.title}`);
1126
+ }
1127
+ return;
1128
+ }
986
1129
  if (command === "lifecycle" || command === "memory-lifecycle") {
987
1130
  const result = (0, kernel_js_1.kageMemoryLifecycle)(projectArg(args));
988
1131
  if (args.includes("--json")) {
@@ -1574,119 +1717,6 @@ async function main() {
1574
1717
  }
1575
1718
  return;
1576
1719
  }
1577
- if (command === "marketplace") {
1578
- const result = (0, kernel_js_1.buildMarketplace)(projectArg(args));
1579
- if (args.includes("--json")) {
1580
- console.log(JSON.stringify(result, null, 2));
1581
- return;
1582
- }
1583
- console.log(`Marketplace manifest: ${result.path}`);
1584
- console.log(`Packs: ${result.packs.length}`);
1585
- for (const pack of result.packs) {
1586
- console.log(`- ${pack.id} [${pack.kind}] ${pack.title} (${pack.install})`);
1587
- }
1588
- return;
1589
- }
1590
- if (command === "org") {
1591
- const action = args[1];
1592
- const org = takeArg(args, "--org") ?? "local";
1593
- const projectDir = projectArg(args);
1594
- if (action === "status") {
1595
- const result = (0, kernel_js_1.orgStatus)(projectDir, org);
1596
- if (args.includes("--json"))
1597
- console.log(JSON.stringify(result, null, 2));
1598
- else {
1599
- console.log(`Org memory: ${result.org}`);
1600
- console.log(`Path: ${result.path}`);
1601
- console.log(`Inbox: ${result.inbox}`);
1602
- console.log(`Approved: ${result.approved}`);
1603
- console.log(`Rejected: ${result.rejected}`);
1604
- console.log(`Audit events: ${result.audit_events}`);
1605
- if (result.registry_path)
1606
- console.log(`Registry: ${result.registry_path}`);
1607
- }
1608
- return;
1609
- }
1610
- if (action === "upload") {
1611
- const id = takeArg(args, "--packet");
1612
- if (!id)
1613
- usage();
1614
- const result = (0, kernel_js_1.orgUploadPacket)(projectDir, org, id);
1615
- if (!result.ok) {
1616
- console.error(`Org upload blocked:\n${result.errors.map((error) => ` - ${error}`).join("\n")}`);
1617
- process.exit(2);
1618
- }
1619
- console.log(`Created org review candidate: ${result.path}`);
1620
- console.log("Approve explicitly with: kage org review --approve");
1621
- return;
1622
- }
1623
- if (action === "review") {
1624
- const id = takeArg(args, "--packet");
1625
- if (!id || (!args.includes("--approve") && !args.includes("--reject")))
1626
- usage();
1627
- const result = (0, kernel_js_1.orgReviewPacket)(projectDir, org, id, args.includes("--approve") ? "approve" : "reject");
1628
- if (!result.ok) {
1629
- console.error(`Org review failed:\n${result.errors.map((error) => ` - ${error}`).join("\n")}`);
1630
- process.exit(2);
1631
- }
1632
- console.log(`Org review wrote: ${result.path}`);
1633
- return;
1634
- }
1635
- if (action === "recall") {
1636
- const query = firstPositional(args.slice(1));
1637
- if (!query)
1638
- usage();
1639
- const result = (0, kernel_js_1.orgRecall)(projectDir, org, query);
1640
- if (args.includes("--json"))
1641
- console.log(JSON.stringify(result, null, 2));
1642
- else
1643
- console.log(result.context_block);
1644
- return;
1645
- }
1646
- if (action === "export") {
1647
- const result = (0, kernel_js_1.exportOrgRegistry)(projectDir, org);
1648
- if (args.includes("--json"))
1649
- console.log(JSON.stringify(result, null, 2));
1650
- else
1651
- console.log(`Exported org registry: ${result.registry_path}`);
1652
- return;
1653
- }
1654
- usage();
1655
- }
1656
- if (command === "layered-recall") {
1657
- const query = firstPositional(args);
1658
- if (!query)
1659
- usage();
1660
- const result = (0, kernel_js_1.layeredRecall)(projectArg(args), query, {
1661
- org: takeArg(args, "--org"),
1662
- includeGlobal: args.includes("--global"),
1663
- });
1664
- if (args.includes("--json"))
1665
- console.log(JSON.stringify(result, null, 2));
1666
- else
1667
- console.log(result.context_block);
1668
- return;
1669
- }
1670
- if (command === "global") {
1671
- const action = args[1];
1672
- if (action !== "build")
1673
- usage();
1674
- const result = (0, kernel_js_1.buildGlobalCdnBundle)(projectArg(args), takeArg(args, "--org") ?? "local");
1675
- if (args.includes("--json")) {
1676
- console.log(JSON.stringify(result, null, 2));
1677
- return;
1678
- }
1679
- if (!result.ok) {
1680
- console.error(`Global bundle failed:\n${result.errors.map((error) => ` - ${error}`).join("\n")}`);
1681
- process.exit(2);
1682
- }
1683
- console.log(`Global registry: ${result.manifest_path}`);
1684
- console.log(`Latest alias: ${result.alias_path}`);
1685
- console.log(`Marketplace: ${result.marketplace_path}`);
1686
- console.log(`Public packets: ${result.packet_count}`);
1687
- console.log(`Marketplace packs: ${result.marketplace_packs}`);
1688
- return;
1689
- }
1690
1720
  if (command === "recall") {
1691
1721
  const query = firstPositional(args);
1692
1722
  if (!query)
@@ -1698,8 +1728,12 @@ async function main() {
1698
1728
  : (0, kernel_js_1.recall)(projectArg(args), query, 5, args.includes("--explain"), { maxContextTokens, structuralHops });
1699
1729
  if (args.includes("--json"))
1700
1730
  console.log(JSON.stringify(result, null, 2));
1701
- else
1731
+ else {
1702
1732
  console.log(result.context_block);
1733
+ if (result.value_receipt) {
1734
+ console.log(`\n↳ saved ~${(0, kernel_js_1.formatTokenCount)(result.value_receipt.tokens_saved)} tokens vs reading source · ${result.value_receipt.stale_withheld} stale withheld`);
1735
+ }
1736
+ }
1703
1737
  return;
1704
1738
  }
1705
1739
  if (command === "embeddings") {
package/dist/daemon.js CHANGED
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.viewerStaticHeaders = viewerStaticHeaders;
4
4
  exports.viewerRedirectLocation = viewerRedirectLocation;
5
+ exports.viewerReportPaths = viewerReportPaths;
6
+ exports.viewerUrl = viewerUrl;
5
7
  exports.viewerBenchmarkReport = viewerBenchmarkReport;
6
8
  exports.daemonContextReport = daemonContextReport;
7
9
  exports.readDaemonStatus = readDaemonStatus;
@@ -63,6 +65,52 @@ function viewerRedirectLocation(pathname, search, fallbackSearch) {
63
65
  return null;
64
66
  return `/viewer/index.html${search || fallbackSearch}`;
65
67
  }
68
+ // Every report file the dashboard reads, keyed by its query-string param name.
69
+ // `value` points at the cumulative value ledger written by recall — it is read-only
70
+ // here and must never be regenerated, or the all-time savings history is lost.
71
+ function viewerReportPaths(projectRoot) {
72
+ const agentDir = (0, node_path_1.join)(projectRoot, ".agent_memory");
73
+ const reportsDir = (0, node_path_1.join)(agentDir, "reports");
74
+ return {
75
+ graph: (0, node_path_1.join)(agentDir, "graph", "graph.json"),
76
+ code: (0, node_path_1.join)(agentDir, "code_graph", "graph.json"),
77
+ metrics: (0, node_path_1.join)(agentDir, "metrics.json"),
78
+ inbox: (0, node_path_1.join)(agentDir, "inbox.json"),
79
+ review: (0, node_path_1.join)(agentDir, "review", "memory-review.md"),
80
+ pending: (0, node_path_1.join)(agentDir, "pending"),
81
+ quality: (0, node_path_1.join)(reportsDir, "quality.json"),
82
+ benchmark: (0, node_path_1.join)(reportsDir, "benchmark.json"),
83
+ contributors: (0, node_path_1.join)(reportsDir, "contributors.json"),
84
+ profile: (0, node_path_1.join)(reportsDir, "profile.json"),
85
+ xray: (0, node_path_1.join)(reportsDir, "xray.json"),
86
+ capabilities: (0, node_path_1.join)(reportsDir, "capabilities.json"),
87
+ slots: (0, node_path_1.join)(reportsDir, "context-slots.json"),
88
+ decisions: (0, node_path_1.join)(reportsDir, "decisions.json"),
89
+ risk: (0, node_path_1.join)(reportsDir, "risk.json"),
90
+ moduleHealth: (0, node_path_1.join)(reportsDir, "module-health.json"),
91
+ graphInsights: (0, node_path_1.join)(reportsDir, "graph-insights.json"),
92
+ workspace: (0, node_path_1.join)(reportsDir, "workspace.json"),
93
+ sessions: (0, node_path_1.join)(reportsDir, "sessions.json"),
94
+ replay: (0, node_path_1.join)(reportsDir, "replay.json"),
95
+ memoryAccess: (0, node_path_1.join)(reportsDir, "memory-access.json"),
96
+ memoryAudit: (0, node_path_1.join)(reportsDir, "memory-audit.json"),
97
+ handoff: (0, node_path_1.join)(reportsDir, "handoff.json"),
98
+ lifecycle: (0, node_path_1.join)(reportsDir, "lifecycle.json"),
99
+ activity: (0, node_path_1.join)(reportsDir, "activity.json"),
100
+ timeline: (0, node_path_1.join)(reportsDir, "timeline.json"),
101
+ lineage: (0, node_path_1.join)(reportsDir, "lineage.json"),
102
+ setup: (0, node_path_1.join)(reportsDir, "setup.json"),
103
+ trust: (0, node_path_1.join)(reportsDir, "trust.json"),
104
+ suppressed: (0, node_path_1.join)(reportsDir, "suppressed.json"),
105
+ value: (0, node_path_1.join)(reportsDir, "value.json"),
106
+ };
107
+ }
108
+ function viewerUrl(host, port, projectRoot) {
109
+ const query = Object.entries(viewerReportPaths(projectRoot))
110
+ .map(([name, path]) => `${name}=${encodeURIComponent(path)}`)
111
+ .join("&");
112
+ return `http://${host}:${port}/viewer/index.html?${query}&view=code`;
113
+ }
66
114
  function viewerBenchmarkReport(projectDir) {
67
115
  const gates = (0, kernel_js_1.benchmarkProject)(projectDir);
68
116
  const memoryQuality = (0, kernel_js_1.benchmarkCodingMemoryQuality)();
@@ -545,71 +593,46 @@ async function startViewer(projectDir, options = {}) {
545
593
  const viewerDir = (0, node_path_1.resolve)(__dirname, "..", "viewer");
546
594
  const threeDir = (0, node_path_1.resolve)(__dirname, "..", "node_modules", "three");
547
595
  const projectRoot = (0, node_path_1.resolve)(projectDir);
548
- const graphPath = (0, node_path_1.join)(projectRoot, ".agent_memory", "graph", "graph.json");
549
- const codePath = (0, node_path_1.join)(projectRoot, ".agent_memory", "code_graph", "graph.json");
550
- const metricsPath = (0, node_path_1.join)(projectRoot, ".agent_memory", "metrics.json");
551
- const inboxPath = (0, node_path_1.join)(projectRoot, ".agent_memory", "inbox.json");
552
- const reviewPath = (0, node_path_1.join)(projectRoot, ".agent_memory", "review", "memory-review.md");
553
- const pendingDir = (0, node_path_1.join)(projectRoot, ".agent_memory", "pending");
596
+ const reports = viewerReportPaths(projectRoot);
554
597
  const reportsDir = (0, node_path_1.join)(projectRoot, ".agent_memory", "reports");
555
- const qualityPath = (0, node_path_1.join)(reportsDir, "quality.json");
556
- const benchmarkPath = (0, node_path_1.join)(reportsDir, "benchmark.json");
557
- const contributorsPath = (0, node_path_1.join)(reportsDir, "contributors.json");
558
- const profilePath = (0, node_path_1.join)(reportsDir, "profile.json");
559
- const xrayPath = (0, node_path_1.join)(reportsDir, "xray.json");
560
- const capabilitiesPath = (0, node_path_1.join)(reportsDir, "capabilities.json");
561
- const slotsPath = (0, node_path_1.join)(reportsDir, "context-slots.json");
562
- const decisionsPath = (0, node_path_1.join)(reportsDir, "decisions.json");
563
- const riskPath = (0, node_path_1.join)(reportsDir, "risk.json");
564
- const moduleHealthPath = (0, node_path_1.join)(reportsDir, "module-health.json");
565
- const graphInsightsPath = (0, node_path_1.join)(reportsDir, "graph-insights.json");
566
- const workspacePath = (0, node_path_1.join)(reportsDir, "workspace.json");
567
- const sessionsPath = (0, node_path_1.join)(reportsDir, "sessions.json");
568
- const replayPath = (0, node_path_1.join)(reportsDir, "replay.json");
569
- const memoryAccessPath = (0, node_path_1.join)(reportsDir, "memory-access.json");
570
- const memoryAuditPath = (0, node_path_1.join)(reportsDir, "memory-audit.json");
571
- const handoffPath = (0, node_path_1.join)(reportsDir, "handoff.json");
572
- const lifecyclePath = (0, node_path_1.join)(reportsDir, "lifecycle.json");
573
- const timelinePath = (0, node_path_1.join)(reportsDir, "timeline.json");
574
- const lineagePath = (0, node_path_1.join)(reportsDir, "lineage.json");
575
- const setupPath = (0, node_path_1.join)(reportsDir, "setup.json");
576
- const trustPath = (0, node_path_1.join)(reportsDir, "trust.json");
577
- const suppressedPath = (0, node_path_1.join)(reportsDir, "suppressed.json");
578
598
  // Pre-generate lightweight JSON reports so the viewer can load them directly.
599
+ // Note: reports.value (the cumulative value ledger written by recall) is served
600
+ // as-is and intentionally never regenerated here.
579
601
  try {
580
602
  (0, node_fs_1.mkdirSync)(reportsDir, { recursive: true });
581
603
  const metrics = (0, kernel_js_1.kageMetrics)(projectDir);
582
- (0, node_fs_1.writeFileSync)(metricsPath, JSON.stringify(metrics, null, 2));
604
+ (0, node_fs_1.writeFileSync)(reports.metrics, JSON.stringify(metrics, null, 2));
583
605
  const inbox = (0, kernel_js_1.memoryInbox)(projectDir);
584
- (0, node_fs_1.writeFileSync)(inboxPath, JSON.stringify(inbox, null, 2));
585
- (0, node_fs_1.writeFileSync)(qualityPath, JSON.stringify((0, kernel_js_1.qualityReport)(projectDir), null, 2));
586
- (0, node_fs_1.writeFileSync)(benchmarkPath, JSON.stringify(viewerBenchmarkReport(projectDir), null, 2));
587
- (0, node_fs_1.writeFileSync)(contributorsPath, JSON.stringify((0, kernel_js_1.kageContributors)(projectDir), null, 2));
588
- (0, node_fs_1.writeFileSync)(profilePath, JSON.stringify((0, kernel_js_1.kageProjectProfile)(projectDir), null, 2));
589
- (0, node_fs_1.writeFileSync)(xrayPath, JSON.stringify((0, kernel_js_1.kageRepoXray)(projectDir), null, 2));
590
- (0, node_fs_1.writeFileSync)(capabilitiesPath, JSON.stringify((0, kernel_js_1.kageCapabilityAudit)(projectDir), null, 2));
591
- (0, node_fs_1.writeFileSync)(slotsPath, JSON.stringify((0, kernel_js_1.kageContextSlots)(projectDir), null, 2));
592
- (0, node_fs_1.writeFileSync)(decisionsPath, JSON.stringify((0, kernel_js_1.kageDecisionIntelligence)(projectDir), null, 2));
593
- (0, node_fs_1.writeFileSync)(riskPath, JSON.stringify((0, kernel_js_1.kageRisk)(projectDir), null, 2));
594
- (0, node_fs_1.writeFileSync)(moduleHealthPath, JSON.stringify((0, kernel_js_1.kageModuleHealth)(projectDir), null, 2));
595
- (0, node_fs_1.writeFileSync)(graphInsightsPath, JSON.stringify((0, kernel_js_1.kageGraphInsights)(projectDir), null, 2));
596
- (0, node_fs_1.writeFileSync)(workspacePath, JSON.stringify((0, kernel_js_1.kageWorkspace)(projectDir), null, 2));
597
- (0, node_fs_1.writeFileSync)(sessionsPath, JSON.stringify((0, kernel_js_1.kageSessionCaptureReport)(projectDir), null, 2));
598
- (0, node_fs_1.writeFileSync)(replayPath, JSON.stringify((0, kernel_js_1.kageSessionReplay)(projectDir), null, 2));
599
- (0, node_fs_1.writeFileSync)(memoryAccessPath, JSON.stringify((0, kernel_js_1.kageMemoryAccess)(projectDir), null, 2));
600
- (0, node_fs_1.writeFileSync)(memoryAuditPath, JSON.stringify((0, kernel_js_1.kageMemoryAudit)(projectDir), null, 2));
601
- (0, node_fs_1.writeFileSync)(handoffPath, JSON.stringify((0, kernel_js_1.kageMemoryHandoff)(projectDir), null, 2));
602
- (0, node_fs_1.writeFileSync)(lifecyclePath, JSON.stringify((0, kernel_js_1.kageMemoryLifecycle)(projectDir), null, 2));
603
- (0, node_fs_1.writeFileSync)(timelinePath, JSON.stringify((0, kernel_js_1.kageMemoryTimeline)(projectDir), null, 2));
604
- (0, node_fs_1.writeFileSync)(lineagePath, JSON.stringify((0, kernel_js_1.kageMemoryLineage)(projectDir), null, 2));
605
- (0, node_fs_1.writeFileSync)(setupPath, JSON.stringify((0, kernel_js_1.setupDoctor)(projectDir), null, 2));
606
- (0, node_fs_1.writeFileSync)(trustPath, JSON.stringify((0, kernel_js_1.benchmarkTrust)(projectDir), null, 2));
607
- (0, node_fs_1.writeFileSync)(suppressedPath, JSON.stringify((0, kernel_js_1.kageSuppressedMemory)(projectDir), null, 2));
606
+ (0, node_fs_1.writeFileSync)(reports.inbox, JSON.stringify(inbox, null, 2));
607
+ (0, node_fs_1.writeFileSync)(reports.quality, JSON.stringify((0, kernel_js_1.qualityReport)(projectDir), null, 2));
608
+ (0, node_fs_1.writeFileSync)(reports.benchmark, JSON.stringify(viewerBenchmarkReport(projectDir), null, 2));
609
+ (0, node_fs_1.writeFileSync)(reports.contributors, JSON.stringify((0, kernel_js_1.kageContributors)(projectDir), null, 2));
610
+ (0, node_fs_1.writeFileSync)(reports.profile, JSON.stringify((0, kernel_js_1.kageProjectProfile)(projectDir), null, 2));
611
+ (0, node_fs_1.writeFileSync)(reports.xray, JSON.stringify((0, kernel_js_1.kageRepoXray)(projectDir), null, 2));
612
+ (0, node_fs_1.writeFileSync)(reports.capabilities, JSON.stringify((0, kernel_js_1.kageCapabilityAudit)(projectDir), null, 2));
613
+ (0, node_fs_1.writeFileSync)(reports.slots, JSON.stringify((0, kernel_js_1.kageContextSlots)(projectDir), null, 2));
614
+ (0, node_fs_1.writeFileSync)(reports.decisions, JSON.stringify((0, kernel_js_1.kageDecisionIntelligence)(projectDir), null, 2));
615
+ (0, node_fs_1.writeFileSync)(reports.risk, JSON.stringify((0, kernel_js_1.kageRisk)(projectDir), null, 2));
616
+ (0, node_fs_1.writeFileSync)(reports.moduleHealth, JSON.stringify((0, kernel_js_1.kageModuleHealth)(projectDir), null, 2));
617
+ (0, node_fs_1.writeFileSync)(reports.graphInsights, JSON.stringify((0, kernel_js_1.kageGraphInsights)(projectDir), null, 2));
618
+ (0, node_fs_1.writeFileSync)(reports.workspace, JSON.stringify((0, kernel_js_1.kageWorkspace)(projectDir), null, 2));
619
+ (0, node_fs_1.writeFileSync)(reports.sessions, JSON.stringify((0, kernel_js_1.kageSessionCaptureReport)(projectDir), null, 2));
620
+ (0, node_fs_1.writeFileSync)(reports.replay, JSON.stringify((0, kernel_js_1.kageSessionReplay)(projectDir), null, 2));
621
+ (0, node_fs_1.writeFileSync)(reports.memoryAccess, JSON.stringify((0, kernel_js_1.kageMemoryAccess)(projectDir), null, 2));
622
+ (0, node_fs_1.writeFileSync)(reports.memoryAudit, JSON.stringify((0, kernel_js_1.kageMemoryAudit)(projectDir), null, 2));
623
+ (0, node_fs_1.writeFileSync)(reports.handoff, JSON.stringify((0, kernel_js_1.kageMemoryHandoff)(projectDir), null, 2));
624
+ (0, node_fs_1.writeFileSync)(reports.lifecycle, JSON.stringify((0, kernel_js_1.kageMemoryLifecycle)(projectDir), null, 2));
625
+ (0, node_fs_1.writeFileSync)(reports.activity, JSON.stringify((0, kernel_js_1.kageActivity)(projectDir), null, 2));
626
+ (0, node_fs_1.writeFileSync)(reports.timeline, JSON.stringify((0, kernel_js_1.kageMemoryTimeline)(projectDir), null, 2));
627
+ (0, node_fs_1.writeFileSync)(reports.lineage, JSON.stringify((0, kernel_js_1.kageMemoryLineage)(projectDir), null, 2));
628
+ (0, node_fs_1.writeFileSync)(reports.setup, JSON.stringify((0, kernel_js_1.setupDoctor)(projectDir), null, 2));
629
+ (0, node_fs_1.writeFileSync)(reports.trust, JSON.stringify((0, kernel_js_1.benchmarkTrust)(projectDir), null, 2));
630
+ (0, node_fs_1.writeFileSync)(reports.suppressed, JSON.stringify((0, kernel_js_1.kageSuppressedMemory)(projectDir), null, 2));
608
631
  }
609
632
  catch {
610
633
  // non-fatal: viewer will show 404 for reports if generation fails
611
634
  }
612
- const url = `http://${host}:${port}/viewer/index.html?graph=${encodeURIComponent(graphPath)}&code=${encodeURIComponent(codePath)}&metrics=${encodeURIComponent(metricsPath)}&inbox=${encodeURIComponent(inboxPath)}&review=${encodeURIComponent(reviewPath)}&pending=${encodeURIComponent(pendingDir)}&quality=${encodeURIComponent(qualityPath)}&benchmark=${encodeURIComponent(benchmarkPath)}&contributors=${encodeURIComponent(contributorsPath)}&profile=${encodeURIComponent(profilePath)}&xray=${encodeURIComponent(xrayPath)}&capabilities=${encodeURIComponent(capabilitiesPath)}&slots=${encodeURIComponent(slotsPath)}&decisions=${encodeURIComponent(decisionsPath)}&risk=${encodeURIComponent(riskPath)}&moduleHealth=${encodeURIComponent(moduleHealthPath)}&graphInsights=${encodeURIComponent(graphInsightsPath)}&workspace=${encodeURIComponent(workspacePath)}&sessions=${encodeURIComponent(sessionsPath)}&replay=${encodeURIComponent(replayPath)}&memoryAccess=${encodeURIComponent(memoryAccessPath)}&memoryAudit=${encodeURIComponent(memoryAuditPath)}&handoff=${encodeURIComponent(handoffPath)}&lifecycle=${encodeURIComponent(lifecyclePath)}&timeline=${encodeURIComponent(timelinePath)}&lineage=${encodeURIComponent(lineagePath)}&setup=${encodeURIComponent(setupPath)}&trust=${encodeURIComponent(trustPath)}&suppressed=${encodeURIComponent(suppressedPath)}&view=code`;
635
+ const url = viewerUrl(host, port, projectRoot);
613
636
  const server = (0, node_http_1.createServer)((req, res) => {
614
637
  const requestUrl = new URL(req.url ?? "/", `http://${host}:${port}`);
615
638
  let filePath = null;