@kage-core/kage-graph-mcp 1.1.6 → 1.1.8
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/README.md +5 -0
- package/dist/cli.js +27 -0
- package/dist/index.js +1 -1
- package/dist/kernel.js +71 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -137,6 +137,11 @@ meaningful file changes. Refresh rebuilds indexes, code graph, memory graph,
|
|
|
137
137
|
metrics, and stale-memory metadata. Memory is marked stale when status or
|
|
138
138
|
feedback says it is stale, its TTL expires, or grounded paths disappear.
|
|
139
139
|
|
|
140
|
+
Use `kage gc --project <repo> --dry-run` to preview stale packet cleanup.
|
|
141
|
+
`kage gc --project <repo>` marks stale repo packets deprecated, rebuilds
|
|
142
|
+
indexes/graphs/metrics, and keeps helpful-voted memories unless `--force` is
|
|
143
|
+
used.
|
|
144
|
+
|
|
140
145
|
Use `kage pr summarize --project <repo>` / `kage_pr_summarize` before handoff to
|
|
141
146
|
write branch review metadata and repo-local change memory from the git diff.
|
|
142
147
|
Use `kage pr check --project <repo>` / `kage_pr_check` before merge to verify
|
package/dist/cli.js
CHANGED
|
@@ -24,6 +24,7 @@ Usage:
|
|
|
24
24
|
kage daemon doctor --project <dir> [--json]
|
|
25
25
|
kage viewer --project <dir> [--port 3113]
|
|
26
26
|
kage refresh --project <dir> [--json]
|
|
27
|
+
kage gc --project <dir> [--dry-run] [--force] [--json]
|
|
27
28
|
kage pr summarize --project <dir> [--json]
|
|
28
29
|
kage pr check --project <dir> [--json]
|
|
29
30
|
kage upgrade [--dry-run]
|
|
@@ -302,6 +303,32 @@ async function main() {
|
|
|
302
303
|
await (0, daemon_js_1.startViewer)(projectArg(args), { port: numberArg(args, "--port", 3113) });
|
|
303
304
|
return;
|
|
304
305
|
}
|
|
306
|
+
if (command === "gc") {
|
|
307
|
+
const project = projectArg(args);
|
|
308
|
+
const dryRun = args.includes("--dry-run");
|
|
309
|
+
const force = args.includes("--force");
|
|
310
|
+
const result = (0, kernel_js_1.gcProject)(project, { dryRun, force });
|
|
311
|
+
if (args.includes("--json")) {
|
|
312
|
+
console.log(JSON.stringify(result, null, 2));
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
const label = dryRun ? " [dry-run]" : "";
|
|
316
|
+
console.log(`Kage GC${label} — scanned ${result.total_scanned} packets`);
|
|
317
|
+
if (result.deprecated.length) {
|
|
318
|
+
console.log(`\nDeprecated (${result.deprecated.length}):`);
|
|
319
|
+
for (const p of result.deprecated)
|
|
320
|
+
console.log(` ✗ ${p.title} — ${p.reason}`);
|
|
321
|
+
}
|
|
322
|
+
if (result.deleted.length) {
|
|
323
|
+
console.log(`\nDeleted (${result.deleted.length}):`);
|
|
324
|
+
for (const p of result.deleted)
|
|
325
|
+
console.log(` 🗑 ${p.title}`);
|
|
326
|
+
}
|
|
327
|
+
if (!result.deprecated.length && !result.deleted.length) {
|
|
328
|
+
console.log("No stale packets found — memory is clean.");
|
|
329
|
+
}
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
305
332
|
if (command === "refresh") {
|
|
306
333
|
const result = (0, kernel_js_1.refreshProject)(projectArg(args));
|
|
307
334
|
if (args.includes("--json")) {
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,7 @@ function arrayArg(value) {
|
|
|
54
54
|
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
55
55
|
return [];
|
|
56
56
|
}
|
|
57
|
-
const server = new index_js_1.Server({ name: "kage-graph", version: "1.1.
|
|
57
|
+
const server = new index_js_1.Server({ name: "kage-graph", version: "1.1.7" }, { capabilities: { tools: {} } });
|
|
58
58
|
function listTools() {
|
|
59
59
|
return [
|
|
60
60
|
{
|
package/dist/kernel.js
CHANGED
|
@@ -67,6 +67,7 @@ exports.buildKnowledgeGraph = buildKnowledgeGraph;
|
|
|
67
67
|
exports.buildIndexes = buildIndexes;
|
|
68
68
|
exports.indexProject = indexProject;
|
|
69
69
|
exports.refreshProject = refreshProject;
|
|
70
|
+
exports.gcProject = gcProject;
|
|
70
71
|
exports.installAgentPolicy = installAgentPolicy;
|
|
71
72
|
exports.recall = recall;
|
|
72
73
|
exports.queryCodeGraph = queryCodeGraph;
|
|
@@ -335,6 +336,9 @@ function repoKey(projectDir) {
|
|
|
335
336
|
}
|
|
336
337
|
return slugify((0, node_path_1.basename)(projectDir));
|
|
337
338
|
}
|
|
339
|
+
function repoDisplayName(projectDir) {
|
|
340
|
+
return (0, node_path_1.basename)((0, node_path_1.resolve)(projectDir));
|
|
341
|
+
}
|
|
338
342
|
function makePacketId(projectDir, type, title, suffix) {
|
|
339
343
|
const raw = suffix ? `${title}-${suffix}` : title;
|
|
340
344
|
return `repo:${repoKey(projectDir)}:${type}:${slugify(raw)}`;
|
|
@@ -931,14 +935,14 @@ function createRepoOverviewPacket(projectDir) {
|
|
|
931
935
|
const readmePath = (0, node_path_1.join)(projectDir, "README.md");
|
|
932
936
|
if (!(0, node_fs_1.existsSync)(packagePath) && !(0, node_fs_1.existsSync)(readmePath))
|
|
933
937
|
return null;
|
|
934
|
-
let title = `${(
|
|
938
|
+
let title = `${repoDisplayName(projectDir)} repo overview`;
|
|
935
939
|
const tags = ["repo", "overview"];
|
|
936
940
|
const bodyParts = [];
|
|
937
941
|
const paths = ["root"];
|
|
938
942
|
const stack = [];
|
|
939
943
|
if ((0, node_fs_1.existsSync)(packagePath)) {
|
|
940
944
|
const pkg = readJson(packagePath);
|
|
941
|
-
title = `${String(pkg.name ?? (
|
|
945
|
+
title = `${String(pkg.name ?? repoDisplayName(projectDir))} repo overview`;
|
|
942
946
|
const scripts = pkg.scripts && typeof pkg.scripts === "object" ? Object.keys(pkg.scripts) : [];
|
|
943
947
|
const deps = {
|
|
944
948
|
...pkg.dependencies,
|
|
@@ -1050,8 +1054,8 @@ function createRepoStructurePacket(projectDir) {
|
|
|
1050
1054
|
].filter(Boolean).join("\n");
|
|
1051
1055
|
return {
|
|
1052
1056
|
schema_version: exports.PACKET_SCHEMA_VERSION,
|
|
1053
|
-
id: makePacketId(projectDir, "repo_map", `${(
|
|
1054
|
-
title: `${(
|
|
1057
|
+
id: makePacketId(projectDir, "repo_map", `${repoDisplayName(projectDir)} repo structure`, "auto-structure"),
|
|
1058
|
+
title: `${repoDisplayName(projectDir)} repo structure`,
|
|
1055
1059
|
summary: summarize(body),
|
|
1056
1060
|
body,
|
|
1057
1061
|
type: "repo_map",
|
|
@@ -1083,7 +1087,18 @@ function createRepoStructurePacket(projectDir) {
|
|
|
1083
1087
|
}
|
|
1084
1088
|
function upsertGeneratedPacket(projectDir, packet) {
|
|
1085
1089
|
const dir = packetsDir(projectDir);
|
|
1086
|
-
const
|
|
1090
|
+
const entries = loadPacketEntriesFromDir(dir);
|
|
1091
|
+
const generatedKind = packet.tags.includes("overview") ? "overview" : packet.tags.includes("structure") ? "structure" : null;
|
|
1092
|
+
for (const entry of entries) {
|
|
1093
|
+
if (generatedKind &&
|
|
1094
|
+
entry.packet.id !== packet.id &&
|
|
1095
|
+
entry.packet.type === packet.type &&
|
|
1096
|
+
entry.packet.quality?.reviewer === "kage-indexer" &&
|
|
1097
|
+
entry.packet.tags.includes(generatedKind)) {
|
|
1098
|
+
(0, node_fs_1.unlinkSync)(entry.path);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
const existing = entries.find((entry) => entry.packet.id === packet.id)?.packet;
|
|
1087
1102
|
if (existing && existing.quality?.reviewer !== "kage-indexer")
|
|
1088
1103
|
return;
|
|
1089
1104
|
if (existing) {
|
|
@@ -2502,6 +2517,57 @@ function refreshProject(projectDir) {
|
|
|
2502
2517
|
next_actions: nextActions,
|
|
2503
2518
|
};
|
|
2504
2519
|
}
|
|
2520
|
+
function gcProject(projectDir, options = {}) {
|
|
2521
|
+
ensureMemoryDirs(projectDir);
|
|
2522
|
+
const packetEntries = loadPacketEntriesFromDir(packetsDir(projectDir));
|
|
2523
|
+
const deprecated = [];
|
|
2524
|
+
const deleted = [];
|
|
2525
|
+
const skipped = [];
|
|
2526
|
+
for (const { path, packet } of packetEntries) {
|
|
2527
|
+
if (packet.status === "deprecated") {
|
|
2528
|
+
skipped.push({ id: packet.id, title: packet.title, reason: "already deprecated" });
|
|
2529
|
+
continue;
|
|
2530
|
+
}
|
|
2531
|
+
const reasons = staleMemoryReasons(projectDir, packet);
|
|
2532
|
+
if (!reasons.length) {
|
|
2533
|
+
skipped.push({ id: packet.id, title: packet.title, reason: "healthy" });
|
|
2534
|
+
continue;
|
|
2535
|
+
}
|
|
2536
|
+
const quality = packet.quality;
|
|
2537
|
+
const hasHelpfulVotes = Number(quality?.votes_up ?? 0) > 0;
|
|
2538
|
+
if (hasHelpfulVotes && !options.force) {
|
|
2539
|
+
skipped.push({ id: packet.id, title: packet.title, reason: `stale but has helpful votes (use --force to override)` });
|
|
2540
|
+
continue;
|
|
2541
|
+
}
|
|
2542
|
+
// Mark as deprecated (or hard-delete if --force)
|
|
2543
|
+
if (options.force && !hasHelpfulVotes) {
|
|
2544
|
+
if (!options.dryRun) {
|
|
2545
|
+
(0, node_fs_1.unlinkSync)(path);
|
|
2546
|
+
}
|
|
2547
|
+
deleted.push({ id: packet.id, title: packet.title });
|
|
2548
|
+
}
|
|
2549
|
+
else {
|
|
2550
|
+
if (!options.dryRun) {
|
|
2551
|
+
const updated = { ...packet, status: "deprecated", updated_at: nowIso() };
|
|
2552
|
+
writeJson(path, updated);
|
|
2553
|
+
}
|
|
2554
|
+
deprecated.push({ id: packet.id, title: packet.title, reason: reasons[0] });
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
if (!options.dryRun && (deprecated.length || deleted.length)) {
|
|
2558
|
+
buildIndexes(projectDir);
|
|
2559
|
+
buildKnowledgeGraph(projectDir);
|
|
2560
|
+
writeJson((0, node_path_1.join)(memoryRoot(projectDir), "metrics.json"), kageMetrics(projectDir));
|
|
2561
|
+
}
|
|
2562
|
+
return {
|
|
2563
|
+
ok: true,
|
|
2564
|
+
project_dir: projectDir,
|
|
2565
|
+
deprecated,
|
|
2566
|
+
deleted,
|
|
2567
|
+
skipped,
|
|
2568
|
+
total_scanned: packetEntries.length,
|
|
2569
|
+
};
|
|
2570
|
+
}
|
|
2505
2571
|
function installAgentPolicy(projectDir) {
|
|
2506
2572
|
const agentsPath = (0, node_path_1.join)(projectDir, "AGENTS.md");
|
|
2507
2573
|
const claudePath = (0, node_path_1.join)(projectDir, "CLAUDE.md");
|