kirograph 0.27.1 → 0.28.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.
Files changed (222) hide show
  1. package/README.md +35 -2
  2. package/dist/bin/commands/annotations.js +56 -0
  3. package/dist/bin/commands/annotations.js.map +7 -0
  4. package/dist/bin/commands/ast-rewrite.js +55 -0
  5. package/dist/bin/commands/ast-rewrite.js.map +7 -0
  6. package/dist/bin/commands/bench.js +103 -0
  7. package/dist/bin/commands/bench.js.map +7 -0
  8. package/dist/bin/commands/branch.js +133 -0
  9. package/dist/bin/commands/branch.js.map +7 -0
  10. package/dist/bin/commands/callees.js +76 -0
  11. package/dist/bin/commands/callees.js.map +7 -0
  12. package/dist/bin/commands/callers.js +76 -0
  13. package/dist/bin/commands/callers.js.map +7 -0
  14. package/dist/bin/commands/changelog.js +55 -0
  15. package/dist/bin/commands/changelog.js.map +7 -0
  16. package/dist/bin/commands/circular-deps.js +68 -0
  17. package/dist/bin/commands/circular-deps.js.map +7 -0
  18. package/dist/bin/commands/commit-context.js +55 -0
  19. package/dist/bin/commands/commit-context.js.map +7 -0
  20. package/dist/bin/commands/complexity.js +60 -0
  21. package/dist/bin/commands/complexity.js.map +7 -0
  22. package/dist/bin/commands/cost.js +146 -0
  23. package/dist/bin/commands/cost.js.map +7 -0
  24. package/dist/bin/commands/dependency-depth.js +55 -0
  25. package/dist/bin/commands/dependency-depth.js.map +7 -0
  26. package/dist/bin/commands/diff-context.js +55 -0
  27. package/dist/bin/commands/diff-context.js.map +7 -0
  28. package/dist/bin/commands/distribution.js +56 -0
  29. package/dist/bin/commands/distribution.js.map +7 -0
  30. package/dist/bin/commands/doc-coverage.js +56 -0
  31. package/dist/bin/commands/doc-coverage.js.map +7 -0
  32. package/dist/bin/commands/doctor.js +202 -0
  33. package/dist/bin/commands/doctor.js.map +7 -0
  34. package/dist/bin/commands/dsm.js +56 -0
  35. package/dist/bin/commands/dsm.js.map +7 -0
  36. package/dist/bin/commands/gini.js +55 -0
  37. package/dist/bin/commands/gini.js.map +7 -0
  38. package/dist/bin/commands/god-class.js +56 -0
  39. package/dist/bin/commands/god-class.js.map +7 -0
  40. package/dist/bin/commands/health.js +55 -0
  41. package/dist/bin/commands/health.js.map +7 -0
  42. package/dist/bin/commands/help.js +224 -45
  43. package/dist/bin/commands/help.js.map +2 -2
  44. package/dist/bin/commands/impact.js +76 -0
  45. package/dist/bin/commands/impact.js.map +7 -0
  46. package/dist/bin/commands/inheritance-depth.js +56 -0
  47. package/dist/bin/commands/inheritance-depth.js.map +7 -0
  48. package/dist/bin/commands/insert-at.js +55 -0
  49. package/dist/bin/commands/insert-at.js.map +7 -0
  50. package/dist/bin/commands/largest.js +56 -0
  51. package/dist/bin/commands/largest.js.map +7 -0
  52. package/dist/bin/commands/manifest.js +158 -0
  53. package/dist/bin/commands/manifest.js.map +7 -0
  54. package/dist/bin/commands/module-api.js +57 -0
  55. package/dist/bin/commands/module-api.js.map +7 -0
  56. package/dist/bin/commands/monitor.js +91 -0
  57. package/dist/bin/commands/monitor.js.map +7 -0
  58. package/dist/bin/commands/multi-replace.js +66 -0
  59. package/dist/bin/commands/multi-replace.js.map +7 -0
  60. package/dist/bin/commands/pr-context.js +55 -0
  61. package/dist/bin/commands/pr-context.js.map +7 -0
  62. package/dist/bin/commands/query.js +19 -1
  63. package/dist/bin/commands/query.js.map +3 -3
  64. package/dist/bin/commands/rank.js +56 -0
  65. package/dist/bin/commands/rank.js.map +7 -0
  66. package/dist/bin/commands/read.js +1 -1
  67. package/dist/bin/commands/read.js.map +2 -2
  68. package/dist/bin/commands/recursion.js +56 -0
  69. package/dist/bin/commands/recursion.js.map +7 -0
  70. package/dist/bin/commands/rename-preview.js +56 -0
  71. package/dist/bin/commands/rename-preview.js.map +7 -0
  72. package/dist/bin/commands/session.js +60 -0
  73. package/dist/bin/commands/session.js.map +7 -0
  74. package/dist/bin/commands/simplify-scan.js +56 -0
  75. package/dist/bin/commands/simplify-scan.js.map +7 -0
  76. package/dist/bin/commands/str-replace.js +55 -0
  77. package/dist/bin/commands/str-replace.js.map +7 -0
  78. package/dist/bin/commands/test-coverage.js +59 -0
  79. package/dist/bin/commands/test-coverage.js.map +7 -0
  80. package/dist/bin/commands/test-map.js +56 -0
  81. package/dist/bin/commands/test-map.js.map +7 -0
  82. package/dist/bin/commands/test-risk.js +59 -0
  83. package/dist/bin/commands/test-risk.js.map +7 -0
  84. package/dist/bin/commands/type-hierarchy.js +76 -0
  85. package/dist/bin/commands/type-hierarchy.js.map +7 -0
  86. package/dist/bin/commands/unused-imports.js +55 -0
  87. package/dist/bin/commands/unused-imports.js.map +7 -0
  88. package/dist/bin/commands/upgrade.js +78 -0
  89. package/dist/bin/commands/upgrade.js.map +7 -0
  90. package/dist/bin/installer/common.js +19 -9
  91. package/dist/bin/installer/common.js.map +2 -2
  92. package/dist/bin/installer/config-prompt.js +147 -12
  93. package/dist/bin/installer/config-prompt.js.map +3 -3
  94. package/dist/bin/installer/index.js +62 -6
  95. package/dist/bin/installer/index.js.map +2 -2
  96. package/dist/bin/installer/instructions.js +14 -25
  97. package/dist/bin/installer/instructions.js.map +2 -2
  98. package/dist/bin/installer/mcp.js.map +2 -2
  99. package/dist/bin/installer/steering.js +569 -100
  100. package/dist/bin/installer/steering.js.map +2 -2
  101. package/dist/bin/installer/targets/aider.js +3 -3
  102. package/dist/bin/installer/targets/aider.js.map +2 -2
  103. package/dist/bin/installer/targets/amp.js +3 -3
  104. package/dist/bin/installer/targets/amp.js.map +2 -2
  105. package/dist/bin/installer/targets/antigravity.js +4 -4
  106. package/dist/bin/installer/targets/antigravity.js.map +2 -2
  107. package/dist/bin/installer/targets/augment.js +3 -3
  108. package/dist/bin/installer/targets/augment.js.map +2 -2
  109. package/dist/bin/installer/targets/claude.js +3 -3
  110. package/dist/bin/installer/targets/claude.js.map +2 -2
  111. package/dist/bin/installer/targets/cline.js +4 -4
  112. package/dist/bin/installer/targets/cline.js.map +2 -2
  113. package/dist/bin/installer/targets/codex.js +4 -4
  114. package/dist/bin/installer/targets/codex.js.map +2 -2
  115. package/dist/bin/installer/targets/continue.js +4 -4
  116. package/dist/bin/installer/targets/continue.js.map +2 -2
  117. package/dist/bin/installer/targets/copilot-cli.js +4 -4
  118. package/dist/bin/installer/targets/copilot-cli.js.map +2 -2
  119. package/dist/bin/installer/targets/copilot.js +4 -4
  120. package/dist/bin/installer/targets/copilot.js.map +2 -2
  121. package/dist/bin/installer/targets/cursor.js +5 -5
  122. package/dist/bin/installer/targets/cursor.js.map +2 -2
  123. package/dist/bin/installer/targets/devin.js +4 -4
  124. package/dist/bin/installer/targets/devin.js.map +2 -2
  125. package/dist/bin/installer/targets/gemini-cli.js +4 -4
  126. package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
  127. package/dist/bin/installer/targets/generic.js +2 -2
  128. package/dist/bin/installer/targets/generic.js.map +2 -2
  129. package/dist/bin/installer/targets/goose.js +3 -4
  130. package/dist/bin/installer/targets/goose.js.map +3 -3
  131. package/dist/bin/installer/targets/index.js.map +1 -1
  132. package/dist/bin/installer/targets/junie.js +4 -4
  133. package/dist/bin/installer/targets/junie.js.map +2 -2
  134. package/dist/bin/installer/targets/kilo.js +4 -4
  135. package/dist/bin/installer/targets/kilo.js.map +2 -2
  136. package/dist/bin/installer/targets/kiro.js +27 -3
  137. package/dist/bin/installer/targets/kiro.js.map +2 -2
  138. package/dist/bin/installer/targets/opencode.js +3 -3
  139. package/dist/bin/installer/targets/opencode.js.map +2 -2
  140. package/dist/bin/installer/targets/openhands.js +3 -3
  141. package/dist/bin/installer/targets/openhands.js.map +2 -2
  142. package/dist/bin/installer/targets/qoder.js +2 -2
  143. package/dist/bin/installer/targets/qoder.js.map +2 -2
  144. package/dist/bin/installer/targets/qwen.js +2 -2
  145. package/dist/bin/installer/targets/qwen.js.map +2 -2
  146. package/dist/bin/installer/targets/replit.js +3 -3
  147. package/dist/bin/installer/targets/replit.js.map +2 -2
  148. package/dist/bin/installer/targets/roo.js +4 -4
  149. package/dist/bin/installer/targets/roo.js.map +2 -2
  150. package/dist/bin/installer/targets/tabnine.js +3 -3
  151. package/dist/bin/installer/targets/tabnine.js.map +2 -2
  152. package/dist/bin/installer/targets/trae.js +3 -3
  153. package/dist/bin/installer/targets/trae.js.map +2 -2
  154. package/dist/bin/installer/targets/warp.js +4 -4
  155. package/dist/bin/installer/targets/warp.js.map +2 -2
  156. package/dist/bin/installer/targets/windsurf.js +4 -4
  157. package/dist/bin/installer/targets/windsurf.js.map +2 -2
  158. package/dist/bin/kirograph.js +83 -1
  159. package/dist/bin/kirograph.js.map +3 -3
  160. package/dist/config.js +30 -8
  161. package/dist/config.js.map +2 -2
  162. package/dist/core/branch-manager.js +111 -0
  163. package/dist/core/branch-manager.js.map +7 -0
  164. package/dist/core/pipeline.js +3 -3
  165. package/dist/core/pipeline.js.map +2 -2
  166. package/dist/data/pixelrag-bridge.js +93 -0
  167. package/dist/data/pixelrag-bridge.js.map +7 -0
  168. package/dist/data/pixelrag-manager.js +416 -0
  169. package/dist/data/pixelrag-manager.js.map +7 -0
  170. package/dist/db/database.js +34 -7
  171. package/dist/db/database.js.map +2 -2
  172. package/dist/db/schema.sql +7 -1
  173. package/dist/extraction/complexity.js +116 -0
  174. package/dist/extraction/complexity.js.map +7 -0
  175. package/dist/extraction/extractor.js +52 -1
  176. package/dist/extraction/extractor.js.map +2 -2
  177. package/dist/graph/git-context.js +229 -0
  178. package/dist/graph/git-context.js.map +7 -0
  179. package/dist/index.js +4 -2
  180. package/dist/index.js.map +2 -2
  181. package/dist/mcp/cache.js +1 -1
  182. package/dist/mcp/cache.js.map +2 -2
  183. package/dist/mcp/handler.js +446 -0
  184. package/dist/mcp/handler.js.map +7 -0
  185. package/dist/mcp/handlers/architecture.js +297 -0
  186. package/dist/mcp/handlers/architecture.js.map +7 -0
  187. package/dist/mcp/handlers/branch.js +175 -0
  188. package/dist/mcp/handlers/branch.js.map +7 -0
  189. package/dist/mcp/handlers/code-health.js +563 -0
  190. package/dist/mcp/handlers/code-health.js.map +7 -0
  191. package/dist/mcp/handlers/complexity.js +267 -0
  192. package/dist/mcp/handlers/complexity.js.map +7 -0
  193. package/dist/mcp/handlers/core.js +611 -0
  194. package/dist/mcp/handlers/core.js.map +7 -0
  195. package/dist/mcp/handlers/data.js +337 -0
  196. package/dist/mcp/handlers/data.js.map +7 -0
  197. package/dist/mcp/handlers/docs.js +159 -0
  198. package/dist/mcp/handlers/docs.js.map +7 -0
  199. package/dist/mcp/handlers/edit-primitives.js +200 -0
  200. package/dist/mcp/handlers/edit-primitives.js.map +7 -0
  201. package/dist/mcp/handlers/git-context.js +286 -0
  202. package/dist/mcp/handlers/git-context.js.map +7 -0
  203. package/dist/mcp/handlers/memory.js +363 -0
  204. package/dist/mcp/handlers/memory.js.map +7 -0
  205. package/dist/mcp/handlers/patterns.js +310 -0
  206. package/dist/mcp/handlers/patterns.js.map +7 -0
  207. package/dist/mcp/handlers/security.js +699 -0
  208. package/dist/mcp/handlers/security.js.map +7 -0
  209. package/dist/mcp/handlers/utils.js +97 -0
  210. package/dist/mcp/handlers/utils.js.map +7 -0
  211. package/dist/mcp/handlers/watchmen.js +104 -0
  212. package/dist/mcp/handlers/watchmen.js.map +7 -0
  213. package/dist/mcp/handlers/wiki.js +242 -0
  214. package/dist/mcp/handlers/wiki.js.map +7 -0
  215. package/dist/mcp/server.js +72 -3
  216. package/dist/mcp/server.js.map +2 -2
  217. package/dist/mcp/tool-names.js +136 -10
  218. package/dist/mcp/tool-names.js.map +2 -2
  219. package/dist/mcp/tools.js +846 -3019
  220. package/dist/mcp/tools.js.map +3 -3
  221. package/dist/types.js.map +2 -2
  222. package/package.json +36 -10
@@ -0,0 +1,563 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var code_health_exports = {};
20
+ __export(code_health_exports, {
21
+ handleCodeHealth: () => handleCodeHealth
22
+ });
23
+ module.exports = __toCommonJS(code_health_exports);
24
+ var import_utils = require("./utils");
25
+ async function handleCodeHealth(toolName, args, cg) {
26
+ switch (toolName) {
27
+ case "kirograph_dead_code": {
28
+ const limit = (0, import_utils.clampLimit)(args.limit, 50);
29
+ const dead = cg.findDeadCode(limit);
30
+ if (dead.length === 0) return "No dead code detected.";
31
+ return `Potential dead code (${dead.length} unexported symbols with no incoming references):
32
+ ` + dead.map((n) => `- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`).join("\n");
33
+ }
34
+ case "kirograph_circular_deps": {
35
+ const cycles = cg.findCircularDependencies();
36
+ if (cycles.length === 0) return "No circular dependencies found.";
37
+ return `Found ${cycles.length} circular dependency cycle(s):
38
+ ` + cycles.map((cycle, i) => `Cycle ${i + 1}: ${cycle.join(" \u2192 ")}`).join("\n");
39
+ }
40
+ case "kirograph_path": {
41
+ const fromResults = cg.searchNodes(args.from, void 0, 3);
42
+ const toResults = cg.searchNodes(args.to, void 0, 3);
43
+ if (fromResults.length === 0) return `Symbol "${args.from}" not found in index.`;
44
+ if (toResults.length === 0) return `Symbol "${args.to}" not found in index.`;
45
+ const fromNode = fromResults[0].node;
46
+ const toNode = toResults[0].node;
47
+ const pathNodes = await cg.findPath(fromNode.id, toNode.id);
48
+ if (pathNodes.length === 0) return `No path found between \`${fromNode.name}\` and \`${toNode.name}\`.`;
49
+ return `Path from \`${fromNode.name}\` to \`${toNode.name}\` (${pathNodes.length} nodes):
50
+ ` + pathNodes.map((n, i) => `${i + 1}. ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`).join("\n");
51
+ }
52
+ case "kirograph_type_hierarchy": {
53
+ const results = cg.searchNodes(args.symbol, void 0, 5);
54
+ if (results.length === 0) return `Symbol "${args.symbol}" not found in index.`;
55
+ const node = results[0].node;
56
+ const direction = args.direction ?? "both";
57
+ const hierarchy = cg.getTypeHierarchy(node.id, direction);
58
+ if (hierarchy.length === 0) return `No type hierarchy found for \`${node.name}\`.`;
59
+ return `Type hierarchy for \`${node.name}\` (direction: ${direction}):
60
+ ` + hierarchy.map((n) => `- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`).join("\n");
61
+ }
62
+ case "kirograph_hotspots": {
63
+ const limit = (0, import_utils.clampLimit)(args.limit, 20);
64
+ const hotspots = cg.findHotspots(limit);
65
+ if (hotspots.length === 0) return "No symbols found in index.";
66
+ const lines = [`Top ${hotspots.length} most-connected symbols (by edge degree):
67
+ `];
68
+ for (const n of hotspots) {
69
+ lines.push(`${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 degree ${n.degree} (in: ${n.inDegree}, out: ${n.outDegree})`);
70
+ lines.push(` File: ${n.filePath}:${n.startLine}`);
71
+ }
72
+ return lines.join("\n");
73
+ }
74
+ case "kirograph_surprising": {
75
+ const limit = (0, import_utils.clampLimit)(args.limit, 20);
76
+ const connections = cg.findSurprisingConnections(limit);
77
+ if (connections.length === 0) return "No surprising cross-file connections found.";
78
+ const lines = [`Top ${connections.length} surprising cross-file connections:
79
+ `];
80
+ for (const c of connections) {
81
+ lines.push(`${(0, import_utils.mapKind)(c.source.kind)} \`${c.source.name}\` ${c.kind}\u2192 ${(0, import_utils.mapKind)(c.target.kind)} \`${c.target.name}\` (score: ${c.score.toFixed(2)})`);
82
+ lines.push(` ${c.source.filePath} \u2192 ${c.target.filePath}`);
83
+ }
84
+ return lines.join("\n");
85
+ }
86
+ case "kirograph_diff": {
87
+ const sm = cg.createSnapshotManager();
88
+ const snapshot = args.snapshot ? sm.load(args.snapshot) : sm.loadLatest();
89
+ if (!snapshot) {
90
+ return args.snapshot ? `Snapshot "${args.snapshot}" not found. Use \`kirograph snapshot list\` to see available snapshots.` : "No snapshots found. Run `kirograph snapshot` to save one first.";
91
+ }
92
+ const diff = sm.diff(snapshot, sm.currentSnapshot());
93
+ const fromDate = new Date(diff.from.timestamp).toISOString().slice(0, 19).replace("T", " ");
94
+ const lines = [
95
+ `Graph diff: "${diff.from.label}" (${fromDate}) \u2192 current`,
96
+ ``,
97
+ `Symbols: +${diff.addedNodes.length} added, -${diff.removedNodes.length} removed`,
98
+ `Edges: +${diff.addedEdges.length} added, -${diff.removedEdges.length} removed`
99
+ ];
100
+ if (diff.addedNodes.length > 0) {
101
+ lines.push(`
102
+ ## Added symbols (${diff.addedNodes.length})`);
103
+ for (const n of diff.addedNodes.slice(0, 30)) {
104
+ lines.push(`+ ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}`);
105
+ }
106
+ if (diff.addedNodes.length > 30) lines.push(` \u2026and ${diff.addedNodes.length - 30} more`);
107
+ }
108
+ if (diff.removedNodes.length > 0) {
109
+ lines.push(`
110
+ ## Removed symbols (${diff.removedNodes.length})`);
111
+ for (const n of diff.removedNodes.slice(0, 30)) {
112
+ lines.push(`- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}`);
113
+ }
114
+ if (diff.removedNodes.length > 30) lines.push(` \u2026and ${diff.removedNodes.length - 30} more`);
115
+ }
116
+ return lines.join("\n");
117
+ }
118
+ case "kirograph_snapshot_save": {
119
+ const sm = cg.createSnapshotManager();
120
+ const snapshot = sm.save(args.label);
121
+ return `Snapshot saved: "${snapshot.label}" \u2014 ${snapshot.nodeCount} symbols, ${snapshot.edgeCount} edges`;
122
+ }
123
+ case "kirograph_snapshot_list": {
124
+ const sm = cg.createSnapshotManager();
125
+ const snapshots = sm.list();
126
+ if (snapshots.length === 0) return "No snapshots yet. Use kirograph_snapshot_save to save one first.";
127
+ const lines = [`Saved snapshots (${snapshots.length}):
128
+ `];
129
+ for (const s of snapshots) {
130
+ const date = new Date(s.timestamp).toISOString().slice(0, 19).replace("T", " ");
131
+ lines.push(`- ${s.label} (${date}, ${s.nodeCount} symbols, ${s.edgeCount} edges)`);
132
+ }
133
+ return lines.join("\n");
134
+ }
135
+ case "kirograph_module_api": {
136
+ const rawDb = cg.getDatabase().getRawDb();
137
+ const pathArg = args.path;
138
+ let rows;
139
+ if (pathArg) {
140
+ const exact = pathArg.endsWith(".ts") || pathArg.endsWith(".js") || pathArg.includes(".");
141
+ rows = exact ? rawDb.all(`SELECT * FROM nodes WHERE is_exported = 1 AND file_path = ? ORDER BY kind, name`, [pathArg]) : rawDb.all(`SELECT * FROM nodes WHERE is_exported = 1 AND file_path LIKE ? ORDER BY kind, name`, [pathArg.replace(/\/$/, "") + "/%"]);
142
+ } else {
143
+ rows = rawDb.all(`SELECT * FROM nodes WHERE is_exported = 1 ORDER BY file_path, kind, name`);
144
+ }
145
+ if (rows.length === 0) return pathArg ? `No exported symbols found in "${pathArg}".` : "No exported symbols found.";
146
+ const limit = (0, import_utils.clampLimit)(args.limit, 100);
147
+ const limited = rows.slice(0, limit);
148
+ const lines = [`Exported API surface${pathArg ? ` for "${pathArg}"` : ""} (${limited.length}${rows.length > limit ? `/${rows.length}` : ""} symbols):
149
+ `];
150
+ let lastFile = "";
151
+ for (const r of limited) {
152
+ if (r.file_path !== lastFile) {
153
+ lines.push(`
154
+ ${r.file_path}`);
155
+ lastFile = r.file_path;
156
+ }
157
+ const sig = r.signature ? ` ${r.signature}` : "";
158
+ lines.push(` ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\`${sig}`);
159
+ }
160
+ return lines.join("\n");
161
+ }
162
+ case "kirograph_rename_preview": {
163
+ const results = cg.searchNodes(args.symbol, void 0, 5);
164
+ if (results.length === 0) return `Symbol "${args.symbol}" not found in index.`;
165
+ const node = results[0].node;
166
+ const rawDb = cg.getDatabase().getRawDb();
167
+ const refs = rawDb.all(
168
+ `SELECT n.name, n.kind, n.file_path, n.start_line, e.kind as edge_kind
169
+ FROM edges e JOIN nodes n ON e.source = n.id
170
+ WHERE e.target = ? AND e.kind != 'contains'
171
+ ORDER BY n.file_path, n.start_line`,
172
+ [node.id]
173
+ );
174
+ if (refs.length === 0) return `No references to \`${node.name}\` found. Safe to rename.`;
175
+ const lines = [
176
+ `Rename preview for \`${node.name}\` (${(0, import_utils.mapKind)(node.kind)})`,
177
+ `Defined in: ${node.filePath}:${node.startLine}`,
178
+ `
179
+ ${refs.length} reference site(s):
180
+ `
181
+ ];
182
+ let lastFile = "";
183
+ for (const r of refs) {
184
+ if (r.file_path !== lastFile) {
185
+ lines.push(`
186
+ ${r.file_path}`);
187
+ lastFile = r.file_path;
188
+ }
189
+ lines.push(` ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` (line ${r.start_line}, via ${r.edge_kind})`);
190
+ }
191
+ return lines.join("\n");
192
+ }
193
+ case "kirograph_doc_coverage": {
194
+ const rawDb = cg.getDatabase().getRawDb();
195
+ const limitN = (0, import_utils.clampLimit)(args.limit, 50);
196
+ const rows = rawDb.all(
197
+ `SELECT kind, name, file_path, start_line FROM nodes
198
+ WHERE is_exported = 1 AND (docstring IS NULL OR docstring = '')
199
+ AND kind IN ('function','method','class','interface','type_alias')
200
+ ORDER BY file_path, start_line LIMIT ?`,
201
+ [limitN]
202
+ );
203
+ if (rows.length === 0) return "All exported symbols have docstrings.";
204
+ const lines = [`Exported symbols missing docstrings (${rows.length}):
205
+ `];
206
+ let lastFile = "";
207
+ for (const r of rows) {
208
+ if (r.file_path !== lastFile) {
209
+ lines.push(`
210
+ ${r.file_path}`);
211
+ lastFile = r.file_path;
212
+ }
213
+ lines.push(` ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 line ${r.start_line}`);
214
+ }
215
+ return lines.join("\n");
216
+ }
217
+ case "kirograph_god_class": {
218
+ const rawDb = cg.getDatabase().getRawDb();
219
+ const limitN = (0, import_utils.clampLimit)(args.limit, 20);
220
+ const rows = rawDb.all(
221
+ `SELECT n.name, n.file_path, n.start_line, COUNT(e.target) as member_count
222
+ FROM nodes n JOIN edges e ON e.source = n.id AND e.kind = 'contains'
223
+ WHERE n.kind IN ('class','interface')
224
+ GROUP BY n.id HAVING member_count > 0
225
+ ORDER BY member_count DESC LIMIT ?`,
226
+ [limitN]
227
+ );
228
+ if (rows.length === 0) return "No class definitions found.";
229
+ const threshold = args.threshold ?? 10;
230
+ const gods = rows.filter((r) => r.member_count >= threshold);
231
+ const lines = [
232
+ `Classes ranked by member count (threshold: ${threshold}):
233
+ `,
234
+ ...rows.map((r) => `${r.member_count >= threshold ? "\u26A0 " : " "}${r.member_count.toString().padStart(4)} members \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`)
235
+ ];
236
+ if (gods.length > 0) lines.unshift(`${gods.length} god class(es) found (\u2265${threshold} members).
237
+ `);
238
+ return lines.join("\n");
239
+ }
240
+ case "kirograph_inheritance_depth": {
241
+ let depth2 = function(id) {
242
+ if (depths.has(id)) return depths.get(id);
243
+ const parents = childToParents.get(id) ?? [];
244
+ const d = parents.length === 0 ? 0 : 1 + Math.max(...parents.map(depth2));
245
+ depths.set(id, d);
246
+ return d;
247
+ };
248
+ var depth = depth2;
249
+ const rawDb = cg.getDatabase().getRawDb();
250
+ const limitN = (0, import_utils.clampLimit)(args.limit, 20);
251
+ const allNodes = rawDb.all(
252
+ `SELECT id, name, file_path, start_line FROM nodes WHERE kind IN ('class','interface')`,
253
+ []
254
+ );
255
+ const childToParents = /* @__PURE__ */ new Map();
256
+ const extEdges = rawDb.all(
257
+ `SELECT source, target FROM edges WHERE kind IN ('extends','implements')`,
258
+ []
259
+ );
260
+ for (const e of extEdges) {
261
+ if (!childToParents.has(e.source)) childToParents.set(e.source, []);
262
+ childToParents.get(e.source).push(e.target);
263
+ }
264
+ const depths = /* @__PURE__ */ new Map();
265
+ for (const n of allNodes) depth2(n.id);
266
+ const sorted = allNodes.map((n) => ({ ...n, depth: depths.get(n.id) ?? 0 })).filter((n) => n.depth > 0).sort((a, b) => b.depth - a.depth).slice(0, limitN);
267
+ if (sorted.length === 0) return "No inheritance hierarchies found.";
268
+ return `Deepest inheritance chains (${sorted.length}):
269
+
270
+ ` + sorted.map((n) => ` depth ${n.depth} \`${n.name}\` \u2014 ${n.file_path}:${n.start_line}`).join("\n");
271
+ }
272
+ case "kirograph_recursion": {
273
+ const rawDb = cg.getDatabase().getRawDb();
274
+ const limitN = (0, import_utils.clampLimit)(args.limit, 30);
275
+ const direct = rawDb.all(
276
+ `SELECT n.name, n.kind, n.file_path, n.start_line FROM nodes n
277
+ JOIN edges e ON e.source = n.id AND e.target = n.id AND e.kind = 'calls'
278
+ WHERE n.kind IN ('function','method')
279
+ ORDER BY n.file_path, n.start_line LIMIT ?`,
280
+ [Math.ceil(limitN / 2)]
281
+ );
282
+ const mutual = rawDb.all(
283
+ `SELECT n1.name as a, n2.name as b, n1.file_path, n1.start_line FROM edges e1
284
+ JOIN edges e2 ON e1.target = e2.source AND e2.target = e1.source
285
+ JOIN nodes n1 ON n1.id = e1.source JOIN nodes n2 ON n2.id = e2.source
286
+ WHERE e1.kind = 'calls' AND e2.kind = 'calls' AND e1.source < e2.source
287
+ ORDER BY n1.name LIMIT ?`,
288
+ [Math.ceil(limitN / 2)]
289
+ );
290
+ if (direct.length === 0 && mutual.length === 0) return "No recursive functions detected.";
291
+ const lines = [];
292
+ if (direct.length > 0) {
293
+ lines.push(`Direct recursion (${direct.length}):
294
+ `);
295
+ for (const r of direct) lines.push(` ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`);
296
+ }
297
+ if (mutual.length > 0) {
298
+ if (lines.length > 0) lines.push("");
299
+ lines.push(`Mutual recursion (${mutual.length} pairs):
300
+ `);
301
+ for (const r of mutual) lines.push(` \`${r.a}\` \u2194 \`${r.b}\` \u2014 ${r.file_path}:${r.start_line}`);
302
+ }
303
+ return lines.join("\n");
304
+ }
305
+ case "kirograph_largest": {
306
+ const rawDb = cg.getDatabase().getRawDb();
307
+ const limitN = (0, import_utils.clampLimit)(args.limit, 30);
308
+ const rows = rawDb.all(
309
+ `SELECT name, kind, file_path, start_line, (end_line - start_line + 1) as loc
310
+ FROM nodes WHERE end_line IS NOT NULL AND end_line > start_line
311
+ ORDER BY loc DESC LIMIT ?`,
312
+ [limitN]
313
+ );
314
+ if (rows.length === 0) return "No symbol size data available.";
315
+ return `Largest symbols by lines of code (${rows.length}):
316
+
317
+ ` + rows.map((r) => ` ${r.loc.toString().padStart(5)} LOC ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`).join("\n");
318
+ }
319
+ case "kirograph_rank": {
320
+ const rawDb = cg.getDatabase().getRawDb();
321
+ const limitN = (0, import_utils.clampLimit)(args.limit, 30);
322
+ const by = args.by ?? "fan-in";
323
+ let rows;
324
+ if (by === "fan-out") {
325
+ rows = rawDb.all(
326
+ `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.target) as score
327
+ FROM nodes n JOIN edges e ON e.source = n.id AND e.kind = 'calls'
328
+ GROUP BY n.id ORDER BY score DESC LIMIT ?`,
329
+ [limitN]
330
+ );
331
+ } else {
332
+ rows = rawDb.all(
333
+ `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.source) as score
334
+ FROM nodes n JOIN edges e ON e.target = n.id AND e.kind IN ('calls','imports')
335
+ GROUP BY n.id ORDER BY score DESC LIMIT ?`,
336
+ [limitN]
337
+ );
338
+ }
339
+ if (rows.length === 0) return `No ${by} data available.`;
340
+ return `Symbols ranked by ${by} (${rows.length}):
341
+
342
+ ` + rows.map((r) => ` ${r.score.toString().padStart(5)} ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`).join("\n");
343
+ }
344
+ case "kirograph_distribution": {
345
+ const rawDb = cg.getDatabase().getRawDb();
346
+ const pathArg = args.path;
347
+ let rows;
348
+ if (pathArg) {
349
+ rows = rawDb.all(
350
+ `SELECT kind, COUNT(*) as count FROM nodes WHERE file_path LIKE ?
351
+ GROUP BY kind ORDER BY count DESC`,
352
+ [pathArg.replace(/\/$/, "") + "%"]
353
+ );
354
+ } else {
355
+ rows = rawDb.all(`SELECT kind, COUNT(*) as count FROM nodes GROUP BY kind ORDER BY count DESC`, []);
356
+ }
357
+ if (rows.length === 0) return "No symbols found.";
358
+ const total = rows.reduce((s, r) => s + r.count, 0);
359
+ const lines = [`Symbol distribution${pathArg ? ` in "${pathArg}"` : ""} (${total} total):
360
+ `];
361
+ for (const r of rows) {
362
+ const pct = (r.count / total * 100).toFixed(1);
363
+ lines.push(` ${r.count.toString().padStart(6)} (${pct.padStart(5)}%) ${r.kind}`);
364
+ }
365
+ return lines.join("\n");
366
+ }
367
+ case "kirograph_annotations": {
368
+ const rawDb = cg.getDatabase().getRawDb();
369
+ const limitN = (0, import_utils.clampLimit)(args.limit, 50);
370
+ const decorator = args.decorator;
371
+ let rows;
372
+ if (decorator) {
373
+ rows = rawDb.all(
374
+ `SELECT name, kind, file_path, start_line, decorators FROM nodes
375
+ WHERE decorators LIKE ? ORDER BY file_path, start_line LIMIT ?`,
376
+ [`%${decorator}%`, limitN]
377
+ );
378
+ } else {
379
+ const all = rawDb.all(`SELECT decorators FROM nodes WHERE decorators IS NOT NULL AND decorators != '[]'`, []);
380
+ const hist = /* @__PURE__ */ new Map();
381
+ for (const r of all) {
382
+ try {
383
+ const decs = JSON.parse(r.decorators);
384
+ for (const d of decs) hist.set(d, (hist.get(d) ?? 0) + 1);
385
+ } catch {
386
+ }
387
+ }
388
+ if (hist.size === 0) return "No decorators/annotations found.";
389
+ const sorted = [...hist.entries()].sort((a, b) => b[1] - a[1]).slice(0, limitN);
390
+ return `Decorator/annotation histogram (${hist.size} unique):
391
+
392
+ ` + sorted.map(([d, n]) => ` ${n.toString().padStart(5)} @${d}`).join("\n");
393
+ }
394
+ if (rows.length === 0) return `No symbols with decorator "${decorator}" found.`;
395
+ return `Symbols with @${decorator} (${rows.length}):
396
+
397
+ ` + rows.map((r) => ` ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`).join("\n");
398
+ }
399
+ case "kirograph_session_start": {
400
+ const sm = cg.createSnapshotManager();
401
+ const snapshot = sm.save("session-baseline");
402
+ return `Session baseline saved: ${snapshot.nodeCount} symbols, ${snapshot.edgeCount} edges.
403
+ Use kirograph_session_end to see what changed.`;
404
+ }
405
+ case "kirograph_session_end": {
406
+ const sm = cg.createSnapshotManager();
407
+ const snapshots = sm.list();
408
+ const baseline = snapshots.find((s) => s.label === "session-baseline");
409
+ if (!baseline) return "No session baseline found. Run kirograph_session_start first.";
410
+ const current = sm.save(`session-end-${Date.now()}`);
411
+ const nodeDelta = current.nodeCount - baseline.nodeCount;
412
+ const edgeDelta = current.edgeCount - baseline.edgeCount;
413
+ const lines = [
414
+ `Session delta (since ${new Date(baseline.timestamp).toISOString().slice(0, 19).replace("T", " ")}):`,
415
+ ` Symbols: ${baseline.nodeCount} \u2192 ${current.nodeCount} (${nodeDelta >= 0 ? "+" : ""}${nodeDelta})`,
416
+ ` Edges: ${baseline.edgeCount} \u2192 ${current.edgeCount} (${edgeDelta >= 0 ? "+" : ""}${edgeDelta})`
417
+ ];
418
+ return lines.join("\n");
419
+ }
420
+ case "kirograph_unused_imports": {
421
+ const rawDb = cg.getDatabase().getRawDb();
422
+ const limitN = (0, import_utils.clampLimit)(args.limit, 50);
423
+ const rows = rawDb.all(
424
+ `SELECT n.* FROM nodes n
425
+ LEFT JOIN edges e ON e.source = n.id AND e.kind != 'contains'
426
+ WHERE n.kind = 'import'
427
+ GROUP BY n.id HAVING COUNT(e.id) = 0
428
+ ORDER BY n.file_path, n.start_line LIMIT ?`,
429
+ [limitN]
430
+ );
431
+ if (rows.length === 0) return "No unused imports detected.";
432
+ const lines = [`Unused imports (${rows.length}):
433
+ `];
434
+ let lastFile = "";
435
+ for (const r of rows) {
436
+ if (r.file_path !== lastFile) {
437
+ lines.push(`
438
+ ${r.file_path}`);
439
+ lastFile = r.file_path;
440
+ }
441
+ lines.push(` ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 line ${r.start_line}`);
442
+ }
443
+ return lines.join("\n");
444
+ }
445
+ case "kirograph_gini": {
446
+ const rawDb = cg.getDatabase().getRawDb();
447
+ const metric = args.metric ?? "loc";
448
+ let values;
449
+ let rows;
450
+ if (metric === "loc") {
451
+ rows = rawDb.all(
452
+ `SELECT name, kind, file_path, start_line, (end_line - start_line + 1) as val
453
+ FROM nodes
454
+ WHERE kind IN ('function','method') AND end_line IS NOT NULL AND end_line >= start_line
455
+ ORDER BY val DESC`,
456
+ []
457
+ );
458
+ } else if (metric === "fan-out") {
459
+ rows = rawDb.all(
460
+ `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.target) as val
461
+ FROM nodes n LEFT JOIN edges e ON e.source = n.id AND e.kind = 'calls'
462
+ WHERE n.kind IN ('function','method')
463
+ GROUP BY n.id ORDER BY val DESC`,
464
+ []
465
+ );
466
+ } else {
467
+ rows = rawDb.all(
468
+ `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.source) as val
469
+ FROM nodes n LEFT JOIN edges e ON e.target = n.id AND e.kind IN ('calls','imports','references')
470
+ WHERE n.kind IN ('function','method')
471
+ GROUP BY n.id ORDER BY val DESC`,
472
+ []
473
+ );
474
+ }
475
+ if (rows.length < 2) return "Not enough function/method nodes to compute Gini coefficient.";
476
+ values = rows.map((r) => Number(r.val));
477
+ const n = values.length;
478
+ const sum = values.reduce((a, b) => a + b, 0);
479
+ let gini = 0;
480
+ if (sum > 0) {
481
+ const sorted = [...values].sort((a, b) => a - b);
482
+ const numerator = sorted.reduce((acc, x, i) => acc + (2 * (i + 1) - n - 1) * x, 0);
483
+ gini = numerator / (n * sum);
484
+ }
485
+ const top5 = rows.slice(0, 5);
486
+ const bottom5 = rows.slice(-5).reverse();
487
+ const lines = [
488
+ `Gini coefficient for ${metric} across ${n} function/method nodes: ${gini.toFixed(4)}`,
489
+ `(0 = perfect equality, 1 = total inequality)
490
+ `,
491
+ `Top 5 by ${metric}:`,
492
+ ...top5.map((r) => ` ${String(r.val).padStart(6)} ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`),
493
+ `
494
+ Bottom 5 by ${metric}:`,
495
+ ...bottom5.map((r) => ` ${String(r.val).padStart(6)} ${(0, import_utils.mapKind)(r.kind)} \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`)
496
+ ];
497
+ return lines.join("\n");
498
+ }
499
+ case "kirograph_dependency_depth": {
500
+ const rawDb = cg.getDatabase().getRawDb();
501
+ const limitN = (0, import_utils.clampLimit)(args.limit, 20);
502
+ const fileRows = rawDb.all(`SELECT DISTINCT file_path FROM nodes ORDER BY file_path`, []);
503
+ const files = fileRows.map((r) => r.file_path);
504
+ if (files.length === 0) return "No files found in index.";
505
+ const edgeRows = rawDb.all(
506
+ `SELECT DISTINCT n1.file_path as src, n2.file_path as tgt
507
+ FROM edges e
508
+ JOIN nodes n1 ON n1.id = e.source
509
+ JOIN nodes n2 ON n2.id = e.target
510
+ WHERE e.kind = 'imports' AND n1.file_path != n2.file_path`,
511
+ []
512
+ );
513
+ const outEdges = /* @__PURE__ */ new Map();
514
+ const inDegree = /* @__PURE__ */ new Map();
515
+ for (const f of files) {
516
+ outEdges.set(f, /* @__PURE__ */ new Set());
517
+ inDegree.set(f, 0);
518
+ }
519
+ for (const e of edgeRows) {
520
+ outEdges.get(e.src)?.add(e.tgt);
521
+ inDegree.set(e.tgt, (inDegree.get(e.tgt) ?? 0) + 1);
522
+ }
523
+ const level = /* @__PURE__ */ new Map();
524
+ const queue = [];
525
+ for (const f of files) {
526
+ if ((inDegree.get(f) ?? 0) === 0) {
527
+ queue.push(f);
528
+ level.set(f, 0);
529
+ }
530
+ }
531
+ while (queue.length > 0) {
532
+ const cur = queue.shift();
533
+ const curLevel = level.get(cur) ?? 0;
534
+ for (const nb of outEdges.get(cur) ?? []) {
535
+ const newLevel = curLevel + 1;
536
+ if ((level.get(nb) ?? -1) < newLevel) level.set(nb, newLevel);
537
+ const deg = (inDegree.get(nb) ?? 1) - 1;
538
+ inDegree.set(nb, deg);
539
+ if (deg === 0) queue.push(nb);
540
+ }
541
+ }
542
+ const sorted = files.map((f) => ({ file: f, depth: level.get(f) ?? 0 })).sort((a, b) => b.depth - a.depth).slice(0, limitN);
543
+ const lines = [`File dependency depths (deepest first, limit ${limitN}):
544
+ `];
545
+ for (const { file, depth: depth2 } of sorted) {
546
+ const sample = rawDb.all(
547
+ `SELECT name, kind FROM nodes WHERE file_path = ? AND kind IN ('function','class','interface','method') LIMIT 3`,
548
+ [file]
549
+ );
550
+ const symbols = sample.map((r) => `\`${r.name}\``).join(", ");
551
+ lines.push(` depth ${String(depth2).padStart(3)} ${file}${symbols ? ` (${symbols})` : ""}`);
552
+ }
553
+ return lines.join("\n");
554
+ }
555
+ default:
556
+ return `Unknown tool: ${toolName}`;
557
+ }
558
+ }
559
+ // Annotate the CommonJS export names for ESM import in node:
560
+ 0 && (module.exports = {
561
+ handleCodeHealth
562
+ });
563
+ //# sourceMappingURL=code-health.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/handlers/code-health.ts"],
4
+ "sourcesContent": ["import KiroGraph from '../../index';\nimport { clampLimit, mapKind, truncate } from './utils';\n\nexport async function handleCodeHealth(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\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_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 case 'kirograph_snapshot_save': {\n const sm = cg.createSnapshotManager();\n const snapshot = sm.save(args.label as string | undefined);\n return `Snapshot saved: \"${snapshot.label}\" \u2014 ${snapshot.nodeCount} symbols, ${snapshot.edgeCount} edges`;\n }\n\n case 'kirograph_snapshot_list': {\n const sm = cg.createSnapshotManager();\n const snapshots = sm.list();\n if (snapshots.length === 0) return 'No snapshots yet. Use kirograph_snapshot_save to save one first.';\n const lines = [`Saved snapshots (${snapshots.length}):\\n`];\n for (const s of snapshots) {\n const date = new Date(s.timestamp).toISOString().slice(0, 19).replace('T', ' ');\n lines.push(`- ${s.label} (${date}, ${s.nodeCount} symbols, ${s.edgeCount} edges)`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_module_api': {\n const rawDb = cg.getDatabase().getRawDb();\n const pathArg = args.path as string | undefined;\n let rows: any[];\n if (pathArg) {\n const exact = pathArg.endsWith('.ts') || pathArg.endsWith('.js') || pathArg.includes('.');\n rows = exact\n ? rawDb.all(`SELECT * FROM nodes WHERE is_exported = 1 AND file_path = ? ORDER BY kind, name`, [pathArg])\n : rawDb.all(`SELECT * FROM nodes WHERE is_exported = 1 AND file_path LIKE ? ORDER BY kind, name`, [pathArg.replace(/\\/$/, '') + '/%']);\n } else {\n rows = rawDb.all(`SELECT * FROM nodes WHERE is_exported = 1 ORDER BY file_path, kind, name`);\n }\n if (rows.length === 0) return pathArg ? `No exported symbols found in \"${pathArg}\".` : 'No exported symbols found.';\n const limit = clampLimit(args.limit as number | undefined, 100);\n const limited = rows.slice(0, limit);\n const lines = [`Exported API surface${pathArg ? ` for \"${pathArg}\"` : ''} (${limited.length}${rows.length > limit ? `/${rows.length}` : ''} symbols):\\n`];\n let lastFile = '';\n for (const r of limited) {\n if (r.file_path !== lastFile) { lines.push(`\\n${r.file_path}`); lastFile = r.file_path; }\n const sig = r.signature ? ` ${r.signature}` : '';\n lines.push(` ${mapKind(r.kind)} \\`${r.name}\\`${sig}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_rename_preview': {\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 rawDb = cg.getDatabase().getRawDb();\n const refs = rawDb.all(\n `SELECT n.name, n.kind, n.file_path, n.start_line, e.kind as edge_kind\n FROM edges e JOIN nodes n ON e.source = n.id\n WHERE e.target = ? AND e.kind != 'contains'\n ORDER BY n.file_path, n.start_line`,\n [node.id]\n );\n if (refs.length === 0) return `No references to \\`${node.name}\\` found. Safe to rename.`;\n const lines = [\n `Rename preview for \\`${node.name}\\` (${mapKind(node.kind)})`,\n `Defined in: ${node.filePath}:${node.startLine}`,\n `\\n${refs.length} reference site(s):\\n`,\n ];\n let lastFile = '';\n for (const r of refs) {\n if (r.file_path !== lastFile) { lines.push(`\\n${r.file_path}`); lastFile = r.file_path; }\n lines.push(` ${mapKind(r.kind)} \\`${r.name}\\` (line ${r.start_line}, via ${r.edge_kind})`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_doc_coverage': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 50);\n const rows = rawDb.all(\n `SELECT kind, name, file_path, start_line FROM nodes\n WHERE is_exported = 1 AND (docstring IS NULL OR docstring = '')\n AND kind IN ('function','method','class','interface','type_alias')\n ORDER BY file_path, start_line LIMIT ?`,\n [limitN]\n );\n if (rows.length === 0) return 'All exported symbols have docstrings.';\n const lines = [`Exported symbols missing docstrings (${rows.length}):\\n`];\n let lastFile = '';\n for (const r of rows) {\n if (r.file_path !== lastFile) { lines.push(`\\n${r.file_path}`); lastFile = r.file_path; }\n lines.push(` ${mapKind(r.kind)} \\`${r.name}\\` \u2014 line ${r.start_line}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_god_class': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 20);\n const rows = rawDb.all(\n `SELECT n.name, n.file_path, n.start_line, COUNT(e.target) as member_count\n FROM nodes n JOIN edges e ON e.source = n.id AND e.kind = 'contains'\n WHERE n.kind IN ('class','interface')\n GROUP BY n.id HAVING member_count > 0\n ORDER BY member_count DESC LIMIT ?`,\n [limitN]\n );\n if (rows.length === 0) return 'No class definitions found.';\n const threshold = (args.threshold as number) ?? 10;\n const gods = rows.filter((r: any) => r.member_count >= threshold);\n const lines = [\n `Classes ranked by member count (threshold: ${threshold}):\\n`,\n ...rows.map((r: any) => `${r.member_count >= threshold ? '\u26A0 ' : ' '}${r.member_count.toString().padStart(4)} members \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`),\n ];\n if (gods.length > 0) lines.unshift(`${gods.length} god class(es) found (\u2265${threshold} members).\\n`);\n return lines.join('\\n');\n }\n\n case 'kirograph_inheritance_depth': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 20);\n // BFS from root classes down the extends/implements hierarchy\n const allNodes = rawDb.all(\n `SELECT id, name, file_path, start_line FROM nodes WHERE kind IN ('class','interface')`,\n []\n );\n const childToParents: Map<string, string[]> = new Map();\n const extEdges = rawDb.all(\n `SELECT source, target FROM edges WHERE kind IN ('extends','implements')`,\n []\n );\n for (const e of extEdges) {\n if (!childToParents.has(e.source)) childToParents.set(e.source, []);\n childToParents.get(e.source)!.push(e.target);\n }\n // Compute depth per node via memoized DFS\n const depths = new Map<string, number>();\n function depth(id: string): number {\n if (depths.has(id)) return depths.get(id)!;\n const parents = childToParents.get(id) ?? [];\n const d = parents.length === 0 ? 0 : 1 + Math.max(...parents.map(depth));\n depths.set(id, d);\n return d;\n }\n for (const n of allNodes) depth(n.id);\n const sorted = allNodes\n .map((n: any) => ({ ...n, depth: depths.get(n.id) ?? 0 }))\n .filter((n: any) => n.depth > 0)\n .sort((a: any, b: any) => b.depth - a.depth)\n .slice(0, limitN);\n if (sorted.length === 0) return 'No inheritance hierarchies found.';\n return `Deepest inheritance chains (${sorted.length}):\\n\\n` +\n sorted.map((n: any) => ` depth ${n.depth} \\`${n.name}\\` \u2014 ${n.file_path}:${n.start_line}`).join('\\n');\n }\n\n case 'kirograph_recursion': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 30);\n // Direct recursion: node calls itself\n const direct = rawDb.all(\n `SELECT n.name, n.kind, n.file_path, n.start_line FROM nodes n\n JOIN edges e ON e.source = n.id AND e.target = n.id AND e.kind = 'calls'\n WHERE n.kind IN ('function','method')\n ORDER BY n.file_path, n.start_line LIMIT ?`,\n [Math.ceil(limitN / 2)]\n );\n // Mutual recursion via SCCs on call graph (simple 2-cycle detection)\n const mutual = rawDb.all(\n `SELECT n1.name as a, n2.name as b, n1.file_path, n1.start_line FROM edges e1\n JOIN edges e2 ON e1.target = e2.source AND e2.target = e1.source\n JOIN nodes n1 ON n1.id = e1.source JOIN nodes n2 ON n2.id = e2.source\n WHERE e1.kind = 'calls' AND e2.kind = 'calls' AND e1.source < e2.source\n ORDER BY n1.name LIMIT ?`,\n [Math.ceil(limitN / 2)]\n );\n if (direct.length === 0 && mutual.length === 0) return 'No recursive functions detected.';\n const lines = [];\n if (direct.length > 0) {\n lines.push(`Direct recursion (${direct.length}):\\n`);\n for (const r of direct) lines.push(` ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`);\n }\n if (mutual.length > 0) {\n if (lines.length > 0) lines.push('');\n lines.push(`Mutual recursion (${mutual.length} pairs):\\n`);\n for (const r of mutual) lines.push(` \\`${r.a}\\` \u2194 \\`${r.b}\\` \u2014 ${r.file_path}:${r.start_line}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_largest': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 30);\n const rows = rawDb.all(\n `SELECT name, kind, file_path, start_line, (end_line - start_line + 1) as loc\n FROM nodes WHERE end_line IS NOT NULL AND end_line > start_line\n ORDER BY loc DESC LIMIT ?`,\n [limitN]\n );\n if (rows.length === 0) return 'No symbol size data available.';\n return `Largest symbols by lines of code (${rows.length}):\\n\\n` +\n rows.map((r: any) => ` ${r.loc.toString().padStart(5)} LOC ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`).join('\\n');\n }\n\n case 'kirograph_rank': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 30);\n const by = (args.by as string) ?? 'fan-in';\n let rows: any[];\n if (by === 'fan-out') {\n rows = rawDb.all(\n `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.target) as score\n FROM nodes n JOIN edges e ON e.source = n.id AND e.kind = 'calls'\n GROUP BY n.id ORDER BY score DESC LIMIT ?`,\n [limitN]\n );\n } else {\n rows = rawDb.all(\n `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.source) as score\n FROM nodes n JOIN edges e ON e.target = n.id AND e.kind IN ('calls','imports')\n GROUP BY n.id ORDER BY score DESC LIMIT ?`,\n [limitN]\n );\n }\n if (rows.length === 0) return `No ${by} data available.`;\n return `Symbols ranked by ${by} (${rows.length}):\\n\\n` +\n rows.map((r: any) => ` ${r.score.toString().padStart(5)} ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`).join('\\n');\n }\n\n case 'kirograph_distribution': {\n const rawDb = cg.getDatabase().getRawDb();\n const pathArg = args.path as string | undefined;\n let rows: any[];\n if (pathArg) {\n rows = rawDb.all(\n `SELECT kind, COUNT(*) as count FROM nodes WHERE file_path LIKE ?\n GROUP BY kind ORDER BY count DESC`,\n [pathArg.replace(/\\/$/, '') + '%']\n );\n } else {\n rows = rawDb.all(`SELECT kind, COUNT(*) as count FROM nodes GROUP BY kind ORDER BY count DESC`, []);\n }\n if (rows.length === 0) return 'No symbols found.';\n const total = rows.reduce((s: number, r: any) => s + r.count, 0);\n const lines = [`Symbol distribution${pathArg ? ` in \"${pathArg}\"` : ''} (${total} total):\\n`];\n for (const r of rows) {\n const pct = ((r.count / total) * 100).toFixed(1);\n lines.push(` ${r.count.toString().padStart(6)} (${pct.padStart(5)}%) ${r.kind}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_annotations': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 50);\n const decorator = args.decorator as string | undefined;\n let rows: any[];\n if (decorator) {\n rows = rawDb.all(\n `SELECT name, kind, file_path, start_line, decorators FROM nodes\n WHERE decorators LIKE ? ORDER BY file_path, start_line LIMIT ?`,\n [`%${decorator}%`, limitN]\n );\n } else {\n // Histogram of decorators\n const all = rawDb.all(`SELECT decorators FROM nodes WHERE decorators IS NOT NULL AND decorators != '[]'`, []);\n const hist = new Map<string, number>();\n for (const r of all) {\n try {\n const decs: string[] = JSON.parse(r.decorators);\n for (const d of decs) hist.set(d, (hist.get(d) ?? 0) + 1);\n } catch { /* skip */ }\n }\n if (hist.size === 0) return 'No decorators/annotations found.';\n const sorted = [...hist.entries()].sort((a, b) => b[1] - a[1]).slice(0, limitN);\n return `Decorator/annotation histogram (${hist.size} unique):\\n\\n` +\n sorted.map(([d, n]) => ` ${n.toString().padStart(5)} @${d}`).join('\\n');\n }\n if (rows.length === 0) return `No symbols with decorator \"${decorator}\" found.`;\n return `Symbols with @${decorator} (${rows.length}):\\n\\n` +\n rows.map((r: any) => ` ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`).join('\\n');\n }\n\n case 'kirograph_session_start': {\n const sm = cg.createSnapshotManager();\n const snapshot = sm.save('session-baseline');\n return `Session baseline saved: ${snapshot.nodeCount} symbols, ${snapshot.edgeCount} edges.\\nUse kirograph_session_end to see what changed.`;\n }\n\n case 'kirograph_session_end': {\n const sm = cg.createSnapshotManager();\n const snapshots = sm.list();\n const baseline = snapshots.find(s => s.label === 'session-baseline');\n if (!baseline) return 'No session baseline found. Run kirograph_session_start first.';\n const current = sm.save(`session-end-${Date.now()}`);\n const nodeDelta = current.nodeCount - baseline.nodeCount;\n const edgeDelta = current.edgeCount - baseline.edgeCount;\n const lines = [\n `Session delta (since ${new Date(baseline.timestamp).toISOString().slice(0, 19).replace('T', ' ')}):`,\n ` Symbols: ${baseline.nodeCount} \u2192 ${current.nodeCount} (${nodeDelta >= 0 ? '+' : ''}${nodeDelta})`,\n ` Edges: ${baseline.edgeCount} \u2192 ${current.edgeCount} (${edgeDelta >= 0 ? '+' : ''}${edgeDelta})`,\n ];\n return lines.join('\\n');\n }\n\n case 'kirograph_unused_imports': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 50);\n const rows = rawDb.all(\n `SELECT n.* FROM nodes n\n LEFT JOIN edges e ON e.source = n.id AND e.kind != 'contains'\n WHERE n.kind = 'import'\n GROUP BY n.id HAVING COUNT(e.id) = 0\n ORDER BY n.file_path, n.start_line LIMIT ?`,\n [limitN]\n );\n if (rows.length === 0) return 'No unused imports detected.';\n const lines = [`Unused imports (${rows.length}):\\n`];\n let lastFile = '';\n for (const r of rows) {\n if (r.file_path !== lastFile) { lines.push(`\\n${r.file_path}`); lastFile = r.file_path; }\n lines.push(` ${mapKind(r.kind)} \\`${r.name}\\` \u2014 line ${r.start_line}`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_gini': {\n const rawDb = cg.getDatabase().getRawDb();\n const metric = (args.metric as string) ?? 'loc';\n let values: number[];\n let rows: any[];\n\n if (metric === 'loc') {\n rows = rawDb.all(\n `SELECT name, kind, file_path, start_line, (end_line - start_line + 1) as val\n FROM nodes\n WHERE kind IN ('function','method') AND end_line IS NOT NULL AND end_line >= start_line\n ORDER BY val DESC`,\n []\n );\n } else if (metric === 'fan-out') {\n rows = rawDb.all(\n `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.target) as val\n FROM nodes n LEFT JOIN edges e ON e.source = n.id AND e.kind = 'calls'\n WHERE n.kind IN ('function','method')\n GROUP BY n.id ORDER BY val DESC`,\n []\n );\n } else {\n // fan-in\n rows = rawDb.all(\n `SELECT n.name, n.kind, n.file_path, n.start_line, COUNT(e.source) as val\n FROM nodes n LEFT JOIN edges e ON e.target = n.id AND e.kind IN ('calls','imports','references')\n WHERE n.kind IN ('function','method')\n GROUP BY n.id ORDER BY val DESC`,\n []\n );\n }\n\n if (rows.length < 2) return 'Not enough function/method nodes to compute Gini coefficient.';\n\n values = rows.map((r: any) => Number(r.val));\n const n = values.length;\n const sum = values.reduce((a, b) => a + b, 0);\n\n let gini = 0;\n if (sum > 0) {\n const sorted = [...values].sort((a, b) => a - b);\n const numerator = sorted.reduce((acc, x, i) => acc + (2 * (i + 1) - n - 1) * x, 0);\n gini = numerator / (n * sum);\n }\n\n const top5 = rows.slice(0, 5);\n const bottom5 = rows.slice(-5).reverse();\n\n const lines = [\n `Gini coefficient for ${metric} across ${n} function/method nodes: ${gini.toFixed(4)}`,\n `(0 = perfect equality, 1 = total inequality)\\n`,\n `Top 5 by ${metric}:`,\n ...top5.map((r: any) => ` ${String(r.val).padStart(6)} ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`),\n `\\nBottom 5 by ${metric}:`,\n ...bottom5.map((r: any) => ` ${String(r.val).padStart(6)} ${mapKind(r.kind)} \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`),\n ];\n return lines.join('\\n');\n }\n\n case 'kirograph_dependency_depth': {\n const rawDb = cg.getDatabase().getRawDb();\n const limitN = clampLimit(args.limit as number | undefined, 20);\n\n // Get all distinct file paths\n const fileRows = rawDb.all(`SELECT DISTINCT file_path FROM nodes ORDER BY file_path`, []);\n const files: string[] = fileRows.map((r: any) => r.file_path);\n if (files.length === 0) return 'No files found in index.';\n\n // Get file-level import edges (source file imports target file)\n const edgeRows = rawDb.all(\n `SELECT DISTINCT n1.file_path as src, n2.file_path as tgt\n FROM edges e\n JOIN nodes n1 ON n1.id = e.source\n JOIN nodes n2 ON n2.id = e.target\n WHERE e.kind = 'imports' AND n1.file_path != n2.file_path`,\n []\n );\n\n // Build adjacency + in-degree for Kahn's algorithm\n const outEdges = new Map<string, Set<string>>();\n const inDegree = new Map<string, number>();\n for (const f of files) { outEdges.set(f, new Set()); inDegree.set(f, 0); }\n for (const e of edgeRows) {\n outEdges.get(e.src)?.add(e.tgt);\n inDegree.set(e.tgt, (inDegree.get(e.tgt) ?? 0) + 1);\n }\n\n // Kahn's \u2014 assign levels (longest path from a root)\n const level = new Map<string, number>();\n const queue: string[] = [];\n for (const f of files) {\n if ((inDegree.get(f) ?? 0) === 0) { queue.push(f); level.set(f, 0); }\n }\n while (queue.length > 0) {\n const cur = queue.shift()!;\n const curLevel = level.get(cur) ?? 0;\n for (const nb of (outEdges.get(cur) ?? [])) {\n const newLevel = curLevel + 1;\n if ((level.get(nb) ?? -1) < newLevel) level.set(nb, newLevel);\n const deg = (inDegree.get(nb) ?? 1) - 1;\n inDegree.set(nb, deg);\n if (deg === 0) queue.push(nb);\n }\n }\n\n const sorted = files\n .map(f => ({ file: f, depth: level.get(f) ?? 0 }))\n .sort((a, b) => b.depth - a.depth)\n .slice(0, limitN);\n\n const lines = [`File dependency depths (deepest first, limit ${limitN}):\\n`];\n for (const { file, depth } of sorted) {\n const sample = rawDb.all(\n `SELECT name, kind FROM nodes WHERE file_path = ? AND kind IN ('function','class','interface','method') LIMIT 3`,\n [file]\n );\n const symbols = sample.map((r: any) => `\\`${r.name}\\``).join(', ');\n lines.push(` depth ${String(depth).padStart(3)} ${file}${symbols ? ` (${symbols})` : ''}`);\n }\n return lines.join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["depth"]
7
+ }