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,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/mcp/handler.ts"],
4
+ "sourcesContent": ["import fs from 'fs';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport KiroGraph from '../index';\nimport { logError } from '../errors';\nimport { compress } from '../compression/index';\nimport { TokenTracker } from '../compression/tracker';\nimport { truncate, writeSessionMarker } from './handlers/utils';\nimport { handleCore } from './handlers/core';\nimport { handleCodeHealth } from './handlers/code-health';\nimport { handleArchitecture } from './handlers/architecture';\nimport { handleEditPrimitives } from './handlers/edit-primitives';\nimport { handleGitContext } from './handlers/git-context';\nimport { handleComplexity } from './handlers/complexity';\nimport { handleMemory } from './handlers/memory';\nimport { handleDocs } from './handlers/docs';\nimport { handleData } from './handlers/data';\nimport { handleWatchmen } from './handlers/watchmen';\nimport { handleSecurity } from './handlers/security';\nimport { handlePatterns } from './handlers/patterns';\nimport { handleWiki } from './handlers/wiki';\nimport { handleBranch } from './handlers/branch';\n\nconst CORE_TOOLS = new Set([\n 'kirograph_search', 'kirograph_context', 'kirograph_callers', 'kirograph_callees',\n 'kirograph_impact', 'kirograph_node', 'kirograph_status', 'kirograph_files', 'kirograph_affected',\n]);\n\nconst CODE_HEALTH_TOOLS = new Set([\n 'kirograph_dead_code', 'kirograph_circular_deps', 'kirograph_path', 'kirograph_type_hierarchy',\n 'kirograph_hotspots', 'kirograph_surprising', 'kirograph_diff', 'kirograph_snapshot_save',\n 'kirograph_snapshot_list', 'kirograph_module_api', 'kirograph_rename_preview',\n 'kirograph_doc_coverage', 'kirograph_god_class', 'kirograph_inheritance_depth',\n 'kirograph_recursion', 'kirograph_largest', 'kirograph_rank', 'kirograph_distribution',\n 'kirograph_annotations', 'kirograph_session_start', 'kirograph_session_end',\n 'kirograph_unused_imports', 'kirograph_gini', 'kirograph_dependency_depth',\n]);\n\nconst ARCHITECTURE_TOOLS = new Set([\n 'kirograph_architecture', 'kirograph_coupling', 'kirograph_package', 'kirograph_communities',\n 'kirograph_manifest',\n]);\n\nconst GIT_CONTEXT_TOOLS = new Set([\n 'kirograph_flows', 'kirograph_diff_context', 'kirograph_commit_context',\n 'kirograph_pr_context', 'kirograph_changelog', 'kirograph_test_map',\n 'kirograph_test_coverage',\n]);\n\nconst COMPLEXITY_TOOLS = new Set([\n 'kirograph_complexity', 'kirograph_simplify_scan',\n 'kirograph_health', 'kirograph_dsm', 'kirograph_test_risk',\n]);\n\nconst BRANCH_TOOLS = new Set(['kirograph_branch_list', 'kirograph_branch_diff', 'kirograph_branch_search']);\n\nconst EDIT_PRIMITIVES_TOOLS = new Set([\n 'kirograph_refactor', 'kirograph_str_replace', 'kirograph_multi_str_replace',\n 'kirograph_insert_at', 'kirograph_ast_grep_rewrite',\n]);\n\nconst SECURITY_TOOLS = new Set([\n 'kirograph_security', 'kirograph_vulns', 'kirograph_vuln_add', 'kirograph_vuln_suppress',\n 'kirograph_sbom', 'kirograph_vex', 'kirograph_reachability', 'kirograph_staleness',\n 'kirograph_licenses', 'kirograph_attack_surface', 'kirograph_secrets', 'kirograph_security_flows',\n 'kirograph_supply_chain', 'kirograph_dep_confusion', 'kirograph_remediation',\n]);\n\nconst PATTERNS_TOOLS = new Set([\n 'kirograph_live_search', 'kirograph_pattern_coverage', 'kirograph_pattern_save_baseline',\n 'kirograph_pattern_diff',\n]);\n\nconst WATCHMEN_TOOLS = new Set([\n 'kirograph_watchmen_status', 'kirograph_watchmen_synthesize', 'kirograph_watchmen_reset',\n]);\n\nexport class ToolHandler {\n private defaultCg: KiroGraph | null;\n private connections = new Map<string, KiroGraph>();\n\n constructor(cg: KiroGraph | null) {\n this.defaultCg = cg;\n }\n\n setDefaultKiroGraph(cg: KiroGraph): void {\n this.defaultCg = cg;\n }\n\n /** Close all cached cross-project connections. */\n closeAll(): void {\n for (const cg of this.connections.values()) {\n try { cg.close(); } catch { /* ignore */ }\n }\n this.connections.clear();\n }\n\n private async getConnection(projectPath?: string): Promise<KiroGraph | null> {\n if (!projectPath) return this.defaultCg;\n // Normalize and validate: must be an absolute path after resolution\n const resolved = path.resolve(projectPath);\n if (!path.isAbsolute(resolved)) return null;\n if (this.connections.has(resolved)) return this.connections.get(resolved)!;\n try {\n const cg = await KiroGraph.open(resolved);\n this.connections.set(resolved, cg);\n return cg;\n } catch {\n return null;\n }\n }\n\n async handle(toolName: string, args: Record<string, unknown>): Promise<{ content: Array<{ type: 'text'; text: string }>; isError?: boolean }> {\n try {\n const text = await this.dispatch(toolName, args);\n const truncated = truncate(text);\n\n // Track graph/memory tool savings and append per-call metrics trailer.\n let metricsTrailer = '';\n if (toolName !== 'kirograph_exec' && toolName !== 'kirograph_gain') {\n try {\n const projectRoot = (args.projectPath as string) || this.defaultCg?.getProjectRoot() || process.cwd();\n const { estimateNaiveCost } = await Promise.resolve().then(() => require('../compression/naive-cost.js'));\n const { estimateTokens } = await Promise.resolve().then(() => require('../compression/index.js'));\n const outputTokens = estimateTokens(truncated);\n const naiveCost = estimateNaiveCost(toolName, outputTokens, args);\n if (naiveCost !== null && naiveCost > outputTokens) {\n const tracker = new TokenTracker(projectRoot);\n if (toolName.startsWith('kirograph_mem_')) {\n tracker.recordMemorySaving(toolName, outputTokens, naiveCost);\n } else if (toolName.startsWith('kirograph_docs_')) {\n tracker.recordDocsSaving(toolName, outputTokens, naiveCost);\n } else if (toolName.startsWith('kirograph_data_')) {\n tracker.recordDataSaving(toolName, outputTokens, naiveCost);\n } else {\n tracker.recordGraphSaving(toolName, outputTokens, naiveCost);\n }\n const saved = Math.round(((naiveCost - outputTokens) / naiveCost) * 100);\n metricsTrailer = `\\n\\n[kirograph_metrics: before=${naiveCost} after=${outputTokens} saved=${saved}%]`;\n } else {\n metricsTrailer = `\\n\\n[kirograph_metrics: tokens=${outputTokens}]`;\n }\n } catch { /* non-critical */ }\n }\n\n return { content: [{ type: 'text', text: truncated + metricsTrailer }] };\n } catch (err) {\n logError('MCP tool error', { tool: toolName, error: err });\n const message = err instanceof Error ? err.message : String(err);\n return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true };\n }\n }\n\n private async dispatch(toolName: string, args: Record<string, unknown>): Promise<string> {\n // Tools that don't require an initialized graph\n if (toolName === 'kirograph_exec') {\n const cmd = args.command as string;\n if (!cmd) return 'Error: command is required.';\n\n const projectRoot = (args.projectPath as string) || (args.cwd as string) || process.cwd();\n const execCwd = (args.cwd as string) || projectRoot;\n\n // Read default level from config if not explicitly provided\n let defaultLevel: 'normal' | 'aggressive' | 'ultra' = 'normal';\n try {\n const { loadConfig } = await Promise.resolve().then(() => require('../config.js'));\n const config = await loadConfig(projectRoot);\n if (config.shellCompressionLevel && config.shellCompressionLevel !== 'off') {\n defaultLevel = config.shellCompressionLevel as 'normal' | 'aggressive' | 'ultra';\n }\n } catch { /* no config \u2014 use default */ }\n\n const level = (args.level as 'normal' | 'aggressive' | 'ultra') ?? defaultLevel;\n const timeout = ((args.timeout as number) ?? 60) * 1000;\n\n let rawOutput: string;\n let exitCode = 0;\n try {\n rawOutput = execSync(cmd, {\n cwd: execCwd,\n timeout,\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'pipe'],\n maxBuffer: 10 * 1024 * 1024,\n });\n } catch (err: any) {\n // Command failed \u2014 capture output anyway\n rawOutput = (err.stdout || '') + (err.stderr || '');\n exitCode = err.status ?? 1;\n }\n\n const result = compress(cmd, rawOutput, { level, preserveErrors: exitCode !== 0 });\n\n // Track savings\n const tracker = new TokenTracker(projectRoot);\n tracker.record(cmd, result.originalTokens, result.compressedTokens, result.strategy);\n\n const header = exitCode !== 0 ? `[exit ${exitCode}] ` : '';\n const footer = result.savings > 5\n ? `\\n\\n[${result.savings}% tokens saved | ${result.originalTokens}\u2192${result.compressedTokens} | ${result.strategy}]`\n : '';\n\n return `${header}${result.output}${footer}`;\n }\n\n if (toolName === 'kirograph_gain') {\n const projectRoot = (args.projectPath as string) || process.cwd();\n const period = (args.period as string) ?? 'session';\n const tracker = new TokenTracker(projectRoot);\n const stats = tracker.getStats(period as 'session' | 'today' | 'week' | 'all');\n\n if (stats.totalCommands === 0) {\n return 'No savings recorded yet. Use kirograph tools and kirograph_exec \u2014 savings are tracked automatically.';\n }\n\n const lines = [\n `Token Savings (${period}):`,\n ` Total calls: ${stats.totalCommands}`,\n ` Tokens without KiroGraph: ~${stats.totalOriginal.toLocaleString()}`,\n ` Tokens with KiroGraph: ~${stats.totalCompressed.toLocaleString()}`,\n ` Saved: ${stats.totalSaved.toLocaleString()} tokens (${stats.savingsPercent}%)`,\n ];\n\n // Source breakdown\n if (stats.bySource.exec.count > 0 || stats.bySource.graph.count > 0 || stats.bySource.memory.count > 0 || stats.bySource.docs.count > 0) {\n lines.push('', 'By source:');\n if (stats.bySource.graph.count > 0) {\n lines.push(` Graph tools: ${stats.bySource.graph.count} calls, ~${stats.bySource.graph.saved.toLocaleString()} tokens saved (vs file reads/grep)`);\n }\n if (stats.bySource.docs.count > 0) {\n lines.push(` Docs tools: ${stats.bySource.docs.count} calls, ~${stats.bySource.docs.saved.toLocaleString()} tokens saved (vs reading full doc files)`);\n }\n if (stats.bySource.data.count > 0) {\n lines.push(` Data tools: ${stats.bySource.data.count} calls, ~${stats.bySource.data.saved.toLocaleString()} tokens saved (vs loading raw data files)`);\n }\n if (stats.bySource.exec.count > 0) {\n lines.push(` Compression: ${stats.bySource.exec.count} calls, ~${stats.bySource.exec.saved.toLocaleString()} tokens saved (vs raw output)`);\n }\n if (stats.bySource.memory.count > 0) {\n lines.push(` Memory: ${stats.bySource.memory.count} calls, ~${stats.bySource.memory.saved.toLocaleString()} tokens saved (vs re-discovering context)`);\n }\n }\n\n if (Object.keys(stats.byFamily).length > 0) {\n lines.push('', 'Top families:');\n for (const [family, data] of Object.entries(stats.byFamily).slice(0, 7)) {\n lines.push(` ${family}: ${data.count} calls, ${data.savings}% avg savings`);\n }\n }\n\n if (stats.recentCommands.length > 0) {\n lines.push('', 'Recent:');\n for (const cmd of stats.recentCommands.slice(0, 5)) {\n const tag = cmd.source === 'graph' ? '\uD83D\uDCCA' : '\u26A1';\n lines.push(` ${tag} ${cmd.command.slice(0, 40)} \u2192 ${cmd.savings}% saved`);\n }\n }\n\n return lines.join('\\n');\n }\n\n if (toolName === 'kirograph_read') {\n const filePath = args.path as string;\n if (!filePath) return 'Error: path is required.';\n\n const projectRoot = (args.projectPath as string) || process.cwd();\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(projectRoot, filePath);\n const mode = (args.mode as string) ?? 'full';\n const noCache = (args.noCache as boolean) ?? false;\n\n if (!fs.existsSync(resolvedPath)) {\n return `Error: File not found: ${resolvedPath}`;\n }\n\n const { getFileReadCache } = await Promise.resolve().then(() => require('./cache.js'));\n const { executeReadMode } = await Promise.resolve().then(() => require('./read-modes.js'));\n const cache = getFileReadCache();\n\n // For non-full modes, skip caching logic and use read-modes directly\n if (mode !== 'full') {\n // Get graph connection for map/signatures/imports/exports modes\n let cg: KiroGraph | null = null;\n try {\n cg = await this.getConnection(args.projectPath as string | undefined);\n } catch { /* no graph available */ }\n\n const result = executeReadMode({\n mode: mode as any,\n filePath: resolvedPath,\n start: args.start as number | undefined,\n end: args.end as number | undefined,\n cg,\n });\n\n // Update cache with current content for future diff mode\n cache.read(resolvedPath, true);\n\n return result.content;\n }\n\n // Full mode with caching\n const result = cache.read(resolvedPath, noCache);\n\n if (result.cached) {\n return result.content;\n }\n\n if (result.changed) {\n return `[file changed since last read]\\n\\n${result.content}`;\n }\n\n return result.content;\n }\n\n if (toolName === 'kirograph_retrieve') {\n const filePath = args.path as string;\n if (!filePath) return 'Error: path is required.';\n\n const projectRoot = (args.projectPath as string) || process.cwd();\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(projectRoot, filePath);\n\n const { getFileReadCache } = await Promise.resolve().then(() => require('./cache.js'));\n const cache = getFileReadCache();\n\n // Return cached content if we have it; otherwise read and cache\n const cached = cache.getPreviousContent(resolvedPath);\n if (cached !== undefined) {\n return cached;\n }\n\n if (!fs.existsSync(resolvedPath)) {\n return `Error: File not found: ${resolvedPath}`;\n }\n\n // Not in cache yet \u2014 do a fresh read and populate it\n const result = cache.read(resolvedPath, true);\n return result.content;\n }\n\n if (toolName === 'kirograph_compress') {\n const text = args.text as string;\n if (!text) return 'Error: text is required.';\n\n const rawLevel = (args.level as string) ?? 'full';\n const command = args.command as string | undefined;\n const { estimateTokens: est } = await Promise.resolve().then(() => require('../compression/index.js'));\n const originalTokens = est(text);\n\n let compressed: string;\n let strategy: string;\n\n if (command) {\n // Shell output \u2014 use rtk-style structural filters\n const shellLevel = rawLevel === 'ultra' ? 'ultra' : rawLevel === 'lite' || rawLevel === 'normal' ? 'normal' : 'aggressive';\n const { compress } = await Promise.resolve().then(() => require('../compression/index.js'));\n const result = compress(command, text, { level: shellLevel as any });\n compressed = result.output;\n strategy = `rtk:${result.commandFamily}:${shellLevel}`;\n } else {\n // Prose / observations \u2014 use caveman grammar\n const cavemanLevel = rawLevel === 'normal' || rawLevel === 'lite' ? 'lite' : rawLevel === 'aggressive' ? 'full' : rawLevel as any;\n const { compressObservation } = await Promise.resolve().then(() => require('../memory/compress.js'));\n const result = compressObservation(text, cavemanLevel);\n compressed = result.compressed;\n strategy = `caveman:${cavemanLevel}`;\n }\n\n const compressedTokens = est(compressed);\n const savings = originalTokens > 0 ? Math.round(((originalTokens - compressedTokens) / originalTokens) * 100) : 0;\n const footer = savings > 5\n ? `\\n\\n[${savings}% tokens saved | ${originalTokens}\u2192${compressedTokens} | ${strategy}]`\n : '';\n\n return compressed + footer;\n }\n\n if (toolName === 'kirograph_budget') {\n const projectRoot = (args.projectPath as string) || process.cwd();\n const reset = (args.reset as boolean) ?? false;\n\n const { BudgetTracker } = await Promise.resolve().then(() => require('../compression/tracker.js'));\n const budget = BudgetTracker.getInstance(projectRoot);\n\n if (reset) {\n budget.reset();\n return 'Context budget counters reset.';\n }\n\n const status = budget.getStatus();\n const lines = [\n 'Context Budget:',\n ` Tokens consumed: ${status.consumed.toLocaleString()}`,\n ` Budget limit: ${status.limit > 0 ? status.limit.toLocaleString() : 'unlimited'}`,\n ` Remaining: ${status.limit > 0 ? status.remaining.toLocaleString() : '\u221E'}`,\n ` Utilization: ${status.utilization}%`,\n ];\n\n if (status.warning) {\n lines.push(`\\n \u26A0 ${status.warning}`);\n }\n\n return lines.join('\\n');\n }\n\n const cg = await this.getConnection(args.projectPath as string | undefined);\n if (!cg) return 'KiroGraph not initialized. Run `kirograph init` in your project first.';\n\n // Write session marker so hooks can detect MCP was consulted\n writeSessionMarker(cg.getProjectRoot());\n\n if (CORE_TOOLS.has(toolName)) return handleCore(toolName, args, cg);\n if (CODE_HEALTH_TOOLS.has(toolName)) return handleCodeHealth(toolName, args, cg);\n if (ARCHITECTURE_TOOLS.has(toolName)) return handleArchitecture(toolName, args, cg);\n if (GIT_CONTEXT_TOOLS.has(toolName)) return handleGitContext(toolName, args, cg);\n if (COMPLEXITY_TOOLS.has(toolName)) return handleComplexity(toolName, args, cg);\n if (BRANCH_TOOLS.has(toolName)) return handleBranch(toolName, args, cg);\n if (EDIT_PRIMITIVES_TOOLS.has(toolName)) return handleEditPrimitives(toolName, args, cg);\n if (SECURITY_TOOLS.has(toolName)) return handleSecurity(toolName, args, cg);\n if (PATTERNS_TOOLS.has(toolName)) return handlePatterns(toolName, args, cg);\n if (WATCHMEN_TOOLS.has(toolName)) return handleWatchmen(toolName, args, cg);\n if (toolName.startsWith('kirograph_mem_')) return handleMemory(toolName, args, cg);\n if (toolName.startsWith('kirograph_docs_')) return handleDocs(toolName, args, cg);\n if (toolName.startsWith('kirograph_data_')) return handleData(toolName, args, cg);\n if (toolName.startsWith('kirograph_wiki_')) return handleWiki(toolName, args, cg);\n\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["path", "KiroGraph", "fs", "cg", "result", "compress"]
7
+ }
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var architecture_exports = {};
30
+ __export(architecture_exports, {
31
+ handleArchitecture: () => handleArchitecture
32
+ });
33
+ module.exports = __toCommonJS(architecture_exports);
34
+ var fs = __toESM(require("fs"));
35
+ var path = __toESM(require("path"));
36
+ var import_manifest = require("../../architecture/manifest/index");
37
+ var import_utils = require("./utils");
38
+ async function handleArchitecture(toolName, args, cg) {
39
+ switch (toolName) {
40
+ case "kirograph_architecture": {
41
+ if (!cg.isArchitectureEnabled()) {
42
+ return "Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.";
43
+ }
44
+ const level = args.level ?? "both";
45
+ const includeFiles = args.includeFiles === true;
46
+ const arch = cg.getArchitecture();
47
+ const lines = ["# Architecture"];
48
+ if ((level === "packages" || level === "both") && arch.packages.length > 0) {
49
+ lines.push("\n## Packages");
50
+ for (const pkg of arch.packages) {
51
+ const meta = [pkg.language, pkg.version].filter(Boolean).join(", ");
52
+ lines.push(`- **${pkg.name}** (${pkg.path}) [${pkg.source}${meta ? " \xB7 " + meta : ""}]`);
53
+ }
54
+ if (arch.packageDeps.length > 0) {
55
+ lines.push("\n## Package Dependencies");
56
+ for (const dep of arch.packageDeps) {
57
+ const src = arch.packages.find((p) => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;
58
+ const tgt = arch.packages.find((p) => p.id === dep.targetPkg)?.name ?? dep.targetPkg;
59
+ lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount} import${dep.depCount !== 1 ? "s" : ""})`);
60
+ }
61
+ }
62
+ }
63
+ if ((level === "layers" || level === "both") && arch.layers.length > 0) {
64
+ lines.push("\n## Layers");
65
+ for (const layer of arch.layers) {
66
+ const fileCount = Object.values(arch.fileLayers).filter((fl) => fl.some((l) => l.layerId === layer.id)).length;
67
+ lines.push(`- **${layer.name}** [${layer.source}] \u2014 ${fileCount} file${fileCount !== 1 ? "s" : ""}`);
68
+ }
69
+ if (arch.layerDeps.length > 0) {
70
+ lines.push("\n## Layer Dependencies");
71
+ for (const dep of arch.layerDeps) {
72
+ const src = dep.sourceLayer.replace("layer:", "");
73
+ const tgt = dep.targetLayer.replace("layer:", "");
74
+ lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount})`);
75
+ }
76
+ }
77
+ }
78
+ if (includeFiles && (level === "packages" || level === "both")) {
79
+ lines.push("\n## File \u2192 Package");
80
+ for (const [file, pkgIds] of Object.entries(arch.filePackages).slice(0, 50)) {
81
+ const names = pkgIds.map((id) => arch.packages.find((p) => p.id === id)?.name ?? id).join(", ");
82
+ lines.push(`- ${file}: ${names}`);
83
+ }
84
+ if (Object.keys(arch.filePackages).length > 50) lines.push(" \u2026(truncated)");
85
+ }
86
+ if (arch.packages.length === 0 && arch.layers.length === 0) {
87
+ return "No architecture data found. Run `kirograph index` with enableArchitecture=true.";
88
+ }
89
+ return lines.join("\n");
90
+ }
91
+ case "kirograph_coupling": {
92
+ if (!cg.isArchitectureEnabled()) {
93
+ return "Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.";
94
+ }
95
+ const sortBy = args.sortBy ?? "instability";
96
+ const limit = (0, import_utils.clampLimit)(args.limit, 20);
97
+ const arch = cg.getArchitecture();
98
+ if (arch.coupling.length === 0) {
99
+ return "No coupling data. Run `kirograph index` with enableArchitecture=true.";
100
+ }
101
+ const sorted = [...arch.coupling].sort((a, b) => {
102
+ if (sortBy === "afferent") return b.afferent - a.afferent;
103
+ if (sortBy === "efferent") return b.efferent - a.efferent;
104
+ return b.instability - a.instability;
105
+ }).slice(0, limit);
106
+ const lines = [
107
+ `Coupling Metrics (sorted by ${sortBy}):`,
108
+ "",
109
+ "Package Ca Ce I",
110
+ "\u2500".repeat(52)
111
+ ];
112
+ for (const c of sorted) {
113
+ const pkg = arch.packages.find((p) => p.id === c.packageId);
114
+ const name = (pkg?.name ?? c.packageId).slice(0, 32).padEnd(32);
115
+ const ca = String(c.afferent).padStart(4);
116
+ const ce = String(c.efferent).padStart(4);
117
+ const inst = c.instability.toFixed(2).padStart(5);
118
+ lines.push(`${name} ${ca} ${ce} ${inst}`);
119
+ }
120
+ lines.push("", "Ca=afferent (depended on by), Ce=efferent (depends on), I=instability (Ce/(Ca+Ce))");
121
+ return lines.join("\n");
122
+ }
123
+ case "kirograph_package": {
124
+ if (!cg.isArchitectureEnabled()) {
125
+ return "Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.";
126
+ }
127
+ const query = args.package.toLowerCase();
128
+ const includeFiles = args.includeFiles !== false;
129
+ const arch = cg.getArchitecture();
130
+ const pkg = arch.packages.find(
131
+ (p) => p.name.toLowerCase().includes(query) || p.path.toLowerCase().includes(query) || p.id.toLowerCase().includes(query)
132
+ );
133
+ if (!pkg) return `Package "${args.package}" not found. Use kirograph_architecture to list all packages.`;
134
+ const lines = [
135
+ `## Package: ${pkg.name}`,
136
+ `Path: ${pkg.path}`,
137
+ `Source: ${pkg.source}${pkg.manifestPath ? ` (${pkg.manifestPath})` : ""}`,
138
+ ...pkg.version ? [`Version: ${pkg.version}`] : [],
139
+ ...pkg.language ? [`Language: ${pkg.language}`] : []
140
+ ];
141
+ const deps = arch.packageDeps.filter((d) => d.sourcePkg === pkg.id);
142
+ const dependents = arch.packageDeps.filter((d) => d.targetPkg === pkg.id);
143
+ const coupling = arch.coupling.find((c) => c.packageId === pkg.id);
144
+ if (coupling) {
145
+ lines.push("", `Coupling: Ca=${coupling.afferent} Ce=${coupling.efferent} I=${coupling.instability.toFixed(2)}`);
146
+ }
147
+ if (deps.length > 0) {
148
+ lines.push("", `Depends on (${deps.length}):`);
149
+ for (const dep of deps) {
150
+ const name = arch.packages.find((p) => p.id === dep.targetPkg)?.name ?? dep.targetPkg;
151
+ lines.push(` \u2192 ${name} (${dep.depCount} import${dep.depCount !== 1 ? "s" : ""})`);
152
+ }
153
+ }
154
+ if (dependents.length > 0) {
155
+ lines.push("", `Depended on by (${dependents.length}):`);
156
+ for (const dep of dependents) {
157
+ const name = arch.packages.find((p) => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;
158
+ lines.push(` \u2190 ${name} (${dep.depCount} import${dep.depCount !== 1 ? "s" : ""})`);
159
+ }
160
+ }
161
+ if (pkg.externalDeps && pkg.externalDeps.length > 0) {
162
+ lines.push("", `External deps (${pkg.externalDeps.length}): ${pkg.externalDeps.slice(0, 10).join(", ")}${pkg.externalDeps.length > 10 ? "\u2026" : ""}`);
163
+ }
164
+ if (includeFiles) {
165
+ const files = Object.entries(arch.filePackages).filter(([, ids]) => ids.includes(pkg.id)).map(([f]) => f).sort();
166
+ if (files.length > 0) {
167
+ lines.push("", `Files (${files.length}):`);
168
+ for (const f of files.slice(0, 30)) lines.push(` ${f}`);
169
+ if (files.length > 30) lines.push(` \u2026and ${files.length - 30} more`);
170
+ }
171
+ }
172
+ return lines.join("\n");
173
+ }
174
+ case "kirograph_communities": {
175
+ const { detectCommunities } = await Promise.resolve().then(() => require("../../graph/communities.js"));
176
+ const db = cg.getDatabase();
177
+ const result = detectCommunities(db, {
178
+ resolution: args.resolution ?? 1
179
+ });
180
+ if (result.communities.length === 0) return "No communities detected. The graph may be too small or have no edges.";
181
+ const limit = Math.min(args.limit ?? 15, result.communities.length);
182
+ const lines = [
183
+ `## Communities (${result.communities.length} detected, modularity: ${result.modularity.toFixed(3)})`,
184
+ `Graph: ${result.totalNodes} nodes, ${result.totalEdges} edges`,
185
+ ""
186
+ ];
187
+ for (const c of result.communities.slice(0, limit)) {
188
+ lines.push(`### ${c.label} (${c.memberCount} symbols)`);
189
+ lines.push(`- Directory: \`${c.dominantDirectory}\``);
190
+ lines.push(`- Language: ${c.dominantLanguage}`);
191
+ lines.push(`- Inter-community edges: ${c.interCommunityEdges}`);
192
+ lines.push(`- Top members:`);
193
+ for (const m of c.members.slice(0, 8)) {
194
+ lines.push(` - ${m.kind} \`${m.name}\` \u2014 ${m.filePath}`);
195
+ }
196
+ if (c.memberCount > 8) lines.push(` - \u2026and ${c.memberCount - 8} more`);
197
+ lines.push("");
198
+ }
199
+ return lines.join("\n");
200
+ }
201
+ case "kirograph_manifest": {
202
+ const projectRoot = cg.getProjectRoot();
203
+ const packages = await (0, import_manifest.parseAllManifests)(projectRoot);
204
+ const licenseMap = /* @__PURE__ */ new Map();
205
+ for (const pkg of packages) {
206
+ if (!pkg.manifestPath) continue;
207
+ const absManifest = path.join(projectRoot, pkg.manifestPath);
208
+ try {
209
+ const basename = path.basename(absManifest);
210
+ if (basename === "package.json") {
211
+ const raw = JSON.parse(fs.readFileSync(absManifest, "utf8"));
212
+ const lic = raw.license;
213
+ if (typeof lic === "string") licenseMap.set(pkg.id, lic);
214
+ } else if (basename === "Cargo.toml") {
215
+ const content = fs.readFileSync(absManifest, "utf8");
216
+ const m = content.match(/^\s*license\s*=\s*"([^"]+)"/m);
217
+ if (m) licenseMap.set(pkg.id, m[1]);
218
+ } else if (basename === "pyproject.toml") {
219
+ const content = fs.readFileSync(absManifest, "utf8");
220
+ const m = content.match(/^\s*license\s*=\s*"([^"]+)"/m);
221
+ if (m) licenseMap.set(pkg.id, m[1]);
222
+ }
223
+ } catch {
224
+ }
225
+ }
226
+ const ecosystemFilter = args.ecosystem?.toLowerCase();
227
+ let filtered = ecosystemFilter ? packages.filter((p) => p.language?.toLowerCase().includes(ecosystemFilter) || p.source === "manifest" && p.manifestPath?.toLowerCase().includes(ecosystemFilter)) : packages;
228
+ const packageQuery = args.package?.toLowerCase();
229
+ if (packageQuery) {
230
+ const pkg = filtered.find(
231
+ (p) => p.name.toLowerCase().includes(packageQuery) || p.path.toLowerCase().includes(packageQuery) || p.id.toLowerCase().includes(packageQuery)
232
+ );
233
+ if (!pkg) return `Package "${args.package}" not found. Use kirograph_manifest (no args) to list all packages.`;
234
+ const lines2 = [
235
+ `## ${pkg.name}`,
236
+ `ID: ${pkg.id}`,
237
+ `Path: ${pkg.path}`,
238
+ `Source: ${pkg.source}${pkg.manifestPath ? ` (${pkg.manifestPath})` : ""}`,
239
+ ...pkg.version ? [`Version: ${pkg.version}`] : [],
240
+ ...pkg.language ? [`Language: ${pkg.language}`] : [],
241
+ ...licenseMap.has(pkg.id) ? [`License: ${licenseMap.get(pkg.id)}`] : []
242
+ ];
243
+ if (pkg.externalDeps && pkg.externalDeps.length > 0) {
244
+ lines2.push("", `External deps (${pkg.externalDeps.length}):`);
245
+ for (const dep of pkg.externalDeps) lines2.push(` - ${dep}`);
246
+ }
247
+ return lines2.join("\n");
248
+ }
249
+ if (args.showDrift) {
250
+ const byName = /* @__PURE__ */ new Map();
251
+ for (const pkg of filtered) {
252
+ const key = pkg.name.toLowerCase();
253
+ if (!byName.has(key)) byName.set(key, []);
254
+ byName.get(key).push({ id: pkg.id, version: pkg.version, path: pkg.path });
255
+ }
256
+ const drifted = [...byName.entries()].filter(([, entries]) => {
257
+ const versions = new Set(entries.map((e) => e.version).filter(Boolean));
258
+ return entries.length > 1 && versions.size > 1;
259
+ });
260
+ if (drifted.length === 0) return "No version drift detected across packages.";
261
+ const lines2 = ["## Version Drift", ""];
262
+ for (const [name, entries] of drifted) {
263
+ lines2.push(`**${name}**`);
264
+ for (const e of entries) lines2.push(` - ${e.path}: ${e.version ?? "(no version)"}`);
265
+ }
266
+ return lines2.join("\n");
267
+ }
268
+ if (filtered.length === 0) return "No manifest packages found. Run `kirograph index` or check your project root.";
269
+ const byLang = /* @__PURE__ */ new Map();
270
+ for (const pkg of filtered) {
271
+ const lang = pkg.language ?? "unknown";
272
+ if (!byLang.has(lang)) byLang.set(lang, []);
273
+ byLang.get(lang).push(pkg);
274
+ }
275
+ const lines = [`## Workspace Manifest (${filtered.length} package${filtered.length !== 1 ? "s" : ""})`, ""];
276
+ for (const [lang, pkgs] of [...byLang.entries()].sort(([a], [b]) => a.localeCompare(b))) {
277
+ lines.push(`### ${lang} (${pkgs.length})`);
278
+ for (const pkg of pkgs) {
279
+ const ver = pkg.version ? ` v${pkg.version}` : "";
280
+ const deps = pkg.externalDeps ? ` \xB7 ${pkg.externalDeps.length} deps` : "";
281
+ const lic = licenseMap.has(pkg.id) ? ` \xB7 ${licenseMap.get(pkg.id)}` : "";
282
+ lines.push(`- **${pkg.name}**${ver} \`${pkg.path}\`${deps}${lic}`);
283
+ }
284
+ lines.push("");
285
+ }
286
+ lines.push(`Tip: pass package=<name> for full dep list, showDrift=true for version conflicts.`);
287
+ return lines.join("\n");
288
+ }
289
+ default:
290
+ return `Unknown tool: ${toolName}`;
291
+ }
292
+ }
293
+ // Annotate the CommonJS export names for ESM import in node:
294
+ 0 && (module.exports = {
295
+ handleArchitecture
296
+ });
297
+ //# sourceMappingURL=architecture.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/handlers/architecture.ts"],
4
+ "sourcesContent": ["import * as fs from 'fs';\nimport * as path from 'path';\nimport KiroGraph from '../../index';\nimport { parseAllManifests } from '../../architecture/manifest/index';\nimport { clampLimit } from './utils';\n\nexport async function handleArchitecture(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\n case 'kirograph_architecture': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const level = (args.level as string) ?? 'both';\n const includeFiles = args.includeFiles === true;\n const arch = cg.getArchitecture();\n\n const lines: string[] = ['# Architecture'];\n\n if ((level === 'packages' || level === 'both') && arch.packages.length > 0) {\n lines.push('\\n## Packages');\n for (const pkg of arch.packages) {\n const meta = [pkg.language, pkg.version].filter(Boolean).join(', ');\n lines.push(`- **${pkg.name}** (${pkg.path}) [${pkg.source}${meta ? ' \u00B7 ' + meta : ''}]`);\n }\n if (arch.packageDeps.length > 0) {\n lines.push('\\n## Package Dependencies');\n for (const dep of arch.packageDeps) {\n const src = arch.packages.find(p => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;\n const tgt = arch.packages.find(p => p.id === dep.targetPkg)?.name ?? dep.targetPkg;\n lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n }\n\n if ((level === 'layers' || level === 'both') && arch.layers.length > 0) {\n lines.push('\\n## Layers');\n for (const layer of arch.layers) {\n const fileCount = Object.values(arch.fileLayers).filter(fl => fl.some(l => l.layerId === layer.id)).length;\n lines.push(`- **${layer.name}** [${layer.source}] \u2014 ${fileCount} file${fileCount !== 1 ? 's' : ''}`);\n }\n if (arch.layerDeps.length > 0) {\n lines.push('\\n## Layer Dependencies');\n for (const dep of arch.layerDeps) {\n const src = dep.sourceLayer.replace('layer:', '');\n const tgt = dep.targetLayer.replace('layer:', '');\n lines.push(`- ${src} \u2192 ${tgt} (${dep.depCount})`);\n }\n }\n }\n\n if (includeFiles && (level === 'packages' || level === 'both')) {\n lines.push('\\n## File \u2192 Package');\n for (const [file, pkgIds] of Object.entries(arch.filePackages).slice(0, 50)) {\n const names = pkgIds.map(id => arch.packages.find(p => p.id === id)?.name ?? id).join(', ');\n lines.push(`- ${file}: ${names}`);\n }\n if (Object.keys(arch.filePackages).length > 50) lines.push(' \u2026(truncated)');\n }\n\n if (arch.packages.length === 0 && arch.layers.length === 0) {\n return 'No architecture data found. Run `kirograph index` with enableArchitecture=true.';\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_coupling': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const sortBy = (args.sortBy as string) ?? 'instability';\n const limit = clampLimit(args.limit as number | undefined, 20);\n const arch = cg.getArchitecture();\n\n if (arch.coupling.length === 0) {\n return 'No coupling data. Run `kirograph index` with enableArchitecture=true.';\n }\n\n const sorted = [...arch.coupling].sort((a, b) => {\n if (sortBy === 'afferent') return b.afferent - a.afferent;\n if (sortBy === 'efferent') return b.efferent - a.efferent;\n return b.instability - a.instability;\n }).slice(0, limit);\n\n const lines = [\n `Coupling Metrics (sorted by ${sortBy}):`,\n '',\n 'Package Ca Ce I',\n '\u2500'.repeat(52),\n ];\n\n for (const c of sorted) {\n const pkg = arch.packages.find(p => p.id === c.packageId);\n const name = (pkg?.name ?? c.packageId).slice(0, 32).padEnd(32);\n const ca = String(c.afferent).padStart(4);\n const ce = String(c.efferent).padStart(4);\n const inst = c.instability.toFixed(2).padStart(5);\n lines.push(`${name} ${ca} ${ce} ${inst}`);\n }\n\n lines.push('', 'Ca=afferent (depended on by), Ce=efferent (depends on), I=instability (Ce/(Ca+Ce))');\n return lines.join('\\n');\n }\n\n case 'kirograph_package': {\n if (!cg.isArchitectureEnabled()) {\n return 'Architecture analysis is disabled. Set enableArchitecture=true in .kirograph/config.json and re-index.';\n }\n const query = (args.package as string).toLowerCase();\n const includeFiles = args.includeFiles !== false;\n const arch = cg.getArchitecture();\n\n const pkg = arch.packages.find(p =>\n p.name.toLowerCase().includes(query) || p.path.toLowerCase().includes(query) || p.id.toLowerCase().includes(query)\n );\n if (!pkg) return `Package \"${args.package}\" not found. Use kirograph_architecture to list all packages.`;\n\n const lines = [\n `## Package: ${pkg.name}`,\n `Path: ${pkg.path}`,\n `Source: ${pkg.source}${pkg.manifestPath ? ` (${pkg.manifestPath})` : ''}`,\n ...(pkg.version ? [`Version: ${pkg.version}`] : []),\n ...(pkg.language ? [`Language: ${pkg.language}`] : []),\n ];\n\n const deps = arch.packageDeps.filter(d => d.sourcePkg === pkg.id);\n const dependents = arch.packageDeps.filter(d => d.targetPkg === pkg.id);\n const coupling = arch.coupling.find(c => c.packageId === pkg.id);\n\n if (coupling) {\n lines.push('', `Coupling: Ca=${coupling.afferent} Ce=${coupling.efferent} I=${coupling.instability.toFixed(2)}`);\n }\n\n if (deps.length > 0) {\n lines.push('', `Depends on (${deps.length}):`);\n for (const dep of deps) {\n const name = arch.packages.find(p => p.id === dep.targetPkg)?.name ?? dep.targetPkg;\n lines.push(` \u2192 ${name} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n\n if (dependents.length > 0) {\n lines.push('', `Depended on by (${dependents.length}):`);\n for (const dep of dependents) {\n const name = arch.packages.find(p => p.id === dep.sourcePkg)?.name ?? dep.sourcePkg;\n lines.push(` \u2190 ${name} (${dep.depCount} import${dep.depCount !== 1 ? 's' : ''})`);\n }\n }\n\n if (pkg.externalDeps && pkg.externalDeps.length > 0) {\n lines.push('', `External deps (${pkg.externalDeps.length}): ${pkg.externalDeps.slice(0, 10).join(', ')}${pkg.externalDeps.length > 10 ? '\u2026' : ''}`);\n }\n\n if (includeFiles) {\n const files = Object.entries(arch.filePackages)\n .filter(([, ids]) => ids.includes(pkg.id))\n .map(([f]) => f)\n .sort();\n if (files.length > 0) {\n lines.push('', `Files (${files.length}):`);\n for (const f of files.slice(0, 30)) lines.push(` ${f}`);\n if (files.length > 30) lines.push(` \u2026and ${files.length - 30} more`);\n }\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_communities': {\n const { detectCommunities } = await Promise.resolve().then(() => require('../../graph/communities.js'));\n const db = cg.getDatabase();\n const result = detectCommunities(db, {\n resolution: (args.resolution as number) ?? 1.0,\n });\n\n if (result.communities.length === 0) return 'No communities detected. The graph may be too small or have no edges.';\n\n const limit = Math.min((args.limit as number) ?? 15, result.communities.length);\n const lines = [\n `## Communities (${result.communities.length} detected, modularity: ${result.modularity.toFixed(3)})`,\n `Graph: ${result.totalNodes} nodes, ${result.totalEdges} edges`,\n '',\n ];\n\n for (const c of result.communities.slice(0, limit)) {\n lines.push(`### ${c.label} (${c.memberCount} symbols)`);\n lines.push(`- Directory: \\`${c.dominantDirectory}\\``);\n lines.push(`- Language: ${c.dominantLanguage}`);\n lines.push(`- Inter-community edges: ${c.interCommunityEdges}`);\n lines.push(`- Top members:`);\n for (const m of c.members.slice(0, 8)) {\n lines.push(` - ${m.kind} \\`${m.name}\\` \u2014 ${m.filePath}`);\n }\n if (c.memberCount > 8) lines.push(` - \u2026and ${c.memberCount - 8} more`);\n lines.push('');\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_manifest': {\n const projectRoot = cg.getProjectRoot();\n const packages = await parseAllManifests(projectRoot);\n\n // Read license fields from manifest files for packages that have them\n const licenseMap = new Map<string, string>();\n for (const pkg of packages) {\n if (!pkg.manifestPath) continue;\n const absManifest = path.join(projectRoot, pkg.manifestPath);\n try {\n const basename = path.basename(absManifest);\n if (basename === 'package.json') {\n const raw = JSON.parse(fs.readFileSync(absManifest, 'utf8')) as Record<string, unknown>;\n const lic = raw.license;\n if (typeof lic === 'string') licenseMap.set(pkg.id, lic);\n } else if (basename === 'Cargo.toml') {\n const content = fs.readFileSync(absManifest, 'utf8');\n const m = content.match(/^\\s*license\\s*=\\s*\"([^\"]+)\"/m);\n if (m) licenseMap.set(pkg.id, m[1]);\n } else if (basename === 'pyproject.toml') {\n const content = fs.readFileSync(absManifest, 'utf8');\n const m = content.match(/^\\s*license\\s*=\\s*\"([^\"]+)\"/m);\n if (m) licenseMap.set(pkg.id, m[1]);\n }\n } catch {\n // ignore read errors\n }\n }\n\n // Filter by ecosystem if requested\n const ecosystemFilter = (args.ecosystem as string | undefined)?.toLowerCase();\n let filtered = ecosystemFilter\n ? packages.filter(p => p.language?.toLowerCase().includes(ecosystemFilter) || p.source === 'manifest' && p.manifestPath?.toLowerCase().includes(ecosystemFilter))\n : packages;\n\n // Drill into a single package\n const packageQuery = (args.package as string | undefined)?.toLowerCase();\n if (packageQuery) {\n const pkg = filtered.find(p =>\n p.name.toLowerCase().includes(packageQuery) || p.path.toLowerCase().includes(packageQuery) || p.id.toLowerCase().includes(packageQuery)\n );\n if (!pkg) return `Package \"${args.package}\" not found. Use kirograph_manifest (no args) to list all packages.`;\n\n const lines = [\n `## ${pkg.name}`,\n `ID: ${pkg.id}`,\n `Path: ${pkg.path}`,\n `Source: ${pkg.source}${pkg.manifestPath ? ` (${pkg.manifestPath})` : ''}`,\n ...(pkg.version ? [`Version: ${pkg.version}`] : []),\n ...(pkg.language ? [`Language: ${pkg.language}`] : []),\n ...(licenseMap.has(pkg.id) ? [`License: ${licenseMap.get(pkg.id)}`] : []),\n ];\n\n if (pkg.externalDeps && pkg.externalDeps.length > 0) {\n lines.push('', `External deps (${pkg.externalDeps.length}):`);\n for (const dep of pkg.externalDeps) lines.push(` - ${dep}`);\n }\n return lines.join('\\n');\n }\n\n // Version drift: packages declared in multiple places with differing versions\n if (args.showDrift) {\n const byName = new Map<string, Array<{ id: string; version?: string; path: string }>>();\n for (const pkg of filtered) {\n const key = pkg.name.toLowerCase();\n if (!byName.has(key)) byName.set(key, []);\n byName.get(key)!.push({ id: pkg.id, version: pkg.version, path: pkg.path });\n }\n const drifted = [...byName.entries()].filter(([, entries]) => {\n const versions = new Set(entries.map(e => e.version).filter(Boolean));\n return entries.length > 1 && versions.size > 1;\n });\n if (drifted.length === 0) return 'No version drift detected across packages.';\n const lines = ['## Version Drift', ''];\n for (const [name, entries] of drifted) {\n lines.push(`**${name}**`);\n for (const e of entries) lines.push(` - ${e.path}: ${e.version ?? '(no version)'}`);\n }\n return lines.join('\\n');\n }\n\n // Summary table\n if (filtered.length === 0) return 'No manifest packages found. Run `kirograph index` or check your project root.';\n\n const byLang = new Map<string, typeof filtered>();\n for (const pkg of filtered) {\n const lang = pkg.language ?? 'unknown';\n if (!byLang.has(lang)) byLang.set(lang, []);\n byLang.get(lang)!.push(pkg);\n }\n\n const lines: string[] = [`## Workspace Manifest (${filtered.length} package${filtered.length !== 1 ? 's' : ''})`, ''];\n for (const [lang, pkgs] of [...byLang.entries()].sort(([a], [b]) => a.localeCompare(b))) {\n lines.push(`### ${lang} (${pkgs.length})`);\n for (const pkg of pkgs) {\n const ver = pkg.version ? ` v${pkg.version}` : '';\n const deps = pkg.externalDeps ? ` \u00B7 ${pkg.externalDeps.length} deps` : '';\n const lic = licenseMap.has(pkg.id) ? ` \u00B7 ${licenseMap.get(pkg.id)}` : '';\n lines.push(`- **${pkg.name}**${ver} \\`${pkg.path}\\`${deps}${lic}`);\n }\n lines.push('');\n }\n\n lines.push(`Tip: pass package=<name> for full dep list, showDrift=true for version conflicts.`);\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": ["lines"]
7
+ }
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var branch_exports = {};
30
+ __export(branch_exports, {
31
+ handleBranch: () => handleBranch
32
+ });
33
+ module.exports = __toCommonJS(branch_exports);
34
+ var import_branch_manager = require("../../core/branch-manager");
35
+ function humanSize(bytes) {
36
+ if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
37
+ return `${(bytes / 1024).toFixed(1)} KB`;
38
+ }
39
+ async function handleBranch(toolName, args, cg) {
40
+ const projectRoot = cg.getProjectRoot();
41
+ switch (toolName) {
42
+ case "kirograph_branch_list": {
43
+ const currentBranch = (0, import_branch_manager.getCurrentGitBranch)(projectRoot);
44
+ const branches = (0, import_branch_manager.listTrackedBranches)(projectRoot);
45
+ const lines = [`## Tracked Branch Databases
46
+ `];
47
+ lines.push(`Current git branch: ${currentBranch}
48
+ `);
49
+ if (branches.length === 0) {
50
+ lines.push("No branch databases found.");
51
+ lines.push("\nTo add a branch snapshot, run:");
52
+ lines.push(" kirograph branch add <branch-name>");
53
+ return lines.join("\n");
54
+ }
55
+ lines.push(`${"Branch".padEnd(40)} ${"Size".padEnd(10)} Last Sync`);
56
+ lines.push("-".repeat(70));
57
+ for (const b of branches) {
58
+ const lastSync = new Date(b.mtimeMs).toISOString().replace("T", " ").slice(0, 19);
59
+ lines.push(`${b.name.padEnd(40)} ${humanSize(b.sizeBytes).padEnd(10)} ${lastSync}`);
60
+ }
61
+ lines.push(`
62
+ Total: ${branches.length} branch database(s)`);
63
+ lines.push("\nTo add a new branch: kirograph branch add <branch-name>");
64
+ return lines.join("\n");
65
+ }
66
+ case "kirograph_branch_diff": {
67
+ const branchA = args.branchA;
68
+ const branchB = args.branchB ?? "main";
69
+ if (!branchA) return "Error: branchA is required.";
70
+ const pathA = (0, import_branch_manager.branchDbPath)(projectRoot, branchA);
71
+ const pathB = (0, import_branch_manager.branchDbPath)(projectRoot, branchB);
72
+ const fs = await import("fs");
73
+ if (!fs.existsSync(pathA)) {
74
+ return `Branch database for "${branchA}" not found at ${pathA}.
75
+ Use kirograph branch add ${branchA} to create it.`;
76
+ }
77
+ if (!fs.existsSync(pathB)) {
78
+ return `Branch database for "${branchB}" not found at ${pathB}.
79
+ Use kirograph branch add ${branchB} to create it.`;
80
+ }
81
+ const { Database } = (await import("node-sqlite3-wasm")).default;
82
+ const rawDbA = new Database(pathA);
83
+ const rowsA = rawDbA.all("SELECT id, name, kind, file_path, qualified_name FROM nodes", []);
84
+ rawDbA.close();
85
+ const rawDbB = new Database(pathB);
86
+ const rowsB = rawDbB.all("SELECT id, name, kind, file_path, qualified_name FROM nodes", []);
87
+ rawDbB.close();
88
+ const mapA = new Map(rowsA.map((r) => [r.id, r]));
89
+ const mapB = new Map(rowsB.map((r) => [r.id, r]));
90
+ const onlyInA = [];
91
+ const onlyInB = [];
92
+ const changed = [];
93
+ for (const [id, nodeA] of mapA) {
94
+ if (!mapB.has(id)) {
95
+ onlyInA.push(nodeA);
96
+ } else {
97
+ const nodeB = mapB.get(id);
98
+ if (nodeA.qualified_name !== nodeB.qualified_name) {
99
+ changed.push({ a: nodeA, b: nodeB });
100
+ }
101
+ }
102
+ }
103
+ for (const [id, nodeB] of mapB) {
104
+ if (!mapA.has(id)) onlyInB.push(nodeB);
105
+ }
106
+ const lines = [
107
+ `## Branch Diff: ${branchA} vs ${branchB}
108
+ `,
109
+ `Added in ${branchA} (not in ${branchB}): ${onlyInA.length}`,
110
+ `Removed from ${branchA} (in ${branchB} only): ${onlyInB.length}`,
111
+ `Changed (different qualified_name): ${changed.length}`,
112
+ ""
113
+ ];
114
+ if (onlyInA.length > 0) {
115
+ lines.push(`### Added (${Math.min(onlyInA.length, 20)} shown):`);
116
+ for (const n of onlyInA.slice(0, 20)) {
117
+ lines.push(` + [${n.kind}] \`${n.name}\` \u2014 ${n.file_path}`);
118
+ }
119
+ if (onlyInA.length > 20) lines.push(` \u2026and ${onlyInA.length - 20} more`);
120
+ lines.push("");
121
+ }
122
+ if (onlyInB.length > 0) {
123
+ lines.push(`### Removed (${Math.min(onlyInB.length, 20)} shown):`);
124
+ for (const n of onlyInB.slice(0, 20)) {
125
+ lines.push(` - [${n.kind}] \`${n.name}\` \u2014 ${n.file_path}`);
126
+ }
127
+ if (onlyInB.length > 20) lines.push(` \u2026and ${onlyInB.length - 20} more`);
128
+ lines.push("");
129
+ }
130
+ if (changed.length > 0) {
131
+ lines.push(`### Changed (${Math.min(changed.length, 20)} shown):`);
132
+ for (const { a, b } of changed.slice(0, 20)) {
133
+ lines.push(` ~ [${a.kind}] \`${a.name}\`: ${b.qualified_name} \u2192 ${a.qualified_name}`);
134
+ }
135
+ if (changed.length > 20) lines.push(` \u2026and ${changed.length - 20} more`);
136
+ }
137
+ return lines.join("\n");
138
+ }
139
+ case "kirograph_branch_search": {
140
+ const query = args.query;
141
+ const branch = args.branch;
142
+ const limitN = typeof args.limit === "number" ? Math.max(1, Math.min(args.limit, 100)) : 20;
143
+ if (!query) return "Error: query is required.";
144
+ if (!branch) return "Error: branch is required.";
145
+ const dbPath = (0, import_branch_manager.branchDbPath)(projectRoot, branch);
146
+ const fs = await import("fs");
147
+ if (!fs.existsSync(dbPath)) {
148
+ return `Branch database for "${branch}" not found at ${dbPath}.
149
+ Use kirograph branch add ${branch} to create it.`;
150
+ }
151
+ const { Database } = (await import("node-sqlite3-wasm")).default;
152
+ const rawDb = new Database(dbPath);
153
+ const pattern = `%${query}%`;
154
+ const rows = rawDb.all(
155
+ "SELECT name, kind, file_path, start_line FROM nodes WHERE name LIKE ? OR qualified_name LIKE ? LIMIT ?",
156
+ [pattern, pattern, limitN]
157
+ );
158
+ rawDb.close();
159
+ if (rows.length === 0) return `No symbols matching "${query}" found in branch "${branch}".`;
160
+ const lines = [`## Search results for "${query}" in branch "${branch}" (${rows.length} found)
161
+ `];
162
+ for (const r of rows) {
163
+ lines.push(` [${r.kind}] \`${r.name}\` \u2014 ${r.file_path}:${r.start_line}`);
164
+ }
165
+ return lines.join("\n");
166
+ }
167
+ default:
168
+ return `Unknown tool: ${toolName}`;
169
+ }
170
+ }
171
+ // Annotate the CommonJS export names for ESM import in node:
172
+ 0 && (module.exports = {
173
+ handleBranch
174
+ });
175
+ //# sourceMappingURL=branch.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/handlers/branch.ts"],
4
+ "sourcesContent": ["import KiroGraph from '../../index';\nimport { listTrackedBranches, branchDbPath, getCurrentGitBranch } from '../../core/branch-manager';\n\nfunction humanSize(bytes: number): string {\n if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / 1024).toFixed(1)} KB`;\n}\n\nexport async function handleBranch(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n const projectRoot = cg.getProjectRoot();\n\n switch (toolName) {\n case 'kirograph_branch_list': {\n const currentBranch = getCurrentGitBranch(projectRoot);\n const branches = listTrackedBranches(projectRoot);\n\n const lines = [`## Tracked Branch Databases\\n`];\n lines.push(`Current git branch: ${currentBranch}\\n`);\n\n if (branches.length === 0) {\n lines.push('No branch databases found.');\n lines.push('\\nTo add a branch snapshot, run:');\n lines.push(' kirograph branch add <branch-name>');\n return lines.join('\\n');\n }\n\n lines.push(`${'Branch'.padEnd(40)} ${'Size'.padEnd(10)} Last Sync`);\n lines.push('-'.repeat(70));\n for (const b of branches) {\n const lastSync = new Date(b.mtimeMs).toISOString().replace('T', ' ').slice(0, 19);\n lines.push(`${b.name.padEnd(40)} ${humanSize(b.sizeBytes).padEnd(10)} ${lastSync}`);\n }\n lines.push(`\\nTotal: ${branches.length} branch database(s)`);\n lines.push('\\nTo add a new branch: kirograph branch add <branch-name>');\n return lines.join('\\n');\n }\n\n case 'kirograph_branch_diff': {\n const branchA = args.branchA as string | undefined;\n const branchB = (args.branchB as string) ?? 'main';\n\n if (!branchA) return 'Error: branchA is required.';\n\n const pathA = branchDbPath(projectRoot, branchA);\n const pathB = branchDbPath(projectRoot, branchB);\n\n const fs = await import('fs');\n if (!fs.existsSync(pathA)) {\n return `Branch database for \"${branchA}\" not found at ${pathA}.\\nUse kirograph branch add ${branchA} to create it.`;\n }\n if (!fs.existsSync(pathB)) {\n return `Branch database for \"${branchB}\" not found at ${pathB}.\\nUse kirograph branch add ${branchB} to create it.`;\n }\n\n const { Database } = ((await import('node-sqlite3-wasm')) as any).default;\n const rawDbA = new Database(pathA);\n const rowsA = rawDbA.all('SELECT id, name, kind, file_path, qualified_name FROM nodes', []) as Array<{\n id: string; name: string; kind: string; file_path: string; qualified_name: string;\n }>;\n rawDbA.close();\n\n const rawDbB = new Database(pathB);\n const rowsB = rawDbB.all('SELECT id, name, kind, file_path, qualified_name FROM nodes', []) as Array<{\n id: string; name: string; kind: string; file_path: string; qualified_name: string;\n }>;\n rawDbB.close();\n\n const mapA = new Map(rowsA.map(r => [r.id, r]));\n const mapB = new Map(rowsB.map(r => [r.id, r]));\n\n const onlyInA: typeof rowsA = [];\n const onlyInB: typeof rowsB = [];\n const changed: Array<{ a: typeof rowsA[0]; b: typeof rowsB[0] }> = [];\n\n for (const [id, nodeA] of mapA) {\n if (!mapB.has(id)) {\n onlyInA.push(nodeA);\n } else {\n const nodeB = mapB.get(id)!;\n if (nodeA.qualified_name !== nodeB.qualified_name) {\n changed.push({ a: nodeA, b: nodeB });\n }\n }\n }\n for (const [id, nodeB] of mapB) {\n if (!mapA.has(id)) onlyInB.push(nodeB);\n }\n\n const lines = [\n `## Branch Diff: ${branchA} vs ${branchB}\\n`,\n `Added in ${branchA} (not in ${branchB}): ${onlyInA.length}`,\n `Removed from ${branchA} (in ${branchB} only): ${onlyInB.length}`,\n `Changed (different qualified_name): ${changed.length}`,\n '',\n ];\n\n if (onlyInA.length > 0) {\n lines.push(`### Added (${Math.min(onlyInA.length, 20)} shown):`);\n for (const n of onlyInA.slice(0, 20)) {\n lines.push(` + [${n.kind}] \\`${n.name}\\` \u2014 ${n.file_path}`);\n }\n if (onlyInA.length > 20) lines.push(` \u2026and ${onlyInA.length - 20} more`);\n lines.push('');\n }\n\n if (onlyInB.length > 0) {\n lines.push(`### Removed (${Math.min(onlyInB.length, 20)} shown):`);\n for (const n of onlyInB.slice(0, 20)) {\n lines.push(` - [${n.kind}] \\`${n.name}\\` \u2014 ${n.file_path}`);\n }\n if (onlyInB.length > 20) lines.push(` \u2026and ${onlyInB.length - 20} more`);\n lines.push('');\n }\n\n if (changed.length > 0) {\n lines.push(`### Changed (${Math.min(changed.length, 20)} shown):`);\n for (const { a, b } of changed.slice(0, 20)) {\n lines.push(` ~ [${a.kind}] \\`${a.name}\\`: ${b.qualified_name} \u2192 ${a.qualified_name}`);\n }\n if (changed.length > 20) lines.push(` \u2026and ${changed.length - 20} more`);\n }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_branch_search': {\n const query = args.query as string | undefined;\n const branch = args.branch as string | undefined;\n const limitN = typeof args.limit === 'number' ? Math.max(1, Math.min(args.limit, 100)) : 20;\n\n if (!query) return 'Error: query is required.';\n if (!branch) return 'Error: branch is required.';\n\n const dbPath = branchDbPath(projectRoot, branch);\n const fs = await import('fs');\n if (!fs.existsSync(dbPath)) {\n return `Branch database for \"${branch}\" not found at ${dbPath}.\\nUse kirograph branch add ${branch} to create it.`;\n }\n\n const { Database } = ((await import('node-sqlite3-wasm')) as any).default;\n const rawDb = new Database(dbPath);\n const pattern = `%${query}%`;\n const rows = rawDb.all(\n 'SELECT name, kind, file_path, start_line FROM nodes WHERE name LIKE ? OR qualified_name LIKE ? LIMIT ?',\n [pattern, pattern, limitN]\n ) as Array<{ name: string; kind: string; file_path: string; start_line: number }>;\n rawDb.close();\n\n if (rows.length === 0) return `No symbols matching \"${query}\" found in branch \"${branch}\".`;\n\n const lines = [`## Search results for \"${query}\" in branch \"${branch}\" (${rows.length} found)\\n`];\n for (const r of rows) {\n lines.push(` [${r.kind}] \\`${r.name}\\` \u2014 ${r.file_path}:${r.start_line}`);\n }\n return lines.join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,4BAAuE;AAEvE,SAAS,UAAU,OAAuB;AACxC,MAAI,SAAS,OAAO,KAAM,QAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AACtE,SAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AACrC;AAEA,eAAsB,aAAa,UAAkB,MAA+B,IAAgC;AAClH,QAAM,cAAc,GAAG,eAAe;AAEtC,UAAQ,UAAU;AAAA,IAChB,KAAK,yBAAyB;AAC5B,YAAM,oBAAgB,2CAAoB,WAAW;AACrD,YAAM,eAAW,2CAAoB,WAAW;AAEhD,YAAM,QAAQ,CAAC;AAAA,CAA+B;AAC9C,YAAM,KAAK,uBAAuB,aAAa;AAAA,CAAI;AAEnD,UAAI,SAAS,WAAW,GAAG;AACzB,cAAM,KAAK,4BAA4B;AACvC,cAAM,KAAK,kCAAkC;AAC7C,cAAM,KAAK,sCAAsC;AACjD,eAAO,MAAM,KAAK,IAAI;AAAA,MACxB;AAEA,YAAM,KAAK,GAAG,SAAS,OAAO,EAAE,CAAC,KAAK,OAAO,OAAO,EAAE,CAAC,aAAa;AACpE,YAAM,KAAK,IAAI,OAAO,EAAE,CAAC;AACzB,iBAAW,KAAK,UAAU;AACxB,cAAM,WAAW,IAAI,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE;AAChF,cAAM,KAAK,GAAG,EAAE,KAAK,OAAO,EAAE,CAAC,KAAK,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,KAAK,QAAQ,EAAE;AAAA,MACtF;AACA,YAAM,KAAK;AAAA,SAAY,SAAS,MAAM,qBAAqB;AAC3D,YAAM,KAAK,2DAA2D;AACtE,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,IAEA,KAAK,yBAAyB;AAC5B,YAAM,UAAU,KAAK;AACrB,YAAM,UAAW,KAAK,WAAsB;AAE5C,UAAI,CAAC,QAAS,QAAO;AAErB,YAAM,YAAQ,oCAAa,aAAa,OAAO;AAC/C,YAAM,YAAQ,oCAAa,aAAa,OAAO;AAE/C,YAAM,KAAK,MAAM,OAAO,IAAI;AAC5B,UAAI,CAAC,GAAG,WAAW,KAAK,GAAG;AACzB,eAAO,wBAAwB,OAAO,kBAAkB,KAAK;AAAA,2BAA+B,OAAO;AAAA,MACrG;AACA,UAAI,CAAC,GAAG,WAAW,KAAK,GAAG;AACzB,eAAO,wBAAwB,OAAO,kBAAkB,KAAK;AAAA,2BAA+B,OAAO;AAAA,MACrG;AAEA,YAAM,EAAE,SAAS,KAAM,MAAM,OAAO,mBAAmB,GAAW;AAClE,YAAM,SAAS,IAAI,SAAS,KAAK;AACjC,YAAM,QAAQ,OAAO,IAAI,+DAA+D,CAAC,CAAC;AAG1F,aAAO,MAAM;AAEb,YAAM,SAAS,IAAI,SAAS,KAAK;AACjC,YAAM,QAAQ,OAAO,IAAI,+DAA+D,CAAC,CAAC;AAG1F,aAAO,MAAM;AAEb,YAAM,OAAO,IAAI,IAAI,MAAM,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9C,YAAM,OAAO,IAAI,IAAI,MAAM,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAE9C,YAAM,UAAwB,CAAC;AAC/B,YAAM,UAAwB,CAAC;AAC/B,YAAM,UAA6D,CAAC;AAEpE,iBAAW,CAAC,IAAI,KAAK,KAAK,MAAM;AAC9B,YAAI,CAAC,KAAK,IAAI,EAAE,GAAG;AACjB,kBAAQ,KAAK,KAAK;AAAA,QACpB,OAAO;AACL,gBAAM,QAAQ,KAAK,IAAI,EAAE;AACzB,cAAI,MAAM,mBAAmB,MAAM,gBAAgB;AACjD,oBAAQ,KAAK,EAAE,GAAG,OAAO,GAAG,MAAM,CAAC;AAAA,UACrC;AAAA,QACF;AAAA,MACF;AACA,iBAAW,CAAC,IAAI,KAAK,KAAK,MAAM;AAC9B,YAAI,CAAC,KAAK,IAAI,EAAE,EAAG,SAAQ,KAAK,KAAK;AAAA,MACvC;AAEA,YAAM,QAAQ;AAAA,QACZ,mBAAmB,OAAO,SAAS,OAAO;AAAA;AAAA,QAC1C,YAAY,OAAO,YAAY,OAAO,MAAM,QAAQ,MAAM;AAAA,QAC1D,gBAAgB,OAAO,QAAQ,OAAO,WAAW,QAAQ,MAAM;AAAA,QAC/D,uCAAuC,QAAQ,MAAM;AAAA,QACrD;AAAA,MACF;AAEA,UAAI,QAAQ,SAAS,GAAG;AACtB,cAAM,KAAK,cAAc,KAAK,IAAI,QAAQ,QAAQ,EAAE,CAAC,UAAU;AAC/D,mBAAW,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG;AACpC,gBAAM,KAAK,QAAQ,EAAE,IAAI,OAAO,EAAE,IAAI,aAAQ,EAAE,SAAS,EAAE;AAAA,QAC7D;AACA,YAAI,QAAQ,SAAS,GAAI,OAAM,KAAK,eAAU,QAAQ,SAAS,EAAE,OAAO;AACxE,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,QAAQ,SAAS,GAAG;AACtB,cAAM,KAAK,gBAAgB,KAAK,IAAI,QAAQ,QAAQ,EAAE,CAAC,UAAU;AACjE,mBAAW,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG;AACpC,gBAAM,KAAK,QAAQ,EAAE,IAAI,OAAO,EAAE,IAAI,aAAQ,EAAE,SAAS,EAAE;AAAA,QAC7D;AACA,YAAI,QAAQ,SAAS,GAAI,OAAM,KAAK,eAAU,QAAQ,SAAS,EAAE,OAAO;AACxE,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,QAAQ,SAAS,GAAG;AACtB,cAAM,KAAK,gBAAgB,KAAK,IAAI,QAAQ,QAAQ,EAAE,CAAC,UAAU;AACjE,mBAAW,EAAE,GAAG,EAAE,KAAK,QAAQ,MAAM,GAAG,EAAE,GAAG;AAC3C,gBAAM,KAAK,QAAQ,EAAE,IAAI,OAAO,EAAE,IAAI,OAAO,EAAE,cAAc,WAAM,EAAE,cAAc,EAAE;AAAA,QACvF;AACA,YAAI,QAAQ,SAAS,GAAI,OAAM,KAAK,eAAU,QAAQ,SAAS,EAAE,OAAO;AAAA,MAC1E;AAEA,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,IAEA,KAAK,2BAA2B;AAC9B,YAAM,QAAQ,KAAK;AACnB,YAAM,SAAS,KAAK;AACpB,YAAM,SAAS,OAAO,KAAK,UAAU,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,OAAO,GAAG,CAAC,IAAI;AAEzF,UAAI,CAAC,MAAO,QAAO;AACnB,UAAI,CAAC,OAAQ,QAAO;AAEpB,YAAM,aAAS,oCAAa,aAAa,MAAM;AAC/C,YAAM,KAAK,MAAM,OAAO,IAAI;AAC5B,UAAI,CAAC,GAAG,WAAW,MAAM,GAAG;AAC1B,eAAO,wBAAwB,MAAM,kBAAkB,MAAM;AAAA,2BAA+B,MAAM;AAAA,MACpG;AAEA,YAAM,EAAE,SAAS,KAAM,MAAM,OAAO,mBAAmB,GAAW;AAClE,YAAM,QAAQ,IAAI,SAAS,MAAM;AACjC,YAAM,UAAU,IAAI,KAAK;AACzB,YAAM,OAAO,MAAM;AAAA,QACjB;AAAA,QACA,CAAC,SAAS,SAAS,MAAM;AAAA,MAC3B;AACA,YAAM,MAAM;AAEZ,UAAI,KAAK,WAAW,EAAG,QAAO,wBAAwB,KAAK,sBAAsB,MAAM;AAEvF,YAAM,QAAQ,CAAC,0BAA0B,KAAK,gBAAgB,MAAM,MAAM,KAAK,MAAM;AAAA,CAAW;AAChG,iBAAW,KAAK,MAAM;AACpB,cAAM,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,IAAI,aAAQ,EAAE,SAAS,IAAI,EAAE,UAAU,EAAE;AAAA,MAC3E;AACA,aAAO,MAAM,KAAK,IAAI;AAAA,IACxB;AAAA,IAEA;AACE,aAAO,iBAAiB,QAAQ;AAAA,EACpC;AACF;",
6
+ "names": []
7
+ }