kirograph 0.28.1 → 1.0.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.
- package/dist/architecture/index.js +4 -1
- package/dist/architecture/index.js.map +2 -2
- package/dist/architecture/manifest/index.js +13 -2
- package/dist/architecture/manifest/index.js.map +2 -2
- package/dist/bin/commands/install.js +2 -1
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/status.js +2 -1
- package/dist/bin/commands/status.js.map +2 -2
- package/dist/bin/commands/uninit.js +2 -1
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/commands/vulns.js +10 -5
- package/dist/bin/commands/vulns.js.map +2 -2
- package/dist/bin/installer/common.js +7 -1
- package/dist/bin/installer/common.js.map +2 -2
- package/dist/bin/installer/detect.js +10 -0
- package/dist/bin/installer/detect.js.map +2 -2
- package/dist/bin/installer/hooks.js +13 -8
- package/dist/bin/installer/hooks.js.map +2 -2
- package/dist/bin/installer/targets/antigravity.js +1 -1
- package/dist/bin/installer/targets/antigravity.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +1 -1
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/codex.js +1 -1
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/commandcode.js +84 -0
- package/dist/bin/installer/targets/commandcode.js.map +7 -0
- package/dist/bin/installer/targets/copilot.js +1 -1
- package/dist/bin/installer/targets/copilot.js.map +2 -2
- package/dist/bin/installer/targets/cursor.js +2 -2
- package/dist/bin/installer/targets/cursor.js.map +2 -2
- package/dist/bin/installer/targets/devin.js +1 -1
- package/dist/bin/installer/targets/devin.js.map +2 -2
- package/dist/bin/installer/targets/gemini-cli.js +1 -1
- package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
- package/dist/bin/installer/targets/index.js +10 -0
- package/dist/bin/installer/targets/index.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +1 -1
- package/dist/bin/installer/targets/opencode.js.map +2 -2
- package/dist/bin/installer/targets/windsurf.js +1 -1
- package/dist/bin/installer/targets/windsurf.js.map +2 -2
- package/dist/bin/kirograph.js +1 -1
- package/dist/bin/kirograph.js.map +1 -1
- package/dist/config.js +21 -1
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +18 -6
- package/dist/core/pipeline.js.map +2 -2
- package/dist/extraction/extractor.js +58 -1
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/extraction/grammars.js +38 -3
- package/dist/extraction/grammars.js.map +2 -2
- package/dist/extraction/wasm/tree-sitter-bash.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-c.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cpp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-csharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-css.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-dart.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-elisp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-elixir.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-elm.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-embedded_template.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-embeddedtemplate.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-html.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-json.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-kotlin.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-objc.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ocaml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-php.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ql.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-rescript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-ruby.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-rust.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-solidity.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-swift.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-systemrdl.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-tlaplus.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-toml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-vue.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-yaml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-zig.wasm +0 -0
- package/dist/frameworks/index.js +68 -7
- package/dist/frameworks/index.js.map +2 -2
- package/dist/security/manifest/adapter.js +17 -2
- package/dist/security/manifest/adapter.js.map +2 -2
- package/dist/security/manifest/parser.js +2 -2
- package/dist/security/manifest/parser.js.map +2 -2
- package/dist/security/pipeline.js +4 -1
- package/dist/security/pipeline.js.map +2 -2
- package/dist/security/reachability.js +61 -45
- package/dist/security/reachability.js.map +3 -3
- package/dist/security/types.js.map +1 -1
- package/dist/security/vuln/epss-client.js +1 -1
- package/dist/security/vuln/epss-client.js.map +1 -1
- package/dist/security/vuln/osv-adapter.js +99 -31
- package/dist/security/vuln/osv-adapter.js.map +2 -2
- package/dist/sync/index.js +9 -2
- package/dist/sync/index.js.map +2 -2
- package/dist/vectors/libsql-index.js +287 -0
- package/dist/vectors/libsql-index.js.map +7 -0
- package/dist/vectors/turso-index.js +307 -0
- package/dist/vectors/turso-index.js.map +7 -0
- package/package.json +3 -2
|
@@ -32,7 +32,10 @@ class ArchitectureAnalyzer {
|
|
|
32
32
|
async analyze(onProgress) {
|
|
33
33
|
const log = (msg) => onProgress?.(msg);
|
|
34
34
|
log("architecture: parsing manifests");
|
|
35
|
-
const manifestPackages = await (0, import_manifest.parseAllManifests)(this.projectRoot
|
|
35
|
+
const manifestPackages = await (0, import_manifest.parseAllManifests)(this.projectRoot, {
|
|
36
|
+
include: this.config.include,
|
|
37
|
+
exclude: this.config.exclude
|
|
38
|
+
});
|
|
36
39
|
const allFiles = this.db.getAllFiles().map((f) => f.path);
|
|
37
40
|
log("architecture: assigning files to packages");
|
|
38
41
|
const filePackageMap = /* @__PURE__ */ new Map();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/architecture/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * ArchitectureAnalyzer\n *\n * Orchestrates the full architecture analysis pipeline:\n * 1. Parse manifests \u2192 packages\n * 2. Directory-based fallback for uncovered file trees\n * 3. Detect layers from file paths\n * 4. Roll up package-to-package dependencies from existing import edges\n * 5. Roll up layer-to-layer dependencies\n * 6. Compute coupling metrics (Ca, Ce, instability)\n *\n * Only runs when enableArchitecture=true. Writes to arch_* tables in kirograph.db.\n */\nimport * as path from 'path';\nimport type { GraphDatabase } from '../db/database';\nimport type { KiroGraphConfig } from '../config';\nimport type {\n ArchPackage, ArchLayer, ArchPackageDep, ArchLayerDep, ArchCoupling, ArchitectureResult,\n} from './types';\nimport { parseAllManifests } from './manifest/index';\nimport { detectAllLayers, buildArchLayers, type FileLayerAssignment } from './layers/index';\n\nexport class ArchitectureAnalyzer {\n constructor(\n private readonly db: GraphDatabase,\n private readonly config: KiroGraphConfig,\n private readonly projectRoot: string,\n ) {}\n\n async analyze(onProgress?: (msg: string) => void): Promise<ArchitectureResult> {\n const log = (msg: string) => onProgress?.(msg);\n\n // \u2500\u2500 1. Parse manifests \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: parsing manifests');\n const manifestPackages = await parseAllManifests(this.projectRoot);\n\n // \u2500\u2500 2. Get all indexed files \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const allFiles = this.db.getAllFiles().map(f => f.path); // relative paths\n\n // \u2500\u2500 3. Assign files to packages (manifest-based) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: assigning files to packages');\n const filePackageMap = new Map<string, string>(); // filePath \u2192 packageId\n // Sort packages by path length desc so the most-specific package wins\n const sortedPkgs = [...manifestPackages].sort((a, b) => b.path.length - a.path.length);\n for (const file of allFiles) {\n for (const pkg of sortedPkgs) {\n const pkgPath = pkg.path === '.' ? '' : pkg.path + '/';\n if (pkg.path === '.' || file.startsWith(pkgPath)) {\n filePackageMap.set(file, pkg.id);\n break;\n }\n }\n }\n\n // \u2500\u2500 4. Directory-based fallback / subdivision \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n //\n // Three cases:\n // A) No manifests at all \u2192 group by top-level directory.\n // B) Root manifest (path='.') covers everything \u2192 subdivide its files into\n // second-level directory packages so internal structure is visible.\n // C) Manifests exist but don't cover the whole tree \u2192 create directory\n // packages for uncovered subdirectories (threshold: 3 files).\n //\n const SUBDIR_THRESHOLD = 1;\n const directoryPackages: ArchPackage[] = [];\n\n const rootManifestIds = new Set(manifestPackages.filter(p => p.path === '.').map(p => p.id));\n const hasRootManifest = rootManifestIds.size > 0;\n\n if (manifestPackages.length === 0) {\n // Case A: no manifests \u2014 group by top-level directory\n const topDirs = new Set<string>();\n for (const file of allFiles) {\n const parts = file.split('/');\n if (parts.length > 1) topDirs.add(parts[0]);\n }\n for (const dir of topDirs) {\n const pkgId = `pkg:dir:${dir}`;\n directoryPackages.push({ id: pkgId, name: dir, path: dir, source: 'directory', updatedAt: Date.now() });\n for (const file of allFiles) {\n if (file.startsWith(dir + '/')) filePackageMap.set(file, pkgId);\n }\n }\n } else if (hasRootManifest) {\n // Case B: root manifest(s) cover everything \u2014 subdivide into second-level dirs.\n // Collect files owned by a root manifest, then re-assign them to more specific\n // directory packages so internal module boundaries become visible.\n const rootOwnedFiles = allFiles.filter(f => rootManifestIds.has(filePackageMap.get(f) ?? ''));\n const subDirCounts = new Map<string, number>();\n for (const file of rootOwnedFiles) {\n const parts = file.split('/');\n if (parts.length > 2) {\n // Use two-level path (e.g. src/mcp) for granularity inside a src root\n const dir = parts.slice(0, 2).join('/');\n subDirCounts.set(dir, (subDirCounts.get(dir) ?? 0) + 1);\n }\n // Files directly at one level deep (e.g. src/index.ts) stay with the\n // root manifest package \u2014 no single-level dir package is created.\n }\n for (const [dir, count] of subDirCounts) {\n if (count >= SUBDIR_THRESHOLD) {\n const pkgId = `pkg:dir:${dir}`;\n const name = dir.split('/').pop() ?? dir;\n const pkg: ArchPackage = { id: pkgId, name, path: dir, source: 'directory', updatedAt: Date.now() };\n directoryPackages.push(pkg);\n for (const file of rootOwnedFiles) {\n if (file.startsWith(dir + '/') || file === dir) {\n filePackageMap.set(file, pkgId);\n }\n }\n }\n }\n } else {\n // Case C: manifests exist but don't cover root \u2014 create dir packages for uncovered files\n const uncovered = allFiles.filter(f => !filePackageMap.has(f));\n const subDirCounts = new Map<string, number>();\n for (const file of uncovered) {\n const parts = file.split('/');\n if (parts.length > 1) {\n const dir = parts.slice(0, 2).join('/');\n subDirCounts.set(dir, (subDirCounts.get(dir) ?? 0) + 1);\n }\n }\n for (const [dir, count] of subDirCounts) {\n if (count >= SUBDIR_THRESHOLD) {\n const pkgId = `pkg:dir:${dir}`;\n const name = dir.split('/').pop() ?? dir;\n const pkg: ArchPackage = { id: pkgId, name, path: dir, source: 'directory', updatedAt: Date.now() };\n directoryPackages.push(pkg);\n for (const file of uncovered) {\n if (file.startsWith(dir + '/') && !filePackageMap.has(file)) {\n filePackageMap.set(file, pkgId);\n }\n }\n }\n }\n }\n\n const allPackages = [...manifestPackages, ...directoryPackages];\n\n // \u2500\u2500 5. Detect layers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: detecting layers');\n const layerAssignments: FileLayerAssignment[] = [];\n const fileLayerMap = new Map<string, FileLayerAssignment>();\n\n if (this.config.architectureLayers !== undefined || this.config.enableArchitecture) {\n const assignments = await detectAllLayers(allFiles, this.projectRoot, this.config.architectureLayers);\n for (const a of assignments) {\n layerAssignments.push(a);\n fileLayerMap.set(a.filePath, a);\n }\n }\n\n const allLayers = buildArchLayers(layerAssignments, this.config.architectureLayers);\n\n // \u2500\u2500 6. Roll up package dependencies from import edges \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: rolling up package dependencies');\n const importPairs = this.db.getFileImportPairs();\n const pkgDepCounts = new Map<string, Map<string, { count: number; files: Array<{ from: string; to: string }> }>>();\n\n for (const { sourceFile, targetFile } of importPairs) {\n const sourcePkg = filePackageMap.get(sourceFile);\n const targetPkg = filePackageMap.get(targetFile);\n if (!sourcePkg || !targetPkg || sourcePkg === targetPkg) continue;\n\n if (!pkgDepCounts.has(sourcePkg)) pkgDepCounts.set(sourcePkg, new Map());\n const inner = pkgDepCounts.get(sourcePkg)!;\n if (!inner.has(targetPkg)) inner.set(targetPkg, { count: 0, files: [] });\n const entry = inner.get(targetPkg)!;\n entry.count++;\n if (entry.files.length < 5) entry.files.push({ from: sourceFile, to: targetFile });\n }\n\n const packageDeps: ArchPackageDep[] = [];\n for (const [sourcePkg, targets] of pkgDepCounts) {\n for (const [targetPkg, { count, files }] of targets) {\n packageDeps.push({ sourcePkg, targetPkg, depCount: count, files });\n }\n }\n\n // \u2500\u2500 7. Roll up layer dependencies \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const layerDepCounts = new Map<string, Map<string, number>>();\n for (const dep of packageDeps) {\n const srcFile = [...filePackageMap.entries()].find(([, pkgId]) => pkgId === dep.sourcePkg)?.[0];\n const tgtFile = [...filePackageMap.entries()].find(([, pkgId]) => pkgId === dep.targetPkg)?.[0];\n const srcLayer = srcFile ? fileLayerMap.get(srcFile)?.layerName : undefined;\n const tgtLayer = tgtFile ? fileLayerMap.get(tgtFile)?.layerName : undefined;\n if (!srcLayer || !tgtLayer || srcLayer === tgtLayer) continue;\n const srcLayerId = `layer:${srcLayer}`;\n const tgtLayerId = `layer:${tgtLayer}`;\n if (!layerDepCounts.has(srcLayerId)) layerDepCounts.set(srcLayerId, new Map());\n const inner = layerDepCounts.get(srcLayerId)!;\n inner.set(tgtLayerId, (inner.get(tgtLayerId) ?? 0) + dep.depCount);\n }\n\n const layerDeps: ArchLayerDep[] = [];\n for (const [srcLayer, targets] of layerDepCounts) {\n for (const [tgtLayer, count] of targets) {\n layerDeps.push({ sourceLayer: srcLayer, targetLayer: tgtLayer, depCount: count });\n }\n }\n\n // \u2500\u2500 8. Compute coupling metrics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const afferentMap = new Map<string, number>(); // Ca: who depends on me\n const efferentMap = new Map<string, number>(); // Ce: who I depend on\n for (const dep of packageDeps) {\n efferentMap.set(dep.sourcePkg, (efferentMap.get(dep.sourcePkg) ?? 0) + 1);\n afferentMap.set(dep.targetPkg, (afferentMap.get(dep.targetPkg) ?? 0) + 1);\n }\n const coupling: ArchCoupling[] = allPackages.map(pkg => {\n const ca = afferentMap.get(pkg.id) ?? 0;\n const ce = efferentMap.get(pkg.id) ?? 0;\n const instability = ca + ce === 0 ? 0 : ce / (ca + ce);\n return { packageId: pkg.id, afferent: ca, efferent: ce, instability, updatedAt: Date.now() };\n });\n\n // \u2500\u2500 9. Persist to DB \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: persisting to database');\n this.db.clearArchitecture();\n\n for (const pkg of allPackages) this.db.upsertArchPackage(pkg);\n for (const layer of allLayers) this.db.upsertArchLayer(layer);\n\n for (const [filePath, pkgId] of filePackageMap) this.db.upsertArchFilePackage(filePath, pkgId);\n for (const a of layerAssignments) {\n this.db.upsertArchFileLayer(a.filePath, `layer:${a.layerName}`, a.confidence, a.matchedPattern);\n }\n\n for (const dep of packageDeps) {\n this.db.upsertArchPackageDep(dep.sourcePkg, dep.targetPkg, dep.depCount, dep.files);\n }\n for (const dep of layerDeps) {\n this.db.upsertArchLayerDep(dep.sourceLayer, dep.targetLayer, dep.depCount);\n }\n for (const c of coupling) this.db.upsertArchCoupling(c);\n\n // Build return value\n const filePackages: Record<string, string[]> = {};\n for (const [filePath, pkgId] of filePackageMap) {\n if (!filePackages[filePath]) filePackages[filePath] = [];\n filePackages[filePath].push(pkgId);\n }\n\n const fileLayers: Record<string, Array<{ layerId: string; confidence: number; matchedPattern: string }>> = {};\n for (const a of layerAssignments) {\n fileLayers[a.filePath] = [{ layerId: `layer:${a.layerName}`, confidence: a.confidence, matchedPattern: a.matchedPattern }];\n }\n\n return { packages: allPackages, layers: allLayers, packageDeps, layerDeps, coupling, filePackages, fileLayers };\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,sBAAkC;AAClC,oBAA2E;AAEpE,MAAM,qBAAqB;AAAA,EAChC,YACmB,IACA,QACA,aACjB;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAEH,MAAM,QAAQ,YAAiE;AAC7E,UAAM,MAAM,CAAC,QAAgB,aAAa,GAAG;AAG7C,QAAI,iCAAiC;AACrC,UAAM,mBAAmB,UAAM,mCAAkB,KAAK,
|
|
4
|
+
"sourcesContent": ["/**\n * ArchitectureAnalyzer\n *\n * Orchestrates the full architecture analysis pipeline:\n * 1. Parse manifests \u2192 packages\n * 2. Directory-based fallback for uncovered file trees\n * 3. Detect layers from file paths\n * 4. Roll up package-to-package dependencies from existing import edges\n * 5. Roll up layer-to-layer dependencies\n * 6. Compute coupling metrics (Ca, Ce, instability)\n *\n * Only runs when enableArchitecture=true. Writes to arch_* tables in kirograph.db.\n */\nimport * as path from 'path';\nimport type { GraphDatabase } from '../db/database';\nimport type { KiroGraphConfig } from '../config';\nimport type {\n ArchPackage, ArchLayer, ArchPackageDep, ArchLayerDep, ArchCoupling, ArchitectureResult,\n} from './types';\nimport { parseAllManifests } from './manifest/index';\nimport { detectAllLayers, buildArchLayers, type FileLayerAssignment } from './layers/index';\n\nexport class ArchitectureAnalyzer {\n constructor(\n private readonly db: GraphDatabase,\n private readonly config: KiroGraphConfig,\n private readonly projectRoot: string,\n ) {}\n\n async analyze(onProgress?: (msg: string) => void): Promise<ArchitectureResult> {\n const log = (msg: string) => onProgress?.(msg);\n\n // \u2500\u2500 1. Parse manifests \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: parsing manifests');\n const manifestPackages = await parseAllManifests(this.projectRoot, {\n include: this.config.include,\n exclude: this.config.exclude,\n });\n\n // \u2500\u2500 2. Get all indexed files \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const allFiles = this.db.getAllFiles().map(f => f.path); // relative paths\n\n // \u2500\u2500 3. Assign files to packages (manifest-based) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: assigning files to packages');\n const filePackageMap = new Map<string, string>(); // filePath \u2192 packageId\n // Sort packages by path length desc so the most-specific package wins\n const sortedPkgs = [...manifestPackages].sort((a, b) => b.path.length - a.path.length);\n for (const file of allFiles) {\n for (const pkg of sortedPkgs) {\n const pkgPath = pkg.path === '.' ? '' : pkg.path + '/';\n if (pkg.path === '.' || file.startsWith(pkgPath)) {\n filePackageMap.set(file, pkg.id);\n break;\n }\n }\n }\n\n // \u2500\u2500 4. Directory-based fallback / subdivision \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n //\n // Three cases:\n // A) No manifests at all \u2192 group by top-level directory.\n // B) Root manifest (path='.') covers everything \u2192 subdivide its files into\n // second-level directory packages so internal structure is visible.\n // C) Manifests exist but don't cover the whole tree \u2192 create directory\n // packages for uncovered subdirectories (threshold: 3 files).\n //\n const SUBDIR_THRESHOLD = 1;\n const directoryPackages: ArchPackage[] = [];\n\n const rootManifestIds = new Set(manifestPackages.filter(p => p.path === '.').map(p => p.id));\n const hasRootManifest = rootManifestIds.size > 0;\n\n if (manifestPackages.length === 0) {\n // Case A: no manifests \u2014 group by top-level directory\n const topDirs = new Set<string>();\n for (const file of allFiles) {\n const parts = file.split('/');\n if (parts.length > 1) topDirs.add(parts[0]);\n }\n for (const dir of topDirs) {\n const pkgId = `pkg:dir:${dir}`;\n directoryPackages.push({ id: pkgId, name: dir, path: dir, source: 'directory', updatedAt: Date.now() });\n for (const file of allFiles) {\n if (file.startsWith(dir + '/')) filePackageMap.set(file, pkgId);\n }\n }\n } else if (hasRootManifest) {\n // Case B: root manifest(s) cover everything \u2014 subdivide into second-level dirs.\n // Collect files owned by a root manifest, then re-assign them to more specific\n // directory packages so internal module boundaries become visible.\n const rootOwnedFiles = allFiles.filter(f => rootManifestIds.has(filePackageMap.get(f) ?? ''));\n const subDirCounts = new Map<string, number>();\n for (const file of rootOwnedFiles) {\n const parts = file.split('/');\n if (parts.length > 2) {\n // Use two-level path (e.g. src/mcp) for granularity inside a src root\n const dir = parts.slice(0, 2).join('/');\n subDirCounts.set(dir, (subDirCounts.get(dir) ?? 0) + 1);\n }\n // Files directly at one level deep (e.g. src/index.ts) stay with the\n // root manifest package \u2014 no single-level dir package is created.\n }\n for (const [dir, count] of subDirCounts) {\n if (count >= SUBDIR_THRESHOLD) {\n const pkgId = `pkg:dir:${dir}`;\n const name = dir.split('/').pop() ?? dir;\n const pkg: ArchPackage = { id: pkgId, name, path: dir, source: 'directory', updatedAt: Date.now() };\n directoryPackages.push(pkg);\n for (const file of rootOwnedFiles) {\n if (file.startsWith(dir + '/') || file === dir) {\n filePackageMap.set(file, pkgId);\n }\n }\n }\n }\n } else {\n // Case C: manifests exist but don't cover root \u2014 create dir packages for uncovered files\n const uncovered = allFiles.filter(f => !filePackageMap.has(f));\n const subDirCounts = new Map<string, number>();\n for (const file of uncovered) {\n const parts = file.split('/');\n if (parts.length > 1) {\n const dir = parts.slice(0, 2).join('/');\n subDirCounts.set(dir, (subDirCounts.get(dir) ?? 0) + 1);\n }\n }\n for (const [dir, count] of subDirCounts) {\n if (count >= SUBDIR_THRESHOLD) {\n const pkgId = `pkg:dir:${dir}`;\n const name = dir.split('/').pop() ?? dir;\n const pkg: ArchPackage = { id: pkgId, name, path: dir, source: 'directory', updatedAt: Date.now() };\n directoryPackages.push(pkg);\n for (const file of uncovered) {\n if (file.startsWith(dir + '/') && !filePackageMap.has(file)) {\n filePackageMap.set(file, pkgId);\n }\n }\n }\n }\n }\n\n const allPackages = [...manifestPackages, ...directoryPackages];\n\n // \u2500\u2500 5. Detect layers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: detecting layers');\n const layerAssignments: FileLayerAssignment[] = [];\n const fileLayerMap = new Map<string, FileLayerAssignment>();\n\n if (this.config.architectureLayers !== undefined || this.config.enableArchitecture) {\n const assignments = await detectAllLayers(allFiles, this.projectRoot, this.config.architectureLayers);\n for (const a of assignments) {\n layerAssignments.push(a);\n fileLayerMap.set(a.filePath, a);\n }\n }\n\n const allLayers = buildArchLayers(layerAssignments, this.config.architectureLayers);\n\n // \u2500\u2500 6. Roll up package dependencies from import edges \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: rolling up package dependencies');\n const importPairs = this.db.getFileImportPairs();\n const pkgDepCounts = new Map<string, Map<string, { count: number; files: Array<{ from: string; to: string }> }>>();\n\n for (const { sourceFile, targetFile } of importPairs) {\n const sourcePkg = filePackageMap.get(sourceFile);\n const targetPkg = filePackageMap.get(targetFile);\n if (!sourcePkg || !targetPkg || sourcePkg === targetPkg) continue;\n\n if (!pkgDepCounts.has(sourcePkg)) pkgDepCounts.set(sourcePkg, new Map());\n const inner = pkgDepCounts.get(sourcePkg)!;\n if (!inner.has(targetPkg)) inner.set(targetPkg, { count: 0, files: [] });\n const entry = inner.get(targetPkg)!;\n entry.count++;\n if (entry.files.length < 5) entry.files.push({ from: sourceFile, to: targetFile });\n }\n\n const packageDeps: ArchPackageDep[] = [];\n for (const [sourcePkg, targets] of pkgDepCounts) {\n for (const [targetPkg, { count, files }] of targets) {\n packageDeps.push({ sourcePkg, targetPkg, depCount: count, files });\n }\n }\n\n // \u2500\u2500 7. Roll up layer dependencies \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const layerDepCounts = new Map<string, Map<string, number>>();\n for (const dep of packageDeps) {\n const srcFile = [...filePackageMap.entries()].find(([, pkgId]) => pkgId === dep.sourcePkg)?.[0];\n const tgtFile = [...filePackageMap.entries()].find(([, pkgId]) => pkgId === dep.targetPkg)?.[0];\n const srcLayer = srcFile ? fileLayerMap.get(srcFile)?.layerName : undefined;\n const tgtLayer = tgtFile ? fileLayerMap.get(tgtFile)?.layerName : undefined;\n if (!srcLayer || !tgtLayer || srcLayer === tgtLayer) continue;\n const srcLayerId = `layer:${srcLayer}`;\n const tgtLayerId = `layer:${tgtLayer}`;\n if (!layerDepCounts.has(srcLayerId)) layerDepCounts.set(srcLayerId, new Map());\n const inner = layerDepCounts.get(srcLayerId)!;\n inner.set(tgtLayerId, (inner.get(tgtLayerId) ?? 0) + dep.depCount);\n }\n\n const layerDeps: ArchLayerDep[] = [];\n for (const [srcLayer, targets] of layerDepCounts) {\n for (const [tgtLayer, count] of targets) {\n layerDeps.push({ sourceLayer: srcLayer, targetLayer: tgtLayer, depCount: count });\n }\n }\n\n // \u2500\u2500 8. Compute coupling metrics \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const afferentMap = new Map<string, number>(); // Ca: who depends on me\n const efferentMap = new Map<string, number>(); // Ce: who I depend on\n for (const dep of packageDeps) {\n efferentMap.set(dep.sourcePkg, (efferentMap.get(dep.sourcePkg) ?? 0) + 1);\n afferentMap.set(dep.targetPkg, (afferentMap.get(dep.targetPkg) ?? 0) + 1);\n }\n const coupling: ArchCoupling[] = allPackages.map(pkg => {\n const ca = afferentMap.get(pkg.id) ?? 0;\n const ce = efferentMap.get(pkg.id) ?? 0;\n const instability = ca + ce === 0 ? 0 : ce / (ca + ce);\n return { packageId: pkg.id, afferent: ca, efferent: ce, instability, updatedAt: Date.now() };\n });\n\n // \u2500\u2500 9. Persist to DB \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n log('architecture: persisting to database');\n this.db.clearArchitecture();\n\n for (const pkg of allPackages) this.db.upsertArchPackage(pkg);\n for (const layer of allLayers) this.db.upsertArchLayer(layer);\n\n for (const [filePath, pkgId] of filePackageMap) this.db.upsertArchFilePackage(filePath, pkgId);\n for (const a of layerAssignments) {\n this.db.upsertArchFileLayer(a.filePath, `layer:${a.layerName}`, a.confidence, a.matchedPattern);\n }\n\n for (const dep of packageDeps) {\n this.db.upsertArchPackageDep(dep.sourcePkg, dep.targetPkg, dep.depCount, dep.files);\n }\n for (const dep of layerDeps) {\n this.db.upsertArchLayerDep(dep.sourceLayer, dep.targetLayer, dep.depCount);\n }\n for (const c of coupling) this.db.upsertArchCoupling(c);\n\n // Build return value\n const filePackages: Record<string, string[]> = {};\n for (const [filePath, pkgId] of filePackageMap) {\n if (!filePackages[filePath]) filePackages[filePath] = [];\n filePackages[filePath].push(pkgId);\n }\n\n const fileLayers: Record<string, Array<{ layerId: string; confidence: number; matchedPattern: string }>> = {};\n for (const a of layerAssignments) {\n fileLayers[a.filePath] = [{ layerId: `layer:${a.layerName}`, confidence: a.confidence, matchedPattern: a.matchedPattern }];\n }\n\n return { packages: allPackages, layers: allLayers, packageDeps, layerDeps, coupling, filePackages, fileLayers };\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -91,8 +91,19 @@ function registerManifestParser(parser) {
|
|
|
91
91
|
if (idx >= 0) MANIFEST_PARSERS[idx] = parser;
|
|
92
92
|
else MANIFEST_PARSERS.push(parser);
|
|
93
93
|
}
|
|
94
|
-
async function parseAllManifests(projectRoot) {
|
|
95
|
-
|
|
94
|
+
async function parseAllManifests(projectRoot, scanOptions) {
|
|
95
|
+
let manifestPaths = _findManifests(projectRoot);
|
|
96
|
+
if (scanOptions?.include && scanOptions.include.length > 0) {
|
|
97
|
+
const picomatch = require("picomatch");
|
|
98
|
+
const includeMatchers = scanOptions.include.map((p) => picomatch(p));
|
|
99
|
+
const excludeMatchers = (scanOptions.exclude ?? []).map((p) => picomatch(p));
|
|
100
|
+
manifestPaths = manifestPaths.filter((absPath) => {
|
|
101
|
+
const rel = path.relative(projectRoot, absPath).replace(/\\/g, "/");
|
|
102
|
+
const included = includeMatchers.some((m) => m(rel));
|
|
103
|
+
if (!included) return false;
|
|
104
|
+
return !excludeMatchers.some((m) => m(rel));
|
|
105
|
+
});
|
|
106
|
+
}
|
|
96
107
|
const all = [];
|
|
97
108
|
const seenIds = /* @__PURE__ */ new Set();
|
|
98
109
|
for (const manifestPath of manifestPaths) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/architecture/manifest/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Manifest Parser Registry\n *\n * Discovers and dispatches manifest parsers. Each parser handles one or more\n * manifest file types. The registry walks the project looking for manifest files\n * and assigns them to the correct parser.\n */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ManifestParser, ArchPackage } from '../types';\nimport { npmParser } from './npm';\nimport { goParser } from './go';\nimport { cargoParser } from './cargo';\nimport { pythonParser } from './python';\nimport { mavenParser } from './maven';\nimport { gradleParser } from './gradle';\nimport { csprojParser } from './csproj';\nimport { sbtParser } from './scala';\nimport { ocamlParser } from './ocaml';\nimport { elmParser } from './elm';\n\n// All registered manifest parsers, in priority order\nconst MANIFEST_PARSERS: ManifestParser[] = [\n npmParser,\n goParser,\n cargoParser,\n pythonParser,\n mavenParser,\n gradleParser,\n csprojParser,\n sbtParser,\n ocamlParser,\n elmParser,\n];\n\n// All manifest filenames we care about (for fast lookup during directory walk)\nconst MANIFEST_FILENAMES = new Set(\n MANIFEST_PARSERS.flatMap(p => p.manifestFiles)\n);\n\n// Directories to never descend into when scanning for manifests\nconst SKIP_DIRS = new Set([\n 'node_modules', '.git', 'dist', 'build', 'target', '.gradle', '__pycache__',\n '.kirograph', 'vendor', '.cache', 'coverage', '.nyc_output', '_build', '_opam',\n 'elm-stuff', 'zig-cache', 'zig-out',\n]);\n\nexport function getAllManifestParsers(): ManifestParser[] {\n return MANIFEST_PARSERS;\n}\n\nexport function getManifestParser(name: string): ManifestParser | undefined {\n return MANIFEST_PARSERS.find(p => p.name === name);\n}\n\nexport function registerManifestParser(parser: ManifestParser): void {\n const idx = MANIFEST_PARSERS.findIndex(p => p.name === parser.name);\n if (idx >= 0) MANIFEST_PARSERS[idx] = parser;\n else MANIFEST_PARSERS.push(parser);\n}\n\n/**\n * Walk projectRoot looking for manifest files, parse each, deduplicate, and\n * return all detected packages. Packages from manifests take priority; the\n * deduplication ensures that a workspace root pom.xml and a sub-module\n * pom.xml don't produce overlapping directory mappings.\n */\nexport async function parseAllManifests(projectRoot: string): Promise<ArchPackage[]> {\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,SAAoB;AACpB,WAAsB;AAEtB,iBAA0B;AAC1B,gBAAyB;AACzB,mBAA4B;AAC5B,oBAA6B;AAC7B,mBAA4B;AAC5B,oBAA6B;AAC7B,oBAA6B;AAC7B,mBAA0B;AAC1B,mBAA4B;AAC5B,iBAA0B;AAG1B,MAAM,mBAAqC;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,MAAM,qBAAqB,IAAI;AAAA,EAC7B,iBAAiB,QAAQ,OAAK,EAAE,aAAa;AAC/C;AAGA,MAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EAAgB;AAAA,EAAQ;AAAA,EAAQ;AAAA,EAAS;AAAA,EAAU;AAAA,EAAW;AAAA,EAC9D;AAAA,EAAc;AAAA,EAAU;AAAA,EAAU;AAAA,EAAY;AAAA,EAAe;AAAA,EAAU;AAAA,EACvE;AAAA,EAAa;AAAA,EAAa;AAC5B,CAAC;AAEM,SAAS,wBAA0C;AACxD,SAAO;AACT;AAEO,SAAS,kBAAkB,MAA0C;AAC1E,SAAO,iBAAiB,KAAK,OAAK,EAAE,SAAS,IAAI;AACnD;AAEO,SAAS,uBAAuB,QAA8B;AACnE,QAAM,MAAM,iBAAiB,UAAU,OAAK,EAAE,SAAS,OAAO,IAAI;AAClE,MAAI,OAAO,EAAG,kBAAiB,GAAG,IAAI;AAAA,MACjC,kBAAiB,KAAK,MAAM;AACnC;
|
|
4
|
+
"sourcesContent": ["/**\n * Manifest Parser Registry\n *\n * Discovers and dispatches manifest parsers. Each parser handles one or more\n * manifest file types. The registry walks the project looking for manifest files\n * and assigns them to the correct parser.\n */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ManifestParser, ArchPackage } from '../types';\nimport { npmParser } from './npm';\nimport { goParser } from './go';\nimport { cargoParser } from './cargo';\nimport { pythonParser } from './python';\nimport { mavenParser } from './maven';\nimport { gradleParser } from './gradle';\nimport { csprojParser } from './csproj';\nimport { sbtParser } from './scala';\nimport { ocamlParser } from './ocaml';\nimport { elmParser } from './elm';\n\n// All registered manifest parsers, in priority order\nconst MANIFEST_PARSERS: ManifestParser[] = [\n npmParser,\n goParser,\n cargoParser,\n pythonParser,\n mavenParser,\n gradleParser,\n csprojParser,\n sbtParser,\n ocamlParser,\n elmParser,\n];\n\n// All manifest filenames we care about (for fast lookup during directory walk)\nconst MANIFEST_FILENAMES = new Set(\n MANIFEST_PARSERS.flatMap(p => p.manifestFiles)\n);\n\n// Directories to never descend into when scanning for manifests\nconst SKIP_DIRS = new Set([\n 'node_modules', '.git', 'dist', 'build', 'target', '.gradle', '__pycache__',\n '.kirograph', 'vendor', '.cache', 'coverage', '.nyc_output', '_build', '_opam',\n 'elm-stuff', 'zig-cache', 'zig-out',\n]);\n\nexport function getAllManifestParsers(): ManifestParser[] {\n return MANIFEST_PARSERS;\n}\n\nexport function getManifestParser(name: string): ManifestParser | undefined {\n return MANIFEST_PARSERS.find(p => p.name === name);\n}\n\nexport function registerManifestParser(parser: ManifestParser): void {\n const idx = MANIFEST_PARSERS.findIndex(p => p.name === parser.name);\n if (idx >= 0) MANIFEST_PARSERS[idx] = parser;\n else MANIFEST_PARSERS.push(parser);\n}\n\nexport interface ManifestScanOptions {\n include?: string[];\n exclude?: string[];\n}\n\n/**\n * Walk projectRoot looking for manifest files, parse each, deduplicate, and\n * return all detected packages. Packages from manifests take priority; the\n * deduplication ensures that a workspace root pom.xml and a sub-module\n * pom.xml don't produce overlapping directory mappings.\n *\n * When scanOptions.include is provided, only manifests within included paths\n * are processed (aligning with the code graph scope).\n */\nexport async function parseAllManifests(projectRoot: string, scanOptions?: ManifestScanOptions): Promise<ArchPackage[]> {\n let manifestPaths = _findManifests(projectRoot);\n\n // Filter by include/exclude if provided\n if (scanOptions?.include && scanOptions.include.length > 0) {\n const picomatch = require('picomatch');\n const includeMatchers = scanOptions.include.map((p: string) => picomatch(p));\n const excludeMatchers = (scanOptions.exclude ?? []).map((p: string) => picomatch(p));\n manifestPaths = manifestPaths.filter(absPath => {\n const rel = path.relative(projectRoot, absPath).replace(/\\\\/g, '/');\n const included = includeMatchers.some((m: (s: string) => boolean) => m(rel));\n if (!included) return false;\n return !excludeMatchers.some((m: (s: string) => boolean) => m(rel));\n });\n }\n\n const all: ArchPackage[] = [];\n const seenIds = new Set<string>();\n\n for (const manifestPath of manifestPaths) {\n const parser = MANIFEST_PARSERS.find(p => p.canParse(manifestPath));\n if (!parser) continue;\n try {\n const pkgs = await parser.parse(manifestPath, projectRoot);\n for (const pkg of pkgs) {\n if (!seenIds.has(pkg.id)) {\n seenIds.add(pkg.id);\n all.push(pkg);\n }\n }\n } catch {\n // Ignore parse errors for individual manifests\n }\n }\n\n return all;\n}\n\nfunction _findManifests(dir: string, results: string[] = []): string[] {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (!SKIP_DIRS.has(entry.name)) {\n _findManifests(path.join(dir, entry.name), results);\n }\n } else if (entry.isFile()) {\n // Check exact filename or extension match\n if (MANIFEST_FILENAMES.has(entry.name) || entry.name.endsWith('.csproj')) {\n results.push(path.join(dir, entry.name));\n }\n }\n }\n\n return results;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -65,7 +65,8 @@ const INSTALL_TARGETS = [
|
|
|
65
65
|
"iflow",
|
|
66
66
|
"qwen",
|
|
67
67
|
"rovo",
|
|
68
|
-
"qoder"
|
|
68
|
+
"qoder",
|
|
69
|
+
"commandcode"
|
|
69
70
|
];
|
|
70
71
|
function register(program) {
|
|
71
72
|
program.command("install").description("Configure KiroGraph for an agent workspace").option("--target <target>", `Integration target: ${INSTALL_TARGETS.join(", ")}`).option("--all", "Install for all auto-detected platforms without prompting").option("--yes", "Skip confirmation prompts and use existing config (non-interactive mode)").option("--dry-run", "Show what would be written without making changes").action(async (opts) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/commands/install.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command } from 'commander';\n\nconst INSTALL_TARGETS = [\n 'kiro', 'claude', 'codex', 'cursor', 'antigravity', 'opencode',\n 'windsurf', 'cline', 'copilot', 'copilot-cli', 'junie', 'gemini-cli',\n 'continue', 'roo', 'warp', 'aider', 'trae',\n 'augment', 'kilo', 'amp', 'devin', 'replit', 'goose', 'openhands', 'tabnine',\n 'mistral-vibe', 'ibm-bob', 'crush', 'droid-factory', 'forgecode', 'iflow', 'qwen', 'rovo', 'qoder',\n];\n\nexport function register(program: Command): void {\n program\n .command('install')\n .description('Configure KiroGraph for an agent workspace')\n .option('--target <target>', `Integration target: ${INSTALL_TARGETS.join(', ')}`)\n .option('--all', 'Install for all auto-detected platforms without prompting')\n .option('--yes', 'Skip confirmation prompts and use existing config (non-interactive mode)')\n .option('--dry-run', 'Show what would be written without making changes')\n .action(async (opts: { target?: string; all?: boolean; yes?: boolean; dryRun?: boolean }) => {\n if (opts.target) {\n // Explicit target: validate and install\n const target = opts.target.toLowerCase();\n if (target !== 'all' && !INSTALL_TARGETS.includes(target)) {\n console.error(`Unknown install target: ${opts.target}. Choose from: ${INSTALL_TARGETS.join(', ')}`);\n process.exit(1);\n }\n\n if (target === 'all') {\n // --target all is an alias for --all\n const { runAutoDetectInstaller } = await Promise.resolve().then(() => require('../installer/auto-detect.js'));\n await runAutoDetectInstaller({ skipPrompt: true, dryRun: opts.dryRun });\n } else {\n const { runInstaller } = await Promise.resolve().then(() => require('../installer/index.js'));\n await runInstaller(target as any, { yes: opts.yes });\n }\n } else if (opts.all) {\n // --all flag: auto-detect and install all without prompting\n const { runAutoDetectInstaller } = await Promise.resolve().then(() => require('../installer/auto-detect.js'));\n await runAutoDetectInstaller({ skipPrompt: true, dryRun: opts.dryRun });\n } else {\n // No target specified: ask Kiro-only vs auto-detect\n const readline = await import('readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const bold = '\\x1b[1m';\n const dim = '\\x1b[2m';\n const violet = '\\x1b[38;5;99m';\n const reset = '\\x1b[0m';\n const { printBanner } = await Promise.resolve().then(() => require('../banner.js'));\n printBanner();\n console.log(` ${bold}How do you want to install KiroGraph?${reset}\\n`);\n console.log(` ${violet}1${reset} Kiro only ${dim}(recommended \u2014 full support with IDE hooks, steering, CLI agent)${reset}`);\n console.log(` ${violet}2${reset} Auto-detect ${dim}(configure all AI tools found in this environment)${reset}\\n`);\n const answer = await new Promise<string>((resolve) => {\n rl.question(` Choose [1/2]: `, resolve);\n });\n rl.close();\n console.log();\n const choice = answer.trim();\n if (choice === '2') {\n const { runAutoDetectInstaller } = await Promise.resolve().then(() => require('../installer/auto-detect.js'));\n await runAutoDetectInstaller({ skipPrompt: false, skipBanner: true, dryRun: opts.dryRun });\n } else {\n // Default to Kiro (choice === '1' or Enter)\n const { runInstaller } = await Promise.resolve().then(() => require('../installer/index.js'));\n await runInstaller('kiro', { yes: opts.yes });\n }\n }\n });\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,MAAM,kBAAkB;AAAA,EACtB;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAe;AAAA,EACpD;AAAA,EAAY;AAAA,EAAS;AAAA,EAAW;AAAA,EAAe;AAAA,EAAS;AAAA,EACxD;AAAA,EAAY;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EACpC;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAa;AAAA,EACnE;AAAA,EAAgB;AAAA,EAAW;AAAA,EAAS;AAAA,EAAiB;AAAA,EAAa;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\n\nconst INSTALL_TARGETS = [\n 'kiro', 'claude', 'codex', 'cursor', 'antigravity', 'opencode',\n 'windsurf', 'cline', 'copilot', 'copilot-cli', 'junie', 'gemini-cli',\n 'continue', 'roo', 'warp', 'aider', 'trae',\n 'augment', 'kilo', 'amp', 'devin', 'replit', 'goose', 'openhands', 'tabnine',\n 'mistral-vibe', 'ibm-bob', 'crush', 'droid-factory', 'forgecode', 'iflow', 'qwen', 'rovo', 'qoder', 'commandcode',\n];\n\nexport function register(program: Command): void {\n program\n .command('install')\n .description('Configure KiroGraph for an agent workspace')\n .option('--target <target>', `Integration target: ${INSTALL_TARGETS.join(', ')}`)\n .option('--all', 'Install for all auto-detected platforms without prompting')\n .option('--yes', 'Skip confirmation prompts and use existing config (non-interactive mode)')\n .option('--dry-run', 'Show what would be written without making changes')\n .action(async (opts: { target?: string; all?: boolean; yes?: boolean; dryRun?: boolean }) => {\n if (opts.target) {\n // Explicit target: validate and install\n const target = opts.target.toLowerCase();\n if (target !== 'all' && !INSTALL_TARGETS.includes(target)) {\n console.error(`Unknown install target: ${opts.target}. Choose from: ${INSTALL_TARGETS.join(', ')}`);\n process.exit(1);\n }\n\n if (target === 'all') {\n // --target all is an alias for --all\n const { runAutoDetectInstaller } = await Promise.resolve().then(() => require('../installer/auto-detect.js'));\n await runAutoDetectInstaller({ skipPrompt: true, dryRun: opts.dryRun });\n } else {\n const { runInstaller } = await Promise.resolve().then(() => require('../installer/index.js'));\n await runInstaller(target as any, { yes: opts.yes });\n }\n } else if (opts.all) {\n // --all flag: auto-detect and install all without prompting\n const { runAutoDetectInstaller } = await Promise.resolve().then(() => require('../installer/auto-detect.js'));\n await runAutoDetectInstaller({ skipPrompt: true, dryRun: opts.dryRun });\n } else {\n // No target specified: ask Kiro-only vs auto-detect\n const readline = await import('readline');\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n const bold = '\\x1b[1m';\n const dim = '\\x1b[2m';\n const violet = '\\x1b[38;5;99m';\n const reset = '\\x1b[0m';\n const { printBanner } = await Promise.resolve().then(() => require('../banner.js'));\n printBanner();\n console.log(` ${bold}How do you want to install KiroGraph?${reset}\\n`);\n console.log(` ${violet}1${reset} Kiro only ${dim}(recommended \u2014 full support with IDE hooks, steering, CLI agent)${reset}`);\n console.log(` ${violet}2${reset} Auto-detect ${dim}(configure all AI tools found in this environment)${reset}\\n`);\n const answer = await new Promise<string>((resolve) => {\n rl.question(` Choose [1/2]: `, resolve);\n });\n rl.close();\n console.log();\n const choice = answer.trim();\n if (choice === '2') {\n const { runAutoDetectInstaller } = await Promise.resolve().then(() => require('../installer/auto-detect.js'));\n await runAutoDetectInstaller({ skipPrompt: false, skipBanner: true, dryRun: opts.dryRun });\n } else {\n // Default to Kiro (choice === '1' or Enter)\n const { runInstaller } = await Promise.resolve().then(() => require('../installer/index.js'));\n await runInstaller('kiro', { yes: opts.yes });\n }\n }\n });\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -206,7 +206,8 @@ async function showIntegrations(projectRoot) {
|
|
|
206
206
|
"amp": { path: path.join(projectRoot, ".amp", "config.json"), key: "mcpServers" },
|
|
207
207
|
"cline": { path: path.join(projectRoot, ".cline", "mcp_settings.json"), key: "mcpServers" },
|
|
208
208
|
"qoder": { path: path.join(projectRoot, ".qoder", "mcp.json"), key: "mcpServers" },
|
|
209
|
-
"qwen": { path: path.join(home, ".qwen", "settings.json"), key: "mcpServers" }
|
|
209
|
+
"qwen": { path: path.join(home, ".qwen", "settings.json"), key: "mcpServers" },
|
|
210
|
+
"commandcode": { path: path.join(projectRoot, ".mcp.json"), key: "mcpServers" }
|
|
210
211
|
};
|
|
211
212
|
function isConfigured(target) {
|
|
212
213
|
const check = configChecks[target];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/commands/status.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport { dim, reset, violet, bold, green, label, value, section, renderTable } from '../ui';\nimport { loadConfig } from '../../config';\nimport { readTurboQuantStats } from '../../vectors/turboquant-index';\n\nexport function register(program: Command): void {\n program\n .command('status [projectPath]')\n .description('Show index statistics')\n .option('--integrations', 'Show detected and configured platforms')\n .action(async (projectPath: string | undefined, opts: { integrations?: boolean }) => {\n const target = path.resolve(projectPath ?? process.cwd());\n\n if (opts.integrations) {\n await showIntegrations(target);\n return;\n }\n\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cg = await KiroGraph.open(target);\n const stats = await cg.getStats();\n\n console.log();\n console.log(section(' Graph'));\n console.log(` ${label('Files')} ${value(String(stats.files))}`);\n console.log(` ${label('Symbols')} ${value(String(stats.nodes))}`);\n console.log(` ${label('Edges')} ${value(String(stats.edges))}`);\n\n if (stats.frameworks.length > 0) {\n console.log(` ${label('Frameworks')} ${value(stats.frameworks.join(', '))}`);\n }\n\n const kindEntries = Object.entries(stats.nodesByKind).sort((a, b) => b[1] - a[1]);\n if (kindEntries.length > 0) {\n console.log(`\\n ${label('By kind')}`);\n console.log(renderTable(kindEntries.map(([k, v]) => [k, String(v)])));\n }\n\n const langEntries = Object.entries(stats.filesByLanguage ?? {}).sort((a, b) => b[1] - a[1]);\n if (langEntries.length > 0) {\n console.log(`\\n ${label('By language')}`);\n console.log(renderTable(langEntries.map(([k, v]) => [k, String(v)])));\n }\n\n // Sync state\n const threshold = stats.syncWarningThreshold ?? 10;\n const pendingFiles: number = stats.pendingFiles ?? 0;\n const syncRunning: boolean = stats.syncRunning ?? false;\n console.log();\n console.log(section(' Sync'));\n if (syncRunning) {\n console.log(` ${'\\x1b[33m'}\u26A0 Sync is currently running in the background.${reset}`);\n } else {\n console.log(` ${label('Status')} ${dim}idle${reset}`);\n }\n if (pendingFiles > 0) {\n const warn = threshold > 0 && pendingFiles >= threshold;\n const pendingLabel = warn ? `${'\\x1b[33m'}${pendingFiles} files pending${reset}` : `${dim}${pendingFiles} files pending${reset}`;\n console.log(` ${label('Pending')} ${pendingLabel}`);\n if (warn) {\n console.log(` ${'\\x1b[33m'}\u26A0 Index may be stale. Run \\`kirograph sync\\` to update.${reset}`);\n }\n } else {\n console.log(` ${label('Pending')} ${green}up to date${reset}`);\n }\n\n console.log();\n console.log(section(' Semantic Search'));\n if (stats.embeddingsEnabled) {\n const tqStats = stats.semanticEngine === 'turboquant'\n ? readTurboQuantStats(path.join(target, '.kirograph'))\n : null;\n const engineLabel =\n stats.semanticEngine === 'turboquant' ? `turboquant ${dim}(${stats.vecIndexCount} entries \u00B7 ${tqStats ? `${tqStats.bits} bits \u00B7 ${tqStats.compressionRatio.toFixed(1)}\u00D7 compression` : 'not yet indexed'})${reset}` :\n stats.semanticEngine === 'sqlite-vec' ? `sqlite-vec ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'orama' ? `orama ${dim}(hybrid \u2014 ${stats.vecIndexCount} docs in index)${reset}` :\n stats.semanticEngine === 'pglite' ? `pglite+pgvector ${dim}(hybrid \u2014 ${stats.vecIndexCount} rows in DB)${reset}` :\n stats.semanticEngine === 'lancedb' ? `lancedb ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'qdrant' ? `qdrant ${dim}(${stats.vecIndexCount} points in collection)${reset}` :\n stats.semanticEngine === 'typesense' ? `typesense ${dim}(${stats.vecIndexCount} documents in collection)${reset}` :\n stats.semanticEngine === 'turbovec' ? `turbovec ${dim}(${stats.vecIndexCount} entries \u00B7 ${stats.turbovecBits ?? 4} bits \u00B7 Rust/SIMD)${reset}` :\n `in-process cosine`;\n const total = stats.embeddableNodeCount > 0 ? stats.embeddableNodeCount : stats.nodes;\n const displayed = Math.min(stats.embeddingCount, total);\n const coverage = total > 0 ? Math.min(100, Math.round((stats.embeddingCount / total) * 100)) : 0;\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n console.log(` ${label('Model')} ${value(stats.embeddingModel)}`);\n console.log(` ${label('Engine')} ${violet}${engineLabel}${reset}`);\n if (stats.engineFallback) {\n console.log(` ${'\\x1b[33m'}\u26A0 engine fallback: ${stats.engineFallback}${reset}`);\n }\n console.log(` ${label('Indexed')} ${value(`${displayed} / ${total}`)} ${dim}(${coverage}%)${reset}`);\n if (tqStats) {\n const rawMB = (tqStats.rawBytes / 1_048_576).toFixed(1);\n const compMB = (tqStats.actualBytes / 1_048_576).toFixed(1);\n const savedMB = (tqStats.savedBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Raw size')} ${dim}${rawMB} MB \u2192 compressed ${compMB} MB (${savedMB} MB saved)${reset}`);\n if (tqStats.memEnabled && tqStats.memCount > 0) {\n const mRawMB = (tqStats.memRawBytes / 1_048_576).toFixed(1);\n const mCompMB = (tqStats.memActualBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Memory')} ${dim}${tqStats.memCount} observations \u2192 ${mRawMB} MB \u2192 ${mCompMB} MB${reset}`);\n }\n if (tqStats.docsEnabled && tqStats.docsCount > 0) {\n const dRawMB = (tqStats.docsRawBytes / 1_048_576).toFixed(1);\n const dCompMB = (tqStats.docsActualBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Docs')} ${dim}${tqStats.docsCount} sections \u2192 ${dRawMB} MB \u2192 ${dCompMB} MB${reset}`);\n }\n const totalSaved = tqStats.savedBytes + (tqStats.memRawBytes - tqStats.memActualBytes) + (tqStats.docsRawBytes - tqStats.docsActualBytes);\n if (totalSaved > 0) {\n console.log(` ${label('Total RAM')} ${green}${(totalSaved / 1_048_576).toFixed(1)} MB saved${reset} ${dim}(TurboQuant compression)${reset}`);\n }\n }\n } else {\n console.log(` ${label('Status')} ${dim}disabled${reset}`);\n }\n\n // Pattern SAST section\n try {\n const patConfig = await loadConfig(target);\n if (patConfig.enablePatterns) {\n const db2 = cg.getDatabase();\n (db2 as any).applyPatternsSchema?.();\n const rawDb2 = db2.getRawDb();\n const tableExists = rawDb2.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExists) {\n const matchCount = (rawDb2.get('SELECT COUNT(*) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const fileCount = (rawDb2.get('SELECT COUNT(DISTINCT file_path) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const ruleCount = (rawDb2.get('SELECT COUNT(DISTINCT pattern_id) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n if (matchCount > 0) {\n console.log(` ${label('Matches')} ${value(String(matchCount))} ${dim}across ${fileCount} files, ${ruleCount} rules triggered${reset}`);\n } else {\n console.log(` ${label('Matches')} ${dim}none yet \u2014 run kirograph index${reset}`);\n }\n } else {\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset} ${dim}(not yet indexed \u2014 run kirograph index)${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n // Security stats (conditional on enableSecurity)\n try {\n const config = await loadConfig(target);\n if (config.enableSecurity) {\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n const depCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies')?.cnt ?? 0;\n const vulnCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_vulnerabilities')?.cnt ?? 0;\n const affectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'affected'\")?.cnt ?? 0;\n const notAffectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'not_affected'\")?.cnt ?? 0;\n const investigatingCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'under_investigation'\")?.cnt ?? 0;\n const staleCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies WHERE vuln_data_stale = 1')?.cnt ?? 0;\n\n console.log();\n console.log(section(' \uD83D\uDD12 Security'));\n console.log(` ${label('Dependencies')} ${value(String(depCount))}`);\n console.log(` ${label('Vulnerabilities')} ${value(String(vulnCount))}`);\n\n if (vulnCount > 0) {\n const affectedLabel = affectedCount > 0\n ? `${'\\x1b[31m'}${affectedCount} affected${reset}`\n : `${dim}0 affected${reset}`;\n console.log(` ${label('Affected')} ${affectedLabel}`);\n console.log(` ${label('Not Affected')} ${dim}${notAffectedCount}${reset}`);\n console.log(` ${label('Investigating')} ${dim}${investigatingCount}${reset}`);\n }\n\n if (staleCount > 0) {\n console.log(` ${'\\x1b[33m'}\u26A0 ${staleCount} dependenc${staleCount === 1 ? 'y has' : 'ies have'} stale vulnerability data. Run \\`kirograph vulns --refresh\\` to update.${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n console.log();\n cg.close();\n });\n}\n\nasync function showIntegrations(projectRoot: string): Promise<void> {\n const fs = await import('fs');\n const { detectPlatforms } = await Promise.resolve().then(() => require('../installer/detect.js'));\n const { readJson, KIROGRAPH_SERVER_NAME } = await Promise.resolve().then(() => require('../installer/common.js'));\n\n const detected = detectPlatforms(projectRoot);\n const home = process.env.HOME || process.env.USERPROFILE || '';\n\n // Map of target \u2192 config path to check if kirograph is configured\n const configChecks: Record<string, { path: string; key: string }> = {\n 'kiro': { path: path.join(projectRoot, '.kiro', 'settings', 'mcp.json'), key: 'mcpServers' },\n 'claude': { path: path.join(projectRoot, '.mcp.json'), key: 'mcpServers' },\n 'cursor': { path: path.join(projectRoot, '.cursor', 'mcp.json'), key: 'mcpServers' },\n 'windsurf': { path: path.join(home, '.codeium', 'windsurf', 'mcp_config.json'), key: 'mcpServers' },\n 'codex': { path: path.join(projectRoot, '.codex', 'hooks.json'), key: 'hooks' },\n 'copilot': { path: path.join(projectRoot, '.vscode', 'mcp.json'), key: 'servers' },\n 'copilot-cli': { path: path.join(home, '.copilot', 'mcp-config.json'), key: 'servers' },\n 'gemini-cli': { path: path.join(projectRoot, '.gemini', 'settings.json'), key: 'mcpServers' },\n 'continue': { path: path.join(projectRoot, '.continue', 'mcpServers', 'kirograph.json'), key: 'mcpServers' },\n 'opencode': { path: path.join(projectRoot, '.opencode.json'), key: 'mcp' },\n 'antigravity': { path: path.join(home, '.gemini', 'antigravity', 'mcp_config.json'), key: 'mcpServers' },\n 'roo': { path: path.join(projectRoot, '.roo', 'mcp.json'), key: 'mcpServers' },\n 'warp': { path: path.join(projectRoot, '.warp', '.mcp.json'), key: 'mcpServers' },\n 'trae': { path: path.join(projectRoot, '.trae', 'mcp.json'), key: 'mcpServers' },\n 'amp': { path: path.join(projectRoot, '.amp', 'config.json'), key: 'mcpServers' },\n 'cline': { path: path.join(projectRoot, '.cline', 'mcp_settings.json'), key: 'mcpServers' },\n 'qoder': { path: path.join(projectRoot, '.qoder', 'mcp.json'), key: 'mcpServers' },\n 'qwen': { path: path.join(home, '.qwen', 'settings.json'), key: 'mcpServers' },\n };\n\n function isConfigured(target: string): boolean {\n const check = configChecks[target];\n if (!check) return false;\n if (!fs.existsSync(check.path)) return false;\n const config = readJson(check.path);\n const container = config[check.key];\n if (!container) return false;\n if (typeof container === 'object' && !Array.isArray(container)) {\n return KIROGRAPH_SERVER_NAME in container;\n }\n return false;\n }\n\n const configured = detected.filter(d => isConfigured(d.target));\n const notConfigured = detected.filter(d => !isConfigured(d.target));\n\n console.log();\n console.log(section(' Integrations'));\n console.log();\n\n if (configured.length > 0) {\n console.log(` ${label('Configured:')}`);\n for (const d of configured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${green}\u2713${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n }\n\n if (notConfigured.length > 0) {\n if (configured.length > 0) console.log();\n console.log(` ${label('Detected but not configured:')}`);\n for (const d of notConfigured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${dim}\u25CB${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n console.log();\n console.log(` ${dim}Run \\`kirograph install\\` to configure detected platforms.${reset}`);\n }\n\n if (detected.length === 0) {\n console.log(` ${dim}No AI coding platforms detected.${reset}`);\n }\n\n console.log();\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport { dim, reset, violet, bold, green, label, value, section, renderTable } from '../ui';\nimport { loadConfig } from '../../config';\nimport { readTurboQuantStats } from '../../vectors/turboquant-index';\n\nexport function register(program: Command): void {\n program\n .command('status [projectPath]')\n .description('Show index statistics')\n .option('--integrations', 'Show detected and configured platforms')\n .action(async (projectPath: string | undefined, opts: { integrations?: boolean }) => {\n const target = path.resolve(projectPath ?? process.cwd());\n\n if (opts.integrations) {\n await showIntegrations(target);\n return;\n }\n\n const KiroGraph = (await Promise.resolve().then(() => require('../../index.js'))).default;\n const cg = await KiroGraph.open(target);\n const stats = await cg.getStats();\n\n console.log();\n console.log(section(' Graph'));\n console.log(` ${label('Files')} ${value(String(stats.files))}`);\n console.log(` ${label('Symbols')} ${value(String(stats.nodes))}`);\n console.log(` ${label('Edges')} ${value(String(stats.edges))}`);\n\n if (stats.frameworks.length > 0) {\n console.log(` ${label('Frameworks')} ${value(stats.frameworks.join(', '))}`);\n }\n\n const kindEntries = Object.entries(stats.nodesByKind).sort((a, b) => b[1] - a[1]);\n if (kindEntries.length > 0) {\n console.log(`\\n ${label('By kind')}`);\n console.log(renderTable(kindEntries.map(([k, v]) => [k, String(v)])));\n }\n\n const langEntries = Object.entries(stats.filesByLanguage ?? {}).sort((a, b) => b[1] - a[1]);\n if (langEntries.length > 0) {\n console.log(`\\n ${label('By language')}`);\n console.log(renderTable(langEntries.map(([k, v]) => [k, String(v)])));\n }\n\n // Sync state\n const threshold = stats.syncWarningThreshold ?? 10;\n const pendingFiles: number = stats.pendingFiles ?? 0;\n const syncRunning: boolean = stats.syncRunning ?? false;\n console.log();\n console.log(section(' Sync'));\n if (syncRunning) {\n console.log(` ${'\\x1b[33m'}\u26A0 Sync is currently running in the background.${reset}`);\n } else {\n console.log(` ${label('Status')} ${dim}idle${reset}`);\n }\n if (pendingFiles > 0) {\n const warn = threshold > 0 && pendingFiles >= threshold;\n const pendingLabel = warn ? `${'\\x1b[33m'}${pendingFiles} files pending${reset}` : `${dim}${pendingFiles} files pending${reset}`;\n console.log(` ${label('Pending')} ${pendingLabel}`);\n if (warn) {\n console.log(` ${'\\x1b[33m'}\u26A0 Index may be stale. Run \\`kirograph sync\\` to update.${reset}`);\n }\n } else {\n console.log(` ${label('Pending')} ${green}up to date${reset}`);\n }\n\n console.log();\n console.log(section(' Semantic Search'));\n if (stats.embeddingsEnabled) {\n const tqStats = stats.semanticEngine === 'turboquant'\n ? readTurboQuantStats(path.join(target, '.kirograph'))\n : null;\n const engineLabel =\n stats.semanticEngine === 'turboquant' ? `turboquant ${dim}(${stats.vecIndexCount} entries \u00B7 ${tqStats ? `${tqStats.bits} bits \u00B7 ${tqStats.compressionRatio.toFixed(1)}\u00D7 compression` : 'not yet indexed'})${reset}` :\n stats.semanticEngine === 'sqlite-vec' ? `sqlite-vec ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'orama' ? `orama ${dim}(hybrid \u2014 ${stats.vecIndexCount} docs in index)${reset}` :\n stats.semanticEngine === 'pglite' ? `pglite+pgvector ${dim}(hybrid \u2014 ${stats.vecIndexCount} rows in DB)${reset}` :\n stats.semanticEngine === 'lancedb' ? `lancedb ${dim}(${stats.vecIndexCount} entries in ANN index)${reset}` :\n stats.semanticEngine === 'qdrant' ? `qdrant ${dim}(${stats.vecIndexCount} points in collection)${reset}` :\n stats.semanticEngine === 'typesense' ? `typesense ${dim}(${stats.vecIndexCount} documents in collection)${reset}` :\n stats.semanticEngine === 'turbovec' ? `turbovec ${dim}(${stats.vecIndexCount} entries \u00B7 ${stats.turbovecBits ?? 4} bits \u00B7 Rust/SIMD)${reset}` :\n `in-process cosine`;\n const total = stats.embeddableNodeCount > 0 ? stats.embeddableNodeCount : stats.nodes;\n const displayed = Math.min(stats.embeddingCount, total);\n const coverage = total > 0 ? Math.min(100, Math.round((stats.embeddingCount / total) * 100)) : 0;\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n console.log(` ${label('Model')} ${value(stats.embeddingModel)}`);\n console.log(` ${label('Engine')} ${violet}${engineLabel}${reset}`);\n if (stats.engineFallback) {\n console.log(` ${'\\x1b[33m'}\u26A0 engine fallback: ${stats.engineFallback}${reset}`);\n }\n console.log(` ${label('Indexed')} ${value(`${displayed} / ${total}`)} ${dim}(${coverage}%)${reset}`);\n if (tqStats) {\n const rawMB = (tqStats.rawBytes / 1_048_576).toFixed(1);\n const compMB = (tqStats.actualBytes / 1_048_576).toFixed(1);\n const savedMB = (tqStats.savedBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Raw size')} ${dim}${rawMB} MB \u2192 compressed ${compMB} MB (${savedMB} MB saved)${reset}`);\n if (tqStats.memEnabled && tqStats.memCount > 0) {\n const mRawMB = (tqStats.memRawBytes / 1_048_576).toFixed(1);\n const mCompMB = (tqStats.memActualBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Memory')} ${dim}${tqStats.memCount} observations \u2192 ${mRawMB} MB \u2192 ${mCompMB} MB${reset}`);\n }\n if (tqStats.docsEnabled && tqStats.docsCount > 0) {\n const dRawMB = (tqStats.docsRawBytes / 1_048_576).toFixed(1);\n const dCompMB = (tqStats.docsActualBytes / 1_048_576).toFixed(1);\n console.log(` ${label('Docs')} ${dim}${tqStats.docsCount} sections \u2192 ${dRawMB} MB \u2192 ${dCompMB} MB${reset}`);\n }\n const totalSaved = tqStats.savedBytes + (tqStats.memRawBytes - tqStats.memActualBytes) + (tqStats.docsRawBytes - tqStats.docsActualBytes);\n if (totalSaved > 0) {\n console.log(` ${label('Total RAM')} ${green}${(totalSaved / 1_048_576).toFixed(1)} MB saved${reset} ${dim}(TurboQuant compression)${reset}`);\n }\n }\n } else {\n console.log(` ${label('Status')} ${dim}disabled${reset}`);\n }\n\n // Pattern SAST section\n try {\n const patConfig = await loadConfig(target);\n if (patConfig.enablePatterns) {\n const db2 = cg.getDatabase();\n (db2 as any).applyPatternsSchema?.();\n const rawDb2 = db2.getRawDb();\n const tableExists = rawDb2.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\");\n if (tableExists) {\n const matchCount = (rawDb2.get('SELECT COUNT(*) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const fileCount = (rawDb2.get('SELECT COUNT(DISTINCT file_path) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n const ruleCount = (rawDb2.get('SELECT COUNT(DISTINCT pattern_id) as cnt FROM pattern_matches') as any)?.cnt ?? 0;\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset}`);\n if (matchCount > 0) {\n console.log(` ${label('Matches')} ${value(String(matchCount))} ${dim}across ${fileCount} files, ${ruleCount} rules triggered${reset}`);\n } else {\n console.log(` ${label('Matches')} ${dim}none yet \u2014 run kirograph index${reset}`);\n }\n } else {\n console.log();\n console.log(section(' Patterns'));\n console.log(` ${label('Status')} ${green}${bold}enabled${reset} ${dim}(not yet indexed \u2014 run kirograph index)${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n // Security stats (conditional on enableSecurity)\n try {\n const config = await loadConfig(target);\n if (config.enableSecurity) {\n const db = cg.getDatabase();\n db.applySecuritySchema();\n const rawDb = db.getRawDb();\n\n const depCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies')?.cnt ?? 0;\n const vulnCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_vulnerabilities')?.cnt ?? 0;\n const affectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'affected'\")?.cnt ?? 0;\n const notAffectedCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'not_affected'\")?.cnt ?? 0;\n const investigatingCount: number = rawDb.get(\"SELECT COUNT(*) as cnt FROM sec_reachability WHERE verdict = 'under_investigation'\")?.cnt ?? 0;\n const staleCount: number = rawDb.get('SELECT COUNT(*) as cnt FROM sec_dependencies WHERE vuln_data_stale = 1')?.cnt ?? 0;\n\n console.log();\n console.log(section(' \uD83D\uDD12 Security'));\n console.log(` ${label('Dependencies')} ${value(String(depCount))}`);\n console.log(` ${label('Vulnerabilities')} ${value(String(vulnCount))}`);\n\n if (vulnCount > 0) {\n const affectedLabel = affectedCount > 0\n ? `${'\\x1b[31m'}${affectedCount} affected${reset}`\n : `${dim}0 affected${reset}`;\n console.log(` ${label('Affected')} ${affectedLabel}`);\n console.log(` ${label('Not Affected')} ${dim}${notAffectedCount}${reset}`);\n console.log(` ${label('Investigating')} ${dim}${investigatingCount}${reset}`);\n }\n\n if (staleCount > 0) {\n console.log(` ${'\\x1b[33m'}\u26A0 ${staleCount} dependenc${staleCount === 1 ? 'y has' : 'ies have'} stale vulnerability data. Run \\`kirograph vulns --refresh\\` to update.${reset}`);\n }\n }\n } catch { /* non-critical */ }\n\n console.log();\n cg.close();\n });\n}\n\nasync function showIntegrations(projectRoot: string): Promise<void> {\n const fs = await import('fs');\n const { detectPlatforms } = await Promise.resolve().then(() => require('../installer/detect.js'));\n const { readJson, KIROGRAPH_SERVER_NAME } = await Promise.resolve().then(() => require('../installer/common.js'));\n\n const detected = detectPlatforms(projectRoot);\n const home = process.env.HOME || process.env.USERPROFILE || '';\n\n // Map of target \u2192 config path to check if kirograph is configured\n const configChecks: Record<string, { path: string; key: string }> = {\n 'kiro': { path: path.join(projectRoot, '.kiro', 'settings', 'mcp.json'), key: 'mcpServers' },\n 'claude': { path: path.join(projectRoot, '.mcp.json'), key: 'mcpServers' },\n 'cursor': { path: path.join(projectRoot, '.cursor', 'mcp.json'), key: 'mcpServers' },\n 'windsurf': { path: path.join(home, '.codeium', 'windsurf', 'mcp_config.json'), key: 'mcpServers' },\n 'codex': { path: path.join(projectRoot, '.codex', 'hooks.json'), key: 'hooks' },\n 'copilot': { path: path.join(projectRoot, '.vscode', 'mcp.json'), key: 'servers' },\n 'copilot-cli': { path: path.join(home, '.copilot', 'mcp-config.json'), key: 'servers' },\n 'gemini-cli': { path: path.join(projectRoot, '.gemini', 'settings.json'), key: 'mcpServers' },\n 'continue': { path: path.join(projectRoot, '.continue', 'mcpServers', 'kirograph.json'), key: 'mcpServers' },\n 'opencode': { path: path.join(projectRoot, '.opencode.json'), key: 'mcp' },\n 'antigravity': { path: path.join(home, '.gemini', 'antigravity', 'mcp_config.json'), key: 'mcpServers' },\n 'roo': { path: path.join(projectRoot, '.roo', 'mcp.json'), key: 'mcpServers' },\n 'warp': { path: path.join(projectRoot, '.warp', '.mcp.json'), key: 'mcpServers' },\n 'trae': { path: path.join(projectRoot, '.trae', 'mcp.json'), key: 'mcpServers' },\n 'amp': { path: path.join(projectRoot, '.amp', 'config.json'), key: 'mcpServers' },\n 'cline': { path: path.join(projectRoot, '.cline', 'mcp_settings.json'), key: 'mcpServers' },\n 'qoder': { path: path.join(projectRoot, '.qoder', 'mcp.json'), key: 'mcpServers' },\n 'qwen': { path: path.join(home, '.qwen', 'settings.json'), key: 'mcpServers' },\n 'commandcode': { path: path.join(projectRoot, '.mcp.json'), key: 'mcpServers' },\n };\n\n function isConfigured(target: string): boolean {\n const check = configChecks[target];\n if (!check) return false;\n if (!fs.existsSync(check.path)) return false;\n const config = readJson(check.path);\n const container = config[check.key];\n if (!container) return false;\n if (typeof container === 'object' && !Array.isArray(container)) {\n return KIROGRAPH_SERVER_NAME in container;\n }\n return false;\n }\n\n const configured = detected.filter(d => isConfigured(d.target));\n const notConfigured = detected.filter(d => !isConfigured(d.target));\n\n console.log();\n console.log(section(' Integrations'));\n console.log();\n\n if (configured.length > 0) {\n console.log(` ${label('Configured:')}`);\n for (const d of configured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${green}\u2713${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n }\n\n if (notConfigured.length > 0) {\n if (configured.length > 0) console.log();\n console.log(` ${label('Detected but not configured:')}`);\n for (const d of notConfigured) {\n const check = configChecks[d.target];\n const configPath = check ? check.path.replace(projectRoot, '.').replace(home, '~') : '';\n console.log(` ${dim}\u25CB${reset} ${d.label.padEnd(20)} ${dim}${configPath}${reset}`);\n }\n console.log();\n console.log(` ${dim}Run \\`kirograph install\\` to configure detected platforms.${reset}`);\n }\n\n if (detected.length === 0) {\n console.log(` ${dim}No AI coding platforms detected.${reset}`);\n }\n\n console.log();\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/bin/commands/uninit.ts"],
|
|
4
|
-
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as readline from 'readline';\nimport { printBanner } from '../banner';\nimport { dim, reset, violet, bold, green } from '../ui';\nimport { askToggle } from '../installer/prompts';\nimport type { InstallTarget } from '../installer/common';\nimport { getTargetInstaller } from '../installer/targets';\n\nexport const UNINIT_FAREWELLS = [\n \"Oh. So it's come to this.\",\n \"We're sorry to see you go. (Are we? Yes. We are.)\",\n \"Deleting months of carefully indexed knowledge. Bold move.\",\n \"Fine. We'll just sit here in the dark.\",\n \"You can always come back. We won't mention this.\",\n \"The graph remembers everything. Except, soon, anything.\",\n \"Somewhere a tree-sitter is crying.\",\n \"Uninstalling... and pretending it doesn't hurt.\",\n \"574 embeddings. Gone. Just like that.\",\n \"See you on the other side of `kirograph install`.\",\n];\n\nconst ALL_TARGETS: InstallTarget[] = [\n 'kiro', 'claude', 'codex', 'cursor', 'antigravity', 'opencode',\n 'windsurf', 'cline', 'copilot', 'junie', 'gemini-cli',\n 'continue', 'roo', 'warp', 'aider', 'trae',\n 'augment', 'kilo', 'amp', 'devin', 'replit', 'goose', 'openhands', 'tabnine',\n 'mistral-vibe', 'ibm-bob', 'crush', 'droid-factory', 'forgecode', 'iflow', 'qwen', 'rovo', 'qoder',\n];\n\nfunction isValidTarget(t: string): t is InstallTarget | 'all' {\n return t === 'all' || ALL_TARGETS.includes(t as InstallTarget);\n}\n\nfunction uninitKiro(projectRoot: string): void {\n // Remove .kiro hooks created by kirograph (v2 .json format)\n const kiroHooks = [\n 'kirograph-sync-if-dirty.json',\n 'kirograph-compress-hint.json',\n 'kirograph-mem-capture.json',\n 'kirograph-watchmen.json',\n 'kirograph-wiki-ingest.json',\n 'kirograph-wiki-lint.json',\n // Legacy v1 .kiro.hook filenames\n 'kirograph-mark-dirty-on-save.kiro.hook',\n 'kirograph-mark-dirty-on-create.kiro.hook',\n 'kirograph-sync-on-delete.kiro.hook',\n 'kirograph-sync-if-dirty.kiro.hook',\n 'kirograph-compress-hint.kiro.hook',\n 'kirograph-mem-capture.kiro.hook',\n 'kirograph-watchmen.kiro.hook',\n 'kirograph-wiki-ingest.kiro.hook',\n 'kirograph-wiki-lint.kiro.hook',\n // Legacy pre-v1 .json filenames (different schema)\n 'kirograph-mark-dirty-on-save.json',\n 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json',\n 'kirograph-sync-on-save.json',\n 'kirograph-sync-on-create.json',\n ];\n const hooksDir = path.join(projectRoot, '.kiro', 'hooks');\n let removedHooks = 0;\n for (const hook of kiroHooks) {\n const p = path.join(hooksDir, hook);\n if (fs.existsSync(p)) { fs.unlinkSync(p); removedHooks++; }\n }\n if (removedHooks > 0) console.log(` ${green}\u2713${reset} Removed ${removedHooks} hook(s) from .kiro/hooks/`);\n\n // Remove .kiro/steering/kirograph*.md (main + all workflow files)\n const steeringDir = path.join(projectRoot, '.kiro', 'steering');\n let removedSteering = 0;\n if (fs.existsSync(steeringDir)) {\n for (const entry of fs.readdirSync(steeringDir)) {\n if (entry.startsWith('kirograph') && entry.endsWith('.md')) {\n fs.unlinkSync(path.join(steeringDir, entry));\n removedSteering++;\n }\n }\n }\n if (removedSteering > 0) {\n console.log(` ${green}\u2713${reset} Removed ${removedSteering} steering file(s) from .kiro/steering/`);\n }\n\n // Remove .kiro/agents/kirograph.json\n const agentPath = path.join(projectRoot, '.kiro', 'agents', 'kirograph.json');\n if (fs.existsSync(agentPath)) {\n fs.unlinkSync(agentPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/agents/kirograph.json`);\n }\n\n // Remove kirograph server from .kiro/settings/mcp.json\n const { removeMcpServersConfig } = require('../installer/common');\n const mcpPath = path.join(projectRoot, '.kiro', 'settings', 'mcp.json');\n if (removeMcpServersConfig(mcpPath)) {\n console.log(` ${green}\u2713${reset} Removed kirograph from .kiro/settings/mcp.json`);\n }\n}\n\nasync function runUninit(projectPath: string | undefined, opts: { force?: boolean; target?: string }): Promise<void> {\n const projectRoot = path.resolve(projectPath ?? process.cwd());\n const targetName = (opts.target ?? 'kiro').toLowerCase();\n\n if (!isValidTarget(targetName)) {\n console.error(`Unknown uninit target: ${opts.target}. Choose from: ${ALL_TARGETS.join(', ')}, all`);\n process.exit(1);\n }\n\n const dir = path.join(projectRoot, '.kirograph');\n if (!fs.existsSync(dir)) { console.log('Not initialized.'); return; }\n\n let removeIntegration = true;\n let removeGraph = opts.force === true;\n\n if (!opts.force) {\n printBanner();\n const farewell = UNINIT_FAREWELLS[Math.floor(Math.random() * UNINIT_FAREWELLS.length)]!;\n console.log(` ${violet}${bold}${farewell}${reset}`);\n console.log(`\\n ${dim}This can remove ${targetName} integration files and, separately, the shared .kirograph/ data.${reset}`);\n console.log(` ${dim}Your source code is untouched.${reset}`);\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\n removeIntegration = await askToggle(rl, `Remove ${targetName} integration files?`, 'Removes hooks, MCP config, rules, and agent instructions for this target.', false);\n removeGraph = await askToggle(rl, 'Remove shared .kirograph/ data too?', 'Deletes the graph database, snapshots, and all indexed data. Cannot be undone.', false);\n\n rl.close();\n\n if (!removeIntegration && !removeGraph) {\n console.log(`\\n ${dim}Cancelled. Nothing removed.${reset}\\n`);\n return;\n }\n console.log();\n }\n\n if (removeGraph) {\n fs.rmSync(dir, { recursive: true, force: true });\n console.log(` ${green}\u2713${reset} Removed .kirograph/`);\n }\n\n if (removeIntegration) {\n const targets: InstallTarget[] = targetName === 'all' ? [...ALL_TARGETS] : [targetName as InstallTarget];\n\n for (const t of targets) {\n if (t === 'kiro') {\n uninitKiro(projectRoot);\n } else {\n const installer = getTargetInstaller(t);\n installer.uninit?.(projectRoot);\n }\n }\n }\n\n console.log(`\\n ${dim}Done. Run ${violet}kirograph install --target ${targetName === 'all' ? 'kiro' : targetName}${reset}${dim} to come back anytime.${reset}\\n`);\n}\n\nexport function register(program: Command): void {\n program\n .command('uninit [projectPath]')\n .description('Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', `Integration target to clean up (or \"all\"): ${ALL_TARGETS.slice(0, 6).join(', ')}, ...`, 'kiro')\n .action(runUninit);\n\n program\n .command('uninstall [projectPath]')\n .description('Alias for uninit. Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', `Integration target to clean up (or \"all\"): ${ALL_TARGETS.slice(0, 6).join(', ')}, ...`, 'kiro')\n .action(runUninit);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,WAAsB;AACtB,SAAoB;AACpB,eAA0B;AAC1B,oBAA4B;AAC5B,gBAAgD;AAChD,qBAA0B;AAE1B,qBAAmC;AAE5B,MAAM,mBAAmB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,MAAM,cAA+B;AAAA,EACnC;AAAA,EAAQ;AAAA,EAAU;AAAA,EAAS;AAAA,EAAU;AAAA,EAAe;AAAA,EACpD;AAAA,EAAY;AAAA,EAAS;AAAA,EAAW;AAAA,EAAS;AAAA,EACzC;AAAA,EAAY;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAS;AAAA,EACpC;AAAA,EAAW;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EAAS;AAAA,EAAa;AAAA,EACnE;AAAA,EAAgB;AAAA,EAAW;AAAA,EAAS;AAAA,EAAiB;AAAA,EAAa;AAAA,EAAS;AAAA,EAAQ;AAAA,EAAQ;
|
|
4
|
+
"sourcesContent": ["import { Command } from 'commander';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as readline from 'readline';\nimport { printBanner } from '../banner';\nimport { dim, reset, violet, bold, green } from '../ui';\nimport { askToggle } from '../installer/prompts';\nimport type { InstallTarget } from '../installer/common';\nimport { getTargetInstaller } from '../installer/targets';\n\nexport const UNINIT_FAREWELLS = [\n \"Oh. So it's come to this.\",\n \"We're sorry to see you go. (Are we? Yes. We are.)\",\n \"Deleting months of carefully indexed knowledge. Bold move.\",\n \"Fine. We'll just sit here in the dark.\",\n \"You can always come back. We won't mention this.\",\n \"The graph remembers everything. Except, soon, anything.\",\n \"Somewhere a tree-sitter is crying.\",\n \"Uninstalling... and pretending it doesn't hurt.\",\n \"574 embeddings. Gone. Just like that.\",\n \"See you on the other side of `kirograph install`.\",\n];\n\nconst ALL_TARGETS: InstallTarget[] = [\n 'kiro', 'claude', 'codex', 'cursor', 'antigravity', 'opencode',\n 'windsurf', 'cline', 'copilot', 'junie', 'gemini-cli',\n 'continue', 'roo', 'warp', 'aider', 'trae',\n 'augment', 'kilo', 'amp', 'devin', 'replit', 'goose', 'openhands', 'tabnine',\n 'mistral-vibe', 'ibm-bob', 'crush', 'droid-factory', 'forgecode', 'iflow', 'qwen', 'rovo', 'qoder', 'commandcode',\n];\n\nfunction isValidTarget(t: string): t is InstallTarget | 'all' {\n return t === 'all' || ALL_TARGETS.includes(t as InstallTarget);\n}\n\nfunction uninitKiro(projectRoot: string): void {\n // Remove .kiro hooks created by kirograph (v2 .json format)\n const kiroHooks = [\n 'kirograph-sync-if-dirty.json',\n 'kirograph-compress-hint.json',\n 'kirograph-mem-capture.json',\n 'kirograph-watchmen.json',\n 'kirograph-wiki-ingest.json',\n 'kirograph-wiki-lint.json',\n // Legacy v1 .kiro.hook filenames\n 'kirograph-mark-dirty-on-save.kiro.hook',\n 'kirograph-mark-dirty-on-create.kiro.hook',\n 'kirograph-sync-on-delete.kiro.hook',\n 'kirograph-sync-if-dirty.kiro.hook',\n 'kirograph-compress-hint.kiro.hook',\n 'kirograph-mem-capture.kiro.hook',\n 'kirograph-watchmen.kiro.hook',\n 'kirograph-wiki-ingest.kiro.hook',\n 'kirograph-wiki-lint.kiro.hook',\n // Legacy pre-v1 .json filenames (different schema)\n 'kirograph-mark-dirty-on-save.json',\n 'kirograph-mark-dirty-on-create.json',\n 'kirograph-sync-on-delete.json',\n 'kirograph-sync-on-save.json',\n 'kirograph-sync-on-create.json',\n ];\n const hooksDir = path.join(projectRoot, '.kiro', 'hooks');\n let removedHooks = 0;\n for (const hook of kiroHooks) {\n const p = path.join(hooksDir, hook);\n if (fs.existsSync(p)) { fs.unlinkSync(p); removedHooks++; }\n }\n if (removedHooks > 0) console.log(` ${green}\u2713${reset} Removed ${removedHooks} hook(s) from .kiro/hooks/`);\n\n // Remove .kiro/steering/kirograph*.md (main + all workflow files)\n const steeringDir = path.join(projectRoot, '.kiro', 'steering');\n let removedSteering = 0;\n if (fs.existsSync(steeringDir)) {\n for (const entry of fs.readdirSync(steeringDir)) {\n if (entry.startsWith('kirograph') && entry.endsWith('.md')) {\n fs.unlinkSync(path.join(steeringDir, entry));\n removedSteering++;\n }\n }\n }\n if (removedSteering > 0) {\n console.log(` ${green}\u2713${reset} Removed ${removedSteering} steering file(s) from .kiro/steering/`);\n }\n\n // Remove .kiro/agents/kirograph.json\n const agentPath = path.join(projectRoot, '.kiro', 'agents', 'kirograph.json');\n if (fs.existsSync(agentPath)) {\n fs.unlinkSync(agentPath);\n console.log(` ${green}\u2713${reset} Removed .kiro/agents/kirograph.json`);\n }\n\n // Remove kirograph server from .kiro/settings/mcp.json\n const { removeMcpServersConfig } = require('../installer/common');\n const mcpPath = path.join(projectRoot, '.kiro', 'settings', 'mcp.json');\n if (removeMcpServersConfig(mcpPath)) {\n console.log(` ${green}\u2713${reset} Removed kirograph from .kiro/settings/mcp.json`);\n }\n}\n\nasync function runUninit(projectPath: string | undefined, opts: { force?: boolean; target?: string }): Promise<void> {\n const projectRoot = path.resolve(projectPath ?? process.cwd());\n const targetName = (opts.target ?? 'kiro').toLowerCase();\n\n if (!isValidTarget(targetName)) {\n console.error(`Unknown uninit target: ${opts.target}. Choose from: ${ALL_TARGETS.join(', ')}, all`);\n process.exit(1);\n }\n\n const dir = path.join(projectRoot, '.kirograph');\n if (!fs.existsSync(dir)) { console.log('Not initialized.'); return; }\n\n let removeIntegration = true;\n let removeGraph = opts.force === true;\n\n if (!opts.force) {\n printBanner();\n const farewell = UNINIT_FAREWELLS[Math.floor(Math.random() * UNINIT_FAREWELLS.length)]!;\n console.log(` ${violet}${bold}${farewell}${reset}`);\n console.log(`\\n ${dim}This can remove ${targetName} integration files and, separately, the shared .kirograph/ data.${reset}`);\n console.log(` ${dim}Your source code is untouched.${reset}`);\n\n const rl = readline.createInterface({ input: process.stdin, output: process.stdout });\n\n removeIntegration = await askToggle(rl, `Remove ${targetName} integration files?`, 'Removes hooks, MCP config, rules, and agent instructions for this target.', false);\n removeGraph = await askToggle(rl, 'Remove shared .kirograph/ data too?', 'Deletes the graph database, snapshots, and all indexed data. Cannot be undone.', false);\n\n rl.close();\n\n if (!removeIntegration && !removeGraph) {\n console.log(`\\n ${dim}Cancelled. Nothing removed.${reset}\\n`);\n return;\n }\n console.log();\n }\n\n if (removeGraph) {\n fs.rmSync(dir, { recursive: true, force: true });\n console.log(` ${green}\u2713${reset} Removed .kirograph/`);\n }\n\n if (removeIntegration) {\n const targets: InstallTarget[] = targetName === 'all' ? [...ALL_TARGETS] : [targetName as InstallTarget];\n\n for (const t of targets) {\n if (t === 'kiro') {\n uninitKiro(projectRoot);\n } else {\n const installer = getTargetInstaller(t);\n installer.uninit?.(projectRoot);\n }\n }\n }\n\n console.log(`\\n ${dim}Done. Run ${violet}kirograph install --target ${targetName === 'all' ? 'kiro' : targetName}${reset}${dim} to come back anytime.${reset}\\n`);\n}\n\nexport function register(program: Command): void {\n program\n .command('uninit [projectPath]')\n .description('Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', `Integration target to clean up (or \"all\"): ${ALL_TARGETS.slice(0, 6).join(', ')}, ...`, 'kiro')\n .action(runUninit);\n\n program\n .command('uninstall [projectPath]')\n .description('Alias for uninit. Remove KiroGraph from a project')\n .option('--force', 'Skip confirmation')\n .option('--target <target>', `Integration target to clean up (or \"all\"): ${ALL_TARGETS.slice(0, 6).join(', ')}, ...`, 'kiro')\n .action(runUninit);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -165,10 +165,10 @@ function register(program) {
|
|
|
165
165
|
const params = [];
|
|
166
166
|
if (opts.severity) {
|
|
167
167
|
const severityRanges = {
|
|
168
|
-
critical: [9, 10],
|
|
169
|
-
high: [7,
|
|
170
|
-
medium: [4,
|
|
171
|
-
low: [0
|
|
168
|
+
critical: [9, 10.01],
|
|
169
|
+
high: [7, 9],
|
|
170
|
+
medium: [4, 7],
|
|
171
|
+
low: [0, 4]
|
|
172
172
|
};
|
|
173
173
|
const range = severityRanges[opts.severity.toLowerCase()];
|
|
174
174
|
if (!range) {
|
|
@@ -176,7 +176,7 @@ function register(program) {
|
|
|
176
176
|
cg.close();
|
|
177
177
|
process.exit(1);
|
|
178
178
|
}
|
|
179
|
-
query += ` AND v.severity_score >= ? AND v.severity_score
|
|
179
|
+
query += ` AND v.severity_score IS NOT NULL AND v.severity_score >= ? AND v.severity_score < ?`;
|
|
180
180
|
params.push(range[0], range[1]);
|
|
181
181
|
}
|
|
182
182
|
if (opts.verdict) {
|
|
@@ -341,6 +341,11 @@ function register(program) {
|
|
|
341
341
|
}
|
|
342
342
|
if (suppressedRows.length > 0) {
|
|
343
343
|
console.log(` ${import_ui.dim}${suppressedRows.length} CVE(s) suppressed \u2014 kirograph vuln suppressions to review${import_ui.reset}
|
|
344
|
+
`);
|
|
345
|
+
}
|
|
346
|
+
const pendingCount = filteredRows.filter((r) => !r.verdict).length;
|
|
347
|
+
if (pendingCount > 0) {
|
|
348
|
+
console.log(` ${import_ui.dim}${pendingCount} vulnerabilit${pendingCount === 1 ? "y is" : "ies are"} [pending] reachability analysis \u2014 run ${import_ui.reset}kirograph index${import_ui.dim} to compute call-graph verdicts.${import_ui.reset}
|
|
344
349
|
`);
|
|
345
350
|
}
|
|
346
351
|
if (opts.failOn !== void 0) {
|