@optave/codegraph 3.4.0 → 3.5.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 (453) hide show
  1. package/README.md +23 -22
  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/rules/javascript.d.ts.map +1 -1
  6. package/dist/ast-analysis/rules/javascript.js +1 -0
  7. package/dist/ast-analysis/rules/javascript.js.map +1 -1
  8. package/dist/ast-analysis/shared.d.ts.map +1 -1
  9. package/dist/ast-analysis/shared.js +0 -1
  10. package/dist/ast-analysis/shared.js.map +1 -1
  11. package/dist/ast-analysis/visitors/ast-store-visitor.d.ts.map +1 -1
  12. package/dist/ast-analysis/visitors/ast-store-visitor.js +103 -35
  13. package/dist/ast-analysis/visitors/ast-store-visitor.js.map +1 -1
  14. package/dist/ast-analysis/visitors/cfg-conditionals.d.ts +5 -0
  15. package/dist/ast-analysis/visitors/cfg-conditionals.d.ts.map +1 -0
  16. package/dist/ast-analysis/visitors/cfg-conditionals.js +166 -0
  17. package/dist/ast-analysis/visitors/cfg-conditionals.js.map +1 -0
  18. package/dist/ast-analysis/visitors/cfg-loops.d.ts +7 -0
  19. package/dist/ast-analysis/visitors/cfg-loops.d.ts.map +1 -0
  20. package/dist/ast-analysis/visitors/cfg-loops.js +73 -0
  21. package/dist/ast-analysis/visitors/cfg-loops.js.map +1 -0
  22. package/dist/ast-analysis/visitors/cfg-shared.d.ts +56 -0
  23. package/dist/ast-analysis/visitors/cfg-shared.d.ts.map +1 -0
  24. package/dist/ast-analysis/visitors/cfg-shared.js +107 -0
  25. package/dist/ast-analysis/visitors/cfg-shared.js.map +1 -0
  26. package/dist/ast-analysis/visitors/cfg-try-catch.d.ts +4 -0
  27. package/dist/ast-analysis/visitors/cfg-try-catch.d.ts.map +1 -0
  28. package/dist/ast-analysis/visitors/cfg-try-catch.js +100 -0
  29. package/dist/ast-analysis/visitors/cfg-try-catch.js.map +1 -0
  30. package/dist/ast-analysis/visitors/cfg-visitor.d.ts +2 -2
  31. package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
  32. package/dist/ast-analysis/visitors/cfg-visitor.js +11 -445
  33. package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
  34. package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
  35. package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
  36. package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
  37. package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
  38. package/dist/cli/commands/batch.d.ts.map +1 -1
  39. package/dist/cli/commands/batch.js +4 -3
  40. package/dist/cli/commands/batch.js.map +1 -1
  41. package/dist/cli/commands/branch-compare.js +1 -1
  42. package/dist/cli/commands/branch-compare.js.map +1 -1
  43. package/dist/cli/commands/build.js +1 -1
  44. package/dist/cli/commands/build.js.map +1 -1
  45. package/dist/cli/commands/info.d.ts.map +1 -1
  46. package/dist/cli/commands/info.js +1 -2
  47. package/dist/cli/commands/info.js.map +1 -1
  48. package/dist/cli/commands/path.d.ts.map +1 -1
  49. package/dist/cli/commands/path.js +7 -2
  50. package/dist/cli/commands/path.js.map +1 -1
  51. package/dist/cli/commands/plot.d.ts.map +1 -1
  52. package/dist/cli/commands/plot.js +2 -2
  53. package/dist/cli/commands/plot.js.map +1 -1
  54. package/dist/cli/commands/watch.js +1 -1
  55. package/dist/cli/commands/watch.js.map +1 -1
  56. package/dist/cli/index.js +2 -2
  57. package/dist/cli/index.js.map +1 -1
  58. package/dist/cli/shared/open-graph.d.ts +2 -2
  59. package/dist/cli/shared/open-graph.d.ts.map +1 -1
  60. package/dist/cli/shared/open-graph.js.map +1 -1
  61. package/dist/cli/types.d.ts +1 -1
  62. package/dist/cli/types.d.ts.map +1 -1
  63. package/dist/cli.js +2 -3
  64. package/dist/cli.js.map +1 -1
  65. package/dist/db/better-sqlite3.d.ts +3 -0
  66. package/dist/db/better-sqlite3.d.ts.map +1 -0
  67. package/dist/db/better-sqlite3.js +19 -0
  68. package/dist/db/better-sqlite3.js.map +1 -0
  69. package/dist/db/connection.d.ts +30 -2
  70. package/dist/db/connection.d.ts.map +1 -1
  71. package/dist/db/connection.js +167 -4
  72. package/dist/db/connection.js.map +1 -1
  73. package/dist/db/index.d.ts +2 -2
  74. package/dist/db/index.d.ts.map +1 -1
  75. package/dist/db/index.js +1 -1
  76. package/dist/db/index.js.map +1 -1
  77. package/dist/db/migrations.d.ts.map +1 -1
  78. package/dist/db/migrations.js +9 -0
  79. package/dist/db/migrations.js.map +1 -1
  80. package/dist/db/query-builder.d.ts +5 -5
  81. package/dist/db/query-builder.d.ts.map +1 -1
  82. package/dist/db/query-builder.js +20 -4
  83. package/dist/db/query-builder.js.map +1 -1
  84. package/dist/db/repository/index.d.ts +1 -0
  85. package/dist/db/repository/index.d.ts.map +1 -1
  86. package/dist/db/repository/index.js +1 -0
  87. package/dist/db/repository/index.js.map +1 -1
  88. package/dist/db/repository/native-repository.d.ts +58 -0
  89. package/dist/db/repository/native-repository.d.ts.map +1 -0
  90. package/dist/db/repository/native-repository.js +261 -0
  91. package/dist/db/repository/native-repository.js.map +1 -0
  92. package/dist/db/repository/nodes.d.ts +4 -4
  93. package/dist/db/repository/nodes.d.ts.map +1 -1
  94. package/dist/db/repository/nodes.js +6 -6
  95. package/dist/db/repository/nodes.js.map +1 -1
  96. package/dist/domain/analysis/brief.d.ts.map +1 -1
  97. package/dist/domain/analysis/brief.js +1 -3
  98. package/dist/domain/analysis/brief.js.map +1 -1
  99. package/dist/domain/analysis/context.d.ts.map +1 -1
  100. package/dist/domain/analysis/context.js +2 -4
  101. package/dist/domain/analysis/context.js.map +1 -1
  102. package/dist/domain/analysis/dependencies.d.ts +49 -0
  103. package/dist/domain/analysis/dependencies.d.ts.map +1 -1
  104. package/dist/domain/analysis/dependencies.js +145 -0
  105. package/dist/domain/analysis/dependencies.js.map +1 -1
  106. package/dist/domain/analysis/diff-impact.d.ts +76 -0
  107. package/dist/domain/analysis/diff-impact.d.ts.map +1 -0
  108. package/dist/domain/analysis/diff-impact.js +282 -0
  109. package/dist/domain/analysis/diff-impact.js.map +1 -0
  110. package/dist/domain/analysis/exports.d.ts.map +1 -1
  111. package/dist/domain/analysis/exports.js +0 -1
  112. package/dist/domain/analysis/exports.js.map +1 -1
  113. package/dist/domain/analysis/fn-impact.d.ts +66 -0
  114. package/dist/domain/analysis/fn-impact.d.ts.map +1 -0
  115. package/dist/domain/analysis/fn-impact.js +189 -0
  116. package/dist/domain/analysis/fn-impact.js.map +1 -0
  117. package/dist/domain/analysis/impact.d.ts +8 -148
  118. package/dist/domain/analysis/impact.d.ts.map +1 -1
  119. package/dist/domain/analysis/impact.js +8 -568
  120. package/dist/domain/analysis/impact.js.map +1 -1
  121. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  122. package/dist/domain/analysis/module-map.js +1 -3
  123. package/dist/domain/analysis/module-map.js.map +1 -1
  124. package/dist/domain/graph/builder/context.d.ts +3 -3
  125. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  126. package/dist/domain/graph/builder/context.js +1 -0
  127. package/dist/domain/graph/builder/context.js.map +1 -1
  128. package/dist/domain/graph/builder/helpers.d.ts +4 -5
  129. package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
  130. package/dist/domain/graph/builder/helpers.js +1 -2
  131. package/dist/domain/graph/builder/helpers.js.map +1 -1
  132. package/dist/domain/graph/builder/incremental.d.ts +2 -3
  133. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  134. package/dist/domain/graph/builder/incremental.js.map +1 -1
  135. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  136. package/dist/domain/graph/builder/pipeline.js +34 -6
  137. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  138. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  139. package/dist/domain/graph/builder/stages/build-edges.js +113 -15
  140. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  141. package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -1
  142. package/dist/domain/graph/builder/stages/build-structure.js +186 -62
  143. package/dist/domain/graph/builder/stages/build-structure.js.map +1 -1
  144. package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
  145. package/dist/domain/graph/builder/stages/collect-files.js +71 -7
  146. package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
  147. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  148. package/dist/domain/graph/builder/stages/detect-changes.js +42 -20
  149. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  150. package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
  151. package/dist/domain/graph/builder/stages/finalize.js +111 -64
  152. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  153. package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
  154. package/dist/domain/graph/builder/stages/insert-nodes.js +104 -9
  155. package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
  156. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  157. package/dist/domain/graph/builder/stages/resolve-imports.js +58 -11
  158. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  159. package/dist/domain/graph/cycles.js +2 -2
  160. package/dist/domain/graph/cycles.js.map +1 -1
  161. package/dist/domain/graph/resolve.d.ts.map +1 -1
  162. package/dist/domain/graph/resolve.js +10 -8
  163. package/dist/domain/graph/resolve.js.map +1 -1
  164. package/dist/domain/graph/watcher.d.ts.map +1 -1
  165. package/dist/domain/graph/watcher.js +1 -3
  166. package/dist/domain/graph/watcher.js.map +1 -1
  167. package/dist/domain/parser.d.ts.map +1 -1
  168. package/dist/domain/parser.js +12 -12
  169. package/dist/domain/parser.js.map +1 -1
  170. package/dist/domain/queries.d.ts +3 -2
  171. package/dist/domain/queries.d.ts.map +1 -1
  172. package/dist/domain/queries.js +3 -2
  173. package/dist/domain/queries.js.map +1 -1
  174. package/dist/domain/search/generator.d.ts.map +1 -1
  175. package/dist/domain/search/generator.js.map +1 -1
  176. package/dist/extractors/csharp.js +2 -2
  177. package/dist/extractors/csharp.js.map +1 -1
  178. package/dist/extractors/go.js +2 -2
  179. package/dist/extractors/go.js.map +1 -1
  180. package/dist/extractors/helpers.d.ts +5 -0
  181. package/dist/extractors/helpers.d.ts.map +1 -1
  182. package/dist/extractors/helpers.js +5 -0
  183. package/dist/extractors/helpers.js.map +1 -1
  184. package/dist/extractors/javascript.js +111 -98
  185. package/dist/extractors/javascript.js.map +1 -1
  186. package/dist/extractors/php.js +2 -2
  187. package/dist/extractors/php.js.map +1 -1
  188. package/dist/extractors/python.js +2 -2
  189. package/dist/extractors/python.js.map +1 -1
  190. package/dist/extractors/rust.js +4 -3
  191. package/dist/extractors/rust.js.map +1 -1
  192. package/dist/features/ast.d.ts +14 -1
  193. package/dist/features/ast.d.ts.map +1 -1
  194. package/dist/features/ast.js +38 -1
  195. package/dist/features/ast.js.map +1 -1
  196. package/dist/features/audit.d.ts.map +1 -1
  197. package/dist/features/audit.js +1 -2
  198. package/dist/features/audit.js.map +1 -1
  199. package/dist/features/branch-compare.d.ts.map +1 -1
  200. package/dist/features/branch-compare.js +5 -4
  201. package/dist/features/branch-compare.js.map +1 -1
  202. package/dist/features/cfg.d.ts.map +1 -1
  203. package/dist/features/cfg.js +2 -4
  204. package/dist/features/cfg.js.map +1 -1
  205. package/dist/features/cochange.js +4 -4
  206. package/dist/features/cochange.js.map +1 -1
  207. package/dist/features/communities.js +4 -4
  208. package/dist/features/communities.js.map +1 -1
  209. package/dist/features/complexity-query.d.ts +37 -0
  210. package/dist/features/complexity-query.d.ts.map +1 -0
  211. package/dist/features/complexity-query.js +263 -0
  212. package/dist/features/complexity-query.js.map +1 -0
  213. package/dist/features/complexity.d.ts +2 -30
  214. package/dist/features/complexity.d.ts.map +1 -1
  215. package/dist/features/complexity.js +7 -261
  216. package/dist/features/complexity.js.map +1 -1
  217. package/dist/features/dataflow.d.ts.map +1 -1
  218. package/dist/features/dataflow.js +8 -24
  219. package/dist/features/dataflow.js.map +1 -1
  220. package/dist/features/export.d.ts +7 -8
  221. package/dist/features/export.d.ts.map +1 -1
  222. package/dist/features/export.js.map +1 -1
  223. package/dist/features/flow.d.ts.map +1 -1
  224. package/dist/features/flow.js.map +1 -1
  225. package/dist/features/graph-enrichment.d.ts.map +1 -1
  226. package/dist/features/graph-enrichment.js +1 -3
  227. package/dist/features/graph-enrichment.js.map +1 -1
  228. package/dist/features/manifesto.js +8 -8
  229. package/dist/features/manifesto.js.map +1 -1
  230. package/dist/features/snapshot.js +2 -2
  231. package/dist/features/snapshot.js.map +1 -1
  232. package/dist/features/structure-query.d.ts +76 -0
  233. package/dist/features/structure-query.d.ts.map +1 -0
  234. package/dist/features/structure-query.js +245 -0
  235. package/dist/features/structure-query.js.map +1 -0
  236. package/dist/features/structure.d.ts +12 -67
  237. package/dist/features/structure.d.ts.map +1 -1
  238. package/dist/features/structure.js +188 -244
  239. package/dist/features/structure.js.map +1 -1
  240. package/dist/features/triage.js +2 -2
  241. package/dist/features/triage.js.map +1 -1
  242. package/dist/graph/algorithms/leiden/adapter.d.ts.map +1 -1
  243. package/dist/graph/algorithms/leiden/adapter.js +2 -9
  244. package/dist/graph/algorithms/leiden/adapter.js.map +1 -1
  245. package/dist/graph/classifiers/roles.d.ts +5 -1
  246. package/dist/graph/classifiers/roles.d.ts.map +1 -1
  247. package/dist/graph/classifiers/roles.js +20 -12
  248. package/dist/graph/classifiers/roles.js.map +1 -1
  249. package/dist/index.d.ts +1 -0
  250. package/dist/index.d.ts.map +1 -1
  251. package/dist/index.js.map +1 -1
  252. package/dist/infrastructure/config.d.ts.map +1 -1
  253. package/dist/infrastructure/config.js +12 -11
  254. package/dist/infrastructure/config.js.map +1 -1
  255. package/dist/infrastructure/native.d.ts.map +1 -1
  256. package/dist/infrastructure/native.js +7 -3
  257. package/dist/infrastructure/native.js.map +1 -1
  258. package/dist/infrastructure/registry.d.ts.map +1 -1
  259. package/dist/infrastructure/registry.js +1 -1
  260. package/dist/infrastructure/registry.js.map +1 -1
  261. package/dist/infrastructure/update-check.js +3 -3
  262. package/dist/infrastructure/update-check.js.map +1 -1
  263. package/dist/mcp/server.d.ts.map +1 -1
  264. package/dist/mcp/server.js +4 -17
  265. package/dist/mcp/server.js.map +1 -1
  266. package/dist/mcp/tool-registry.d.ts.map +1 -1
  267. package/dist/mcp/tool-registry.js +9 -4
  268. package/dist/mcp/tool-registry.js.map +1 -1
  269. package/dist/mcp/tools/audit.js +1 -1
  270. package/dist/mcp/tools/audit.js.map +1 -1
  271. package/dist/mcp/tools/cfg.js +1 -1
  272. package/dist/mcp/tools/cfg.js.map +1 -1
  273. package/dist/mcp/tools/check.js +2 -2
  274. package/dist/mcp/tools/check.js.map +1 -1
  275. package/dist/mcp/tools/dataflow.js +2 -2
  276. package/dist/mcp/tools/dataflow.js.map +1 -1
  277. package/dist/mcp/tools/export-graph.js +1 -1
  278. package/dist/mcp/tools/export-graph.js.map +1 -1
  279. package/dist/mcp/tools/index.d.ts.map +1 -1
  280. package/dist/mcp/tools/index.js.map +1 -1
  281. package/dist/mcp/tools/path.d.ts +1 -0
  282. package/dist/mcp/tools/path.d.ts.map +1 -1
  283. package/dist/mcp/tools/path.js +9 -0
  284. package/dist/mcp/tools/path.js.map +1 -1
  285. package/dist/mcp/tools/query.js +1 -1
  286. package/dist/mcp/tools/query.js.map +1 -1
  287. package/dist/mcp/tools/semantic-search.js +1 -1
  288. package/dist/mcp/tools/semantic-search.js.map +1 -1
  289. package/dist/mcp/tools/sequence.js +1 -1
  290. package/dist/mcp/tools/sequence.js.map +1 -1
  291. package/dist/mcp/tools/symbol-children.js +1 -1
  292. package/dist/mcp/tools/symbol-children.js.map +1 -1
  293. package/dist/mcp/tools/triage.js +1 -1
  294. package/dist/mcp/tools/triage.js.map +1 -1
  295. package/dist/presentation/audit.d.ts.map +1 -1
  296. package/dist/presentation/audit.js +0 -1
  297. package/dist/presentation/audit.js.map +1 -1
  298. package/dist/presentation/diff-impact-mermaid.d.ts +11 -0
  299. package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -0
  300. package/dist/presentation/diff-impact-mermaid.js +105 -0
  301. package/dist/presentation/diff-impact-mermaid.js.map +1 -0
  302. package/dist/presentation/flow.d.ts.map +1 -1
  303. package/dist/presentation/flow.js +0 -2
  304. package/dist/presentation/flow.js.map +1 -1
  305. package/dist/presentation/manifesto.d.ts.map +1 -1
  306. package/dist/presentation/manifesto.js +0 -1
  307. package/dist/presentation/manifesto.js.map +1 -1
  308. package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
  309. package/dist/presentation/queries-cli/inspect.js.map +1 -1
  310. package/dist/presentation/queries-cli/path.d.ts.map +1 -1
  311. package/dist/presentation/queries-cli/path.js +45 -1
  312. package/dist/presentation/queries-cli/path.js.map +1 -1
  313. package/dist/presentation/result-formatter.d.ts.map +1 -1
  314. package/dist/presentation/result-formatter.js +1 -3
  315. package/dist/presentation/result-formatter.js.map +1 -1
  316. package/dist/presentation/sequence.d.ts.map +1 -1
  317. package/dist/presentation/sequence.js +0 -1
  318. package/dist/presentation/sequence.js.map +1 -1
  319. package/dist/presentation/structure.d.ts.map +1 -1
  320. package/dist/presentation/structure.js.map +1 -1
  321. package/dist/presentation/triage.d.ts.map +1 -1
  322. package/dist/presentation/triage.js +0 -1
  323. package/dist/presentation/triage.js.map +1 -1
  324. package/dist/shared/constants.d.ts +9 -3
  325. package/dist/shared/constants.d.ts.map +1 -1
  326. package/dist/shared/constants.js +6 -3
  327. package/dist/shared/constants.js.map +1 -1
  328. package/dist/shared/errors.d.ts +2 -0
  329. package/dist/shared/errors.d.ts.map +1 -1
  330. package/dist/shared/errors.js +4 -0
  331. package/dist/shared/errors.js.map +1 -1
  332. package/dist/shared/version.d.ts +2 -0
  333. package/dist/shared/version.d.ts.map +1 -0
  334. package/dist/shared/version.js +5 -0
  335. package/dist/shared/version.js.map +1 -0
  336. package/dist/types.d.ts +230 -2
  337. package/dist/types.d.ts.map +1 -1
  338. package/package.json +62 -11
  339. package/src/ast-analysis/engine.ts +3 -9
  340. package/src/ast-analysis/rules/javascript.ts +1 -0
  341. package/src/ast-analysis/shared.ts +0 -1
  342. package/src/ast-analysis/visitors/ast-store-visitor.ts +102 -33
  343. package/src/ast-analysis/visitors/cfg-conditionals.ts +227 -0
  344. package/src/ast-analysis/visitors/cfg-loops.ts +136 -0
  345. package/src/ast-analysis/visitors/cfg-shared.ts +196 -0
  346. package/src/ast-analysis/visitors/cfg-try-catch.ts +142 -0
  347. package/src/ast-analysis/visitors/cfg-visitor.ts +34 -655
  348. package/src/ast-analysis/visitors/complexity-visitor.ts +0 -1
  349. package/src/ast-analysis/visitors/dataflow-visitor.ts +0 -1
  350. package/src/cli/commands/batch.ts +4 -3
  351. package/src/cli/commands/branch-compare.ts +1 -1
  352. package/src/cli/commands/build.ts +1 -1
  353. package/src/cli/commands/info.ts +1 -2
  354. package/src/cli/commands/path.ts +7 -2
  355. package/src/cli/commands/plot.ts +2 -2
  356. package/src/cli/commands/watch.ts +1 -1
  357. package/src/cli/index.ts +2 -2
  358. package/src/cli/shared/open-graph.ts +2 -2
  359. package/src/cli/types.ts +1 -1
  360. package/src/cli.ts +2 -3
  361. package/src/db/better-sqlite3.ts +20 -0
  362. package/src/db/connection.ts +191 -16
  363. package/src/db/index.ts +5 -1
  364. package/src/db/migrations.ts +9 -0
  365. package/src/db/query-builder.ts +30 -5
  366. package/src/db/repository/index.ts +1 -0
  367. package/src/db/repository/native-repository.ts +361 -0
  368. package/src/db/repository/nodes.ts +7 -3
  369. package/src/domain/analysis/brief.ts +0 -1
  370. package/src/domain/analysis/context.ts +2 -6
  371. package/src/domain/analysis/dependencies.ts +165 -0
  372. package/src/domain/analysis/diff-impact.ts +354 -0
  373. package/src/domain/analysis/exports.ts +0 -2
  374. package/src/domain/analysis/fn-impact.ts +241 -0
  375. package/src/domain/analysis/impact.ts +8 -718
  376. package/src/domain/analysis/module-map.ts +1 -5
  377. package/src/domain/graph/builder/context.ts +4 -2
  378. package/src/domain/graph/builder/helpers.ts +14 -11
  379. package/src/domain/graph/builder/incremental.ts +33 -28
  380. package/src/domain/graph/builder/pipeline.ts +37 -5
  381. package/src/domain/graph/builder/stages/build-edges.ts +131 -20
  382. package/src/domain/graph/builder/stages/build-structure.ts +245 -80
  383. package/src/domain/graph/builder/stages/collect-files.ts +84 -7
  384. package/src/domain/graph/builder/stages/detect-changes.ts +49 -32
  385. package/src/domain/graph/builder/stages/finalize.ts +132 -84
  386. package/src/domain/graph/builder/stages/insert-nodes.ts +141 -18
  387. package/src/domain/graph/builder/stages/resolve-imports.ts +75 -10
  388. package/src/domain/graph/cycles.ts +2 -2
  389. package/src/domain/graph/resolve.ts +14 -8
  390. package/src/domain/graph/watcher.ts +2 -4
  391. package/src/domain/parser.ts +12 -13
  392. package/src/domain/queries.ts +2 -2
  393. package/src/domain/search/generator.ts +3 -4
  394. package/src/extractors/csharp.ts +2 -2
  395. package/src/extractors/go.ts +2 -2
  396. package/src/extractors/helpers.ts +6 -0
  397. package/src/extractors/javascript.ts +112 -97
  398. package/src/extractors/php.ts +2 -2
  399. package/src/extractors/python.ts +2 -2
  400. package/src/extractors/rust.ts +4 -3
  401. package/src/features/ast.ts +66 -1
  402. package/src/features/audit.ts +1 -2
  403. package/src/features/branch-compare.ts +6 -10
  404. package/src/features/cfg.ts +2 -4
  405. package/src/features/cochange.ts +4 -4
  406. package/src/features/communities.ts +4 -4
  407. package/src/features/complexity-query.ts +370 -0
  408. package/src/features/complexity.ts +6 -365
  409. package/src/features/dataflow.ts +48 -70
  410. package/src/features/export.ts +12 -16
  411. package/src/features/flow.ts +0 -1
  412. package/src/features/graph-enrichment.ts +1 -3
  413. package/src/features/manifesto.ts +8 -8
  414. package/src/features/snapshot.ts +3 -3
  415. package/src/features/structure-query.ts +387 -0
  416. package/src/features/structure.ts +231 -376
  417. package/src/features/triage.ts +2 -2
  418. package/src/graph/algorithms/leiden/adapter.ts +2 -9
  419. package/src/graph/classifiers/roles.ts +22 -13
  420. package/src/index.ts +1 -0
  421. package/src/infrastructure/config.ts +12 -13
  422. package/src/infrastructure/native.ts +7 -3
  423. package/src/infrastructure/registry.ts +1 -1
  424. package/src/infrastructure/update-check.ts +3 -3
  425. package/src/mcp/server.ts +4 -20
  426. package/src/mcp/tool-registry.ts +11 -4
  427. package/src/mcp/tools/audit.ts +1 -1
  428. package/src/mcp/tools/cfg.ts +1 -1
  429. package/src/mcp/tools/check.ts +2 -2
  430. package/src/mcp/tools/dataflow.ts +2 -2
  431. package/src/mcp/tools/export-graph.ts +1 -1
  432. package/src/mcp/tools/index.ts +0 -1
  433. package/src/mcp/tools/path.ts +10 -0
  434. package/src/mcp/tools/query.ts +1 -1
  435. package/src/mcp/tools/semantic-search.ts +1 -1
  436. package/src/mcp/tools/sequence.ts +1 -1
  437. package/src/mcp/tools/symbol-children.ts +1 -1
  438. package/src/mcp/tools/triage.ts +1 -1
  439. package/src/presentation/audit.ts +0 -1
  440. package/src/presentation/diff-impact-mermaid.ts +127 -0
  441. package/src/presentation/flow.ts +0 -2
  442. package/src/presentation/manifesto.ts +0 -1
  443. package/src/presentation/queries-cli/inspect.ts +0 -1
  444. package/src/presentation/queries-cli/path.ts +71 -1
  445. package/src/presentation/result-formatter.ts +0 -1
  446. package/src/presentation/sequence.ts +0 -1
  447. package/src/presentation/structure.ts +0 -12
  448. package/src/presentation/triage.ts +0 -1
  449. package/src/shared/constants.ts +33 -19
  450. package/src/shared/errors.ts +5 -0
  451. package/src/shared/version.ts +10 -0
  452. package/src/types.ts +277 -10
  453. package/src/vendor.d.ts +0 -39
@@ -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
  },
@@ -5,6 +5,7 @@ import type { Tree } from 'web-tree-sitter';
5
5
  import { Language, Parser, Query } from 'web-tree-sitter';
6
6
  import { debug, warn } from '../infrastructure/logger.js';
7
7
  import { getNative, getNativePackageVersion, loadNative } from '../infrastructure/native.js';
8
+ import { toErrorMessage } from '../shared/errors.js';
8
9
  import type {
9
10
  EngineMode,
10
11
  ExtractorOutput,
@@ -69,7 +70,6 @@ interface ParseEngineOpts {
69
70
 
70
71
  interface ResolvedEngine {
71
72
  name: 'native' | 'wasm';
72
- // biome-ignore lint/suspicious/noExplicitAny: native addon has no type declarations
73
73
  native: any;
74
74
  }
75
75
 
@@ -85,6 +85,7 @@ const COMMON_QUERY_PATTERNS: string[] = [
85
85
  '(variable_declarator name: (identifier) @varfn_name value: (arrow_function) @varfn_value)',
86
86
  '(variable_declarator name: (identifier) @varfn_name value: (function_expression) @varfn_value)',
87
87
  '(method_definition name: (property_identifier) @meth_name) @meth_node',
88
+ '(method_definition name: (private_property_identifier) @meth_name) @meth_node',
88
89
  '(import_statement source: (string) @imp_source) @imp_node',
89
90
  '(export_statement) @exp_node',
90
91
  '(call_expression function: (identifier) @callfn_name) @callfn_node',
@@ -171,7 +172,6 @@ export function disposeParsers(): void {
171
172
  _queryCache.clear();
172
173
  if (_cachedLanguages) {
173
174
  for (const [id, lang] of _cachedLanguages) {
174
- // biome-ignore lint/suspicious/noExplicitAny: .delete() exists at runtime on WASM Language objects but is missing from typings
175
175
  if (lang && typeof (lang as any).delete === 'function') {
176
176
  try {
177
177
  (lang as any).delete();
@@ -197,7 +197,6 @@ export function getParser(parsers: Map<string, Parser | null>, filePath: string)
197
197
  * don't each need to create parsers and re-parse independently.
198
198
  * Only parses files whose extension is in SUPPORTED_EXTENSIONS.
199
199
  */
200
- // biome-ignore lint/suspicious/noExplicitAny: fileSymbols values have dynamic shape from extractors
201
200
  export async function ensureWasmTrees(
202
201
  fileSymbols: Map<string, any>,
203
202
  rootDir: string,
@@ -274,7 +273,6 @@ function resolveEngine(opts: ParseEngineOpts = {}): ResolvedEngine {
274
273
  * - Backward compat for older native binaries missing js_name annotations
275
274
  * - dataflow argFlows/mutations bindingType -> binding wrapper
276
275
  */
277
- // biome-ignore lint/suspicious/noExplicitAny: native addon result has no type declarations
278
276
  function patchNativeResult(r: any): ExtractorOutput {
279
277
  // lineCount: napi(js_name) emits "lineCount"; older binaries may emit "line_count"
280
278
  r.lineCount = r.lineCount ?? r.line_count ?? null;
@@ -433,7 +431,6 @@ export const SUPPORTED_EXTENSIONS: Set<string> = new Set(_extToLang.keys());
433
431
  * matches inside comments and string literals.
434
432
  * TODO: Remove once all published native binaries include typeMap extraction (>= 3.2.0)
435
433
  */
436
- // biome-ignore lint/suspicious/noExplicitAny: return shape matches native result typeMap
437
434
  async function backfillTypeMap(
438
435
  filePath: string,
439
436
  source?: string,
@@ -442,7 +439,8 @@ async function backfillTypeMap(
442
439
  if (!code) {
443
440
  try {
444
441
  code = fs.readFileSync(filePath, 'utf-8');
445
- } catch {
442
+ } catch (e) {
443
+ debug(`backfillTypeMap: failed to read ${filePath}: ${toErrorMessage(e)}`);
446
444
  return { typeMap: new Map(), backfilled: false };
447
445
  }
448
446
  }
@@ -458,7 +456,9 @@ async function backfillTypeMap(
458
456
  if (extracted?.tree && typeof extracted.tree.delete === 'function') {
459
457
  try {
460
458
  extracted.tree.delete();
461
- } catch {}
459
+ } catch (e) {
460
+ debug(`backfillTypeMap: WASM tree cleanup failed: ${toErrorMessage(e)}`);
461
+ }
462
462
  }
463
463
  }
464
464
  }
@@ -488,7 +488,6 @@ function wasmExtractSymbols(
488
488
  if (!entry) return null;
489
489
  const query = _queryCache.get(entry.id) ?? undefined;
490
490
  // Query (web-tree-sitter) is structurally compatible with TreeSitterQuery at runtime
491
- // biome-ignore lint/suspicious/noExplicitAny: thin WASM wrapper type mismatch
492
491
  const symbols = entry.extractor(tree as any, filePath, query as any);
493
492
  return symbols ? { symbols, tree, langId: entry.id } : null;
494
493
  }
@@ -571,14 +570,16 @@ export async function parseFilesAuto(
571
570
  symbols.typeMap = extracted.symbols.typeMap;
572
571
  symbols._typeMapBackfilled = true;
573
572
  }
574
- } catch {
575
- /* skip — typeMap is a best-effort backfill */
573
+ } catch (e) {
574
+ debug(`batchExtract: typeMap backfill failed: ${toErrorMessage(e)}`);
576
575
  } finally {
577
576
  // Free the WASM tree to prevent memory accumulation across repeated builds
578
577
  if (extracted?.tree && typeof extracted.tree.delete === 'function') {
579
578
  try {
580
579
  extracted.tree.delete();
581
- } catch {}
580
+ } catch (e) {
581
+ debug(`batchExtract: WASM tree cleanup failed: ${toErrorMessage(e)}`);
582
+ }
582
583
  }
583
584
  }
584
585
  }
@@ -638,7 +639,6 @@ export function getActiveEngine(opts: ParseEngineOpts = {}): {
638
639
  * Create a native ParseTreeCache for incremental parsing.
639
640
  * Returns null if the native engine is unavailable (WASM fallback).
640
641
  */
641
- // biome-ignore lint/suspicious/noExplicitAny: native ParseTreeCache has no type declarations
642
642
  export function createParseTreeCache(): any {
643
643
  const native = loadNative();
644
644
  if (!native || !native.ParseTreeCache) return null;
@@ -648,7 +648,6 @@ export function createParseTreeCache(): any {
648
648
  /**
649
649
  * Parse a file incrementally using the cache, or fall back to full parse.
650
650
  */
651
- // biome-ignore lint/suspicious/noExplicitAny: cache is native ParseTreeCache with no type declarations
652
651
  export async function parseFileIncremental(
653
652
  cache: any,
654
653
  filePath: string,
@@ -8,6 +8,7 @@
8
8
 
9
9
  // ── Re-export from dedicated module for backward compat ───────────────────
10
10
  export { isTestFile, TEST_PATTERN } from '../infrastructure/test-filter.js';
11
+ export { diffImpactMermaid } from '../presentation/diff-impact-mermaid.js';
11
12
  export { iterListFunctions, iterRoles, iterWhere } from '../shared/generators.js';
12
13
  // ── Kind/edge constants (canonical source: kinds.js) ─────────────────────
13
14
  export {
@@ -24,11 +25,10 @@ export {
24
25
  export { kindIcon, normalizeSymbol } from '../shared/normalize.js';
25
26
  export { briefData } from './analysis/brief.js';
26
27
  export { contextData, explainData } from './analysis/context.js';
27
- export { fileDepsData, fnDepsData, pathData } from './analysis/dependencies.js';
28
+ export { fileDepsData, filePathData, fnDepsData, pathData } from './analysis/dependencies.js';
28
29
  export { exportsData } from './analysis/exports.js';
29
30
  export {
30
31
  diffImpactData,
31
- diffImpactMermaid,
32
32
  fnImpactData,
33
33
  impactAnalysisData,
34
34
  } from './analysis/impact.js';
@@ -1,10 +1,9 @@
1
1
  import fs from 'node:fs';
2
2
  import path from 'node:path';
3
- import type BetterSqlite3 from 'better-sqlite3';
4
3
  import { closeDb, findDbPath, openDb } from '../../db/index.js';
5
4
  import { warn } from '../../infrastructure/logger.js';
6
5
  import { DbError } from '../../shared/errors.js';
7
- import type { NodeRow } from '../../types.js';
6
+ import type { BetterSqlite3Database, NodeRow } from '../../types.js';
8
7
  import { embed, getModelConfig } from './models.js';
9
8
  import { buildSourceText } from './strategies/source.js';
10
9
  import { buildStructuredText } from './strategies/structured.js';
@@ -17,7 +16,7 @@ export function estimateTokens(text: string): number {
17
16
  return Math.ceil(text.length / 4);
18
17
  }
19
18
 
20
- function initEmbeddingsSchema(db: BetterSqlite3.Database): void {
19
+ function initEmbeddingsSchema(db: BetterSqlite3Database): void {
21
20
  db.exec(`
22
21
  CREATE TABLE IF NOT EXISTS embeddings (
23
22
  node_id INTEGER PRIMARY KEY,
@@ -71,7 +70,7 @@ export async function buildEmbeddings(
71
70
  );
72
71
  }
73
72
 
74
- const db = openDb(dbPath) as BetterSqlite3.Database;
73
+ const db = openDb(dbPath) as BetterSqlite3Database;
75
74
  initEmbeddingsSchema(db);
76
75
 
77
76
  db.exec('DELETE FROM embeddings');
@@ -6,7 +6,7 @@ import type {
6
6
  TreeSitterNode,
7
7
  TreeSitterTree,
8
8
  } from '../types.js';
9
- import { extractModifierVisibility, findChild, nodeEndLine } from './helpers.js';
9
+ import { extractModifierVisibility, findChild, MAX_WALK_DEPTH, nodeEndLine } from './helpers.js';
10
10
 
11
11
  /**
12
12
  * Extract symbols from C# files.
@@ -333,7 +333,7 @@ function extractCSharpTypeMapDepth(
333
333
  ctx: ExtractorOutput,
334
334
  depth: number,
335
335
  ): void {
336
- if (depth >= 200) return;
336
+ if (depth >= MAX_WALK_DEPTH) return;
337
337
 
338
338
  // local_declaration_statement → variable_declaration → type + variable_declarator(s)
339
339
  if (node.type === 'variable_declaration') {
@@ -6,7 +6,7 @@ import type {
6
6
  TreeSitterTree,
7
7
  TypeMapEntry,
8
8
  } from '../types.js';
9
- import { findChild, goVisibility, nodeEndLine } from './helpers.js';
9
+ import { findChild, goVisibility, MAX_WALK_DEPTH, nodeEndLine } from './helpers.js';
10
10
 
11
11
  /**
12
12
  * Extract symbols from Go files.
@@ -233,7 +233,7 @@ function setIfHigher(
233
233
  }
234
234
 
235
235
  function extractGoTypeMapDepth(node: TreeSitterNode, ctx: ExtractorOutput, depth: number): void {
236
- if (depth >= 200) return;
236
+ if (depth >= MAX_WALK_DEPTH) return;
237
237
 
238
238
  // var x MyType = ... or var x, y MyType → var_declaration > var_spec (confidence 0.9)
239
239
  if (node.type === 'var_spec') {
@@ -1,5 +1,11 @@
1
1
  import type { TreeSitterNode } from '../types.js';
2
2
 
3
+ /**
4
+ * Maximum recursion depth for tree-sitter AST walkers.
5
+ * Shared across all language extractors to prevent stack overflow on deeply nested ASTs.
6
+ */
7
+ export const MAX_WALK_DEPTH = 200;
8
+
3
9
  export function nodeEndLine(node: TreeSitterNode): number {
4
10
  return node.endPosition.row + 1;
5
11
  }
@@ -12,7 +12,7 @@ import type {
12
12
  TreeSitterTree,
13
13
  TypeMapEntry,
14
14
  } from '../types.js';
15
- import { findChild, nodeEndLine } from './helpers.js';
15
+ import { findChild, MAX_WALK_DEPTH, nodeEndLine } from './helpers.js';
16
16
 
17
17
  /** Built-in globals that start with uppercase but are not user-defined types. */
18
18
  const BUILTIN_GLOBALS: Set<string> = new Set([
@@ -102,44 +102,42 @@ function extractSymbolsQuery(tree: TreeSitterTree, query: TreeSitterQuery): Extr
102
102
  const c: Record<string, TreeSitterNode> = Object.create(null);
103
103
  for (const cap of match.captures) c[cap.name] = cap.node;
104
104
 
105
- if (c['fn_node']) {
105
+ if (c.fn_node) {
106
106
  // function_declaration
107
- const fnChildren = extractParameters(c['fn_node']);
107
+ const fnChildren = extractParameters(c.fn_node);
108
108
  definitions.push({
109
- name: c['fn_name']!.text,
109
+ name: c.fn_name!.text,
110
110
  kind: 'function',
111
- line: c['fn_node'].startPosition.row + 1,
112
- endLine: nodeEndLine(c['fn_node']),
111
+ line: c.fn_node.startPosition.row + 1,
112
+ endLine: nodeEndLine(c.fn_node),
113
113
  children: fnChildren.length > 0 ? fnChildren : undefined,
114
114
  });
115
- } else if (c['varfn_name']) {
115
+ } else if (c.varfn_name) {
116
116
  // variable_declarator with arrow_function / function_expression
117
- const declNode = c['varfn_name'].parent?.parent;
118
- const line = declNode
119
- ? declNode.startPosition.row + 1
120
- : c['varfn_name'].startPosition.row + 1;
121
- const varFnChildren = extractParameters(c['varfn_value']!);
117
+ const declNode = c.varfn_name.parent?.parent;
118
+ const line = declNode ? declNode.startPosition.row + 1 : c.varfn_name.startPosition.row + 1;
119
+ const varFnChildren = extractParameters(c.varfn_value!);
122
120
  definitions.push({
123
- name: c['varfn_name'].text,
121
+ name: c.varfn_name.text,
124
122
  kind: 'function',
125
123
  line,
126
- endLine: nodeEndLine(c['varfn_value']!),
124
+ endLine: nodeEndLine(c.varfn_value!),
127
125
  children: varFnChildren.length > 0 ? varFnChildren : undefined,
128
126
  });
129
- } else if (c['cls_node']) {
127
+ } else if (c.cls_node) {
130
128
  // class_declaration
131
- const className = c['cls_name']!.text;
132
- const startLine = c['cls_node'].startPosition.row + 1;
133
- const clsChildren = extractClassProperties(c['cls_node']);
129
+ const className = c.cls_name!.text;
130
+ const startLine = c.cls_node.startPosition.row + 1;
131
+ const clsChildren = extractClassProperties(c.cls_node);
134
132
  definitions.push({
135
133
  name: className,
136
134
  kind: 'class',
137
135
  line: startLine,
138
- endLine: nodeEndLine(c['cls_node']),
136
+ endLine: nodeEndLine(c.cls_node),
139
137
  children: clsChildren.length > 0 ? clsChildren : undefined,
140
138
  });
141
139
  const heritage =
142
- c['cls_node'].childForFieldName('heritage') || findChild(c['cls_node'], 'class_heritage');
140
+ c.cls_node.childForFieldName('heritage') || findChild(c.cls_node, 'class_heritage');
143
141
  if (heritage) {
144
142
  const superName = extractSuperclass(heritage);
145
143
  if (superName) classes.push({ name: className, extends: superName, line: startLine });
@@ -148,58 +146,58 @@ function extractSymbolsQuery(tree: TreeSitterTree, query: TreeSitterQuery): Extr
148
146
  classes.push({ name: className, implements: iface, line: startLine });
149
147
  }
150
148
  }
151
- } else if (c['meth_node']) {
149
+ } else if (c.meth_node) {
152
150
  // method_definition
153
- const methName = c['meth_name']!.text;
154
- const parentClass = findParentClass(c['meth_node']);
151
+ const methName = c.meth_name!.text;
152
+ const parentClass = findParentClass(c.meth_node);
155
153
  const fullName = parentClass ? `${parentClass}.${methName}` : methName;
156
- const methChildren = extractParameters(c['meth_node']);
157
- const methVis = extractVisibility(c['meth_node']);
154
+ const methChildren = extractParameters(c.meth_node);
155
+ const methVis = extractVisibility(c.meth_node);
158
156
  definitions.push({
159
157
  name: fullName,
160
158
  kind: 'method',
161
- line: c['meth_node'].startPosition.row + 1,
162
- endLine: nodeEndLine(c['meth_node']),
159
+ line: c.meth_node.startPosition.row + 1,
160
+ endLine: nodeEndLine(c.meth_node),
163
161
  children: methChildren.length > 0 ? methChildren : undefined,
164
162
  visibility: methVis,
165
163
  });
166
- } else if (c['iface_node']) {
164
+ } else if (c.iface_node) {
167
165
  // interface_declaration (TS/TSX only)
168
- const ifaceName = c['iface_name']!.text;
166
+ const ifaceName = c.iface_name!.text;
169
167
  definitions.push({
170
168
  name: ifaceName,
171
169
  kind: 'interface',
172
- line: c['iface_node'].startPosition.row + 1,
173
- endLine: nodeEndLine(c['iface_node']),
170
+ line: c.iface_node.startPosition.row + 1,
171
+ endLine: nodeEndLine(c.iface_node),
174
172
  });
175
173
  const body =
176
- c['iface_node'].childForFieldName('body') ||
177
- findChild(c['iface_node'], 'interface_body') ||
178
- findChild(c['iface_node'], 'object_type');
174
+ c.iface_node.childForFieldName('body') ||
175
+ findChild(c.iface_node, 'interface_body') ||
176
+ findChild(c.iface_node, 'object_type');
179
177
  if (body) extractInterfaceMethods(body, ifaceName, definitions);
180
- } else if (c['type_node']) {
178
+ } else if (c.type_node) {
181
179
  // type_alias_declaration (TS/TSX only)
182
180
  definitions.push({
183
- name: c['type_name']!.text,
181
+ name: c.type_name!.text,
184
182
  kind: 'type',
185
- line: c['type_node'].startPosition.row + 1,
186
- endLine: nodeEndLine(c['type_node']),
183
+ line: c.type_node.startPosition.row + 1,
184
+ endLine: nodeEndLine(c.type_node),
187
185
  });
188
- } else if (c['imp_node']) {
186
+ } else if (c.imp_node) {
189
187
  // import_statement
190
- const isTypeOnly = c['imp_node'].text.startsWith('import type');
191
- const modPath = c['imp_source']!.text.replace(/['"]/g, '');
192
- const names = extractImportNames(c['imp_node']);
188
+ const isTypeOnly = c.imp_node.text.startsWith('import type');
189
+ const modPath = c.imp_source!.text.replace(/['"]/g, '');
190
+ const names = extractImportNames(c.imp_node);
193
191
  imports.push({
194
192
  source: modPath,
195
193
  names,
196
- line: c['imp_node'].startPosition.row + 1,
194
+ line: c.imp_node.startPosition.row + 1,
197
195
  typeOnly: isTypeOnly,
198
196
  });
199
- } else if (c['exp_node']) {
197
+ } else if (c.exp_node) {
200
198
  // export_statement
201
- const exportLine = c['exp_node'].startPosition.row + 1;
202
- const decl = c['exp_node'].childForFieldName('declaration');
199
+ const exportLine = c.exp_node.startPosition.row + 1;
200
+ const decl = c.exp_node.childForFieldName('declaration');
203
201
  if (decl) {
204
202
  const declType = decl.type;
205
203
  const kindMap: Record<string, string> = {
@@ -214,12 +212,11 @@ function extractSymbolsQuery(tree: TreeSitterTree, query: TreeSitterQuery): Extr
214
212
  if (n) exps.push({ name: n.text, kind: kind as Export['kind'], line: exportLine });
215
213
  }
216
214
  }
217
- const source =
218
- c['exp_node'].childForFieldName('source') || findChild(c['exp_node'], 'string');
215
+ const source = c.exp_node.childForFieldName('source') || findChild(c.exp_node, 'string');
219
216
  if (source && !decl) {
220
217
  const modPath = source.text.replace(/['"]/g, '');
221
- const reexportNames = extractImportNames(c['exp_node']);
222
- const nodeText = c['exp_node'].text;
218
+ const reexportNames = extractImportNames(c.exp_node);
219
+ const nodeText = c.exp_node.text;
223
220
  const isWildcard = nodeText.includes('export *') || nodeText.includes('export*');
224
221
  imports.push({
225
222
  source: modPath,
@@ -229,25 +226,25 @@ function extractSymbolsQuery(tree: TreeSitterTree, query: TreeSitterQuery): Extr
229
226
  wildcardReexport: isWildcard && reexportNames.length === 0,
230
227
  });
231
228
  }
232
- } else if (c['callfn_node']) {
229
+ } else if (c.callfn_node) {
233
230
  // call_expression with identifier function
234
231
  calls.push({
235
- name: c['callfn_name']!.text,
236
- line: c['callfn_node'].startPosition.row + 1,
232
+ name: c.callfn_name!.text,
233
+ line: c.callfn_node.startPosition.row + 1,
237
234
  });
238
- } else if (c['callmem_node']) {
235
+ } else if (c.callmem_node) {
239
236
  // call_expression with member_expression function
240
- const callInfo = extractCallInfo(c['callmem_fn']!, c['callmem_node']);
237
+ const callInfo = extractCallInfo(c.callmem_fn!, c.callmem_node);
241
238
  if (callInfo) calls.push(callInfo);
242
- const cbDef = extractCallbackDefinition(c['callmem_node'], c['callmem_fn']);
239
+ const cbDef = extractCallbackDefinition(c.callmem_node, c.callmem_fn);
243
240
  if (cbDef) definitions.push(cbDef);
244
- } else if (c['callsub_node']) {
241
+ } else if (c.callsub_node) {
245
242
  // call_expression with subscript_expression function
246
- const callInfo = extractCallInfo(c['callsub_fn']!, c['callsub_node']);
243
+ const callInfo = extractCallInfo(c.callsub_fn!, c.callsub_node);
247
244
  if (callInfo) calls.push(callInfo);
248
- } else if (c['assign_node']) {
245
+ } else if (c.assign_node) {
249
246
  // CommonJS: module.exports = require(...) / module.exports = { ...require(...) }
250
- handleCommonJSAssignment(c['assign_left']!, c['assign_right']!, c['assign_node'], imports);
247
+ handleCommonJSAssignment(c.assign_left!, c.assign_right!, c.assign_node, imports);
251
248
  }
252
249
  }
253
250
 
@@ -263,51 +260,69 @@ function extractSymbolsQuery(tree: TreeSitterTree, query: TreeSitterQuery): Extr
263
260
  return { definitions, calls, imports, classes, exports: exps, typeMap };
264
261
  }
265
262
 
263
+ /** Node types that define a function scope — constants inside these are skipped. */
264
+ const FUNCTION_SCOPE_TYPES = new Set([
265
+ 'function_declaration',
266
+ 'arrow_function',
267
+ 'function_expression',
268
+ 'method_definition',
269
+ 'generator_function_declaration',
270
+ 'generator_function',
271
+ ]);
272
+
266
273
  /**
267
- * Walk program-level children to extract `const x = <literal>` as constants.
268
- * The query-based fast path has no pattern for lexical_declaration/variable_declaration,
269
- * so constants are missed. This targeted walk fills that gap without a full tree traversal.
274
+ * Recursively walk the AST to extract `const x = <literal>` as constants.
275
+ * Skips nodes inside function scopes so only file-level / block-level constants
276
+ * are captured matching the native engine's behaviour.
270
277
  */
271
- function extractConstantsWalk(rootNode: TreeSitterNode, definitions: Definition[]): void {
272
- for (let i = 0; i < rootNode.childCount; i++) {
273
- const node = rootNode.child(i);
274
- if (!node) continue;
278
+ function extractConstantsWalk(node: TreeSitterNode, definitions: Definition[]): void {
279
+ for (let i = 0; i < node.childCount; i++) {
280
+ const child = node.child(i);
281
+ if (!child) continue;
282
+
283
+ // Don't descend into function scopes
284
+ if (FUNCTION_SCOPE_TYPES.has(child.type)) continue;
275
285
 
276
- let declNode = node;
286
+ let declNode = child;
277
287
  // Handle `export const …` — unwrap the export_statement to its declaration child
278
- if (node.type === 'export_statement') {
279
- const inner = node.childForFieldName('declaration');
280
- if (!inner) continue;
281
- declNode = inner;
288
+ if (child.type === 'export_statement') {
289
+ const inner = child.childForFieldName('declaration');
290
+ if (inner) declNode = inner;
282
291
  }
283
292
 
284
293
  const t = declNode.type;
285
- if (t !== 'lexical_declaration' && t !== 'variable_declaration') continue;
286
- if (!declNode.text.startsWith('const ')) continue;
287
-
288
- for (let j = 0; j < declNode.childCount; j++) {
289
- const declarator = declNode.child(j);
290
- if (!declarator || declarator.type !== 'variable_declarator') continue;
291
- const nameN = declarator.childForFieldName('name');
292
- const valueN = declarator.childForFieldName('value');
293
- if (!nameN || nameN.type !== 'identifier' || !valueN) continue;
294
- // Skip functions — already captured by query patterns
295
- const valType = valueN.type;
296
- if (
297
- valType === 'arrow_function' ||
298
- valType === 'function_expression' ||
299
- valType === 'function'
300
- )
301
- continue;
302
- if (isConstantValue(valueN)) {
303
- definitions.push({
304
- name: nameN.text,
305
- kind: 'constant',
306
- line: declNode.startPosition.row + 1,
307
- endLine: nodeEndLine(declNode),
308
- });
294
+ if (t === 'lexical_declaration' || t === 'variable_declaration') {
295
+ if (declNode.text.startsWith('const ')) {
296
+ for (let j = 0; j < declNode.childCount; j++) {
297
+ const declarator = declNode.child(j);
298
+ if (!declarator || declarator.type !== 'variable_declarator') continue;
299
+ const nameN = declarator.childForFieldName('name');
300
+ const valueN = declarator.childForFieldName('value');
301
+ if (!nameN || nameN.type !== 'identifier' || !valueN) continue;
302
+ // Skip functions already captured by query patterns
303
+ const valType = valueN.type;
304
+ if (
305
+ valType === 'arrow_function' ||
306
+ valType === 'function_expression' ||
307
+ valType === 'function'
308
+ )
309
+ continue;
310
+ if (isConstantValue(valueN)) {
311
+ definitions.push({
312
+ name: nameN.text,
313
+ kind: 'constant',
314
+ line: declNode.startPosition.row + 1,
315
+ endLine: nodeEndLine(declNode),
316
+ });
317
+ }
318
+ }
309
319
  }
310
320
  }
321
+
322
+ // Recurse into non-function, non-export-statement children (blocks, if-statements, etc.)
323
+ if (child.type !== 'export_statement') {
324
+ extractConstantsWalk(child, definitions);
325
+ }
311
326
  }
312
327
  }
313
328
 
@@ -929,7 +944,7 @@ function extractTypeMapWalk(rootNode: TreeSitterNode, typeMap: Map<string, TypeM
929
944
  }
930
945
 
931
946
  function walk(node: TreeSitterNode, depth: number): void {
932
- if (depth >= 200) return;
947
+ if (depth >= MAX_WALK_DEPTH) return;
933
948
  const t = node.type;
934
949
  if (t === 'variable_declarator') {
935
950
  const nameN = node.childForFieldName('name');
@@ -5,7 +5,7 @@ import type {
5
5
  TreeSitterNode,
6
6
  TreeSitterTree,
7
7
  } from '../types.js';
8
- import { extractModifierVisibility, findChild, nodeEndLine } from './helpers.js';
8
+ import { extractModifierVisibility, findChild, MAX_WALK_DEPTH, nodeEndLine } from './helpers.js';
9
9
 
10
10
  function extractPhpParameters(fnNode: TreeSitterNode): SubDeclaration[] {
11
11
  const params: SubDeclaration[] = [];
@@ -340,7 +340,7 @@ function extractPhpTypeMap(node: TreeSitterNode, ctx: ExtractorOutput): void {
340
340
  }
341
341
 
342
342
  function extractPhpTypeMapDepth(node: TreeSitterNode, ctx: ExtractorOutput, depth: number): void {
343
- if (depth >= 200) return;
343
+ if (depth >= MAX_WALK_DEPTH) return;
344
344
 
345
345
  // Function/method parameters with type hints
346
346
  if (