@kage-core/kage-graph-mcp 1.1.37 → 1.2.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 +99 -4
- package/dist/daemon.js +31 -1
- package/dist/index.js +116 -5
- package/dist/kernel.js +896 -18
- package/package.json +1 -1
- package/viewer/app.js +216 -63
- package/viewer/data.html +6 -6
- package/viewer/graph.html +6 -6
- package/viewer/index.html +18 -7
- package/viewer/intel.html +6 -6
- package/viewer/memory.html +6 -6
- package/viewer/owners.html +6 -6
- package/viewer/review.html +7 -7
- package/viewer/styles.css +149 -1
package/dist/cli.js
CHANGED
|
@@ -29,6 +29,8 @@ Usage:
|
|
|
29
29
|
kage hook uninstall --project <dir> [--json]
|
|
30
30
|
kage refresh --project <dir> [--full] [--json]
|
|
31
31
|
kage gc --project <dir> [--dry-run] [--force] [--json]
|
|
32
|
+
kage compact --project <dir> [--dry-run] [--json]
|
|
33
|
+
kage verify --project <dir> [--id <packet-id>] [--json]
|
|
32
34
|
kage pr summarize --project <dir> [--json]
|
|
33
35
|
kage pr check --project <dir> [--json]
|
|
34
36
|
kage upgrade [--dry-run]
|
|
@@ -47,6 +49,7 @@ Usage:
|
|
|
47
49
|
kage supersede --project <dir> --packet <old-id> --replacement <new-id> [--reason <text>] [--json]
|
|
48
50
|
kage contributors --project <dir> [--json]
|
|
49
51
|
kage profile --project <dir> [--json]
|
|
52
|
+
kage xray --project <dir> [--json]
|
|
50
53
|
kage capabilities --project <dir> [--json]
|
|
51
54
|
kage decisions --project <dir> [--json]
|
|
52
55
|
kage module-health --project <dir> [--json]
|
|
@@ -73,14 +76,14 @@ Usage:
|
|
|
73
76
|
kage graph "<query>" --project <dir> [--json]
|
|
74
77
|
kage graph-registry --project <dir> [--json]
|
|
75
78
|
kage embeddings build --project <dir> [--model Xenova/all-MiniLM-L6-v2] [--json]
|
|
76
|
-
kage recall "<query>" --project <dir> [--json] [--explain] [--embeddings]
|
|
79
|
+
kage recall "<query>" --project <dir> [--json] [--explain] [--embeddings] [--max-context-tokens <n>] [--structural-hops <n>]
|
|
77
80
|
kage observe --project <dir> --event <json>
|
|
78
81
|
kage sessions --project <dir> [--json]
|
|
79
82
|
kage replay --project <dir> [--session <id>] [--limit <n>] [--json]
|
|
80
83
|
kage distill --project <dir> --session <id>
|
|
81
|
-
kage learn --project <dir> --learning <text> [--title <title>] [--type <type>] [--evidence <text>] [--verified-by <text>] [--tags a,b] [--paths a,b]
|
|
84
|
+
kage learn --project <dir> --learning <text> [--title <title>] [--type <type>] [--evidence <text>] [--verified-by <text>] [--tags a,b] [--paths a,b] [--graph-nodes a,b] [--allow-missing-paths]
|
|
82
85
|
kage feedback --project <dir> --packet <packet-id> --kind helpful|wrong|stale
|
|
83
|
-
kage capture --project <dir> --title <title> --body <body> [--type <type>] [--summary <summary>] [--tags a,b] [--paths a,b] [--stack a,b]
|
|
86
|
+
kage capture --project <dir> --title <title> --body <body> [--type <type>] [--summary <summary>] [--tags a,b] [--paths a,b] [--stack a,b] [--graph-nodes a,b] [--allow-missing-paths]
|
|
84
87
|
kage propose --project <dir> --from-diff
|
|
85
88
|
kage review-artifact --project <dir>
|
|
86
89
|
kage promote --project <dir> --public <packet-id>
|
|
@@ -403,6 +406,65 @@ async function main() {
|
|
|
403
406
|
}
|
|
404
407
|
return;
|
|
405
408
|
}
|
|
409
|
+
if (command === "compact") {
|
|
410
|
+
const project = projectArg(args);
|
|
411
|
+
const dryRun = args.includes("--dry-run");
|
|
412
|
+
const result = (0, kernel_js_1.compactProject)(project, { dryRun });
|
|
413
|
+
if (args.includes("--json")) {
|
|
414
|
+
console.log(JSON.stringify(result, null, 2));
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
const label = dryRun ? " [dry-run]" : "";
|
|
418
|
+
console.log(`Kage compact${label} — scanned ${result.total_scanned} packets`);
|
|
419
|
+
if (result.pruned_citations.length) {
|
|
420
|
+
console.log(`\nPruned dead citations (${result.pruned_citations.length}):`);
|
|
421
|
+
for (const p of result.pruned_citations)
|
|
422
|
+
console.log(` ✂ ${p.title} — removed ${p.removed_paths.join(", ")}`);
|
|
423
|
+
}
|
|
424
|
+
if (result.deprecated.length) {
|
|
425
|
+
console.log(`\nDeprecated stale (${result.deprecated.length}):`);
|
|
426
|
+
for (const p of result.deprecated)
|
|
427
|
+
console.log(` ✗ ${p.title} — ${p.reason}`);
|
|
428
|
+
}
|
|
429
|
+
if (result.duplicate_clusters.length) {
|
|
430
|
+
console.log(`\nDuplicate clusters to merge (${result.duplicate_clusters.length}) — review with kage_compact / kage supersede:`);
|
|
431
|
+
for (const cluster of result.duplicate_clusters) {
|
|
432
|
+
console.log(` ~${cluster.score} similarity:`);
|
|
433
|
+
for (const member of cluster.packets)
|
|
434
|
+
console.log(` • ${member.title} (${member.id})`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (!result.pruned_citations.length && !result.deprecated.length && !result.duplicate_clusters.length) {
|
|
438
|
+
console.log("Nothing to compact — memory is clean.");
|
|
439
|
+
}
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
if (command === "verify") {
|
|
443
|
+
const project = projectArg(args);
|
|
444
|
+
const idFlag = args.indexOf("--id");
|
|
445
|
+
const id = idFlag >= 0 ? args[idFlag + 1] : undefined;
|
|
446
|
+
const result = (0, kernel_js_1.verifyCitations)(project, { id });
|
|
447
|
+
if (args.includes("--json")) {
|
|
448
|
+
console.log(JSON.stringify(result, null, 2));
|
|
449
|
+
if (!result.ok)
|
|
450
|
+
process.exit(2);
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
if (!result.ok) {
|
|
454
|
+
console.log(`Verification failed:\n${result.errors.map((error) => ` - ${error}`).join("\n")}`);
|
|
455
|
+
process.exit(2);
|
|
456
|
+
}
|
|
457
|
+
console.log(`Kage verify — ${result.checked} packet(s): ${result.valid} valid, ${result.stale} stale, ${result.ungrounded} ungrounded`);
|
|
458
|
+
for (const entry of result.packets.filter((p) => p.stale || !p.grounded)) {
|
|
459
|
+
const flags = [entry.stale ? `stale:${entry.stale_severity}` : "", entry.grounded ? "" : "ungrounded"].filter(Boolean).join(", ");
|
|
460
|
+
console.log(` ⚠ ${entry.title} [${flags}]`);
|
|
461
|
+
if (entry.missing_paths.length)
|
|
462
|
+
console.log(` missing: ${entry.missing_paths.join(", ")}`);
|
|
463
|
+
for (const reason of entry.stale_reasons)
|
|
464
|
+
console.log(` - ${reason}`);
|
|
465
|
+
}
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
406
468
|
if (command === "refresh") {
|
|
407
469
|
const result = (0, kernel_js_1.refreshProject)(projectArg(args), { full: args.includes("--full") });
|
|
408
470
|
if (args.includes("--json")) {
|
|
@@ -692,6 +754,27 @@ async function main() {
|
|
|
692
754
|
console.log(`Warnings:\n${result.warnings.map((warning) => ` - ${warning}`).join("\n")}`);
|
|
693
755
|
return;
|
|
694
756
|
}
|
|
757
|
+
if (command === "xray" || command === "repo-xray") {
|
|
758
|
+
const result = (0, kernel_js_1.kageRepoXray)(projectArg(args));
|
|
759
|
+
if (args.includes("--json")) {
|
|
760
|
+
console.log(JSON.stringify(result, null, 2));
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
console.log(`Kage Repo X-Ray: ${result.summary}`);
|
|
764
|
+
for (const line of result.first_use_script)
|
|
765
|
+
console.log(`- ${line}`);
|
|
766
|
+
for (const layer of result.layers) {
|
|
767
|
+
console.log(`\n${layer.title}: ${layer.summary}`);
|
|
768
|
+
for (const item of layer.items.slice(0, 5)) {
|
|
769
|
+
console.log(`- ${item.path}: ${item.evidence.slice(0, 2).join("; ")}`);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
if (result.next_actions.length)
|
|
773
|
+
console.log(`\nNext: ${result.next_actions[0]}`);
|
|
774
|
+
if (result.warnings.length)
|
|
775
|
+
console.log(`Warnings:\n${result.warnings.map((warning) => ` - ${warning}`).join("\n")}`);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
695
778
|
if (command === "decisions") {
|
|
696
779
|
const result = (0, kernel_js_1.kageDecisionIntelligence)(projectArg(args));
|
|
697
780
|
if (args.includes("--json")) {
|
|
@@ -1355,12 +1438,17 @@ async function main() {
|
|
|
1355
1438
|
tags: listArg(takeArg(args, "--tags")),
|
|
1356
1439
|
paths: listArg(takeArg(args, "--paths")),
|
|
1357
1440
|
stack: listArg(takeArg(args, "--stack")),
|
|
1441
|
+
graphNodes: listArg(takeArg(args, "--graph-nodes")),
|
|
1442
|
+
allowMissingPaths: args.includes("--allow-missing-paths"),
|
|
1443
|
+
strictCitations: true,
|
|
1358
1444
|
});
|
|
1359
1445
|
if (!result.ok) {
|
|
1360
1446
|
console.error(`Learning capture blocked:\n${result.errors.map((error) => ` - ${error}`).join("\n")}`);
|
|
1361
1447
|
process.exit(2);
|
|
1362
1448
|
}
|
|
1363
1449
|
console.log(`Captured session learning: ${result.path}`);
|
|
1450
|
+
if (result.warnings?.length)
|
|
1451
|
+
console.log(`Warnings:\n${result.warnings.map((warning) => ` - ${warning}`).join("\n")}`);
|
|
1364
1452
|
console.log("Repo-local memory is written immediately. Promotion to org/global still requires explicit review.");
|
|
1365
1453
|
return;
|
|
1366
1454
|
}
|
|
@@ -1543,9 +1631,11 @@ async function main() {
|
|
|
1543
1631
|
const query = firstPositional(args);
|
|
1544
1632
|
if (!query)
|
|
1545
1633
|
usage();
|
|
1634
|
+
const maxContextTokens = args.includes("--max-context-tokens") ? numberArg(args, "--max-context-tokens", 0) : undefined;
|
|
1635
|
+
const structuralHops = args.includes("--structural-hops") ? numberArg(args, "--structural-hops", 2) : undefined;
|
|
1546
1636
|
const result = args.includes("--embeddings")
|
|
1547
1637
|
? await (0, kernel_js_1.recallWithEmbeddings)(projectArg(args), query, 5, args.includes("--explain"))
|
|
1548
|
-
: (0, kernel_js_1.recall)(projectArg(args), query, 5, args.includes("--explain"));
|
|
1638
|
+
: (0, kernel_js_1.recall)(projectArg(args), query, 5, args.includes("--explain"), { maxContextTokens, structuralHops });
|
|
1549
1639
|
if (args.includes("--json"))
|
|
1550
1640
|
console.log(JSON.stringify(result, null, 2));
|
|
1551
1641
|
else
|
|
@@ -1689,6 +1779,9 @@ async function main() {
|
|
|
1689
1779
|
tags: listArg(takeArg(args, "--tags")),
|
|
1690
1780
|
paths: listArg(takeArg(args, "--paths")),
|
|
1691
1781
|
stack: listArg(takeArg(args, "--stack")),
|
|
1782
|
+
graphNodes: listArg(takeArg(args, "--graph-nodes")),
|
|
1783
|
+
allowMissingPaths: args.includes("--allow-missing-paths"),
|
|
1784
|
+
strictCitations: true,
|
|
1692
1785
|
};
|
|
1693
1786
|
const result = (0, kernel_js_1.capture)(input);
|
|
1694
1787
|
if (!result.ok) {
|
|
@@ -1696,6 +1789,8 @@ async function main() {
|
|
|
1696
1789
|
process.exit(2);
|
|
1697
1790
|
}
|
|
1698
1791
|
console.log(`Captured repo-local packet: ${result.path}`);
|
|
1792
|
+
if (result.warnings?.length)
|
|
1793
|
+
console.log(`Warnings:\n${result.warnings.map((warning) => ` - ${warning}`).join("\n")}`);
|
|
1699
1794
|
console.log("Repo-local memory is written immediately. Promotion to org/global still requires explicit review.");
|
|
1700
1795
|
return;
|
|
1701
1796
|
}
|
package/dist/daemon.js
CHANGED
|
@@ -212,9 +212,22 @@ function daemonContextReport(projectDir, body) {
|
|
|
212
212
|
sessionId: typeof body.session_id === "string" ? body.session_id : undefined,
|
|
213
213
|
limit: 5,
|
|
214
214
|
});
|
|
215
|
+
const teammateBrief = (0, kernel_js_1.kageTeammateBrief)(projectDir, {
|
|
216
|
+
query,
|
|
217
|
+
targets: explicitTargets,
|
|
218
|
+
changedFiles,
|
|
219
|
+
recallResult,
|
|
220
|
+
riskResult,
|
|
221
|
+
reconciliation,
|
|
222
|
+
});
|
|
223
|
+
const learningLedger = typeof body.session_id === "string" && body.session_id.trim()
|
|
224
|
+
? (0, kernel_js_1.kageSessionLearningLedger)(projectDir, { sessionId: body.session_id, limit: 20 })
|
|
225
|
+
: null;
|
|
215
226
|
const validationText = validation.ok ? "Memory healthy." : `Warnings: ${validation.warnings.join("; ")}`;
|
|
216
227
|
const contextBlock = [
|
|
217
228
|
recallResult.context_block,
|
|
229
|
+
teammateBrief.context_block,
|
|
230
|
+
learningLedger ? learningLedger.context_block : "",
|
|
218
231
|
graphResult.context_block ? `\n## Graph Facts\n${graphResult.context_block}` : "",
|
|
219
232
|
riskResult ? riskContextBlock(riskResult) : "",
|
|
220
233
|
dependencyResult ? `\n## Dependency Path\n${dependencyResult.summary}${dependencyResult.path.length ? `\nPath: ${dependencyResult.path.join(" -> ")}` : ""}` : "",
|
|
@@ -225,6 +238,8 @@ function daemonContextReport(projectDir, body) {
|
|
|
225
238
|
context_block: contextBlock,
|
|
226
239
|
recall: recallResult,
|
|
227
240
|
graph: graphResult,
|
|
241
|
+
teammate_brief: teammateBrief,
|
|
242
|
+
learning_ledger: learningLedger,
|
|
228
243
|
risk: riskResult,
|
|
229
244
|
dependency_path: dependencyResult,
|
|
230
245
|
validation,
|
|
@@ -267,9 +282,11 @@ function daemonDoctor(projectDir) {
|
|
|
267
282
|
`POST http://${DEFAULT_HOST}:${restPort}/kage/feedback`,
|
|
268
283
|
`POST http://${DEFAULT_HOST}:${restPort}/kage/observe`,
|
|
269
284
|
`POST http://${DEFAULT_HOST}:${restPort}/kage/distill`,
|
|
285
|
+
`GET http://${DEFAULT_HOST}:${restPort}/kage/learning-ledger`,
|
|
270
286
|
`GET http://${DEFAULT_HOST}:${restPort}/kage/replay`,
|
|
271
287
|
`GET http://${DEFAULT_HOST}:${restPort}/kage/setup-doctor`,
|
|
272
288
|
`GET http://${DEFAULT_HOST}:${restPort}/kage/profile`,
|
|
289
|
+
`GET http://${DEFAULT_HOST}:${restPort}/kage/xray`,
|
|
273
290
|
`GET http://${DEFAULT_HOST}:${restPort}/kage/capabilities`,
|
|
274
291
|
`GET http://${DEFAULT_HOST}:${restPort}/kage/context-slots`,
|
|
275
292
|
`POST http://${DEFAULT_HOST}:${restPort}/kage/context-slots`,
|
|
@@ -369,6 +386,10 @@ async function startDaemon(projectDir, options = {}) {
|
|
|
369
386
|
json(res, 200, (0, kernel_js_1.kageProjectProfile)(projectDir));
|
|
370
387
|
return;
|
|
371
388
|
}
|
|
389
|
+
if (req.method === "GET" && url.pathname === "/kage/xray") {
|
|
390
|
+
json(res, 200, (0, kernel_js_1.kageRepoXray)(projectDir));
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
372
393
|
if (req.method === "GET" && url.pathname === "/kage/capabilities") {
|
|
373
394
|
json(res, 200, (0, kernel_js_1.kageCapabilityAudit)(projectDir));
|
|
374
395
|
return;
|
|
@@ -380,6 +401,13 @@ async function startDaemon(projectDir, options = {}) {
|
|
|
380
401
|
}));
|
|
381
402
|
return;
|
|
382
403
|
}
|
|
404
|
+
if (req.method === "GET" && url.pathname === "/kage/learning-ledger") {
|
|
405
|
+
json(res, 200, (0, kernel_js_1.kageSessionLearningLedger)(projectDir, {
|
|
406
|
+
sessionId: url.searchParams.get("session") ?? undefined,
|
|
407
|
+
limit: Number(url.searchParams.get("limit") ?? 50),
|
|
408
|
+
}));
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
383
411
|
if (req.method === "GET" && url.pathname === "/kage/context-slots") {
|
|
384
412
|
json(res, 200, (0, kernel_js_1.kageContextSlots)(projectDir));
|
|
385
413
|
return;
|
|
@@ -528,6 +556,7 @@ async function startViewer(projectDir, options = {}) {
|
|
|
528
556
|
const benchmarkPath = (0, node_path_1.join)(reportsDir, "benchmark.json");
|
|
529
557
|
const contributorsPath = (0, node_path_1.join)(reportsDir, "contributors.json");
|
|
530
558
|
const profilePath = (0, node_path_1.join)(reportsDir, "profile.json");
|
|
559
|
+
const xrayPath = (0, node_path_1.join)(reportsDir, "xray.json");
|
|
531
560
|
const capabilitiesPath = (0, node_path_1.join)(reportsDir, "capabilities.json");
|
|
532
561
|
const slotsPath = (0, node_path_1.join)(reportsDir, "context-slots.json");
|
|
533
562
|
const decisionsPath = (0, node_path_1.join)(reportsDir, "decisions.json");
|
|
@@ -555,6 +584,7 @@ async function startViewer(projectDir, options = {}) {
|
|
|
555
584
|
(0, node_fs_1.writeFileSync)(benchmarkPath, JSON.stringify(viewerBenchmarkReport(projectDir), null, 2));
|
|
556
585
|
(0, node_fs_1.writeFileSync)(contributorsPath, JSON.stringify((0, kernel_js_1.kageContributors)(projectDir), null, 2));
|
|
557
586
|
(0, node_fs_1.writeFileSync)(profilePath, JSON.stringify((0, kernel_js_1.kageProjectProfile)(projectDir), null, 2));
|
|
587
|
+
(0, node_fs_1.writeFileSync)(xrayPath, JSON.stringify((0, kernel_js_1.kageRepoXray)(projectDir), null, 2));
|
|
558
588
|
(0, node_fs_1.writeFileSync)(capabilitiesPath, JSON.stringify((0, kernel_js_1.kageCapabilityAudit)(projectDir), null, 2));
|
|
559
589
|
(0, node_fs_1.writeFileSync)(slotsPath, JSON.stringify((0, kernel_js_1.kageContextSlots)(projectDir), null, 2));
|
|
560
590
|
(0, node_fs_1.writeFileSync)(decisionsPath, JSON.stringify((0, kernel_js_1.kageDecisionIntelligence)(projectDir), null, 2));
|
|
@@ -575,7 +605,7 @@ async function startViewer(projectDir, options = {}) {
|
|
|
575
605
|
catch {
|
|
576
606
|
// non-fatal: viewer will show 404 for reports if generation fails
|
|
577
607
|
}
|
|
578
|
-
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)}&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)}&view=code`;
|
|
608
|
+
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)}&view=code`;
|
|
579
609
|
const server = (0, node_http_1.createServer)((req, res) => {
|
|
580
610
|
const requestUrl = new URL(req.url ?? "/", `http://${host}:${port}`);
|
|
581
611
|
let filePath = null;
|
package/dist/index.js
CHANGED
|
@@ -152,6 +152,8 @@ function listTools() {
|
|
|
152
152
|
explain: { type: "boolean" },
|
|
153
153
|
embeddings: { type: "boolean" },
|
|
154
154
|
json: { type: "boolean" },
|
|
155
|
+
max_context_tokens: { type: "number" },
|
|
156
|
+
structural_hops: { type: "number", description: "If >0, append a bounded N-hop code-graph blast radius seeded from the recalled memory's files." },
|
|
155
157
|
},
|
|
156
158
|
required: ["query", "project_dir"],
|
|
157
159
|
},
|
|
@@ -267,6 +269,17 @@ function listTools() {
|
|
|
267
269
|
required: ["project_dir"],
|
|
268
270
|
},
|
|
269
271
|
},
|
|
272
|
+
{
|
|
273
|
+
name: "kage_xray",
|
|
274
|
+
description: "Return a first-use Repo X-Ray: code structure layers for entry points, core files, risk, tests, memory overlay, and knowledge gaps.",
|
|
275
|
+
inputSchema: {
|
|
276
|
+
type: "object",
|
|
277
|
+
properties: {
|
|
278
|
+
project_dir: { type: "string" },
|
|
279
|
+
},
|
|
280
|
+
required: ["project_dir"],
|
|
281
|
+
},
|
|
282
|
+
},
|
|
270
283
|
{
|
|
271
284
|
name: "kage_capabilities",
|
|
272
285
|
description: "Return an evidence-backed Kage memory-system capability audit across repo memory, collaboration/session proof, benchmarks, and dashboard/viewer readiness.",
|
|
@@ -657,7 +670,7 @@ function listTools() {
|
|
|
657
670
|
},
|
|
658
671
|
{
|
|
659
672
|
name: "kage_learn",
|
|
660
|
-
description: "Capture an actual reusable learning from the current session as repo-local memory. Prefer this over diff proposal when the agent knows what was learned.",
|
|
673
|
+
description: "Capture an actual reusable learning from the current session as repo-local memory. Prefer this over diff proposal when the agent knows what was learned. Capture is rejected if every referenced path is missing from the repo; set allow_missing_paths to record anyway (e.g. a file you are about to create).",
|
|
661
674
|
inputSchema: {
|
|
662
675
|
type: "object",
|
|
663
676
|
properties: {
|
|
@@ -670,13 +683,15 @@ function listTools() {
|
|
|
670
683
|
tags: { type: "array", items: { type: "string" } },
|
|
671
684
|
paths: { type: "array", items: { type: "string" } },
|
|
672
685
|
stack: { type: "array", items: { type: "string" } },
|
|
686
|
+
graph_nodes: { type: "array", items: { type: "string" } },
|
|
687
|
+
allow_missing_paths: { type: "boolean" },
|
|
673
688
|
},
|
|
674
689
|
required: ["project_dir", "learning"],
|
|
675
690
|
},
|
|
676
691
|
},
|
|
677
692
|
{
|
|
678
693
|
name: "kage_capture",
|
|
679
|
-
description: "Create a repo-local Kage memory packet immediately. Org/global promotion still requires explicit human review.",
|
|
694
|
+
description: "Create a repo-local Kage memory packet immediately. Org/global promotion still requires explicit human review. Capture is rejected if every referenced path is missing from the repo; set allow_missing_paths to record anyway.",
|
|
680
695
|
inputSchema: {
|
|
681
696
|
type: "object",
|
|
682
697
|
properties: {
|
|
@@ -688,10 +703,36 @@ function listTools() {
|
|
|
688
703
|
tags: { type: "array", items: { type: "string" } },
|
|
689
704
|
paths: { type: "array", items: { type: "string" } },
|
|
690
705
|
stack: { type: "array", items: { type: "string" } },
|
|
706
|
+
graph_nodes: { type: "array", items: { type: "string" }, description: "Code-graph node references (symbol/route/file) this memory is about." },
|
|
707
|
+
allow_missing_paths: { type: "boolean" },
|
|
691
708
|
},
|
|
692
709
|
required: ["project_dir", "title", "body"],
|
|
693
710
|
},
|
|
694
711
|
},
|
|
712
|
+
{
|
|
713
|
+
name: "kage_verify_citations",
|
|
714
|
+
description: "Verify that a memory packet's cited file paths still exist and that the memory is not stale, before trusting it. Pass an id to check one packet, or omit to audit all approved repo memory. Returns grounding and staleness for each.",
|
|
715
|
+
inputSchema: {
|
|
716
|
+
type: "object",
|
|
717
|
+
properties: {
|
|
718
|
+
project_dir: { type: "string" },
|
|
719
|
+
id: { type: "string" },
|
|
720
|
+
},
|
|
721
|
+
required: ["project_dir"],
|
|
722
|
+
},
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
name: "kage_compact",
|
|
726
|
+
description: "Consolidate repo memory: prune dead citations, deprecate hard-stale packets, and surface near-duplicate clusters to merge (via kage_supersede). Defaults to a dry run; pass dry_run=false to apply pruning/deprecation. Duplicate merging stays an agent decision — no hosted LLM is used.",
|
|
727
|
+
inputSchema: {
|
|
728
|
+
type: "object",
|
|
729
|
+
properties: {
|
|
730
|
+
project_dir: { type: "string" },
|
|
731
|
+
dry_run: { type: "boolean" },
|
|
732
|
+
},
|
|
733
|
+
required: ["project_dir"],
|
|
734
|
+
},
|
|
735
|
+
},
|
|
695
736
|
{
|
|
696
737
|
name: "kage_observe",
|
|
697
738
|
description: "Store an automatic local observation event from an agent session. Observations are privacy-scanned, deduplicated, and never published automatically.",
|
|
@@ -737,6 +778,19 @@ function listTools() {
|
|
|
737
778
|
required: ["project_dir"],
|
|
738
779
|
},
|
|
739
780
|
},
|
|
781
|
+
{
|
|
782
|
+
name: "kage_learning_ledger",
|
|
783
|
+
description: "Return an agent-facing ledger that classifies observed session events into save, ignore, needs-evidence, or already-distilled memory decisions.",
|
|
784
|
+
inputSchema: {
|
|
785
|
+
type: "object",
|
|
786
|
+
properties: {
|
|
787
|
+
project_dir: { type: "string" },
|
|
788
|
+
session_id: { type: "string" },
|
|
789
|
+
limit: { type: "number" },
|
|
790
|
+
},
|
|
791
|
+
required: ["project_dir"],
|
|
792
|
+
},
|
|
793
|
+
},
|
|
740
794
|
{
|
|
741
795
|
name: "kage_session_replay",
|
|
742
796
|
description: "Return a privacy-preserving replay digest for observed agent sessions: timeline, touched paths, commands, durable candidates, and distill actions without raw transcript text.",
|
|
@@ -1042,8 +1096,21 @@ async function callTool(name, args) {
|
|
|
1042
1096
|
sessionId: typeof args?.session_id === "string" ? args.session_id : undefined,
|
|
1043
1097
|
limit: 5,
|
|
1044
1098
|
});
|
|
1099
|
+
const teammateBrief = (0, kernel_js_1.kageTeammateBrief)(projectDir, {
|
|
1100
|
+
query,
|
|
1101
|
+
targets: explicitTargets,
|
|
1102
|
+
changedFiles,
|
|
1103
|
+
recallResult,
|
|
1104
|
+
riskResult,
|
|
1105
|
+
reconciliation,
|
|
1106
|
+
});
|
|
1107
|
+
const learningLedger = typeof args?.session_id === "string" && args.session_id.trim()
|
|
1108
|
+
? (0, kernel_js_1.kageSessionLearningLedger)(projectDir, { sessionId: args.session_id, limit: 20 })
|
|
1109
|
+
: null;
|
|
1045
1110
|
const sections = [
|
|
1046
1111
|
recallResult.context_block,
|
|
1112
|
+
teammateBrief.context_block,
|
|
1113
|
+
learningLedger ? learningLedger.context_block : "",
|
|
1047
1114
|
graphResult.context_block ? `\n## Graph Facts\n${graphResult.context_block}` : "",
|
|
1048
1115
|
riskResult ? riskContextBlock(riskResult) : "",
|
|
1049
1116
|
dependencyResult ? `\n## Dependency Path\n${dependencyResult.summary}${dependencyResult.path.length ? `\nPath: ${dependencyResult.path.join(" -> ")}` : ""}` : "",
|
|
@@ -1055,9 +1122,11 @@ async function callTool(name, args) {
|
|
|
1055
1122
|
};
|
|
1056
1123
|
}
|
|
1057
1124
|
if (name === "kage_recall") {
|
|
1125
|
+
const maxContextTokens = typeof args?.max_context_tokens === "number" ? args.max_context_tokens : undefined;
|
|
1126
|
+
const structuralHops = typeof args?.structural_hops === "number" ? args.structural_hops : undefined;
|
|
1058
1127
|
const result = args?.embeddings
|
|
1059
1128
|
? await (0, kernel_js_1.recallWithEmbeddings)(String(args?.project_dir ?? ""), String(args?.query ?? ""), Number(args?.limit ?? 5), Boolean(args?.explain))
|
|
1060
|
-
: (0, kernel_js_1.recall)(String(args?.project_dir ?? ""), String(args?.query ?? ""), Number(args?.limit ?? 5), Boolean(args?.explain));
|
|
1129
|
+
: (0, kernel_js_1.recall)(String(args?.project_dir ?? ""), String(args?.query ?? ""), Number(args?.limit ?? 5), Boolean(args?.explain), { maxContextTokens, structuralHops });
|
|
1061
1130
|
return {
|
|
1062
1131
|
content: [{ type: "text", text: args?.json || args?.explain ? JSON.stringify(result, null, 2) : result.context_block }],
|
|
1063
1132
|
};
|
|
@@ -1125,6 +1194,12 @@ async function callTool(name, args) {
|
|
|
1125
1194
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
1126
1195
|
};
|
|
1127
1196
|
}
|
|
1197
|
+
if (name === "kage_xray") {
|
|
1198
|
+
const result = (0, kernel_js_1.kageRepoXray)(String(args?.project_dir ?? ""));
|
|
1199
|
+
return {
|
|
1200
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1128
1203
|
if (name === "kage_capabilities") {
|
|
1129
1204
|
const result = (0, kernel_js_1.kageCapabilityAudit)(String(args?.project_dir ?? ""));
|
|
1130
1205
|
return {
|
|
@@ -1360,13 +1435,17 @@ async function callTool(name, args) {
|
|
|
1360
1435
|
tags: arrayArg(args?.tags),
|
|
1361
1436
|
paths: arrayArg(args?.paths),
|
|
1362
1437
|
stack: arrayArg(args?.stack),
|
|
1438
|
+
graphNodes: arrayArg(args?.graph_nodes),
|
|
1439
|
+
allowMissingPaths: Boolean(args?.allow_missing_paths),
|
|
1440
|
+
strictCitations: true,
|
|
1363
1441
|
});
|
|
1442
|
+
const learnWarnings = result.warnings?.length ? `\nWarnings:\n${result.warnings.map((warning) => `- ${warning}`).join("\n")}` : "";
|
|
1364
1443
|
return {
|
|
1365
1444
|
content: [
|
|
1366
1445
|
{
|
|
1367
1446
|
type: "text",
|
|
1368
1447
|
text: result.ok
|
|
1369
|
-
? `Captured session learning: ${result.path}\nRepo-local memory is written immediately. Org/global promotion still requires explicit review
|
|
1448
|
+
? `Captured session learning: ${result.path}\nRepo-local memory is written immediately. Org/global promotion still requires explicit review.${learnWarnings}`
|
|
1370
1449
|
: `Learning capture blocked:\n${result.errors.map((error) => `- ${error}`).join("\n")}`,
|
|
1371
1450
|
},
|
|
1372
1451
|
],
|
|
@@ -1383,19 +1462,41 @@ async function callTool(name, args) {
|
|
|
1383
1462
|
tags: arrayArg(args?.tags),
|
|
1384
1463
|
paths: arrayArg(args?.paths),
|
|
1385
1464
|
stack: arrayArg(args?.stack),
|
|
1465
|
+
graphNodes: arrayArg(args?.graph_nodes),
|
|
1466
|
+
allowMissingPaths: Boolean(args?.allow_missing_paths),
|
|
1467
|
+
strictCitations: true,
|
|
1386
1468
|
});
|
|
1469
|
+
const captureWarnings = result.warnings?.length ? `\nWarnings:\n${result.warnings.map((warning) => `- ${warning}`).join("\n")}` : "";
|
|
1387
1470
|
return {
|
|
1388
1471
|
content: [
|
|
1389
1472
|
{
|
|
1390
1473
|
type: "text",
|
|
1391
1474
|
text: result.ok
|
|
1392
|
-
? `Captured repo-local packet: ${result.path}\nOrg/global promotion still requires explicit review
|
|
1475
|
+
? `Captured repo-local packet: ${result.path}\nOrg/global promotion still requires explicit review.${captureWarnings}`
|
|
1393
1476
|
: `Capture blocked:\n${result.errors.map((error) => `- ${error}`).join("\n")}`,
|
|
1394
1477
|
},
|
|
1395
1478
|
],
|
|
1396
1479
|
isError: !result.ok,
|
|
1397
1480
|
};
|
|
1398
1481
|
}
|
|
1482
|
+
if (name === "kage_verify_citations") {
|
|
1483
|
+
const result = (0, kernel_js_1.verifyCitations)(String(args?.project_dir ?? ""), {
|
|
1484
|
+
id: args?.id ? String(args.id) : undefined,
|
|
1485
|
+
});
|
|
1486
|
+
return {
|
|
1487
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
1488
|
+
isError: !result.ok,
|
|
1489
|
+
};
|
|
1490
|
+
}
|
|
1491
|
+
if (name === "kage_compact") {
|
|
1492
|
+
const result = (0, kernel_js_1.compactProject)(String(args?.project_dir ?? ""), {
|
|
1493
|
+
dryRun: args?.dry_run === undefined ? true : Boolean(args.dry_run),
|
|
1494
|
+
});
|
|
1495
|
+
return {
|
|
1496
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
1497
|
+
isError: !result.ok,
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1399
1500
|
if (name === "kage_observe") {
|
|
1400
1501
|
const projectDir = String(args?.project_dir ?? "");
|
|
1401
1502
|
const event = { ...args };
|
|
@@ -1420,6 +1521,16 @@ async function callTool(name, args) {
|
|
|
1420
1521
|
isError: false,
|
|
1421
1522
|
};
|
|
1422
1523
|
}
|
|
1524
|
+
if (name === "kage_learning_ledger") {
|
|
1525
|
+
const result = (0, kernel_js_1.kageSessionLearningLedger)(String(args?.project_dir ?? ""), {
|
|
1526
|
+
sessionId: args?.session_id ? String(args.session_id) : undefined,
|
|
1527
|
+
limit: typeof args?.limit === "number" ? args.limit : undefined,
|
|
1528
|
+
});
|
|
1529
|
+
return {
|
|
1530
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
1531
|
+
isError: false,
|
|
1532
|
+
};
|
|
1533
|
+
}
|
|
1423
1534
|
if (name === "kage_session_replay") {
|
|
1424
1535
|
const result = (0, kernel_js_1.kageSessionReplay)(String(args?.project_dir ?? ""), {
|
|
1425
1536
|
sessionId: args?.session_id ? String(args.session_id) : undefined,
|