kirograph 1.2.2 → 1.3.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 (45) hide show
  1. package/README.md +4 -3
  2. package/dist/bin/commands/attack-surface.js +15 -2
  3. package/dist/bin/commands/attack-surface.js.map +2 -2
  4. package/dist/bin/commands/help.js +4 -2
  5. package/dist/bin/commands/help.js.map +2 -2
  6. package/dist/bin/commands/memory.js +23 -3
  7. package/dist/bin/commands/memory.js.map +2 -2
  8. package/dist/bin/commands/security-export.js +7 -1
  9. package/dist/bin/commands/security-export.js.map +2 -2
  10. package/dist/bin/commands/wiki.js +12 -1
  11. package/dist/bin/commands/wiki.js.map +2 -2
  12. package/dist/bin/installer/common.js +25 -0
  13. package/dist/bin/installer/common.js.map +2 -2
  14. package/dist/bin/installer/config-prompt.js +25 -1
  15. package/dist/bin/installer/config-prompt.js.map +2 -2
  16. package/dist/bin/installer/index.js +23 -0
  17. package/dist/bin/installer/index.js.map +2 -2
  18. package/dist/bin/installer/steering.js +5 -1
  19. package/dist/bin/installer/steering.js.map +2 -2
  20. package/dist/bin/kirograph.js +1 -1
  21. package/dist/config.js +63 -2
  22. package/dist/config.js.map +2 -2
  23. package/dist/mcp/handlers/memory.js +17 -5
  24. package/dist/mcp/handlers/memory.js.map +2 -2
  25. package/dist/mcp/handlers/security.js +13 -2
  26. package/dist/mcp/handlers/security.js.map +2 -2
  27. package/dist/mcp/handlers/wiki.js +11 -1
  28. package/dist/mcp/handlers/wiki.js.map +2 -2
  29. package/dist/mcp/tools.js +4 -4
  30. package/dist/mcp/tools.js.map +2 -2
  31. package/dist/memory/index.js +40 -10
  32. package/dist/memory/index.js.map +2 -2
  33. package/dist/memory/relation-display.js +37 -0
  34. package/dist/memory/relation-display.js.map +7 -0
  35. package/dist/patterns/library/sql-injection-concat-js.yaml +3 -0
  36. package/dist/patterns/library/sql-injection-template-js.yaml +4 -0
  37. package/dist/security/attack-surface.js +20 -2
  38. package/dist/security/attack-surface.js.map +2 -2
  39. package/dist/security/data-flows.js +0 -10
  40. package/dist/security/data-flows.js.map +2 -2
  41. package/dist/wiki/index.js +15 -2
  42. package/dist/wiki/index.js.map +2 -2
  43. package/dist/wiki/lint.js +23 -11
  44. package/dist/wiki/lint.js.map +2 -2
  45. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
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, undefined, projectRoot);\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, explainReachability } = 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 `Why: ${explainReachability(result)}`,\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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",
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, undefined, projectRoot);\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, explainReachability } = 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 `Why: ${explainReachability(result)}`,\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 authDetectionMode: config.securityAuthDetectionMode,\n authConfidenceThreshold: config.securityAuthConfidenceThreshold,\n jevApiKey: config.jevApiKey,\n jevBaseUrl: config.jevBaseUrl,\n jevModel: config.jevModel,\n });\n let result;\n try {\n result = await analyzer.analyze();\n } catch (err) {\n return `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\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
6
  "names": ["lines", "denyCount", "warnCount"]
7
7
  }
@@ -125,10 +125,20 @@ Produce WIKI_DIFF blocks following SCHEMA.md, then call kirograph_wiki_apply_dif
125
125
  const db = cg.getDatabase();
126
126
  db.applyWikiSchema();
127
127
  const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + "/.kirograph", {
128
+ wikiContradictionMode: config.wikiContradictionMode,
129
+ wikiContradictionConfidenceThreshold: config.wikiContradictionConfidenceThreshold,
130
+ jevApiKey: config.jevApiKey,
131
+ jevBaseUrl: config.jevBaseUrl,
132
+ jevModel: config.jevModel,
128
133
  typedPages: config.wikiTypedPages
129
134
  });
130
135
  wiki.initialize();
131
- const issues = wiki.lint();
136
+ let issues;
137
+ try {
138
+ issues = await wiki.lint();
139
+ } catch (err) {
140
+ return `Error: ${err instanceof Error ? err.message : String(err)}`;
141
+ }
132
142
  if (issues.length === 0) return "\u2713 Wiki lint passed \u2014 no issues found.";
133
143
  const lines = [`Wiki Lint \u2014 ${issues.length} issue(s)`, ""];
134
144
  for (const issue of issues) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/mcp/handlers/wiki.ts"],
4
- "sourcesContent": ["import KiroGraph from '../../index';\n\nexport async function handleWiki(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\n case 'kirograph_wiki_ingest': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initialize();\n\n const source = args.source as string ?? '';\n const sourceName = args.sourceName as string ?? 'source';\n if (!source) return 'source is required';\n\n if (config.wikiSynthesisMode === 'local') {\n wiki.queueSource(source, sourceName);\n const count = wiki.getQueueCount();\n return `Source \"${sourceName}\" queued for local wiki synthesis (${count} in queue). The agentStop hook will run \"kirograph wiki synthesize\" automatically.`;\n }\n\n const prompt = wiki.getIngestPrompt(source, sourceName);\n return `WIKI_INGEST_PROMPT\\n${prompt}\\n\\nProduce WIKI_DIFF blocks following SCHEMA.md, then call kirograph_wiki_apply_diff with the diff string.`;\n }\n\n case 'kirograph_wiki_apply_diff': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initialize();\n\n const diff = args.diff as string ?? '';\n if (!diff) return 'diff is required';\n\n const result = wiki.applyDiff(diff);\n const lines: string[] = ['\u2713 Wiki diff applied'];\n if (result.created.length) lines.push(` Created: ${result.created.join(', ')}`);\n if (result.updated.length) lines.push(` Updated: ${result.updated.join(', ')}`);\n if (result.conflictsResolved.length) lines.push(` Conflicts auto-resolved: ${result.conflictsResolved.join(', ')}`);\n if (result.conflictsPending.length) {\n lines.push(` \u26A1 Conflicts pending (${result.conflictsPending.length}):`);\n for (const c of result.conflictsPending) {\n lines.push(` ${c.page} \u00A7${c.section}: \"${c.existing}\" vs \"${c.incoming}\" (source: ${c.source})`);\n }\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_wiki_search': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const query = args.query as string ?? '';\n if (!query) return 'query is required';\n const limit = Math.min(Number(args.limit ?? 5), 20);\n\n const results = wiki.search(query, limit);\n if (results.length === 0) return `No wiki pages found for \"${query}\".`;\n\n const lines = [`Wiki Search: ${query}`, ''];\n for (const { page, score } of results) {\n lines.push(`[${page.slug}] ${page.title} (score: ${score.toFixed(3)})`);\n // Show first non-heading line as preview\n const preview = page.content.split('\\n').find(l => l.trim() && !l.startsWith('#'));\n if (preview) lines.push(` ${preview.trim().slice(0, 120)}`);\n lines.push('');\n }\n return lines.join('\\n').trim();\n }\n\n case 'kirograph_wiki_page': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const slug = args.slug as string ?? '';\n if (!slug) return 'slug is required';\n\n const page = wiki.getPage(slug);\n if (!page) return `Wiki page \"${slug}\" not found. Use kirograph_wiki_list to see available pages.`;\n\n return page.content;\n }\n\n case 'kirograph_wiki_lint': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n typedPages: config.wikiTypedPages,\n });\n wiki.initialize();\n\n const issues = wiki.lint();\n if (issues.length === 0) return '\u2713 Wiki lint passed \u2014 no issues found.';\n\n const lines = [`Wiki Lint \u2014 ${issues.length} issue(s)`, ''];\n for (const issue of issues) {\n const icon = issue.kind === 'contradiction' ? '\u26A1' : issue.kind === 'orphan' ? '\u25CB' : issue.kind === 'broken_link' ? '\uD83D\uDD17' : issue.kind === 'schema_error' ? '\u2716' : '\u26A0';\n lines.push(`${icon} [${issue.kind}] ${issue.slug}`);\n lines.push(` ${issue.detail}`);\n lines.push('');\n }\n return lines.join('\\n').trim();\n }\n\n case 'kirograph_wiki_list': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const pages = wiki.listPages();\n if (pages.length === 0) return 'Wiki is empty. Use kirograph_wiki_ingest to add pages.';\n\n const stats = wiki.getStats();\n const lines = [\n `Wiki \u2014 ${stats.pageCount} page(s), ${stats.totalSources} total sources`,\n '',\n ];\n for (const page of pages) {\n const date = new Date(page.updatedAt).toISOString().slice(0, 10);\n lines.push(` ${page.slug.padEnd(32)} ${page.title} (${page.sourceCount} src, ${date})`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_wiki_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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n if (config.wikiSynthesisMode !== 'local') return 'wikiSynthesisMode is not \"local\". This tool is for local-model synthesis only.';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initialize();\n\n const queueCount = wiki.getQueueCount();\n if (queueCount === 0) return 'Wiki queue is empty \u2014 nothing to synthesize.';\n\n const result = await wiki.synthesize(config.wikiLocalModel, true);\n const synthLines = [`Wiki synthesis complete \u2014 processed ${result.processed} source(s).`];\n if (result.created.length) synthLines.push(`Created: ${result.created.join(', ')}`);\n if (result.updated.length) synthLines.push(`Updated: ${result.updated.join(', ')}`);\n if (result.errors.length) synthLines.push(`Errors: ${result.errors.join('; ')}`);\n return synthLines.join('\\n');\n }\n\n case 'kirograph_wiki_init': {\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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initWiki();\n return 'Wiki initialized. SCHEMA.md and MANIFEST.md created in .kirograph/wiki/.';\n }\n\n case 'kirograph_wiki_reindex': {\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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const count = wiki.reindex();\n return `Reindexed ${count} wiki page(s) from .kirograph/wiki/*.md.`;\n }\n\n case 'kirograph_wiki_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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const stats = wiki.getStats();\n const oldest = stats.oldestPage ? new Date(stats.oldestPage).toISOString().slice(0, 10) : 'n/a';\n const newest = stats.newestPage ? new Date(stats.newestPage).toISOString().slice(0, 10) : 'n/a';\n return [\n 'Wiki Status:',\n ` Pages: ${stats.pageCount}`,\n ` Total sources: ${stats.totalSources}`,\n ` Oldest page: ${oldest}`,\n ` Newest page: ${newest}`,\n ` Wiki dir: .kirograph/wiki/`,\n ].join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import KiroGraph from '../../index';\n\nexport async function handleWiki(toolName: string, args: Record<string, unknown>, cg: KiroGraph): Promise<string> {\n switch (toolName) {\n case 'kirograph_wiki_ingest': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initialize();\n\n const source = args.source as string ?? '';\n const sourceName = args.sourceName as string ?? 'source';\n if (!source) return 'source is required';\n\n if (config.wikiSynthesisMode === 'local') {\n wiki.queueSource(source, sourceName);\n const count = wiki.getQueueCount();\n return `Source \"${sourceName}\" queued for local wiki synthesis (${count} in queue). The agentStop hook will run \"kirograph wiki synthesize\" automatically.`;\n }\n\n const prompt = wiki.getIngestPrompt(source, sourceName);\n return `WIKI_INGEST_PROMPT\\n${prompt}\\n\\nProduce WIKI_DIFF blocks following SCHEMA.md, then call kirograph_wiki_apply_diff with the diff string.`;\n }\n\n case 'kirograph_wiki_apply_diff': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initialize();\n\n const diff = args.diff as string ?? '';\n if (!diff) return 'diff is required';\n\n const result = wiki.applyDiff(diff);\n const lines: string[] = ['\u2713 Wiki diff applied'];\n if (result.created.length) lines.push(` Created: ${result.created.join(', ')}`);\n if (result.updated.length) lines.push(` Updated: ${result.updated.join(', ')}`);\n if (result.conflictsResolved.length) lines.push(` Conflicts auto-resolved: ${result.conflictsResolved.join(', ')}`);\n if (result.conflictsPending.length) {\n lines.push(` \u26A1 Conflicts pending (${result.conflictsPending.length}):`);\n for (const c of result.conflictsPending) {\n lines.push(` ${c.page} \u00A7${c.section}: \"${c.existing}\" vs \"${c.incoming}\" (source: ${c.source})`);\n }\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_wiki_search': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const query = args.query as string ?? '';\n if (!query) return 'query is required';\n const limit = Math.min(Number(args.limit ?? 5), 20);\n\n const results = wiki.search(query, limit);\n if (results.length === 0) return `No wiki pages found for \"${query}\".`;\n\n const lines = [`Wiki Search: ${query}`, ''];\n for (const { page, score } of results) {\n lines.push(`[${page.slug}] ${page.title} (score: ${score.toFixed(3)})`);\n // Show first non-heading line as preview\n const preview = page.content.split('\\n').find(l => l.trim() && !l.startsWith('#'));\n if (preview) lines.push(` ${preview.trim().slice(0, 120)}`);\n lines.push('');\n }\n return lines.join('\\n').trim();\n }\n\n case 'kirograph_wiki_page': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const slug = args.slug as string ?? '';\n if (!slug) return 'slug is required';\n\n const page = wiki.getPage(slug);\n if (!page) return `Wiki page \"${slug}\" not found. Use kirograph_wiki_list to see available pages.`;\n\n return page.content;\n }\n\n case 'kirograph_wiki_lint': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n wikiContradictionMode: config.wikiContradictionMode,\n wikiContradictionConfidenceThreshold: config.wikiContradictionConfidenceThreshold,\n jevApiKey: config.jevApiKey,\n jevBaseUrl: config.jevBaseUrl,\n jevModel: config.jevModel,\n typedPages: config.wikiTypedPages,\n });\n wiki.initialize();\n\n let issues;\n try {\n issues = await wiki.lint();\n } catch (err) {\n return `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n if (issues.length === 0) return '\u2713 Wiki lint passed \u2014 no issues found.';\n\n const lines = [`Wiki Lint \u2014 ${issues.length} issue(s)`, ''];\n for (const issue of issues) {\n const icon = issue.kind === 'contradiction' ? '\u26A1' : issue.kind === 'orphan' ? '\u25CB' : issue.kind === 'broken_link' ? '\uD83D\uDD17' : issue.kind === 'schema_error' ? '\u2716' : '\u26A0';\n lines.push(`${icon} [${issue.kind}] ${issue.slug}`);\n lines.push(` ${issue.detail}`);\n lines.push('');\n }\n return lines.join('\\n').trim();\n }\n\n case 'kirograph_wiki_list': {\n const { loadConfig } = await Promise.resolve().then(() => require('../../config.js'));\n const projectRoot = cg.getProjectRoot();\n const config = await loadConfig(projectRoot);\n if (!config.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const pages = wiki.listPages();\n if (pages.length === 0) return 'Wiki is empty. Use kirograph_wiki_ingest to add pages.';\n\n const stats = wiki.getStats();\n const lines = [\n `Wiki \u2014 ${stats.pageCount} page(s), ${stats.totalSources} total sources`,\n '',\n ];\n for (const page of pages) {\n const date = new Date(page.updatedAt).toISOString().slice(0, 10);\n lines.push(` ${page.slug.padEnd(32)} ${page.title} (${page.sourceCount} src, ${date})`);\n }\n return lines.join('\\n');\n }\n\n case 'kirograph_wiki_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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n if (config.wikiSynthesisMode !== 'local') return 'wikiSynthesisMode is not \"local\". This tool is for local-model synthesis only.';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initialize();\n\n const queueCount = wiki.getQueueCount();\n if (queueCount === 0) return 'Wiki queue is empty \u2014 nothing to synthesize.';\n\n const result = await wiki.synthesize(config.wikiLocalModel, true);\n const synthLines = [`Wiki synthesis complete \u2014 processed ${result.processed} source(s).`];\n if (result.created.length) synthLines.push(`Created: ${result.created.join(', ')}`);\n if (result.updated.length) synthLines.push(`Updated: ${result.updated.join(', ')}`);\n if (result.errors.length) synthLines.push(`Errors: ${result.errors.join('; ')}`);\n return synthLines.join('\\n');\n }\n\n case 'kirograph_wiki_init': {\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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph', {\n autoResolveConflicts: (config as any).wikiAutoResolveConflicts ?? false,\n });\n wiki.initWiki();\n return 'Wiki initialized. SCHEMA.md and MANIFEST.md created in .kirograph/wiki/.';\n }\n\n case 'kirograph_wiki_reindex': {\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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const count = wiki.reindex();\n return `Reindexed ${count} wiki page(s) from .kirograph/wiki/*.md.`;\n }\n\n case 'kirograph_wiki_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.enableWiki) return 'Wiki is not enabled. Set enableWiki: true in .kirograph/config.json';\n\n const { KiroGraphWiki } = await Promise.resolve().then(() => require('../../wiki/index.js'));\n const db = cg.getDatabase();\n db.applyWikiSchema();\n const wiki = new KiroGraphWiki(db.getRawDb(), projectRoot + '/.kirograph');\n wiki.initialize();\n\n const stats = wiki.getStats();\n const oldest = stats.oldestPage ? new Date(stats.oldestPage).toISOString().slice(0, 10) : 'n/a';\n const newest = stats.newestPage ? new Date(stats.newestPage).toISOString().slice(0, 10) : 'n/a';\n return [\n 'Wiki Status:',\n ` Pages: ${stats.pageCount}`,\n ` Total sources: ${stats.totalSources}`,\n ` Oldest page: ${oldest}`,\n ` Newest page: ${newest}`,\n ` Wiki dir: .kirograph/wiki/`,\n ].join('\\n');\n }\n\n default:\n return `Unknown tool: ${toolName}`;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/mcp/tools.js CHANGED
@@ -881,19 +881,19 @@ const tools = [
881
881
  },
882
882
  {
883
883
  name: "kirograph_mem_compare",
884
- description: "Establish a typed relation between two observations (supersedes, conflicts_with, compatible, scoped, related, not_conflict). Accepts observation IDs or topic_key values.",
884
+ description: 'Establish a typed relation between two observations (supersedes, conflicts_with, compatible, scoped, related, not_conflict). Accepts observation IDs or topic_key values. When memoryRelationMode is "jev", omit `relation` to have it classified automatically instead of reasoning it out yourself.',
885
885
  inputSchema: {
886
886
  type: "object",
887
887
  properties: {
888
888
  observationA: { type: "string", description: "First observation ID or topic_key" },
889
889
  observationB: { type: "string", description: "Second observation ID or topic_key" },
890
- relation: { type: "string", enum: ["supersedes", "conflicts_with", "compatible", "scoped", "related", "not_conflict"], description: "Relation type" },
891
- confidence: { type: "number", description: "Confidence 0.0\u20131.0 (default: 1.0)" },
890
+ relation: { type: "string", enum: ["supersedes", "conflicts_with", "compatible", "scoped", "related", "not_conflict"], description: 'Relation type. Required unless memoryRelationMode is "jev", in which case omitting it classifies the relation automatically.' },
891
+ confidence: { type: "number", description: "Confidence 0.0\u20131.0 (default: 1.0). Ignored when relation is omitted in jev mode \u2014 jev supplies its own calibrated confidence." },
892
892
  reason: { type: "string", description: "Explanation of the relation" },
893
893
  evidence: { type: "string", description: "Supporting evidence text" },
894
894
  projectPath: { type: "string" }
895
895
  },
896
- required: ["observationA", "observationB", "relation"]
896
+ required: ["observationA", "observationB"]
897
897
  }
898
898
  },
899
899
  {