@optave/codegraph 3.4.0 → 3.4.1

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 (410) hide show
  1. package/README.md +7 -7
  2. package/dist/ast-analysis/engine.d.ts.map +1 -1
  3. package/dist/ast-analysis/engine.js +3 -9
  4. package/dist/ast-analysis/engine.js.map +1 -1
  5. package/dist/ast-analysis/shared.d.ts.map +1 -1
  6. package/dist/ast-analysis/shared.js +0 -1
  7. package/dist/ast-analysis/shared.js.map +1 -1
  8. package/dist/ast-analysis/visitors/cfg-conditionals.d.ts +5 -0
  9. package/dist/ast-analysis/visitors/cfg-conditionals.d.ts.map +1 -0
  10. package/dist/ast-analysis/visitors/cfg-conditionals.js +166 -0
  11. package/dist/ast-analysis/visitors/cfg-conditionals.js.map +1 -0
  12. package/dist/ast-analysis/visitors/cfg-loops.d.ts +7 -0
  13. package/dist/ast-analysis/visitors/cfg-loops.d.ts.map +1 -0
  14. package/dist/ast-analysis/visitors/cfg-loops.js +73 -0
  15. package/dist/ast-analysis/visitors/cfg-loops.js.map +1 -0
  16. package/dist/ast-analysis/visitors/cfg-shared.d.ts +56 -0
  17. package/dist/ast-analysis/visitors/cfg-shared.d.ts.map +1 -0
  18. package/dist/ast-analysis/visitors/cfg-shared.js +107 -0
  19. package/dist/ast-analysis/visitors/cfg-shared.js.map +1 -0
  20. package/dist/ast-analysis/visitors/cfg-try-catch.d.ts +4 -0
  21. package/dist/ast-analysis/visitors/cfg-try-catch.d.ts.map +1 -0
  22. package/dist/ast-analysis/visitors/cfg-try-catch.js +100 -0
  23. package/dist/ast-analysis/visitors/cfg-try-catch.js.map +1 -0
  24. package/dist/ast-analysis/visitors/cfg-visitor.d.ts +2 -2
  25. package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
  26. package/dist/ast-analysis/visitors/cfg-visitor.js +11 -445
  27. package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
  28. package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
  29. package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
  30. package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
  31. package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
  32. package/dist/cli/commands/batch.d.ts.map +1 -1
  33. package/dist/cli/commands/batch.js +4 -3
  34. package/dist/cli/commands/batch.js.map +1 -1
  35. package/dist/cli/commands/branch-compare.js +1 -1
  36. package/dist/cli/commands/branch-compare.js.map +1 -1
  37. package/dist/cli/commands/build.js +1 -1
  38. package/dist/cli/commands/build.js.map +1 -1
  39. package/dist/cli/commands/info.d.ts.map +1 -1
  40. package/dist/cli/commands/info.js +1 -2
  41. package/dist/cli/commands/info.js.map +1 -1
  42. package/dist/cli/commands/path.d.ts.map +1 -1
  43. package/dist/cli/commands/path.js +7 -2
  44. package/dist/cli/commands/path.js.map +1 -1
  45. package/dist/cli/commands/plot.d.ts.map +1 -1
  46. package/dist/cli/commands/plot.js +2 -2
  47. package/dist/cli/commands/plot.js.map +1 -1
  48. package/dist/cli/commands/watch.js +1 -1
  49. package/dist/cli/commands/watch.js.map +1 -1
  50. package/dist/cli/index.js +2 -2
  51. package/dist/cli/index.js.map +1 -1
  52. package/dist/cli/shared/open-graph.d.ts +2 -2
  53. package/dist/cli/shared/open-graph.d.ts.map +1 -1
  54. package/dist/cli/shared/open-graph.js.map +1 -1
  55. package/dist/cli/types.d.ts +1 -1
  56. package/dist/cli/types.d.ts.map +1 -1
  57. package/dist/cli.js +2 -3
  58. package/dist/cli.js.map +1 -1
  59. package/dist/db/connection.d.ts +17 -0
  60. package/dist/db/connection.d.ts.map +1 -1
  61. package/dist/db/connection.js +91 -2
  62. package/dist/db/connection.js.map +1 -1
  63. package/dist/db/index.d.ts +1 -1
  64. package/dist/db/index.d.ts.map +1 -1
  65. package/dist/db/index.js +1 -1
  66. package/dist/db/index.js.map +1 -1
  67. package/dist/db/migrations.d.ts.map +1 -1
  68. package/dist/db/migrations.js +7 -0
  69. package/dist/db/migrations.js.map +1 -1
  70. package/dist/domain/analysis/brief.d.ts.map +1 -1
  71. package/dist/domain/analysis/brief.js +1 -3
  72. package/dist/domain/analysis/brief.js.map +1 -1
  73. package/dist/domain/analysis/context.d.ts.map +1 -1
  74. package/dist/domain/analysis/context.js +2 -4
  75. package/dist/domain/analysis/context.js.map +1 -1
  76. package/dist/domain/analysis/dependencies.d.ts +49 -0
  77. package/dist/domain/analysis/dependencies.d.ts.map +1 -1
  78. package/dist/domain/analysis/dependencies.js +145 -0
  79. package/dist/domain/analysis/dependencies.js.map +1 -1
  80. package/dist/domain/analysis/diff-impact.d.ts +76 -0
  81. package/dist/domain/analysis/diff-impact.d.ts.map +1 -0
  82. package/dist/domain/analysis/diff-impact.js +282 -0
  83. package/dist/domain/analysis/diff-impact.js.map +1 -0
  84. package/dist/domain/analysis/exports.d.ts.map +1 -1
  85. package/dist/domain/analysis/exports.js +0 -1
  86. package/dist/domain/analysis/exports.js.map +1 -1
  87. package/dist/domain/analysis/fn-impact.d.ts +66 -0
  88. package/dist/domain/analysis/fn-impact.d.ts.map +1 -0
  89. package/dist/domain/analysis/fn-impact.js +189 -0
  90. package/dist/domain/analysis/fn-impact.js.map +1 -0
  91. package/dist/domain/analysis/impact.d.ts +8 -148
  92. package/dist/domain/analysis/impact.d.ts.map +1 -1
  93. package/dist/domain/analysis/impact.js +8 -568
  94. package/dist/domain/analysis/impact.js.map +1 -1
  95. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  96. package/dist/domain/analysis/module-map.js +1 -3
  97. package/dist/domain/analysis/module-map.js.map +1 -1
  98. package/dist/domain/graph/builder/context.d.ts +2 -3
  99. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  100. package/dist/domain/graph/builder/context.js.map +1 -1
  101. package/dist/domain/graph/builder/helpers.d.ts +4 -5
  102. package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
  103. package/dist/domain/graph/builder/helpers.js +1 -2
  104. package/dist/domain/graph/builder/helpers.js.map +1 -1
  105. package/dist/domain/graph/builder/incremental.d.ts +2 -3
  106. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  107. package/dist/domain/graph/builder/incremental.js.map +1 -1
  108. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  109. package/dist/domain/graph/builder/pipeline.js +6 -0
  110. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  111. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  112. package/dist/domain/graph/builder/stages/build-edges.js +12 -2
  113. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  114. package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -1
  115. package/dist/domain/graph/builder/stages/build-structure.js +155 -59
  116. package/dist/domain/graph/builder/stages/build-structure.js.map +1 -1
  117. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  118. package/dist/domain/graph/builder/stages/detect-changes.js +6 -6
  119. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  120. package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
  121. package/dist/domain/graph/builder/stages/finalize.js +85 -61
  122. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  123. package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
  124. package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
  125. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  126. package/dist/domain/graph/builder/stages/resolve-imports.js +58 -11
  127. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  128. package/dist/domain/graph/cycles.js +2 -2
  129. package/dist/domain/graph/cycles.js.map +1 -1
  130. package/dist/domain/graph/resolve.d.ts.map +1 -1
  131. package/dist/domain/graph/resolve.js +10 -8
  132. package/dist/domain/graph/resolve.js.map +1 -1
  133. package/dist/domain/graph/watcher.d.ts.map +1 -1
  134. package/dist/domain/graph/watcher.js +1 -3
  135. package/dist/domain/graph/watcher.js.map +1 -1
  136. package/dist/domain/parser.d.ts.map +1 -1
  137. package/dist/domain/parser.js +11 -12
  138. package/dist/domain/parser.js.map +1 -1
  139. package/dist/domain/queries.d.ts +3 -2
  140. package/dist/domain/queries.d.ts.map +1 -1
  141. package/dist/domain/queries.js +3 -2
  142. package/dist/domain/queries.js.map +1 -1
  143. package/dist/domain/search/generator.d.ts.map +1 -1
  144. package/dist/domain/search/generator.js.map +1 -1
  145. package/dist/extractors/csharp.js +2 -2
  146. package/dist/extractors/csharp.js.map +1 -1
  147. package/dist/extractors/go.js +2 -2
  148. package/dist/extractors/go.js.map +1 -1
  149. package/dist/extractors/helpers.d.ts +5 -0
  150. package/dist/extractors/helpers.d.ts.map +1 -1
  151. package/dist/extractors/helpers.js +5 -0
  152. package/dist/extractors/helpers.js.map +1 -1
  153. package/dist/extractors/javascript.js +58 -60
  154. package/dist/extractors/javascript.js.map +1 -1
  155. package/dist/extractors/php.js +2 -2
  156. package/dist/extractors/php.js.map +1 -1
  157. package/dist/extractors/python.js +2 -2
  158. package/dist/extractors/python.js.map +1 -1
  159. package/dist/extractors/rust.js +2 -2
  160. package/dist/extractors/rust.js.map +1 -1
  161. package/dist/features/audit.d.ts.map +1 -1
  162. package/dist/features/audit.js +1 -2
  163. package/dist/features/audit.js.map +1 -1
  164. package/dist/features/branch-compare.d.ts.map +1 -1
  165. package/dist/features/branch-compare.js +2 -3
  166. package/dist/features/branch-compare.js.map +1 -1
  167. package/dist/features/cfg.d.ts.map +1 -1
  168. package/dist/features/cfg.js +2 -4
  169. package/dist/features/cfg.js.map +1 -1
  170. package/dist/features/cochange.js +4 -4
  171. package/dist/features/cochange.js.map +1 -1
  172. package/dist/features/communities.js +4 -4
  173. package/dist/features/communities.js.map +1 -1
  174. package/dist/features/complexity-query.d.ts +37 -0
  175. package/dist/features/complexity-query.d.ts.map +1 -0
  176. package/dist/features/complexity-query.js +263 -0
  177. package/dist/features/complexity-query.js.map +1 -0
  178. package/dist/features/complexity.d.ts +2 -30
  179. package/dist/features/complexity.d.ts.map +1 -1
  180. package/dist/features/complexity.js +7 -261
  181. package/dist/features/complexity.js.map +1 -1
  182. package/dist/features/dataflow.d.ts.map +1 -1
  183. package/dist/features/dataflow.js +8 -24
  184. package/dist/features/dataflow.js.map +1 -1
  185. package/dist/features/export.d.ts +7 -8
  186. package/dist/features/export.d.ts.map +1 -1
  187. package/dist/features/export.js.map +1 -1
  188. package/dist/features/flow.d.ts.map +1 -1
  189. package/dist/features/flow.js.map +1 -1
  190. package/dist/features/graph-enrichment.d.ts.map +1 -1
  191. package/dist/features/graph-enrichment.js +1 -3
  192. package/dist/features/graph-enrichment.js.map +1 -1
  193. package/dist/features/manifesto.js +8 -8
  194. package/dist/features/manifesto.js.map +1 -1
  195. package/dist/features/snapshot.d.ts.map +1 -1
  196. package/dist/features/snapshot.js +0 -1
  197. package/dist/features/snapshot.js.map +1 -1
  198. package/dist/features/structure-query.d.ts +76 -0
  199. package/dist/features/structure-query.d.ts.map +1 -0
  200. package/dist/features/structure-query.js +245 -0
  201. package/dist/features/structure-query.js.map +1 -0
  202. package/dist/features/structure.d.ts +12 -67
  203. package/dist/features/structure.d.ts.map +1 -1
  204. package/dist/features/structure.js +188 -244
  205. package/dist/features/structure.js.map +1 -1
  206. package/dist/features/triage.js +2 -2
  207. package/dist/features/triage.js.map +1 -1
  208. package/dist/graph/algorithms/leiden/adapter.d.ts.map +1 -1
  209. package/dist/graph/algorithms/leiden/adapter.js +2 -9
  210. package/dist/graph/algorithms/leiden/adapter.js.map +1 -1
  211. package/dist/graph/classifiers/roles.d.ts +5 -1
  212. package/dist/graph/classifiers/roles.d.ts.map +1 -1
  213. package/dist/graph/classifiers/roles.js +20 -12
  214. package/dist/graph/classifiers/roles.js.map +1 -1
  215. package/dist/index.d.ts +1 -0
  216. package/dist/index.d.ts.map +1 -1
  217. package/dist/index.js.map +1 -1
  218. package/dist/infrastructure/config.d.ts.map +1 -1
  219. package/dist/infrastructure/config.js +12 -11
  220. package/dist/infrastructure/config.js.map +1 -1
  221. package/dist/infrastructure/native.d.ts.map +1 -1
  222. package/dist/infrastructure/native.js +7 -3
  223. package/dist/infrastructure/native.js.map +1 -1
  224. package/dist/infrastructure/registry.d.ts.map +1 -1
  225. package/dist/infrastructure/registry.js +1 -1
  226. package/dist/infrastructure/registry.js.map +1 -1
  227. package/dist/infrastructure/update-check.js +3 -3
  228. package/dist/infrastructure/update-check.js.map +1 -1
  229. package/dist/mcp/server.d.ts.map +1 -1
  230. package/dist/mcp/server.js +2 -8
  231. package/dist/mcp/server.js.map +1 -1
  232. package/dist/mcp/tool-registry.d.ts.map +1 -1
  233. package/dist/mcp/tool-registry.js +9 -4
  234. package/dist/mcp/tool-registry.js.map +1 -1
  235. package/dist/mcp/tools/audit.js +1 -1
  236. package/dist/mcp/tools/audit.js.map +1 -1
  237. package/dist/mcp/tools/cfg.js +1 -1
  238. package/dist/mcp/tools/cfg.js.map +1 -1
  239. package/dist/mcp/tools/check.js +2 -2
  240. package/dist/mcp/tools/check.js.map +1 -1
  241. package/dist/mcp/tools/dataflow.js +2 -2
  242. package/dist/mcp/tools/dataflow.js.map +1 -1
  243. package/dist/mcp/tools/export-graph.js +1 -1
  244. package/dist/mcp/tools/export-graph.js.map +1 -1
  245. package/dist/mcp/tools/index.d.ts.map +1 -1
  246. package/dist/mcp/tools/index.js.map +1 -1
  247. package/dist/mcp/tools/path.d.ts +1 -0
  248. package/dist/mcp/tools/path.d.ts.map +1 -1
  249. package/dist/mcp/tools/path.js +9 -0
  250. package/dist/mcp/tools/path.js.map +1 -1
  251. package/dist/mcp/tools/query.js +1 -1
  252. package/dist/mcp/tools/query.js.map +1 -1
  253. package/dist/mcp/tools/semantic-search.js +1 -1
  254. package/dist/mcp/tools/semantic-search.js.map +1 -1
  255. package/dist/mcp/tools/sequence.js +1 -1
  256. package/dist/mcp/tools/sequence.js.map +1 -1
  257. package/dist/mcp/tools/symbol-children.js +1 -1
  258. package/dist/mcp/tools/symbol-children.js.map +1 -1
  259. package/dist/mcp/tools/triage.js +1 -1
  260. package/dist/mcp/tools/triage.js.map +1 -1
  261. package/dist/presentation/audit.d.ts.map +1 -1
  262. package/dist/presentation/audit.js +0 -1
  263. package/dist/presentation/audit.js.map +1 -1
  264. package/dist/presentation/diff-impact-mermaid.d.ts +11 -0
  265. package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -0
  266. package/dist/presentation/diff-impact-mermaid.js +105 -0
  267. package/dist/presentation/diff-impact-mermaid.js.map +1 -0
  268. package/dist/presentation/flow.d.ts.map +1 -1
  269. package/dist/presentation/flow.js +0 -2
  270. package/dist/presentation/flow.js.map +1 -1
  271. package/dist/presentation/manifesto.d.ts.map +1 -1
  272. package/dist/presentation/manifesto.js +0 -1
  273. package/dist/presentation/manifesto.js.map +1 -1
  274. package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
  275. package/dist/presentation/queries-cli/inspect.js.map +1 -1
  276. package/dist/presentation/queries-cli/path.d.ts.map +1 -1
  277. package/dist/presentation/queries-cli/path.js +45 -1
  278. package/dist/presentation/queries-cli/path.js.map +1 -1
  279. package/dist/presentation/result-formatter.d.ts.map +1 -1
  280. package/dist/presentation/result-formatter.js +1 -3
  281. package/dist/presentation/result-formatter.js.map +1 -1
  282. package/dist/presentation/sequence.d.ts.map +1 -1
  283. package/dist/presentation/sequence.js +0 -1
  284. package/dist/presentation/sequence.js.map +1 -1
  285. package/dist/presentation/structure.d.ts.map +1 -1
  286. package/dist/presentation/structure.js.map +1 -1
  287. package/dist/presentation/triage.d.ts.map +1 -1
  288. package/dist/presentation/triage.js +0 -1
  289. package/dist/presentation/triage.js.map +1 -1
  290. package/dist/shared/constants.d.ts +9 -3
  291. package/dist/shared/constants.d.ts.map +1 -1
  292. package/dist/shared/constants.js +6 -3
  293. package/dist/shared/constants.js.map +1 -1
  294. package/dist/shared/errors.d.ts +2 -0
  295. package/dist/shared/errors.d.ts.map +1 -1
  296. package/dist/shared/errors.js +4 -0
  297. package/dist/shared/errors.js.map +1 -1
  298. package/dist/shared/version.d.ts +2 -0
  299. package/dist/shared/version.d.ts.map +1 -0
  300. package/dist/shared/version.js +5 -0
  301. package/dist/shared/version.js.map +1 -0
  302. package/dist/types.d.ts +2 -2
  303. package/dist/types.d.ts.map +1 -1
  304. package/package.json +8 -7
  305. package/src/ast-analysis/engine.ts +3 -9
  306. package/src/ast-analysis/shared.ts +0 -1
  307. package/src/ast-analysis/visitors/cfg-conditionals.ts +227 -0
  308. package/src/ast-analysis/visitors/cfg-loops.ts +136 -0
  309. package/src/ast-analysis/visitors/cfg-shared.ts +196 -0
  310. package/src/ast-analysis/visitors/cfg-try-catch.ts +142 -0
  311. package/src/ast-analysis/visitors/cfg-visitor.ts +34 -655
  312. package/src/ast-analysis/visitors/complexity-visitor.ts +0 -1
  313. package/src/ast-analysis/visitors/dataflow-visitor.ts +0 -1
  314. package/src/cli/commands/batch.ts +4 -3
  315. package/src/cli/commands/branch-compare.ts +1 -1
  316. package/src/cli/commands/build.ts +1 -1
  317. package/src/cli/commands/info.ts +1 -2
  318. package/src/cli/commands/path.ts +7 -2
  319. package/src/cli/commands/plot.ts +2 -2
  320. package/src/cli/commands/watch.ts +1 -1
  321. package/src/cli/index.ts +2 -2
  322. package/src/cli/shared/open-graph.ts +2 -2
  323. package/src/cli/types.ts +1 -1
  324. package/src/cli.ts +2 -3
  325. package/src/db/connection.ts +97 -13
  326. package/src/db/index.ts +2 -0
  327. package/src/db/migrations.ts +7 -0
  328. package/src/domain/analysis/brief.ts +0 -1
  329. package/src/domain/analysis/context.ts +2 -6
  330. package/src/domain/analysis/dependencies.ts +165 -0
  331. package/src/domain/analysis/diff-impact.ts +354 -0
  332. package/src/domain/analysis/exports.ts +0 -2
  333. package/src/domain/analysis/fn-impact.ts +241 -0
  334. package/src/domain/analysis/impact.ts +8 -718
  335. package/src/domain/analysis/module-map.ts +1 -5
  336. package/src/domain/graph/builder/context.ts +2 -2
  337. package/src/domain/graph/builder/helpers.ts +14 -11
  338. package/src/domain/graph/builder/incremental.ts +33 -28
  339. package/src/domain/graph/builder/pipeline.ts +8 -0
  340. package/src/domain/graph/builder/stages/build-edges.ts +17 -4
  341. package/src/domain/graph/builder/stages/build-structure.ts +205 -76
  342. package/src/domain/graph/builder/stages/detect-changes.ts +11 -12
  343. package/src/domain/graph/builder/stages/finalize.ts +100 -81
  344. package/src/domain/graph/builder/stages/insert-nodes.ts +12 -8
  345. package/src/domain/graph/builder/stages/resolve-imports.ts +75 -10
  346. package/src/domain/graph/cycles.ts +2 -2
  347. package/src/domain/graph/resolve.ts +14 -8
  348. package/src/domain/graph/watcher.ts +2 -4
  349. package/src/domain/parser.ts +11 -13
  350. package/src/domain/queries.ts +2 -2
  351. package/src/domain/search/generator.ts +3 -4
  352. package/src/extractors/csharp.ts +2 -2
  353. package/src/extractors/go.ts +2 -2
  354. package/src/extractors/helpers.ts +6 -0
  355. package/src/extractors/javascript.ts +58 -61
  356. package/src/extractors/php.ts +2 -2
  357. package/src/extractors/python.ts +2 -2
  358. package/src/extractors/rust.ts +2 -2
  359. package/src/features/audit.ts +1 -2
  360. package/src/features/branch-compare.ts +3 -9
  361. package/src/features/cfg.ts +2 -4
  362. package/src/features/cochange.ts +4 -4
  363. package/src/features/communities.ts +4 -4
  364. package/src/features/complexity-query.ts +370 -0
  365. package/src/features/complexity.ts +6 -365
  366. package/src/features/dataflow.ts +48 -70
  367. package/src/features/export.ts +12 -16
  368. package/src/features/flow.ts +0 -1
  369. package/src/features/graph-enrichment.ts +1 -3
  370. package/src/features/manifesto.ts +8 -8
  371. package/src/features/snapshot.ts +1 -2
  372. package/src/features/structure-query.ts +387 -0
  373. package/src/features/structure.ts +231 -376
  374. package/src/features/triage.ts +2 -2
  375. package/src/graph/algorithms/leiden/adapter.ts +2 -9
  376. package/src/graph/classifiers/roles.ts +22 -13
  377. package/src/index.ts +1 -0
  378. package/src/infrastructure/config.ts +12 -13
  379. package/src/infrastructure/native.ts +7 -3
  380. package/src/infrastructure/registry.ts +1 -1
  381. package/src/infrastructure/update-check.ts +3 -3
  382. package/src/mcp/server.ts +2 -10
  383. package/src/mcp/tool-registry.ts +11 -4
  384. package/src/mcp/tools/audit.ts +1 -1
  385. package/src/mcp/tools/cfg.ts +1 -1
  386. package/src/mcp/tools/check.ts +2 -2
  387. package/src/mcp/tools/dataflow.ts +2 -2
  388. package/src/mcp/tools/export-graph.ts +1 -1
  389. package/src/mcp/tools/index.ts +0 -1
  390. package/src/mcp/tools/path.ts +10 -0
  391. package/src/mcp/tools/query.ts +1 -1
  392. package/src/mcp/tools/semantic-search.ts +1 -1
  393. package/src/mcp/tools/sequence.ts +1 -1
  394. package/src/mcp/tools/symbol-children.ts +1 -1
  395. package/src/mcp/tools/triage.ts +1 -1
  396. package/src/presentation/audit.ts +0 -1
  397. package/src/presentation/diff-impact-mermaid.ts +127 -0
  398. package/src/presentation/flow.ts +0 -2
  399. package/src/presentation/manifesto.ts +0 -1
  400. package/src/presentation/queries-cli/inspect.ts +0 -1
  401. package/src/presentation/queries-cli/path.ts +71 -1
  402. package/src/presentation/result-formatter.ts +0 -1
  403. package/src/presentation/sequence.ts +0 -1
  404. package/src/presentation/structure.ts +0 -12
  405. package/src/presentation/triage.ts +0 -1
  406. package/src/shared/constants.ts +33 -19
  407. package/src/shared/errors.ts +5 -0
  408. package/src/shared/version.ts +10 -0
  409. package/src/types.ts +4 -10
  410. package/src/vendor.d.ts +0 -39
@@ -7,11 +7,10 @@
7
7
  */
8
8
  import fs from 'node:fs';
9
9
  import path from 'node:path';
10
- import type BetterSqlite3 from 'better-sqlite3';
11
10
  import { closeDb } from '../../../../db/index.js';
12
11
  import { debug, info } from '../../../../infrastructure/logger.js';
13
12
  import { normalizePath } from '../../../../shared/constants.js';
14
- import type { EngineOpts, ExtractorOutput } from '../../../../types.js';
13
+ import type { BetterSqlite3Database, ExtractorOutput } from '../../../../types.js';
15
14
  import { parseFilesAuto } from '../../../parser.js';
16
15
  import { readJournal, writeJournalHeader } from '../../journal.js';
17
16
  import type { PipelineContext } from '../context.js';
@@ -56,7 +55,7 @@ interface NeedsHashItem {
56
55
  // ── Helpers ────────────────────────────────────────────────────────────
57
56
 
58
57
  function getChangedFiles(
59
- db: BetterSqlite3.Database,
58
+ db: BetterSqlite3Database,
60
59
  allFiles: string[],
61
60
  rootDir: string,
62
61
  ): ChangeResult {
@@ -107,7 +106,7 @@ function detectRemovedFiles(
107
106
  }
108
107
 
109
108
  function tryJournalTier(
110
- db: BetterSqlite3.Database,
109
+ db: BetterSqlite3Database,
111
110
  existing: Map<string, FileHashRow>,
112
111
  rootDir: string,
113
112
  removed: string[],
@@ -227,7 +226,7 @@ function mtimeAndHashTiers(
227
226
  async function runPendingAnalysis(ctx: PipelineContext): Promise<boolean> {
228
227
  const { db, opts, engineOpts, allFiles, rootDir } = ctx;
229
228
  const needsCfg =
230
- (opts as Record<string, unknown>)['cfg'] !== false &&
229
+ (opts as Record<string, unknown>).cfg !== false &&
231
230
  (() => {
232
231
  try {
233
232
  return (
@@ -239,7 +238,7 @@ async function runPendingAnalysis(ctx: PipelineContext): Promise<boolean> {
239
238
  }
240
239
  })();
241
240
  const needsDataflow =
242
- (opts as Record<string, unknown>)['dataflow'] !== false &&
241
+ (opts as Record<string, unknown>).dataflow !== false &&
243
242
  (() => {
244
243
  try {
245
244
  return (
@@ -255,7 +254,7 @@ async function runPendingAnalysis(ctx: PipelineContext): Promise<boolean> {
255
254
  info('No file changes. Running pending analysis pass...');
256
255
  const analysisOpts = {
257
256
  ...engineOpts,
258
- dataflow: needsDataflow && (opts as Record<string, unknown>)['dataflow'] !== false,
257
+ dataflow: needsDataflow && (opts as Record<string, unknown>).dataflow !== false,
259
258
  };
260
259
  const analysisSymbols: Map<string, ExtractorOutput> = await parseFilesAuto(
261
260
  allFiles,
@@ -295,7 +294,7 @@ function healMetadata(ctx: PipelineContext): void {
295
294
  }
296
295
 
297
296
  function findReverseDependencies(
298
- db: BetterSqlite3.Database,
297
+ db: BetterSqlite3Database,
299
298
  changedRelPaths: Set<string>,
300
299
  rootDir: string,
301
300
  ): Set<string> {
@@ -343,7 +342,7 @@ function purgeAndAddReverseDeps(
343
342
  }
344
343
  }
345
344
 
346
- function detectHasEmbeddings(db: BetterSqlite3.Database): boolean {
345
+ function detectHasEmbeddings(db: BetterSqlite3Database): boolean {
347
346
  try {
348
347
  db.prepare('SELECT 1 FROM embeddings LIMIT 1').get();
349
348
  return true;
@@ -359,7 +358,7 @@ function handleScopedBuild(ctx: PipelineContext): void {
359
358
  (item) => item.relPath || normalizePath(path.relative(rootDir, item.file)),
360
359
  );
361
360
  let reverseDeps = new Set<string>();
362
- if (!(opts as Record<string, unknown>)['noReverseDeps']) {
361
+ if (!(opts as Record<string, unknown>).noReverseDeps) {
363
362
  const changedRelPaths = new Set<string>([...changePaths, ...ctx.removed]);
364
363
  reverseDeps = findReverseDependencies(db, changedRelPaths, rootDir);
365
364
  }
@@ -386,7 +385,7 @@ function handleIncrementalBuild(ctx: PipelineContext): void {
386
385
  const { db, rootDir, opts } = ctx;
387
386
  ctx.hasEmbeddings = detectHasEmbeddings(db);
388
387
  let reverseDeps = new Set<string>();
389
- if (!(opts as Record<string, unknown>)['noReverseDeps']) {
388
+ if (!(opts as Record<string, unknown>).noReverseDeps) {
390
389
  const changedRelPaths = new Set<string>();
391
390
  for (const item of ctx.parseChanges) {
392
391
  changedRelPaths.add(item.relPath || normalizePath(path.relative(rootDir, item.file)));
@@ -410,7 +409,7 @@ function handleIncrementalBuild(ctx: PipelineContext): void {
410
409
 
411
410
  export async function detectChanges(ctx: PipelineContext): Promise<void> {
412
411
  const { db, allFiles, rootDir, incremental, forceFullRebuild, opts } = ctx;
413
- if ((opts as Record<string, unknown>)['scope']) {
412
+ if ((opts as Record<string, unknown>).scope) {
414
413
  handleScopedBuild(ctx);
415
414
  return;
416
415
  }
@@ -3,21 +3,15 @@
3
3
  *
4
4
  * WASM cleanup, stats logging, drift detection, build metadata, registry, journal.
5
5
  */
6
- import fs from 'node:fs';
6
+ import { tmpdir } from 'node:os';
7
7
  import path from 'node:path';
8
8
  import { performance } from 'node:perf_hooks';
9
- import { closeDb, getBuildMeta, setBuildMeta } from '../../../../db/index.js';
9
+ import { closeDb, closeDbDeferred, getBuildMeta, setBuildMeta } from '../../../../db/index.js';
10
10
  import { debug, info, warn } from '../../../../infrastructure/logger.js';
11
+ import { CODEGRAPH_VERSION } from '../../../../shared/version.js';
11
12
  import { writeJournalHeader } from '../../journal.js';
12
13
  import type { PipelineContext } from '../context.js';
13
14
 
14
- const __builderDir = path.dirname(new URL(import.meta.url).pathname.replace(/^\/([A-Z]:)/i, '$1'));
15
- const CODEGRAPH_VERSION = (
16
- JSON.parse(
17
- fs.readFileSync(path.join(__builderDir, '..', '..', '..', '..', '..', 'package.json'), 'utf-8'),
18
- ) as { version: string }
19
- ).version;
20
-
21
15
  export async function finalize(ctx: PipelineContext): Promise<void> {
22
16
  const { db, allSymbols, rootDir, isFullBuild, hasEmbeddings, config, opts, schemaVersion } = ctx;
23
17
 
@@ -46,8 +40,9 @@ export async function finalize(ctx: PipelineContext): Promise<void> {
46
40
  info(`Graph built: ${nodeCount} nodes, ${actualEdgeCount} edges`);
47
41
  info(`Stored in ${ctx.dbPath}`);
48
42
 
49
- // Incremental drift detection
50
- if (!isFullBuild) {
43
+ // Incremental drift detection — skip for small incremental changes where
44
+ // count fluctuation is expected (reverse-dep edge churn).
45
+ if (!isFullBuild && allSymbols.size > 3) {
51
46
  const prevNodes = getBuildMeta(db, 'node_count');
52
47
  const prevEdges = getBuildMeta(db, 'edge_count');
53
48
  if (prevNodes && prevEdges) {
@@ -67,95 +62,121 @@ export async function finalize(ctx: PipelineContext): Promise<void> {
67
62
  }
68
63
  }
69
64
 
70
- // Persist build metadata early so downstream checks (e.g. stale-embeddings)
71
- // can read the *current* build's built_at rather than the previous one.
72
- try {
73
- setBuildMeta(db, {
74
- engine: ctx.engineName,
75
- engine_version: ctx.engineVersion || '',
76
- codegraph_version: CODEGRAPH_VERSION,
77
- schema_version: String(schemaVersion),
78
- built_at: buildNow.toISOString(),
79
- node_count: nodeCount,
80
- edge_count: actualEdgeCount,
81
- });
82
- } catch (err) {
83
- warn(`Failed to write build metadata: ${(err as Error).message}`);
65
+ // For small incremental builds, skip persisting build metadata — the
66
+ // engine/version/schema haven't changed (would have triggered a full rebuild),
67
+ // built_at is only used by stale-embeddings check (skipped for incremental),
68
+ // and counts are only used by drift detection (skipped for ≤3 files).
69
+ // This avoids a transaction commit + WAL fsync (~15-30ms).
70
+ if (isFullBuild || allSymbols.size > 5) {
71
+ try {
72
+ setBuildMeta(db, {
73
+ engine: ctx.engineName,
74
+ engine_version: ctx.engineVersion || '',
75
+ codegraph_version: CODEGRAPH_VERSION,
76
+ schema_version: String(schemaVersion),
77
+ built_at: buildNow.toISOString(),
78
+ node_count: nodeCount,
79
+ edge_count: actualEdgeCount,
80
+ });
81
+ } catch (err) {
82
+ warn(`Failed to write build metadata: ${(err as Error).message}`);
83
+ }
84
84
  }
85
85
 
86
- // Orphaned embeddings warning
87
- if (hasEmbeddings) {
86
+ // Skip expensive advisory queries for incremental builds — these are
87
+ // informational warnings that don't affect correctness and cost ~40-60ms.
88
+ if (!isFullBuild) {
89
+ debug(
90
+ 'Finalize: skipping advisory queries (orphaned/stale embeddings, unused exports) for incremental build',
91
+ );
92
+ } else {
93
+ // Orphaned embeddings warning
94
+ if (hasEmbeddings) {
95
+ try {
96
+ const orphaned = (
97
+ db
98
+ .prepare(
99
+ 'SELECT COUNT(*) as c FROM embeddings WHERE node_id NOT IN (SELECT id FROM nodes)',
100
+ )
101
+ .get() as { c: number }
102
+ ).c;
103
+ if (orphaned > 0) {
104
+ warn(
105
+ `${orphaned} embeddings are orphaned (nodes changed). Run "codegraph embed" to refresh.`,
106
+ );
107
+ }
108
+ } catch {
109
+ /* ignore - embeddings table may have been dropped */
110
+ }
111
+ }
112
+
113
+ // Stale embeddings warning (built before current graph rebuild)
114
+ if (hasEmbeddings) {
115
+ try {
116
+ const embedBuiltAt = (
117
+ db.prepare("SELECT value FROM embedding_meta WHERE key = 'built_at'").get() as
118
+ | { value: string }
119
+ | undefined
120
+ )?.value;
121
+ if (embedBuiltAt) {
122
+ const embedTime = new Date(embedBuiltAt).getTime();
123
+ if (!Number.isNaN(embedTime) && embedTime < buildNow.getTime()) {
124
+ warn(
125
+ 'Embeddings were built before the last graph rebuild. Run "codegraph embed" to update.',
126
+ );
127
+ }
128
+ }
129
+ } catch {
130
+ /* ignore - embedding_meta table may not exist */
131
+ }
132
+ }
133
+
134
+ // Unused exports warning
88
135
  try {
89
- const orphaned = (
136
+ const unusedCount = (
90
137
  db
91
138
  .prepare(
92
- 'SELECT COUNT(*) as c FROM embeddings WHERE node_id NOT IN (SELECT id FROM nodes)',
139
+ `SELECT COUNT(*) as c FROM nodes
140
+ WHERE exported = 1 AND kind != 'file'
141
+ AND id NOT IN (
142
+ SELECT DISTINCT e.target_id FROM edges e
143
+ JOIN nodes caller ON e.source_id = caller.id
144
+ JOIN nodes target ON e.target_id = target.id
145
+ WHERE e.kind = 'calls' AND caller.file != target.file
146
+ )`,
93
147
  )
94
148
  .get() as { c: number }
95
149
  ).c;
96
- if (orphaned > 0) {
150
+ if (unusedCount > 0) {
97
151
  warn(
98
- `${orphaned} embeddings are orphaned (nodes changed). Run "codegraph embed" to refresh.`,
152
+ `${unusedCount} exported symbol${unusedCount > 1 ? 's have' : ' has'} zero cross-file consumers. Run "codegraph exports <file> --unused" to inspect.`,
99
153
  );
100
154
  }
101
155
  } catch {
102
- /* ignore - embeddings table may have been dropped */
156
+ /* exported column may not exist on older DBs */
103
157
  }
104
158
  }
105
159
 
106
- // Stale embeddings warning (built before current graph rebuild)
107
- if (hasEmbeddings) {
108
- try {
109
- const embedBuiltAt = (
110
- db.prepare("SELECT value FROM embedding_meta WHERE key = 'built_at'").get() as
111
- | { value: string }
112
- | undefined
113
- )?.value;
114
- if (embedBuiltAt) {
115
- const embedTime = new Date(embedBuiltAt).getTime();
116
- if (!Number.isNaN(embedTime) && embedTime < buildNow.getTime()) {
117
- warn(
118
- 'Embeddings were built before the last graph rebuild. Run "codegraph embed" to update.',
119
- );
120
- }
121
- }
122
- } catch {
123
- /* ignore - embedding_meta table may not exist */
124
- }
125
- }
160
+ ctx.timing.finalizeMs = performance.now() - t0;
126
161
 
127
- // Unused exports warning
128
- try {
129
- const unusedCount = (
130
- db
131
- .prepare(
132
- `SELECT COUNT(*) as c FROM nodes
133
- WHERE exported = 1 AND kind != 'file'
134
- AND id NOT IN (
135
- SELECT DISTINCT e.target_id FROM edges e
136
- JOIN nodes caller ON e.source_id = caller.id
137
- JOIN nodes target ON e.target_id = target.id
138
- WHERE e.kind = 'calls' AND caller.file != target.file
139
- )`,
140
- )
141
- .get() as { c: number }
142
- ).c;
143
- if (unusedCount > 0) {
144
- warn(
145
- `${unusedCount} exported symbol${unusedCount > 1 ? 's have' : ' has'} zero cross-file consumers. Run "codegraph exports <file> --unused" to inspect.`,
146
- );
147
- }
148
- } catch {
149
- /* exported column may not exist on older DBs */
162
+ // For small incremental builds, defer db.close() to the next event loop tick.
163
+ // The WAL checkpoint in db.close() costs ~250ms on Windows NTFS due to fsync.
164
+ // Deferring lets buildGraph() return immediately; the checkpoint runs after.
165
+ // Skip for temp directories (tests) — they rmSync immediately after build.
166
+ const isTempDir = path.resolve(rootDir).startsWith(path.resolve(tmpdir()));
167
+ if (!isFullBuild && allSymbols.size <= 5 && !isTempDir) {
168
+ closeDbDeferred(db);
169
+ } else {
170
+ closeDb(db);
150
171
  }
151
172
 
152
- closeDb(db);
153
-
154
173
  // Write journal header after successful build
155
174
  writeJournalHeader(rootDir, Date.now());
156
175
 
157
- // Auto-registration
158
- if (!opts.skipRegistry) {
176
+ // Skip auto-registration for incremental builds — the repo was already
177
+ // registered during the initial full build. The dynamic import + file I/O
178
+ // costs ~100ms which dominates incremental finalize time.
179
+ if (!opts.skipRegistry && isFullBuild) {
159
180
  const { tmpdir } = await import('node:os');
160
181
  const tmpDir = path.resolve(tmpdir());
161
182
  const resolvedRoot = path.resolve(rootDir);
@@ -172,6 +193,4 @@ export async function finalize(ctx: PipelineContext): Promise<void> {
172
193
  }
173
194
  }
174
195
  }
175
-
176
- ctx.timing.finalizeMs = performance.now() - t0;
177
196
  }
@@ -6,9 +6,13 @@
6
6
  */
7
7
  import path from 'node:path';
8
8
  import { performance } from 'node:perf_hooks';
9
- import type BetterSqlite3 from 'better-sqlite3';
10
9
  import { bulkNodeIdsByFile } from '../../../../db/index.js';
11
- import type { ExtractorOutput, MetadataUpdate } from '../../../../types.js';
10
+ import type {
11
+ BetterSqlite3Database,
12
+ ExtractorOutput,
13
+ MetadataUpdate,
14
+ SqliteStatement,
15
+ } from '../../../../types.js';
12
16
  import type { PipelineContext } from '../context.js';
13
17
  import {
14
18
  batchInsertEdges,
@@ -31,7 +35,7 @@ interface PrecomputedFileData {
31
35
  // ── Phase 1: Insert file nodes, definitions, exports ────────────────────
32
36
 
33
37
  function insertDefinitionsAndExports(
34
- db: BetterSqlite3.Database,
38
+ db: BetterSqlite3Database,
35
39
  allSymbols: Map<string, ExtractorOutput>,
36
40
  ): void {
37
41
  const phase1Rows: unknown[][] = [];
@@ -63,7 +67,7 @@ function insertDefinitionsAndExports(
63
67
  // Mark exported symbols in batches (cache prepared statements by chunk size)
64
68
  if (exportKeys.length > 0) {
65
69
  const EXPORT_CHUNK = 500;
66
- const exportStmtCache = new Map<number, BetterSqlite3.Statement>();
70
+ const exportStmtCache = new Map<number, SqliteStatement>();
67
71
  for (let i = 0; i < exportKeys.length; i += EXPORT_CHUNK) {
68
72
  const end = Math.min(i + EXPORT_CHUNK, exportKeys.length);
69
73
  const chunkSize = end - i;
@@ -89,7 +93,7 @@ function insertDefinitionsAndExports(
89
93
  // ── Phase 2+3: Insert children and containment edges (two nodeIdMap passes) ──
90
94
 
91
95
  function insertChildrenAndEdges(
92
- db: BetterSqlite3.Database,
96
+ db: BetterSqlite3Database,
93
97
  allSymbols: Map<string, ExtractorOutput>,
94
98
  ): void {
95
99
  const childRows: unknown[][] = [];
@@ -164,12 +168,12 @@ function insertChildrenAndEdges(
164
168
  // ── Phase 4: Update file hashes ─────────────────────────────────────────
165
169
 
166
170
  function updateFileHashes(
167
- _db: BetterSqlite3.Database,
171
+ _db: BetterSqlite3Database,
168
172
  allSymbols: Map<string, ExtractorOutput>,
169
173
  precomputedData: Map<string, PrecomputedFileData>,
170
174
  metadataUpdates: MetadataUpdate[],
171
175
  rootDir: string,
172
- upsertHash: BetterSqlite3.Statement | null,
176
+ upsertHash: SqliteStatement | null,
173
177
  ): void {
174
178
  if (!upsertHash) return;
175
179
 
@@ -224,7 +228,7 @@ export async function insertNodes(ctx: PipelineContext): Promise<void> {
224
228
  if (item.relPath) precomputedData.set(item.relPath, item as PrecomputedFileData);
225
229
  }
226
230
 
227
- let upsertHash: BetterSqlite3.Statement | null;
231
+ let upsertHash: SqliteStatement | null;
228
232
  try {
229
233
  upsertHash = db.prepare(
230
234
  'INSERT OR REPLACE INTO file_hashes (file, hash, mtime, size) VALUES (?, ?, ?, ?)',
@@ -41,18 +41,83 @@ export async function resolveImports(ctx: PipelineContext): Promise<void> {
41
41
 
42
42
  ctx.barrelOnlyFiles = new Set<string>();
43
43
  if (!isFullBuild) {
44
- const barrelCandidates = db
45
- .prepare(`SELECT DISTINCT n1.file FROM edges e
44
+ // Collect the set of changed file paths to scope barrel re-parsing.
45
+ const changedRelPaths = new Set<string>(fileSymbols.keys());
46
+
47
+ // For small incremental builds (≤5 files), only re-parse barrel files
48
+ // that are related to the changed files — either re-exporting from them
49
+ // or imported by them. For larger changes, re-parse all barrels.
50
+ let barrelCandidates: Array<{ file: string }>;
51
+ if (changedRelPaths.size <= 5) {
52
+ // All known barrel files (has at least one reexport edge)
53
+ const allBarrelFiles = new Set(
54
+ (
55
+ db
56
+ .prepare(
57
+ `SELECT DISTINCT n1.file FROM edges e
58
+ JOIN nodes n1 ON e.source_id = n1.id
59
+ WHERE e.kind = 'reexports' AND n1.kind = 'file'`,
60
+ )
61
+ .all() as Array<{ file: string }>
62
+ ).map((r) => r.file),
63
+ );
64
+
65
+ const barrels = new Set<string>();
66
+
67
+ // Find barrels imported by changed files using parsed import data
68
+ // (can't query DB edges — they were purged for the changed files).
69
+ for (const relPath of changedRelPaths) {
70
+ const symbols = fileSymbols.get(relPath);
71
+ if (!symbols) continue;
72
+ for (const imp of symbols.imports) {
73
+ const resolved = ctx.batchResolved?.get(`${path.join(rootDir, relPath)}|${imp.source}`);
74
+ const target =
75
+ resolved ??
76
+ resolveImportPath(path.join(rootDir, relPath), imp.source, rootDir, aliases);
77
+ if (allBarrelFiles.has(target)) barrels.add(target);
78
+ }
79
+ }
80
+
81
+ // Also find barrels that re-export from the changed files
82
+ const reexportSourceStmt = db.prepare(
83
+ `SELECT DISTINCT n1.file FROM edges e
46
84
  JOIN nodes n1 ON e.source_id = n1.id
47
- WHERE e.kind = 'reexports' AND n1.kind = 'file'`)
48
- .all() as Array<{ file: string }>;
85
+ JOIN nodes n2 ON e.target_id = n2.id
86
+ WHERE e.kind = 'reexports' AND n1.kind = 'file' AND n2.file = ?`,
87
+ );
88
+ for (const relPath of changedRelPaths) {
89
+ for (const row of reexportSourceStmt.all(relPath) as Array<{ file: string }>) {
90
+ barrels.add(row.file);
91
+ }
92
+ }
93
+ barrelCandidates = [...barrels].map((file) => ({ file }));
94
+ } else {
95
+ barrelCandidates = db
96
+ .prepare(
97
+ `SELECT DISTINCT n1.file FROM edges e
98
+ JOIN nodes n1 ON e.source_id = n1.id
99
+ WHERE e.kind = 'reexports' AND n1.kind = 'file'`,
100
+ )
101
+ .all() as Array<{ file: string }>;
102
+ }
103
+
104
+ // Batch-parse all barrel candidates at once instead of one-by-one
105
+ const barrelPaths: string[] = [];
49
106
  for (const { file: relPath } of barrelCandidates) {
50
- if (fileSymbols.has(relPath)) continue;
51
- const absPath = path.join(rootDir, relPath);
107
+ if (!fileSymbols.has(relPath)) {
108
+ barrelPaths.push(path.join(rootDir, relPath));
109
+ }
110
+ }
111
+
112
+ if (barrelPaths.length > 0) {
113
+ const deleteOutgoingEdges = db.prepare(
114
+ 'DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?)',
115
+ );
116
+
52
117
  try {
53
- const symbols = await parseFilesAuto([absPath], rootDir, engineOpts);
54
- const fileSym = symbols.get(relPath);
55
- if (fileSym) {
118
+ const barrelSymbols = await parseFilesAuto(barrelPaths, rootDir, engineOpts);
119
+ for (const [relPath, fileSym] of barrelSymbols) {
120
+ deleteOutgoingEdges.run(relPath);
56
121
  fileSymbols.set(relPath, fileSym);
57
122
  ctx.barrelOnlyFiles.add(relPath);
58
123
  const reexports = fileSym.imports.filter((imp: Import) => imp.reexport);
@@ -60,7 +125,7 @@ export async function resolveImports(ctx: PipelineContext): Promise<void> {
60
125
  ctx.reexportMap.set(
61
126
  relPath,
62
127
  reexports.map((imp: Import) => ({
63
- source: getResolved(ctx, absPath, imp.source),
128
+ source: getResolved(ctx, path.join(rootDir, relPath), imp.source),
64
129
  names: imp.names,
65
130
  wildcardReexport: imp.wildcardReexport || false,
66
131
  })),
@@ -16,9 +16,9 @@ export function findCycles(
16
16
  const idToLabel = new Map<string, string>();
17
17
  for (const [id, attrs] of graph.nodes()) {
18
18
  if (fileLevel) {
19
- idToLabel.set(id, attrs['file'] as string);
19
+ idToLabel.set(id, attrs.file as string);
20
20
  } else {
21
- idToLabel.set(id, `${attrs['label']}|${attrs['file']}`);
21
+ idToLabel.set(id, `${attrs.label}|${attrs.file}`);
22
22
  }
23
23
  }
24
24
 
@@ -1,13 +1,14 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { debug } from '../../infrastructure/logger.js';
3
4
  import { loadNative } from '../../infrastructure/native.js';
4
5
  import { normalizePath } from '../../shared/constants.js';
6
+ import { toErrorMessage } from '../../shared/errors.js';
5
7
  import type { BareSpecifier, BatchResolvedMap, ImportBatchItem, PathAliases } from '../../types.js';
6
8
 
7
9
  // ── package.json exports resolution ─────────────────────────────────
8
10
 
9
11
  /** Cache: packageDir → parsed exports field (or null) */
10
- // biome-ignore lint/suspicious/noExplicitAny: package.json exports field has no fixed schema
11
12
  const _exportsCache: Map<string, any> = new Map();
12
13
 
13
14
  /**
@@ -55,7 +56,6 @@ function findPackageDir(packageName: string, rootDir: string): string | null {
55
56
  * Read and cache the exports field from a package's package.json.
56
57
  * Returns the exports value or null.
57
58
  */
58
- // biome-ignore lint/suspicious/noExplicitAny: package.json exports field has no fixed schema
59
59
  function getPackageExports(packageDir: string): any {
60
60
  if (_exportsCache.has(packageDir)) return _exportsCache.get(packageDir);
61
61
  try {
@@ -64,7 +64,8 @@ function getPackageExports(packageDir: string): any {
64
64
  const exports = pkg.exports ?? null;
65
65
  _exportsCache.set(packageDir, exports);
66
66
  return exports;
67
- } catch {
67
+ } catch (e) {
68
+ debug(`readPackageExports: failed to read package.json in ${packageDir}: ${toErrorMessage(e)}`);
68
69
  _exportsCache.set(packageDir, null);
69
70
  return null;
70
71
  }
@@ -515,8 +516,10 @@ export function resolveImportPath(
515
516
  // unresolved ".." components (PathBuf::components().collect() doesn't
516
517
  // collapse parent refs). Apply the remap on the JS side as a fallback.
517
518
  return remapJsToTs(normalized, rootDir);
518
- } catch {
519
- // fall through to JS
519
+ } catch (e) {
520
+ debug(
521
+ `resolveImportPath: native resolution failed, falling back to JS: ${toErrorMessage(e)}`,
522
+ );
520
523
  }
521
524
  }
522
525
  return resolveImportPathJS(fromFile, importSource, rootDir, aliases);
@@ -535,8 +538,10 @@ export function computeConfidence(
535
538
  if (native) {
536
539
  try {
537
540
  return native.computeConfidence(callerFile, targetFile, importedFrom || null);
538
- } catch {
539
- // fall through to JS
541
+ } catch (e) {
542
+ debug(
543
+ `computeConfidence: native computation failed, falling back to JS: ${toErrorMessage(e)}`,
544
+ );
540
545
  }
541
546
  }
542
547
  return computeConfidenceJS(callerFile, targetFile, importedFrom);
@@ -575,7 +580,8 @@ export function resolveImportsBatch(
575
580
  map.set(`${r.fromFile}|${r.importSource}`, resolved);
576
581
  }
577
582
  return map;
578
- } catch {
583
+ } catch (e) {
584
+ debug(`batchResolve: native batch resolution failed: ${toErrorMessage(e)}`);
579
585
  return null;
580
586
  }
581
587
  }
@@ -24,9 +24,7 @@ export async function watchProject(rootDir: string, opts: { engine?: string } =
24
24
  throw new DbError('No graph.db found. Run `codegraph build` first.', { file: dbPath });
25
25
  }
26
26
 
27
- const db = openDb(dbPath) as import('better-sqlite3').Database;
28
- // Alias for functions expecting the project's BetterSqlite3Database interface
29
- const typedDb = db as unknown as import('../../types.js').BetterSqlite3Database;
27
+ const db = openDb(dbPath);
30
28
  initSchema(db);
31
29
  const engineOpts: import('../../types.js').EngineOpts = {
32
30
  engine: (opts.engine || 'auto') as import('../../types.js').EngineMode,
@@ -51,7 +49,7 @@ export async function watchProject(rootDir: string, opts: { engine?: string } =
51
49
  ),
52
50
  getNodeId: {
53
51
  get: (name: string, kind: string, file: string, line: number) => {
54
- const id = getNodeIdQuery(typedDb, name, kind, file, line);
52
+ const id = getNodeIdQuery(db, name, kind, file, line);
55
53
  return id != null ? { id } : undefined;
56
54
  },
57
55
  },