kirograph 0.16.1 → 0.19.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 (365) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +103 -1605
  3. package/dist/architecture/layers/dart.js +112 -0
  4. package/dist/architecture/layers/dart.js.map +7 -0
  5. package/dist/architecture/layers/index.js +3 -1
  6. package/dist/architecture/layers/index.js.map +2 -2
  7. package/dist/bin/banner.js +74 -6
  8. package/dist/bin/banner.js.map +2 -2
  9. package/dist/bin/commands/affected.js +40 -5
  10. package/dist/bin/commands/affected.js.map +2 -2
  11. package/dist/bin/commands/attack-surface.js +157 -0
  12. package/dist/bin/commands/attack-surface.js.map +7 -0
  13. package/dist/bin/commands/benchmark.js +206 -0
  14. package/dist/bin/commands/benchmark.js.map +7 -0
  15. package/dist/bin/commands/budget.js +70 -0
  16. package/dist/bin/commands/budget.js.map +7 -0
  17. package/dist/bin/commands/communities.js +77 -0
  18. package/dist/bin/commands/communities.js.map +7 -0
  19. package/dist/bin/commands/data.js +665 -0
  20. package/dist/bin/commands/data.js.map +7 -0
  21. package/dist/bin/commands/dep-confusion.js +119 -0
  22. package/dist/bin/commands/dep-confusion.js.map +7 -0
  23. package/dist/bin/commands/export.js +304 -10
  24. package/dist/bin/commands/export.js.map +2 -2
  25. package/dist/bin/commands/flows.js +97 -0
  26. package/dist/bin/commands/flows.js.map +7 -0
  27. package/dist/bin/commands/help.js +386 -100
  28. package/dist/bin/commands/help.js.map +2 -2
  29. package/dist/bin/commands/install.js +90 -8
  30. package/dist/bin/commands/install.js.map +2 -2
  31. package/dist/bin/commands/licenses.js +201 -0
  32. package/dist/bin/commands/licenses.js.map +7 -0
  33. package/dist/bin/commands/reachability.js +160 -0
  34. package/dist/bin/commands/reachability.js.map +7 -0
  35. package/dist/bin/commands/read.js +100 -0
  36. package/dist/bin/commands/read.js.map +7 -0
  37. package/dist/bin/commands/refactor.js +116 -0
  38. package/dist/bin/commands/refactor.js.map +7 -0
  39. package/dist/bin/commands/remediation.js +133 -0
  40. package/dist/bin/commands/remediation.js.map +7 -0
  41. package/dist/bin/commands/sbom.js +76 -0
  42. package/dist/bin/commands/sbom.js.map +7 -0
  43. package/dist/bin/commands/security-ci-report.js +267 -0
  44. package/dist/bin/commands/security-ci-report.js.map +7 -0
  45. package/dist/bin/commands/security-export.js +1349 -0
  46. package/dist/bin/commands/security-export.js.map +7 -0
  47. package/dist/bin/commands/security-flows.js +126 -0
  48. package/dist/bin/commands/security-flows.js.map +7 -0
  49. package/dist/bin/commands/security-secrets.js +170 -0
  50. package/dist/bin/commands/security-secrets.js.map +7 -0
  51. package/dist/bin/commands/security.js +193 -0
  52. package/dist/bin/commands/security.js.map +7 -0
  53. package/dist/bin/commands/staleness.js +144 -0
  54. package/dist/bin/commands/staleness.js.map +7 -0
  55. package/dist/bin/commands/status.js +102 -2
  56. package/dist/bin/commands/status.js.map +2 -2
  57. package/dist/bin/commands/supply-chain.js +138 -0
  58. package/dist/bin/commands/supply-chain.js.map +7 -0
  59. package/dist/bin/commands/uninit.js +109 -60
  60. package/dist/bin/commands/uninit.js.map +2 -2
  61. package/dist/bin/commands/vex.js +76 -0
  62. package/dist/bin/commands/vex.js.map +7 -0
  63. package/dist/bin/commands/vuln-suppress.js +95 -0
  64. package/dist/bin/commands/vuln-suppress.js.map +7 -0
  65. package/dist/bin/commands/vulns.js +382 -0
  66. package/dist/bin/commands/vulns.js.map +7 -0
  67. package/dist/bin/installer/auto-detect.js +125 -0
  68. package/dist/bin/installer/auto-detect.js.map +7 -0
  69. package/dist/bin/installer/cli-agent.js +28 -5
  70. package/dist/bin/installer/cli-agent.js.map +2 -2
  71. package/dist/bin/installer/common.js +47 -0
  72. package/dist/bin/installer/common.js.map +2 -2
  73. package/dist/bin/installer/config-prompt.js +39 -1
  74. package/dist/bin/installer/config-prompt.js.map +2 -2
  75. package/dist/bin/installer/detect.js +309 -0
  76. package/dist/bin/installer/detect.js.map +7 -0
  77. package/dist/bin/installer/index.js +36 -1
  78. package/dist/bin/installer/index.js.map +2 -2
  79. package/dist/bin/installer/instructions.js +195 -3
  80. package/dist/bin/installer/instructions.js.map +2 -2
  81. package/dist/bin/installer/steering.js +440 -0
  82. package/dist/bin/installer/steering.js.map +2 -2
  83. package/dist/bin/installer/targets/aider.js +3 -3
  84. package/dist/bin/installer/targets/aider.js.map +2 -2
  85. package/dist/bin/installer/targets/amp.js +3 -3
  86. package/dist/bin/installer/targets/amp.js.map +2 -2
  87. package/dist/bin/installer/targets/antigravity.js +35 -6
  88. package/dist/bin/installer/targets/antigravity.js.map +2 -2
  89. package/dist/bin/installer/targets/augment.js +3 -3
  90. package/dist/bin/installer/targets/augment.js.map +2 -2
  91. package/dist/bin/installer/targets/claude.js +49 -5
  92. package/dist/bin/installer/targets/claude.js.map +2 -2
  93. package/dist/bin/installer/targets/cline.js +32 -6
  94. package/dist/bin/installer/targets/cline.js.map +2 -2
  95. package/dist/bin/installer/targets/codex.js +64 -12
  96. package/dist/bin/installer/targets/codex.js.map +2 -2
  97. package/dist/bin/installer/targets/continue.js +2 -2
  98. package/dist/bin/installer/targets/continue.js.map +2 -2
  99. package/dist/bin/installer/targets/copilot-cli.js +101 -0
  100. package/dist/bin/installer/targets/copilot-cli.js.map +7 -0
  101. package/dist/bin/installer/targets/copilot.js +31 -5
  102. package/dist/bin/installer/targets/copilot.js.map +2 -2
  103. package/dist/bin/installer/targets/cursor.js +4 -4
  104. package/dist/bin/installer/targets/cursor.js.map +2 -2
  105. package/dist/bin/installer/targets/devin.js +2 -2
  106. package/dist/bin/installer/targets/devin.js.map +2 -2
  107. package/dist/bin/installer/targets/gemini-cli.js +2 -2
  108. package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
  109. package/dist/bin/installer/targets/generic.js +2 -14
  110. package/dist/bin/installer/targets/generic.js.map +2 -2
  111. package/dist/bin/installer/targets/goose.js +3 -3
  112. package/dist/bin/installer/targets/goose.js.map +2 -2
  113. package/dist/bin/installer/targets/index.js +250 -0
  114. package/dist/bin/installer/targets/index.js.map +2 -2
  115. package/dist/bin/installer/targets/junie.js +2 -2
  116. package/dist/bin/installer/targets/junie.js.map +2 -2
  117. package/dist/bin/installer/targets/kilo.js +2 -2
  118. package/dist/bin/installer/targets/kilo.js.map +2 -2
  119. package/dist/bin/installer/targets/kiro.js +3 -3
  120. package/dist/bin/installer/targets/kiro.js.map +2 -2
  121. package/dist/bin/installer/targets/opencode.js +2 -2
  122. package/dist/bin/installer/targets/opencode.js.map +2 -2
  123. package/dist/bin/installer/targets/openhands.js +3 -3
  124. package/dist/bin/installer/targets/openhands.js.map +2 -2
  125. package/dist/bin/installer/targets/qoder.js +91 -0
  126. package/dist/bin/installer/targets/qoder.js.map +7 -0
  127. package/dist/bin/installer/targets/qwen.js +96 -0
  128. package/dist/bin/installer/targets/qwen.js.map +7 -0
  129. package/dist/bin/installer/targets/replit.js +3 -3
  130. package/dist/bin/installer/targets/replit.js.map +2 -2
  131. package/dist/bin/installer/targets/roo.js +2 -2
  132. package/dist/bin/installer/targets/roo.js.map +2 -2
  133. package/dist/bin/installer/targets/tabnine.js +3 -3
  134. package/dist/bin/installer/targets/tabnine.js.map +2 -2
  135. package/dist/bin/installer/targets/trae.js +5 -5
  136. package/dist/bin/installer/targets/trae.js.map +2 -2
  137. package/dist/bin/installer/targets/warp.js +2 -2
  138. package/dist/bin/installer/targets/warp.js.map +2 -2
  139. package/dist/bin/installer/targets/windsurf.js +35 -6
  140. package/dist/bin/installer/targets/windsurf.js.map +2 -2
  141. package/dist/bin/kirograph.js +74 -6
  142. package/dist/bin/kirograph.js.map +3 -3
  143. package/dist/bin/progress.js +30 -0
  144. package/dist/bin/progress.js.map +2 -2
  145. package/dist/compression/naive-cost.js +25 -0
  146. package/dist/compression/naive-cost.js.map +2 -2
  147. package/dist/compression/tracker.js +91 -2
  148. package/dist/compression/tracker.js.map +2 -2
  149. package/dist/compression/types.js.map +1 -1
  150. package/dist/config.js +126 -3
  151. package/dist/config.js.map +2 -2
  152. package/dist/core/pipeline.js +92 -4
  153. package/dist/core/pipeline.js.map +2 -2
  154. package/dist/data/filters.js +105 -0
  155. package/dist/data/filters.js.map +7 -0
  156. package/dist/data/indexer.js +225 -0
  157. package/dist/data/indexer.js.map +7 -0
  158. package/dist/data/linker.js +150 -0
  159. package/dist/data/linker.js.map +7 -0
  160. package/dist/data/lint.js +109 -0
  161. package/dist/data/lint.js.map +7 -0
  162. package/dist/data/parsers/csv.js +132 -0
  163. package/dist/data/parsers/csv.js.map +7 -0
  164. package/dist/data/parsers/excel.js +88 -0
  165. package/dist/data/parsers/excel.js.map +7 -0
  166. package/dist/data/parsers/index.js +79 -0
  167. package/dist/data/parsers/index.js.map +7 -0
  168. package/dist/data/parsers/json-array.js +89 -0
  169. package/dist/data/parsers/json-array.js.map +7 -0
  170. package/dist/data/parsers/jsonl.js +84 -0
  171. package/dist/data/parsers/jsonl.js.map +7 -0
  172. package/dist/data/parsers/parquet.js +95 -0
  173. package/dist/data/parsers/parquet.js.map +7 -0
  174. package/dist/data/profiler.js +182 -0
  175. package/dist/data/profiler.js.map +7 -0
  176. package/dist/data/queries.js +512 -0
  177. package/dist/data/queries.js.map +7 -0
  178. package/dist/data/types.js +17 -0
  179. package/dist/data/types.js.map +7 -0
  180. package/dist/db/data-schema.sql +61 -0
  181. package/dist/db/database.js +67 -5
  182. package/dist/db/database.js.map +2 -2
  183. package/dist/db/memory-schema.sql +5 -1
  184. package/dist/db/schema.sql +3 -1
  185. package/dist/db/security-schema.sql +72 -0
  186. package/dist/extraction/extractor.js +81 -0
  187. package/dist/extraction/extractor.js.map +2 -2
  188. package/dist/extraction/grammars.js +32 -8
  189. package/dist/extraction/grammars.js.map +2 -2
  190. package/dist/extraction/languages.js +43 -1
  191. package/dist/extraction/languages.js.map +2 -2
  192. package/dist/extraction/notebook.js +300 -0
  193. package/dist/extraction/notebook.js.map +7 -0
  194. package/dist/extraction/wasm/tree-sitter-astro.wasm +0 -0
  195. package/dist/extraction/wasm/tree-sitter-gdscript.wasm +0 -0
  196. package/dist/extraction/wasm/tree-sitter-julia.wasm +0 -0
  197. package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  198. package/dist/extraction/wasm/tree-sitter-perl.wasm +0 -0
  199. package/dist/extraction/wasm/tree-sitter-powershell.wasm +0 -0
  200. package/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
  201. package/dist/extraction/wasm/tree-sitter-sql.wasm +0 -0
  202. package/dist/extraction/wasm/tree-sitter-verilog.wasm +0 -0
  203. package/dist/frameworks/flutter.js +130 -0
  204. package/dist/frameworks/flutter.js.map +7 -0
  205. package/dist/frameworks/index.js +7 -1
  206. package/dist/frameworks/index.js.map +3 -3
  207. package/dist/graph/communities.js +317 -0
  208. package/dist/graph/communities.js.map +7 -0
  209. package/dist/graph/flows.js +138 -0
  210. package/dist/graph/flows.js.map +7 -0
  211. package/dist/graph/refactor.js +155 -0
  212. package/dist/graph/refactor.js.map +7 -0
  213. package/dist/index.js +1 -1
  214. package/dist/index.js.map +2 -2
  215. package/dist/mcp/cache.js +172 -0
  216. package/dist/mcp/cache.js.map +7 -0
  217. package/dist/mcp/read-modes.js +295 -0
  218. package/dist/mcp/read-modes.js.map +7 -0
  219. package/dist/mcp/server.js +2 -1
  220. package/dist/mcp/server.js.map +2 -2
  221. package/dist/mcp/tool-names.js +29 -1
  222. package/dist/mcp/tool-names.js.map +2 -2
  223. package/dist/mcp/tools.js +1588 -6
  224. package/dist/mcp/tools.js.map +3 -3
  225. package/dist/memory/database.js +32 -2
  226. package/dist/memory/database.js.map +2 -2
  227. package/dist/memory/types.js.map +1 -1
  228. package/dist/resolution/bridges/android-rn.js +298 -0
  229. package/dist/resolution/bridges/android-rn.js.map +7 -0
  230. package/dist/resolution/bridges/expo-modules.js +155 -0
  231. package/dist/resolution/bridges/expo-modules.js.map +7 -0
  232. package/dist/resolution/bridges/flutter-channel.js +385 -0
  233. package/dist/resolution/bridges/flutter-channel.js.map +7 -0
  234. package/dist/resolution/bridges/index.js +80 -0
  235. package/dist/resolution/bridges/index.js.map +7 -0
  236. package/dist/resolution/bridges/native-events.js +188 -0
  237. package/dist/resolution/bridges/native-events.js.map +7 -0
  238. package/dist/resolution/bridges/native-views.js +244 -0
  239. package/dist/resolution/bridges/native-views.js.map +7 -0
  240. package/dist/resolution/bridges/react-native.js +161 -0
  241. package/dist/resolution/bridges/react-native.js.map +7 -0
  242. package/dist/resolution/bridges/swift-objc.js +227 -0
  243. package/dist/resolution/bridges/swift-objc.js.map +7 -0
  244. package/dist/resolution/bridges/turbomodules.js +216 -0
  245. package/dist/resolution/bridges/turbomodules.js.map +7 -0
  246. package/dist/resolution/index.js +61 -2
  247. package/dist/resolution/index.js.map +2 -2
  248. package/dist/security/attack-surface.js +164 -0
  249. package/dist/security/attack-surface.js.map +7 -0
  250. package/dist/security/context-warnings.js +123 -0
  251. package/dist/security/context-warnings.js.map +7 -0
  252. package/dist/security/context-warnings.test.js +300 -0
  253. package/dist/security/context-warnings.test.js.map +7 -0
  254. package/dist/security/data-flows.js +228 -0
  255. package/dist/security/data-flows.js.map +7 -0
  256. package/dist/security/dep-confusion.js +255 -0
  257. package/dist/security/dep-confusion.js.map +7 -0
  258. package/dist/security/errors.js +51 -0
  259. package/dist/security/errors.js.map +7 -0
  260. package/dist/security/export/fix-suggestions.js +58 -0
  261. package/dist/security/export/fix-suggestions.js.map +7 -0
  262. package/dist/security/export/fix-suggestions.test.js +74 -0
  263. package/dist/security/export/fix-suggestions.test.js.map +7 -0
  264. package/dist/security/export/sbom.js +230 -0
  265. package/dist/security/export/sbom.js.map +7 -0
  266. package/dist/security/export/sbom.test.js +288 -0
  267. package/dist/security/export/sbom.test.js.map +7 -0
  268. package/dist/security/export/serialization.js +142 -0
  269. package/dist/security/export/serialization.js.map +7 -0
  270. package/dist/security/export/serialization.test.js +310 -0
  271. package/dist/security/export/serialization.test.js.map +7 -0
  272. package/dist/security/export/vex.js +220 -0
  273. package/dist/security/export/vex.js.map +7 -0
  274. package/dist/security/export/vex.test.js +278 -0
  275. package/dist/security/export/vex.test.js.map +7 -0
  276. package/dist/security/index.js +67 -0
  277. package/dist/security/index.js.map +7 -0
  278. package/dist/security/integrator-transitives.test.js +359 -0
  279. package/dist/security/integrator-transitives.test.js.map +7 -0
  280. package/dist/security/integrator.js +491 -0
  281. package/dist/security/integrator.js.map +7 -0
  282. package/dist/security/integrator.test.js +237 -0
  283. package/dist/security/integrator.test.js.map +7 -0
  284. package/dist/security/license.js +70 -0
  285. package/dist/security/license.js.map +7 -0
  286. package/dist/security/manifest/adapter.js +243 -0
  287. package/dist/security/manifest/adapter.js.map +7 -0
  288. package/dist/security/manifest/adapter.test.js +272 -0
  289. package/dist/security/manifest/adapter.test.js.map +7 -0
  290. package/dist/security/manifest/parser.js +376 -0
  291. package/dist/security/manifest/parser.js.map +7 -0
  292. package/dist/security/manifest/parser.test.js +110 -0
  293. package/dist/security/manifest/parser.test.js.map +7 -0
  294. package/dist/security/manifest/plugins/cargo.js +233 -0
  295. package/dist/security/manifest/plugins/cargo.js.map +7 -0
  296. package/dist/security/manifest/plugins/cargo.test.js +304 -0
  297. package/dist/security/manifest/plugins/cargo.test.js.map +7 -0
  298. package/dist/security/manifest/plugins/composer.js +152 -0
  299. package/dist/security/manifest/plugins/composer.js.map +7 -0
  300. package/dist/security/manifest/plugins/go.js +146 -0
  301. package/dist/security/manifest/plugins/go.js.map +7 -0
  302. package/dist/security/manifest/plugins/go.test.js +341 -0
  303. package/dist/security/manifest/plugins/go.test.js.map +7 -0
  304. package/dist/security/manifest/plugins/gradle.js +159 -0
  305. package/dist/security/manifest/plugins/gradle.js.map +7 -0
  306. package/dist/security/manifest/plugins/hex.js +159 -0
  307. package/dist/security/manifest/plugins/hex.js.map +7 -0
  308. package/dist/security/manifest/plugins/maven.js +128 -0
  309. package/dist/security/manifest/plugins/maven.js.map +7 -0
  310. package/dist/security/manifest/plugins/maven.test.js +389 -0
  311. package/dist/security/manifest/plugins/maven.test.js.map +7 -0
  312. package/dist/security/manifest/plugins/npm.js +284 -0
  313. package/dist/security/manifest/plugins/npm.js.map +7 -0
  314. package/dist/security/manifest/plugins/npm.test.js +298 -0
  315. package/dist/security/manifest/plugins/npm.test.js.map +7 -0
  316. package/dist/security/manifest/plugins/nuget.js +186 -0
  317. package/dist/security/manifest/plugins/nuget.js.map +7 -0
  318. package/dist/security/manifest/plugins/pip.js +123 -0
  319. package/dist/security/manifest/plugins/pip.js.map +7 -0
  320. package/dist/security/manifest/plugins/pip.test.js +208 -0
  321. package/dist/security/manifest/plugins/pip.test.js.map +7 -0
  322. package/dist/security/manifest/plugins/pubspec.js +212 -0
  323. package/dist/security/manifest/plugins/pubspec.js.map +7 -0
  324. package/dist/security/manifest/plugins/pyproject.js +261 -0
  325. package/dist/security/manifest/plugins/pyproject.js.map +7 -0
  326. package/dist/security/manifest/plugins/rubygems.js +185 -0
  327. package/dist/security/manifest/plugins/rubygems.js.map +7 -0
  328. package/dist/security/manifest/plugins/swift.js +200 -0
  329. package/dist/security/manifest/plugins/swift.js.map +7 -0
  330. package/dist/security/owasp.js +104 -0
  331. package/dist/security/owasp.js.map +7 -0
  332. package/dist/security/pipeline.js +125 -0
  333. package/dist/security/pipeline.js.map +7 -0
  334. package/dist/security/reachability.js +276 -0
  335. package/dist/security/reachability.js.map +7 -0
  336. package/dist/security/reachability.test.js +394 -0
  337. package/dist/security/reachability.test.js.map +7 -0
  338. package/dist/security/remediation.js +126 -0
  339. package/dist/security/remediation.js.map +7 -0
  340. package/dist/security/secrets.js +176 -0
  341. package/dist/security/secrets.js.map +7 -0
  342. package/dist/security/staleness.js +231 -0
  343. package/dist/security/staleness.js.map +7 -0
  344. package/dist/security/supply-chain.js +301 -0
  345. package/dist/security/supply-chain.js.map +7 -0
  346. package/dist/security/suppressions.js +106 -0
  347. package/dist/security/suppressions.js.map +7 -0
  348. package/dist/security/types.js +17 -0
  349. package/dist/security/types.js.map +7 -0
  350. package/dist/security/vuln/client.js +355 -0
  351. package/dist/security/vuln/client.js.map +7 -0
  352. package/dist/security/vuln/client.test.js +288 -0
  353. package/dist/security/vuln/client.test.js.map +7 -0
  354. package/dist/security/vuln/epss-client.js +95 -0
  355. package/dist/security/vuln/epss-client.js.map +7 -0
  356. package/dist/security/vuln/index.js +29 -0
  357. package/dist/security/vuln/index.js.map +7 -0
  358. package/dist/security/vuln/osv-adapter.js +321 -0
  359. package/dist/security/vuln/osv-adapter.js.map +7 -0
  360. package/dist/security/vuln/osv-adapter.test.js +391 -0
  361. package/dist/security/vuln/osv-adapter.test.js.map +7 -0
  362. package/dist/security/vuln/types.js +17 -0
  363. package/dist/security/vuln/types.js.map +7 -0
  364. package/dist/types.js.map +2 -2
  365. package/package.json +5 -2
@@ -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);\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);\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)\n if (this.config.enableArchitecture) {\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 // 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: 'architecture', current: 0, total: 1, meta: { msg } }),\n });\n } catch { /* docs indexing is non-critical */ }\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 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);\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)\n if (this.config.enableArchitecture) {\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 // 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: 'architecture', current: 0, total: 1, meta: { msg } }),\n });\n } catch { /* docs indexing is 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\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);\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);\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 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 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);\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 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": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,WAAsB;AACtB,SAAoB;AAEpB,kBAA+E;AAC/E,uBAA4B;AAC5B,sBAA+D;AAC/D,wBAAiC;AAOjC,mBAAsB;AAEtB,MAAM,qBAAqB;AAEpB,MAAM,cAAc;AAAA,EAGzB,YACmB,IACA,SACA,UACA,MACA,MACA,QACA,aACjB;AAPiB;AACA;AACA;AACA;AACA;AACA;AACA;AATnB,SAAiB,QAAQ,IAAI,mBAAM;AAAA,EAUhC;AAAA,EAEH,MAAM,SAAS,MAIU;AACvB,UAAM,UAAU,MAAM,KAAK,MAAM,QAAQ;AACzC,SAAK,KAAK,QAAQ;AAClB,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,SAAmB,CAAC;AAC1B,QAAI,eAAe;AACnB,QAAI,eAAe;AACnB,QAAI,eAAe;AAKnB,UAAM,oBAAoB,oBAAI,IAAY;AAE1C,QAAI;AACF,YAAM,QAAQ,UAAM,2BAAc,KAAK,aAAa,KAAK,QAAQ,MAAM,MAAM;AAC7E,YAAM,aAAa,EAAE,OAAO,YAAY,SAAS,MAAM,QAAQ,OAAO,MAAM,OAAO,CAAC;AAGpF,YAAM,aAAa,oBAAI,IAAoB;AAC3C,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,oBAAoB;AACzD,cAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,kBAAkB;AACnD,cAAM,UAAU,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAK,GAAG,SAAS,SAAS,CAAC,EAAE,MAAM,MAAM,IAAI,CAAC,CAAC;AAC3F,iBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAI,QAAQ,CAAC,EAAG,YAAW,IAAI,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAE;AAAA,QACtD;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAM,OAAO,MAAM,CAAC;AACpB,cAAM,aAAa,EAAE,OAAO,WAAW,SAAS,IAAI,GAAG,OAAO,MAAM,QAAQ,aAAa,KAAK,CAAC;AAE/F,YAAI;AACF,gBAAM,UAAU,WAAW,IAAI,IAAI;AACnC,cAAI,CAAC,QAAS;AACd,cAAI,QAAQ,SAAS,KAAK,OAAO,YAAa;AAE9C,gBAAM,UAAU,KAAK,SAAS,KAAK,aAAa,IAAI,EAAE,QAAQ,OAAO,GAAG;AAExE,cAAI,CAAC,MAAM,OAAO;AAChB,kBAAM,WAAW,KAAK,GAAG,QAAQ,OAAO;AACxC,gBAAI,gBAAY,yBAAY,OAAO,MAAM,SAAS,YAAa;AAAA,UACjE;AAGA,gBAAM,EAAE,eAAe,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,4BAA4B,CAAC;AACnG,gBAAM,OAAO,eAAe,IAAI;AAChC,cAAI,kBAAkB,IAAI,IAAI,EAAG;AAEjC,gBAAM,YAAY,UAAM,8BAAY,MAAM,KAAK,aAAa,OAAO;AACnE,cAAI,CAAC,UAAW;AAEhB,gBAAM,WAAW,KAAK,GAAG,eAAe,UAAU,QAAQ;AAC1D,cAAI,SAAS,SAAS,EAAG,OAAM,KAAK,QAAQ,iBAAiB,SAAS,IAAI,OAAK,EAAE,EAAE,CAAC;AAEpF,eAAK,GAAG,YAAY,MAAM;AACxB,iBAAK,GAAG,kBAAkB,UAAU,QAAQ;AAC5C,iBAAK,GAAG,2BAA2B,UAAU,QAAQ;AACrD,iBAAK,GAAG,WAAW;AAAA,cACjB,MAAM,UAAU;AAAA,cAChB,aAAa,UAAU;AAAA,cACvB,UAAU,UAAU;AAAA,cACpB,UAAU,UAAU;AAAA,cACpB,aAAa,UAAU,MAAM;AAAA,cAC7B,WAAW,KAAK,IAAI;AAAA,YACtB,CAAC;AACD,uBAAW,QAAQ,UAAU,OAAO;AAAE,mBAAK,GAAG,WAAW,IAAI;AAAG;AAAA,YAAgB;AAChF,uBAAW,QAAQ,UAAU,OAAO;AAAE,mBAAK,GAAG,WAAW,IAAI;AAAG;AAAA,YAAgB;AAChF,uBAAW,OAAO,UAAU,gBAAgB;AAC1C,mBAAK,GAAG,oBAAoB,IAAI,UAAU,IAAI,SAAS,IAAI,SAAS,UAAU,UAAU,IAAI,MAAM,IAAI,MAAM;AAAA,YAC9G;AAAA,UACF,CAAC;AAED;AAAA,QACF,SAAS,KAAK;AACZ,gBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,iBAAO,KAAK,GAAG,IAAI,KAAK,GAAG,EAAE;AAG7B,gBAAM,cAAe,KAAa,aAAa,SAAS,kBACnD,IAAI,SAAS,UAAU,KACvB,IAAI,SAAS,cAAc,KAC3B,IAAI,SAAS,wCAAwC;AAC1D,cAAI,aAAa;AAEf,kBAAM,EAAE,eAAe,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,4BAA4B,CAAC;AACnG,kBAAM,OAAO,eAAe,IAAI;AAChC,8BAAkB,IAAI,IAAI;AAE1B,kDAAiB;AACjB,gBAAI;AACF,wBAAM,8BAAa;AAEnB,gCAAkB,MAAM;AAAA,YAC1B,QAAQ;AACN,qBAAO,KAAK,8DAAyD;AACrE;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,YAAM,aAAa,KAAK,GAAG,YAAY,EAAE;AAAA,QACvC,CAAC,MAAW,EAAE,gBAAgB,SAAK,gCAAe,EAAE,QAAQ;AAAA,MAC9D;AACA,UAAI,WAAW,SAAS,GAAG;AACzB,cAAM,aAAa,EAAE,OAAO,YAAY,SAAS,GAAG,OAAO,WAAW,OAAO,CAAC;AAC9E,iBAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,gBAAM,KAAK,WAAW,CAAC;AACvB,gBAAM,UAAU,KAAK,KAAK,KAAK,aAAa,GAAG,IAAI;AACnD,gBAAM,aAAa,EAAE,OAAO,YAAY,SAAS,IAAI,GAAG,OAAO,WAAW,QAAQ,aAAa,QAAQ,CAAC;AACxG,cAAI;AACF,kBAAM,YAAY,UAAM,8BAAY,SAAS,KAAK,WAAW;AAC7D,gBAAI,CAAC,aAAa,UAAU,MAAM,WAAW,EAAG;AAEhD,kBAAM,WAAW,KAAK,GAAG,eAAe,UAAU,QAAQ;AAC1D,gBAAI,SAAS,SAAS,EAAG,OAAM,KAAK,QAAQ,iBAAiB,SAAS,IAAI,OAAK,EAAE,EAAE,CAAC;AAEpF,iBAAK,GAAG,YAAY,MAAM;AACxB,mBAAK,GAAG,kBAAkB,UAAU,QAAQ;AAC5C,mBAAK,GAAG,2BAA2B,UAAU,QAAQ;AACrD,mBAAK,GAAG,WAAW;AAAA,gBACjB,MAAM,UAAU;AAAA,gBAChB,aAAa,UAAU;AAAA,gBACvB,UAAU,UAAU;AAAA,gBACpB,UAAU,UAAU;AAAA,gBACpB,aAAa,UAAU,MAAM;AAAA,gBAC7B,WAAW,KAAK,IAAI;AAAA,cACtB,CAAC;AACD,yBAAW,QAAQ,UAAU,OAAO;AAAE,qBAAK,GAAG,WAAW,IAAI;AAAG;AAAA,cAAgB;AAChF,yBAAW,QAAQ,UAAU,OAAO;AAAE,qBAAK,GAAG,WAAW,IAAI;AAAG;AAAA,cAAgB;AAChF,yBAAW,OAAO,UAAU,gBAAgB;AAC1C,qBAAK,GAAG,oBAAoB,IAAI,UAAU,IAAI,SAAS,IAAI,SAAS,UAAU,UAAU,IAAI,MAAM,IAAI,MAAM;AAAA,cAC9G;AAAA,YACF,CAAC;AACD;AAAA,UACF,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAGA,YAAM,aAAa,EAAE,OAAO,aAAa,SAAS,GAAG,OAAO,EAAE,CAAC;AAC/D,YAAM,KAAK,SAAS,WAAW,CAAC,SAAS,UAAU;AACjD,cAAM,aAAa,EAAE,OAAO,aAAa,SAAS,MAAM,CAAC;AAAA,MAC3D,CAAC;AAGD,YAAM,aAAa,EAAE,OAAO,wBAAwB,SAAS,GAAG,OAAO,EAAE,CAAC;AAC1E,YAAM,qBAAqB,UAAM,oCAAiB,KAAK,aAAa,KAAK,EAAE;AAC3E,YAAM,YAAY,CAAC,GAAG,IAAI,IAAI,KAAK,GAAG,YAAY,EAAE,IAAI,OAAM,EAAU,QAAQ,EAAE,OAAO,OAAO,CAAC,CAAC;AAClG,YAAM,aAAa;AAAA,QACjB,OAAO;AAAA,QAAwB,SAAS;AAAA,QAAG,OAAO;AAAA,QAClD,MAAM,EAAE,YAAY,mBAAmB,IAAI,OAAK,EAAE,IAAI,GAAG,UAAU;AAAA,MACrE,CAAC;AAGD,UAAI,KAAK,QAAQ,cAAc,GAAG;AAChC,cAAM,aAAa,EAAE,OAAO,cAAc,SAAS,GAAG,OAAO,EAAE,CAAC;AAChE,cAAM,KAAK,QAAQ;AAAA,UAAS,CAAC,SAAS,UACpC,MAAM,aAAa,EAAE,OAAO,cAAc,SAAS,MAAM,CAAC;AAAA,QAC5D;AAAA,MACF;AAGA,UAAI,KAAK,OAAO,sBAAsB,KAAK,OAAO,gBAAgB;AAChE,YAAI,KAAK,OAAO,kBAAkB,CAAC,KAAK,OAAO,oBAAoB;AACjE,gBAAM,EAAE,QAAQ,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,cAAc,CAAC;AAC9E,kBAAQ,oGAA+F;AAAA,QACzG;AACA,cAAM,aAAa,EAAE,OAAO,gBAAgB,SAAS,GAAG,OAAO,EAAE,CAAC;AAClE,cAAM,KAAK,KAAK;AAAA,UAAQ,SACtB,MAAM,aAAa,EAAE,OAAO,gBAAgB,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,QACnF;AACA,cAAM,aAAa,EAAE,OAAO,gBAAgB,SAAS,GAAG,OAAO,EAAE,CAAC;AAAA,MACpE;AAGA,UAAI,KAAK,OAAO,gBAAgB;AAC9B,YAAI;AACF,gBAAM,EAAE,iBAAiB,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,yBAAyB,CAAC;AAClG,eAAK,GAAG,oBAAoB;AAC5B,gBAAM,cAAc,IAAI,iBAAiB,KAAK,IAAI,KAAK,QAAQ,KAAK,WAAW;AAC/E,gBAAM,aAAa,EAAE,OAAO,YAAY,SAAS,GAAG,OAAO,EAAE,CAAC;AAC9D,gBAAM,YAAY;AAAA,YAAI,CAAC,OAAO,SAAS,UACrC,MAAM,aAAa,EAAE,OAAO,YAAY,SAAS,OAAO,MAAM,EAAE,UAAU,MAAM,EAAE,CAAC;AAAA,UACrF;AACA,gBAAM,aAAa,EAAE,OAAO,YAAY,SAAS,GAAG,OAAO,EAAE,CAAC;AAAA,QAChE,QAAQ;AAAA,QAA0C;AAAA,MACpD;AAGA,UAAI,KAAK,OAAO,YAAY;AAC1B,YAAI;AACF,gBAAM,EAAE,YAAY,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,oBAAoB,CAAC;AACxF,eAAK,GAAG,gBAAgB;AACxB,gBAAM,cAAc,IAAI,YAAY,KAAK,GAAG,SAAS,GAAG,KAAK,QAAQ,KAAK,WAAW;AACrF,gBAAM,YAAY,SAAS;AAAA,YACzB,OAAO,MAAM;AAAA,YACb,YAAY,SAAO,MAAM,aAAa,EAAE,OAAO,QAAQ,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,UAC9F,CAAC;AAAA,QACH,QAAQ;AAAA,QAAsC;AAAA,MAChD;AAGA,UAAK,KAAK,OAAe,YAAY;AACnC,YAAI;AACF,gBAAM,EAAE,YAAY,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,oBAAoB,CAAC;AACxF,eAAK,GAAG,gBAAgB;AACxB,gBAAM,cAAc,IAAI,YAAY,KAAK,GAAG,SAAS,GAAG,KAAK,QAAQ,KAAK,WAAW;AACrF,gBAAM,YAAY,SAAS;AAAA,YACzB,YAAY,SAAO,MAAM,aAAa,EAAE,OAAO,QAAQ,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,UAC9F,CAAC;AAGD,cAAI,KAAK,OAAO,oBAAoB;AAClC,gBAAI;AACF,oBAAM,QAAQ,KAAK,GAAG,SAAS;AAE/B,oBAAM,cAAc,MAAM,IAAI,+EAA+E;AAC7G,kBAAI,aAAa;AACf,sBAAM,WAAW,MAAM,IAAI,qCAAqC;AAChE,2BAAW,MAAM,UAAU;AACzB,wBAAM;AAAA,oBACJ;AAAA,oBACA,CAAC,GAAG,WAAW,cAAc,CAAG;AAAA,kBAClC;AAAA,gBACF;AAAA,cACF;AAAA,YACF,QAAQ;AAAA,YAAqB;AAAA,UAC/B;AAAA,QACF,QAAQ;AAAA,QAAsC;AAAA,MAChD;AAEA,WAAK,KAAK,WAAW;AACrB,aAAO,EAAE,SAAS,OAAO,WAAW,GAAG,cAAc,cAAc,cAAc,QAAQ,UAAU,KAAK,IAAI,IAAI,MAAM;AAAA,IACxH,UAAE;AACA,WAAK,KAAK,QAAQ;AAClB,cAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,MAGa;AACtB,UAAM,UAAU,MAAM,KAAK,MAAM,QAAQ;AACzC,SAAK,KAAK,QAAQ;AAClB,UAAM,QAAQ,KAAK,IAAI;AACvB,UAAM,eAAe,MAAM;AAC3B,UAAM,aAAa,MAAM;AACzB,UAAM,SAAqB;AAAA,MACzB,OAAO,CAAC;AAAA,MAAG,UAAU,CAAC;AAAA,MAAG,SAAS,CAAC;AAAA,MACnC,cAAc;AAAA,MAAG,cAAc;AAAA,MAAG,cAAc;AAAA,MAChD,cAAc;AAAA,MAAG,cAAc;AAAA,MAC/B,cAAc;AAAA,MAAG,QAAQ,CAAC;AAAA,MAAG,UAAU;AAAA,IACzC;AAEA,QAAI;AACF,YAAM,aAAa,OAAO,QAAgB;AACxC,cAAM,WAAW,KAAK,GAAG,eAAe,GAAG;AAC3C,cAAM,eAAe,KAAK,GAAG,iBAAiB,SAAS,IAAI,OAAK,EAAE,EAAE,CAAC,EAAE;AACvE,eAAO,gBAAgB,SAAS;AAChC,eAAO,gBAAgB;AACvB,cAAM,KAAK,QAAQ,iBAAiB,SAAS,IAAI,OAAK,EAAE,EAAE,CAAC;AAC3D,aAAK,GAAG,WAAW,GAAG;AACtB,aAAK,GAAG,2BAA2B,GAAG;AACtC,eAAO,QAAQ,KAAK,GAAG;AAAA,MACzB;AAOA,YAAM,aAAa,KAAK,GAAG,YAAY;AACvC,iBAAW,KAAK,YAAY;AAC1B,YAAI,KAAC,+BAAkB,EAAE,MAAM,KAAK,MAAM,GAAG;AAC3C,uBAAa,EAAE,OAAO,YAAY,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,gBAAgB,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC;AACtG,gBAAM,WAAW,EAAE,IAAI;AAAA,QACzB;AAAA,MACF;AAEA,UAAI;AAEJ,mBAAa,EAAE,OAAO,YAAY,SAAS,GAAG,OAAO,EAAE,CAAC;AAExD,UAAI,cAAc;AAChB,yBAAiB,aAAa,IAAI,OAAK,KAAK,QAAQ,KAAK,aAAa,CAAC,CAAC;AAAA,MAC1E,OAAO;AACL,cAAM,aAAa,UAAM,6BAAgB,KAAK,aAAa,KAAK,MAAM;AACtE,cAAM,aAAa,WAAW,MAAM,SAAS,KAAK,WAAW,SAAS,SAAS,KAAK,WAAW,QAAQ,SAAS;AAEhH,YAAI,YAAY;AACd,qBAAW,KAAK,WAAW,SAAS;AAClC,kBAAM,WAAW,KAAK,SAAS,KAAK,aAAa,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA,UACzE;AACA,2BAAiB,CAAC,GAAG,WAAW,OAAO,GAAG,WAAW,QAAQ;AAAA,QAC/D,OAAO;AAEL,gBAAM,UAAU,IAAI,IAAI,KAAK,GAAG,YAAY,EAAE,IAAI,OAAK,EAAE,IAAI,CAAC;AAC9D,gBAAM,UAAU,IAAI;AAAA,aACjB,UAAM,2BAAc,KAAK,aAAa,KAAK,MAAM,GAC/C,IAAI,OAAK,KAAK,SAAS,KAAK,aAAa,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA,UACpE;AACA,iBAAO,eAAe,QAAQ;AAC9B,qBAAW,KAAK,SAAS;AACvB,gBAAI,CAAC,QAAQ,IAAI,CAAC,EAAG,OAAM,WAAW,CAAC;AAAA,UACzC;AACA,2BAAiB,UAAM,2BAAc,KAAK,aAAa,KAAK,MAAM;AAAA,QACpE;AAAA,MACF;AAEA,aAAO,eAAe,OAAO,gBAAgB,eAAe;AAC5D,mBAAa,EAAE,OAAO,YAAY,SAAS,OAAO,cAAc,OAAO,OAAO,aAAa,CAAC;AAE5F,YAAM,oBAAoB,oBAAI,IAAY;AAE1C,eAAS,IAAI,GAAG,IAAI,eAAe,QAAQ,KAAK;AAC9C,cAAM,OAAO,eAAe,CAAC;AAC7B,qBAAa,EAAE,OAAO,WAAW,SAAS,IAAI,GAAG,OAAO,eAAe,QAAQ,aAAa,KAAK,CAAC;AAElG,YAAI,CAAC,GAAG,WAAW,IAAI,GAAG;AACxB,gBAAM,MAAM,KAAK,SAAS,KAAK,aAAa,IAAI,EAAE,QAAQ,OAAO,GAAG;AACpE,gBAAM,WAAW,GAAG;AACpB;AAAA,QACF;AAEA,YAAI;AAEF,gBAAM,EAAE,eAAe,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,4BAA4B,CAAC;AACnG,gBAAM,OAAO,eAAe,IAAI;AAChC,cAAI,kBAAkB,IAAI,IAAI,EAAG;AAEjC,gBAAM,YAAY,UAAM,8BAAY,MAAM,KAAK,WAAW;AAC1D,cAAI,CAAC,UAAW;AAEhB,gBAAM,WAAW,KAAK,GAAG,QAAQ,UAAU,QAAQ;AACnD,gBAAM,QAAQ,CAAC;AACf,cAAI,CAAC,SAAS,SAAU,gBAAgB,UAAU,YAAa;AAE/D,gBAAM,WAAW,KAAK,GAAG,eAAe,UAAU,QAAQ;AAC1D,gBAAM,eAAe,KAAK,GAAG,iBAAiB,SAAS,IAAI,OAAK,EAAE,EAAE,CAAC,EAAE;AACvE,gBAAM,KAAK,QAAQ,iBAAiB,SAAS,IAAI,OAAK,EAAE,EAAE,CAAC;AAE3D,eAAK,GAAG,YAAY,MAAM;AACxB,mBAAO,gBAAgB,SAAS;AAChC,mBAAO,gBAAgB;AACvB,iBAAK,GAAG,kBAAkB,UAAU,QAAQ;AAC5C,iBAAK,GAAG,2BAA2B,UAAU,QAAQ;AACrD,iBAAK,GAAG,WAAW;AAAA,cACjB,MAAM,UAAU;AAAA,cAChB,aAAa,UAAU;AAAA,cACvB,UAAU,UAAU;AAAA,cACpB,UAAU,UAAU;AAAA,cACpB,aAAa,UAAU,MAAM;AAAA,cAC7B,WAAW,KAAK,IAAI;AAAA,YACtB,CAAC;AACD,uBAAW,QAAQ,UAAU,OAAO;AAAE,mBAAK,GAAG,WAAW,IAAI;AAAG,qBAAO;AAAA,YAAgB;AACvF,uBAAW,QAAQ,UAAU,OAAO;AAAE,mBAAK,GAAG,WAAW,IAAI;AAAG,qBAAO;AAAA,YAAgB;AACvF,uBAAW,OAAO,UAAU,gBAAgB;AAC1C,mBAAK,GAAG,oBAAoB,IAAI,UAAU,IAAI,SAAS,IAAI,SAAS,UAAU,UAAU,IAAI,MAAM,IAAI,MAAM;AAAA,YAC9G;AAAA,UACF,CAAC;AAED,eAAK,SAAS,eAAe,UAAU,QAAQ;AAC/C,cAAI,MAAO,QAAO,MAAM,KAAK,UAAU,QAAQ;AAAA,eAC1C;AAAE,mBAAO,SAAS,KAAK,UAAU,QAAQ;AAAG,mBAAO,gBAAgB,UAAU,MAAM;AAAA,UAAQ;AAAA,QAClG,SAAS,KAAK;AACZ,gBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,iBAAO,OAAO,KAAK,GAAG,IAAI,KAAK,GAAG,EAAE;AAGpC,gBAAM,cAAe,KAAa,aAAa,SAAS,kBACnD,IAAI,SAAS,UAAU,KACvB,IAAI,SAAS,cAAc,KAC3B,IAAI,SAAS,wCAAwC;AAC1D,cAAI,aAAa;AACf,kBAAM,EAAE,eAAe,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,4BAA4B,CAAC;AACnG,kBAAM,OAAO,eAAe,IAAI;AAChC,8BAAkB,IAAI,IAAI;AAE1B,kDAAiB;AACjB,gBAAI;AACF,wBAAM,8BAAa;AACnB,gCAAkB,MAAM;AAAA,YAC1B,QAAQ;AACN,qBAAO,OAAO,KAAK,6DAAwD;AAC3E;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAGA,mBAAa,EAAE,OAAO,aAAa,SAAS,GAAG,OAAO,EAAE,CAAC;AACzD,YAAM,KAAK,SAAS,WAAW,CAAC,SAAS,UAAU;AACjD,qBAAa,EAAE,OAAO,aAAa,SAAS,MAAM,CAAC;AAAA,MACrD,CAAC;AAED,gBAAM,oCAAiB,KAAK,WAAW;AAGvC,UAAI,KAAK,QAAQ,cAAc,GAAG;AAChC,qBAAa,EAAE,OAAO,cAAc,SAAS,GAAG,OAAO,EAAE,CAAC;AAC1D,cAAM,KAAK,QAAQ;AAAA,UAAS,CAAC,SAAS,UACpC,aAAa,EAAE,OAAO,cAAc,SAAS,MAAM,CAAC;AAAA,QACtD;AAAA,MACF;AAGA,UAAI,KAAK,OAAO,sBAAsB,KAAK,OAAO,gBAAgB;AAChE,YAAI,KAAK,OAAO,kBAAkB,CAAC,KAAK,OAAO,oBAAoB;AACjE,gBAAM,EAAE,QAAQ,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,cAAc,CAAC;AAC9E,kBAAQ,oGAA+F;AAAA,QACzG;AACA,qBAAa,EAAE,OAAO,gBAAgB,SAAS,GAAG,OAAO,EAAE,CAAC;AAC5D,cAAM,KAAK,KAAK;AAAA,UAAQ,SACtB,aAAa,EAAE,OAAO,gBAAgB,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,QAC7E;AACA,qBAAa,EAAE,OAAO,gBAAgB,SAAS,GAAG,OAAO,EAAE,CAAC;AAAA,MAC9D;AAGA,UAAI,KAAK,OAAO,gBAAgB;AAC9B,YAAI;AACF,gBAAM,EAAE,iBAAiB,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,yBAAyB,CAAC;AAClG,eAAK,GAAG,oBAAoB;AAC5B,gBAAM,cAAc,IAAI,iBAAiB,KAAK,IAAI,KAAK,QAAQ,KAAK,WAAW;AAC/E,uBAAa,EAAE,OAAO,YAAY,SAAS,GAAG,OAAO,EAAE,CAAC;AACxD,gBAAM,YAAY;AAAA,YAAI,CAAC,OAAO,SAAS,UACrC,aAAa,EAAE,OAAO,YAAY,SAAS,OAAO,MAAM,EAAE,UAAU,MAAM,EAAE,CAAC;AAAA,UAC/E;AACA,uBAAa,EAAE,OAAO,YAAY,SAAS,GAAG,OAAO,EAAE,CAAC;AAAA,QAC1D,QAAQ;AAAA,QAA0C;AAAA,MACpD;AAGA,UAAI,KAAK,OAAO,YAAY;AAC1B,YAAI;AACF,gBAAM,EAAE,YAAY,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,oBAAoB,CAAC;AACxF,eAAK,GAAG,gBAAgB;AACxB,gBAAM,cAAc,IAAI,YAAY,KAAK,GAAG,SAAS,GAAG,KAAK,QAAQ,KAAK,WAAW;AACrF,gBAAM,YAAY,SAAS;AAAA,YACzB,YAAY,SAAO,aAAa,EAAE,OAAO,QAAQ,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,UACxF,CAAC;AAAA,QACH,QAAQ;AAAA,QAAsC;AAAA,MAChD;AAGA,UAAK,KAAK,OAAe,YAAY;AACnC,YAAI;AACF,gBAAM,EAAE,YAAY,IAAI,MAAM,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,oBAAoB,CAAC;AACxF,eAAK,GAAG,gBAAgB;AACxB,gBAAM,cAAc,IAAI,YAAY,KAAK,GAAG,SAAS,GAAG,KAAK,QAAQ,KAAK,WAAW;AACrF,gBAAM,YAAY,SAAS;AAAA,YACzB,YAAY,SAAO,aAAa,EAAE,OAAO,QAAQ,SAAS,GAAG,OAAO,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC;AAAA,UACxF,CAAC;AAGD,cAAI,KAAK,OAAO,oBAAoB;AAClC,gBAAI;AACF,oBAAM,QAAQ,KAAK,GAAG,SAAS;AAC/B,oBAAM,cAAc,MAAM,IAAI,+EAA+E;AAC7G,kBAAI,aAAa;AACf,sBAAM,WAAW,MAAM,IAAI,qCAAqC;AAChE,2BAAW,MAAM,UAAU;AACzB,wBAAM;AAAA,oBACJ;AAAA,oBACA,CAAC,GAAG,WAAW,cAAc,CAAG;AAAA,kBAClC;AAAA,gBACF;AAAA,cACF;AAAA,YACF,QAAQ;AAAA,YAAqB;AAAA,UAC/B;AAAA,QACF,QAAQ;AAAA,QAAsC;AAAA,MAChD;AAEA,WAAK,KAAK,WAAW;AACrB,aAAO,WAAW,KAAK,IAAI,IAAI;AAC/B,aAAO;AAAA,IACT,UAAE;AACA,WAAK,KAAK,QAAQ;AAClB,cAAQ;AAAA,IACV;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var filters_exports = {};
20
+ __export(filters_exports, {
21
+ buildWhereClause: () => buildWhereClause
22
+ });
23
+ module.exports = __toCommonJS(filters_exports);
24
+ function validateColumn(column, validColumns) {
25
+ if (!validColumns.has(column)) {
26
+ throw new Error(`Invalid column: "${column}". Available columns: ${[...validColumns].join(", ")}`);
27
+ }
28
+ return `"${column.replace(/"/g, '""')}"`;
29
+ }
30
+ function buildWhereClause(filters, validColumns) {
31
+ if (filters.length === 0) {
32
+ return { where: "", params: [] };
33
+ }
34
+ const conditions = [];
35
+ const params = [];
36
+ for (const filter of filters) {
37
+ const col = validateColumn(filter.column, validColumns);
38
+ switch (filter.op) {
39
+ case "eq":
40
+ conditions.push(`${col} = ?`);
41
+ params.push(filter.value);
42
+ break;
43
+ case "neq":
44
+ conditions.push(`${col} != ?`);
45
+ params.push(filter.value);
46
+ break;
47
+ case "gt":
48
+ conditions.push(`${col} > ?`);
49
+ params.push(filter.value);
50
+ break;
51
+ case "gte":
52
+ conditions.push(`${col} >= ?`);
53
+ params.push(filter.value);
54
+ break;
55
+ case "lt":
56
+ conditions.push(`${col} < ?`);
57
+ params.push(filter.value);
58
+ break;
59
+ case "lte":
60
+ conditions.push(`${col} <= ?`);
61
+ params.push(filter.value);
62
+ break;
63
+ case "contains":
64
+ conditions.push(`${col} LIKE ?`);
65
+ params.push(`%${filter.value}%`);
66
+ break;
67
+ case "in": {
68
+ if (!Array.isArray(filter.value) || filter.value.length === 0) {
69
+ conditions.push("0");
70
+ } else {
71
+ const placeholders = filter.value.map(() => "?").join(",");
72
+ conditions.push(`${col} IN (${placeholders})`);
73
+ params.push(...filter.value);
74
+ }
75
+ break;
76
+ }
77
+ case "is_null":
78
+ if (filter.value === true || filter.value === "true") {
79
+ conditions.push(`${col} IS NULL`);
80
+ } else {
81
+ conditions.push(`${col} IS NOT NULL`);
82
+ }
83
+ break;
84
+ case "between": {
85
+ if (!Array.isArray(filter.value) || filter.value.length !== 2) {
86
+ throw new Error(`"between" filter requires a [min, max] array`);
87
+ }
88
+ conditions.push(`${col} BETWEEN ? AND ?`);
89
+ params.push(filter.value[0], filter.value[1]);
90
+ break;
91
+ }
92
+ default:
93
+ throw new Error(`Unknown filter operator: "${filter.op}"`);
94
+ }
95
+ }
96
+ return {
97
+ where: `WHERE ${conditions.join(" AND ")}`,
98
+ params
99
+ };
100
+ }
101
+ // Annotate the CommonJS export names for ESM import in node:
102
+ 0 && (module.exports = {
103
+ buildWhereClause
104
+ });
105
+ //# sourceMappingURL=filters.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/data/filters.ts"],
4
+ "sourcesContent": ["/**\n * Structured Filter \u2192 SQL WHERE Clause Builder\n *\n * Converts QueryFilter objects into parameterized SQL.\n * Zero injection surface \u2014 column names are validated against schema,\n * values are always parameterized.\n */\n\nimport type { QueryFilter } from './types';\n\ninterface SQLClause {\n where: string;\n params: any[];\n}\n\n/**\n * Validate that a column name exists in the schema.\n * Prevents SQL injection via column names.\n */\nfunction validateColumn(column: string, validColumns: Set<string>): string {\n if (!validColumns.has(column)) {\n throw new Error(`Invalid column: \"${column}\". Available columns: ${[...validColumns].join(', ')}`);\n }\n // Quote column name to handle spaces and reserved words\n return `\"${column.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Build a parameterized WHERE clause from structured filters.\n * All filters are ANDed together.\n *\n * @param filters - Array of QueryFilter objects\n * @param validColumns - Set of valid column names (from schema)\n * @returns SQL WHERE clause and parameter array\n */\nexport function buildWhereClause(filters: QueryFilter[], validColumns: Set<string>): SQLClause {\n if (filters.length === 0) {\n return { where: '', params: [] };\n }\n\n const conditions: string[] = [];\n const params: any[] = [];\n\n for (const filter of filters) {\n const col = validateColumn(filter.column, validColumns);\n\n switch (filter.op) {\n case 'eq':\n conditions.push(`${col} = ?`);\n params.push(filter.value);\n break;\n\n case 'neq':\n conditions.push(`${col} != ?`);\n params.push(filter.value);\n break;\n\n case 'gt':\n conditions.push(`${col} > ?`);\n params.push(filter.value);\n break;\n\n case 'gte':\n conditions.push(`${col} >= ?`);\n params.push(filter.value);\n break;\n\n case 'lt':\n conditions.push(`${col} < ?`);\n params.push(filter.value);\n break;\n\n case 'lte':\n conditions.push(`${col} <= ?`);\n params.push(filter.value);\n break;\n\n case 'contains':\n conditions.push(`${col} LIKE ?`);\n params.push(`%${filter.value}%`);\n break;\n\n case 'in': {\n if (!Array.isArray(filter.value) || filter.value.length === 0) {\n conditions.push('0'); // Always false\n } else {\n const placeholders = filter.value.map(() => '?').join(',');\n conditions.push(`${col} IN (${placeholders})`);\n params.push(...filter.value);\n }\n break;\n }\n\n case 'is_null':\n if (filter.value === true || filter.value === 'true') {\n conditions.push(`${col} IS NULL`);\n } else {\n conditions.push(`${col} IS NOT NULL`);\n }\n break;\n\n case 'between': {\n if (!Array.isArray(filter.value) || filter.value.length !== 2) {\n throw new Error(`\"between\" filter requires a [min, max] array`);\n }\n conditions.push(`${col} BETWEEN ? AND ?`);\n params.push(filter.value[0], filter.value[1]);\n break;\n }\n\n default:\n throw new Error(`Unknown filter operator: \"${(filter as any).op}\"`);\n }\n }\n\n return {\n where: `WHERE ${conditions.join(' AND ')}`,\n params,\n };\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,SAAS,eAAe,QAAgB,cAAmC;AACzE,MAAI,CAAC,aAAa,IAAI,MAAM,GAAG;AAC7B,UAAM,IAAI,MAAM,oBAAoB,MAAM,yBAAyB,CAAC,GAAG,YAAY,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EACnG;AAEA,SAAO,IAAI,OAAO,QAAQ,MAAM,IAAI,CAAC;AACvC;AAUO,SAAS,iBAAiB,SAAwB,cAAsC;AAC7F,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,EAAE,OAAO,IAAI,QAAQ,CAAC,EAAE;AAAA,EACjC;AAEA,QAAM,aAAuB,CAAC;AAC9B,QAAM,SAAgB,CAAC;AAEvB,aAAW,UAAU,SAAS;AAC5B,UAAM,MAAM,eAAe,OAAO,QAAQ,YAAY;AAEtD,YAAQ,OAAO,IAAI;AAAA,MACjB,KAAK;AACH,mBAAW,KAAK,GAAG,GAAG,MAAM;AAC5B,eAAO,KAAK,OAAO,KAAK;AACxB;AAAA,MAEF,KAAK;AACH,mBAAW,KAAK,GAAG,GAAG,OAAO;AAC7B,eAAO,KAAK,OAAO,KAAK;AACxB;AAAA,MAEF,KAAK;AACH,mBAAW,KAAK,GAAG,GAAG,MAAM;AAC5B,eAAO,KAAK,OAAO,KAAK;AACxB;AAAA,MAEF,KAAK;AACH,mBAAW,KAAK,GAAG,GAAG,OAAO;AAC7B,eAAO,KAAK,OAAO,KAAK;AACxB;AAAA,MAEF,KAAK;AACH,mBAAW,KAAK,GAAG,GAAG,MAAM;AAC5B,eAAO,KAAK,OAAO,KAAK;AACxB;AAAA,MAEF,KAAK;AACH,mBAAW,KAAK,GAAG,GAAG,OAAO;AAC7B,eAAO,KAAK,OAAO,KAAK;AACxB;AAAA,MAEF,KAAK;AACH,mBAAW,KAAK,GAAG,GAAG,SAAS;AAC/B,eAAO,KAAK,IAAI,OAAO,KAAK,GAAG;AAC/B;AAAA,MAEF,KAAK,MAAM;AACT,YAAI,CAAC,MAAM,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,WAAW,GAAG;AAC7D,qBAAW,KAAK,GAAG;AAAA,QACrB,OAAO;AACL,gBAAM,eAAe,OAAO,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG;AACzD,qBAAW,KAAK,GAAG,GAAG,QAAQ,YAAY,GAAG;AAC7C,iBAAO,KAAK,GAAG,OAAO,KAAK;AAAA,QAC7B;AACA;AAAA,MACF;AAAA,MAEA,KAAK;AACH,YAAI,OAAO,UAAU,QAAQ,OAAO,UAAU,QAAQ;AACpD,qBAAW,KAAK,GAAG,GAAG,UAAU;AAAA,QAClC,OAAO;AACL,qBAAW,KAAK,GAAG,GAAG,cAAc;AAAA,QACtC;AACA;AAAA,MAEF,KAAK,WAAW;AACd,YAAI,CAAC,MAAM,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,WAAW,GAAG;AAC7D,gBAAM,IAAI,MAAM,8CAA8C;AAAA,QAChE;AACA,mBAAW,KAAK,GAAG,GAAG,kBAAkB;AACxC,eAAO,KAAK,OAAO,MAAM,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC;AAC5C;AAAA,MACF;AAAA,MAEA;AACE,cAAM,IAAI,MAAM,6BAA8B,OAAe,EAAE,GAAG;AAAA,IACtE;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,SAAS,WAAW,KAAK,OAAO,CAAC;AAAA,IACxC;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var indexer_exports = {};
30
+ __export(indexer_exports, {
31
+ DataIndexer: () => DataIndexer
32
+ });
33
+ module.exports = __toCommonJS(indexer_exports);
34
+ var fs = __toESM(require("fs"));
35
+ var path = __toESM(require("path"));
36
+ var crypto = __toESM(require("crypto"));
37
+ var import_picomatch = __toESM(require("picomatch"));
38
+ var import_parsers = require("./parsers/index");
39
+ var import_profiler = require("./profiler");
40
+ function generateDatasetId(filePath) {
41
+ return filePath.replace(/\.[^.]+$/, "").replace(/[/\\]/g, "-").replace(/[^a-zA-Z0-9-_]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
42
+ }
43
+ class DataIndexer {
44
+ constructor(db, config, projectRoot) {
45
+ this.db = db;
46
+ this.config = config;
47
+ this.projectRoot = projectRoot;
48
+ }
49
+ async indexAll(opts) {
50
+ const start = Date.now();
51
+ const result = {
52
+ datasetsIndexed: 0,
53
+ rowsIndexed: 0,
54
+ columnsProfiled: 0,
55
+ errors: [],
56
+ duration: 0
57
+ };
58
+ const files = this.scanDataFiles();
59
+ opts?.onProgress?.(`data: found ${files.length} data files`);
60
+ for (const relPath of files) {
61
+ try {
62
+ const indexed = await this.indexFile(relPath, opts?.force ?? false);
63
+ if (indexed) {
64
+ result.datasetsIndexed++;
65
+ result.rowsIndexed += indexed.rows;
66
+ result.columnsProfiled += indexed.columns;
67
+ }
68
+ } catch (err) {
69
+ result.errors.push(`${relPath}: ${err instanceof Error ? err.message : String(err)}`);
70
+ }
71
+ }
72
+ this.removeDeletedDatasets(files);
73
+ if (this.config.dataLinkCode !== false && result.datasetsIndexed > 0) {
74
+ try {
75
+ const { DataCodeLinker } = await Promise.resolve().then(() => require("./linker.js"));
76
+ const linker = new DataCodeLinker(this.db, this.projectRoot);
77
+ const refsCreated = linker.linkAll();
78
+ opts?.onProgress?.(`data: linked ${refsCreated} code references`);
79
+ } catch {
80
+ }
81
+ }
82
+ result.duration = Date.now() - start;
83
+ return result;
84
+ }
85
+ async indexFile(relPath, force = false) {
86
+ const absPath = path.join(this.projectRoot, relPath);
87
+ if (!fs.existsSync(absPath)) return null;
88
+ const stat = fs.statSync(absPath);
89
+ if (stat.size > this.config.dataMaxFileSize) return null;
90
+ const fileBuffer = fs.readFileSync(absPath);
91
+ const contentHash = crypto.createHash("sha256").update(fileBuffer).digest("hex");
92
+ const datasetId = generateDatasetId(relPath);
93
+ if (!force) {
94
+ const existing = this.db.get("SELECT content_hash FROM data_datasets WHERE id = ?", [datasetId]);
95
+ if (existing?.content_hash === contentHash) return null;
96
+ }
97
+ const parser = (0, import_parsers.getDataParser)(relPath);
98
+ if (!parser) return null;
99
+ const profiler = new import_profiler.ColumnProfiler();
100
+ const allRows = [];
101
+ const maxRows = this.config.dataMaxRows ?? 1e6;
102
+ const { columns, totalRows } = await parser.parse(absPath, {
103
+ maxRows,
104
+ onBatch: (rows, cols) => {
105
+ profiler.addBatch(rows, cols);
106
+ allRows.push(...rows);
107
+ }
108
+ });
109
+ if (columns.length === 0) return null;
110
+ const columnProfiles = profiler.finalize(datasetId);
111
+ this.db.run("BEGIN");
112
+ try {
113
+ const rowTableName = `data_rows_${datasetId.replace(/[^a-zA-Z0-9_]/g, "_")}`;
114
+ this.db.run(`DROP TABLE IF EXISTS "${rowTableName}"`);
115
+ this.db.run("DELETE FROM data_columns WHERE dataset_id = ?", [datasetId]);
116
+ this.db.run("DELETE FROM data_datasets WHERE id = ?", [datasetId]);
117
+ this.db.run(`
118
+ INSERT INTO data_datasets (id, file_path, format, row_count, column_count, file_size, content_hash, summary, indexed_at)
119
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
120
+ `, [datasetId, relPath, parser.name, totalRows, columns.length, stat.size, contentHash, null, Date.now()]);
121
+ for (const col of columnProfiles) {
122
+ this.db.run(`
123
+ INSERT INTO data_columns (id, dataset_id, name, position, inferred_type, nullable, null_count, null_pct, cardinality, min_value, max_value, mean_value, sample_values, summary, updated_at)
124
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
125
+ `, [
126
+ col.id,
127
+ col.datasetId,
128
+ col.name,
129
+ col.position,
130
+ col.inferredType,
131
+ col.nullable ? 1 : 0,
132
+ col.nullCount,
133
+ col.nullPct,
134
+ col.cardinality,
135
+ col.minValue,
136
+ col.maxValue,
137
+ col.meanValue,
138
+ JSON.stringify(col.sampleValues),
139
+ col.summary,
140
+ col.updatedAt
141
+ ]);
142
+ }
143
+ const colDefs = columns.map((c) => `"${c.replace(/"/g, '""')}" TEXT`).join(", ");
144
+ this.db.run(`CREATE TABLE "${rowTableName}" (rowid INTEGER PRIMARY KEY AUTOINCREMENT, ${colDefs})`);
145
+ const colNames = columns.map((c) => `"${c.replace(/"/g, '""')}"`).join(", ");
146
+ const placeholders = columns.map(() => "?").join(", ");
147
+ const insertStmt = `INSERT INTO "${rowTableName}" (${colNames}) VALUES (${placeholders})`;
148
+ for (const row of allRows) {
149
+ const values = columns.map((c) => {
150
+ const v = row[c];
151
+ if (v === null || v === void 0) return null;
152
+ if (typeof v === "object") return JSON.stringify(v);
153
+ return v;
154
+ });
155
+ this.db.run(insertStmt, values);
156
+ }
157
+ const historyColumns = columnProfiles.map((col) => ({
158
+ name: col.name,
159
+ type: col.inferredType,
160
+ cardinality: col.cardinality,
161
+ nullPct: col.nullPct
162
+ }));
163
+ this.db.run(`
164
+ INSERT INTO data_dataset_history (dataset_id, snapshot_at, row_count, column_count, columns_json, content_hash)
165
+ VALUES (?, ?, ?, ?, ?, ?)
166
+ `, [datasetId, Date.now(), totalRows, columns.length, JSON.stringify(historyColumns), contentHash]);
167
+ this.db.run("COMMIT");
168
+ } catch (err) {
169
+ this.db.run("ROLLBACK");
170
+ throw err;
171
+ }
172
+ return { rows: totalRows, columns: columns.length };
173
+ }
174
+ // ── Private ─────────────────────────────────────────────────────────────────
175
+ scanDataFiles() {
176
+ const includePatterns = this.config.dataInclude ?? [];
177
+ const excludePatterns = this.config.dataExclude ?? [];
178
+ const includeMatchers = includePatterns.map((p) => (0, import_picomatch.default)(p));
179
+ const excludeMatchers = excludePatterns.map((p) => (0, import_picomatch.default)(p));
180
+ const results = [];
181
+ const walk = (dir) => {
182
+ let entries;
183
+ try {
184
+ entries = fs.readdirSync(dir, { withFileTypes: true });
185
+ } catch {
186
+ return;
187
+ }
188
+ for (const entry of entries) {
189
+ const full = path.join(dir, entry.name);
190
+ const rel = path.relative(this.projectRoot, full).replace(/\\/g, "/");
191
+ if (entry.isDirectory()) {
192
+ if (excludeMatchers.some((m) => m(rel + "/"))) continue;
193
+ walk(full);
194
+ } else if (entry.isFile()) {
195
+ if (excludeMatchers.some((m) => m(rel))) continue;
196
+ if (includeMatchers.some((m) => m(rel))) {
197
+ if ((0, import_parsers.getDataParser)(rel)) {
198
+ results.push(rel);
199
+ }
200
+ }
201
+ }
202
+ }
203
+ };
204
+ walk(this.projectRoot);
205
+ return results;
206
+ }
207
+ removeDeletedDatasets(currentFiles) {
208
+ const currentSet = new Set(currentFiles.map((f) => generateDatasetId(f)));
209
+ const indexed = this.db.all("SELECT id FROM data_datasets").map((r) => r.id);
210
+ for (const id of indexed) {
211
+ if (!currentSet.has(id)) {
212
+ const rowTableName = `data_rows_${id.replace(/[^a-zA-Z0-9_]/g, "_")}`;
213
+ this.db.run(`DROP TABLE IF EXISTS "${rowTableName}"`);
214
+ this.db.run("DELETE FROM data_columns WHERE dataset_id = ?", [id]);
215
+ this.db.run("DELETE FROM data_code_refs WHERE dataset_id = ?", [id]);
216
+ this.db.run("DELETE FROM data_datasets WHERE id = ?", [id]);
217
+ }
218
+ }
219
+ }
220
+ }
221
+ // Annotate the CommonJS export names for ESM import in node:
222
+ 0 && (module.exports = {
223
+ DataIndexer
224
+ });
225
+ //# sourceMappingURL=indexer.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/data/indexer.ts"],
4
+ "sourcesContent": ["/**\n * Data Indexer\n *\n * Orchestrates: scan data files \u2192 parse \u2192 profile columns \u2192 persist rows to SQLite.\n * Supports incremental re-indexing via content hashes.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as crypto from 'crypto';\nimport picomatch from 'picomatch';\nimport type { KiroGraphConfig } from '../config';\nimport type { DataSet, DataColumn, DataIndexResult, ParsedRow } from './types';\nimport { getDataParser } from './parsers/index';\nimport { ColumnProfiler } from './profiler';\n\n/**\n * Generate a dataset ID from a file path.\n * Slugifies the relative path: tests/fixtures/users.csv \u2192 tests-fixtures-users\n */\nfunction generateDatasetId(filePath: string): string {\n return filePath\n .replace(/\\.[^.]+$/, '') // remove extension\n .replace(/[/\\\\]/g, '-') // replace path separators\n .replace(/[^a-zA-Z0-9-_]/g, '-') // replace special chars\n .replace(/-+/g, '-') // collapse multiple dashes\n .replace(/^-|-$/g, '') // trim leading/trailing dashes\n .toLowerCase();\n}\n\nexport class DataIndexer {\n private readonly db: any;\n private readonly config: KiroGraphConfig;\n private readonly projectRoot: string;\n\n constructor(db: any, config: KiroGraphConfig, projectRoot: string) {\n this.db = db;\n this.config = config;\n this.projectRoot = projectRoot;\n }\n\n async indexAll(opts?: { force?: boolean; onProgress?: (msg: string) => void }): Promise<DataIndexResult> {\n const start = Date.now();\n const result: DataIndexResult = {\n datasetsIndexed: 0, rowsIndexed: 0, columnsProfiled: 0, errors: [], duration: 0,\n };\n\n const files = this.scanDataFiles();\n opts?.onProgress?.(`data: found ${files.length} data files`);\n\n for (const relPath of files) {\n try {\n const indexed = await this.indexFile(relPath, opts?.force ?? false);\n if (indexed) {\n result.datasetsIndexed++;\n result.rowsIndexed += indexed.rows;\n result.columnsProfiled += indexed.columns;\n }\n } catch (err) {\n result.errors.push(`${relPath}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Remove datasets for files that no longer exist\n this.removeDeletedDatasets(files);\n\n // Link data files to code (if enabled)\n if ((this.config as any).dataLinkCode !== false && result.datasetsIndexed > 0) {\n try {\n const { DataCodeLinker } = await Promise.resolve().then(() => require('./linker.js'));\n const linker = new DataCodeLinker(this.db, this.projectRoot);\n const refsCreated = linker.linkAll();\n opts?.onProgress?.(`data: linked ${refsCreated} code references`);\n } catch {\n // Non-critical \u2014 linking failure shouldn't block indexing\n }\n }\n\n result.duration = Date.now() - start;\n return result;\n }\n\n async indexFile(relPath: string, force = false): Promise<{ rows: number; columns: number } | null> {\n const absPath = path.join(this.projectRoot, relPath);\n if (!fs.existsSync(absPath)) return null;\n\n const stat = fs.statSync(absPath);\n if (stat.size > (this.config as any).dataMaxFileSize) return null;\n\n // Check content hash for incremental\n const fileBuffer = fs.readFileSync(absPath);\n const contentHash = crypto.createHash('sha256').update(fileBuffer).digest('hex');\n\n const datasetId = generateDatasetId(relPath);\n\n if (!force) {\n const existing = this.db.get('SELECT content_hash FROM data_datasets WHERE id = ?', [datasetId]);\n if (existing?.content_hash === contentHash) return null; // unchanged\n }\n\n // Get parser\n const parser = getDataParser(relPath);\n if (!parser) return null;\n\n // Parse and profile\n const profiler = new ColumnProfiler();\n const allRows: ParsedRow[] = [];\n const maxRows = (this.config as any).dataMaxRows ?? 1_000_000;\n\n const { columns, totalRows } = await parser.parse(absPath, {\n maxRows,\n onBatch: (rows, cols) => {\n profiler.addBatch(rows, cols);\n allRows.push(...rows);\n },\n });\n\n if (columns.length === 0) return null;\n\n // Finalize profiles\n const columnProfiles = profiler.finalize(datasetId);\n\n // Persist in transaction\n this.db.run('BEGIN');\n try {\n // Delete old dataset data\n const rowTableName = `data_rows_${datasetId.replace(/[^a-zA-Z0-9_]/g, '_')}`;\n this.db.run(`DROP TABLE IF EXISTS \"${rowTableName}\"`);\n this.db.run('DELETE FROM data_columns WHERE dataset_id = ?', [datasetId]);\n this.db.run('DELETE FROM data_datasets WHERE id = ?', [datasetId]);\n\n // Insert dataset\n this.db.run(`\n INSERT INTO data_datasets (id, file_path, format, row_count, column_count, file_size, content_hash, summary, indexed_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `, [datasetId, relPath, parser.name, totalRows, columns.length, stat.size, contentHash, null, Date.now()]);\n\n // Insert column profiles\n for (const col of columnProfiles) {\n this.db.run(`\n INSERT INTO data_columns (id, dataset_id, name, position, inferred_type, nullable, null_count, null_pct, cardinality, min_value, max_value, mean_value, sample_values, summary, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `, [\n col.id, col.datasetId, col.name, col.position, col.inferredType,\n col.nullable ? 1 : 0, col.nullCount, col.nullPct, col.cardinality,\n col.minValue, col.maxValue, col.meanValue,\n JSON.stringify(col.sampleValues), col.summary, col.updatedAt,\n ]);\n }\n\n // Create row table with dynamic schema\n const colDefs = columns.map(c => `\"${c.replace(/\"/g, '\"\"')}\" TEXT`).join(', ');\n this.db.run(`CREATE TABLE \"${rowTableName}\" (rowid INTEGER PRIMARY KEY AUTOINCREMENT, ${colDefs})`);\n\n // Insert rows in batches\n const colNames = columns.map(c => `\"${c.replace(/\"/g, '\"\"')}\"`).join(', ');\n const placeholders = columns.map(() => '?').join(', ');\n const insertStmt = `INSERT INTO \"${rowTableName}\" (${colNames}) VALUES (${placeholders})`;\n\n for (const row of allRows) {\n const values = columns.map(c => {\n const v = row[c];\n if (v === null || v === undefined) return null;\n if (typeof v === 'object') return JSON.stringify(v);\n return v;\n });\n this.db.run(insertStmt, values);\n }\n\n // Save history snapshot for drift detection\n const historyColumns = columnProfiles.map(col => ({\n name: col.name,\n type: col.inferredType,\n cardinality: col.cardinality,\n nullPct: col.nullPct,\n }));\n this.db.run(`\n INSERT INTO data_dataset_history (dataset_id, snapshot_at, row_count, column_count, columns_json, content_hash)\n VALUES (?, ?, ?, ?, ?, ?)\n `, [datasetId, Date.now(), totalRows, columns.length, JSON.stringify(historyColumns), contentHash]);\n\n this.db.run('COMMIT');\n } catch (err) {\n this.db.run('ROLLBACK');\n throw err;\n }\n\n return { rows: totalRows, columns: columns.length };\n }\n\n // \u2500\u2500 Private \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\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 private scanDataFiles(): string[] {\n const includePatterns = (this.config as any).dataInclude ?? [];\n const excludePatterns = (this.config as any).dataExclude ?? [];\n const includeMatchers = includePatterns.map((p: string) => picomatch(p));\n const excludeMatchers = excludePatterns.map((p: string) => picomatch(p));\n const results: string[] = [];\n\n const walk = (dir: string) => {\n let entries: fs.Dirent[];\n try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }\n\n for (const entry of entries) {\n const full = path.join(dir, entry.name);\n const rel = path.relative(this.projectRoot, full).replace(/\\\\/g, '/');\n\n if (entry.isDirectory()) {\n if (excludeMatchers.some((m: any) => m(rel + '/'))) continue;\n walk(full);\n } else if (entry.isFile()) {\n if (excludeMatchers.some((m: any) => m(rel))) continue;\n if (includeMatchers.some((m: any) => m(rel))) {\n // Verify a parser exists for this format\n if (getDataParser(rel)) {\n results.push(rel);\n }\n }\n }\n }\n };\n\n walk(this.projectRoot);\n return results;\n }\n\n private removeDeletedDatasets(currentFiles: string[]): void {\n const currentSet = new Set(currentFiles.map(f => generateDatasetId(f)));\n const indexed = (this.db.all('SELECT id FROM data_datasets') as Array<{ id: string }>).map(r => r.id);\n\n for (const id of indexed) {\n if (!currentSet.has(id)) {\n const rowTableName = `data_rows_${id.replace(/[^a-zA-Z0-9_]/g, '_')}`;\n this.db.run(`DROP TABLE IF EXISTS \"${rowTableName}\"`);\n this.db.run('DELETE FROM data_columns WHERE dataset_id = ?', [id]);\n this.db.run('DELETE FROM data_code_refs WHERE dataset_id = ?', [id]);\n this.db.run('DELETE FROM data_datasets WHERE id = ?', [id]);\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["picomatch"]
7
+ }