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/handlers/security.ts"],
4
+ "sourcesContent": ["import KiroGraph from '../../index';\nimport { clampLimit, truncate } from './utils';\n\nexport async function handleSecurity(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\n case 'kirograph_security': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n if (!config.enableArchitecture) return 'Security requires architecture analysis. Set enableArchitecture: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n const depCount: { count: number } = rawDb.get(\n `SELECT COUNT(*) as count FROM sec_dependencies`,\n ) ?? { count: 0 };\n\n const vulnCount: { count: number } = rawDb.get(\n `SELECT COUNT(*) as count FROM sec_vulnerabilities`,\n ) ?? { count: 0 };\n\n const verdictRows: Array<{ verdict: string; count: number }> = rawDb.all(\n `SELECT verdict, COUNT(*) as count FROM sec_reachability GROUP BY verdict`,\n );\n const verdicts: Record<string, number> = {};\n for (const row of verdictRows) {\n verdicts[row.verdict] = row.count;\n }\n\n const staleCount: { count: number } = rawDb.get(\n `SELECT COUNT(*) as count FROM sec_dependencies WHERE vuln_data_stale = 1`,\n ) ?? { count: 0 };\n\n // Count suppressed CVEs\n const { SuppressionManager: SecSuppressionManager } = await Promise.resolve().then(() => require('../../security/suppressions.js'));\n const secSuppressions = new SecSuppressionManager(projectRoot);\n const allCveIds: Array<{ cve_id: string }> = rawDb.all(`SELECT cve_id FROM sec_vulnerabilities`);\n const suppressedCveCount = allCveIds.filter(r => secSuppressions.isSuppressed(r.cve_id)).length;\n const visibleVulnCount = vulnCount.count - suppressedCveCount;\n\n const lines: string[] = [\n '# Security Overview',\n '',\n `Dependencies: ${depCount.count}`,\n `Vulnerabilities: ${visibleVulnCount}${suppressedCveCount > 0 ? ` (${suppressedCveCount} suppressed)` : ''}`,\n ];\n\n if (visibleVulnCount > 0) {\n const affected = verdicts['affected'] ?? 0;\n const notAffected = verdicts['not_affected'] ?? 0;\n const underInvestigation = verdicts['under_investigation'] ?? 0;\n const pending = visibleVulnCount - affected - notAffected - underInvestigation;\n\n lines.push('', '## Reachability Verdicts', '');\n if (affected > 0) lines.push(`\u25CF Affected: ${affected}`);\n if (notAffected > 0) lines.push(`\u25CF Not affected: ${notAffected}`);\n if (underInvestigation > 0) lines.push(`\u25CF Under investigation: ${underInvestigation}`);\n if (pending > 0) lines.push(`\u25CF Pending analysis: ${pending}`);\n }\n\n if (staleCount.count > 0) {\n lines.push('', `\u26A0 ${staleCount.count} dependenc${staleCount.count === 1 ? 'y has' : 'ies have'} stale vulnerability data. Use kirograph_vulns with refresh=true to update.`);\n }\n\n // Check if vulnerability data is stale by age\n const lastVulnCheck = (rawDb.get(\n `SELECT MIN(last_vuln_check) as oldest FROM sec_dependencies WHERE last_vuln_check IS NOT NULL`,\n ) as { oldest: number | null } | undefined)?.oldest;\n if (lastVulnCheck != null) {\n const ageMs = Date.now() - lastVulnCheck;\n const ageDays = ageMs / (1000 * 60 * 60 * 24);\n const maxAge = config.securityEnrichMaxAgeDays ?? 7;\n if (ageDays > maxAge) {\n lines.push('', `\u26A0 Vulnerability data is ${Math.floor(ageDays)} days old (max: ${maxAge}). Run kirograph vulns --refresh to update.`);\n }\n }\n\n // Pattern SAST findings count\n try {\n const rawDbSec = db.getRawDb();\n const tableExistsSec = rawDbSec.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExistsSec) {\n const patternCount = rawDbSec.get('SELECT COUNT(*) as cnt FROM pattern_matches')?.cnt ?? 0;\n if (patternCount > 0) {\n const critCount = rawDbSec.get(\"SELECT COUNT(*) as cnt FROM pattern_matches WHERE severity = 'critical'\")?.cnt ?? 0;\n lines.push(`SAST findings: ${patternCount} pattern matches (${critCount} critical)`);\n }\n }\n } catch { /* non-critical */ }\n\n return lines.join('\\n');\n }\n\n case 'kirograph_vulns': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n // Handle refresh\n if (args.refresh === true) {\n const { OsvAdapter } = await Promise.resolve().then(() => require('../../security/vuln/osv-adapter.js'));\n const { VulnerabilityDatabaseClient } = await Promise.resolve().then(() => require('../../security/vuln/client.js'));\n\n const adapters = config.securityDatabases.map((dbName: string) => {\n if (dbName.toUpperCase() === 'OSV') return new OsvAdapter();\n return null;\n }).filter(Boolean) as any[];\n\n const client = new VulnerabilityDatabaseClient(adapters, db);\n await client.enrichAll();\n }\n\n // Build query\n let query = `\n SELECT\n v.node_id, v.cve_id, v.severity_score, v.fixed_version, v.summary,\n v.epss_score, v.epss_percentile, v.risk_score,\n d.package_name, d.ecosystem, d.resolved_version, d.declared_constraint,\n r.verdict\n FROM sec_vulnerabilities v\n LEFT JOIN edges e ON e.target = v.node_id AND e.kind = 'has_vulnerability'\n LEFT JOIN sec_dependencies d ON d.node_id = e.source\n LEFT JOIN sec_reachability r ON r.vulnerability_node_id = v.node_id\n WHERE 1=1\n `;\n const params: any[] = [];\n\n // Severity filter\n if (args.severity) {\n const severityRanges: Record<string, [number, number]> = {\n critical: [9.0, 10.0],\n high: [7.0, 8.9],\n medium: [4.0, 6.9],\n low: [0.1, 3.9],\n };\n const range = severityRanges[(args.severity as string).toLowerCase()];\n if (!range) return `Invalid severity: ${args.severity}. Use: critical, high, medium, low`;\n query += ` AND v.severity_score >= ? AND v.severity_score <= ?`;\n params.push(range[0], range[1]);\n }\n\n // Verdict filter\n if (args.verdict) {\n const validVerdicts = ['affected', 'not_affected', 'under_investigation'];\n if (!validVerdicts.includes(args.verdict as string)) {\n return `Invalid verdict: ${args.verdict}. Use: affected, not_affected, under_investigation`;\n }\n query += ` AND r.verdict = ?`;\n params.push(args.verdict);\n }\n\n const limit = clampLimit(args.limit as number | undefined, 20);\n query += ` ORDER BY v.risk_score DESC NULLS LAST LIMIT ?`;\n params.push(limit);\n\n const rows: Array<{\n node_id: string;\n cve_id: string;\n severity_score: number | null;\n fixed_version: string | null;\n summary: string | null;\n epss_score: number | null;\n epss_percentile: number | null;\n risk_score: number | null;\n package_name: string | null;\n ecosystem: string | null;\n resolved_version: string | null;\n declared_constraint: string | null;\n verdict: string | null;\n }> = rawDb.all(query, params);\n\n // Deduplicate by (cve_id, package_name, ecosystem) \u2014 same CVE can appear multiple\n // times when a package is declared in multiple manifests (monorepo).\n const verdictRankMcp = (v: string | null) =>\n v === 'affected' ? 3 : v === 'under_investigation' ? 2 : v === 'not_affected' ? 1 : 0;\n const dedupMapMcp = new Map<string, typeof rows[0]>();\n for (const row of rows) {\n const key = `${row.cve_id}::${row.package_name ?? ''}::${row.ecosystem ?? ''}`;\n const ex = dedupMapMcp.get(key);\n if (!ex || verdictRankMcp(row.verdict) > verdictRankMcp(ex.verdict)) dedupMapMcp.set(key, row);\n }\n const dedupedRowsMcp = [...dedupMapMcp.values()];\n\n // Filter out suppressed CVEs\n const { SuppressionManager } = await Promise.resolve().then(() => require('../../security/suppressions.js'));\n const suppressionMgr = new SuppressionManager(projectRoot);\n const suppressedCount = dedupedRowsMcp.filter(row => suppressionMgr.isSuppressed(row.cve_id)).length;\n const filteredRows = dedupedRowsMcp.filter(row => !suppressionMgr.isSuppressed(row.cve_id));\n\n if (filteredRows.length === 0) {\n const noMatch = 'No vulnerabilities found' + ((args.severity || args.verdict) ? ' matching filters.' : '.');\n return suppressedCount > 0 ? `${noMatch} (${suppressedCount} suppressed)` : noMatch;\n }\n\n const { formatFixSuggestion } = await Promise.resolve().then(() => require('../../security/export/fix-suggestions.js'));\n\n const lines: string[] = [`Vulnerabilities (${filteredRows.length}${suppressedCount > 0 ? `, ${suppressedCount} suppressed` : ''}):\\n`];\n\n for (const row of filteredRows) {\n const score = row.severity_score;\n let severityLabel: string;\n if (score == null) severityLabel = 'UNKNOWN';\n else if (score >= 9.0) severityLabel = 'CRITICAL';\n else if (score >= 7.0) severityLabel = 'HIGH';\n else if (score >= 4.0) severityLabel = 'MEDIUM';\n else severityLabel = 'LOW';\n\n let verdictLabel: string;\n if (!row.verdict) verdictLabel = 'pending';\n else if (row.verdict === 'affected') verdictLabel = 'affected';\n else if (row.verdict === 'not_affected') verdictLabel = 'not affected';\n else verdictLabel = 'investigating';\n\n const pkg = row.package_name\n ? `${row.package_name}@${row.resolved_version || row.declared_constraint || '?'}`\n : 'unknown package';\n\n const epssNote = row.epss_score != null\n ? ` [EPSS: ${row.epss_score.toFixed(2)}]`\n : '';\n const riskNote = row.risk_score != null\n ? ` [Risk: ${row.risk_score.toFixed(1)}]`\n : '';\n lines.push(`${severityLabel} ${row.cve_id} ${pkg} [${verdictLabel}]${epssNote}${riskNote}`);\n\n if (row.summary && row.summary !== 'Manually registered') {\n const truncSummary = row.summary.length > 120 ? row.summary.slice(0, 120) + '\u2026' : row.summary;\n lines.push(` ${truncSummary}`);\n }\n\n if (row.fixed_version && row.ecosystem && row.package_name) {\n const fix = formatFixSuggestion(row.ecosystem, row.package_name, row.fixed_version);\n if (fix) lines.push(` ${fix}`);\n }\n }\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_vuln_add': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const cveId = args.cveId as string;\n const pkgName = args.package as string;\n if (!cveId) return 'Error: cveId is required.';\n if (!pkgName) return 'Error: package is required.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n // Find matching Dependency_Node\n const depRow: { node_id: string; ecosystem: string } | undefined = rawDb.get(\n `SELECT node_id, ecosystem FROM sec_dependencies WHERE package_name = ?`,\n [pkgName],\n );\n\n if (!depRow) {\n return `No dependency found matching \"${pkgName}\". Run kirograph index first to discover dependencies.`;\n }\n\n // Create Vulnerability_Node\n const vulnNodeId = `vuln:${cveId}`;\n const now = Date.now();\n const severity = args.severity as number | undefined;\n const summary = (args.summary as string) ?? 'Manually registered';\n const fixedVersion = (args.fixedVersion as string) ?? null;\n\n rawDb.run(\n `INSERT OR REPLACE INTO nodes\n (id, kind, name, qualified_name, file_path, language,\n start_line, end_line, start_column, end_column,\n is_exported, is_async, is_static, is_abstract, updated_at)\n VALUES (?, 'vulnerability', ?, ?, '', 'unknown', 0, 0, 0, 0, 0, 0, 0, 0, ?)`,\n [vulnNodeId, cveId, cveId, now],\n );\n\n rawDb.run(\n `INSERT OR REPLACE INTO sec_vulnerabilities\n (node_id, cve_id, severity_score, affected_ranges, fixed_version, summary, source_database)\n VALUES (?, ?, ?, '[]', ?, ?, 'manual')`,\n [vulnNodeId, cveId, severity ?? null, fixedVersion, summary],\n );\n\n // Create has_vulnerability edge\n rawDb.run(\n `INSERT OR IGNORE INTO edges (source, target, kind, confidence, confidence_score)\n VALUES (?, ?, 'has_vulnerability', 'extracted', 1.0)`,\n [depRow.node_id, vulnNodeId],\n );\n\n return `Registered ${cveId} against ${pkgName}.`;\n }\n\n case 'kirograph_vuln_suppress': {\n const projectRoot = cg.getProjectRoot();\n const cveId = args.cveId as string;\n if (!cveId) return 'Error: cveId is required.';\n\n const { SuppressionManager } = await Promise.resolve().then(() => require('../../security/suppressions.js'));\n const manager = new SuppressionManager(projectRoot);\n manager.add(cveId, args.reason as string | undefined, args.expires as string | undefined);\n\n const reasonNote = args.reason ? ` Reason: ${args.reason}.` : '';\n const expiresNote = args.expires ? ` Expires: ${args.expires}.` : '';\n return `${cveId} suppressed.${reasonNote}${expiresNote}`;\n }\n\n case 'kirograph_sbom': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { SBOMExporter } = await Promise.resolve().then(() => require('../../security/export/sbom.js'));\n const exporter = new SBOMExporter(db, projectRoot);\n const json = exporter.exportJSON();\n\n return truncate(json);\n }\n\n case 'kirograph_vex': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { VEXExporter } = await Promise.resolve().then(() => require('../../security/export/vex.js'));\n const exporter = new VEXExporter(db, projectRoot);\n const json = exporter.exportJSON();\n\n return truncate(json);\n }\n\n case 'kirograph_reachability': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const target = args.target as string;\n if (!target) return 'Error: target is required (dependency name or CVE ID).';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n // Try to find target as a CVE ID in sec_vulnerabilities\n let vulnerabilityNodeId: string | null = null;\n let targetLabel = target;\n\n const vulnRow: { node_id: string } | undefined = rawDb.get(\n `SELECT node_id FROM sec_vulnerabilities WHERE cve_id = ?`,\n [target],\n );\n\n if (vulnRow) {\n vulnerabilityNodeId = vulnRow.node_id;\n } else {\n // Try to find target as a dependency name\n const depRow: { node_id: string; package_name: string } | undefined = rawDb.get(\n `SELECT node_id, package_name FROM sec_dependencies WHERE package_name = ?`,\n [target],\n );\n\n if (depRow) {\n targetLabel = depRow.package_name;\n // Find vulnerabilities linked to this dependency\n const vulnEdge: { target: string } | undefined = rawDb.get(\n `SELECT target FROM edges WHERE source = ? AND kind = 'has_vulnerability' LIMIT 1`,\n [depRow.node_id],\n );\n\n if (vulnEdge) {\n vulnerabilityNodeId = vulnEdge.target;\n } else {\n return `No vulnerabilities found for dependency \"${target}\". The dependency exists but has no known vulnerabilities.`;\n }\n } else {\n return `Target \"${target}\" not found. Provide a valid CVE ID or dependency package name.`;\n }\n }\n\n // Run reachability analysis\n const { ReachabilityAnalyzer } = await Promise.resolve().then(() => require('../../security/reachability.js'));\n const analyzer = new ReachabilityAnalyzer(db, config);\n const result = await analyzer.analyze(vulnerabilityNodeId);\n\n const lines: string[] = [\n `# Reachability: ${targetLabel}`,\n '',\n `Verdict: ${result.verdict}`,\n `Reaching entry points: ${result.reachingEntryPointCount}`,\n ];\n\n if (result.paths.length > 0) {\n lines.push('', '## Paths');\n for (const p of result.paths.slice(0, 5)) {\n lines.push(`- From ${p.entryPoint}: ${p.path.join(' \u2192 ')}`);\n }\n if (result.paths.length > 5) {\n lines.push(` \u2026and ${result.paths.length - 5} more paths`);\n }\n }\n\n if (result.unresolvedSymbols.length > 0) {\n lines.push('', '## Unresolved Symbols');\n for (const sym of result.unresolvedSymbols.slice(0, 10)) {\n lines.push(`- ${sym}`);\n }\n if (result.unresolvedSymbols.length > 10) {\n lines.push(` \u2026and ${result.unresolvedSymbols.length - 10} more`);\n }\n }\n\n // Get impact summary if affected\n if (result.verdict === 'affected') {\n const impact = await analyzer.getImpactSummary(vulnerabilityNodeId);\n if (impact) {\n lines.push('', '## Impact Summary');\n if (impact.affectedLayers.length > 0) {\n lines.push(`Affected layers: ${impact.affectedLayers.join(', ')}`);\n }\n lines.push(`Affected entry points: ${impact.affectedEntryPoints.length}`);\n lines.push(`Distinct paths: ${impact.distinctPathCount}`);\n }\n }\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_staleness': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n const threshold = typeof args.threshold === 'number' ? args.threshold : 0.3;\n\n // Optionally refresh staleness data from registries\n if (args.refresh === true) {\n const { StalenessChecker } = await Promise.resolve().then(() => require('../../security/staleness.js'));\n const checker = new StalenessChecker(db);\n await checker.checkAll();\n }\n\n const rows: Array<{\n package_name: string;\n ecosystem: string;\n resolved_version: string | null;\n declared_constraint: string;\n latest_version: string | null;\n latest_published: number | null;\n staleness_score: number | null;\n }> = rawDb.all(\n `SELECT package_name, ecosystem, resolved_version, declared_constraint,\n latest_version, latest_published, staleness_score\n FROM sec_dependencies\n WHERE staleness_score >= ?\n ORDER BY staleness_score DESC`,\n [threshold],\n );\n\n if (rows.length === 0) {\n return `No dependencies found with staleness_score >= ${threshold}.` +\n (args.refresh ? '' : ' Use refresh=true to fetch latest version data from registries.');\n }\n\n const lines: string[] = [`Stale Dependencies (threshold: ${threshold}):\\n`];\n for (const row of rows) {\n const resolved = row.resolved_version ?? row.declared_constraint ?? '?';\n const latest = row.latest_version ?? '?';\n const score = row.staleness_score ?? 0;\n const months = row.latest_published\n ? Math.round((Date.now() - row.latest_published) / (1000 * 60 * 60 * 24 * 30))\n : null;\n const bar = '\u2588'.repeat(Math.round(score * 10)) + '\u2591'.repeat(10 - Math.round(score * 10));\n const monthsStr = months !== null ? `, ${months}mo since latest` : '';\n lines.push(`${row.package_name} (${row.ecosystem}): ${resolved} \u2192 ${latest}${monthsStr}`);\n lines.push(` ${bar} ${score.toFixed(2)}`);\n }\n\n const totalCount: { count: number } = rawDb.get(`SELECT COUNT(*) as count FROM sec_dependencies`) ?? { count: 0 };\n lines.push('', `${rows.length} of ${totalCount.count} dependencies are stale (score >= ${threshold})`);\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_licenses': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n const deps: Array<{\n package_name: string;\n ecosystem: string;\n license: string | null;\n }> = rawDb.all(\n `SELECT package_name, ecosystem, license FROM sec_dependencies ORDER BY ecosystem, package_name`,\n );\n\n const { checkLicensePolicy } = await Promise.resolve().then(() => require('../../security/license.js'));\n const policy = config.securityLicensePolicy;\n const violations = checkLicensePolicy(deps, policy);\n\n if (args.policy === true) {\n // Return only violations\n if (violations.length === 0) {\n return 'No license policy violations found.';\n }\n const lines: string[] = ['# License Policy Violations\\n'];\n for (const v of violations) {\n lines.push(`${v.severity.toUpperCase()} ${v.packageName} [${v.ecosystem}] ${v.license}`);\n }\n const denyCount = violations.filter(v => v.severity === 'deny').length;\n const warnCount = violations.filter(v => v.severity === 'warn').length;\n lines.push('');\n if (denyCount > 0) lines.push(`${denyCount} denied license${denyCount !== 1 ? 's' : ''}`);\n if (warnCount > 0) lines.push(`${warnCount} license warning${warnCount !== 1 ? 's' : ''}`);\n return truncate(lines.join('\\n'));\n }\n\n // Full listing\n if (deps.length === 0) {\n return 'No dependencies found. Run kirograph index first.';\n }\n\n const violationMap = new Map<string, 'deny' | 'warn'>();\n for (const v of violations) {\n violationMap.set(`${v.ecosystem}:${v.packageName}`, v.severity);\n }\n\n const lines: string[] = [`# License Report (${deps.length} dependencies)\\n`];\n\n // Violations first\n if (violations.length > 0) {\n lines.push('## Policy Violations\\n');\n for (const v of violations) {\n lines.push(`${v.severity.toUpperCase()} ${v.packageName} [${v.ecosystem}] ${v.license}`);\n }\n lines.push('');\n }\n\n lines.push('## All Dependencies\\n');\n lines.push('package | ecosystem | license | status');\n lines.push('------- | --------- | ------- | ------');\n\n for (const dep of deps) {\n const key = `${dep.ecosystem}:${dep.package_name}`;\n const violation = violationMap.get(key);\n const license = dep.license ?? '(unknown)';\n const status = violation ?? (dep.license ? 'ok' : 'unknown');\n lines.push(`${dep.package_name} | ${dep.ecosystem} | ${license} | ${status}`);\n }\n\n const denyCount = violations.filter(v => v.severity === 'deny').length;\n const warnCount = violations.filter(v => v.severity === 'warn').length;\n const unknownCount = deps.filter(d => !d.license).length;\n\n lines.push('');\n if (denyCount > 0) lines.push(`${denyCount} denied license${denyCount !== 1 ? 's' : ''}`);\n if (warnCount > 0) lines.push(`${warnCount} license warning${warnCount !== 1 ? 's' : ''}`);\n if (unknownCount > 0) lines.push(`${unknownCount} unknown license${unknownCount !== 1 ? 's' : ''}`);\n if (denyCount === 0 && warnCount === 0) lines.push('No policy violations');\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_attack_surface': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { AttackSurfaceAnalyzer } = await Promise.resolve().then(() => require('../../security/attack-surface.js'));\n const analyzer = new AttackSurfaceAnalyzer(db);\n const result = await analyzer.analyze();\n\n if (result.totalRoutes === 0) {\n return 'No route nodes found in the graph. Ensure the project has been indexed with architecture analysis enabled.';\n }\n\n const limit = clampLimit(args.limit as number | undefined, 20);\n const routes = (args.publicOnly === true)\n ? result.criticalPaths.filter(r => r.exposureLevel === 'public')\n : result.criticalPaths;\n\n const lines: string[] = [\n '# Attack Surface',\n '',\n `Total routes: ${result.totalRoutes} Public: ${result.publicRoutes} Authenticated: ${result.authenticatedRoutes} Routes with vulns: ${result.routesWithVulns}`,\n '',\n ];\n\n const displayed = routes.slice(0, limit);\n if (displayed.length === 0) {\n lines.push(args.publicOnly === true\n ? 'No public routes with vulnerable dependencies found.'\n : 'No routes with vulnerable dependencies found.');\n } else {\n for (const entry of displayed) {\n const authTag = entry.isAuthenticated ? '[auth]' : '[public]';\n const riskTag = entry.riskScore > 0 ? ` risk=${entry.riskScore.toFixed(1)}` : '';\n lines.push(`${authTag} ${entry.route} (${entry.exposureLevel})${riskTag} ${entry.filePath}`);\n for (const dep of entry.vulnerableDeps.slice(0, 3)) {\n lines.push(` \u2514 ${dep.cveId} via ${dep.packageName} (${dep.hopCount} hop${dep.hopCount !== 1 ? 's' : ''}${dep.verdict ? `, ${dep.verdict}` : ''})`);\n }\n if (entry.vulnerableDeps.length > 3) {\n lines.push(` \u2514 \u2026and ${entry.vulnerableDeps.length - 3} more vulns`);\n }\n }\n if (routes.length > limit) {\n lines.push('', `\u2026and ${routes.length - limit} more routes (increase limit to see all)`);\n }\n }\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_secrets': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { SecretsScanner } = await Promise.resolve().then(() => require('../../security/secrets.js'));\n const scanner = new SecretsScanner(db, projectRoot);\n const result = await scanner.scan({ includeTests: args.includeTests === true });\n\n if (result.totalFindings === 0) {\n return `No secrets found. Scanned ${result.filesScanned} file${result.filesScanned !== 1 ? 's' : ''}.`;\n }\n\n let findings = result.findings;\n if (args.severity) {\n findings = findings.filter(f => f.severity === (args.severity as string));\n }\n\n if (findings.length === 0) {\n return `No secrets found matching severity \"${args.severity}\". Total findings (all severities): ${result.totalFindings}.`;\n }\n\n const lines: string[] = [\n `# Secrets Scan (${result.filesScanned} files scanned)`,\n '',\n `Found: ${result.totalFindings} Critical: ${result.criticalCount} High: ${result.highCount}`,\n '',\n ];\n\n for (const f of findings) {\n lines.push(`${f.severity.toUpperCase()} ${f.type}`);\n lines.push(` ${f.filePath}:${f.line}:${f.column} snippet: ${f.snippet}`);\n if (f.nodeName) {\n lines.push(` in function: ${f.nodeName}`);\n }\n if (f.entryPointCount > 0) {\n lines.push(` reachable from ${f.entryPointCount} entry point${f.entryPointCount !== 1 ? 's' : ''}`);\n }\n }\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_security_flows': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { DataFlowAnalyzer } = await Promise.resolve().then(() => require('../../security/data-flows.js'));\n const analyzer = new DataFlowAnalyzer(db);\n let findings = await analyzer.analyze();\n\n const typeFilter = (args.type as string | undefined) ?? 'all';\n const TYPE_MAP: Record<string, string> = {\n sql: 'sql-injection',\n eval: 'dangerous-eval',\n deserialize: 'unsafe-deserialize',\n path: 'path-traversal',\n crypto: 'hardcoded-crypto',\n };\n\n if (typeFilter !== 'all') {\n const mapped = TYPE_MAP[typeFilter];\n if (!mapped) return `Invalid type filter \"${typeFilter}\". Use: sql, eval, deserialize, path, crypto, all`;\n findings = findings.filter(f => f.type === mapped);\n }\n\n if (findings.length === 0) {\n return typeFilter === 'all'\n ? 'No dangerous data flows detected.'\n : `No \"${typeFilter}\" findings detected.`;\n }\n\n const lines: string[] = [\n `# Security Flows (${findings.length} finding${findings.length !== 1 ? 's' : ''})`,\n '',\n ];\n\n for (const f of findings) {\n lines.push(`${f.severity.toUpperCase()} [${f.owaspCategory}] ${f.type}`);\n lines.push(` ${f.filePath}:${f.line} symbol: ${f.symbol}`);\n lines.push(` ${f.description}`);\n lines.push(` Fix: ${f.recommendation}`);\n lines.push('');\n }\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_supply_chain': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { SupplyChainChecker } = await Promise.resolve().then(() => require('../../security/supply-chain.js'));\n const checker = new SupplyChainChecker(db);\n const { results, errors } = await checker.checkAll();\n\n const RISK_ORDER: Record<string, number> = { critical: 0, high: 1, medium: 2, low: 3, unknown: 4 };\n const thresholdArg = args.threshold as string | undefined;\n const thresholdOrder = thresholdArg ? (RISK_ORDER[thresholdArg] ?? 4) : 2; // default: medium and above\n\n const filtered = results\n .filter(r => (RISK_ORDER[r.riskLevel] ?? 4) <= thresholdOrder)\n .sort((a, b) => (RISK_ORDER[a.riskLevel] ?? 4) - (RISK_ORDER[b.riskLevel] ?? 4));\n\n if (filtered.length === 0) {\n return `No supply chain risks found at threshold \"${thresholdArg ?? 'medium'}\" or above. Checked ${results.length} dependencies.`;\n }\n\n const lines: string[] = [\n `# Supply Chain Health (${filtered.length} risks, threshold: ${thresholdArg ?? 'medium'})`,\n '',\n ];\n\n for (const r of filtered) {\n const scoreStr = r.scorecardScore !== null ? ` scorecard=${r.scorecardScore.toFixed(1)}/10` : '';\n const maintainerStr = r.maintainerCount !== null ? ` maintainers=${r.maintainerCount}` : '';\n lines.push(`${r.riskLevel.toUpperCase()} ${r.packageName} (${r.ecosystem})${scoreStr}${maintainerStr}`);\n for (const reason of r.riskReasons) {\n lines.push(` \u2022 ${reason}`);\n }\n }\n\n if (errors.length > 0) {\n lines.push('', `\u26A0 ${errors.length} package${errors.length !== 1 ? 's' : ''} could not be checked (network errors)`);\n }\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_dep_confusion': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { DepConfusionChecker } = await Promise.resolve().then(() => require('../../security/dep-confusion.js'));\n const checker = new DepConfusionChecker(db);\n const findings = await checker.check();\n\n if (findings.length === 0) {\n return 'No dependency confusion vulnerabilities detected.';\n }\n\n const RISK_ORDER: Record<string, number> = { critical: 0, high: 1, medium: 2 };\n const sorted = [...findings].sort((a, b) => (RISK_ORDER[a.riskLevel] ?? 3) - (RISK_ORDER[b.riskLevel] ?? 3));\n\n const lines: string[] = [\n `# Dependency Confusion (${findings.length} finding${findings.length !== 1 ? 's' : ''})`,\n '',\n ];\n\n for (const f of sorted) {\n lines.push(`${f.riskLevel.toUpperCase()} ${f.packageName} (${f.ecosystem})`);\n lines.push(` ${f.explanation}`);\n if (f.publicExists && f.publicVersion) {\n lines.push(` Public version: ${f.publicVersion}${f.publicPublishedAt ? ` published: ${f.publicPublishedAt}` : ''}`);\n }\n }\n\n return truncate(lines.join('\\n'));\n }\n\n case 'kirograph_remediation': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableSecurity) return 'Security analysis is not enabled. Set enableSecurity: true in .kirograph/config.json and run kirograph index.';\n\n const db = cg.getDatabase();\n db.applySecuritySchema();\n\n const { RemediationTracker } = await Promise.resolve().then(() => require('../../security/remediation.js'));\n const tracker = new RemediationTracker(db);\n let statuses = tracker.getStatus();\n\n if (args.overdueOnly === true) {\n statuses = statuses.filter(s => s.isOverdue);\n }\n\n if (statuses.length === 0) {\n return args.overdueOnly === true\n ? 'No overdue vulnerabilities found.'\n : 'No open vulnerabilities with SLA tracking data found.';\n }\n\n // Sort: overdue first, then by slaStatus, then by severity desc\n const SLA_ORDER: Record<string, number> = { overdue: 0, warning: 1, no_fix: 2, ok: 3 };\n statuses.sort((a, b) => {\n const slaA = SLA_ORDER[a.slaStatus] ?? 3;\n const slaB = SLA_ORDER[b.slaStatus] ?? 3;\n if (slaA !== slaB) return slaA - slaB;\n return (b.severity ?? 0) - (a.severity ?? 0);\n });\n\n const overdueCount = statuses.filter(s => s.isOverdue).length;\n const warningCount = statuses.filter(s => s.slaStatus === 'warning').length;\n\n const lines: string[] = [\n `# Remediation SLA (${statuses.length} open${overdueCount > 0 ? `, ${overdueCount} overdue` : ''}${warningCount > 0 ? `, ${warningCount} warning` : ''})`,\n '',\n ];\n\n for (const s of statuses) {\n const severityLabel = s.severity == null ? 'UNKNOWN'\n : s.severity >= 9 ? 'CRITICAL'\n : s.severity >= 7 ? 'HIGH'\n : s.severity >= 4 ? 'MEDIUM'\n : 'LOW';\n\n const slaTag = s.slaStatus === 'overdue' ? '[OVERDUE]'\n : s.slaStatus === 'warning' ? '[WARNING]'\n : s.slaStatus === 'no_fix' ? '[NO_FIX]'\n : '[OK]';\n\n lines.push(`${slaTag} ${severityLabel} ${s.cveId} ${s.packageName}`);\n if (s.daysOpen !== null) lines.push(` Open for ${s.daysOpen} day${s.daysOpen !== 1 ? 's' : ''}`);\n if (s.daysWithFixAvailable !== null) lines.push(` Fix available for ${s.daysWithFixAvailable} day${s.daysWithFixAvailable !== 1 ? 's' : ''}`);\n if (s.slaDeadline !== null) {\n const deadlineDate = new Date(s.slaDeadline).toISOString().slice(0, 10);\n lines.push(` SLA deadline: ${deadlineDate}`);\n }\n }\n\n return truncate(lines.join('\\n'));\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["lines", "denyCount", "warnCount"]
7
+ }
@@ -0,0 +1,97 @@
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 utils_exports = {};
30
+ __export(utils_exports, {
31
+ MAX_OUTPUT: () => MAX_OUTPUT,
32
+ clampLimit: () => clampLimit,
33
+ estimateFileTokens: () => estimateFileTokens,
34
+ formatAge: () => formatAge,
35
+ mapKind: () => mapKind,
36
+ truncate: () => truncate,
37
+ writeSessionMarker: () => writeSessionMarker
38
+ });
39
+ module.exports = __toCommonJS(utils_exports);
40
+ var fs = __toESM(require("fs"));
41
+ var path = __toESM(require("path"));
42
+ var crypto = __toESM(require("crypto"));
43
+ const MAX_OUTPUT = 15e3;
44
+ function truncate(s) {
45
+ return s.length > MAX_OUTPUT ? s.slice(0, MAX_OUTPUT) + "\n\u2026[truncated]" : s;
46
+ }
47
+ function estimateFileTokens(projectRoot, filePaths) {
48
+ let total = 0;
49
+ for (const fp of filePaths) {
50
+ try {
51
+ const fullPath = path.isAbsolute(fp) ? fp : path.join(projectRoot, fp);
52
+ const stat = fs.statSync(fullPath);
53
+ total += Math.round(stat.size / 4);
54
+ } catch {
55
+ }
56
+ }
57
+ return total;
58
+ }
59
+ function clampLimit(value, defaultValue) {
60
+ const n = typeof value === "number" ? value : defaultValue;
61
+ return Math.max(1, Math.min(100, Math.round(n)));
62
+ }
63
+ function mapKind(kind) {
64
+ if (kind === "type_alias") return "type";
65
+ return kind;
66
+ }
67
+ function writeSessionMarker(projectRoot) {
68
+ try {
69
+ const hash = crypto.createHash("sha256").update(projectRoot).digest("hex").slice(0, 16);
70
+ fs.writeFileSync(`/tmp/kirograph-consulted-${hash}`, String(Date.now()));
71
+ } catch {
72
+ }
73
+ }
74
+ function formatAge(timestamp) {
75
+ const diff = Date.now() - timestamp;
76
+ const minutes = Math.floor(diff / 6e4);
77
+ if (minutes < 60) return `${minutes}m ago`;
78
+ const hours = Math.floor(minutes / 60);
79
+ if (hours < 24) return `${hours}h ago`;
80
+ const days = Math.floor(hours / 24);
81
+ if (days < 7) return `${days}d ago`;
82
+ const weeks = Math.floor(days / 7);
83
+ if (weeks < 5) return `${weeks}w ago`;
84
+ const months = Math.floor(days / 30);
85
+ return `${months}mo ago`;
86
+ }
87
+ // Annotate the CommonJS export names for ESM import in node:
88
+ 0 && (module.exports = {
89
+ MAX_OUTPUT,
90
+ clampLimit,
91
+ estimateFileTokens,
92
+ formatAge,
93
+ mapKind,
94
+ truncate,
95
+ writeSessionMarker
96
+ });
97
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/handlers/utils.ts"],
4
+ "sourcesContent": ["import * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\n\nexport const MAX_OUTPUT = 15_000;\n\nexport function truncate(s: string): string {\n return s.length > MAX_OUTPUT ? s.slice(0, MAX_OUTPUT) + '\\n\u2026[truncated]' : s;\n}\n\n/** Estimate how many tokens reading the full files would cost (chars / 4 heuristic). */\nexport function estimateFileTokens(projectRoot: string, filePaths: string[]): number {\n let total = 0;\n for (const fp of filePaths) {\n try {\n const fullPath = path.isAbsolute(fp) ? fp : path.join(projectRoot, fp);\n const stat = fs.statSync(fullPath);\n total += Math.round(stat.size / 4);\n } catch {\n // File may not exist or be unreadable \u2014 skip\n }\n }\n return total;\n}\n\nexport function clampLimit(value: number | undefined, defaultValue: number): number {\n const n = typeof value === 'number' ? value : defaultValue;\n return Math.max(1, Math.min(100, Math.round(n)));\n}\n\n/** Map internal kind values to human-readable MCP response kinds. */\nexport function mapKind(kind: string): string {\n if (kind === 'type_alias') return 'type';\n return kind;\n}\n\n/** Write a session marker so hooks can detect MCP was consulted. */\nexport function writeSessionMarker(projectRoot: string): void {\n try {\n const hash = crypto.createHash('sha256').update(projectRoot).digest('hex').slice(0, 16);\n fs.writeFileSync(`/tmp/kirograph-consulted-${hash}`, String(Date.now()));\n } catch { /* best-effort */ }\n}\n\n/** Format a timestamp as a human-readable relative age. */\nexport function formatAge(timestamp: number): string {\n const diff = Date.now() - timestamp;\n const minutes = Math.floor(diff / 60000);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n if (days < 7) return `${days}d ago`;\n const weeks = Math.floor(days / 7);\n if (weeks < 5) return `${weeks}w ago`;\n const months = Math.floor(days / 30);\n return `${months}mo ago`;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAoB;AACpB,WAAsB;AACtB,aAAwB;AAEjB,MAAM,aAAa;AAEnB,SAAS,SAAS,GAAmB;AAC1C,SAAO,EAAE,SAAS,aAAa,EAAE,MAAM,GAAG,UAAU,IAAI,wBAAmB;AAC7E;AAGO,SAAS,mBAAmB,aAAqB,WAA6B;AACnF,MAAI,QAAQ;AACZ,aAAW,MAAM,WAAW;AAC1B,QAAI;AACF,YAAM,WAAW,KAAK,WAAW,EAAE,IAAI,KAAK,KAAK,KAAK,aAAa,EAAE;AACrE,YAAM,OAAO,GAAG,SAAS,QAAQ;AACjC,eAAS,KAAK,MAAM,KAAK,OAAO,CAAC;AAAA,IACnC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,WAAW,OAA2B,cAA8B;AAClF,QAAM,IAAI,OAAO,UAAU,WAAW,QAAQ;AAC9C,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC;AACjD;AAGO,SAAS,QAAQ,MAAsB;AAC5C,MAAI,SAAS,aAAc,QAAO;AAClC,SAAO;AACT;AAGO,SAAS,mBAAmB,aAA2B;AAC5D,MAAI;AACF,UAAM,OAAO,OAAO,WAAW,QAAQ,EAAE,OAAO,WAAW,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AACtF,OAAG,cAAc,4BAA4B,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC;AAAA,EACzE,QAAQ;AAAA,EAAoB;AAC9B;AAGO,SAAS,UAAU,WAA2B;AACnD,QAAM,OAAO,KAAK,IAAI,IAAI;AAC1B,QAAM,UAAU,KAAK,MAAM,OAAO,GAAK;AACvC,MAAI,UAAU,GAAI,QAAO,GAAG,OAAO;AACnC,QAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,MAAI,QAAQ,GAAI,QAAO,GAAG,KAAK;AAC/B,QAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,MAAI,OAAO,EAAG,QAAO,GAAG,IAAI;AAC5B,QAAM,QAAQ,KAAK,MAAM,OAAO,CAAC;AACjC,MAAI,QAAQ,EAAG,QAAO,GAAG,KAAK;AAC9B,QAAM,SAAS,KAAK,MAAM,OAAO,EAAE;AACnC,SAAO,GAAG,MAAM;AAClB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,104 @@
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 watchmen_exports = {};
20
+ __export(watchmen_exports, {
21
+ handleWatchmen: () => handleWatchmen
22
+ });
23
+ module.exports = __toCommonJS(watchmen_exports);
24
+ async function handleWatchmen(toolName, args, cg) {
25
+ switch (toolName) {
26
+ case "kirograph_watchmen_status": {
27
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
28
+ const projectRoot = args.projectPath ?? cg.getProjectRoot();
29
+ const config = await loadConfig(projectRoot);
30
+ if (!config.enableMemory) return "Memory is not enabled. Set enableMemory: true in .kirograph/config.json";
31
+ if (!config.enableWatchmen) return "Watchmen is not enabled. Set enableWatchmen: true in .kirograph/config.json";
32
+ const { WatchmenChecker } = await Promise.resolve().then(() => require("../../watchmen/index.js"));
33
+ const { MemoryDatabase } = await Promise.resolve().then(() => require("../../memory/database.js"));
34
+ const db = cg.getDatabase();
35
+ db.applyMemorySchema();
36
+ const memDb = new MemoryDatabase(db.getRawDb());
37
+ memDb.initialize();
38
+ const checker = new WatchmenChecker(config.watchmenThreshold);
39
+ const { ready, pendingCount } = checker.shouldSynthesize(memDb);
40
+ const { targetFiles } = checker.buildReadyResponse("", pendingCount, projectRoot);
41
+ const statusLines = [
42
+ `Watchmen Status:`,
43
+ ` Pending observations: ${pendingCount} / ${config.watchmenThreshold} threshold`,
44
+ ` Ready to synthesize: ${ready ? "yes" : "no"}`,
45
+ ` Target files:`
46
+ ];
47
+ for (const f of targetFiles) statusLines.push(` \xB7 ${f}`);
48
+ return statusLines.join("\n");
49
+ }
50
+ case "kirograph_watchmen_synthesize": {
51
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
52
+ const projectRoot = args.projectPath ?? cg.getProjectRoot();
53
+ const config = await loadConfig(projectRoot);
54
+ if (!config.enableMemory || !config.enableWatchmen) return "Watchmen is not enabled (enableMemory + enableWatchmen required).";
55
+ if (config.watchmenSynthesisMode !== "local") return 'watchmenSynthesisMode is not "local" \u2014 use the agent hook instead.';
56
+ const { WatchmenChecker } = await Promise.resolve().then(() => require("../../watchmen/index.js"));
57
+ const { MemoryDatabase } = await Promise.resolve().then(() => require("../../memory/database.js"));
58
+ const { runLocalSynthesis } = await Promise.resolve().then(() => require("../../watchmen/synthesize.js"));
59
+ const { MemoryManager } = await Promise.resolve().then(() => require("../../memory/index.js"));
60
+ const db = cg.getDatabase();
61
+ db.applyMemorySchema();
62
+ const memDb = new MemoryDatabase(db.getRawDb());
63
+ memDb.initialize();
64
+ const checker = new WatchmenChecker(config.watchmenThreshold);
65
+ const { ready, pendingCount } = checker.shouldSynthesize(memDb);
66
+ if (!ready && !args.force) {
67
+ return `Watchmen: ${pendingCount}/${config.watchmenThreshold} observations \u2014 threshold not reached. Pass force: true to run anyway.`;
68
+ }
69
+ const observations = memDb.getObservationsSinceLastSummary(50);
70
+ if (observations.length === 0) return "No observations to synthesize.";
71
+ const readyResult = checker.buildReadyResponse("", pendingCount, projectRoot);
72
+ const result = await runLocalSynthesis(observations, readyResult, config.watchmenLocalModel, projectRoot, true);
73
+ const mgr = new MemoryManager(config, db.getRawDb(), projectRoot);
74
+ mgr.initialize();
75
+ await mgr.store({ content: result.summaryObservation, kind: "summary", source: "agent" });
76
+ const synthLines = [`Watchmen synthesis complete.`];
77
+ if (result.filesWritten.length) synthLines.push(`Brief written to: ${result.filesWritten.join(", ")}`);
78
+ if (result.skillsWritten.length) synthLines.push(`Skills written: ${result.skillsWritten.join(", ")}`);
79
+ if (result.skillsPruned.length) synthLines.push(`Pruned stale: ${result.skillsPruned.join(", ")}`);
80
+ return synthLines.join("\n");
81
+ }
82
+ case "kirograph_watchmen_reset": {
83
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
84
+ const projectRoot = args.projectPath ?? cg.getProjectRoot();
85
+ const config = await loadConfig(projectRoot);
86
+ if (!config.enableMemory) return "Memory is not enabled.";
87
+ if (!config.enableWatchmen) return "Watchmen is not enabled.";
88
+ const { MemoryManager } = await Promise.resolve().then(() => require("../../memory/index.js"));
89
+ const db = cg.getDatabase();
90
+ db.applyMemorySchema();
91
+ const mgr = new MemoryManager(config, db.getRawDb(), projectRoot);
92
+ mgr.initialize();
93
+ const id = await mgr.store({ content: `Watchmen counter reset via MCP at ${(/* @__PURE__ */ new Date()).toISOString()}.`, kind: "summary", source: "manual" });
94
+ return id ? "Watchmen counter reset \u2014 pending observations set back to 0." : "Already at zero \u2014 nothing to reset.";
95
+ }
96
+ default:
97
+ return `Unknown tool: ${toolName}`;
98
+ }
99
+ }
100
+ // Annotate the CommonJS export names for ESM import in node:
101
+ 0 && (module.exports = {
102
+ handleWatchmen
103
+ });
104
+ //# sourceMappingURL=watchmen.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/mcp/handlers/watchmen.ts"],
4
+ "sourcesContent": ["import KiroGraph from '../../index';\n\nexport async function handleWatchmen(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\n case 'kirograph_watchmen_status': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = args.projectPath as string ?? cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableMemory) return 'Memory is not enabled. Set enableMemory: true in .kirograph/config.json';\n if (!config.enableWatchmen) return 'Watchmen is not enabled. Set enableWatchmen: true in .kirograph/config.json';\n\n const { WatchmenChecker } = await Promise.resolve().then(() => require('../../watchmen/index.js'));\n const { MemoryDatabase } = await Promise.resolve().then(() => require('../../memory/database.js'));\n const db = cg.getDatabase();\n db.applyMemorySchema();\n const memDb = new MemoryDatabase(db.getRawDb());\n memDb.initialize();\n\n const checker = new WatchmenChecker(config.watchmenThreshold);\n const { ready, pendingCount } = checker.shouldSynthesize(memDb);\n const { targetFiles } = checker.buildReadyResponse('', pendingCount, projectRoot);\n\n const statusLines = [\n `Watchmen Status:`,\n ` Pending observations: ${pendingCount} / ${config.watchmenThreshold} threshold`,\n ` Ready to synthesize: ${ready ? 'yes' : 'no'}`,\n ` Target files:`,\n ];\n for (const f of targetFiles) statusLines.push(` \u00B7 ${f}`);\n return statusLines.join('\\n');\n }\n\n case 'kirograph_watchmen_synthesize': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = args.projectPath as string ?? cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableMemory || !config.enableWatchmen) return 'Watchmen is not enabled (enableMemory + enableWatchmen required).';\n if (config.watchmenSynthesisMode !== 'local') return 'watchmenSynthesisMode is not \"local\" \u2014 use the agent hook instead.';\n\n const { WatchmenChecker } = await Promise.resolve().then(() => require('../../watchmen/index.js'));\n const { MemoryDatabase } = await Promise.resolve().then(() => require('../../memory/database.js'));\n const { runLocalSynthesis } = await Promise.resolve().then(() => require('../../watchmen/synthesize.js'));\n const { MemoryManager } = await Promise.resolve().then(() => require('../../memory/index.js'));\n const db = cg.getDatabase();\n db.applyMemorySchema();\n const memDb = new MemoryDatabase(db.getRawDb());\n memDb.initialize();\n\n const checker = new WatchmenChecker(config.watchmenThreshold);\n const { ready, pendingCount } = checker.shouldSynthesize(memDb);\n\n if (!ready && !args.force) {\n return `Watchmen: ${pendingCount}/${config.watchmenThreshold} observations \u2014 threshold not reached. Pass force: true to run anyway.`;\n }\n\n const observations = memDb.getObservationsSinceLastSummary(50);\n if (observations.length === 0) return 'No observations to synthesize.';\n\n const readyResult = checker.buildReadyResponse('', pendingCount, projectRoot);\n const result = await runLocalSynthesis(observations, readyResult, config.watchmenLocalModel, projectRoot, true);\n\n const mgr = new MemoryManager(config, db.getRawDb(), projectRoot);\n mgr.initialize();\n await mgr.store({ content: result.summaryObservation, kind: 'summary', source: 'agent' });\n\n const synthLines = [`Watchmen synthesis complete.`];\n if (result.filesWritten.length) synthLines.push(`Brief written to: ${result.filesWritten.join(', ')}`);\n if (result.skillsWritten.length) synthLines.push(`Skills written: ${result.skillsWritten.join(', ')}`);\n if (result.skillsPruned.length) synthLines.push(`Pruned stale: ${result.skillsPruned.join(', ')}`);\n return synthLines.join('\\n');\n }\n\n case 'kirograph_watchmen_reset': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = args.projectPath as string ?? cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableMemory) return 'Memory is not enabled.';\n if (!config.enableWatchmen) return 'Watchmen is not enabled.';\n\n const { MemoryManager } = await Promise.resolve().then(() => require('../../memory/index.js'));\n const db = cg.getDatabase();\n db.applyMemorySchema();\n const mgr = new MemoryManager(config, db.getRawDb(), projectRoot);\n mgr.initialize();\n\n const id = await mgr.store({ content: `Watchmen counter reset via MCP at ${new Date().toISOString()}.`, kind: 'summary', source: 'manual' });\n return id ? 'Watchmen counter reset \u2014 pending observations set back to 0.' : 'Already at zero \u2014 nothing to reset.';\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,242 @@
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 wiki_exports = {};
20
+ __export(wiki_exports, {
21
+ handleWiki: () => handleWiki
22
+ });
23
+ module.exports = __toCommonJS(wiki_exports);
24
+ async function handleWiki(toolName, args, cg) {
25
+ switch (toolName) {
26
+ case "kirograph_wiki_ingest": {
27
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
28
+ const projectRoot = cg.getProjectRoot();
29
+ const config = await loadConfig(projectRoot);
30
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
31
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
32
+ const db = cg.getDatabase();
33
+ db.applyWikiSchema();
34
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph", {
35
+ autoResolveConflicts: config.wikiAutoResolveConflicts ?? false
36
+ });
37
+ wiki.initialize();
38
+ const source = args.source ?? "";
39
+ const sourceName = args.sourceName ?? "source";
40
+ if (!source) return "source is required";
41
+ if (config.wikiSynthesisMode === "local") {
42
+ wiki.queueSource(source, sourceName);
43
+ const count = wiki.getQueueCount();
44
+ return `Source "${sourceName}" queued for local wiki synthesis (${count} in queue). The agentStop hook will run "kirograph wiki synthesize" automatically.`;
45
+ }
46
+ const prompt = wiki.getIngestPrompt(source, sourceName);
47
+ return `WIKI_INGEST_PROMPT
48
+ ${prompt}
49
+
50
+ Produce WIKI_DIFF blocks following SCHEMA.md, then call kirograph_wiki_apply_diff with the diff string.`;
51
+ }
52
+ case "kirograph_wiki_apply_diff": {
53
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
54
+ const projectRoot = cg.getProjectRoot();
55
+ const config = await loadConfig(projectRoot);
56
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
57
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
58
+ const db = cg.getDatabase();
59
+ db.applyWikiSchema();
60
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph", {
61
+ autoResolveConflicts: config.wikiAutoResolveConflicts ?? false
62
+ });
63
+ wiki.initialize();
64
+ const diff = args.diff ?? "";
65
+ if (!diff) return "diff is required";
66
+ const result = wiki.applyDiff(diff);
67
+ const lines = ["\u2713 Wiki diff applied"];
68
+ if (result.created.length) lines.push(` Created: ${result.created.join(", ")}`);
69
+ if (result.updated.length) lines.push(` Updated: ${result.updated.join(", ")}`);
70
+ if (result.conflictsResolved.length) lines.push(` Conflicts auto-resolved: ${result.conflictsResolved.join(", ")}`);
71
+ if (result.conflictsPending.length) {
72
+ lines.push(` \u26A1 Conflicts pending (${result.conflictsPending.length}):`);
73
+ for (const c of result.conflictsPending) {
74
+ lines.push(` ${c.page} \xA7${c.section}: "${c.existing}" vs "${c.incoming}" (source: ${c.source})`);
75
+ }
76
+ }
77
+ return lines.join("\n");
78
+ }
79
+ case "kirograph_wiki_search": {
80
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
81
+ const projectRoot = cg.getProjectRoot();
82
+ const config = await loadConfig(projectRoot);
83
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
84
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
85
+ const db = cg.getDatabase();
86
+ db.applyWikiSchema();
87
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph");
88
+ wiki.initialize();
89
+ const query = args.query ?? "";
90
+ if (!query) return "query is required";
91
+ const limit = Math.min(Number(args.limit ?? 5), 20);
92
+ const results = wiki.search(query, limit);
93
+ if (results.length === 0) return `No wiki pages found for "${query}".`;
94
+ const lines = [`Wiki Search: ${query}`, ""];
95
+ for (const { page, score } of results) {
96
+ lines.push(`[${page.slug}] ${page.title} (score: ${score.toFixed(3)})`);
97
+ const preview = page.content.split("\n").find((l) => l.trim() && !l.startsWith("#"));
98
+ if (preview) lines.push(` ${preview.trim().slice(0, 120)}`);
99
+ lines.push("");
100
+ }
101
+ return lines.join("\n").trim();
102
+ }
103
+ case "kirograph_wiki_page": {
104
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
105
+ const projectRoot = cg.getProjectRoot();
106
+ const config = await loadConfig(projectRoot);
107
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
108
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
109
+ const db = cg.getDatabase();
110
+ db.applyWikiSchema();
111
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph");
112
+ wiki.initialize();
113
+ const slug = args.slug ?? "";
114
+ if (!slug) return "slug is required";
115
+ const page = wiki.getPage(slug);
116
+ if (!page) return `Wiki page "${slug}" not found. Use kirograph_wiki_list to see available pages.`;
117
+ return page.content;
118
+ }
119
+ case "kirograph_wiki_lint": {
120
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
121
+ const projectRoot = cg.getProjectRoot();
122
+ const config = await loadConfig(projectRoot);
123
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
124
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
125
+ const db = cg.getDatabase();
126
+ db.applyWikiSchema();
127
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph");
128
+ wiki.initialize();
129
+ const issues = wiki.lint();
130
+ if (issues.length === 0) return "\u2713 Wiki lint passed \u2014 no issues found.";
131
+ const lines = [`Wiki Lint \u2014 ${issues.length} issue(s)`, ""];
132
+ for (const issue of issues) {
133
+ const icon = issue.kind === "contradiction" ? "\u26A1" : issue.kind === "orphan" ? "\u25CB" : issue.kind === "broken_link" ? "\u{1F517}" : "\u26A0";
134
+ lines.push(`${icon} [${issue.kind}] ${issue.slug}`);
135
+ lines.push(` ${issue.detail}`);
136
+ lines.push("");
137
+ }
138
+ return lines.join("\n").trim();
139
+ }
140
+ case "kirograph_wiki_list": {
141
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
142
+ const projectRoot = cg.getProjectRoot();
143
+ const config = await loadConfig(projectRoot);
144
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
145
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
146
+ const db = cg.getDatabase();
147
+ db.applyWikiSchema();
148
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph");
149
+ wiki.initialize();
150
+ const pages = wiki.listPages();
151
+ if (pages.length === 0) return "Wiki is empty. Use kirograph_wiki_ingest to add pages.";
152
+ const stats = wiki.getStats();
153
+ const lines = [
154
+ `Wiki \u2014 ${stats.pageCount} page(s), ${stats.totalSources} total sources`,
155
+ ""
156
+ ];
157
+ for (const page of pages) {
158
+ const date = new Date(page.updatedAt).toISOString().slice(0, 10);
159
+ lines.push(` ${page.slug.padEnd(32)} ${page.title} (${page.sourceCount} src, ${date})`);
160
+ }
161
+ return lines.join("\n");
162
+ }
163
+ case "kirograph_wiki_synthesize": {
164
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
165
+ const projectRoot = args.projectPath ?? cg.getProjectRoot();
166
+ const config = await loadConfig(projectRoot);
167
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
168
+ if (config.wikiSynthesisMode !== "local") return 'wikiSynthesisMode is not "local". This tool is for local-model synthesis only.';
169
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
170
+ const db = cg.getDatabase();
171
+ db.applyWikiSchema();
172
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph", {
173
+ autoResolveConflicts: config.wikiAutoResolveConflicts ?? false
174
+ });
175
+ wiki.initialize();
176
+ const queueCount = wiki.getQueueCount();
177
+ if (queueCount === 0) return "Wiki queue is empty \u2014 nothing to synthesize.";
178
+ const result = await wiki.synthesize(config.wikiLocalModel, true);
179
+ const synthLines = [`Wiki synthesis complete \u2014 processed ${result.processed} source(s).`];
180
+ if (result.created.length) synthLines.push(`Created: ${result.created.join(", ")}`);
181
+ if (result.updated.length) synthLines.push(`Updated: ${result.updated.join(", ")}`);
182
+ if (result.errors.length) synthLines.push(`Errors: ${result.errors.join("; ")}`);
183
+ return synthLines.join("\n");
184
+ }
185
+ case "kirograph_wiki_init": {
186
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
187
+ const projectRoot = args.projectPath ?? cg.getProjectRoot();
188
+ const config = await loadConfig(projectRoot);
189
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
190
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
191
+ const db = cg.getDatabase();
192
+ db.applyWikiSchema();
193
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph", {
194
+ autoResolveConflicts: config.wikiAutoResolveConflicts ?? false
195
+ });
196
+ wiki.initWiki();
197
+ return "Wiki initialized. SCHEMA.md and MANIFEST.md created in .kirograph/wiki/.";
198
+ }
199
+ case "kirograph_wiki_reindex": {
200
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
201
+ const projectRoot = args.projectPath ?? cg.getProjectRoot();
202
+ const config = await loadConfig(projectRoot);
203
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
204
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
205
+ const db = cg.getDatabase();
206
+ db.applyWikiSchema();
207
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph");
208
+ wiki.initialize();
209
+ const count = wiki.reindex();
210
+ return `Reindexed ${count} wiki page(s) from .kirograph/wiki/*.md.`;
211
+ }
212
+ case "kirograph_wiki_status": {
213
+ const { loadConfig } = await Promise.resolve().then(() => require("../../config.js"));
214
+ const projectRoot = args.projectPath ?? cg.getProjectRoot();
215
+ const config = await loadConfig(projectRoot);
216
+ if (!config.enableWiki) return "Wiki is not enabled. Set enableWiki: true in .kirograph/config.json";
217
+ const { KiroGraphWiki } = await Promise.resolve().then(() => require("../../wiki/index.js"));
218
+ const db = cg.getDatabase();
219
+ db.applyWikiSchema();
220
+ const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph");
221
+ wiki.initialize();
222
+ const stats = wiki.getStats();
223
+ const oldest = stats.oldestPage ? new Date(stats.oldestPage).toISOString().slice(0, 10) : "n/a";
224
+ const newest = stats.newestPage ? new Date(stats.newestPage).toISOString().slice(0, 10) : "n/a";
225
+ return [
226
+ "Wiki Status:",
227
+ ` Pages: ${stats.pageCount}`,
228
+ ` Total sources: ${stats.totalSources}`,
229
+ ` Oldest page: ${oldest}`,
230
+ ` Newest page: ${newest}`,
231
+ ` Wiki dir: .kirograph/wiki/`
232
+ ].join("\n");
233
+ }
234
+ default:
235
+ return `Unknown tool: ${toolName}`;
236
+ }
237
+ }
238
+ // Annotate the CommonJS export names for ESM import in node:
239
+ 0 && (module.exports = {
240
+ handleWiki
241
+ });
242
+ //# sourceMappingURL=wiki.js.map