kirograph 0.13.0 → 0.14.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 +332 -93
- package/dist/bin/commands/caveman.js +19 -2
- package/dist/bin/commands/caveman.js.map +2 -2
- package/dist/bin/commands/compression.js +109 -0
- package/dist/bin/commands/compression.js.map +7 -0
- package/dist/bin/commands/context.js +31 -24
- package/dist/bin/commands/context.js.map +2 -2
- package/dist/bin/commands/exec.js +107 -0
- package/dist/bin/commands/exec.js.map +7 -0
- package/dist/bin/commands/gain.js +119 -0
- package/dist/bin/commands/gain.js.map +7 -0
- package/dist/bin/commands/help.js +16 -5
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/install.js +8 -2
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/query.js +5 -1
- package/dist/bin/commands/query.js.map +2 -2
- package/dist/bin/commands/serve.js +2 -2
- package/dist/bin/commands/serve.js.map +2 -2
- package/dist/bin/commands/uninit.js +65 -41
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/commands/utils.js +16 -0
- package/dist/bin/commands/utils.js.map +2 -2
- package/dist/bin/installer/cli-agent.js +5 -25
- package/dist/bin/installer/cli-agent.js.map +2 -2
- package/dist/bin/installer/common.js +154 -0
- package/dist/bin/installer/common.js.map +7 -0
- package/dist/bin/installer/config-prompt.js +9 -2
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/hooks.js +19 -1
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/index.js +104 -86
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.js +60 -0
- package/dist/bin/installer/instructions.js.map +7 -0
- package/dist/bin/installer/mcp.js +6 -36
- package/dist/bin/installer/mcp.js.map +2 -2
- package/dist/bin/installer/steering.js +116 -40
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +79 -0
- package/dist/bin/installer/targets/claude.js.map +7 -0
- package/dist/bin/installer/targets/codex.js +77 -0
- package/dist/bin/installer/targets/codex.js.map +7 -0
- package/dist/bin/installer/targets/index.js +57 -0
- package/dist/bin/installer/targets/index.js.map +7 -0
- package/dist/bin/installer/targets/kiro.js +63 -0
- package/dist/bin/installer/targets/kiro.js.map +7 -0
- package/dist/bin/kirograph.js +7 -1
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/compression/filters/aws.js +418 -0
- package/dist/compression/filters/aws.js.map +7 -0
- package/dist/compression/filters/docker.js +153 -0
- package/dist/compression/filters/docker.js.map +7 -0
- package/dist/compression/filters/files.js +150 -0
- package/dist/compression/filters/files.js.map +7 -0
- package/dist/compression/filters/generic.js +86 -0
- package/dist/compression/filters/generic.js.map +7 -0
- package/dist/compression/filters/git.js +272 -0
- package/dist/compression/filters/git.js.map +7 -0
- package/dist/compression/filters/github.js +137 -0
- package/dist/compression/filters/github.js.map +7 -0
- package/dist/compression/filters/lint.js +280 -0
- package/dist/compression/filters/lint.js.map +7 -0
- package/dist/compression/filters/misc.js +212 -0
- package/dist/compression/filters/misc.js.map +7 -0
- package/dist/compression/filters/package.js +151 -0
- package/dist/compression/filters/package.js.map +7 -0
- package/dist/compression/filters/test.js +266 -0
- package/dist/compression/filters/test.js.map +7 -0
- package/dist/compression/index.js +144 -0
- package/dist/compression/index.js.map +7 -0
- package/dist/compression/naive-cost.js +94 -0
- package/dist/compression/naive-cost.js.map +7 -0
- package/dist/compression/tracker.js +228 -0
- package/dist/compression/tracker.js.map +7 -0
- package/dist/compression/types.js +17 -0
- package/dist/compression/types.js.map +7 -0
- package/dist/config.js +18 -1
- package/dist/config.js.map +2 -2
- package/dist/mcp/tool-names.js +50 -0
- package/dist/mcp/tool-names.js.map +7 -0
- package/dist/mcp/tools.js +173 -4
- package/dist/mcp/tools.js.map +3 -3
- package/package.json +2 -2
package/dist/mcp/tools.js
CHANGED
|
@@ -28,6 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var tools_exports = {};
|
|
30
30
|
__export(tools_exports, {
|
|
31
|
+
KIROGRAPH_TOOL_NAMES: () => import_tool_names.KIROGRAPH_TOOL_NAMES,
|
|
31
32
|
ToolHandler: () => ToolHandler,
|
|
32
33
|
tools: () => tools
|
|
33
34
|
});
|
|
@@ -35,8 +36,12 @@ module.exports = __toCommonJS(tools_exports);
|
|
|
35
36
|
var fs = __toESM(require("fs"));
|
|
36
37
|
var path = __toESM(require("path"));
|
|
37
38
|
var crypto = __toESM(require("crypto"));
|
|
39
|
+
var import_child_process = require("child_process");
|
|
38
40
|
var import__ = __toESM(require("../index"));
|
|
39
41
|
var import_errors = require("../errors");
|
|
42
|
+
var import_compression = require("../compression/index");
|
|
43
|
+
var import_tracker = require("../compression/tracker");
|
|
44
|
+
var import_tool_names = require("./tool-names");
|
|
40
45
|
const MAX_OUTPUT = 15e3;
|
|
41
46
|
function truncate(s) {
|
|
42
47
|
return s.length > MAX_OUTPUT ? s.slice(0, MAX_OUTPUT) + "\n\u2026[truncated]" : s;
|
|
@@ -162,8 +167,8 @@ const tools = [
|
|
|
162
167
|
maxDepth: { type: "number", description: "Limit tree depth" },
|
|
163
168
|
format: {
|
|
164
169
|
type: "string",
|
|
165
|
-
description: 'Output format: "tree" (default, visual tree), "flat" (one path per line), "grouped" (grouped by directory)',
|
|
166
|
-
enum: ["tree", "flat", "grouped"],
|
|
170
|
+
description: 'Output format: "tree" (default, visual tree), "flat" (one path per line), "grouped" (grouped by directory), "compact" (rtk-style summary with counts)',
|
|
171
|
+
enum: ["tree", "flat", "grouped", "compact"],
|
|
167
172
|
default: "tree"
|
|
168
173
|
},
|
|
169
174
|
includeMetadata: { type: "boolean", description: "Include language and symbol count (default: true)", default: true },
|
|
@@ -302,6 +307,42 @@ const tools = [
|
|
|
302
307
|
},
|
|
303
308
|
required: ["symbol"]
|
|
304
309
|
}
|
|
310
|
+
},
|
|
311
|
+
{
|
|
312
|
+
name: "kirograph_exec",
|
|
313
|
+
description: "Run a shell command and return token-optimized output. Automatically filters noise from git, test runners, linters, build tools, docker, and package managers. Use instead of raw shell for 60-90% token savings on verbose commands.",
|
|
314
|
+
inputSchema: {
|
|
315
|
+
type: "object",
|
|
316
|
+
properties: {
|
|
317
|
+
command: { type: "string", description: 'Shell command to execute (e.g., "git status", "npm test", "cargo build")' },
|
|
318
|
+
cwd: { type: "string", description: "Working directory (default: project root)" },
|
|
319
|
+
level: {
|
|
320
|
+
type: "string",
|
|
321
|
+
description: 'Compression level: "normal" (balanced), "aggressive" (more compact), "ultra" (maximum compression)',
|
|
322
|
+
enum: ["normal", "aggressive", "ultra"],
|
|
323
|
+
default: "normal"
|
|
324
|
+
},
|
|
325
|
+
timeout: { type: "number", description: "Timeout in seconds (default: 60)", default: 60 },
|
|
326
|
+
projectPath: { type: "string", description: "Project root path (optional)" }
|
|
327
|
+
},
|
|
328
|
+
required: ["command"]
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
name: "kirograph_gain",
|
|
333
|
+
description: "Show token savings statistics \u2014 both from graph tools (vs manual file reads/grep) and from kirograph_exec shell compression.",
|
|
334
|
+
inputSchema: {
|
|
335
|
+
type: "object",
|
|
336
|
+
properties: {
|
|
337
|
+
period: {
|
|
338
|
+
type: "string",
|
|
339
|
+
description: 'Time period: "session" (current), "today", "week", or "all"',
|
|
340
|
+
enum: ["session", "today", "week", "all"],
|
|
341
|
+
default: "session"
|
|
342
|
+
},
|
|
343
|
+
projectPath: { type: "string", description: "Project root path (optional)" }
|
|
344
|
+
}
|
|
345
|
+
}
|
|
305
346
|
}
|
|
306
347
|
];
|
|
307
348
|
class ToolHandler {
|
|
@@ -337,7 +378,22 @@ class ToolHandler {
|
|
|
337
378
|
async handle(toolName, args) {
|
|
338
379
|
try {
|
|
339
380
|
const text = await this.dispatch(toolName, args);
|
|
340
|
-
|
|
381
|
+
const truncated = truncate(text);
|
|
382
|
+
if (toolName !== "kirograph_exec" && toolName !== "kirograph_gain") {
|
|
383
|
+
try {
|
|
384
|
+
const projectRoot = args.projectPath || this.defaultCg?.getProjectRoot() || process.cwd();
|
|
385
|
+
const { estimateNaiveCost } = await Promise.resolve().then(() => require("../compression/naive-cost.js"));
|
|
386
|
+
const { estimateTokens: estimateTokens2 } = await Promise.resolve().then(() => require("../compression/index.js"));
|
|
387
|
+
const outputTokens = estimateTokens2(truncated);
|
|
388
|
+
const naiveCost = estimateNaiveCost(toolName, outputTokens, args);
|
|
389
|
+
if (naiveCost !== null && naiveCost > outputTokens) {
|
|
390
|
+
const tracker = new import_tracker.TokenTracker(projectRoot);
|
|
391
|
+
tracker.recordGraphSaving(toolName, outputTokens, naiveCost);
|
|
392
|
+
}
|
|
393
|
+
} catch {
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return { content: [{ type: "text", text: truncated }] };
|
|
341
397
|
} catch (err) {
|
|
342
398
|
(0, import_errors.logError)("MCP tool error", { tool: toolName, error: err });
|
|
343
399
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -345,6 +401,84 @@ class ToolHandler {
|
|
|
345
401
|
}
|
|
346
402
|
}
|
|
347
403
|
async dispatch(toolName, args) {
|
|
404
|
+
if (toolName === "kirograph_exec") {
|
|
405
|
+
const cmd = args.command;
|
|
406
|
+
if (!cmd) return "Error: command is required.";
|
|
407
|
+
const projectRoot = args.projectPath || args.cwd || process.cwd();
|
|
408
|
+
const execCwd = args.cwd || projectRoot;
|
|
409
|
+
let defaultLevel = "normal";
|
|
410
|
+
try {
|
|
411
|
+
const { loadConfig } = await Promise.resolve().then(() => require("../config.js"));
|
|
412
|
+
const config = await loadConfig(projectRoot);
|
|
413
|
+
if (config.shellCompressionLevel && config.shellCompressionLevel !== "off") {
|
|
414
|
+
defaultLevel = config.shellCompressionLevel;
|
|
415
|
+
}
|
|
416
|
+
} catch {
|
|
417
|
+
}
|
|
418
|
+
const level = args.level ?? defaultLevel;
|
|
419
|
+
const timeout = (args.timeout ?? 60) * 1e3;
|
|
420
|
+
let rawOutput;
|
|
421
|
+
let exitCode = 0;
|
|
422
|
+
try {
|
|
423
|
+
rawOutput = (0, import_child_process.execSync)(cmd, {
|
|
424
|
+
cwd: execCwd,
|
|
425
|
+
timeout,
|
|
426
|
+
encoding: "utf8",
|
|
427
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
428
|
+
maxBuffer: 10 * 1024 * 1024
|
|
429
|
+
});
|
|
430
|
+
} catch (err) {
|
|
431
|
+
rawOutput = (err.stdout || "") + (err.stderr || "");
|
|
432
|
+
exitCode = err.status ?? 1;
|
|
433
|
+
}
|
|
434
|
+
const result = (0, import_compression.compress)(cmd, rawOutput, { level, preserveErrors: exitCode !== 0 });
|
|
435
|
+
const tracker = new import_tracker.TokenTracker(projectRoot);
|
|
436
|
+
tracker.record(cmd, result.originalTokens, result.compressedTokens, result.strategy);
|
|
437
|
+
const header = exitCode !== 0 ? `[exit ${exitCode}] ` : "";
|
|
438
|
+
const footer = result.savings > 5 ? `
|
|
439
|
+
|
|
440
|
+
[${result.savings}% tokens saved | ${result.originalTokens}\u2192${result.compressedTokens} | ${result.strategy}]` : "";
|
|
441
|
+
return `${header}${result.output}${footer}`;
|
|
442
|
+
}
|
|
443
|
+
if (toolName === "kirograph_gain") {
|
|
444
|
+
const projectRoot = args.projectPath || process.cwd();
|
|
445
|
+
const period = args.period ?? "session";
|
|
446
|
+
const tracker = new import_tracker.TokenTracker(projectRoot);
|
|
447
|
+
const stats = tracker.getStats(period);
|
|
448
|
+
if (stats.totalCommands === 0) {
|
|
449
|
+
return "No savings recorded yet. Use kirograph tools and kirograph_exec \u2014 savings are tracked automatically.";
|
|
450
|
+
}
|
|
451
|
+
const lines = [
|
|
452
|
+
`Token Savings (${period}):`,
|
|
453
|
+
` Total calls: ${stats.totalCommands}`,
|
|
454
|
+
` Tokens without KiroGraph: ~${stats.totalOriginal.toLocaleString()}`,
|
|
455
|
+
` Tokens with KiroGraph: ~${stats.totalCompressed.toLocaleString()}`,
|
|
456
|
+
` Saved: ${stats.totalSaved.toLocaleString()} tokens (${stats.savingsPercent}%)`
|
|
457
|
+
];
|
|
458
|
+
if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0) {
|
|
459
|
+
lines.push("", "By source:");
|
|
460
|
+
if (stats.bySource.graph.count > 0) {
|
|
461
|
+
lines.push(` Graph tools: ${stats.bySource.graph.count} calls, ~${stats.bySource.graph.saved.toLocaleString()} tokens saved (vs file reads/grep)`);
|
|
462
|
+
}
|
|
463
|
+
if (stats.bySource.exec.count > 0) {
|
|
464
|
+
lines.push(` Compression: ${stats.bySource.exec.count} calls, ~${stats.bySource.exec.saved.toLocaleString()} tokens saved (vs raw output)`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
if (Object.keys(stats.byFamily).length > 0) {
|
|
468
|
+
lines.push("", "Top families:");
|
|
469
|
+
for (const [family, data] of Object.entries(stats.byFamily).slice(0, 7)) {
|
|
470
|
+
lines.push(` ${family}: ${data.count} calls, ${data.savings}% avg savings`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
if (stats.recentCommands.length > 0) {
|
|
474
|
+
lines.push("", "Recent:");
|
|
475
|
+
for (const cmd of stats.recentCommands.slice(0, 5)) {
|
|
476
|
+
const tag = cmd.source === "graph" ? "\u{1F4CA}" : "\u26A1";
|
|
477
|
+
lines.push(` ${tag} ${cmd.command.slice(0, 40)} \u2192 ${cmd.savings}% saved`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
return lines.join("\n");
|
|
481
|
+
}
|
|
348
482
|
const cg = await this.getConnection(args.projectPath);
|
|
349
483
|
if (!cg) return "KiroGraph not initialized. Run `kirograph init` in your project first.";
|
|
350
484
|
writeSessionMarker(cg.getProjectRoot());
|
|
@@ -463,6 +597,12 @@ class ToolHandler {
|
|
|
463
597
|
` \u26A0 Index may be incomplete \u2014 ${pendingFiles} file${pendingFiles !== 1 ? "s" : ""} pending sync.` + (syncRunning ? " Sync is running in background." : " Run `kirograph sync` to update.") + ` Would you like to wait before proceeding?`
|
|
464
598
|
);
|
|
465
599
|
}
|
|
600
|
+
const tracker = new import_tracker.TokenTracker(cg.getProjectRoot());
|
|
601
|
+
const gainStats = tracker.getStats("session");
|
|
602
|
+
const gainLines = [];
|
|
603
|
+
if (gainStats.totalCommands > 0) {
|
|
604
|
+
gainLines.push(` Compression: ${gainStats.totalCommands} commands, ${gainStats.savingsPercent}% avg savings (${gainStats.totalSaved.toLocaleString()} tokens saved this session)`);
|
|
605
|
+
}
|
|
466
606
|
return [
|
|
467
607
|
`KiroGraph Status`,
|
|
468
608
|
` Project: ${cg.getProjectRoot()}`,
|
|
@@ -475,7 +615,8 @@ class ToolHandler {
|
|
|
475
615
|
archLine,
|
|
476
616
|
` DB size: ${dbMb} MB`,
|
|
477
617
|
...semanticLines,
|
|
478
|
-
...syncLines
|
|
618
|
+
...syncLines,
|
|
619
|
+
...gainLines
|
|
479
620
|
].filter(Boolean).join("\n");
|
|
480
621
|
}
|
|
481
622
|
case "kirograph_files": {
|
|
@@ -537,6 +678,33 @@ class ToolHandler {
|
|
|
537
678
|
}
|
|
538
679
|
return lines2.length > 0 ? lines2.join("\n") : "No indexed files found.";
|
|
539
680
|
}
|
|
681
|
+
if (format === "compact") {
|
|
682
|
+
let compactTree2 = function(nodes) {
|
|
683
|
+
for (const node of nodes) {
|
|
684
|
+
if (node.type === "file") {
|
|
685
|
+
const dir = node.path.includes("/") ? node.path.slice(0, node.path.lastIndexOf("/")) : ".";
|
|
686
|
+
const stat = dirStats.get(dir) || { files: 0, symbols: 0, langs: /* @__PURE__ */ new Map() };
|
|
687
|
+
stat.files++;
|
|
688
|
+
stat.symbols += node.symbolCount || 0;
|
|
689
|
+
if (node.language) stat.langs.set(node.language, (stat.langs.get(node.language) || 0) + 1);
|
|
690
|
+
dirStats.set(dir, stat);
|
|
691
|
+
}
|
|
692
|
+
if (node.children?.length) compactTree2(node.children);
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
var compactTree = compactTree2;
|
|
696
|
+
const dirStats = /* @__PURE__ */ new Map();
|
|
697
|
+
compactTree2(tree);
|
|
698
|
+
const totalFiles = [...dirStats.values()].reduce((s, d) => s + d.files, 0);
|
|
699
|
+
const totalSymbols = [...dirStats.values()].reduce((s, d) => s + d.symbols, 0);
|
|
700
|
+
const lines2 = [`${totalFiles} files, ${totalSymbols} symbols in ${dirStats.size} directories:
|
|
701
|
+
`];
|
|
702
|
+
for (const [dir, stat] of [...dirStats.entries()].sort()) {
|
|
703
|
+
const langSummary = [...stat.langs.entries()].map(([l, c]) => `${l}:${c}`).join(" ");
|
|
704
|
+
lines2.push(`${dir}/ (${stat.files} files, ${stat.symbols} symbols) ${langSummary}`);
|
|
705
|
+
}
|
|
706
|
+
return lines2.join("\n");
|
|
707
|
+
}
|
|
540
708
|
const lines = [];
|
|
541
709
|
renderTree2(tree, "");
|
|
542
710
|
return lines.length > 0 ? lines.join("\n") : "No indexed files found.";
|
|
@@ -773,6 +941,7 @@ class ToolHandler {
|
|
|
773
941
|
}
|
|
774
942
|
// Annotate the CommonJS export names for ESM import in node:
|
|
775
943
|
0 && (module.exports = {
|
|
944
|
+
KIROGRAPH_TOOL_NAMES,
|
|
776
945
|
ToolHandler,
|
|
777
946
|
tools
|
|
778
947
|
});
|
package/dist/mcp/tools.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/mcp/tools.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * KiroGraph MCP Tool Definitions + Handlers\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport KiroGraph, { findNearestKiroGraphRoot } from '../index';\nimport type { NodeKind } from '../types';\nimport { logError } from '../errors';\n\nconst MAX_OUTPUT = 15_000;\n\nfunction truncate(s: string): string {\n return s.length > MAX_OUTPUT ? s.slice(0, MAX_OUTPUT) + '\\n\u2026[truncated]' : s;\n}\n\nfunction clampLimit(value: number | undefined, defaultValue: number): number {\n const n = typeof value === 'number' ? value : defaultValue;\n return Math.max(1, Math.min(100, Math.round(n)));\n}\n\n/** Map internal kind values to human-readable MCP response kinds. */\nfunction mapKind(kind: string): string {\n if (kind === 'type_alias') return 'type';\n return kind;\n}\n\n/** Write a session marker so hooks can detect MCP was consulted. */\nfunction writeSessionMarker(projectRoot: string): void {\n try {\n const hash = crypto.createHash('sha256').update(projectRoot).digest('hex').slice(0, 16);\n fs.writeFileSync(`/tmp/kirograph-consulted-${hash}`, String(Date.now()));\n } catch { /* best-effort */ }\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: 'object';\n properties: Record<string, { type: string; description: string; enum?: string[]; default?: unknown }>;\n required?: string[];\n };\n}\n\nexport const tools: ToolDefinition[] = [\n {\n name: 'kirograph_search',\n description: 'Quick symbol search by name. Returns locations only (no code). Use kirograph_context for comprehensive task context.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Symbol name or partial name (e.g., \"auth\", \"signIn\", \"UserService\")' },\n kind: {\n type: 'string',\n description: 'Filter by node kind',\n enum: ['function', 'method', 'class', 'interface', 'type_alias', 'variable', 'route', 'component'],\n },\n limit: { type: 'number', description: 'Max results 1-100 (default: 10)', default: 10 },\n projectPath: { type: 'string', description: 'Project root path (optional, defaults to current project)' },\n },\n required: ['query'],\n },\n },\n {\n name: 'kirograph_context',\n description: 'PRIMARY TOOL: Build comprehensive context for a task or feature request. Returns entry points, related symbols, and key code \u2014 often enough to understand the codebase without additional tool calls.',\n inputSchema: {\n type: 'object',\n properties: {\n task: { type: 'string', description: 'Description of the task, bug, or feature to build context for' },\n maxNodes: { type: 'number', description: 'Max symbols to include (default: 20)', default: 20 },\n includeCode: { type: 'boolean', description: 'Include code snippets (default: true)', default: true },\n projectPath: { type: 'string', description: 'Project root path (optional, defaults to current project)' },\n },\n required: ['task'],\n },\n },\n {\n name: 'kirograph_callers',\n description: 'Find all functions/methods that call a specific symbol.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to find callers for' },\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_callees',\n description: 'Find all functions/methods that a specific symbol calls.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to find callees for' },\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_impact',\n description: 'Analyze what code would be affected by changing a symbol. Use before making changes.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to analyze impact for' },\n depth: { type: 'number', description: 'Traversal depth (default: 2)', default: 2 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_node',\n description: 'Get details about a specific symbol, optionally including its source code.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to look up' },\n includeCode: { type: 'boolean', description: 'Include source code (default: false)', default: false },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_status',\n description: 'Check index health and statistics.',\n inputSchema: {\n type: 'object',\n properties: {\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_files',\n description: 'List the indexed file structure of the project. Supports filtering by path prefix, glob pattern, or depth.',\n inputSchema: {\n type: 'object',\n properties: {\n filterPath: { type: 'string', description: 'Filter by directory path prefix (e.g., \"src/\")' },\n pattern: { type: 'string', description: 'Filter by glob pattern (e.g., \"**/*.ts\")' },\n maxDepth: { type: 'number', description: 'Limit tree depth' },\n format: {\n type: 'string',\n description: 'Output format: \"tree\" (default, visual tree), \"flat\" (one path per line), \"grouped\" (grouped by directory)',\n enum: ['tree', 'flat', 'grouped'],\n default: 'tree',\n },\n includeMetadata: { type: 'boolean', description: 'Include language and symbol count (default: true)', default: true },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_dead_code',\n description: 'Find symbols with no incoming references (potential dead code). Only includes unexported symbols.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'number', description: 'Max results 1-100 (default: 50)', default: 50 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_circular_deps',\n description: 'Find circular import dependencies in the codebase.',\n inputSchema: {\n type: 'object',\n properties: {\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_path',\n description: 'Find the shortest path between two symbols in the graph.',\n inputSchema: {\n type: 'object',\n properties: {\n from: { type: 'string', description: 'Source symbol name' },\n to: { type: 'string', description: 'Target symbol name' },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['from', 'to'],\n },\n },\n {\n name: 'kirograph_architecture',\n description: 'Get the high-level software architecture: packages, layers, and their dependencies. Requires enableArchitecture=true in config. Call this first on a new task to orient yourself without reading files.',\n inputSchema: {\n type: 'object',\n properties: {\n level: {\n type: 'string',\n description: 'View level: \"packages\" (package graph), \"layers\" (architectural layers), or \"both\" (default)',\n enum: ['packages', 'layers', 'both'],\n default: 'both',\n },\n includeFiles: { type: 'boolean', description: 'Include per-file package/layer assignments (default: false)', default: false },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_coupling',\n description: 'Show coupling metrics for packages: afferent (Ca), efferent (Ce), and instability (Ce/(Ca+Ce)). High instability = depends on many others; low instability = depended on by many. Requires enableArchitecture=true.',\n inputSchema: {\n type: 'object',\n properties: {\n sortBy: {\n type: 'string',\n description: 'Sort order: \"instability\" (default), \"afferent\", or \"efferent\"',\n enum: ['instability', 'afferent', 'efferent'],\n default: 'instability',\n },\n limit: { type: 'number', description: 'Max results (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_package',\n description: 'Drill into one package: files it contains, symbols it exports, packages it depends on, and packages that depend on it. Requires enableArchitecture=true.',\n inputSchema: {\n type: 'object',\n properties: {\n package: { type: 'string', description: 'Package name or path (partial match accepted)' },\n includeFiles: { type: 'boolean', description: 'List files in the package (default: true)', default: true },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['package'],\n },\n },\n {\n name: 'kirograph_hotspots',\n description: 'Find the most-connected symbols in the codebase by total edge degree (incoming + outgoing). Useful for identifying load-bearing code, core abstractions, or blast-radius hot zones.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_surprising',\n description: 'Find non-obvious cross-file connections: direct edges between symbols in structurally distant parts of the codebase. High-score pairs indicate unexpected coupling worth investigating.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_diff',\n description: 'Compare the current graph against a saved snapshot. Shows added/removed symbols and relationships since the snapshot was taken. Use `kirograph snapshot` CLI command to save a snapshot first.',\n inputSchema: {\n type: 'object',\n properties: {\n snapshot: { type: 'string', description: 'Snapshot label to compare against. Omit to use the latest saved snapshot.' },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_type_hierarchy',\n description: 'Traverse the type hierarchy of a class or interface (base types and derived types).',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Class or interface name' },\n direction: {\n type: 'string',\n description: 'Direction: \"up\" for base types, \"down\" for derived types, \"both\" for all (default)',\n enum: ['up', 'down', 'both'],\n default: 'both',\n },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n];\n\nexport class ToolHandler {\n private defaultCg: KiroGraph | null;\n private connections = new Map<string, KiroGraph>();\n\n constructor(cg: KiroGraph | null) {\n this.defaultCg = cg;\n }\n\n setDefaultKiroGraph(cg: KiroGraph): void {\n this.defaultCg = cg;\n }\n\n /** Close all cached cross-project connections. */\n closeAll(): void {\n for (const cg of this.connections.values()) {\n try { cg.close(); } catch { /* ignore */ }\n }\n this.connections.clear();\n }\n\n private async getConnection(projectPath?: string): Promise<KiroGraph | null> {\n if (!projectPath) return this.defaultCg;\n const resolved = path.resolve(projectPath);\n if (this.connections.has(resolved)) return this.connections.get(resolved)!;\n try {\n const cg = await KiroGraph.open(resolved);\n this.connections.set(resolved, cg);\n return cg;\n } catch {\n return null;\n }\n }\n\n async handle(toolName: string, args: Record<string, unknown>): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> {\n try {\n const text = await this.dispatch(toolName, args);\n return { content: [{ type: 'text', text: truncate(text) }] };\n } catch (err) {\n logError('MCP tool error', { tool: toolName, error: err });\n const message = err instanceof Error ? err.message : String(err);\n return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true };\n }\n }\n\n private async dispatch(toolName: string, args: Record<string, unknown>): Promise<string> {\n const cg = await this.getConnection(args.projectPath as string | undefined);\n if (!cg) return 'KiroGraph not initialized. Run `kirograph init` in your project first.';\n\n // Write session marker so hooks can detect MCP was consulted\n writeSessionMarker(cg.getProjectRoot());\n\n switch (toolName) {\n case 'kirograph_search': {\n const limit = clampLimit(args.limit as number | undefined, 10);\n const results = cg.searchNodes(\n args.query as string,\n args.kind as NodeKind | undefined,\n limit\n );\n if (results.length === 0) return `No symbols found matching \"${args.query}\".`;\n return results.map(r =>\n `${mapKind(r.node.kind)} ${r.node.name}\\n File: ${r.node.filePath}:${r.node.startLine}\\n Qualified: ${r.node.qualifiedName}`\n ).join('\\n\\n');\n }\n\n case 'kirograph_context': {\n const ctx = await cg.buildContext(args.task as string, {\n maxNodes: (args.maxNodes as number) ?? 20,\n includeCode: (args.includeCode as boolean) ?? true,\n });\n const lines: string[] = [ctx.summary, ''];\n if (ctx.entryPoints.length === 0) {\n lines.push('No matching symbols found. If this is a new feature, consider using kirograph_files to explore the codebase structure.');\n } else {\n lines.push('## Entry Points');\n for (const n of ctx.entryPoints) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`);\n if (ctx.codeSnippets.has(n.id)) {\n lines.push('```', ctx.codeSnippets.get(n.id)!, '```');\n }\n }\n if (ctx.relatedNodes.length > 0) {\n lines.push('', '## Related Symbols');\n for (const n of ctx.relatedNodes.slice(0, 10)) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`);\n }\n }\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_callers': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const callers = await cg.getCallers(node.id, limit);\n if (callers.length === 0) return `No callers found for \\`${node.name}\\`.`;\n return `Callers of \\`${node.name}\\`:\\n` + callers.map(n =>\n `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`\n ).join('\\n');\n }\n\n case 'kirograph_callees': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const callees = await cg.getCallees(node.id, limit);\n if (callees.length === 0) return `\\`${node.name}\\` doesn't call any indexed symbols.`;\n return `\\`${node.name}\\` calls:\\n` + callees.map(n =>\n `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`\n ).join('\\n');\n }\n\n case 'kirograph_impact': {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const affected = await cg.getImpactRadius(node.id, (args.depth as number) ?? 2);\n if (affected.length === 0) return `No dependents found for \\`${node.name}\\`.`;\n return `Changing \\`${node.name}\\` may affect ${affected.length} symbol(s):\\n` +\n affected.map(n => `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_node': {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const lines = [\n `${mapKind(node.kind)} \\`${node.name}\\``,\n `File: ${node.filePath}:${node.startLine}-${node.endLine}`,\n `Qualified: ${node.qualifiedName}`,\n node.signature ? `Signature: ${node.signature}` : '',\n node.docstring ? `Docs: ${node.docstring}` : '',\n ].filter(Boolean);\n if (args.includeCode) {\n const src = cg.getNodeSource(node);\n if (src) lines.push('', '```', src, '```');\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_status': {\n const stats = await cg.getStats();\n const langLine = Object.entries(stats.filesByLanguage)\n .sort((a, b) => b[1] - a[1])\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n const dbMb = (stats.dbSizeBytes / 1024 / 1024).toFixed(2);\n const semanticLines = stats.embeddingsEnabled\n ? [\n ` Semantic search: enabled`,\n ` Semantic model: ${stats.embeddingModel}`,\n ` Semantic engine: ${\n stats.semanticEngine === 'sqlite-vec' ? `sqlite-vec (${stats.vecIndexCount} entries in ANN index)` :\n stats.semanticEngine === 'orama' ? `orama hybrid (${stats.vecIndexCount} docs in index)` :\n stats.semanticEngine === 'pglite' ? `pglite+pgvector (${stats.vecIndexCount} rows in DB)` :\n stats.semanticEngine === 'lancedb' ? `lancedb (${stats.vecIndexCount} entries in ANN index)` :\n stats.semanticEngine === 'qdrant' ? `qdrant (${stats.vecIndexCount} points in collection)` :\n stats.semanticEngine === 'typesense' ? `typesense (${stats.vecIndexCount} documents in collection)` :\n 'in-process cosine'\n }`,\n ` Embeddings: ${stats.embeddingCount} / ${stats.embeddableNodeCount || stats.nodes} embeddable symbols`,\n ...(stats.engineFallback ? [` \u26A0 Engine fallback: ${stats.engineFallback}`] : []),\n ]\n : [` Semantic search: disabled`];\n const frameworkLine = stats.frameworks.length > 0\n ? ` Frameworks: ${stats.frameworks.join(', ')}`\n : ` Frameworks: none detected`;\n const archLine = stats.architectureEnabled\n ? stats.architectureStats\n ? ` Architecture: enabled \u2014 ${stats.architectureStats.packages} packages, ${stats.architectureStats.layers} layers, ${stats.architectureStats.packageDeps} deps`\n : ` Architecture: enabled (not yet analyzed \u2014 run kirograph index)`\n : ` Architecture: disabled`;\n\n // Sync state warning\n const threshold = stats.syncWarningThreshold ?? 10;\n const pendingFiles: number = stats.pendingFiles ?? 0;\n const syncRunning: boolean = stats.syncRunning ?? false;\n const syncLines: string[] = [];\n if (syncRunning) {\n syncLines.push(` \u26A0 Sync is currently running in the background.`);\n }\n if (threshold > 0 && pendingFiles >= threshold) {\n syncLines.push(\n ` \u26A0 Index may be incomplete \u2014 ${pendingFiles} file${pendingFiles !== 1 ? 's' : ''} pending sync.` +\n (syncRunning ? ' Sync is running in background.' : ' Run `kirograph sync` to update.') +\n ` Would you like to wait before proceeding?`\n );\n }\n\n return [\n `KiroGraph Status`,\n ` Project: ${cg.getProjectRoot()}`,\n ` Files indexed: ${stats.files}`,\n ` Symbols: ${stats.nodes}`,\n ` Relationships: ${stats.edges}`,\n ` By kind: ${Object.entries(stats.nodesByKind).map(([k, v]) => `${k}=${v}`).join(', ')}`,\n langLine ? ` By language: ${langLine}` : '',\n frameworkLine,\n archLine,\n ` DB size: ${dbMb} MB`,\n ...semanticLines,\n ...syncLines,\n ].filter(Boolean).join('\\n');\n }\n\n case 'kirograph_files': {\n const format = (args.format as string) ?? 'tree';\n const includeMetadata = args.includeMetadata !== false;\n const tree = cg.getFiles({\n filterPath: args.filterPath as string | undefined,\n pattern: args.pattern as string | undefined,\n maxDepth: args.maxDepth as number | undefined,\n });\n\n if (format === 'flat') {\n const flat: string[] = [];\n function flattenTree(nodes: import('../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const meta = includeMetadata && node.language ? ` [${node.language}${node.symbolCount ? ` \u00B7 ${node.symbolCount}` : ''}]` : '';\n flat.push(`${node.path}${meta}`);\n }\n if (node.children?.length) flattenTree(node.children);\n }\n }\n flattenTree(tree);\n return flat.length > 0 ? flat.join('\\n') : 'No indexed files found.';\n }\n\n if (format === 'grouped') {\n const groups = new Map<string, import('../index').FileTreeNode[]>();\n function groupTree(nodes: import('../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const dir = node.path.includes('/') ? node.path.slice(0, node.path.lastIndexOf('/')) : '.';\n if (!groups.has(dir)) groups.set(dir, []);\n groups.get(dir)!.push(node);\n }\n if (node.children?.length) groupTree(node.children);\n }\n }\n groupTree(tree);\n const lines: string[] = [];\n for (const [dir, files] of [...groups.entries()].sort()) {\n lines.push(`${dir}/`);\n for (const f of files) {\n const meta = includeMetadata && f.language ? ` [${f.language}${f.symbolCount ? ` \u00B7 ${f.symbolCount}` : ''}]` : '';\n lines.push(` ${f.name}${meta}`);\n }\n }\n return lines.length > 0 ? lines.join('\\n') : 'No indexed files found.';\n }\n\n // Default: tree format\n const lines: string[] = [];\n function renderTree(nodes: import('../index').FileTreeNode[], prefix: string): void {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const isLast = i === nodes.length - 1;\n const connector = isLast ? '\u2514\u2500\u2500 ' : '\u251C\u2500\u2500 ';\n const childPrefix = prefix + (isLast ? ' ' : '\u2502 ');\n const meta = includeMetadata && node.type === 'file' && node.language\n ? ` [${node.language}${node.symbolCount ? ` \u00B7 ${node.symbolCount} symbols` : ''}]`\n : '';\n lines.push(`${prefix}${connector}${node.name}${meta}`);\n if (node.children?.length) renderTree(node.children, childPrefix);\n }\n }\n renderTree(tree, '');\n return lines.length > 0 ? lines.join('\\n') : 'No indexed files found.';\n }\n\n case 'kirograph_dead_code': {\n const limit = clampLimit(args.limit as number | undefined, 50);\n const dead = cg.findDeadCode(limit);\n if (dead.length === 0) return 'No dead code detected.';\n return `Potential dead code (${dead.length} unexported symbols with no incoming references):\\n` +\n dead.map(n => `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_circular_deps': {\n const cycles = cg.findCircularDependencies();\n if (cycles.length === 0) return 'No circular dependencies found.';\n return `Found ${cycles.length} circular dependency cycle(s):\\n` +\n cycles.map((cycle, i) => `Cycle ${i + 1}: ${cycle.join(' \u2192 ')}`).join('\\n');\n }\n\n case 'kirograph_path': {\n const fromResults = cg.searchNodes(args.from as string, undefined, 3);\n const toResults = cg.searchNodes(args.to as string, undefined, 3);\n if (fromResults.length === 0) return `Symbol \"${args.from}\" not found in index.`;\n if (toResults.length === 0) return `Symbol \"${args.to}\" not found in index.`;\n const fromNode = fromResults[0].node;\n const toNode = toResults[0].node;\n const pathNodes = await cg.findPath(fromNode.id, toNode.id);\n if (pathNodes.length === 0) return `No path found between \\`${fromNode.name}\\` and \\`${toNode.name}\\`.`;\n return `Path from \\`${fromNode.name}\\` to \\`${toNode.name}\\` (${pathNodes.length} nodes):\\n` +\n pathNodes.map((n, i) => `${i + 1}. ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_type_hierarchy': {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const direction = (args.direction as 'up' | 'down' | 'both') ?? 'both';\n const hierarchy = cg.getTypeHierarchy(node.id, direction);\n if (hierarchy.length === 0) return `No type hierarchy found for \\`${node.name}\\`.`;\n return `Type hierarchy for \\`${node.name}\\` (direction: ${direction}):\\n` +\n hierarchy.map(n => `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_architecture': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const level = (args.level as string) ?? 'both';\n const includeFiles = args.includeFiles === true;\n const arch = cg.getArchitecture();\n\n const lines: string[] = ['# Architecture'];\n\n if ((level === 'packages' || level === 'both') && arch.packages.length > 0) {\n lines.push('\\n## Packages');\n for (const pkg of arch.packages) {\n const meta = [pkg.language, pkg.version].filter(Boolean).join(', ');\n lines.push(`- **${pkg.name}** (${pkg.path}) [${pkg.source}${meta ? ' \u00B7 ' + meta : ''}]`);\n }\n if (arch.packageDeps.length > 0) {\n lines.push('\\n## Package Dependencies');\n for (const dep of arch.packageDeps) {\n const src = arch.packages.find(p => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;\n const tgt = arch.packages.find(p => p.id === dep.targetPkg)?.name ?? dep.targetPkg;\n lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n }\n\n if ((level === 'layers' || level === 'both') && arch.layers.length > 0) {\n lines.push('\\n## Layers');\n for (const layer of arch.layers) {\n const fileCount = Object.values(arch.fileLayers).filter(fl => fl.some(l => l.layerId === layer.id)).length;\n lines.push(`- **${layer.name}** [${layer.source}] \u2014 ${fileCount} file${fileCount !== 1 ? 's' : ''}`);\n }\n if (arch.layerDeps.length > 0) {\n lines.push('\\n## Layer Dependencies');\n for (const dep of arch.layerDeps) {\n const src = dep.sourceLayer.replace('layer:', '');\n const tgt = dep.targetLayer.replace('layer:', '');\n lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount})`);\n }\n }\n }\n\n if (includeFiles && (level === 'packages' || level === 'both')) {\n lines.push('\\n## File \u2192 Package');\n for (const [file, pkgIds] of Object.entries(arch.filePackages).slice(0, 50)) {\n const names = pkgIds.map(id => arch.packages.find(p => p.id === id)?.name ?? id).join(', ');\n lines.push(`- ${file}: ${names}`);\n }\n if (Object.keys(arch.filePackages).length > 50) lines.push(' \u2026(truncated)');\n }\n\n if (arch.packages.length === 0 && arch.layers.length === 0) {\n return 'No architecture data found. Run `kirograph index` with enableArchitecture=true.';\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_coupling': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const sortBy = (args.sortBy as string) ?? 'instability';\n const limit = clampLimit(args.limit as number | undefined, 20);\n const arch = cg.getArchitecture();\n\n if (arch.coupling.length === 0) {\n return 'No coupling data. Run `kirograph index` with enableArchitecture=true.';\n }\n\n const sorted = [...arch.coupling].sort((a, b) => {\n if (sortBy === 'afferent') return b.afferent - a.afferent;\n if (sortBy === 'efferent') return b.efferent - a.efferent;\n return b.instability - a.instability;\n }).slice(0, limit);\n\n const lines = [\n `Coupling Metrics (sorted by ${sortBy}):`,\n '',\n 'Package Ca Ce I',\n '\u2500'.repeat(52),\n ];\n\n for (const c of sorted) {\n const pkg = arch.packages.find(p => p.id === c.packageId);\n const name = (pkg?.name ?? c.packageId).slice(0, 32).padEnd(32);\n const ca = String(c.afferent).padStart(4);\n const ce = String(c.efferent).padStart(4);\n const inst = c.instability.toFixed(2).padStart(5);\n lines.push(`${name} ${ca} ${ce} ${inst}`);\n }\n\n lines.push('', 'Ca=afferent (depended on by), Ce=efferent (depends on), I=instability (Ce/(Ca+Ce))');\n return lines.join('\\n');\n }\n\n case 'kirograph_package': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const query = (args.package as string).toLowerCase();\n const includeFiles = args.includeFiles !== false;\n const arch = cg.getArchitecture();\n\n const pkg = arch.packages.find(p =>\n p.name.toLowerCase().includes(query) || p.path.toLowerCase().includes(query) || p.id.toLowerCase().includes(query)\n );\n if (!pkg) return `Package \"${args.package}\" not found. Use kirograph_architecture to list all packages.`;\n\n const lines = [\n `## Package: ${pkg.name}`,\n `Path: ${pkg.path}`,\n `Source: ${pkg.source}${pkg.manifestPath ? ` (${pkg.manifestPath})` : ''}`,\n ...(pkg.version ? [`Version: ${pkg.version}`] : []),\n ...(pkg.language ? [`Language: ${pkg.language}`] : []),\n ];\n\n const deps = arch.packageDeps.filter(d => d.sourcePkg === pkg.id);\n const dependents = arch.packageDeps.filter(d => d.targetPkg === pkg.id);\n const coupling = arch.coupling.find(c => c.packageId === pkg.id);\n\n if (coupling) {\n lines.push('', `Coupling: Ca=${coupling.afferent} Ce=${coupling.efferent} I=${coupling.instability.toFixed(2)}`);\n }\n\n if (deps.length > 0) {\n lines.push('', `Depends on (${deps.length}):`);\n for (const dep of deps) {\n const name = arch.packages.find(p => p.id === dep.targetPkg)?.name ?? dep.targetPkg;\n lines.push(` \u2192 ${name} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n\n if (dependents.length > 0) {\n lines.push('', `Depended on by (${dependents.length}):`);\n for (const dep of dependents) {\n const name = arch.packages.find(p => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;\n lines.push(` \u2190 ${name} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n\n if (pkg.externalDeps && pkg.externalDeps.length > 0) {\n lines.push('', `External deps (${pkg.externalDeps.length}): ${pkg.externalDeps.slice(0, 10).join(', ')}${pkg.externalDeps.length > 10 ? '\u2026' : ''}`);\n }\n\n if (includeFiles) {\n const files = Object.entries(arch.filePackages)\n .filter(([, ids]) => ids.includes(pkg.id))\n .map(([f]) => f)\n .sort();\n if (files.length > 0) {\n lines.push('', `Files (${files.length}):`);\n for (const f of files.slice(0, 30)) lines.push(` ${f}`);\n if (files.length > 30) lines.push(` \u2026and ${files.length - 30} more`);\n }\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_hotspots': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const hotspots = cg.findHotspots(limit);\n if (hotspots.length === 0) return 'No symbols found in index.';\n const lines = [`Top ${hotspots.length} most-connected symbols (by edge degree):\\n`];\n for (const n of hotspots) {\n lines.push(`${mapKind(n.kind)} \\`${n.name}\\` \u2014 degree ${n.degree} (in: ${n.inDegree}, out: ${n.outDegree})`);\n lines.push(` File: ${n.filePath}:${n.startLine}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_surprising': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const connections = cg.findSurprisingConnections(limit);\n if (connections.length === 0) return 'No surprising cross-file connections found.';\n const lines = [`Top ${connections.length} surprising cross-file connections:\\n`];\n for (const c of connections) {\n lines.push(`${mapKind(c.source.kind)} \\`${c.source.name}\\` ${c.kind}\u2192 ${mapKind(c.target.kind)} \\`${c.target.name}\\` (score: ${c.score.toFixed(2)})`);\n lines.push(` ${c.source.filePath} \u2192 ${c.target.filePath}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_diff': {\n const sm = cg.createSnapshotManager();\n const snapshot = args.snapshot\n ? sm.load(args.snapshot as string)\n : sm.loadLatest();\n if (!snapshot) {\n return args.snapshot\n ? `Snapshot \"${args.snapshot}\" not found. Use \\`kirograph snapshot list\\` to see available snapshots.`\n : 'No snapshots found. Run `kirograph snapshot` to save one first.';\n }\n const diff = sm.diff(snapshot, sm.currentSnapshot());\n const fromDate = new Date(diff.from.timestamp).toISOString().slice(0, 19).replace('T', ' ');\n const lines = [\n `Graph diff: \"${diff.from.label}\" (${fromDate}) \u2192 current`,\n ``,\n `Symbols: +${diff.addedNodes.length} added, -${diff.removedNodes.length} removed`,\n `Edges: +${diff.addedEdges.length} added, -${diff.removedEdges.length} removed`,\n ];\n if (diff.addedNodes.length > 0) {\n lines.push(`\\n## Added symbols (${diff.addedNodes.length})`);\n for (const n of diff.addedNodes.slice(0, 30)) {\n lines.push(`+ ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}`);\n }\n if (diff.addedNodes.length > 30) lines.push(` \u2026and ${diff.addedNodes.length - 30} more`);\n }\n if (diff.removedNodes.length > 0) {\n lines.push(`\\n## Removed symbols (${diff.removedNodes.length})`);\n for (const n of diff.removedNodes.slice(0, 30)) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}`);\n }\n if (diff.removedNodes.length > 30) lines.push(` \u2026and ${diff.removedNodes.length - 30} more`);\n }\n return lines.join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["KiroGraph", "renderTree", "flattenTree", "groupTree", "lines"]
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph MCP Tool Definitions + Handlers\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport { execSync } from 'child_process';\nimport KiroGraph, { findNearestKiroGraphRoot } from '../index';\nimport type { NodeKind } from '../types';\nimport { logError } from '../errors';\nimport { compress, estimateTokens, detectCommandFamily } from '../compression/index';\nimport { TokenTracker } from '../compression/tracker';\nexport { KIROGRAPH_TOOL_NAMES } from './tool-names';\n\nconst MAX_OUTPUT = 15_000;\n\nfunction truncate(s: string): string {\n return s.length > MAX_OUTPUT ? s.slice(0, MAX_OUTPUT) + '\\n\u2026[truncated]' : s;\n}\n\nfunction clampLimit(value: number | undefined, defaultValue: number): number {\n const n = typeof value === 'number' ? value : defaultValue;\n return Math.max(1, Math.min(100, Math.round(n)));\n}\n\n/** Map internal kind values to human-readable MCP response kinds. */\nfunction mapKind(kind: string): string {\n if (kind === 'type_alias') return 'type';\n return kind;\n}\n\n/** Write a session marker so hooks can detect MCP was consulted. */\nfunction writeSessionMarker(projectRoot: string): void {\n try {\n const hash = crypto.createHash('sha256').update(projectRoot).digest('hex').slice(0, 16);\n fs.writeFileSync(`/tmp/kirograph-consulted-${hash}`, String(Date.now()));\n } catch { /* best-effort */ }\n}\n\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: 'object';\n properties: Record<string, { type: string; description: string; enum?: string[]; default?: unknown }>;\n required?: string[];\n };\n}\n\nexport const tools: ToolDefinition[] = [\n {\n name: 'kirograph_search',\n description: 'Quick symbol search by name. Returns locations only (no code). Use kirograph_context for comprehensive task context.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Symbol name or partial name (e.g., \"auth\", \"signIn\", \"UserService\")' },\n kind: {\n type: 'string',\n description: 'Filter by node kind',\n enum: ['function', 'method', 'class', 'interface', 'type_alias', 'variable', 'route', 'component'],\n },\n limit: { type: 'number', description: 'Max results 1-100 (default: 10)', default: 10 },\n projectPath: { type: 'string', description: 'Project root path (optional, defaults to current project)' },\n },\n required: ['query'],\n },\n },\n {\n name: 'kirograph_context',\n description: 'PRIMARY TOOL: Build comprehensive context for a task or feature request. Returns entry points, related symbols, and key code \u2014 often enough to understand the codebase without additional tool calls.',\n inputSchema: {\n type: 'object',\n properties: {\n task: { type: 'string', description: 'Description of the task, bug, or feature to build context for' },\n maxNodes: { type: 'number', description: 'Max symbols to include (default: 20)', default: 20 },\n includeCode: { type: 'boolean', description: 'Include code snippets (default: true)', default: true },\n projectPath: { type: 'string', description: 'Project root path (optional, defaults to current project)' },\n },\n required: ['task'],\n },\n },\n {\n name: 'kirograph_callers',\n description: 'Find all functions/methods that call a specific symbol.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to find callers for' },\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_callees',\n description: 'Find all functions/methods that a specific symbol calls.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to find callees for' },\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_impact',\n description: 'Analyze what code would be affected by changing a symbol. Use before making changes.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to analyze impact for' },\n depth: { type: 'number', description: 'Traversal depth (default: 2)', default: 2 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_node',\n description: 'Get details about a specific symbol, optionally including its source code.',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Symbol name to look up' },\n includeCode: { type: 'boolean', description: 'Include source code (default: false)', default: false },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_status',\n description: 'Check index health and statistics.',\n inputSchema: {\n type: 'object',\n properties: {\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_files',\n description: 'List the indexed file structure of the project. Supports filtering by path prefix, glob pattern, or depth.',\n inputSchema: {\n type: 'object',\n properties: {\n filterPath: { type: 'string', description: 'Filter by directory path prefix (e.g., \"src/\")' },\n pattern: { type: 'string', description: 'Filter by glob pattern (e.g., \"**/*.ts\")' },\n maxDepth: { type: 'number', description: 'Limit tree depth' },\n format: {\n type: 'string',\n description: 'Output format: \"tree\" (default, visual tree), \"flat\" (one path per line), \"grouped\" (grouped by directory), \"compact\" (rtk-style summary with counts)',\n enum: ['tree', 'flat', 'grouped', 'compact'],\n default: 'tree',\n },\n includeMetadata: { type: 'boolean', description: 'Include language and symbol count (default: true)', default: true },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_dead_code',\n description: 'Find symbols with no incoming references (potential dead code). Only includes unexported symbols.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'number', description: 'Max results 1-100 (default: 50)', default: 50 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_circular_deps',\n description: 'Find circular import dependencies in the codebase.',\n inputSchema: {\n type: 'object',\n properties: {\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_path',\n description: 'Find the shortest path between two symbols in the graph.',\n inputSchema: {\n type: 'object',\n properties: {\n from: { type: 'string', description: 'Source symbol name' },\n to: { type: 'string', description: 'Target symbol name' },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['from', 'to'],\n },\n },\n {\n name: 'kirograph_architecture',\n description: 'Get the high-level software architecture: packages, layers, and their dependencies. Requires enableArchitecture=true in config. Call this first on a new task to orient yourself without reading files.',\n inputSchema: {\n type: 'object',\n properties: {\n level: {\n type: 'string',\n description: 'View level: \"packages\" (package graph), \"layers\" (architectural layers), or \"both\" (default)',\n enum: ['packages', 'layers', 'both'],\n default: 'both',\n },\n includeFiles: { type: 'boolean', description: 'Include per-file package/layer assignments (default: false)', default: false },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_coupling',\n description: 'Show coupling metrics for packages: afferent (Ca), efferent (Ce), and instability (Ce/(Ca+Ce)). High instability = depends on many others; low instability = depended on by many. Requires enableArchitecture=true.',\n inputSchema: {\n type: 'object',\n properties: {\n sortBy: {\n type: 'string',\n description: 'Sort order: \"instability\" (default), \"afferent\", or \"efferent\"',\n enum: ['instability', 'afferent', 'efferent'],\n default: 'instability',\n },\n limit: { type: 'number', description: 'Max results (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_package',\n description: 'Drill into one package: files it contains, symbols it exports, packages it depends on, and packages that depend on it. Requires enableArchitecture=true.',\n inputSchema: {\n type: 'object',\n properties: {\n package: { type: 'string', description: 'Package name or path (partial match accepted)' },\n includeFiles: { type: 'boolean', description: 'List files in the package (default: true)', default: true },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['package'],\n },\n },\n {\n name: 'kirograph_hotspots',\n description: 'Find the most-connected symbols in the codebase by total edge degree (incoming + outgoing). Useful for identifying load-bearing code, core abstractions, or blast-radius hot zones.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_surprising',\n description: 'Find non-obvious cross-file connections: direct edges between symbols in structurally distant parts of the codebase. High-score pairs indicate unexpected coupling worth investigating.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'number', description: 'Max results 1-100 (default: 20)', default: 20 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_diff',\n description: 'Compare the current graph against a saved snapshot. Shows added/removed symbols and relationships since the snapshot was taken. Use `kirograph snapshot` CLI command to save a snapshot first.',\n inputSchema: {\n type: 'object',\n properties: {\n snapshot: { type: 'string', description: 'Snapshot label to compare against. Omit to use the latest saved snapshot.' },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n {\n name: 'kirograph_type_hierarchy',\n description: 'Traverse the type hierarchy of a class or interface (base types and derived types).',\n inputSchema: {\n type: 'object',\n properties: {\n symbol: { type: 'string', description: 'Class or interface name' },\n direction: {\n type: 'string',\n description: 'Direction: \"up\" for base types, \"down\" for derived types, \"both\" for all (default)',\n enum: ['up', 'down', 'both'],\n default: 'both',\n },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['symbol'],\n },\n },\n {\n name: 'kirograph_exec',\n description: 'Run a shell command and return token-optimized output. Automatically filters noise from git, test runners, linters, build tools, docker, and package managers. Use instead of raw shell for 60-90% token savings on verbose commands.',\n inputSchema: {\n type: 'object',\n properties: {\n command: { type: 'string', description: 'Shell command to execute (e.g., \"git status\", \"npm test\", \"cargo build\")' },\n cwd: { type: 'string', description: 'Working directory (default: project root)' },\n level: {\n type: 'string',\n description: 'Compression level: \"normal\" (balanced), \"aggressive\" (more compact), \"ultra\" (maximum compression)',\n enum: ['normal', 'aggressive', 'ultra'],\n default: 'normal',\n },\n timeout: { type: 'number', description: 'Timeout in seconds (default: 60)', default: 60 },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n required: ['command'],\n },\n },\n {\n name: 'kirograph_gain',\n description: 'Show token savings statistics \u2014 both from graph tools (vs manual file reads/grep) and from kirograph_exec shell compression.',\n inputSchema: {\n type: 'object',\n properties: {\n period: {\n type: 'string',\n description: 'Time period: \"session\" (current), \"today\", \"week\", or \"all\"',\n enum: ['session', 'today', 'week', 'all'],\n default: 'session',\n },\n projectPath: { type: 'string', description: 'Project root path (optional)' },\n },\n },\n },\n];\n\nexport class ToolHandler {\n private defaultCg: KiroGraph | null;\n private connections = new Map<string, KiroGraph>();\n\n constructor(cg: KiroGraph | null) {\n this.defaultCg = cg;\n }\n\n setDefaultKiroGraph(cg: KiroGraph): void {\n this.defaultCg = cg;\n }\n\n /** Close all cached cross-project connections. */\n closeAll(): void {\n for (const cg of this.connections.values()) {\n try { cg.close(); } catch { /* ignore */ }\n }\n this.connections.clear();\n }\n\n private async getConnection(projectPath?: string): Promise<KiroGraph | null> {\n if (!projectPath) return this.defaultCg;\n const resolved = path.resolve(projectPath);\n if (this.connections.has(resolved)) return this.connections.get(resolved)!;\n try {\n const cg = await KiroGraph.open(resolved);\n this.connections.set(resolved, cg);\n return cg;\n } catch {\n return null;\n }\n }\n\n async handle(toolName: string, args: Record<string, unknown>): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> {\n try {\n const text = await this.dispatch(toolName, args);\n const truncated = truncate(text);\n\n // Track graph tool savings (skip exec/gain \u2014 they track themselves)\n if (toolName !== 'kirograph_exec' && toolName !== 'kirograph_gain') {\n try {\n const projectRoot = (args.projectPath as string) || this.defaultCg?.getProjectRoot() || process.cwd();\n const { estimateNaiveCost } = await Promise.resolve().then(() => require('../compression/naive-cost.js'));\n const { estimateTokens } = await Promise.resolve().then(() => require('../compression/index.js'));\n const outputTokens = estimateTokens(truncated);\n const naiveCost = estimateNaiveCost(toolName, outputTokens, args);\n if (naiveCost !== null && naiveCost > outputTokens) {\n const tracker = new TokenTracker(projectRoot);\n tracker.recordGraphSaving(toolName, outputTokens, naiveCost);\n }\n } catch { /* non-critical */ }\n }\n\n return { content: [{ type: 'text', text: truncated }] };\n } catch (err) {\n logError('MCP tool error', { tool: toolName, error: err });\n const message = err instanceof Error ? err.message : String(err);\n return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true };\n }\n }\n\n private async dispatch(toolName: string, args: Record<string, unknown>): Promise<string> {\n // Tools that don't require an initialized graph\n if (toolName === 'kirograph_exec') {\n const cmd = args.command as string;\n if (!cmd) return 'Error: command is required.';\n\n const projectRoot = (args.projectPath as string) || (args.cwd as string) || process.cwd();\n const execCwd = (args.cwd as string) || projectRoot;\n\n // Read default level from config if not explicitly provided\n let defaultLevel: 'normal' | 'aggressive' | 'ultra' = 'normal';\n try {\n const { loadConfig } = await Promise.resolve().then(() => require('../config.js'));\n const config = await loadConfig(projectRoot);\n if (config.shellCompressionLevel && config.shellCompressionLevel !== 'off') {\n defaultLevel = config.shellCompressionLevel as 'normal' | 'aggressive' | 'ultra';\n }\n } catch { /* no config \u2014 use default */ }\n\n const level = (args.level as 'normal' | 'aggressive' | 'ultra') ?? defaultLevel;\n const timeout = ((args.timeout as number) ?? 60) * 1000;\n\n let rawOutput: string;\n let exitCode = 0;\n try {\n rawOutput = execSync(cmd, {\n cwd: execCwd,\n timeout,\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'pipe'],\n maxBuffer: 10 * 1024 * 1024,\n });\n } catch (err: any) {\n // Command failed \u2014 capture output anyway\n rawOutput = (err.stdout || '') + (err.stderr || '');\n exitCode = err.status ?? 1;\n }\n\n const result = compress(cmd, rawOutput, { level, preserveErrors: exitCode !== 0 });\n\n // Track savings\n const tracker = new TokenTracker(projectRoot);\n tracker.record(cmd, result.originalTokens, result.compressedTokens, result.strategy);\n\n const header = exitCode !== 0 ? `[exit ${exitCode}] ` : '';\n const footer = result.savings > 5\n ? `\\n\\n[${result.savings}% tokens saved | ${result.originalTokens}\u2192${result.compressedTokens} | ${result.strategy}]`\n : '';\n\n return `${header}${result.output}${footer}`;\n }\n\n if (toolName === 'kirograph_gain') {\n const projectRoot = (args.projectPath as string) || process.cwd();\n const period = (args.period as string) ?? 'session';\n const tracker = new TokenTracker(projectRoot);\n const stats = tracker.getStats(period as 'session' | 'today' | 'week' | 'all');\n\n if (stats.totalCommands === 0) {\n return 'No savings recorded yet. Use kirograph tools and kirograph_exec \u2014 savings are tracked automatically.';\n }\n\n const lines = [\n `Token Savings (${period}):`,\n ` Total calls: ${stats.totalCommands}`,\n ` Tokens without KiroGraph: ~${stats.totalOriginal.toLocaleString()}`,\n ` Tokens with KiroGraph: ~${stats.totalCompressed.toLocaleString()}`,\n ` Saved: ${stats.totalSaved.toLocaleString()} tokens (${stats.savingsPercent}%)`,\n ];\n\n // Source breakdown\n if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0) {\n lines.push('', 'By source:');\n if (stats.bySource.graph.count > 0) {\n lines.push(` Graph tools: ${stats.bySource.graph.count} calls, ~${stats.bySource.graph.saved.toLocaleString()} tokens saved (vs file reads/grep)`);\n }\n if (stats.bySource.exec.count > 0) {\n lines.push(` Compression: ${stats.bySource.exec.count} calls, ~${stats.bySource.exec.saved.toLocaleString()} tokens saved (vs raw output)`);\n }\n }\n\n if (Object.keys(stats.byFamily).length > 0) {\n lines.push('', 'Top families:');\n for (const [family, data] of Object.entries(stats.byFamily).slice(0, 7)) {\n lines.push(` ${family}: ${data.count} calls, ${data.savings}% avg savings`);\n }\n }\n\n if (stats.recentCommands.length > 0) {\n lines.push('', 'Recent:');\n for (const cmd of stats.recentCommands.slice(0, 5)) {\n const tag = cmd.source === 'graph' ? '\uD83D\uDCCA' : '\u26A1';\n lines.push(` ${tag} ${cmd.command.slice(0, 40)} \u2192 ${cmd.savings}% saved`);\n }\n }\n\n return lines.join('\\n');\n }\n\n const cg = await this.getConnection(args.projectPath as string | undefined);\n if (!cg) return 'KiroGraph not initialized. Run `kirograph init` in your project first.';\n\n // Write session marker so hooks can detect MCP was consulted\n writeSessionMarker(cg.getProjectRoot());\n\n switch (toolName) {\n case 'kirograph_search': {\n const limit = clampLimit(args.limit as number | undefined, 10);\n const results = cg.searchNodes(\n args.query as string,\n args.kind as NodeKind | undefined,\n limit\n );\n if (results.length === 0) return `No symbols found matching \"${args.query}\".`;\n return results.map(r =>\n `${mapKind(r.node.kind)} ${r.node.name}\\n File: ${r.node.filePath}:${r.node.startLine}\\n Qualified: ${r.node.qualifiedName}`\n ).join('\\n\\n');\n }\n\n case 'kirograph_context': {\n const ctx = await cg.buildContext(args.task as string, {\n maxNodes: (args.maxNodes as number) ?? 20,\n includeCode: (args.includeCode as boolean) ?? true,\n });\n const lines: string[] = [ctx.summary, ''];\n if (ctx.entryPoints.length === 0) {\n lines.push('No matching symbols found. If this is a new feature, consider using kirograph_files to explore the codebase structure.');\n } else {\n lines.push('## Entry Points');\n for (const n of ctx.entryPoints) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`);\n if (ctx.codeSnippets.has(n.id)) {\n lines.push('```', ctx.codeSnippets.get(n.id)!, '```');\n }\n }\n if (ctx.relatedNodes.length > 0) {\n lines.push('', '## Related Symbols');\n for (const n of ctx.relatedNodes.slice(0, 10)) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`);\n }\n }\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_callers': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const callers = await cg.getCallers(node.id, limit);\n if (callers.length === 0) return `No callers found for \\`${node.name}\\`.`;\n return `Callers of \\`${node.name}\\`:\\n` + callers.map(n =>\n `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`\n ).join('\\n');\n }\n\n case 'kirograph_callees': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const callees = await cg.getCallees(node.id, limit);\n if (callees.length === 0) return `\\`${node.name}\\` doesn't call any indexed symbols.`;\n return `\\`${node.name}\\` calls:\\n` + callees.map(n =>\n `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`\n ).join('\\n');\n }\n\n case 'kirograph_impact': {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const affected = await cg.getImpactRadius(node.id, (args.depth as number) ?? 2);\n if (affected.length === 0) return `No dependents found for \\`${node.name}\\`.`;\n return `Changing \\`${node.name}\\` may affect ${affected.length} symbol(s):\\n` +\n affected.map(n => `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_node': {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const lines = [\n `${mapKind(node.kind)} \\`${node.name}\\``,\n `File: ${node.filePath}:${node.startLine}-${node.endLine}`,\n `Qualified: ${node.qualifiedName}`,\n node.signature ? `Signature: ${node.signature}` : '',\n node.docstring ? `Docs: ${node.docstring}` : '',\n ].filter(Boolean);\n if (args.includeCode) {\n const src = cg.getNodeSource(node);\n if (src) lines.push('', '```', src, '```');\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_status': {\n const stats = await cg.getStats();\n const langLine = Object.entries(stats.filesByLanguage)\n .sort((a, b) => b[1] - a[1])\n .map(([k, v]) => `${k}=${v}`)\n .join(', ');\n const dbMb = (stats.dbSizeBytes / 1024 / 1024).toFixed(2);\n const semanticLines = stats.embeddingsEnabled\n ? [\n ` Semantic search: enabled`,\n ` Semantic model: ${stats.embeddingModel}`,\n ` Semantic engine: ${\n stats.semanticEngine === 'sqlite-vec' ? `sqlite-vec (${stats.vecIndexCount} entries in ANN index)` :\n stats.semanticEngine === 'orama' ? `orama hybrid (${stats.vecIndexCount} docs in index)` :\n stats.semanticEngine === 'pglite' ? `pglite+pgvector (${stats.vecIndexCount} rows in DB)` :\n stats.semanticEngine === 'lancedb' ? `lancedb (${stats.vecIndexCount} entries in ANN index)` :\n stats.semanticEngine === 'qdrant' ? `qdrant (${stats.vecIndexCount} points in collection)` :\n stats.semanticEngine === 'typesense' ? `typesense (${stats.vecIndexCount} documents in collection)` :\n 'in-process cosine'\n }`,\n ` Embeddings: ${stats.embeddingCount} / ${stats.embeddableNodeCount || stats.nodes} embeddable symbols`,\n ...(stats.engineFallback ? [` \u26A0 Engine fallback: ${stats.engineFallback}`] : []),\n ]\n : [` Semantic search: disabled`];\n const frameworkLine = stats.frameworks.length > 0\n ? ` Frameworks: ${stats.frameworks.join(', ')}`\n : ` Frameworks: none detected`;\n const archLine = stats.architectureEnabled\n ? stats.architectureStats\n ? ` Architecture: enabled \u2014 ${stats.architectureStats.packages} packages, ${stats.architectureStats.layers} layers, ${stats.architectureStats.packageDeps} deps`\n : ` Architecture: enabled (not yet analyzed \u2014 run kirograph index)`\n : ` Architecture: disabled`;\n\n // Sync state warning\n const threshold = stats.syncWarningThreshold ?? 10;\n const pendingFiles: number = stats.pendingFiles ?? 0;\n const syncRunning: boolean = stats.syncRunning ?? false;\n const syncLines: string[] = [];\n if (syncRunning) {\n syncLines.push(` \u26A0 Sync is currently running in the background.`);\n }\n if (threshold > 0 && pendingFiles >= threshold) {\n syncLines.push(\n ` \u26A0 Index may be incomplete \u2014 ${pendingFiles} file${pendingFiles !== 1 ? 's' : ''} pending sync.` +\n (syncRunning ? ' Sync is running in background.' : ' Run `kirograph sync` to update.') +\n ` Would you like to wait before proceeding?`\n );\n }\n\n // Token savings summary\n const tracker = new TokenTracker(cg.getProjectRoot());\n const gainStats = tracker.getStats('session');\n const gainLines: string[] = [];\n if (gainStats.totalCommands > 0) {\n gainLines.push(` Compression: ${gainStats.totalCommands} commands, ${gainStats.savingsPercent}% avg savings (${gainStats.totalSaved.toLocaleString()} tokens saved this session)`);\n }\n\n return [\n `KiroGraph Status`,\n ` Project: ${cg.getProjectRoot()}`,\n ` Files indexed: ${stats.files}`,\n ` Symbols: ${stats.nodes}`,\n ` Relationships: ${stats.edges}`,\n ` By kind: ${Object.entries(stats.nodesByKind).map(([k, v]) => `${k}=${v}`).join(', ')}`,\n langLine ? ` By language: ${langLine}` : '',\n frameworkLine,\n archLine,\n ` DB size: ${dbMb} MB`,\n ...semanticLines,\n ...syncLines,\n ...gainLines,\n ].filter(Boolean).join('\\n');\n }\n\n case 'kirograph_files': {\n const format = (args.format as string) ?? 'tree';\n const includeMetadata = args.includeMetadata !== false;\n const tree = cg.getFiles({\n filterPath: args.filterPath as string | undefined,\n pattern: args.pattern as string | undefined,\n maxDepth: args.maxDepth as number | undefined,\n });\n\n if (format === 'flat') {\n const flat: string[] = [];\n function flattenTree(nodes: import('../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const meta = includeMetadata && node.language ? ` [${node.language}${node.symbolCount ? ` \u00B7 ${node.symbolCount}` : ''}]` : '';\n flat.push(`${node.path}${meta}`);\n }\n if (node.children?.length) flattenTree(node.children);\n }\n }\n flattenTree(tree);\n return flat.length > 0 ? flat.join('\\n') : 'No indexed files found.';\n }\n\n if (format === 'grouped') {\n const groups = new Map<string, import('../index').FileTreeNode[]>();\n function groupTree(nodes: import('../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const dir = node.path.includes('/') ? node.path.slice(0, node.path.lastIndexOf('/')) : '.';\n if (!groups.has(dir)) groups.set(dir, []);\n groups.get(dir)!.push(node);\n }\n if (node.children?.length) groupTree(node.children);\n }\n }\n groupTree(tree);\n const lines: string[] = [];\n for (const [dir, files] of [...groups.entries()].sort()) {\n lines.push(`${dir}/`);\n for (const f of files) {\n const meta = includeMetadata && f.language ? ` [${f.language}${f.symbolCount ? ` \u00B7 ${f.symbolCount}` : ''}]` : '';\n lines.push(` ${f.name}${meta}`);\n }\n }\n return lines.length > 0 ? lines.join('\\n') : 'No indexed files found.';\n }\n\n if (format === 'compact') {\n // rtk-style compact: directory summary with file counts and language breakdown\n const dirStats = new Map<string, { files: number; symbols: number; langs: Map<string, number> }>();\n function compactTree(nodes: import('../index').FileTreeNode[]): void {\n for (const node of nodes) {\n if (node.type === 'file') {\n const dir = node.path.includes('/') ? node.path.slice(0, node.path.lastIndexOf('/')) : '.';\n const stat = dirStats.get(dir) || { files: 0, symbols: 0, langs: new Map() };\n stat.files++;\n stat.symbols += node.symbolCount || 0;\n if (node.language) stat.langs.set(node.language, (stat.langs.get(node.language) || 0) + 1);\n dirStats.set(dir, stat);\n }\n if (node.children?.length) compactTree(node.children);\n }\n }\n compactTree(tree);\n const totalFiles = [...dirStats.values()].reduce((s, d) => s + d.files, 0);\n const totalSymbols = [...dirStats.values()].reduce((s, d) => s + d.symbols, 0);\n const lines: string[] = [`${totalFiles} files, ${totalSymbols} symbols in ${dirStats.size} directories:\\n`];\n for (const [dir, stat] of [...dirStats.entries()].sort()) {\n const langSummary = [...stat.langs.entries()].map(([l, c]) => `${l}:${c}`).join(' ');\n lines.push(`${dir}/ (${stat.files} files, ${stat.symbols} symbols) ${langSummary}`);\n }\n return lines.join('\\n');\n }\n\n // Default: tree format\n const lines: string[] = [];\n function renderTree(nodes: import('../index').FileTreeNode[], prefix: string): void {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n const isLast = i === nodes.length - 1;\n const connector = isLast ? '\u2514\u2500\u2500 ' : '\u251C\u2500\u2500 ';\n const childPrefix = prefix + (isLast ? ' ' : '\u2502 ');\n const meta = includeMetadata && node.type === 'file' && node.language\n ? ` [${node.language}${node.symbolCount ? ` \u00B7 ${node.symbolCount} symbols` : ''}]`\n : '';\n lines.push(`${prefix}${connector}${node.name}${meta}`);\n if (node.children?.length) renderTree(node.children, childPrefix);\n }\n }\n renderTree(tree, '');\n return lines.length > 0 ? lines.join('\\n') : 'No indexed files found.';\n }\n\n case 'kirograph_dead_code': {\n const limit = clampLimit(args.limit as number | undefined, 50);\n const dead = cg.findDeadCode(limit);\n if (dead.length === 0) return 'No dead code detected.';\n return `Potential dead code (${dead.length} unexported symbols with no incoming references):\\n` +\n dead.map(n => `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_circular_deps': {\n const cycles = cg.findCircularDependencies();\n if (cycles.length === 0) return 'No circular dependencies found.';\n return `Found ${cycles.length} circular dependency cycle(s):\\n` +\n cycles.map((cycle, i) => `Cycle ${i + 1}: ${cycle.join(' \u2192 ')}`).join('\\n');\n }\n\n case 'kirograph_path': {\n const fromResults = cg.searchNodes(args.from as string, undefined, 3);\n const toResults = cg.searchNodes(args.to as string, undefined, 3);\n if (fromResults.length === 0) return `Symbol \"${args.from}\" not found in index.`;\n if (toResults.length === 0) return `Symbol \"${args.to}\" not found in index.`;\n const fromNode = fromResults[0].node;\n const toNode = toResults[0].node;\n const pathNodes = await cg.findPath(fromNode.id, toNode.id);\n if (pathNodes.length === 0) return `No path found between \\`${fromNode.name}\\` and \\`${toNode.name}\\`.`;\n return `Path from \\`${fromNode.name}\\` to \\`${toNode.name}\\` (${pathNodes.length} nodes):\\n` +\n pathNodes.map((n, i) => `${i + 1}. ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_type_hierarchy': {\n const results = cg.searchNodes(args.symbol as string, undefined, 5);\n if (results.length === 0) return `Symbol \"${args.symbol}\" not found in index.`;\n const node = results[0].node;\n const direction = (args.direction as 'up' | 'down' | 'both') ?? 'both';\n const hierarchy = cg.getTypeHierarchy(node.id, direction);\n if (hierarchy.length === 0) return `No type hierarchy found for \\`${node.name}\\`.`;\n return `Type hierarchy for \\`${node.name}\\` (direction: ${direction}):\\n` +\n hierarchy.map(n => `- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}:${n.startLine}`).join('\\n');\n }\n\n case 'kirograph_architecture': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const level = (args.level as string) ?? 'both';\n const includeFiles = args.includeFiles === true;\n const arch = cg.getArchitecture();\n\n const lines: string[] = ['# Architecture'];\n\n if ((level === 'packages' || level === 'both') && arch.packages.length > 0) {\n lines.push('\\n## Packages');\n for (const pkg of arch.packages) {\n const meta = [pkg.language, pkg.version].filter(Boolean).join(', ');\n lines.push(`- **${pkg.name}** (${pkg.path}) [${pkg.source}${meta ? ' \u00B7 ' + meta : ''}]`);\n }\n if (arch.packageDeps.length > 0) {\n lines.push('\\n## Package Dependencies');\n for (const dep of arch.packageDeps) {\n const src = arch.packages.find(p => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;\n const tgt = arch.packages.find(p => p.id === dep.targetPkg)?.name ?? dep.targetPkg;\n lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n }\n\n if ((level === 'layers' || level === 'both') && arch.layers.length > 0) {\n lines.push('\\n## Layers');\n for (const layer of arch.layers) {\n const fileCount = Object.values(arch.fileLayers).filter(fl => fl.some(l => l.layerId === layer.id)).length;\n lines.push(`- **${layer.name}** [${layer.source}] \u2014 ${fileCount} file${fileCount !== 1 ? 's' : ''}`);\n }\n if (arch.layerDeps.length > 0) {\n lines.push('\\n## Layer Dependencies');\n for (const dep of arch.layerDeps) {\n const src = dep.sourceLayer.replace('layer:', '');\n const tgt = dep.targetLayer.replace('layer:', '');\n lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount})`);\n }\n }\n }\n\n if (includeFiles && (level === 'packages' || level === 'both')) {\n lines.push('\\n## File \u2192 Package');\n for (const [file, pkgIds] of Object.entries(arch.filePackages).slice(0, 50)) {\n const names = pkgIds.map(id => arch.packages.find(p => p.id === id)?.name ?? id).join(', ');\n lines.push(`- ${file}: ${names}`);\n }\n if (Object.keys(arch.filePackages).length > 50) lines.push(' \u2026(truncated)');\n }\n\n if (arch.packages.length === 0 && arch.layers.length === 0) {\n return 'No architecture data found. Run `kirograph index` with enableArchitecture=true.';\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_coupling': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const sortBy = (args.sortBy as string) ?? 'instability';\n const limit = clampLimit(args.limit as number | undefined, 20);\n const arch = cg.getArchitecture();\n\n if (arch.coupling.length === 0) {\n return 'No coupling data. Run `kirograph index` with enableArchitecture=true.';\n }\n\n const sorted = [...arch.coupling].sort((a, b) => {\n if (sortBy === 'afferent') return b.afferent - a.afferent;\n if (sortBy === 'efferent') return b.efferent - a.efferent;\n return b.instability - a.instability;\n }).slice(0, limit);\n\n const lines = [\n `Coupling Metrics (sorted by ${sortBy}):`,\n '',\n 'Package Ca Ce I',\n '\u2500'.repeat(52),\n ];\n\n for (const c of sorted) {\n const pkg = arch.packages.find(p => p.id === c.packageId);\n const name = (pkg?.name ?? c.packageId).slice(0, 32).padEnd(32);\n const ca = String(c.afferent).padStart(4);\n const ce = String(c.efferent).padStart(4);\n const inst = c.instability.toFixed(2).padStart(5);\n lines.push(`${name} ${ca} ${ce} ${inst}`);\n }\n\n lines.push('', 'Ca=afferent (depended on by), Ce=efferent (depends on), I=instability (Ce/(Ca+Ce))');\n return lines.join('\\n');\n }\n\n case 'kirograph_package': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const query = (args.package as string).toLowerCase();\n const includeFiles = args.includeFiles !== false;\n const arch = cg.getArchitecture();\n\n const pkg = arch.packages.find(p =>\n p.name.toLowerCase().includes(query) || p.path.toLowerCase().includes(query) || p.id.toLowerCase().includes(query)\n );\n if (!pkg) return `Package \"${args.package}\" not found. Use kirograph_architecture to list all packages.`;\n\n const lines = [\n `## Package: ${pkg.name}`,\n `Path: ${pkg.path}`,\n `Source: ${pkg.source}${pkg.manifestPath ? ` (${pkg.manifestPath})` : ''}`,\n ...(pkg.version ? [`Version: ${pkg.version}`] : []),\n ...(pkg.language ? [`Language: ${pkg.language}`] : []),\n ];\n\n const deps = arch.packageDeps.filter(d => d.sourcePkg === pkg.id);\n const dependents = arch.packageDeps.filter(d => d.targetPkg === pkg.id);\n const coupling = arch.coupling.find(c => c.packageId === pkg.id);\n\n if (coupling) {\n lines.push('', `Coupling: Ca=${coupling.afferent} Ce=${coupling.efferent} I=${coupling.instability.toFixed(2)}`);\n }\n\n if (deps.length > 0) {\n lines.push('', `Depends on (${deps.length}):`);\n for (const dep of deps) {\n const name = arch.packages.find(p => p.id === dep.targetPkg)?.name ?? dep.targetPkg;\n lines.push(` \u2192 ${name} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n\n if (dependents.length > 0) {\n lines.push('', `Depended on by (${dependents.length}):`);\n for (const dep of dependents) {\n const name = arch.packages.find(p => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;\n lines.push(` \u2190 ${name} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n\n if (pkg.externalDeps && pkg.externalDeps.length > 0) {\n lines.push('', `External deps (${pkg.externalDeps.length}): ${pkg.externalDeps.slice(0, 10).join(', ')}${pkg.externalDeps.length > 10 ? '\u2026' : ''}`);\n }\n\n if (includeFiles) {\n const files = Object.entries(arch.filePackages)\n .filter(([, ids]) => ids.includes(pkg.id))\n .map(([f]) => f)\n .sort();\n if (files.length > 0) {\n lines.push('', `Files (${files.length}):`);\n for (const f of files.slice(0, 30)) lines.push(` ${f}`);\n if (files.length > 30) lines.push(` \u2026and ${files.length - 30} more`);\n }\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_hotspots': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const hotspots = cg.findHotspots(limit);\n if (hotspots.length === 0) return 'No symbols found in index.';\n const lines = [`Top ${hotspots.length} most-connected symbols (by edge degree):\\n`];\n for (const n of hotspots) {\n lines.push(`${mapKind(n.kind)} \\`${n.name}\\` \u2014 degree ${n.degree} (in: ${n.inDegree}, out: ${n.outDegree})`);\n lines.push(` File: ${n.filePath}:${n.startLine}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_surprising': {\n const limit = clampLimit(args.limit as number | undefined, 20);\n const connections = cg.findSurprisingConnections(limit);\n if (connections.length === 0) return 'No surprising cross-file connections found.';\n const lines = [`Top ${connections.length} surprising cross-file connections:\\n`];\n for (const c of connections) {\n lines.push(`${mapKind(c.source.kind)} \\`${c.source.name}\\` ${c.kind}\u2192 ${mapKind(c.target.kind)} \\`${c.target.name}\\` (score: ${c.score.toFixed(2)})`);\n lines.push(` ${c.source.filePath} \u2192 ${c.target.filePath}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_diff': {\n const sm = cg.createSnapshotManager();\n const snapshot = args.snapshot\n ? sm.load(args.snapshot as string)\n : sm.loadLatest();\n if (!snapshot) {\n return args.snapshot\n ? `Snapshot \"${args.snapshot}\" not found. Use \\`kirograph snapshot list\\` to see available snapshots.`\n : 'No snapshots found. Run `kirograph snapshot` to save one first.';\n }\n const diff = sm.diff(snapshot, sm.currentSnapshot());\n const fromDate = new Date(diff.from.timestamp).toISOString().slice(0, 19).replace('T', ' ');\n const lines = [\n `Graph diff: \"${diff.from.label}\" (${fromDate}) \u2192 current`,\n ``,\n `Symbols: +${diff.addedNodes.length} added, -${diff.removedNodes.length} removed`,\n `Edges: +${diff.addedEdges.length} added, -${diff.removedEdges.length} removed`,\n ];\n if (diff.addedNodes.length > 0) {\n lines.push(`\\n## Added symbols (${diff.addedNodes.length})`);\n for (const n of diff.addedNodes.slice(0, 30)) {\n lines.push(`+ ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}`);\n }\n if (diff.addedNodes.length > 30) lines.push(` \u2026and ${diff.addedNodes.length - 30} more`);\n }\n if (diff.removedNodes.length > 0) {\n lines.push(`\\n## Removed symbols (${diff.removedNodes.length})`);\n for (const n of diff.removedNodes.slice(0, 30)) {\n lines.push(`- ${mapKind(n.kind)} \\`${n.name}\\` \u2014 ${n.filePath}`);\n }\n if (diff.removedNodes.length > 30) lines.push(` \u2026and ${diff.removedNodes.length - 30} more`);\n }\n return lines.join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["KiroGraph", "estimateTokens", "renderTree", "flattenTree", "groupTree", "lines", "compactTree"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kirograph",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Semantic code knowledge graph for Kiro
|
|
3
|
+
"version": "0.14.0",
|
|
4
|
+
"description": "Semantic code knowledge graph for Kiro: fewer tool calls, instant symbol lookups, 100% local.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"bin": {
|