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.
Files changed (110) hide show
  1. package/dist/architecture/index.js +4 -1
  2. package/dist/architecture/index.js.map +2 -2
  3. package/dist/architecture/manifest/index.js +13 -2
  4. package/dist/architecture/manifest/index.js.map +2 -2
  5. package/dist/bin/commands/install.js +2 -1
  6. package/dist/bin/commands/install.js.map +2 -2
  7. package/dist/bin/commands/status.js +2 -1
  8. package/dist/bin/commands/status.js.map +2 -2
  9. package/dist/bin/commands/uninit.js +2 -1
  10. package/dist/bin/commands/uninit.js.map +2 -2
  11. package/dist/bin/commands/vulns.js +10 -5
  12. package/dist/bin/commands/vulns.js.map +2 -2
  13. package/dist/bin/installer/common.js +7 -1
  14. package/dist/bin/installer/common.js.map +2 -2
  15. package/dist/bin/installer/detect.js +10 -0
  16. package/dist/bin/installer/detect.js.map +2 -2
  17. package/dist/bin/installer/hooks.js +13 -8
  18. package/dist/bin/installer/hooks.js.map +2 -2
  19. package/dist/bin/installer/targets/antigravity.js +1 -1
  20. package/dist/bin/installer/targets/antigravity.js.map +2 -2
  21. package/dist/bin/installer/targets/claude.js +1 -1
  22. package/dist/bin/installer/targets/claude.js.map +2 -2
  23. package/dist/bin/installer/targets/codex.js +1 -1
  24. package/dist/bin/installer/targets/codex.js.map +2 -2
  25. package/dist/bin/installer/targets/commandcode.js +84 -0
  26. package/dist/bin/installer/targets/commandcode.js.map +7 -0
  27. package/dist/bin/installer/targets/copilot.js +1 -1
  28. package/dist/bin/installer/targets/copilot.js.map +2 -2
  29. package/dist/bin/installer/targets/cursor.js +2 -2
  30. package/dist/bin/installer/targets/cursor.js.map +2 -2
  31. package/dist/bin/installer/targets/devin.js +1 -1
  32. package/dist/bin/installer/targets/devin.js.map +2 -2
  33. package/dist/bin/installer/targets/gemini-cli.js +1 -1
  34. package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
  35. package/dist/bin/installer/targets/index.js +10 -0
  36. package/dist/bin/installer/targets/index.js.map +2 -2
  37. package/dist/bin/installer/targets/opencode.js +1 -1
  38. package/dist/bin/installer/targets/opencode.js.map +2 -2
  39. package/dist/bin/installer/targets/windsurf.js +1 -1
  40. package/dist/bin/installer/targets/windsurf.js.map +2 -2
  41. package/dist/bin/kirograph.js +1 -1
  42. package/dist/bin/kirograph.js.map +1 -1
  43. package/dist/config.js +21 -1
  44. package/dist/config.js.map +2 -2
  45. package/dist/core/pipeline.js +18 -6
  46. package/dist/core/pipeline.js.map +2 -2
  47. package/dist/extraction/extractor.js +58 -1
  48. package/dist/extraction/extractor.js.map +2 -2
  49. package/dist/extraction/grammars.js +38 -3
  50. package/dist/extraction/grammars.js.map +2 -2
  51. package/dist/extraction/wasm/tree-sitter-bash.wasm +0 -0
  52. package/dist/extraction/wasm/tree-sitter-c.wasm +0 -0
  53. package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
  54. package/dist/extraction/wasm/tree-sitter-cpp.wasm +0 -0
  55. package/dist/extraction/wasm/tree-sitter-csharp.wasm +0 -0
  56. package/dist/extraction/wasm/tree-sitter-css.wasm +0 -0
  57. package/dist/extraction/wasm/tree-sitter-dart.wasm +0 -0
  58. package/dist/extraction/wasm/tree-sitter-elisp.wasm +0 -0
  59. package/dist/extraction/wasm/tree-sitter-elixir.wasm +0 -0
  60. package/dist/extraction/wasm/tree-sitter-elm.wasm +0 -0
  61. package/dist/extraction/wasm/tree-sitter-embedded_template.wasm +0 -0
  62. package/dist/extraction/wasm/tree-sitter-embeddedtemplate.wasm +0 -0
  63. package/dist/extraction/wasm/tree-sitter-go.wasm +0 -0
  64. package/dist/extraction/wasm/tree-sitter-html.wasm +0 -0
  65. package/dist/extraction/wasm/tree-sitter-java.wasm +0 -0
  66. package/dist/extraction/wasm/tree-sitter-javascript.wasm +0 -0
  67. package/dist/extraction/wasm/tree-sitter-json.wasm +0 -0
  68. package/dist/extraction/wasm/tree-sitter-kotlin.wasm +0 -0
  69. package/dist/extraction/wasm/tree-sitter-lua.wasm +0 -0
  70. package/dist/extraction/wasm/tree-sitter-objc.wasm +0 -0
  71. package/dist/extraction/wasm/tree-sitter-ocaml.wasm +0 -0
  72. package/dist/extraction/wasm/tree-sitter-php.wasm +0 -0
  73. package/dist/extraction/wasm/tree-sitter-python.wasm +0 -0
  74. package/dist/extraction/wasm/tree-sitter-ql.wasm +0 -0
  75. package/dist/extraction/wasm/tree-sitter-rescript.wasm +0 -0
  76. package/dist/extraction/wasm/tree-sitter-ruby.wasm +0 -0
  77. package/dist/extraction/wasm/tree-sitter-rust.wasm +0 -0
  78. package/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
  79. package/dist/extraction/wasm/tree-sitter-solidity.wasm +0 -0
  80. package/dist/extraction/wasm/tree-sitter-swift.wasm +0 -0
  81. package/dist/extraction/wasm/tree-sitter-systemrdl.wasm +0 -0
  82. package/dist/extraction/wasm/tree-sitter-tlaplus.wasm +0 -0
  83. package/dist/extraction/wasm/tree-sitter-toml.wasm +0 -0
  84. package/dist/extraction/wasm/tree-sitter-tsx.wasm +0 -0
  85. package/dist/extraction/wasm/tree-sitter-typescript.wasm +0 -0
  86. package/dist/extraction/wasm/tree-sitter-vue.wasm +0 -0
  87. package/dist/extraction/wasm/tree-sitter-yaml.wasm +0 -0
  88. package/dist/extraction/wasm/tree-sitter-zig.wasm +0 -0
  89. package/dist/frameworks/index.js +68 -7
  90. package/dist/frameworks/index.js.map +2 -2
  91. package/dist/security/manifest/adapter.js +17 -2
  92. package/dist/security/manifest/adapter.js.map +2 -2
  93. package/dist/security/manifest/parser.js +2 -2
  94. package/dist/security/manifest/parser.js.map +2 -2
  95. package/dist/security/pipeline.js +4 -1
  96. package/dist/security/pipeline.js.map +2 -2
  97. package/dist/security/reachability.js +61 -45
  98. package/dist/security/reachability.js.map +3 -3
  99. package/dist/security/types.js.map +1 -1
  100. package/dist/security/vuln/epss-client.js +1 -1
  101. package/dist/security/vuln/epss-client.js.map +1 -1
  102. package/dist/security/vuln/osv-adapter.js +99 -31
  103. package/dist/security/vuln/osv-adapter.js.map +2 -2
  104. package/dist/sync/index.js +9 -2
  105. package/dist/sync/index.js.map +2 -2
  106. package/dist/vectors/libsql-index.js +287 -0
  107. package/dist/vectors/libsql-index.js.map +7 -0
  108. package/dist/vectors/turso-index.js +307 -0
  109. package/dist/vectors/turso-index.js.map +7 -0
  110. package/package.json +3 -2
@@ -59,6 +59,8 @@ class IndexPipeline {
59
59
  let nodesCreated = 0;
60
60
  let edgesCreated = 0;
61
61
  const poisonedLanguages = /* @__PURE__ */ new Set();
62
+ const crashCounts = /* @__PURE__ */ new Map();
63
+ const POISON_THRESHOLD = 3;
62
64
  try {
63
65
  const files = await (0, import_sync.scanDirectory)(this.projectRoot, this.config, opts?.signal);
64
66
  opts?.onProgress?.({ phase: "scanning", current: files.length, total: files.length });
@@ -85,7 +87,7 @@ class IndexPipeline {
85
87
  const { detectLanguage } = await Promise.resolve().then(() => require("../extraction/languages.js"));
86
88
  const lang = detectLanguage(file);
87
89
  if (poisonedLanguages.has(lang)) continue;
88
- const extracted = await (0, import_extractor.extractFile)(file, this.projectRoot, content, { enableComplexity: !!this.config.enableComplexity });
90
+ const extracted = await (0, import_extractor.extractFile)(file, this.projectRoot, content, { enableComplexity: !!this.config.enableComplexity, maxFileSize: this.config.maxFileSize });
89
91
  if (!extracted) continue;
90
92
  const oldNodes = this.db.getNodesByFile(extracted.filePath);
91
93
  if (oldNodes.length > 0) await this.vectors.deleteEmbeddings(oldNodes.map((n) => n.id));
@@ -113,6 +115,7 @@ class IndexPipeline {
113
115
  }
114
116
  });
115
117
  filesIndexed++;
118
+ crashCounts.set(lang, 0);
116
119
  } catch (err) {
117
120
  const msg = err instanceof Error ? err.message : String(err);
118
121
  errors.push(`${file}: ${msg}`);
@@ -120,11 +123,14 @@ class IndexPipeline {
120
123
  if (isWasmCrash) {
121
124
  const { detectLanguage } = await Promise.resolve().then(() => require("../extraction/languages.js"));
122
125
  const lang = detectLanguage(file);
123
- poisonedLanguages.add(lang);
126
+ const count = (crashCounts.get(lang) ?? 0) + 1;
127
+ crashCounts.set(lang, count);
128
+ if (count >= POISON_THRESHOLD) {
129
+ poisonedLanguages.add(lang);
130
+ }
124
131
  (0, import_grammars.clearParserCache)();
125
132
  try {
126
133
  await (0, import_grammars.initGrammars)();
127
- poisonedLanguages.clear();
128
134
  } catch {
129
135
  errors.push("WASM runtime unrecoverable after crash \u2014 aborting batch");
130
136
  break;
@@ -344,6 +350,8 @@ class IndexPipeline {
344
350
  result.filesScanned = result.filesScanned || filesToProcess.length;
345
351
  onProgress?.({ phase: "scanning", current: result.filesScanned, total: result.filesScanned });
346
352
  const poisonedLanguages = /* @__PURE__ */ new Set();
353
+ const crashCounts = /* @__PURE__ */ new Map();
354
+ const POISON_THRESHOLD = 3;
347
355
  for (let i = 0; i < filesToProcess.length; i++) {
348
356
  const file = filesToProcess[i];
349
357
  onProgress?.({ phase: "parsing", current: i + 1, total: filesToProcess.length, currentFile: file });
@@ -356,7 +364,7 @@ class IndexPipeline {
356
364
  const { detectLanguage } = await Promise.resolve().then(() => require("../extraction/languages.js"));
357
365
  const lang = detectLanguage(file);
358
366
  if (poisonedLanguages.has(lang)) continue;
359
- const extracted = await (0, import_extractor.extractFile)(file, this.projectRoot, void 0, { enableComplexity: !!this.config.enableComplexity });
367
+ const extracted = await (0, import_extractor.extractFile)(file, this.projectRoot, void 0, { enableComplexity: !!this.config.enableComplexity, maxFileSize: this.config.maxFileSize });
360
368
  if (!extracted) continue;
361
369
  const existing = this.db.getFile(extracted.filePath);
362
370
  const isNew = !existing;
@@ -390,6 +398,7 @@ class IndexPipeline {
390
398
  }
391
399
  });
392
400
  this.resolver.invalidateFile(extracted.filePath);
401
+ crashCounts.set(lang, 0);
393
402
  if (isNew) result.added.push(extracted.filePath);
394
403
  else {
395
404
  result.modified.push(extracted.filePath);
@@ -402,11 +411,14 @@ class IndexPipeline {
402
411
  if (isWasmCrash) {
403
412
  const { detectLanguage } = await Promise.resolve().then(() => require("../extraction/languages.js"));
404
413
  const lang = detectLanguage(file);
405
- poisonedLanguages.add(lang);
414
+ const count = (crashCounts.get(lang) ?? 0) + 1;
415
+ crashCounts.set(lang, count);
416
+ if (count >= POISON_THRESHOLD) {
417
+ poisonedLanguages.add(lang);
418
+ }
406
419
  (0, import_grammars.clearParserCache)();
407
420
  try {
408
421
  await (0, import_grammars.initGrammars)();
409
- poisonedLanguages.clear();
410
422
  } catch {
411
423
  result.errors.push("WASM runtime unrecoverable after crash \u2014 aborting sync");
412
424
  break;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/core/pipeline.ts"],
4
- "sourcesContent": ["/**\n * IndexPipeline \u2014 full-index and incremental-sync pipelines.\n *\n * Owns the two heavy workflows:\n * - indexAll(): scan all files, extract, store, resolve, detect frameworks,\n * generate embeddings, analyze architecture.\n * - sync(): detect changed files via git (or full scan fallback),\n * re-extract only what changed, then run the same tail pipeline.\n *\n * Everything that touches the filesystem or sub-systems is injected via the\n * constructor, keeping this class testable and free of global state.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { GraphDatabase } from '../db/database';\nimport { scanDirectory, hashContent, getChangedFiles, shouldIncludeFile } from '../sync/index';\nimport { extractFile } from '../extraction/extractor';\nimport { clearParserCache, initGrammars, hasWasmGrammar } from '../extraction/grammars';\nimport { detectFrameworks } from '../frameworks/index';\nimport { ReferenceResolver } from '../resolution/index';\nimport { VectorManager } from '../vectors/index';\nimport { ArchitectureAnalyzer } from '../architecture/index';\nimport type { KiroGraphConfig } from '../config';\nimport type { IndexResult, IndexProgress, SyncResult } from '../types';\nimport { LockManager } from './lock-manager';\nimport { Mutex } from '../utils';\n\nconst FILE_IO_BATCH_SIZE = 10;\n\nexport class IndexPipeline {\n private readonly mutex = new Mutex();\n\n constructor(\n private readonly db: GraphDatabase,\n private readonly vectors: VectorManager,\n private readonly resolver: ReferenceResolver,\n private readonly arch: ArchitectureAnalyzer,\n private readonly lock: LockManager,\n private readonly config: KiroGraphConfig,\n private readonly projectRoot: string,\n ) {}\n\n async indexAll(opts?: {\n onProgress?: (p: IndexProgress) => void;\n force?: boolean;\n signal?: AbortSignal;\n }): Promise<IndexResult> {\n const release = await this.mutex.acquire();\n this.lock.acquire();\n const start = Date.now();\n const errors: string[] = [];\n let filesIndexed = 0;\n let nodesCreated = 0;\n let edgesCreated = 0;\n\n // Track languages whose WASM parser is currently poisoned (ABORT=true on the module).\n // Once a language's parser aborts, every subsequent parse call for that language\n // fails instantly. We skip those files until clearParserCache + initGrammars succeeds.\n const poisonedLanguages = new Set<string>();\n\n try {\n const files = await scanDirectory(this.projectRoot, this.config, opts?.signal);\n opts?.onProgress?.({ phase: 'scanning', current: files.length, total: files.length });\n\n // Batch-read files in parallel\n const contentMap = new Map<string, Buffer>();\n for (let b = 0; b < files.length; b += FILE_IO_BATCH_SIZE) {\n const batch = files.slice(b, b + FILE_IO_BATCH_SIZE);\n const results = await Promise.all(batch.map(f => fs.promises.readFile(f).catch(() => null)));\n for (let i = 0; i < batch.length; i++) {\n if (results[i]) contentMap.set(batch[i], results[i]!);\n }\n }\n\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n opts?.onProgress?.({ phase: 'parsing', current: i + 1, total: files.length, currentFile: file });\n\n try {\n const content = contentMap.get(file);\n if (!content) continue;\n if (content.length > this.config.maxFileSize) continue;\n\n const relPath = path.relative(this.projectRoot, file).replace(/\\\\/g, '/');\n\n if (!opts?.force) {\n const existing = this.db.getFile(relPath);\n if (existing && hashContent(content) === existing.contentHash) continue;\n }\n\n // Skip files whose language parser is currently poisoned\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n if (poisonedLanguages.has(lang)) continue;\n\n const extracted = await extractFile(file, this.projectRoot, content, { enableComplexity: !!(this.config as any).enableComplexity });\n if (!extracted) continue;\n\n const oldNodes = this.db.getNodesByFile(extracted.filePath);\n if (oldNodes.length > 0) await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n\n this.db.transaction(() => {\n this.db.deleteNodesByFile(extracted.filePath);\n this.db.deleteUnresolvedRefsByFile(extracted.filePath);\n this.db.upsertFile({\n path: extracted.filePath,\n contentHash: extracted.contentHash,\n language: extracted.language,\n fileSize: extracted.fileSize,\n symbolCount: extracted.nodes.length,\n indexedAt: Date.now(),\n });\n for (const node of extracted.nodes) { this.db.upsertNode(node); nodesCreated++; }\n for (const edge of extracted.edges) { this.db.insertEdge(edge); edgesCreated++; }\n for (const ref of extracted.unresolvedRefs) {\n this.db.insertUnresolvedRef(ref.sourceId, ref.refName, ref.refKind, extracted.filePath, ref.line, ref.column);\n }\n });\n\n filesIndexed++;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push(`${file}: ${msg}`);\n\n // Detect WASM runtime abort and attempt recovery\n const isWasmCrash = (err as any)?.constructor?.name === 'RuntimeError'\n || msg.includes('Aborted(') \n || msg.includes('RuntimeError')\n || msg.includes('WASM grammar exists but failed to load');\n if (isWasmCrash) {\n // Mark the language as poisoned so we skip remaining files of this language\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n poisonedLanguages.add(lang);\n\n clearParserCache();\n try {\n await initGrammars();\n // Recovery succeeded \u2014 un-poison all languages\n poisonedLanguages.clear();\n } catch {\n errors.push('WASM runtime unrecoverable after crash \u2014 aborting batch');\n break;\n }\n }\n }\n }\n\n // Re-process files that have symbolCount=0 but should have symbols (WASM recovery)\n const emptyFiles = this.db.getAllFiles().filter(\n (f: any) => f.symbolCount === 0 && hasWasmGrammar(f.language)\n );\n if (emptyFiles.length > 0) {\n opts?.onProgress?.({ phase: 'retrying', current: 0, total: emptyFiles.length });\n for (let i = 0; i < emptyFiles.length; i++) {\n const ef = emptyFiles[i];\n const absPath = path.join(this.projectRoot, ef.path);\n opts?.onProgress?.({ phase: 'retrying', current: i + 1, total: emptyFiles.length, currentFile: absPath });\n try {\n const extracted = await extractFile(absPath, this.projectRoot, undefined, { enableComplexity: !!(this.config as any).enableComplexity });\n if (!extracted || extracted.nodes.length === 0) continue;\n\n const oldNodes = this.db.getNodesByFile(extracted.filePath);\n if (oldNodes.length > 0) await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n\n this.db.transaction(() => {\n this.db.deleteNodesByFile(extracted.filePath);\n this.db.deleteUnresolvedRefsByFile(extracted.filePath);\n this.db.upsertFile({\n path: extracted.filePath,\n contentHash: extracted.contentHash,\n language: extracted.language,\n fileSize: extracted.fileSize,\n symbolCount: extracted.nodes.length,\n indexedAt: Date.now(),\n });\n for (const node of extracted.nodes) { this.db.upsertNode(node); nodesCreated++; }\n for (const edge of extracted.edges) { this.db.insertEdge(edge); edgesCreated++; }\n for (const ref of extracted.unresolvedRefs) {\n this.db.insertUnresolvedRef(ref.sourceId, ref.refName, ref.refKind, extracted.filePath, ref.line, ref.column);\n }\n });\n filesIndexed++;\n } catch {\n // Already logged in first pass or genuinely broken \u2014 skip\n }\n }\n }\n\n // Resolve cross-file references\n opts?.onProgress?.({ phase: 'resolving', current: 0, total: 1 });\n await this.resolver.resolveAll((current, total) => {\n opts?.onProgress?.({ phase: 'resolving', current, total });\n });\n\n // Detect frameworks\n opts?.onProgress?.({ phase: 'detecting frameworks', current: 0, total: 1 });\n const detectedFrameworks = await detectFrameworks(this.projectRoot, this.db);\n const languages = [...new Set(this.db.getAllFiles().map(f => (f as any).language).filter(Boolean))];\n opts?.onProgress?.({\n phase: 'detecting frameworks', current: 1, total: 1,\n meta: { frameworks: detectedFrameworks.map(f => f.name), languages },\n });\n\n // Generate embeddings (if enabled)\n if (this.vectors.isInitialized()) {\n opts?.onProgress?.({ phase: 'embeddings', current: 0, total: 1 });\n await this.vectors.embedAll((current, total) =>\n opts?.onProgress?.({ phase: 'embeddings', current, total })\n );\n }\n\n // Analyze architecture (if enabled, or auto-enabled for security)\n if (this.config.enableArchitecture || this.config.enableSecurity) {\n if (this.config.enableSecurity && !this.config.enableArchitecture) {\n const { logWarn } = await Promise.resolve().then(() => require('../errors.js'));\n logWarn('enableSecurity requires enableArchitecture \u2014 auto-enabling architecture analysis for this run');\n }\n opts?.onProgress?.({ phase: 'architecture', current: 0, total: 1 });\n await this.arch.analyze(msg =>\n opts?.onProgress?.({ phase: 'architecture', current: 0, total: 1, meta: { msg } })\n );\n opts?.onProgress?.({ phase: 'architecture', current: 1, total: 1 });\n }\n\n // Run security analysis (if enabled)\n if (this.config.enableSecurity) {\n try {\n const { SecurityPipeline } = await Promise.resolve().then(() => require('../security/pipeline.js'));\n this.db.applySecuritySchema();\n const secPipeline = new SecurityPipeline(this.db, this.config, this.projectRoot);\n opts?.onProgress?.({ phase: 'security', current: 0, total: 1 });\n await secPipeline.run((phase, current, total) =>\n opts?.onProgress?.({ phase: 'security', current, total, meta: { secPhase: phase } })\n );\n opts?.onProgress?.({ phase: 'security', current: 1, total: 1 });\n } catch { /* security analysis is non-critical */ }\n }\n\n // Index documentation (if enabled)\n if (this.config.enableDocs) {\n try {\n const { DocsIndexer } = await Promise.resolve().then(() => require('../docs/indexer.js'));\n this.db.applyDocsSchema();\n const docsIndexer = new DocsIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await docsIndexer.indexAll({\n force: opts?.force,\n onProgress: msg => opts?.onProgress?.({ phase: 'docs', current: 0, total: 1, meta: { msg } }),\n });\n } catch { /* docs indexing is non-critical */ }\n }\n\n // Index data files (if enabled)\n if ((this.config as any).enableData) {\n try {\n const { DataIndexer } = await Promise.resolve().then(() => require('../data/indexer.js'));\n this.db.applyDataSchema();\n const dataIndexer = new DataIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await dataIndexer.indexAll({\n onProgress: msg => opts?.onProgress?.({ phase: 'data', current: 0, total: 1, meta: { msg } }),\n });\n\n // Assign data files to 'data' architecture layer if architecture is enabled\n if (this.config.enableArchitecture) {\n try {\n const rawDb = this.db.getRawDb();\n // Check if arch_file_layers table exists\n const tableExists = rawDb.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='arch_file_layers'\");\n if (tableExists) {\n const datasets = rawDb.all('SELECT file_path FROM data_datasets') as Array<{ file_path: string }>;\n for (const ds of datasets) {\n rawDb.run(\n `INSERT OR REPLACE INTO arch_file_layers (file_path, layer_id, confidence) VALUES (?, ?, ?)`,\n [ds.file_path, 'layer:data', 1.0],\n );\n }\n }\n } catch { /* non-critical */ }\n }\n } catch { /* data indexing is non-critical */ }\n }\n\n // Index pattern matches (if enabled)\n if ((this.config as any).enablePatterns) {\n try {\n this.db.applyPatternsSchema();\n const { PatternIndexer } = await Promise.resolve().then(() => require('../patterns/indexer.js'));\n const indexer = new PatternIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await indexer.indexAll((phase, current, total) => {\n opts?.onProgress?.({ phase: 'patterns' as any, current, total });\n });\n } catch (err) {\n // Patterns are non-critical \u2014 log and continue\n const { logWarn } = await Promise.resolve().then(() => require('../errors.js'));\n const msg = err instanceof Error ? err.message : String(err);\n logWarn(`[patterns] Pattern indexing failed (non-critical): ${msg}`);\n }\n }\n\n this.lock.clearDirty();\n return { success: errors.length === 0, filesIndexed, nodesCreated, edgesCreated, errors, duration: Date.now() - start };\n } finally {\n this.lock.release();\n release();\n }\n }\n\n async sync(opts?: {\n changedFiles?: string[];\n onProgress?: (p: IndexProgress) => void;\n }): Promise<SyncResult> {\n const release = await this.mutex.acquire();\n this.lock.acquire();\n const start = Date.now();\n const changedFiles = opts?.changedFiles;\n const onProgress = opts?.onProgress;\n const result: SyncResult = {\n added: [], modified: [], removed: [],\n nodesCreated: 0, nodesUpdated: 0, nodesRemoved: 0,\n edgesCreated: 0, edgesRemoved: 0,\n filesScanned: 0, errors: [], duration: 0,\n };\n\n try {\n const removeFile = async (rel: string) => {\n const oldNodes = this.db.getNodesByFile(rel);\n const oldEdgeCount = this.db.getEdgesForNodes(oldNodes.map(n => n.id)).length;\n result.nodesRemoved += oldNodes.length;\n result.edgesRemoved += oldEdgeCount;\n await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n this.db.deleteFile(rel);\n this.db.deleteUnresolvedRefsByFile(rel);\n // Clean up pattern matches for removed files (only if patterns are enabled)\n if ((this.config as any).enablePatterns) {\n this.db.getRawDb().run('DELETE FROM pattern_matches WHERE file_path = ?', [rel]);\n }\n result.removed.push(rel);\n };\n\n // \u2500\u2500 Exclude-rule cleanup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // Remove any indexed files that now match the current exclude patterns.\n // This handles the case where a user adds a new exclude pattern (e.g.\n // \"**/.vite/**\") and expects those files to disappear from the index on\n // the next sync without needing a full --force re-index.\n const allIndexed = this.db.getAllFiles();\n for (const f of allIndexed) {\n if (!shouldIncludeFile(f.path, this.config)) {\n onProgress?.({ phase: 'scanning', current: 0, total: 0, meta: { excludeCleanup: true, file: f.path } });\n await removeFile(f.path);\n }\n }\n\n let filesToProcess: string[];\n\n onProgress?.({ phase: 'scanning', current: 0, total: 0 });\n\n if (changedFiles) {\n filesToProcess = changedFiles.map(f => path.resolve(this.projectRoot, f));\n } else {\n const gitChanged = await getChangedFiles(this.projectRoot, this.config);\n const hasChanges = gitChanged.added.length > 0 || gitChanged.modified.length > 0 || gitChanged.removed.length > 0;\n\n if (hasChanges) {\n for (const p of gitChanged.removed) {\n await removeFile(path.relative(this.projectRoot, p).replace(/\\\\/g, '/'));\n }\n filesToProcess = [...gitChanged.added, ...gitChanged.modified];\n } else {\n // Fallback: full scan + detect removed files\n const indexed = new Set(this.db.getAllFiles().map(f => f.path));\n const current = new Set(\n (await scanDirectory(this.projectRoot, this.config))\n .map(f => path.relative(this.projectRoot, f).replace(/\\\\/g, '/'))\n );\n result.filesScanned = current.size;\n for (const p of indexed) {\n if (!current.has(p)) await removeFile(p);\n }\n filesToProcess = await scanDirectory(this.projectRoot, this.config);\n }\n }\n\n result.filesScanned = result.filesScanned || filesToProcess.length;\n onProgress?.({ phase: 'scanning', current: result.filesScanned, total: result.filesScanned });\n\n const poisonedLanguages = new Set<string>();\n\n for (let i = 0; i < filesToProcess.length; i++) {\n const file = filesToProcess[i];\n onProgress?.({ phase: 'parsing', current: i + 1, total: filesToProcess.length, currentFile: file });\n\n if (!fs.existsSync(file)) {\n const rel = path.relative(this.projectRoot, file).replace(/\\\\/g, '/');\n await removeFile(rel);\n continue;\n }\n\n try {\n // Skip files whose language parser is currently poisoned\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n if (poisonedLanguages.has(lang)) continue;\n\n const extracted = await extractFile(file, this.projectRoot, undefined, { enableComplexity: !!(this.config as any).enableComplexity });\n if (!extracted) continue;\n\n const existing = this.db.getFile(extracted.filePath);\n const isNew = !existing;\n if (!isNew && existing!.contentHash === extracted.contentHash) continue;\n\n const oldNodes = this.db.getNodesByFile(extracted.filePath);\n const oldEdgeCount = this.db.getEdgesForNodes(oldNodes.map(n => n.id)).length;\n await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n\n this.db.transaction(() => {\n result.nodesRemoved += oldNodes.length;\n result.edgesRemoved += oldEdgeCount;\n this.db.deleteNodesByFile(extracted.filePath);\n this.db.deleteUnresolvedRefsByFile(extracted.filePath);\n this.db.upsertFile({\n path: extracted.filePath,\n contentHash: extracted.contentHash,\n language: extracted.language,\n fileSize: extracted.fileSize,\n symbolCount: extracted.nodes.length,\n indexedAt: Date.now(),\n });\n for (const node of extracted.nodes) { this.db.upsertNode(node); result.nodesCreated++; }\n for (const edge of extracted.edges) { this.db.insertEdge(edge); result.edgesCreated++; }\n for (const ref of extracted.unresolvedRefs) {\n this.db.insertUnresolvedRef(ref.sourceId, ref.refName, ref.refKind, extracted.filePath, ref.line, ref.column);\n }\n });\n\n this.resolver.invalidateFile(extracted.filePath);\n if (isNew) result.added.push(extracted.filePath);\n else { result.modified.push(extracted.filePath); result.nodesUpdated += extracted.nodes.length; }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n result.errors.push(`${file}: ${msg}`);\n\n // Detect WASM runtime abort and attempt recovery\n const isWasmCrash = (err as any)?.constructor?.name === 'RuntimeError'\n || msg.includes('Aborted(') \n || msg.includes('RuntimeError')\n || msg.includes('WASM grammar exists but failed to load');\n if (isWasmCrash) {\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n poisonedLanguages.add(lang);\n\n clearParserCache();\n try {\n await initGrammars();\n poisonedLanguages.clear();\n } catch {\n result.errors.push('WASM runtime unrecoverable after crash \u2014 aborting sync');\n break;\n }\n }\n }\n }\n\n // Resolve cross-file references\n onProgress?.({ phase: 'resolving', current: 0, total: 1 });\n await this.resolver.resolveAll((current, total) => {\n onProgress?.({ phase: 'resolving', current, total });\n });\n\n await detectFrameworks(this.projectRoot);\n\n // Generate embeddings (if enabled)\n if (this.vectors.isInitialized()) {\n onProgress?.({ phase: 'embeddings', current: 0, total: 1 });\n await this.vectors.embedAll((current, total) =>\n onProgress?.({ phase: 'embeddings', current, total })\n );\n }\n\n // Analyze architecture (if enabled, or auto-enabled for security)\n if (this.config.enableArchitecture || this.config.enableSecurity) {\n if (this.config.enableSecurity && !this.config.enableArchitecture) {\n const { logWarn } = await Promise.resolve().then(() => require('../errors.js'));\n logWarn('enableSecurity requires enableArchitecture \u2014 auto-enabling architecture analysis for this run');\n }\n onProgress?.({ phase: 'architecture', current: 0, total: 1 });\n await this.arch.analyze(msg =>\n onProgress?.({ phase: 'architecture', current: 0, total: 1, meta: { msg } })\n );\n onProgress?.({ phase: 'architecture', current: 1, total: 1 });\n }\n\n // Run security analysis (if enabled)\n if (this.config.enableSecurity) {\n try {\n const { SecurityPipeline } = await Promise.resolve().then(() => require('../security/pipeline.js'));\n this.db.applySecuritySchema();\n const secPipeline = new SecurityPipeline(this.db, this.config, this.projectRoot);\n onProgress?.({ phase: 'security', current: 0, total: 1 });\n await secPipeline.run((phase, current, total) =>\n onProgress?.({ phase: 'security', current, total, meta: { secPhase: phase } })\n );\n onProgress?.({ phase: 'security', current: 1, total: 1 });\n } catch { /* security analysis is non-critical */ }\n }\n\n // Re-index documentation (if enabled)\n if (this.config.enableDocs) {\n try {\n const { DocsIndexer } = await Promise.resolve().then(() => require('../docs/indexer.js'));\n this.db.applyDocsSchema();\n const docsIndexer = new DocsIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await docsIndexer.indexAll({\n onProgress: msg => onProgress?.({ phase: 'docs', current: 0, total: 1, meta: { msg } }),\n });\n } catch { /* docs indexing is non-critical */ }\n }\n\n // Re-index data files (if enabled)\n if ((this.config as any).enableData) {\n try {\n const { DataIndexer } = await Promise.resolve().then(() => require('../data/indexer.js'));\n this.db.applyDataSchema();\n const dataIndexer = new DataIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await dataIndexer.indexAll({\n onProgress: msg => onProgress?.({ phase: 'data', current: 0, total: 1, meta: { msg } }),\n });\n\n // Assign data files to 'data' architecture layer if architecture is enabled\n if (this.config.enableArchitecture) {\n try {\n const rawDb = this.db.getRawDb();\n const tableExists = rawDb.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='arch_file_layers'\");\n if (tableExists) {\n const datasets = rawDb.all('SELECT file_path FROM data_datasets') as Array<{ file_path: string }>;\n for (const ds of datasets) {\n rawDb.run(\n `INSERT OR REPLACE INTO arch_file_layers (file_path, layer_id, confidence) VALUES (?, ?, ?)`,\n [ds.file_path, 'layer:data', 1.0],\n );\n }\n }\n } catch { /* non-critical */ }\n }\n } catch { /* data indexing is non-critical */ }\n }\n\n // Re-index pattern matches for changed files (if enabled)\n if ((this.config as any).enablePatterns) {\n try {\n const tableExists = this.db.getRawDb().get(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\"\n );\n if (tableExists) {\n const { PatternIndexer } = await Promise.resolve().then(() => require('../patterns/indexer.js'));\n const { PatternLibraryLoader } = await Promise.resolve().then(() => require('../patterns/loader.js'));\n const { PatternRunner } = await Promise.resolve().then(() => require('../patterns/runner.js'));\n const runner = new PatternRunner();\n if (runner.isAvailable()) {\n const loader = new PatternLibraryLoader();\n const builtinPath = require('path').join(__dirname, '../patterns/library');\n const rules = loader.load(builtinPath, (this.config as any).patternLibraryPath);\n const threshold = (this.config as any).patternSeverityThreshold ?? 'low';\n const indexer = new PatternIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n const changedPaths = [...result.added, ...result.modified];\n for (const filePath of changedPaths) {\n const fileRecord = this.db.getFile(filePath);\n const language = fileRecord?.language ?? 'unknown';\n await indexer.indexFile(filePath, language, rules, runner, threshold, Date.now());\n }\n }\n }\n } catch { /* non-critical */ }\n }\n\n this.lock.clearDirty();\n result.duration = Date.now() - start;\n return result;\n } finally {\n this.lock.release();\n release();\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * IndexPipeline \u2014 full-index and incremental-sync pipelines.\n *\n * Owns the two heavy workflows:\n * - indexAll(): scan all files, extract, store, resolve, detect frameworks,\n * generate embeddings, analyze architecture.\n * - sync(): detect changed files via git (or full scan fallback),\n * re-extract only what changed, then run the same tail pipeline.\n *\n * Everything that touches the filesystem or sub-systems is injected via the\n * constructor, keeping this class testable and free of global state.\n */\n\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { GraphDatabase } from '../db/database';\nimport { scanDirectory, hashContent, getChangedFiles, shouldIncludeFile } from '../sync/index';\nimport { extractFile } from '../extraction/extractor';\nimport { clearParserCache, initGrammars, hasWasmGrammar } from '../extraction/grammars';\nimport { detectFrameworks } from '../frameworks/index';\nimport { ReferenceResolver } from '../resolution/index';\nimport { VectorManager } from '../vectors/index';\nimport { ArchitectureAnalyzer } from '../architecture/index';\nimport type { KiroGraphConfig } from '../config';\nimport type { IndexResult, IndexProgress, SyncResult } from '../types';\nimport { LockManager } from './lock-manager';\nimport { Mutex } from '../utils';\n\nconst FILE_IO_BATCH_SIZE = 10;\n\nexport class IndexPipeline {\n private readonly mutex = new Mutex();\n\n constructor(\n private readonly db: GraphDatabase,\n private readonly vectors: VectorManager,\n private readonly resolver: ReferenceResolver,\n private readonly arch: ArchitectureAnalyzer,\n private readonly lock: LockManager,\n private readonly config: KiroGraphConfig,\n private readonly projectRoot: string,\n ) {}\n\n async indexAll(opts?: {\n onProgress?: (p: IndexProgress) => void;\n force?: boolean;\n signal?: AbortSignal;\n }): Promise<IndexResult> {\n const release = await this.mutex.acquire();\n this.lock.acquire();\n const start = Date.now();\n const errors: string[] = [];\n let filesIndexed = 0;\n let nodesCreated = 0;\n let edgesCreated = 0;\n\n // Track languages whose WASM parser is currently poisoned (ABORT=true on the module).\n // Once a language's parser aborts, every subsequent parse call for that language\n // fails instantly. We skip those files until clearParserCache + initGrammars succeeds.\n const poisonedLanguages = new Set<string>();\n // Track consecutive WASM crashes per language. Only poison after threshold is exceeded.\n const crashCounts = new Map<string, number>();\n const POISON_THRESHOLD = 3;\n\n try {\n const files = await scanDirectory(this.projectRoot, this.config, opts?.signal);\n opts?.onProgress?.({ phase: 'scanning', current: files.length, total: files.length });\n\n // Batch-read files in parallel\n const contentMap = new Map<string, Buffer>();\n for (let b = 0; b < files.length; b += FILE_IO_BATCH_SIZE) {\n const batch = files.slice(b, b + FILE_IO_BATCH_SIZE);\n const results = await Promise.all(batch.map(f => fs.promises.readFile(f).catch(() => null)));\n for (let i = 0; i < batch.length; i++) {\n if (results[i]) contentMap.set(batch[i], results[i]!);\n }\n }\n\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n opts?.onProgress?.({ phase: 'parsing', current: i + 1, total: files.length, currentFile: file });\n\n try {\n const content = contentMap.get(file);\n if (!content) continue;\n if (content.length > this.config.maxFileSize) continue;\n\n const relPath = path.relative(this.projectRoot, file).replace(/\\\\/g, '/');\n\n if (!opts?.force) {\n const existing = this.db.getFile(relPath);\n if (existing && hashContent(content) === existing.contentHash) continue;\n }\n\n // Skip files whose language parser is currently poisoned\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n if (poisonedLanguages.has(lang)) continue;\n\n const extracted = await extractFile(file, this.projectRoot, content, { enableComplexity: !!(this.config as any).enableComplexity, maxFileSize: this.config.maxFileSize });\n if (!extracted) continue;\n\n const oldNodes = this.db.getNodesByFile(extracted.filePath);\n if (oldNodes.length > 0) await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n\n this.db.transaction(() => {\n this.db.deleteNodesByFile(extracted.filePath);\n this.db.deleteUnresolvedRefsByFile(extracted.filePath);\n this.db.upsertFile({\n path: extracted.filePath,\n contentHash: extracted.contentHash,\n language: extracted.language,\n fileSize: extracted.fileSize,\n symbolCount: extracted.nodes.length,\n indexedAt: Date.now(),\n });\n for (const node of extracted.nodes) { this.db.upsertNode(node); nodesCreated++; }\n for (const edge of extracted.edges) { this.db.insertEdge(edge); edgesCreated++; }\n for (const ref of extracted.unresolvedRefs) {\n this.db.insertUnresolvedRef(ref.sourceId, ref.refName, ref.refKind, extracted.filePath, ref.line, ref.column);\n }\n });\n\n filesIndexed++;\n // Reset crash count on successful parse for this language\n crashCounts.set(lang, 0);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push(`${file}: ${msg}`);\n\n // Detect WASM runtime abort and attempt recovery\n const isWasmCrash = (err as any)?.constructor?.name === 'RuntimeError'\n || msg.includes('Aborted(') \n || msg.includes('RuntimeError')\n || msg.includes('WASM grammar exists but failed to load');\n if (isWasmCrash) {\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n const count = (crashCounts.get(lang) ?? 0) + 1;\n crashCounts.set(lang, count);\n\n // Only poison the language after multiple consecutive crashes\n if (count >= POISON_THRESHOLD) {\n poisonedLanguages.add(lang);\n }\n\n clearParserCache();\n try {\n await initGrammars();\n // Recovery succeeded \u2014 WASM runtime is usable again.\n // Languages with count >= POISON_THRESHOLD remain permanently disabled\n // for this run. Other languages (below threshold) were never poisoned\n // and continue parsing normally.\n } catch {\n errors.push('WASM runtime unrecoverable after crash \u2014 aborting batch');\n break;\n }\n }\n }\n }\n\n // Re-process files that have symbolCount=0 but should have symbols (WASM recovery)\n const emptyFiles = this.db.getAllFiles().filter(\n (f: any) => f.symbolCount === 0 && hasWasmGrammar(f.language)\n );\n if (emptyFiles.length > 0) {\n opts?.onProgress?.({ phase: 'retrying', current: 0, total: emptyFiles.length });\n for (let i = 0; i < emptyFiles.length; i++) {\n const ef = emptyFiles[i];\n const absPath = path.join(this.projectRoot, ef.path);\n opts?.onProgress?.({ phase: 'retrying', current: i + 1, total: emptyFiles.length, currentFile: absPath });\n try {\n const extracted = await extractFile(absPath, this.projectRoot, undefined, { enableComplexity: !!(this.config as any).enableComplexity });\n if (!extracted || extracted.nodes.length === 0) continue;\n\n const oldNodes = this.db.getNodesByFile(extracted.filePath);\n if (oldNodes.length > 0) await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n\n this.db.transaction(() => {\n this.db.deleteNodesByFile(extracted.filePath);\n this.db.deleteUnresolvedRefsByFile(extracted.filePath);\n this.db.upsertFile({\n path: extracted.filePath,\n contentHash: extracted.contentHash,\n language: extracted.language,\n fileSize: extracted.fileSize,\n symbolCount: extracted.nodes.length,\n indexedAt: Date.now(),\n });\n for (const node of extracted.nodes) { this.db.upsertNode(node); nodesCreated++; }\n for (const edge of extracted.edges) { this.db.insertEdge(edge); edgesCreated++; }\n for (const ref of extracted.unresolvedRefs) {\n this.db.insertUnresolvedRef(ref.sourceId, ref.refName, ref.refKind, extracted.filePath, ref.line, ref.column);\n }\n });\n filesIndexed++;\n } catch {\n // Already logged in first pass or genuinely broken \u2014 skip\n }\n }\n }\n\n // Resolve cross-file references\n opts?.onProgress?.({ phase: 'resolving', current: 0, total: 1 });\n await this.resolver.resolveAll((current, total) => {\n opts?.onProgress?.({ phase: 'resolving', current, total });\n });\n\n // Detect frameworks\n opts?.onProgress?.({ phase: 'detecting frameworks', current: 0, total: 1 });\n const detectedFrameworks = await detectFrameworks(this.projectRoot, this.db);\n const languages = [...new Set(this.db.getAllFiles().map(f => (f as any).language).filter(Boolean))];\n opts?.onProgress?.({\n phase: 'detecting frameworks', current: 1, total: 1,\n meta: { frameworks: detectedFrameworks.map(f => f.name), languages },\n });\n\n // Generate embeddings (if enabled)\n if (this.vectors.isInitialized()) {\n opts?.onProgress?.({ phase: 'embeddings', current: 0, total: 1 });\n await this.vectors.embedAll((current, total) =>\n opts?.onProgress?.({ phase: 'embeddings', current, total })\n );\n }\n\n // Analyze architecture (if enabled, or auto-enabled for security)\n if (this.config.enableArchitecture || this.config.enableSecurity) {\n if (this.config.enableSecurity && !this.config.enableArchitecture) {\n const { logWarn } = await Promise.resolve().then(() => require('../errors.js'));\n logWarn('enableSecurity requires enableArchitecture \u2014 auto-enabling architecture analysis for this run');\n }\n opts?.onProgress?.({ phase: 'architecture', current: 0, total: 1 });\n await this.arch.analyze(msg =>\n opts?.onProgress?.({ phase: 'architecture', current: 0, total: 1, meta: { msg } })\n );\n opts?.onProgress?.({ phase: 'architecture', current: 1, total: 1 });\n }\n\n // Run security analysis (if enabled)\n if (this.config.enableSecurity) {\n try {\n const { SecurityPipeline } = await Promise.resolve().then(() => require('../security/pipeline.js'));\n this.db.applySecuritySchema();\n const secPipeline = new SecurityPipeline(this.db, this.config, this.projectRoot);\n opts?.onProgress?.({ phase: 'security', current: 0, total: 1 });\n await secPipeline.run((phase, current, total) =>\n opts?.onProgress?.({ phase: 'security', current, total, meta: { secPhase: phase } })\n );\n opts?.onProgress?.({ phase: 'security', current: 1, total: 1 });\n } catch { /* security analysis is non-critical */ }\n }\n\n // Index documentation (if enabled)\n if (this.config.enableDocs) {\n try {\n const { DocsIndexer } = await Promise.resolve().then(() => require('../docs/indexer.js'));\n this.db.applyDocsSchema();\n const docsIndexer = new DocsIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await docsIndexer.indexAll({\n force: opts?.force,\n onProgress: msg => opts?.onProgress?.({ phase: 'docs', current: 0, total: 1, meta: { msg } }),\n });\n } catch { /* docs indexing is non-critical */ }\n }\n\n // Index data files (if enabled)\n if ((this.config as any).enableData) {\n try {\n const { DataIndexer } = await Promise.resolve().then(() => require('../data/indexer.js'));\n this.db.applyDataSchema();\n const dataIndexer = new DataIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await dataIndexer.indexAll({\n onProgress: msg => opts?.onProgress?.({ phase: 'data', current: 0, total: 1, meta: { msg } }),\n });\n\n // Assign data files to 'data' architecture layer if architecture is enabled\n if (this.config.enableArchitecture) {\n try {\n const rawDb = this.db.getRawDb();\n // Check if arch_file_layers table exists\n const tableExists = rawDb.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='arch_file_layers'\");\n if (tableExists) {\n const datasets = rawDb.all('SELECT file_path FROM data_datasets') as Array<{ file_path: string }>;\n for (const ds of datasets) {\n rawDb.run(\n `INSERT OR REPLACE INTO arch_file_layers (file_path, layer_id, confidence) VALUES (?, ?, ?)`,\n [ds.file_path, 'layer:data', 1.0],\n );\n }\n }\n } catch { /* non-critical */ }\n }\n } catch { /* data indexing is non-critical */ }\n }\n\n // Index pattern matches (if enabled)\n if ((this.config as any).enablePatterns) {\n try {\n this.db.applyPatternsSchema();\n const { PatternIndexer } = await Promise.resolve().then(() => require('../patterns/indexer.js'));\n const indexer = new PatternIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await indexer.indexAll((phase, current, total) => {\n opts?.onProgress?.({ phase: 'patterns' as any, current, total });\n });\n } catch (err) {\n // Patterns are non-critical \u2014 log and continue\n const { logWarn } = await Promise.resolve().then(() => require('../errors.js'));\n const msg = err instanceof Error ? err.message : String(err);\n logWarn(`[patterns] Pattern indexing failed (non-critical): ${msg}`);\n }\n }\n\n this.lock.clearDirty();\n return { success: errors.length === 0, filesIndexed, nodesCreated, edgesCreated, errors, duration: Date.now() - start };\n } finally {\n this.lock.release();\n release();\n }\n }\n\n async sync(opts?: {\n changedFiles?: string[];\n onProgress?: (p: IndexProgress) => void;\n }): Promise<SyncResult> {\n const release = await this.mutex.acquire();\n this.lock.acquire();\n const start = Date.now();\n const changedFiles = opts?.changedFiles;\n const onProgress = opts?.onProgress;\n const result: SyncResult = {\n added: [], modified: [], removed: [],\n nodesCreated: 0, nodesUpdated: 0, nodesRemoved: 0,\n edgesCreated: 0, edgesRemoved: 0,\n filesScanned: 0, errors: [], duration: 0,\n };\n\n try {\n const removeFile = async (rel: string) => {\n const oldNodes = this.db.getNodesByFile(rel);\n const oldEdgeCount = this.db.getEdgesForNodes(oldNodes.map(n => n.id)).length;\n result.nodesRemoved += oldNodes.length;\n result.edgesRemoved += oldEdgeCount;\n await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n this.db.deleteFile(rel);\n this.db.deleteUnresolvedRefsByFile(rel);\n // Clean up pattern matches for removed files (only if patterns are enabled)\n if ((this.config as any).enablePatterns) {\n this.db.getRawDb().run('DELETE FROM pattern_matches WHERE file_path = ?', [rel]);\n }\n result.removed.push(rel);\n };\n\n // \u2500\u2500 Exclude-rule cleanup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 // Remove any indexed files that now match the current exclude patterns.\n // This handles the case where a user adds a new exclude pattern (e.g.\n // \"**/.vite/**\") and expects those files to disappear from the index on\n // the next sync without needing a full --force re-index.\n const allIndexed = this.db.getAllFiles();\n for (const f of allIndexed) {\n if (!shouldIncludeFile(f.path, this.config)) {\n onProgress?.({ phase: 'scanning', current: 0, total: 0, meta: { excludeCleanup: true, file: f.path } });\n await removeFile(f.path);\n }\n }\n\n let filesToProcess: string[];\n\n onProgress?.({ phase: 'scanning', current: 0, total: 0 });\n\n if (changedFiles) {\n filesToProcess = changedFiles.map(f => path.resolve(this.projectRoot, f));\n } else {\n const gitChanged = await getChangedFiles(this.projectRoot, this.config);\n const hasChanges = gitChanged.added.length > 0 || gitChanged.modified.length > 0 || gitChanged.removed.length > 0;\n\n if (hasChanges) {\n for (const p of gitChanged.removed) {\n await removeFile(path.relative(this.projectRoot, p).replace(/\\\\/g, '/'));\n }\n filesToProcess = [...gitChanged.added, ...gitChanged.modified];\n } else {\n // Fallback: full scan + detect removed files\n const indexed = new Set(this.db.getAllFiles().map(f => f.path));\n const current = new Set(\n (await scanDirectory(this.projectRoot, this.config))\n .map(f => path.relative(this.projectRoot, f).replace(/\\\\/g, '/'))\n );\n result.filesScanned = current.size;\n for (const p of indexed) {\n if (!current.has(p)) await removeFile(p);\n }\n filesToProcess = await scanDirectory(this.projectRoot, this.config);\n }\n }\n\n result.filesScanned = result.filesScanned || filesToProcess.length;\n onProgress?.({ phase: 'scanning', current: result.filesScanned, total: result.filesScanned });\n\n const poisonedLanguages = new Set<string>();\n const crashCounts = new Map<string, number>();\n const POISON_THRESHOLD = 3;\n\n for (let i = 0; i < filesToProcess.length; i++) {\n const file = filesToProcess[i];\n onProgress?.({ phase: 'parsing', current: i + 1, total: filesToProcess.length, currentFile: file });\n\n if (!fs.existsSync(file)) {\n const rel = path.relative(this.projectRoot, file).replace(/\\\\/g, '/');\n await removeFile(rel);\n continue;\n }\n\n try {\n // Skip files whose language parser is currently poisoned\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n if (poisonedLanguages.has(lang)) continue;\n\n const extracted = await extractFile(file, this.projectRoot, undefined, { enableComplexity: !!(this.config as any).enableComplexity, maxFileSize: this.config.maxFileSize });\n if (!extracted) continue;\n\n const existing = this.db.getFile(extracted.filePath);\n const isNew = !existing;\n if (!isNew && existing!.contentHash === extracted.contentHash) continue;\n\n const oldNodes = this.db.getNodesByFile(extracted.filePath);\n const oldEdgeCount = this.db.getEdgesForNodes(oldNodes.map(n => n.id)).length;\n await this.vectors.deleteEmbeddings(oldNodes.map(n => n.id));\n\n this.db.transaction(() => {\n result.nodesRemoved += oldNodes.length;\n result.edgesRemoved += oldEdgeCount;\n this.db.deleteNodesByFile(extracted.filePath);\n this.db.deleteUnresolvedRefsByFile(extracted.filePath);\n this.db.upsertFile({\n path: extracted.filePath,\n contentHash: extracted.contentHash,\n language: extracted.language,\n fileSize: extracted.fileSize,\n symbolCount: extracted.nodes.length,\n indexedAt: Date.now(),\n });\n for (const node of extracted.nodes) { this.db.upsertNode(node); result.nodesCreated++; }\n for (const edge of extracted.edges) { this.db.insertEdge(edge); result.edgesCreated++; }\n for (const ref of extracted.unresolvedRefs) {\n this.db.insertUnresolvedRef(ref.sourceId, ref.refName, ref.refKind, extracted.filePath, ref.line, ref.column);\n }\n });\n\n this.resolver.invalidateFile(extracted.filePath);\n // Reset crash count on successful parse for this language\n crashCounts.set(lang, 0);\n if (isNew) result.added.push(extracted.filePath);\n else { result.modified.push(extracted.filePath); result.nodesUpdated += extracted.nodes.length; }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n result.errors.push(`${file}: ${msg}`);\n\n // Detect WASM runtime abort and attempt recovery\n const isWasmCrash = (err as any)?.constructor?.name === 'RuntimeError'\n || msg.includes('Aborted(') \n || msg.includes('RuntimeError')\n || msg.includes('WASM grammar exists but failed to load');\n if (isWasmCrash) {\n const { detectLanguage } = await Promise.resolve().then(() => require('../extraction/languages.js'));\n const lang = detectLanguage(file);\n const count = (crashCounts.get(lang) ?? 0) + 1;\n crashCounts.set(lang, count);\n\n if (count >= POISON_THRESHOLD) {\n poisonedLanguages.add(lang);\n }\n\n clearParserCache();\n try {\n await initGrammars();\n // Recovery succeeded \u2014 WASM runtime is usable again.\n // Languages at POISON_THRESHOLD stay disabled for this run.\n } catch {\n result.errors.push('WASM runtime unrecoverable after crash \u2014 aborting sync');\n break;\n }\n }\n }\n }\n\n // Resolve cross-file references\n onProgress?.({ phase: 'resolving', current: 0, total: 1 });\n await this.resolver.resolveAll((current, total) => {\n onProgress?.({ phase: 'resolving', current, total });\n });\n\n await detectFrameworks(this.projectRoot);\n\n // Generate embeddings (if enabled)\n if (this.vectors.isInitialized()) {\n onProgress?.({ phase: 'embeddings', current: 0, total: 1 });\n await this.vectors.embedAll((current, total) =>\n onProgress?.({ phase: 'embeddings', current, total })\n );\n }\n\n // Analyze architecture (if enabled, or auto-enabled for security)\n if (this.config.enableArchitecture || this.config.enableSecurity) {\n if (this.config.enableSecurity && !this.config.enableArchitecture) {\n const { logWarn } = await Promise.resolve().then(() => require('../errors.js'));\n logWarn('enableSecurity requires enableArchitecture \u2014 auto-enabling architecture analysis for this run');\n }\n onProgress?.({ phase: 'architecture', current: 0, total: 1 });\n await this.arch.analyze(msg =>\n onProgress?.({ phase: 'architecture', current: 0, total: 1, meta: { msg } })\n );\n onProgress?.({ phase: 'architecture', current: 1, total: 1 });\n }\n\n // Run security analysis (if enabled)\n if (this.config.enableSecurity) {\n try {\n const { SecurityPipeline } = await Promise.resolve().then(() => require('../security/pipeline.js'));\n this.db.applySecuritySchema();\n const secPipeline = new SecurityPipeline(this.db, this.config, this.projectRoot);\n onProgress?.({ phase: 'security', current: 0, total: 1 });\n await secPipeline.run((phase, current, total) =>\n onProgress?.({ phase: 'security', current, total, meta: { secPhase: phase } })\n );\n onProgress?.({ phase: 'security', current: 1, total: 1 });\n } catch { /* security analysis is non-critical */ }\n }\n\n // Re-index documentation (if enabled)\n if (this.config.enableDocs) {\n try {\n const { DocsIndexer } = await Promise.resolve().then(() => require('../docs/indexer.js'));\n this.db.applyDocsSchema();\n const docsIndexer = new DocsIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await docsIndexer.indexAll({\n onProgress: msg => onProgress?.({ phase: 'docs', current: 0, total: 1, meta: { msg } }),\n });\n } catch { /* docs indexing is non-critical */ }\n }\n\n // Re-index data files (if enabled)\n if ((this.config as any).enableData) {\n try {\n const { DataIndexer } = await Promise.resolve().then(() => require('../data/indexer.js'));\n this.db.applyDataSchema();\n const dataIndexer = new DataIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n await dataIndexer.indexAll({\n onProgress: msg => onProgress?.({ phase: 'data', current: 0, total: 1, meta: { msg } }),\n });\n\n // Assign data files to 'data' architecture layer if architecture is enabled\n if (this.config.enableArchitecture) {\n try {\n const rawDb = this.db.getRawDb();\n const tableExists = rawDb.get(\"SELECT name FROM sqlite_master WHERE type='table' AND name='arch_file_layers'\");\n if (tableExists) {\n const datasets = rawDb.all('SELECT file_path FROM data_datasets') as Array<{ file_path: string }>;\n for (const ds of datasets) {\n rawDb.run(\n `INSERT OR REPLACE INTO arch_file_layers (file_path, layer_id, confidence) VALUES (?, ?, ?)`,\n [ds.file_path, 'layer:data', 1.0],\n );\n }\n }\n } catch { /* non-critical */ }\n }\n } catch { /* data indexing is non-critical */ }\n }\n\n // Re-index pattern matches for changed files (if enabled)\n if ((this.config as any).enablePatterns) {\n try {\n const tableExists = this.db.getRawDb().get(\n \"SELECT name FROM sqlite_master WHERE type='table' AND name='pattern_matches'\"\n );\n if (tableExists) {\n const { PatternIndexer } = await Promise.resolve().then(() => require('../patterns/indexer.js'));\n const { PatternLibraryLoader } = await Promise.resolve().then(() => require('../patterns/loader.js'));\n const { PatternRunner } = await Promise.resolve().then(() => require('../patterns/runner.js'));\n const runner = new PatternRunner();\n if (runner.isAvailable()) {\n const loader = new PatternLibraryLoader();\n const builtinPath = require('path').join(__dirname, '../patterns/library');\n const rules = loader.load(builtinPath, (this.config as any).patternLibraryPath);\n const threshold = (this.config as any).patternSeverityThreshold ?? 'low';\n const indexer = new PatternIndexer(this.db.getRawDb(), this.config, this.projectRoot);\n const changedPaths = [...result.added, ...result.modified];\n for (const filePath of changedPaths) {\n const fileRecord = this.db.getFile(filePath);\n const language = fileRecord?.language ?? 'unknown';\n await indexer.indexFile(filePath, language, rules, runner, threshold, Date.now());\n }\n }\n }\n } catch { /* non-critical */ }\n }\n\n this.lock.clearDirty();\n result.duration = Date.now() - start;\n return result;\n } finally {\n this.lock.release();\n release();\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -66,6 +66,18 @@ async function extractFile(filePath, projectRoot, content, opts) {
66
66
  } catch {
67
67
  return null;
68
68
  }
69
+ if (opts?.maxFileSize !== void 0 && Buffer.byteLength(source, "utf8") > opts.maxFileSize) {
70
+ const relPathSkip = path.relative(projectRoot, filePath).replace(/\\/g, "/");
71
+ return {
72
+ filePath: relPathSkip,
73
+ language,
74
+ contentHash: crypto.createHash("sha256").update(source).digest("hex"),
75
+ fileSize: Buffer.byteLength(source, "utf8"),
76
+ nodes: [],
77
+ edges: [],
78
+ unresolvedRefs: []
79
+ };
80
+ }
69
81
  if (language === "jupyter") {
70
82
  return (0, import_notebook.extractNotebook)(filePath, projectRoot, source);
71
83
  }
@@ -88,7 +100,36 @@ async function extractFile(filePath, projectRoot, content, opts) {
88
100
  }
89
101
  throw new Error(`Parser unavailable for ${language} (WASM grammar exists but failed to load)`);
90
102
  }
91
- const tree = parser.parse(source);
103
+ if (language === "yaml" && source.includes("{{")) {
104
+ return {
105
+ filePath: relPath,
106
+ language,
107
+ contentHash,
108
+ fileSize,
109
+ nodes: [],
110
+ edges: [],
111
+ unresolvedRefs: []
112
+ };
113
+ }
114
+ let tree;
115
+ try {
116
+ tree = parser.parse(source);
117
+ } catch (parseErr) {
118
+ const parseMsg = parseErr?.message ?? String(parseErr);
119
+ const isWasmCrash = parseErr?.constructor?.name === "RuntimeError" || parseMsg.includes("memory access out of bounds") || parseMsg.includes("Aborted(");
120
+ if (isWasmCrash) {
121
+ return {
122
+ filePath: relPath,
123
+ language,
124
+ contentHash,
125
+ fileSize,
126
+ nodes: [],
127
+ edges: [],
128
+ unresolvedRefs: []
129
+ };
130
+ }
131
+ throw parseErr;
132
+ }
92
133
  const nodes = [];
93
134
  const edges = [];
94
135
  const unresolvedRefs = [];
@@ -251,6 +292,8 @@ const KIND_MAP = {
251
292
  // Java, C#
252
293
  // Classes / structs
253
294
  class_declaration: "class",
295
+ abstract_class_declaration: "class",
296
+ // TypeScript `abstract class` (distinct AST node from class_declaration)
254
297
  class_expression: "class",
255
298
  class_definition: "class",
256
299
  // Python, Scala
@@ -403,6 +446,7 @@ function walkTree(node, source, filePath, language, nodes, edges, unresolvedRefs
403
446
  isExported: isExported(node),
404
447
  isAsync: isAsync(node),
405
448
  isStatic: isStatic(node),
449
+ isAbstract: isAbstract(node),
406
450
  updatedAt: now
407
451
  };
408
452
  nodes.push(graphNode);
@@ -821,6 +865,19 @@ function isStatic(node) {
821
865
  }
822
866
  return false;
823
867
  }
868
+ function isAbstract(node) {
869
+ if (node.type === "abstract_class_declaration") return true;
870
+ for (let i = 0; i < node.childCount; i++) {
871
+ const child = node.child(i);
872
+ if (child.type === "abstract") return true;
873
+ if (child.type === "modifiers") {
874
+ for (let j = 0; j < child.childCount; j++) {
875
+ if (child.child(j).type === "abstract") return true;
876
+ }
877
+ }
878
+ }
879
+ return false;
880
+ }
824
881
  const CALL_NODE_TYPES = /* @__PURE__ */ new Set([
825
882
  "call_expression",
826
883
  // JS/TS/Go/Rust/Swift/Kotlin/Dart/C/C++