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,611 @@
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 core_exports = {};
20
+ __export(core_exports, {
21
+ handleCore: () => handleCore
22
+ });
23
+ module.exports = __toCommonJS(core_exports);
24
+ var import_utils = require("./utils");
25
+ async function handleCore(toolName, args, cg) {
26
+ switch (toolName) {
27
+ case "kirograph_search": {
28
+ const limit = (0, import_utils.clampLimit)(args.limit, 10);
29
+ const mode = args.mode ?? "name";
30
+ let nodes;
31
+ if (mode === "similar") {
32
+ nodes = cg.getDatabase().searchNodesByName(
33
+ args.query,
34
+ { kinds: args.kind ? [args.kind] : void 0, limit }
35
+ );
36
+ } else {
37
+ nodes = cg.searchNodes(args.query, args.kind, limit).map((r) => r.node);
38
+ }
39
+ if (nodes.length === 0) return `No symbols found matching "${args.query}".`;
40
+ return nodes.map(
41
+ (n) => `${(0, import_utils.mapKind)(n.kind)} ${n.name}
42
+ File: ${n.filePath}:${n.startLine}
43
+ Qualified: ${n.qualifiedName}`
44
+ ).join("\n\n");
45
+ }
46
+ case "kirograph_context": {
47
+ const detail = args.detail ?? (args.includeCode === false ? "summary" : "full");
48
+ const ctx = await cg.buildContext(args.task, {
49
+ maxNodes: args.maxNodes ?? 20,
50
+ includeCode: detail === "full"
51
+ });
52
+ const lines = [ctx.summary, ""];
53
+ if (ctx.entryPoints.length === 0) {
54
+ lines.push("No matching symbols found. If this is a new feature, consider using kirograph_files to explore the codebase structure.");
55
+ } else {
56
+ lines.push("## Entry Points");
57
+ for (const n of ctx.entryPoints) {
58
+ lines.push(`- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`);
59
+ if (detail === "full" && ctx.codeSnippets.has(n.id)) {
60
+ lines.push("```", ctx.codeSnippets.get(n.id), "```");
61
+ } else if (detail === "signatures") {
62
+ if (n.signature) lines.push(` Signature: ${n.signature}`);
63
+ if (n.docstring) lines.push(` Docs: ${n.docstring}`);
64
+ }
65
+ }
66
+ if (ctx.relatedNodes.length > 0) {
67
+ lines.push("", "## Related Symbols");
68
+ for (const n of ctx.relatedNodes.slice(0, 10)) {
69
+ lines.push(`- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`);
70
+ }
71
+ }
72
+ }
73
+ try {
74
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
75
+ const projectRoot = cg.getProjectRoot();
76
+ const config = await loadConfig(projectRoot);
77
+ if (config.enableMemory) {
78
+ const { MemoryManager } = await Promise.resolve().then(() => require("../../memory/index.js"));
79
+ const db = cg.getDatabase();
80
+ db.applyMemorySchema();
81
+ const mem = new MemoryManager(config, db.getRawDb());
82
+ mem.initialize();
83
+ const qualifiedNames = [
84
+ ...ctx.entryPoints.map((n) => n.qualifiedName),
85
+ ...ctx.relatedNodes.slice(0, 5).map((n) => n.qualifiedName)
86
+ ].filter(Boolean);
87
+ const contextLimit = config.memoryContextLimit ?? 3;
88
+ const contextThreshold = config.memoryContextThreshold ?? 0.3;
89
+ let memResults = mem.getLinkedObservations(qualifiedNames, contextLimit, contextThreshold);
90
+ if (memResults.length === 0) {
91
+ memResults = (await mem.search(args.task, { limit: contextLimit })).filter((r) => r.score >= contextThreshold);
92
+ }
93
+ if (memResults.length > 0) {
94
+ lines.push("", "## Related Memory");
95
+ for (const r of memResults.slice(0, contextLimit)) {
96
+ lines.push(`- [${r.observation.kind}] ${r.observation.content}`);
97
+ }
98
+ }
99
+ }
100
+ } catch {
101
+ }
102
+ try {
103
+ const projectRoot2 = cg.getProjectRoot();
104
+ const config2 = await (await Promise.resolve().then(() => require("../../config.js"))).loadConfig(projectRoot2);
105
+ if (config2.enableDocs && config2.docsContextLimit > 0) {
106
+ const db2 = cg.getDatabase();
107
+ db2.applyDocsSchema();
108
+ const { DocsQueries } = await Promise.resolve().then(() => require("../../docs/queries.js"));
109
+ const docsQueries = new DocsQueries(db2.getRawDb(), projectRoot2);
110
+ const qNames = ctx.entryPoints.map((n) => n.qualifiedName).filter(Boolean);
111
+ if (qNames.length > 0) {
112
+ const docRefs = docsQueries.getRefs({ qualifiedName: qNames[0] });
113
+ const additionalRefs = qNames.slice(1, 5).flatMap((qn) => docsQueries.getRefs({ qualifiedName: qn }));
114
+ const allDocRefs = [...docRefs, ...additionalRefs];
115
+ const seenSections = /* @__PURE__ */ new Set();
116
+ const uniqueRefs = allDocRefs.filter((r) => {
117
+ if (seenSections.has(r.sectionId)) return false;
118
+ seenSections.add(r.sectionId);
119
+ return r.confidence >= config2.docsContextThreshold;
120
+ }).slice(0, config2.docsContextLimit);
121
+ if (uniqueRefs.length > 0) {
122
+ lines.push("", "## Related Documentation");
123
+ for (const ref of uniqueRefs) {
124
+ const section = docsQueries.getSection(ref.sectionId);
125
+ if (section) {
126
+ const summary = section.section.summary ?? section.section.title;
127
+ lines.push(`- [${ref.refType}] ${summary} \u2014 ${section.section.filePath} (ID: ${ref.sectionId})`);
128
+ }
129
+ }
130
+ }
131
+ }
132
+ }
133
+ } catch {
134
+ }
135
+ try {
136
+ const projectRoot3 = cg.getProjectRoot();
137
+ const config3 = await (await Promise.resolve().then(() => require("../../config.js"))).loadConfig(projectRoot3);
138
+ if (config3.enableData && config3.dataContextLimit > 0) {
139
+ const db3 = cg.getDatabase();
140
+ db3.applyDataSchema();
141
+ const entryFiles = ctx.entryPoints.map((n) => n.filePath).filter(Boolean);
142
+ if (entryFiles.length > 0) {
143
+ const placeholders = entryFiles.map(() => "?").join(", ");
144
+ const dataRefs = db3.getRawDb().all(
145
+ `SELECT DISTINCT d.id, d.file_path, d.row_count, d.column_count
146
+ FROM data_code_refs r JOIN data_datasets d ON r.dataset_id = d.id
147
+ WHERE r.qualified_name IN (${placeholders})`,
148
+ entryFiles
149
+ );
150
+ if (dataRefs.length > 0) {
151
+ const { DataQueries } = await Promise.resolve().then(() => require("../../data/queries.js"));
152
+ const dq = new DataQueries(db3.getRawDb());
153
+ const limit = config3.dataContextLimit;
154
+ lines.push("", "## Related Data");
155
+ for (const ref of dataRefs.slice(0, limit)) {
156
+ const info = dq.describeDataset(ref.id);
157
+ if (info) {
158
+ const colSummary = info.columns.map((c) => `${c.name}:${c.inferredType}`).join(", ");
159
+ lines.push(`- **${ref.id}** (${ref.file_path}) \u2014 ${ref.row_count} rows, ${ref.column_count} cols`);
160
+ lines.push(` Schema: ${colSummary}`);
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ } catch {
167
+ }
168
+ try {
169
+ const projectRootSec = cg.getProjectRoot();
170
+ const configSec = await (await Promise.resolve().then(() => require("../../config.js"))).loadConfig(projectRootSec);
171
+ if (configSec.enableSecurity) {
172
+ const dbSec = cg.getDatabase();
173
+ dbSec.applySecuritySchema();
174
+ const rawDbSec = dbSec.getRawDb();
175
+ const contextNodeIds = [
176
+ ...ctx.entryPoints.map((n) => n.id),
177
+ ...ctx.relatedNodes.map((n) => n.id)
178
+ ].filter(Boolean);
179
+ if (contextNodeIds.length > 0) {
180
+ const { getSecurityWarningsForNodes, formatSecurityWarnings } = await Promise.resolve().then(() => require("../../security/context-warnings.js"));
181
+ const warnings = getSecurityWarningsForNodes(rawDbSec, contextNodeIds);
182
+ if (warnings.length > 0) {
183
+ const nodeNames = /* @__PURE__ */ new Map();
184
+ for (const n of ctx.entryPoints) {
185
+ nodeNames.set(n.id, n.name);
186
+ }
187
+ for (const n of ctx.relatedNodes) {
188
+ nodeNames.set(n.id, n.name);
189
+ }
190
+ const secSection = formatSecurityWarnings(warnings, nodeNames);
191
+ if (secSection) {
192
+ lines.push(secSection);
193
+ }
194
+ }
195
+ }
196
+ }
197
+ } catch {
198
+ }
199
+ try {
200
+ const projectRootPat = cg.getProjectRoot();
201
+ const configPat = await (await Promise.resolve().then(() => require("../../config.js"))).loadConfig(projectRootPat);
202
+ if (configPat.enablePatterns) {
203
+ const dbPat = cg.getDatabase();
204
+ dbPat.applyPatternsSchema();
205
+ const rawDbPat = dbPat.getRawDb();
206
+ const tableExists = rawDbPat.get("SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'");
207
+ if (tableExists) {
208
+ const contextFiles = [
209
+ ...ctx.entryPoints.map((n) => n.filePath),
210
+ ...ctx.relatedNodes.map((n) => n.filePath)
211
+ ].filter(Boolean);
212
+ const uniqueContextFiles = [...new Set(contextFiles)];
213
+ if (uniqueContextFiles.length > 0) {
214
+ const placeholders = uniqueContextFiles.map(() => "?").join(",");
215
+ const patternRows = rawDbPat.all(
216
+ `SELECT file_path, pattern_id, severity, owasp_category, line FROM pattern_matches WHERE file_path IN (${placeholders}) ORDER BY severity DESC LIMIT 5`,
217
+ uniqueContextFiles
218
+ );
219
+ if (patternRows.length > 0) {
220
+ const patternWarnings = patternRows.map(
221
+ (p) => `- **${p.pattern_id}** [${p.severity.toUpperCase()}/${p.owasp_category}]: ${p.file_path}:${p.line}`
222
+ ).join("\n");
223
+ lines.push("", "## \u26A0 Pattern Findings", "", patternWarnings);
224
+ if (patternRows.length === 5) lines.push("", "More findings \u2014 run `kirograph pattern --list` to see all rules.");
225
+ }
226
+ }
227
+ }
228
+ }
229
+ } catch {
230
+ }
231
+ const graphTokens = lines.join("\n").length / 4;
232
+ const uniqueFiles = /* @__PURE__ */ new Set([
233
+ ...ctx.entryPoints.map((n) => n.filePath),
234
+ ...ctx.relatedNodes.map((n) => n.filePath)
235
+ ]);
236
+ if (uniqueFiles.size > 0) {
237
+ const naiveTokens = (0, import_utils.estimateFileTokens)(cg.getProjectRoot(), [...uniqueFiles]);
238
+ if (naiveTokens > 0) {
239
+ const savingsPct = Math.round((1 - graphTokens / naiveTokens) * 100);
240
+ if (savingsPct > 0) {
241
+ lines.push("", `---`, `Context savings: ~${Math.round(graphTokens)} tokens (graph) vs ~${naiveTokens} tokens (full files) \u2014 ${savingsPct}% reduction`);
242
+ }
243
+ }
244
+ }
245
+ return lines.join("\n");
246
+ }
247
+ case "kirograph_callers": {
248
+ const limit = (0, import_utils.clampLimit)(args.limit, 20);
249
+ const results = cg.searchNodes(args.symbol, void 0, 5);
250
+ if (results.length === 0) return `Symbol "${args.symbol}" not found in index.`;
251
+ const node = results[0].node;
252
+ const callers = await cg.getCallers(node.id, limit);
253
+ if (callers.length === 0) return `No callers found for \`${node.name}\`.`;
254
+ return `Callers of \`${node.name}\`:
255
+ ` + callers.map(
256
+ (n) => `- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`
257
+ ).join("\n");
258
+ }
259
+ case "kirograph_callees": {
260
+ const limit = (0, import_utils.clampLimit)(args.limit, 20);
261
+ const results = cg.searchNodes(args.symbol, void 0, 5);
262
+ if (results.length === 0) return `Symbol "${args.symbol}" not found in index.`;
263
+ const node = results[0].node;
264
+ const callees = await cg.getCallees(node.id, limit);
265
+ if (callees.length === 0) return `\`${node.name}\` doesn't call any indexed symbols.`;
266
+ return `\`${node.name}\` calls:
267
+ ` + callees.map(
268
+ (n) => `- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`
269
+ ).join("\n");
270
+ }
271
+ case "kirograph_impact": {
272
+ const results = cg.searchNodes(args.symbol, void 0, 5);
273
+ if (results.length === 0) return `Symbol "${args.symbol}" not found in index.`;
274
+ const node = results[0].node;
275
+ const affected = await cg.getImpactRadius(node.id, args.depth ?? 2);
276
+ if (affected.length === 0) return `No dependents found for \`${node.name}\`.`;
277
+ let output = `Changing \`${node.name}\` may affect ${affected.length} symbol(s):
278
+ ` + affected.map((n) => `- ${(0, import_utils.mapKind)(n.kind)} \`${n.name}\` \u2014 ${n.filePath}:${n.startLine}`).join("\n");
279
+ try {
280
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
281
+ const projectRoot = cg.getProjectRoot();
282
+ const config = await loadConfig(projectRoot);
283
+ if (config.enableMemory) {
284
+ const { MemoryManager } = await Promise.resolve().then(() => require("../../memory/index.js"));
285
+ const db = cg.getDatabase();
286
+ db.applyMemorySchema();
287
+ const mem = new MemoryManager(config, db.getRawDb());
288
+ mem.initialize();
289
+ const contextLimit = config.memoryContextLimit ?? 3;
290
+ const contextThreshold = config.memoryContextThreshold ?? 0.3;
291
+ const memResults = mem.getLinkedObservations(
292
+ [node.qualifiedName],
293
+ contextLimit,
294
+ contextThreshold
295
+ );
296
+ if (memResults.length > 0) {
297
+ output += "\n\nRelated Memory:";
298
+ for (const r of memResults) {
299
+ const age = (0, import_utils.formatAge)(r.observation.createdAt);
300
+ output += `
301
+ - [${r.observation.kind}] ${r.observation.content} (${age})`;
302
+ }
303
+ }
304
+ }
305
+ } catch {
306
+ }
307
+ try {
308
+ const rawDbImp = cg.getDatabase().getRawDb();
309
+ const tableExistsImp = rawDbImp.get("SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'");
310
+ if (tableExistsImp) {
311
+ const symNode = rawDbImp.get("SELECT id FROM nodes WHERE name = ? LIMIT 1", [args.symbol]);
312
+ if (symNode) {
313
+ const patternMatches = rawDbImp.all(
314
+ "SELECT pattern_id, severity, line FROM pattern_matches WHERE symbol_node_id = ?",
315
+ [symNode.id]
316
+ );
317
+ if (patternMatches.length > 0) {
318
+ output += "\n\n\u26A0 This symbol has pattern matches:";
319
+ for (const pm of patternMatches) {
320
+ output += `
321
+ [${pm.severity.toUpperCase()}] ${pm.pattern_id} at line ${pm.line}`;
322
+ }
323
+ }
324
+ }
325
+ }
326
+ } catch {
327
+ }
328
+ return output;
329
+ }
330
+ case "kirograph_node": {
331
+ let node = null;
332
+ if (args.qualified) {
333
+ const row = cg.getDatabase().getRawDb().get(
334
+ `SELECT * FROM nodes WHERE qualified_name = ? LIMIT 1`,
335
+ [args.symbol]
336
+ );
337
+ if (row) {
338
+ node = {
339
+ id: row.id,
340
+ kind: row.kind,
341
+ name: row.name,
342
+ qualifiedName: row.qualified_name,
343
+ filePath: row.file_path,
344
+ language: row.language,
345
+ startLine: row.start_line,
346
+ endLine: row.end_line,
347
+ startColumn: row.start_column,
348
+ endColumn: row.end_column,
349
+ docstring: row.docstring ?? void 0,
350
+ signature: row.signature ?? void 0,
351
+ visibility: row.visibility ?? void 0,
352
+ isExported: row.is_exported === 1,
353
+ isAsync: row.is_async === 1,
354
+ isStatic: row.is_static === 1,
355
+ isAbstract: row.is_abstract === 1
356
+ };
357
+ }
358
+ } else {
359
+ const results = cg.searchNodes(args.symbol, void 0, 5);
360
+ if (results.length > 0) node = results[0].node;
361
+ }
362
+ if (!node) return `Symbol "${args.symbol}" not found in index.`;
363
+ const nodeDetail = args.detail ?? (args.includeCode ? "full" : "summary");
364
+ const lines = [
365
+ `${(0, import_utils.mapKind)(node.kind)} \`${node.name}\``,
366
+ `File: ${node.filePath}:${node.startLine}-${node.endLine}`,
367
+ `Qualified: ${node.qualifiedName}`
368
+ ];
369
+ if (nodeDetail === "signatures" || nodeDetail === "full") {
370
+ if (node.signature) lines.push(`Signature: ${node.signature}`);
371
+ if (node.docstring) lines.push(`Docs: ${node.docstring}`);
372
+ }
373
+ if (nodeDetail === "full") {
374
+ const src = cg.getNodeSource(node);
375
+ if (src) lines.push("", "```", src, "```");
376
+ }
377
+ return lines.join("\n");
378
+ }
379
+ case "kirograph_status": {
380
+ const stats = await cg.getStats();
381
+ const langLine = Object.entries(stats.filesByLanguage).sort((a, b) => b[1] - a[1]).map(([k, v]) => `${k}=${v}`).join(", ");
382
+ const dbMb = (stats.dbSizeBytes / 1024 / 1024).toFixed(2);
383
+ const semanticLines = stats.embeddingsEnabled ? [
384
+ ` Semantic search: enabled`,
385
+ ` Semantic model: ${stats.embeddingModel}`,
386
+ ` Semantic engine: ${stats.semanticEngine === "turboquant" ? `turboquant (${stats.vecIndexCount} entries \xB7 ANN)` : stats.semanticEngine === "turbovec" ? `turbovec (${stats.vecIndexCount} entries \xB7 ${stats.turbovecBits ?? 4} bits \xB7 Rust/SIMD)` : stats.semanticEngine === "sqlite-vec" ? `sqlite-vec (${stats.vecIndexCount} entries in ANN index)` : stats.semanticEngine === "orama" ? `orama hybrid (${stats.vecIndexCount} docs in index)` : stats.semanticEngine === "pglite" ? `pglite+pgvector (${stats.vecIndexCount} rows in DB)` : stats.semanticEngine === "lancedb" ? `lancedb (${stats.vecIndexCount} entries in ANN index)` : stats.semanticEngine === "qdrant" ? `qdrant (${stats.vecIndexCount} points in collection)` : stats.semanticEngine === "typesense" ? `typesense (${stats.vecIndexCount} documents in collection)` : "in-process cosine"}`,
387
+ ` Embeddings: ${stats.embeddingCount} / ${stats.embeddableNodeCount || stats.nodes} embeddable symbols`,
388
+ ...stats.engineFallback ? [` \u26A0 Engine fallback: ${stats.engineFallback}`] : []
389
+ ] : [` Semantic search: disabled`];
390
+ const frameworkLine = stats.frameworks.length > 0 ? ` Frameworks: ${stats.frameworks.join(", ")}` : ` Frameworks: none detected`;
391
+ const archLine = stats.architectureEnabled ? stats.architectureStats ? ` Architecture: enabled \u2014 ${stats.architectureStats.packages} packages, ${stats.architectureStats.layers} layers, ${stats.architectureStats.packageDeps} deps` : ` Architecture: enabled (not yet analyzed \u2014 run kirograph index)` : ` Architecture: disabled`;
392
+ let docsLine = " Documentation: disabled";
393
+ try {
394
+ const { loadConfig: loadCfg } = await Promise.resolve().then(() => require("../../config.js"));
395
+ const cfg = await loadCfg(cg.getProjectRoot());
396
+ if (cfg.enableDocs) {
397
+ const db = cg.getDatabase();
398
+ db.applyDocsSchema();
399
+ const rawDb = db.getRawDb();
400
+ const docFiles = rawDb.get("SELECT COUNT(DISTINCT file_path) as cnt FROM doc_sections")?.cnt ?? 0;
401
+ const docSections = rawDb.get("SELECT COUNT(*) as cnt FROM doc_sections")?.cnt ?? 0;
402
+ const docRefs = rawDb.get("SELECT COUNT(*) as cnt FROM doc_code_refs")?.cnt ?? 0;
403
+ docsLine = ` Documentation: enabled \u2014 ${docFiles} files, ${docSections} sections, ${docRefs} code refs`;
404
+ }
405
+ } catch {
406
+ }
407
+ let dataLine = " Data: disabled";
408
+ try {
409
+ const { loadConfig: loadCfg2 } = await Promise.resolve().then(() => require("../../config.js"));
410
+ const cfg2 = await loadCfg2(cg.getProjectRoot());
411
+ if (cfg2.enableData) {
412
+ const rawDb2 = cg.getDatabase().getRawDb();
413
+ cg.getDatabase().applyDataSchema();
414
+ const datasetCount = rawDb2.get("SELECT COUNT(*) as cnt FROM data_datasets")?.cnt ?? 0;
415
+ if (datasetCount > 0) {
416
+ const totalRows = rawDb2.get("SELECT SUM(row_count) as total FROM data_datasets")?.total ?? 0;
417
+ const totalCols = rawDb2.get("SELECT SUM(column_count) as total FROM data_datasets")?.total ?? 0;
418
+ const totalSize = rawDb2.get("SELECT SUM(file_size) as total FROM data_datasets")?.total ?? 0;
419
+ const sizeMb = (totalSize / 1024 / 1024).toFixed(2);
420
+ dataLine = ` Data: enabled \u2014 ${datasetCount} datasets, ${totalRows.toLocaleString()} rows, ${totalCols} columns (${sizeMb} MB source)`;
421
+ } else {
422
+ dataLine = ` Data: enabled (no datasets indexed yet \u2014 run kirograph index)`;
423
+ }
424
+ }
425
+ } catch {
426
+ }
427
+ let securityLine = " Security: disabled";
428
+ try {
429
+ const { loadConfig: loadCfgSec } = await Promise.resolve().then(() => require("../../config.js"));
430
+ const cfgSec = await loadCfgSec(cg.getProjectRoot());
431
+ if (cfgSec.enableSecurity) {
432
+ const db = cg.getDatabase();
433
+ db.applySecuritySchema();
434
+ const rawDb = db.getRawDb();
435
+ const depCount = rawDb.get("SELECT COUNT(*) as cnt FROM sec_dependencies")?.cnt ?? 0;
436
+ const vulnCount = rawDb.get("SELECT COUNT(*) as cnt FROM sec_vulnerabilities")?.cnt ?? 0;
437
+ const affectedCount = rawDb.get("SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'affected'")?.cnt ?? 0;
438
+ const staleCount = rawDb.get("SELECT COUNT(*) as cnt FROM sec_dependencies WHERE vuln_data_stale = 1")?.cnt ?? 0;
439
+ const staleNote = staleCount > 0 ? ` \u26A0 ${staleCount} stale` : "";
440
+ securityLine = ` Security: enabled \u2014 ${depCount} deps, ${vulnCount} vulns (${affectedCount} affected)${staleNote}`;
441
+ }
442
+ } catch {
443
+ }
444
+ let patternsLine = " Patterns: disabled";
445
+ try {
446
+ const { loadConfig: loadCfgPat } = await Promise.resolve().then(() => require("../../config.js"));
447
+ const cfgP = await loadCfgPat(cg.getProjectRoot());
448
+ if (cfgP.enablePatterns) {
449
+ const rawDbP = cg.getDatabase().getRawDb();
450
+ const tableExistsP = rawDbP.get("SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'");
451
+ if (tableExistsP) {
452
+ const matchCount = rawDbP.get("SELECT COUNT(*) as cnt FROM pattern_matches")?.cnt ?? 0;
453
+ const fileCount = rawDbP.get("SELECT COUNT(DISTINCT file_path) as cnt FROM pattern_matches")?.cnt ?? 0;
454
+ const ruleCount = rawDbP.get("SELECT COUNT(DISTINCT pattern_id) as cnt FROM pattern_matches")?.cnt ?? 0;
455
+ patternsLine = ` Patterns: enabled \u2014 ${matchCount} matches, ${ruleCount} rules triggered, ${fileCount} files`;
456
+ } else {
457
+ patternsLine = ` Patterns: enabled (no data yet \u2014 run kirograph index)`;
458
+ }
459
+ }
460
+ } catch {
461
+ }
462
+ const threshold = stats.syncWarningThreshold ?? 10;
463
+ const pendingFiles = stats.pendingFiles ?? 0;
464
+ const syncRunning = stats.syncRunning ?? false;
465
+ const syncLines = [];
466
+ if (syncRunning) {
467
+ syncLines.push(` \u26A0 Sync is currently running in the background.`);
468
+ }
469
+ if (threshold > 0 && pendingFiles >= threshold) {
470
+ syncLines.push(
471
+ ` \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?`
472
+ );
473
+ }
474
+ const { TokenTracker } = await Promise.resolve().then(() => require("../../compression/tracker.js"));
475
+ const tracker = new TokenTracker(cg.getProjectRoot());
476
+ const gainStats = tracker.getStats("session");
477
+ const gainLines = [];
478
+ if (gainStats.totalCommands > 0) {
479
+ gainLines.push(` Compression: ${gainStats.totalCommands} commands, ${gainStats.savingsPercent}% avg savings (${gainStats.totalSaved.toLocaleString()} tokens saved this session)`);
480
+ }
481
+ return [
482
+ `KiroGraph Status`,
483
+ ` Project: ${cg.getProjectRoot()}`,
484
+ ` Files indexed: ${stats.files}`,
485
+ ` Symbols: ${stats.nodes}`,
486
+ ` Relationships: ${stats.edges}`,
487
+ ` By kind: ${Object.entries(stats.nodesByKind).map(([k, v]) => `${k}=${v}`).join(", ")}`,
488
+ langLine ? ` By language: ${langLine}` : "",
489
+ frameworkLine,
490
+ archLine,
491
+ docsLine,
492
+ dataLine,
493
+ securityLine,
494
+ patternsLine,
495
+ ` DB size: ${dbMb} MB`,
496
+ ...semanticLines,
497
+ ...syncLines,
498
+ ...gainLines
499
+ ].filter(Boolean).join("\n");
500
+ }
501
+ case "kirograph_files": {
502
+ let renderTree2 = function(nodes, prefix) {
503
+ for (let i = 0; i < nodes.length; i++) {
504
+ const node = nodes[i];
505
+ const isLast = i === nodes.length - 1;
506
+ const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
507
+ const childPrefix = prefix + (isLast ? " " : "\u2502 ");
508
+ const meta = includeMetadata && node.type === "file" && node.language ? ` [${node.language}${node.symbolCount ? ` \xB7 ${node.symbolCount} symbols` : ""}]` : "";
509
+ lines.push(`${prefix}${connector}${node.name}${meta}`);
510
+ if (node.children?.length) renderTree2(node.children, childPrefix);
511
+ }
512
+ };
513
+ var renderTree = renderTree2;
514
+ const format = args.format ?? "tree";
515
+ const includeMetadata = args.includeMetadata !== false;
516
+ const tree = cg.getFiles({
517
+ filterPath: args.filterPath,
518
+ pattern: args.pattern,
519
+ maxDepth: args.maxDepth
520
+ });
521
+ if (format === "flat") {
522
+ let flattenTree2 = function(nodes) {
523
+ for (const node of nodes) {
524
+ if (node.type === "file") {
525
+ const meta = includeMetadata && node.language ? ` [${node.language}${node.symbolCount ? ` \xB7 ${node.symbolCount}` : ""}]` : "";
526
+ flat.push(`${node.path}${meta}`);
527
+ }
528
+ if (node.children?.length) flattenTree2(node.children);
529
+ }
530
+ };
531
+ var flattenTree = flattenTree2;
532
+ const flat = [];
533
+ flattenTree2(tree);
534
+ return flat.length > 0 ? flat.join("\n") : "No indexed files found.";
535
+ }
536
+ if (format === "grouped") {
537
+ let groupTree2 = function(nodes) {
538
+ for (const node of nodes) {
539
+ if (node.type === "file") {
540
+ const dir = node.path.includes("/") ? node.path.slice(0, node.path.lastIndexOf("/")) : ".";
541
+ if (!groups.has(dir)) groups.set(dir, []);
542
+ groups.get(dir).push(node);
543
+ }
544
+ if (node.children?.length) groupTree2(node.children);
545
+ }
546
+ };
547
+ var groupTree = groupTree2;
548
+ const groups = /* @__PURE__ */ new Map();
549
+ groupTree2(tree);
550
+ const lines2 = [];
551
+ for (const [dir, files] of [...groups.entries()].sort()) {
552
+ lines2.push(`${dir}/`);
553
+ for (const f of files) {
554
+ const meta = includeMetadata && f.language ? ` [${f.language}${f.symbolCount ? ` \xB7 ${f.symbolCount}` : ""}]` : "";
555
+ lines2.push(` ${f.name}${meta}`);
556
+ }
557
+ }
558
+ return lines2.length > 0 ? lines2.join("\n") : "No indexed files found.";
559
+ }
560
+ if (format === "compact") {
561
+ let compactTree2 = function(nodes) {
562
+ for (const node of nodes) {
563
+ if (node.type === "file") {
564
+ const dir = node.path.includes("/") ? node.path.slice(0, node.path.lastIndexOf("/")) : ".";
565
+ const stat = dirStats.get(dir) || { files: 0, symbols: 0, langs: /* @__PURE__ */ new Map() };
566
+ stat.files++;
567
+ stat.symbols += node.symbolCount || 0;
568
+ if (node.language) stat.langs.set(node.language, (stat.langs.get(node.language) || 0) + 1);
569
+ dirStats.set(dir, stat);
570
+ }
571
+ if (node.children?.length) compactTree2(node.children);
572
+ }
573
+ };
574
+ var compactTree = compactTree2;
575
+ const dirStats = /* @__PURE__ */ new Map();
576
+ compactTree2(tree);
577
+ const totalFiles = [...dirStats.values()].reduce((s, d) => s + d.files, 0);
578
+ const totalSymbols = [...dirStats.values()].reduce((s, d) => s + d.symbols, 0);
579
+ const lines2 = [`${totalFiles} files, ${totalSymbols} symbols in ${dirStats.size} directories:
580
+ `];
581
+ for (const [dir, stat] of [...dirStats.entries()].sort()) {
582
+ const langSummary = [...stat.langs.entries()].map(([l, c]) => `${l}:${c}`).join(" ");
583
+ lines2.push(`${dir}/ (${stat.files} files, ${stat.symbols} symbols) ${langSummary}`);
584
+ }
585
+ return lines2.join("\n");
586
+ }
587
+ const lines = [];
588
+ renderTree2(tree, "");
589
+ return lines.length > 0 ? lines.join("\n") : "No indexed files found.";
590
+ }
591
+ case "kirograph_affected": {
592
+ const files = args.files ?? [];
593
+ if (files.length === 0) return 'No files provided. Pass file paths in the "files" array.';
594
+ const affected = cg.getAffectedTests(files, {
595
+ depth: args.depth ?? 5,
596
+ testPattern: args.testPattern
597
+ });
598
+ if (affected.length === 0) return `No affected test files found for the provided ${files.length} changed file(s).`;
599
+ return `Affected test files (${affected.length}) for ${files.length} changed file(s):
600
+
601
+ ` + affected.map((f) => `- ${f}`).join("\n");
602
+ }
603
+ default:
604
+ return `Unknown tool: ${toolName}`;
605
+ }
606
+ }
607
+ // Annotate the CommonJS export names for ESM import in node:
608
+ 0 && (module.exports = {
609
+ handleCore
610
+ });
611
+ //# sourceMappingURL=core.js.map