kirograph 0.14.1 → 0.15.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/README.md +128 -20
- package/dist/assets/logo.png +0 -0
- package/dist/bin/commands/help.js +3 -0
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/uninit.js +10 -13
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +37 -23
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/hooks.js +20 -1
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/index.js +9 -4
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/prompts.js +37 -6
- package/dist/bin/installer/prompts.js.map +2 -2
- package/dist/bin/installer/steering.js +19 -0
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/aider.js +72 -0
- package/dist/bin/installer/targets/aider.js.map +7 -0
- package/dist/bin/installer/targets/amp.js +91 -0
- package/dist/bin/installer/targets/amp.js.map +7 -0
- package/dist/bin/installer/targets/antigravity.js +109 -0
- package/dist/bin/installer/targets/antigravity.js.map +7 -0
- package/dist/bin/installer/targets/augment.js +81 -0
- package/dist/bin/installer/targets/augment.js.map +7 -0
- package/dist/bin/installer/targets/claude.js +1 -1
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/cline.js +91 -0
- package/dist/bin/installer/targets/cline.js.map +7 -0
- package/dist/bin/installer/targets/codex.js +1 -1
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/continue.js +107 -0
- package/dist/bin/installer/targets/continue.js.map +7 -0
- package/dist/bin/installer/targets/copilot.js +123 -0
- package/dist/bin/installer/targets/copilot.js.map +7 -0
- package/dist/bin/installer/targets/cursor.js +143 -0
- package/dist/bin/installer/targets/cursor.js.map +7 -0
- package/dist/bin/installer/targets/devin.js +148 -0
- package/dist/bin/installer/targets/devin.js.map +7 -0
- package/dist/bin/installer/targets/gemini-cli.js +126 -0
- package/dist/bin/installer/targets/gemini-cli.js.map +7 -0
- package/dist/bin/installer/targets/generic.js +120 -0
- package/dist/bin/installer/targets/generic.js.map +7 -0
- package/dist/bin/installer/targets/goose.js +72 -0
- package/dist/bin/installer/targets/goose.js.map +7 -0
- package/dist/bin/installer/targets/index.js.map +1 -1
- package/dist/bin/installer/targets/junie.js +105 -0
- package/dist/bin/installer/targets/junie.js.map +7 -0
- package/dist/bin/installer/targets/kilo.js +122 -0
- package/dist/bin/installer/targets/kilo.js.map +7 -0
- package/dist/bin/installer/targets/kiro.js +3 -3
- package/dist/bin/installer/targets/kiro.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +135 -0
- package/dist/bin/installer/targets/opencode.js.map +7 -0
- package/dist/bin/installer/targets/openhands.js +90 -0
- package/dist/bin/installer/targets/openhands.js.map +7 -0
- package/dist/bin/installer/targets/replit.js +72 -0
- package/dist/bin/installer/targets/replit.js.map +7 -0
- package/dist/bin/installer/targets/roo.js +96 -0
- package/dist/bin/installer/targets/roo.js.map +7 -0
- package/dist/bin/installer/targets/tabnine.js +82 -0
- package/dist/bin/installer/targets/tabnine.js.map +7 -0
- package/dist/bin/installer/targets/trae.js +84 -0
- package/dist/bin/installer/targets/trae.js.map +7 -0
- package/dist/bin/installer/targets/warp.js +97 -0
- package/dist/bin/installer/targets/warp.js.map +7 -0
- package/dist/bin/installer/targets/windsurf.js +141 -0
- package/dist/bin/installer/targets/windsurf.js.map +7 -0
- package/dist/bin/kirograph.js +3 -1
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/compression/naive-cost.js +14 -0
- package/dist/compression/naive-cost.js.map +2 -2
- package/dist/compression/tracker.js +18 -4
- package/dist/compression/tracker.js.map +2 -2
- package/dist/compression/types.js.map +1 -1
- package/dist/config.js +33 -1
- package/dist/config.js.map +2 -2
- package/dist/db/database.js +17 -0
- package/dist/db/database.js.map +2 -2
- package/dist/index.js +3 -0
- package/dist/index.js.map +2 -2
- package/dist/mcp/tool-names.js +5 -1
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +232 -3
- package/dist/mcp/tools.js.map +2 -2
- package/package.json +1 -1
package/dist/mcp/tools.js
CHANGED
|
@@ -61,6 +61,19 @@ function writeSessionMarker(projectRoot) {
|
|
|
61
61
|
} catch {
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
+
function formatAge(timestamp) {
|
|
65
|
+
const diff = Date.now() - timestamp;
|
|
66
|
+
const minutes = Math.floor(diff / 6e4);
|
|
67
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
68
|
+
const hours = Math.floor(minutes / 60);
|
|
69
|
+
if (hours < 24) return `${hours}h ago`;
|
|
70
|
+
const days = Math.floor(hours / 24);
|
|
71
|
+
if (days < 7) return `${days}d ago`;
|
|
72
|
+
const weeks = Math.floor(days / 7);
|
|
73
|
+
if (weeks < 5) return `${weeks}w ago`;
|
|
74
|
+
const months = Math.floor(days / 30);
|
|
75
|
+
return `${months}mo ago`;
|
|
76
|
+
}
|
|
64
77
|
const tools = [
|
|
65
78
|
{
|
|
66
79
|
name: "kirograph_search",
|
|
@@ -343,6 +356,66 @@ const tools = [
|
|
|
343
356
|
projectPath: { type: "string", description: "Project root path (optional)" }
|
|
344
357
|
}
|
|
345
358
|
}
|
|
359
|
+
},
|
|
360
|
+
// ── Memory tools (require enableMemory=true) ────────────────────────────────
|
|
361
|
+
{
|
|
362
|
+
name: "kirograph_mem_search",
|
|
363
|
+
description: "Search project memory for past decisions, errors, patterns, and context. Returns observations ranked by relevance.",
|
|
364
|
+
inputSchema: {
|
|
365
|
+
type: "object",
|
|
366
|
+
properties: {
|
|
367
|
+
query: { type: "string", description: "Natural language search query" },
|
|
368
|
+
kind: {
|
|
369
|
+
type: "string",
|
|
370
|
+
description: "Filter by observation kind",
|
|
371
|
+
enum: ["decision", "error", "pattern", "architecture", "summary", "note"]
|
|
372
|
+
},
|
|
373
|
+
limit: { type: "number", description: "Max results (default: 10)", default: 10 },
|
|
374
|
+
sessionId: { type: "string", description: "Filter to specific session" },
|
|
375
|
+
projectPath: { type: "string", description: "Project root path (optional)" }
|
|
376
|
+
},
|
|
377
|
+
required: ["query"]
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: "kirograph_mem_store",
|
|
382
|
+
description: "Store an observation in project memory. Content is automatically compressed (if caveman mode is on) and linked to relevant code symbols.",
|
|
383
|
+
inputSchema: {
|
|
384
|
+
type: "object",
|
|
385
|
+
properties: {
|
|
386
|
+
content: { type: "string", description: "Observation text" },
|
|
387
|
+
kind: {
|
|
388
|
+
type: "string",
|
|
389
|
+
description: "Observation kind",
|
|
390
|
+
enum: ["decision", "error", "pattern", "architecture", "summary", "note"],
|
|
391
|
+
default: "note"
|
|
392
|
+
},
|
|
393
|
+
projectPath: { type: "string", description: "Project root path (optional)" }
|
|
394
|
+
},
|
|
395
|
+
required: ["content"]
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
name: "kirograph_mem_timeline",
|
|
400
|
+
description: "List recent sessions and their observations chronologically.",
|
|
401
|
+
inputSchema: {
|
|
402
|
+
type: "object",
|
|
403
|
+
properties: {
|
|
404
|
+
limit: { type: "number", description: "Number of sessions to show (default: 5)", default: 5 },
|
|
405
|
+
sessionId: { type: "string", description: "Show observations for a specific session" },
|
|
406
|
+
projectPath: { type: "string", description: "Project root path (optional)" }
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
name: "kirograph_mem_status",
|
|
412
|
+
description: "Memory subsystem health: session count, observations, embedding coverage, storage size.",
|
|
413
|
+
inputSchema: {
|
|
414
|
+
type: "object",
|
|
415
|
+
properties: {
|
|
416
|
+
projectPath: { type: "string", description: "Project root path (optional)" }
|
|
417
|
+
}
|
|
418
|
+
}
|
|
346
419
|
}
|
|
347
420
|
];
|
|
348
421
|
class ToolHandler {
|
|
@@ -388,7 +461,11 @@ class ToolHandler {
|
|
|
388
461
|
const naiveCost = estimateNaiveCost(toolName, outputTokens, args);
|
|
389
462
|
if (naiveCost !== null && naiveCost > outputTokens) {
|
|
390
463
|
const tracker = new import_tracker.TokenTracker(projectRoot);
|
|
391
|
-
|
|
464
|
+
if (toolName.startsWith("kirograph_mem_")) {
|
|
465
|
+
tracker.recordMemorySaving(toolName, outputTokens, naiveCost);
|
|
466
|
+
} else {
|
|
467
|
+
tracker.recordGraphSaving(toolName, outputTokens, naiveCost);
|
|
468
|
+
}
|
|
392
469
|
}
|
|
393
470
|
} catch {
|
|
394
471
|
}
|
|
@@ -455,7 +532,7 @@ class ToolHandler {
|
|
|
455
532
|
` Tokens with KiroGraph: ~${stats.totalCompressed.toLocaleString()}`,
|
|
456
533
|
` Saved: ${stats.totalSaved.toLocaleString()} tokens (${stats.savingsPercent}%)`
|
|
457
534
|
];
|
|
458
|
-
if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0) {
|
|
535
|
+
if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0 || stats.bySource.memory.count > 0) {
|
|
459
536
|
lines.push("", "By source:");
|
|
460
537
|
if (stats.bySource.graph.count > 0) {
|
|
461
538
|
lines.push(` Graph tools: ${stats.bySource.graph.count} calls, ~${stats.bySource.graph.saved.toLocaleString()} tokens saved (vs file reads/grep)`);
|
|
@@ -463,6 +540,9 @@ class ToolHandler {
|
|
|
463
540
|
if (stats.bySource.exec.count > 0) {
|
|
464
541
|
lines.push(` Compression: ${stats.bySource.exec.count} calls, ~${stats.bySource.exec.saved.toLocaleString()} tokens saved (vs raw output)`);
|
|
465
542
|
}
|
|
543
|
+
if (stats.bySource.memory.count > 0) {
|
|
544
|
+
lines.push(` Memory: ${stats.bySource.memory.count} calls, ~${stats.bySource.memory.saved.toLocaleString()} tokens saved (vs re-discovering context)`);
|
|
545
|
+
}
|
|
466
546
|
}
|
|
467
547
|
if (Object.keys(stats.byFamily).length > 0) {
|
|
468
548
|
lines.push("", "Top families:");
|
|
@@ -520,6 +600,36 @@ class ToolHandler {
|
|
|
520
600
|
}
|
|
521
601
|
}
|
|
522
602
|
}
|
|
603
|
+
try {
|
|
604
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../config.js"));
|
|
605
|
+
const projectRoot = cg.getProjectRoot();
|
|
606
|
+
const config = await loadConfig(projectRoot);
|
|
607
|
+
if (config.enableMemory) {
|
|
608
|
+
const { MemoryManager } = await Promise.resolve().then(() => require("../memory/index.js"));
|
|
609
|
+
const db = cg.getDatabase();
|
|
610
|
+
db.applyMemorySchema();
|
|
611
|
+
const mem = new MemoryManager(config, db.getRawDb());
|
|
612
|
+
mem.initialize();
|
|
613
|
+
const qualifiedNames = [
|
|
614
|
+
...ctx.entryPoints.map((n) => n.qualifiedName),
|
|
615
|
+
...ctx.relatedNodes.slice(0, 5).map((n) => n.qualifiedName)
|
|
616
|
+
].filter(Boolean);
|
|
617
|
+
const contextLimit = config.memoryContextLimit ?? 3;
|
|
618
|
+
const contextThreshold = config.memoryContextThreshold ?? 0.3;
|
|
619
|
+
let memResults = mem.getLinkedObservations(qualifiedNames, contextLimit, contextThreshold);
|
|
620
|
+
if (memResults.length === 0) {
|
|
621
|
+
memResults = (await mem.search(args.task, { limit: contextLimit })).filter((r) => r.score >= contextThreshold);
|
|
622
|
+
}
|
|
623
|
+
if (memResults.length > 0) {
|
|
624
|
+
lines.push("", "## Related Memory");
|
|
625
|
+
for (const r of memResults.slice(0, contextLimit)) {
|
|
626
|
+
const age = formatAge(r.observation.createdAt);
|
|
627
|
+
lines.push(`- [${r.observation.kind}] ${r.observation.content} (${age})`);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
} catch {
|
|
632
|
+
}
|
|
523
633
|
return lines.join("\n");
|
|
524
634
|
}
|
|
525
635
|
case "kirograph_callers": {
|
|
@@ -552,8 +662,37 @@ class ToolHandler {
|
|
|
552
662
|
const node = results[0].node;
|
|
553
663
|
const affected = await cg.getImpactRadius(node.id, args.depth ?? 2);
|
|
554
664
|
if (affected.length === 0) return `No dependents found for \`${node.name}\`.`;
|
|
555
|
-
|
|
665
|
+
let output = `Changing \`${node.name}\` may affect ${affected.length} symbol(s):
|
|
556
666
|
` + affected.map((n) => `- ${mapKind(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`).join("\n");
|
|
667
|
+
try {
|
|
668
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../config.js"));
|
|
669
|
+
const projectRoot = cg.getProjectRoot();
|
|
670
|
+
const config = await loadConfig(projectRoot);
|
|
671
|
+
if (config.enableMemory) {
|
|
672
|
+
const { MemoryManager } = await Promise.resolve().then(() => require("../memory/index.js"));
|
|
673
|
+
const db = cg.getDatabase();
|
|
674
|
+
db.applyMemorySchema();
|
|
675
|
+
const mem = new MemoryManager(config, db.getRawDb());
|
|
676
|
+
mem.initialize();
|
|
677
|
+
const contextLimit = config.memoryContextLimit ?? 3;
|
|
678
|
+
const contextThreshold = config.memoryContextThreshold ?? 0.3;
|
|
679
|
+
const memResults = mem.getLinkedObservations(
|
|
680
|
+
[node.qualifiedName],
|
|
681
|
+
contextLimit,
|
|
682
|
+
contextThreshold
|
|
683
|
+
);
|
|
684
|
+
if (memResults.length > 0) {
|
|
685
|
+
output += "\n\nRelated Memory:";
|
|
686
|
+
for (const r of memResults) {
|
|
687
|
+
const age = formatAge(r.observation.createdAt);
|
|
688
|
+
output += `
|
|
689
|
+
- [${r.observation.kind}] ${r.observation.content} (${age})`;
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
} catch {
|
|
694
|
+
}
|
|
695
|
+
return output;
|
|
557
696
|
}
|
|
558
697
|
case "kirograph_node": {
|
|
559
698
|
const results = cg.searchNodes(args.symbol, void 0, 5);
|
|
@@ -934,6 +1073,96 @@ class ToolHandler {
|
|
|
934
1073
|
}
|
|
935
1074
|
return lines.join("\n");
|
|
936
1075
|
}
|
|
1076
|
+
// ── Memory tools ────────────────────────────────────────────────────────
|
|
1077
|
+
case "kirograph_mem_search": {
|
|
1078
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../config.js"));
|
|
1079
|
+
const projectRoot = cg.getProjectRoot();
|
|
1080
|
+
const config = await loadConfig(projectRoot);
|
|
1081
|
+
if (!config.enableMemory) return "Memory is not enabled. Set enableMemory: true in .kirograph/config.json";
|
|
1082
|
+
const { MemoryManager } = await Promise.resolve().then(() => require("../memory/index.js"));
|
|
1083
|
+
const db = cg.getDatabase();
|
|
1084
|
+
db.applyMemorySchema();
|
|
1085
|
+
const mem = new MemoryManager(config, db.getRawDb());
|
|
1086
|
+
mem.initialize();
|
|
1087
|
+
const results = await mem.search(args.query, {
|
|
1088
|
+
limit: args.limit ?? 10,
|
|
1089
|
+
kind: args.kind,
|
|
1090
|
+
sessionId: args.sessionId
|
|
1091
|
+
});
|
|
1092
|
+
if (results.length === 0) return `No memory observations found for "${args.query}".`;
|
|
1093
|
+
return results.map((r, i) => {
|
|
1094
|
+
const age = formatAge(r.observation.createdAt);
|
|
1095
|
+
return `${i + 1}. [${r.observation.kind}] ${r.observation.content} (${age})`;
|
|
1096
|
+
}).join("\n");
|
|
1097
|
+
}
|
|
1098
|
+
case "kirograph_mem_store": {
|
|
1099
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../config.js"));
|
|
1100
|
+
const projectRoot = cg.getProjectRoot();
|
|
1101
|
+
const config = await loadConfig(projectRoot);
|
|
1102
|
+
if (!config.enableMemory) return "Memory is not enabled. Set enableMemory: true in .kirograph/config.json";
|
|
1103
|
+
const { MemoryManager } = await Promise.resolve().then(() => require("../memory/index.js"));
|
|
1104
|
+
const db = cg.getDatabase();
|
|
1105
|
+
db.applyMemorySchema();
|
|
1106
|
+
const mem = new MemoryManager(config, db.getRawDb());
|
|
1107
|
+
mem.initialize();
|
|
1108
|
+
const id = await mem.store({
|
|
1109
|
+
content: args.content,
|
|
1110
|
+
kind: args.kind ?? "note",
|
|
1111
|
+
source: "agent"
|
|
1112
|
+
});
|
|
1113
|
+
if (!id) return "Observation already exists (duplicate content).";
|
|
1114
|
+
return `Stored observation ${id} [${args.kind ?? "note"}]`;
|
|
1115
|
+
}
|
|
1116
|
+
case "kirograph_mem_timeline": {
|
|
1117
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../config.js"));
|
|
1118
|
+
const projectRoot = cg.getProjectRoot();
|
|
1119
|
+
const config = await loadConfig(projectRoot);
|
|
1120
|
+
if (!config.enableMemory) return "Memory is not enabled. Set enableMemory: true in .kirograph/config.json";
|
|
1121
|
+
const { MemoryManager } = await Promise.resolve().then(() => require("../memory/index.js"));
|
|
1122
|
+
const db = cg.getDatabase();
|
|
1123
|
+
db.applyMemorySchema();
|
|
1124
|
+
const mem = new MemoryManager(config, db.getRawDb());
|
|
1125
|
+
mem.initialize();
|
|
1126
|
+
const { sessions, observations } = mem.timeline({
|
|
1127
|
+
limit: args.limit ?? 5,
|
|
1128
|
+
sessionId: args.sessionId
|
|
1129
|
+
});
|
|
1130
|
+
if (sessions.length === 0) return "No memory sessions found.";
|
|
1131
|
+
const lines = [];
|
|
1132
|
+
for (const session of sessions) {
|
|
1133
|
+
const start = new Date(session.startedAt).toISOString().slice(0, 16).replace("T", " ");
|
|
1134
|
+
const status = session.endedAt ? "ended" : "active";
|
|
1135
|
+
const obs = observations.get(session.id) ?? [];
|
|
1136
|
+
lines.push(`## ${start} [${session.ide ?? "unknown"}] (${status}, ${obs.length} observations)`);
|
|
1137
|
+
for (const o of obs.slice(0, 5)) {
|
|
1138
|
+
lines.push(` - [${o.kind}] ${o.content.slice(0, 120)}`);
|
|
1139
|
+
}
|
|
1140
|
+
if (obs.length > 5) lines.push(` \u2026and ${obs.length - 5} more`);
|
|
1141
|
+
}
|
|
1142
|
+
return lines.join("\n");
|
|
1143
|
+
}
|
|
1144
|
+
case "kirograph_mem_status": {
|
|
1145
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../config.js"));
|
|
1146
|
+
const projectRoot = cg.getProjectRoot();
|
|
1147
|
+
const config = await loadConfig(projectRoot);
|
|
1148
|
+
if (!config.enableMemory) return "Memory is not enabled. Set enableMemory: true in .kirograph/config.json";
|
|
1149
|
+
const { MemoryManager } = await Promise.resolve().then(() => require("../memory/index.js"));
|
|
1150
|
+
const db = cg.getDatabase();
|
|
1151
|
+
db.applyMemorySchema();
|
|
1152
|
+
const mem = new MemoryManager(config, db.getRawDb());
|
|
1153
|
+
mem.initialize();
|
|
1154
|
+
const stats = mem.getStats();
|
|
1155
|
+
const lines = [
|
|
1156
|
+
"KiroGraph Memory Status",
|
|
1157
|
+
` Sessions: ${stats.sessions} (${stats.activeSessions} active)`,
|
|
1158
|
+
` Observations: ${stats.observations}`,
|
|
1159
|
+
` Symbol links: ${stats.links}`,
|
|
1160
|
+
` Embeddings: ${stats.vectors} / ${stats.embeddableCount}`,
|
|
1161
|
+
` Model mismatch: ${stats.modelMismatch ? "\u26A0 yes \u2014 run kirograph mem reembed" : "no"}`,
|
|
1162
|
+
` Caveman compression: ${config.cavemanMode !== "off" ? config.cavemanMode : "off (storing raw)"}`
|
|
1163
|
+
];
|
|
1164
|
+
return lines.join("\n");
|
|
1165
|
+
}
|
|
937
1166
|
default:
|
|
938
1167
|
return `Unknown tool: ${toolName}`;
|
|
939
1168
|
}
|