@optave/codegraph 3.12.0 → 3.15.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 (524) hide show
  1. package/README.md +83 -46
  2. package/dist/ast-analysis/engine.d.ts.map +1 -1
  3. package/dist/ast-analysis/engine.js +38 -40
  4. package/dist/ast-analysis/engine.js.map +1 -1
  5. package/dist/ast-analysis/rules/b2.d.ts +7 -0
  6. package/dist/ast-analysis/rules/b2.d.ts.map +1 -0
  7. package/dist/ast-analysis/rules/b2.js +240 -0
  8. package/dist/ast-analysis/rules/b2.js.map +1 -0
  9. package/dist/ast-analysis/rules/b3.d.ts +6 -0
  10. package/dist/ast-analysis/rules/b3.d.ts.map +1 -0
  11. package/dist/ast-analysis/rules/b3.js +105 -0
  12. package/dist/ast-analysis/rules/b3.js.map +1 -0
  13. package/dist/ast-analysis/rules/b4.d.ts +9 -0
  14. package/dist/ast-analysis/rules/b4.d.ts.map +1 -0
  15. package/dist/ast-analysis/rules/b4.js +361 -0
  16. package/dist/ast-analysis/rules/b4.js.map +1 -0
  17. package/dist/ast-analysis/rules/b5.d.ts +4 -0
  18. package/dist/ast-analysis/rules/b5.d.ts.map +1 -0
  19. package/dist/ast-analysis/rules/b5.js +52 -0
  20. package/dist/ast-analysis/rules/b5.js.map +1 -0
  21. package/dist/ast-analysis/rules/c.d.ts +4 -0
  22. package/dist/ast-analysis/rules/c.d.ts.map +1 -0
  23. package/dist/ast-analysis/rules/c.js +143 -0
  24. package/dist/ast-analysis/rules/c.js.map +1 -0
  25. package/dist/ast-analysis/rules/index.d.ts.map +1 -1
  26. package/dist/ast-analysis/rules/index.js +34 -0
  27. package/dist/ast-analysis/rules/index.js.map +1 -1
  28. package/dist/ast-analysis/rules/javascript.d.ts.map +1 -1
  29. package/dist/ast-analysis/rules/javascript.js +3 -0
  30. package/dist/ast-analysis/rules/javascript.js.map +1 -1
  31. package/dist/ast-analysis/shared.d.ts.map +1 -1
  32. package/dist/ast-analysis/shared.js +2 -0
  33. package/dist/ast-analysis/shared.js.map +1 -1
  34. package/dist/ast-analysis/visitor-utils.d.ts +1 -0
  35. package/dist/ast-analysis/visitor-utils.d.ts.map +1 -1
  36. package/dist/ast-analysis/visitor-utils.js +5 -0
  37. package/dist/ast-analysis/visitor-utils.js.map +1 -1
  38. package/dist/ast-analysis/visitor.d.ts.map +1 -1
  39. package/dist/ast-analysis/visitor.js +60 -47
  40. package/dist/ast-analysis/visitor.js.map +1 -1
  41. package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
  42. package/dist/ast-analysis/visitors/cfg-visitor.js +126 -76
  43. package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
  44. package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
  45. package/dist/ast-analysis/visitors/complexity-visitor.js +27 -15
  46. package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
  47. package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
  48. package/dist/ast-analysis/visitors/dataflow-visitor.js +54 -21
  49. package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
  50. package/dist/cli/commands/audit.d.ts.map +1 -1
  51. package/dist/cli/commands/audit.js +2 -1
  52. package/dist/cli/commands/audit.js.map +1 -1
  53. package/dist/cli/commands/batch.d.ts.map +1 -1
  54. package/dist/cli/commands/batch.js +1 -0
  55. package/dist/cli/commands/batch.js.map +1 -1
  56. package/dist/cli/commands/build.d.ts.map +1 -1
  57. package/dist/cli/commands/build.js +6 -1
  58. package/dist/cli/commands/build.js.map +1 -1
  59. package/dist/cli/commands/config.d.ts +3 -0
  60. package/dist/cli/commands/config.d.ts.map +1 -0
  61. package/dist/cli/commands/config.js +275 -0
  62. package/dist/cli/commands/config.js.map +1 -0
  63. package/dist/cli/commands/roles.d.ts.map +1 -1
  64. package/dist/cli/commands/roles.js +6 -1
  65. package/dist/cli/commands/roles.js.map +1 -1
  66. package/dist/cli/commands/triage.js +1 -1
  67. package/dist/cli/commands/triage.js.map +1 -1
  68. package/dist/cli/index.d.ts.map +1 -1
  69. package/dist/cli/index.js +10 -0
  70. package/dist/cli/index.js.map +1 -1
  71. package/dist/cli/shared/options.d.ts +2 -1
  72. package/dist/cli/shared/options.d.ts.map +1 -1
  73. package/dist/cli/shared/options.js +11 -1
  74. package/dist/cli/shared/options.js.map +1 -1
  75. package/dist/cli/types.d.ts +2 -0
  76. package/dist/cli/types.d.ts.map +1 -1
  77. package/dist/db/better-sqlite3.d.ts +2 -1
  78. package/dist/db/better-sqlite3.d.ts.map +1 -1
  79. package/dist/db/better-sqlite3.js.map +1 -1
  80. package/dist/db/connection.d.ts +7 -1
  81. package/dist/db/connection.d.ts.map +1 -1
  82. package/dist/db/connection.js +20 -5
  83. package/dist/db/connection.js.map +1 -1
  84. package/dist/db/index.d.ts +1 -1
  85. package/dist/db/index.d.ts.map +1 -1
  86. package/dist/db/index.js +1 -1
  87. package/dist/db/index.js.map +1 -1
  88. package/dist/db/migrations.d.ts.map +1 -1
  89. package/dist/db/migrations.js +69 -1
  90. package/dist/db/migrations.js.map +1 -1
  91. package/dist/db/repository/build-stmts.d.ts.map +1 -1
  92. package/dist/db/repository/build-stmts.js +18 -0
  93. package/dist/db/repository/build-stmts.js.map +1 -1
  94. package/dist/db/repository/dataflow.d.ts +5 -0
  95. package/dist/db/repository/dataflow.d.ts.map +1 -1
  96. package/dist/db/repository/dataflow.js +14 -0
  97. package/dist/db/repository/dataflow.js.map +1 -1
  98. package/dist/db/repository/index.d.ts +1 -1
  99. package/dist/db/repository/index.d.ts.map +1 -1
  100. package/dist/db/repository/index.js +1 -1
  101. package/dist/db/repository/index.js.map +1 -1
  102. package/dist/db/repository/native-repository.d.ts.map +1 -1
  103. package/dist/db/repository/native-repository.js +47 -34
  104. package/dist/db/repository/native-repository.js.map +1 -1
  105. package/dist/domain/analysis/context.d.ts +2 -2
  106. package/dist/domain/analysis/dependencies.d.ts +2 -2
  107. package/dist/domain/analysis/diff-impact.d.ts +2 -2
  108. package/dist/domain/analysis/fn-impact.d.ts +3 -1
  109. package/dist/domain/analysis/fn-impact.d.ts.map +1 -1
  110. package/dist/domain/analysis/fn-impact.js +4 -0
  111. package/dist/domain/analysis/fn-impact.js.map +1 -1
  112. package/dist/domain/analysis/implementations.d.ts +2 -2
  113. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  114. package/dist/domain/analysis/module-map.js +32 -5
  115. package/dist/domain/analysis/module-map.js.map +1 -1
  116. package/dist/domain/analysis/roles.d.ts +7 -1
  117. package/dist/domain/analysis/roles.d.ts.map +1 -1
  118. package/dist/domain/analysis/roles.js +16 -0
  119. package/dist/domain/analysis/roles.js.map +1 -1
  120. package/dist/domain/analysis/symbol-lookup.d.ts +4 -4
  121. package/dist/domain/graph/builder/call-resolver.d.ts +29 -13
  122. package/dist/domain/graph/builder/call-resolver.d.ts.map +1 -1
  123. package/dist/domain/graph/builder/call-resolver.js +125 -205
  124. package/dist/domain/graph/builder/call-resolver.js.map +1 -1
  125. package/dist/domain/graph/builder/cha.d.ts +9 -1
  126. package/dist/domain/graph/builder/cha.d.ts.map +1 -1
  127. package/dist/domain/graph/builder/cha.js +17 -2
  128. package/dist/domain/graph/builder/cha.js.map +1 -1
  129. package/dist/domain/graph/builder/context.d.ts +1 -0
  130. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  131. package/dist/domain/graph/builder/context.js.map +1 -1
  132. package/dist/domain/graph/builder/helpers.d.ts +24 -1
  133. package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
  134. package/dist/domain/graph/builder/helpers.js +174 -65
  135. package/dist/domain/graph/builder/helpers.js.map +1 -1
  136. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  137. package/dist/domain/graph/builder/incremental.js +166 -97
  138. package/dist/domain/graph/builder/incremental.js.map +1 -1
  139. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  140. package/dist/domain/graph/builder/pipeline.js +46 -5
  141. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  142. package/dist/domain/graph/builder/stages/build-edges.d.ts +0 -2
  143. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  144. package/dist/domain/graph/builder/stages/build-edges.js +554 -538
  145. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  146. package/dist/domain/graph/builder/stages/collect-files.d.ts.map +1 -1
  147. package/dist/domain/graph/builder/stages/collect-files.js +10 -7
  148. package/dist/domain/graph/builder/stages/collect-files.js.map +1 -1
  149. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  150. package/dist/domain/graph/builder/stages/detect-changes.js +3 -2
  151. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  152. package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
  153. package/dist/domain/graph/builder/stages/finalize.js +4 -0
  154. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  155. package/dist/domain/graph/builder/stages/native-orchestrator.d.ts.map +1 -1
  156. package/dist/domain/graph/builder/stages/native-orchestrator.js +952 -343
  157. package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -1
  158. package/dist/domain/graph/builder/stages/resolve-imports.js +1 -1
  159. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  160. package/dist/domain/graph/resolver/points-to.d.ts.map +1 -1
  161. package/dist/domain/graph/resolver/points-to.js +105 -57
  162. package/dist/domain/graph/resolver/points-to.js.map +1 -1
  163. package/dist/domain/graph/resolver/strategy.d.ts +61 -0
  164. package/dist/domain/graph/resolver/strategy.d.ts.map +1 -0
  165. package/dist/domain/graph/resolver/strategy.js +222 -0
  166. package/dist/domain/graph/resolver/strategy.js.map +1 -0
  167. package/dist/domain/graph/watcher.d.ts.map +1 -1
  168. package/dist/domain/graph/watcher.js +16 -9
  169. package/dist/domain/graph/watcher.js.map +1 -1
  170. package/dist/domain/parser.d.ts +16 -5
  171. package/dist/domain/parser.d.ts.map +1 -1
  172. package/dist/domain/parser.js +58 -17
  173. package/dist/domain/parser.js.map +1 -1
  174. package/dist/domain/queries.d.ts +1 -1
  175. package/dist/domain/queries.d.ts.map +1 -1
  176. package/dist/domain/queries.js +1 -1
  177. package/dist/domain/queries.js.map +1 -1
  178. package/dist/domain/wasm-worker-entry.js +13 -2
  179. package/dist/domain/wasm-worker-entry.js.map +1 -1
  180. package/dist/domain/wasm-worker-pool.d.ts.map +1 -1
  181. package/dist/domain/wasm-worker-pool.js +26 -5
  182. package/dist/domain/wasm-worker-pool.js.map +1 -1
  183. package/dist/domain/wasm-worker-protocol.d.ts +8 -0
  184. package/dist/domain/wasm-worker-protocol.d.ts.map +1 -1
  185. package/dist/extractors/cpp.d.ts.map +1 -1
  186. package/dist/extractors/cpp.js +42 -1
  187. package/dist/extractors/cpp.js.map +1 -1
  188. package/dist/extractors/cuda.d.ts.map +1 -1
  189. package/dist/extractors/cuda.js +42 -1
  190. package/dist/extractors/cuda.js.map +1 -1
  191. package/dist/extractors/dart.js +48 -3
  192. package/dist/extractors/dart.js.map +1 -1
  193. package/dist/extractors/groovy.js +62 -3
  194. package/dist/extractors/groovy.js.map +1 -1
  195. package/dist/extractors/helpers.d.ts +15 -2
  196. package/dist/extractors/helpers.d.ts.map +1 -1
  197. package/dist/extractors/helpers.js +45 -1
  198. package/dist/extractors/helpers.js.map +1 -1
  199. package/dist/extractors/java.d.ts.map +1 -1
  200. package/dist/extractors/java.js +85 -8
  201. package/dist/extractors/java.js.map +1 -1
  202. package/dist/extractors/javascript.d.ts.map +1 -1
  203. package/dist/extractors/javascript.js +686 -169
  204. package/dist/extractors/javascript.js.map +1 -1
  205. package/dist/extractors/kotlin.js +58 -3
  206. package/dist/extractors/kotlin.js.map +1 -1
  207. package/dist/extractors/objc.js +25 -2
  208. package/dist/extractors/objc.js.map +1 -1
  209. package/dist/extractors/scala.js +62 -2
  210. package/dist/extractors/scala.js.map +1 -1
  211. package/dist/extractors/swift.js +52 -3
  212. package/dist/extractors/swift.js.map +1 -1
  213. package/dist/features/audit.js +26 -23
  214. package/dist/features/audit.js.map +1 -1
  215. package/dist/features/boundaries.d.ts.map +1 -1
  216. package/dist/features/boundaries.js +12 -9
  217. package/dist/features/boundaries.js.map +1 -1
  218. package/dist/features/cfg.d.ts.map +1 -1
  219. package/dist/features/cfg.js +25 -18
  220. package/dist/features/cfg.js.map +1 -1
  221. package/dist/features/check.d.ts.map +1 -1
  222. package/dist/features/check.js +18 -5
  223. package/dist/features/check.js.map +1 -1
  224. package/dist/features/communities.d.ts +4 -2
  225. package/dist/features/communities.d.ts.map +1 -1
  226. package/dist/features/communities.js +6 -4
  227. package/dist/features/communities.js.map +1 -1
  228. package/dist/features/dataflow.d.ts +60 -0
  229. package/dist/features/dataflow.d.ts.map +1 -1
  230. package/dist/features/dataflow.js +530 -6
  231. package/dist/features/dataflow.js.map +1 -1
  232. package/dist/features/manifesto.d.ts.map +1 -1
  233. package/dist/features/manifesto.js +59 -72
  234. package/dist/features/manifesto.js.map +1 -1
  235. package/dist/features/sequence.d.ts.map +1 -1
  236. package/dist/features/sequence.js +27 -22
  237. package/dist/features/sequence.js.map +1 -1
  238. package/dist/features/snapshot.d.ts.map +1 -1
  239. package/dist/features/snapshot.js +36 -28
  240. package/dist/features/snapshot.js.map +1 -1
  241. package/dist/features/structure-query.d.ts +1 -1
  242. package/dist/features/structure-query.d.ts.map +1 -1
  243. package/dist/features/structure-query.js +6 -6
  244. package/dist/features/structure-query.js.map +1 -1
  245. package/dist/features/structure.d.ts.map +1 -1
  246. package/dist/features/structure.js +150 -62
  247. package/dist/features/structure.js.map +1 -1
  248. package/dist/features/triage.d.ts.map +1 -1
  249. package/dist/features/triage.js +18 -11
  250. package/dist/features/triage.js.map +1 -1
  251. package/dist/graph/algorithms/bfs.d.ts +1 -1
  252. package/dist/graph/algorithms/bfs.d.ts.map +1 -1
  253. package/dist/graph/algorithms/bfs.js +14 -13
  254. package/dist/graph/algorithms/bfs.js.map +1 -1
  255. package/dist/graph/algorithms/tarjan.d.ts.map +1 -1
  256. package/dist/graph/algorithms/tarjan.js +5 -0
  257. package/dist/graph/algorithms/tarjan.js.map +1 -1
  258. package/dist/graph/builders/dependency.js +28 -22
  259. package/dist/graph/builders/dependency.js.map +1 -1
  260. package/dist/graph/classifiers/roles.d.ts +10 -1
  261. package/dist/graph/classifiers/roles.d.ts.map +1 -1
  262. package/dist/graph/classifiers/roles.js +60 -6
  263. package/dist/graph/classifiers/roles.js.map +1 -1
  264. package/dist/index.d.ts +1 -1
  265. package/dist/index.d.ts.map +1 -1
  266. package/dist/index.js +1 -1
  267. package/dist/index.js.map +1 -1
  268. package/dist/infrastructure/config.d.ts +87 -4
  269. package/dist/infrastructure/config.d.ts.map +1 -1
  270. package/dist/infrastructure/config.js +424 -22
  271. package/dist/infrastructure/config.js.map +1 -1
  272. package/dist/infrastructure/registry.d.ts +27 -7
  273. package/dist/infrastructure/registry.d.ts.map +1 -1
  274. package/dist/infrastructure/registry.js +79 -5
  275. package/dist/infrastructure/registry.js.map +1 -1
  276. package/dist/infrastructure/update-check.d.ts.map +1 -1
  277. package/dist/infrastructure/update-check.js +49 -31
  278. package/dist/infrastructure/update-check.js.map +1 -1
  279. package/dist/mcp/server.d.ts +2 -10
  280. package/dist/mcp/server.d.ts.map +1 -1
  281. package/dist/mcp/server.js.map +1 -1
  282. package/dist/mcp/tools/ast-query.d.ts +1 -1
  283. package/dist/mcp/tools/ast-query.d.ts.map +1 -1
  284. package/dist/mcp/tools/audit.d.ts +1 -1
  285. package/dist/mcp/tools/audit.d.ts.map +1 -1
  286. package/dist/mcp/tools/batch-query.d.ts +1 -1
  287. package/dist/mcp/tools/batch-query.d.ts.map +1 -1
  288. package/dist/mcp/tools/branch-compare.d.ts +1 -1
  289. package/dist/mcp/tools/branch-compare.d.ts.map +1 -1
  290. package/dist/mcp/tools/brief.d.ts +1 -1
  291. package/dist/mcp/tools/brief.d.ts.map +1 -1
  292. package/dist/mcp/tools/cfg.d.ts +1 -1
  293. package/dist/mcp/tools/cfg.d.ts.map +1 -1
  294. package/dist/mcp/tools/check.d.ts +1 -1
  295. package/dist/mcp/tools/check.d.ts.map +1 -1
  296. package/dist/mcp/tools/co-changes.d.ts +1 -1
  297. package/dist/mcp/tools/co-changes.d.ts.map +1 -1
  298. package/dist/mcp/tools/code-owners.d.ts +1 -1
  299. package/dist/mcp/tools/code-owners.d.ts.map +1 -1
  300. package/dist/mcp/tools/communities.d.ts +1 -1
  301. package/dist/mcp/tools/communities.d.ts.map +1 -1
  302. package/dist/mcp/tools/complexity.d.ts +1 -1
  303. package/dist/mcp/tools/complexity.d.ts.map +1 -1
  304. package/dist/mcp/tools/context.d.ts +1 -1
  305. package/dist/mcp/tools/context.d.ts.map +1 -1
  306. package/dist/mcp/tools/dataflow.d.ts +1 -1
  307. package/dist/mcp/tools/dataflow.d.ts.map +1 -1
  308. package/dist/mcp/tools/diff-impact.d.ts +1 -1
  309. package/dist/mcp/tools/diff-impact.d.ts.map +1 -1
  310. package/dist/mcp/tools/execution-flow.d.ts +1 -1
  311. package/dist/mcp/tools/execution-flow.d.ts.map +1 -1
  312. package/dist/mcp/tools/export-graph.d.ts +1 -1
  313. package/dist/mcp/tools/export-graph.d.ts.map +1 -1
  314. package/dist/mcp/tools/file-deps.d.ts +1 -1
  315. package/dist/mcp/tools/file-deps.d.ts.map +1 -1
  316. package/dist/mcp/tools/file-exports.d.ts +1 -1
  317. package/dist/mcp/tools/file-exports.d.ts.map +1 -1
  318. package/dist/mcp/tools/find-cycles.d.ts +1 -1
  319. package/dist/mcp/tools/find-cycles.d.ts.map +1 -1
  320. package/dist/mcp/tools/fn-impact.d.ts +1 -1
  321. package/dist/mcp/tools/fn-impact.d.ts.map +1 -1
  322. package/dist/mcp/tools/impact-analysis.d.ts +1 -1
  323. package/dist/mcp/tools/impact-analysis.d.ts.map +1 -1
  324. package/dist/mcp/tools/implementations.d.ts +1 -1
  325. package/dist/mcp/tools/implementations.d.ts.map +1 -1
  326. package/dist/mcp/tools/index.d.ts +2 -5
  327. package/dist/mcp/tools/index.d.ts.map +1 -1
  328. package/dist/mcp/tools/index.js.map +1 -1
  329. package/dist/mcp/tools/interfaces.d.ts +1 -1
  330. package/dist/mcp/tools/interfaces.d.ts.map +1 -1
  331. package/dist/mcp/tools/list-functions.d.ts +1 -1
  332. package/dist/mcp/tools/list-functions.d.ts.map +1 -1
  333. package/dist/mcp/tools/list-repos.d.ts +1 -1
  334. package/dist/mcp/tools/list-repos.d.ts.map +1 -1
  335. package/dist/mcp/tools/module-map.d.ts +1 -1
  336. package/dist/mcp/tools/module-map.d.ts.map +1 -1
  337. package/dist/mcp/tools/node-roles.d.ts +1 -1
  338. package/dist/mcp/tools/node-roles.d.ts.map +1 -1
  339. package/dist/mcp/tools/path.d.ts +1 -1
  340. package/dist/mcp/tools/path.d.ts.map +1 -1
  341. package/dist/mcp/tools/query.d.ts +1 -1
  342. package/dist/mcp/tools/query.d.ts.map +1 -1
  343. package/dist/mcp/tools/semantic-search.d.ts +1 -1
  344. package/dist/mcp/tools/semantic-search.d.ts.map +1 -1
  345. package/dist/mcp/tools/sequence.d.ts +1 -1
  346. package/dist/mcp/tools/sequence.d.ts.map +1 -1
  347. package/dist/mcp/tools/structure.d.ts +1 -1
  348. package/dist/mcp/tools/structure.d.ts.map +1 -1
  349. package/dist/mcp/tools/symbol-children.d.ts +1 -1
  350. package/dist/mcp/tools/symbol-children.d.ts.map +1 -1
  351. package/dist/mcp/tools/triage.d.ts +1 -1
  352. package/dist/mcp/tools/triage.d.ts.map +1 -1
  353. package/dist/mcp/tools/where.d.ts +1 -1
  354. package/dist/mcp/tools/where.d.ts.map +1 -1
  355. package/dist/mcp/types.d.ts +19 -0
  356. package/dist/mcp/types.d.ts.map +1 -0
  357. package/dist/mcp/types.js +6 -0
  358. package/dist/mcp/types.js.map +1 -0
  359. package/dist/presentation/queries-cli/index.d.ts +1 -1
  360. package/dist/presentation/queries-cli/index.d.ts.map +1 -1
  361. package/dist/presentation/queries-cli/index.js +1 -1
  362. package/dist/presentation/queries-cli/index.js.map +1 -1
  363. package/dist/presentation/queries-cli/overview.d.ts +1 -0
  364. package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
  365. package/dist/presentation/queries-cli/overview.js +20 -1
  366. package/dist/presentation/queries-cli/overview.js.map +1 -1
  367. package/dist/presentation/queries-cli.d.ts +1 -1
  368. package/dist/presentation/queries-cli.d.ts.map +1 -1
  369. package/dist/presentation/queries-cli.js +1 -1
  370. package/dist/presentation/queries-cli.js.map +1 -1
  371. package/dist/presentation/structure.d.ts +1 -1
  372. package/dist/presentation/structure.d.ts.map +1 -1
  373. package/dist/presentation/structure.js +2 -2
  374. package/dist/presentation/structure.js.map +1 -1
  375. package/dist/presentation/viewer.d.ts.map +1 -1
  376. package/dist/presentation/viewer.js +45 -32
  377. package/dist/presentation/viewer.js.map +1 -1
  378. package/dist/shared/constants.d.ts +21 -0
  379. package/dist/shared/constants.d.ts.map +1 -1
  380. package/dist/shared/constants.js +25 -0
  381. package/dist/shared/constants.js.map +1 -1
  382. package/dist/shared/normalize.d.ts.map +1 -1
  383. package/dist/shared/normalize.js +12 -22
  384. package/dist/shared/normalize.js.map +1 -1
  385. package/dist/shared/paginate.d.ts +4 -17
  386. package/dist/shared/paginate.d.ts.map +1 -1
  387. package/dist/shared/paginate.js.map +1 -1
  388. package/dist/types.d.ts +113 -1
  389. package/dist/types.d.ts.map +1 -1
  390. package/grammars/tree-sitter-erlang.wasm +0 -0
  391. package/grammars/tree-sitter-gleam.wasm +0 -0
  392. package/package.json +7 -8
  393. package/src/ast-analysis/engine.ts +43 -63
  394. package/src/ast-analysis/rules/b2.ts +263 -0
  395. package/src/ast-analysis/rules/b3.ts +127 -0
  396. package/src/ast-analysis/rules/b4.ts +378 -0
  397. package/src/ast-analysis/rules/b5.ts +65 -0
  398. package/src/ast-analysis/rules/c.ts +157 -0
  399. package/src/ast-analysis/rules/index.ts +34 -0
  400. package/src/ast-analysis/rules/javascript.ts +3 -0
  401. package/src/ast-analysis/shared.ts +2 -0
  402. package/src/ast-analysis/visitor-utils.ts +5 -0
  403. package/src/ast-analysis/visitor.ts +82 -52
  404. package/src/ast-analysis/visitors/cfg-visitor.ts +198 -84
  405. package/src/ast-analysis/visitors/complexity-visitor.ts +44 -16
  406. package/src/ast-analysis/visitors/dataflow-visitor.ts +68 -29
  407. package/src/cli/commands/audit.ts +2 -1
  408. package/src/cli/commands/batch.ts +1 -0
  409. package/src/cli/commands/build.ts +6 -1
  410. package/src/cli/commands/config.ts +353 -0
  411. package/src/cli/commands/roles.ts +6 -1
  412. package/src/cli/commands/triage.ts +1 -1
  413. package/src/cli/index.ts +10 -0
  414. package/src/cli/shared/options.ts +11 -1
  415. package/src/cli/types.ts +2 -0
  416. package/src/db/better-sqlite3.ts +5 -4
  417. package/src/db/connection.ts +23 -5
  418. package/src/db/index.ts +1 -0
  419. package/src/db/migrations.ts +69 -1
  420. package/src/db/repository/build-stmts.ts +30 -0
  421. package/src/db/repository/dataflow.ts +16 -0
  422. package/src/db/repository/index.ts +1 -1
  423. package/src/db/repository/native-repository.ts +56 -40
  424. package/src/domain/analysis/fn-impact.ts +4 -0
  425. package/src/domain/analysis/module-map.ts +38 -6
  426. package/src/domain/analysis/roles.ts +23 -0
  427. package/src/domain/graph/builder/call-resolver.ts +156 -218
  428. package/src/domain/graph/builder/cha.ts +18 -1
  429. package/src/domain/graph/builder/context.ts +1 -0
  430. package/src/domain/graph/builder/helpers.ts +205 -67
  431. package/src/domain/graph/builder/incremental.ts +249 -119
  432. package/src/domain/graph/builder/pipeline.ts +59 -6
  433. package/src/domain/graph/builder/stages/build-edges.ts +783 -652
  434. package/src/domain/graph/builder/stages/collect-files.ts +12 -6
  435. package/src/domain/graph/builder/stages/detect-changes.ts +4 -2
  436. package/src/domain/graph/builder/stages/finalize.ts +4 -0
  437. package/src/domain/graph/builder/stages/native-orchestrator.ts +1214 -398
  438. package/src/domain/graph/builder/stages/resolve-imports.ts +1 -1
  439. package/src/domain/graph/resolver/points-to.ts +182 -59
  440. package/src/domain/graph/resolver/strategy.ts +265 -0
  441. package/src/domain/graph/watcher.ts +19 -9
  442. package/src/domain/parser.ts +57 -16
  443. package/src/domain/queries.ts +1 -1
  444. package/src/domain/wasm-worker-entry.ts +13 -2
  445. package/src/domain/wasm-worker-pool.ts +29 -4
  446. package/src/domain/wasm-worker-protocol.ts +5 -0
  447. package/src/extractors/cpp.ts +44 -1
  448. package/src/extractors/cuda.ts +44 -1
  449. package/src/extractors/dart.ts +48 -3
  450. package/src/extractors/groovy.ts +62 -2
  451. package/src/extractors/helpers.ts +48 -2
  452. package/src/extractors/java.ts +88 -8
  453. package/src/extractors/javascript.ts +693 -167
  454. package/src/extractors/kotlin.ts +57 -3
  455. package/src/extractors/objc.ts +25 -1
  456. package/src/extractors/scala.ts +63 -1
  457. package/src/extractors/swift.ts +46 -3
  458. package/src/features/audit.ts +43 -34
  459. package/src/features/boundaries.ts +17 -9
  460. package/src/features/cfg.ts +31 -22
  461. package/src/features/check.ts +21 -5
  462. package/src/features/communities.ts +28 -19
  463. package/src/features/dataflow.ts +755 -6
  464. package/src/features/manifesto.ts +76 -75
  465. package/src/features/sequence.ts +29 -23
  466. package/src/features/snapshot.ts +36 -25
  467. package/src/features/structure-query.ts +7 -7
  468. package/src/features/structure.ts +185 -55
  469. package/src/features/triage.ts +28 -15
  470. package/src/graph/algorithms/bfs.ts +13 -12
  471. package/src/graph/algorithms/tarjan.ts +5 -0
  472. package/src/graph/builders/dependency.ts +35 -23
  473. package/src/graph/classifiers/roles.ts +74 -7
  474. package/src/index.ts +5 -1
  475. package/src/infrastructure/config.ts +511 -23
  476. package/src/infrastructure/registry.ts +117 -12
  477. package/src/infrastructure/update-check.ts +55 -33
  478. package/src/mcp/server.ts +2 -8
  479. package/src/mcp/tools/ast-query.ts +1 -1
  480. package/src/mcp/tools/audit.ts +1 -1
  481. package/src/mcp/tools/batch-query.ts +1 -1
  482. package/src/mcp/tools/branch-compare.ts +1 -1
  483. package/src/mcp/tools/brief.ts +1 -1
  484. package/src/mcp/tools/cfg.ts +1 -1
  485. package/src/mcp/tools/check.ts +1 -1
  486. package/src/mcp/tools/co-changes.ts +1 -1
  487. package/src/mcp/tools/code-owners.ts +1 -1
  488. package/src/mcp/tools/communities.ts +1 -1
  489. package/src/mcp/tools/complexity.ts +1 -1
  490. package/src/mcp/tools/context.ts +1 -1
  491. package/src/mcp/tools/dataflow.ts +1 -1
  492. package/src/mcp/tools/diff-impact.ts +1 -1
  493. package/src/mcp/tools/execution-flow.ts +1 -1
  494. package/src/mcp/tools/export-graph.ts +1 -1
  495. package/src/mcp/tools/file-deps.ts +1 -1
  496. package/src/mcp/tools/file-exports.ts +1 -1
  497. package/src/mcp/tools/find-cycles.ts +1 -1
  498. package/src/mcp/tools/fn-impact.ts +1 -1
  499. package/src/mcp/tools/impact-analysis.ts +1 -1
  500. package/src/mcp/tools/implementations.ts +1 -1
  501. package/src/mcp/tools/index.ts +2 -5
  502. package/src/mcp/tools/interfaces.ts +1 -1
  503. package/src/mcp/tools/list-functions.ts +1 -1
  504. package/src/mcp/tools/list-repos.ts +1 -1
  505. package/src/mcp/tools/module-map.ts +1 -1
  506. package/src/mcp/tools/node-roles.ts +1 -1
  507. package/src/mcp/tools/path.ts +1 -1
  508. package/src/mcp/tools/query.ts +1 -1
  509. package/src/mcp/tools/semantic-search.ts +1 -1
  510. package/src/mcp/tools/sequence.ts +1 -1
  511. package/src/mcp/tools/structure.ts +1 -1
  512. package/src/mcp/tools/symbol-children.ts +1 -1
  513. package/src/mcp/tools/triage.ts +1 -1
  514. package/src/mcp/tools/where.ts +1 -1
  515. package/src/mcp/types.ts +21 -0
  516. package/src/presentation/queries-cli/index.ts +1 -1
  517. package/src/presentation/queries-cli/overview.ts +35 -1
  518. package/src/presentation/queries-cli.ts +1 -0
  519. package/src/presentation/structure.ts +3 -3
  520. package/src/presentation/viewer.ts +98 -87
  521. package/src/shared/constants.ts +26 -0
  522. package/src/shared/normalize.ts +13 -22
  523. package/src/shared/paginate.ts +4 -18
  524. package/src/types.ts +127 -1
@@ -114,10 +114,12 @@ function buildContainmentEdges(
114
114
  // Lazily-cached prepared statements for reverse-dep operations
115
115
  let _revDepDb: BetterSqlite3Database | null = null;
116
116
  let _findRevDepsStmt: SqliteStatement | null = null;
117
+ let _deleteDataflowByCallEdgeStmt: SqliteStatement | null | undefined; // undefined = not yet tried
117
118
  let _deleteOutEdgesStmt: SqliteStatement | null = null;
118
119
 
119
120
  function getRevDepStmts(db: BetterSqlite3Database): {
120
121
  findRevDepsStmt: SqliteStatement;
122
+ deleteDataflowByCallEdgeStmt: SqliteStatement | null;
121
123
  deleteOutEdgesStmt: SqliteStatement;
122
124
  } {
123
125
  if (_revDepDb !== db) {
@@ -128,12 +130,24 @@ function getRevDepStmts(db: BetterSqlite3Database): {
128
130
  JOIN nodes n_tgt ON e.target_id = n_tgt.id
129
131
  WHERE n_tgt.file = ? AND n_src.file != ? AND n_src.kind != 'directory'`,
130
132
  );
133
+ // Delete inter-procedural dataflow rows whose call_edge_id references an
134
+ // outgoing edge from this file. Must run before deleteOutEdgesStmt to avoid
135
+ // SQLITE_CONSTRAINT_FOREIGNKEY: dataflow.call_edge_id REFERENCES edges(id).
136
+ try {
137
+ _deleteDataflowByCallEdgeStmt = db.prepare(
138
+ `DELETE FROM dataflow WHERE call_edge_id IN
139
+ (SELECT id FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?))`,
140
+ );
141
+ } catch {
142
+ _deleteDataflowByCallEdgeStmt = null; // dataflow table or call_edge_id column absent
143
+ }
131
144
  _deleteOutEdgesStmt = db.prepare(
132
145
  'DELETE FROM edges WHERE source_id IN (SELECT id FROM nodes WHERE file = ?)',
133
146
  );
134
147
  }
135
148
  return {
136
149
  findRevDepsStmt: _findRevDepsStmt!,
150
+ deleteDataflowByCallEdgeStmt: _deleteDataflowByCallEdgeStmt ?? null,
137
151
  deleteOutEdgesStmt: _deleteOutEdgesStmt!,
138
152
  };
139
153
  }
@@ -144,7 +158,10 @@ function findReverseDeps(db: BetterSqlite3Database, relPath: string): string[] {
144
158
  }
145
159
 
146
160
  function deleteOutgoingEdges(db: BetterSqlite3Database, relPath: string): void {
147
- const { deleteOutEdgesStmt } = getRevDepStmts(db);
161
+ const { deleteDataflowByCallEdgeStmt, deleteOutEdgesStmt } = getRevDepStmts(db);
162
+ // Clear any inter-procedural dataflow rows that reference outgoing edges via
163
+ // call_edge_id before deleting those edges (FK: dataflow.call_edge_id → edges.id).
164
+ deleteDataflowByCallEdgeStmt?.run(relPath);
148
165
  deleteOutEdgesStmt.run(relPath);
149
166
  }
150
167
 
@@ -482,6 +499,215 @@ function makeIncrementalLookup(db: BetterSqlite3Database, stmts: IncrementalStmt
482
499
  };
483
500
  }
484
501
 
502
+ /** Coerce symbols.typeMap (Map, Array, or undefined) to a canonical Map. */
503
+ function coerceTypeMap(symbols: ExtractorOutput): Map<string, unknown> {
504
+ const rawTM: unknown = symbols.typeMap;
505
+ if (rawTM instanceof Map) return rawTM;
506
+ if (Array.isArray(rawTM) && rawTM.length > 0) {
507
+ return new Map(
508
+ (rawTM as Array<{ name: string; typeName?: string; type?: string }>).map((e) => [
509
+ e.name,
510
+ e.typeName ?? e.type ?? null,
511
+ ]),
512
+ );
513
+ }
514
+ return new Map();
515
+ }
516
+
517
+ /**
518
+ * Seed scoped rest-param keys into typeMap (Phase 8.3f).
519
+ * Mirrors buildObjectRestParamPostPass in the full build.
520
+ *
521
+ * Scoped keys (`callee::restName`) prevent same-name rest-param collisions
522
+ * when two functions in the same file both use `...rest` (#1358). The
523
+ * unscoped key is also seeded when only one callee uses a given rest name,
524
+ * preserving resolution when callerName is null.
525
+ */
526
+ function seedRestParamTypeMap(typeMap: Map<string, unknown>, symbols: ExtractorOutput): void {
527
+ if (!symbols.objectRestParamBindings?.length || !symbols.paramBindings?.length) return;
528
+
529
+ const restNameCallees = new Map<string, Set<string>>();
530
+ for (const orpb of symbols.objectRestParamBindings) {
531
+ if (!restNameCallees.has(orpb.restName)) restNameCallees.set(orpb.restName, new Set());
532
+ restNameCallees.get(orpb.restName)!.add(orpb.callee);
533
+ }
534
+ for (const orpb of symbols.objectRestParamBindings) {
535
+ for (const pb of symbols.paramBindings) {
536
+ if (pb.callee === orpb.callee && pb.argIndex === orpb.argIndex) {
537
+ const scopedKey = `${orpb.callee}::${orpb.restName}`;
538
+ if (!typeMap.has(scopedKey)) {
539
+ typeMap.set(scopedKey, { type: pb.argName, confidence: 0.65 });
540
+ if (restNameCallees.get(orpb.restName)!.size === 1 && !typeMap.has(orpb.restName)) {
541
+ typeMap.set(orpb.restName, { type: pb.argName, confidence: 0.65 });
542
+ }
543
+ }
544
+ }
545
+ }
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Normalize symbols.typeMap into a canonical Map and seed scoped rest-param
551
+ * keys (Phase 8.3f). Mirrors buildObjectRestParamPostPass in the full build.
552
+ */
553
+ function buildIncrementalTypeMap(symbols: ExtractorOutput): Map<string, unknown> {
554
+ const typeMap = coerceTypeMap(symbols);
555
+ seedRestParamTypeMap(typeMap, symbols);
556
+ return typeMap;
557
+ }
558
+
559
+ /**
560
+ * Strategy 1 — same-class `this.method()` fallback.
561
+ * Derives the enclosing class name from callerName by extracting the segment
562
+ * immediately before the final dot (e.g. `MyClass.method` → `MyClass`,
563
+ * `Namespace.MyClass.method` → `MyClass`), then retries with the qualified
564
+ * method name `MyClass.callName`.
565
+ *
566
+ * Uses lastIndexOf to match the full-build counterpart in resolveFallbackTargets
567
+ * (build-edges.ts) — indexOf would extract `Namespace` instead of `MyClass` for
568
+ * deeply-qualified caller names like `Namespace.MyClass.method`.
569
+ */
570
+ function resolveThisSameClassTarget(
571
+ callName: string,
572
+ callerName: string,
573
+ relPath: string,
574
+ lookup: CallNodeLookup,
575
+ ): Array<{ id: number; file: string; kind?: string }> {
576
+ const lastDot = callerName.lastIndexOf('.');
577
+ if (lastDot <= 0) return [];
578
+ const prevDot = callerName.lastIndexOf('.', lastDot - 1);
579
+ const className = callerName.slice(prevDot + 1, lastDot);
580
+ return lookup
581
+ .byNameAndFile(`${className}.${callName}`, relPath)
582
+ .filter((n) => n.kind === 'method');
583
+ }
584
+
585
+ /**
586
+ * Strategy 2 — Object.defineProperty accessor fallback.
587
+ * When a function is registered as a getter/setter via
588
+ * `Object.defineProperty(obj, "bar", { get: getter })`, calls to `this.X()`
589
+ * inside `getter` resolve against `obj`. Looks up the receiver var in the
590
+ * typeMap for its type, then falls back to any same-file definition named
591
+ * `callName` with function or method kind.
592
+ */
593
+ function resolveDefinePropertyTarget(
594
+ callName: string,
595
+ callerName: string,
596
+ relPath: string,
597
+ typeMap: Map<string, unknown>,
598
+ lookup: CallNodeLookup,
599
+ definePropertyReceivers: Map<string, string>,
600
+ ): Array<{ id: number; file: string; kind?: string }> {
601
+ const receiverVarName = definePropertyReceivers.get(callerName);
602
+ if (!receiverVarName) return [];
603
+
604
+ const typeEntry = typeMap.get(receiverVarName);
605
+ const typeName = typeEntry
606
+ ? typeof typeEntry === 'string'
607
+ ? typeEntry
608
+ : (typeEntry as { type?: string }).type
609
+ : null;
610
+ if (typeName) {
611
+ const qualified = lookup.byNameAndFile(`${typeName}.${callName}`, relPath);
612
+ if (qualified.length > 0) return [...qualified];
613
+ }
614
+ // Narrow to function/method kinds only to avoid matching unrelated
615
+ // variables or classes that share a name in the same file.
616
+ return lookup
617
+ .byNameAndFile(callName, relPath)
618
+ .filter((n) => n.kind === 'function' || n.kind === 'method');
619
+ }
620
+
621
+ /**
622
+ * Apply `this`-receiver fallback resolution strategies for a single call site
623
+ * when the primary resolveCallTargets pass returned no targets.
624
+ */
625
+ function applyThisReceiverFallbacks(
626
+ call: { name: string; receiver?: string | null },
627
+ callerName: string | null,
628
+ relPath: string,
629
+ typeMap: Map<string, unknown>,
630
+ lookup: CallNodeLookup,
631
+ definePropertyReceivers: Map<string, string> | undefined,
632
+ initialTargets: Array<{ id: number; file: string; kind?: string }>,
633
+ ): Array<{ id: number; file: string; kind?: string }> {
634
+ if (initialTargets.length > 0) return initialTargets;
635
+
636
+ // Strategy 1: same-class `this.method()` fallback.
637
+ if (call.receiver === 'this' && callerName != null) {
638
+ const s1 = resolveThisSameClassTarget(call.name, callerName, relPath, lookup);
639
+ if (s1.length > 0) return s1;
640
+ }
641
+
642
+ // Strategy 2: Object.defineProperty accessor fallback.
643
+ if (call.receiver === 'this' && callerName != null && definePropertyReceivers) {
644
+ return resolveDefinePropertyTarget(
645
+ call.name,
646
+ callerName,
647
+ relPath,
648
+ typeMap,
649
+ lookup,
650
+ definePropertyReceivers,
651
+ );
652
+ }
653
+
654
+ return initialTargets;
655
+ }
656
+
657
+ /**
658
+ * Emit direct `calls` edges for the resolved targets of a single call site,
659
+ * then emit a `receiver` edge when the call has a non-this/self/super receiver.
660
+ * Returns the number of edges inserted.
661
+ */
662
+ function emitIncrementalCallEdges(
663
+ call: { name: string; receiver?: string | null; dynamic?: boolean },
664
+ caller: { id: number; callerName: string | null },
665
+ targets: Array<{ id: number; file: string; kind?: string }>,
666
+ importedFrom: string | null | undefined,
667
+ relPath: string,
668
+ typeMap: Map<string, unknown>,
669
+ lookup: CallNodeLookup,
670
+ importedNames: Map<string, string>,
671
+ seenCallEdges: Set<string>,
672
+ stmts: IncrementalStmts,
673
+ ): number {
674
+ let edgesAdded = 0;
675
+
676
+ for (const t of targets) {
677
+ const edgeKey = `${caller.id}|${t.id}`;
678
+ if (t.id !== caller.id && !seenCallEdges.has(edgeKey)) {
679
+ seenCallEdges.add(edgeKey);
680
+ const confidence = computeConfidence(relPath, t.file, importedFrom ?? null);
681
+ stmts.insertEdge.run(caller.id, t.id, 'calls', confidence, call.dynamic ? 1 : 0);
682
+ edgesAdded++;
683
+ }
684
+ }
685
+
686
+ if (
687
+ call.receiver &&
688
+ !BUILTIN_RECEIVERS.has(call.receiver) &&
689
+ call.receiver !== 'this' &&
690
+ call.receiver !== 'self' &&
691
+ call.receiver !== 'super'
692
+ ) {
693
+ const recv = resolveReceiverEdge(
694
+ lookup,
695
+ { name: call.name, receiver: call.receiver },
696
+ caller,
697
+ relPath,
698
+ typeMap,
699
+ seenCallEdges,
700
+ importedNames,
701
+ );
702
+ if (recv) {
703
+ stmts.insertEdge.run(recv.callerId, recv.receiverId, 'receiver', recv.confidence, 0);
704
+ edgesAdded++;
705
+ }
706
+ }
707
+
708
+ return edgesAdded;
709
+ }
710
+
485
711
  function buildCallEdges(
486
712
  db: BetterSqlite3Database,
487
713
  stmts: IncrementalStmts,
@@ -490,46 +716,7 @@ function buildCallEdges(
490
716
  fileNodeRow: { id: number },
491
717
  importedNames: Map<string, string>,
492
718
  ): number {
493
- const rawTM: unknown = symbols.typeMap;
494
- const typeMap: Map<string, unknown> =
495
- rawTM instanceof Map
496
- ? rawTM
497
- : Array.isArray(rawTM) && rawTM.length > 0
498
- ? new Map(
499
- (rawTM as Array<{ name: string; typeName?: string; type?: string }>).map((e) => [
500
- e.name,
501
- e.typeName ?? e.type ?? null,
502
- ]),
503
- )
504
- : new Map();
505
-
506
- // Phase 8.3f: seed typeMap[callee::restName] = { type: argName } from
507
- // objectRestParamBindings × paramBindings, mirroring buildObjectRestParamPostPass.
508
- // Scoped keys prevent same-name rest-param collisions when two functions in
509
- // the same file both use `...rest` (#1358). The unscoped key is also seeded
510
- // when only one callee uses a given rest name, preserving resolution when
511
- // callerName is null (findCaller couldn't identify the enclosing function).
512
- if (symbols.objectRestParamBindings?.length && symbols.paramBindings?.length) {
513
- const restNameCallees = new Map<string, Set<string>>();
514
- for (const orpb of symbols.objectRestParamBindings) {
515
- if (!restNameCallees.has(orpb.restName)) restNameCallees.set(orpb.restName, new Set());
516
- restNameCallees.get(orpb.restName)!.add(orpb.callee);
517
- }
518
- for (const orpb of symbols.objectRestParamBindings) {
519
- for (const pb of symbols.paramBindings) {
520
- if (pb.callee === orpb.callee && pb.argIndex === orpb.argIndex) {
521
- const scopedKey = `${orpb.callee}::${orpb.restName}`;
522
- if (!typeMap.has(scopedKey)) {
523
- typeMap.set(scopedKey, { type: pb.argName, confidence: 0.65 });
524
- if (restNameCallees.get(orpb.restName)!.size === 1 && !typeMap.has(orpb.restName)) {
525
- typeMap.set(orpb.restName, { type: pb.argName, confidence: 0.65 });
526
- }
527
- }
528
- }
529
- }
530
- }
531
- }
532
-
719
+ const typeMap = buildIncrementalTypeMap(symbols);
533
720
  const seenCallEdges = new Set<string>();
534
721
  const lookup = makeIncrementalLookup(db, stmts);
535
722
  let edgesAdded = 0;
@@ -546,86 +733,29 @@ function buildCallEdges(
546
733
  typeMap,
547
734
  caller.callerName,
548
735
  );
549
- let targets = initialTargets;
550
-
551
- if (targets.length === 0 && call.receiver === 'this' && caller.callerName != null) {
552
- const dotIdx = caller.callerName.indexOf('.');
553
- if (dotIdx > 0) {
554
- const className = caller.callerName.slice(0, dotIdx);
555
- const qualifiedName = `${className}.${call.name}`;
556
- const qualified = lookup
557
- .byNameAndFile(qualifiedName, relPath)
558
- .filter((n) => n.kind === 'method');
559
- if (qualified.length > 0) {
560
- targets = qualified;
561
- }
562
- }
563
- }
564
-
565
- if (
566
- targets.length === 0 &&
567
- call.receiver === 'this' &&
568
- caller.callerName != null &&
569
- symbols.definePropertyReceivers
570
- ) {
571
- const receiverVarName = symbols.definePropertyReceivers.get(caller.callerName);
572
- if (receiverVarName) {
573
- const typeEntry = typeMap.get(receiverVarName);
574
- const typeName = typeEntry
575
- ? typeof typeEntry === 'string'
576
- ? typeEntry
577
- : (typeEntry as { type?: string }).type
578
- : null;
579
- if (typeName) {
580
- const qualifiedName = `${typeName}.${call.name}`;
581
- const qualified = lookup.byNameAndFile(qualifiedName, relPath);
582
- if (qualified.length > 0) {
583
- targets = [...qualified];
584
- }
585
- }
586
- if (targets.length === 0) {
587
- // Narrow to function/method kinds only to avoid matching unrelated
588
- // variables or classes that share a name in the same file.
589
- const sameFile = lookup
590
- .byNameAndFile(call.name, relPath)
591
- .filter((n) => n.kind === 'function' || n.kind === 'method');
592
- if (sameFile.length > 0) {
593
- targets = [...sameFile];
594
- }
595
- }
596
- }
597
- }
598
736
 
599
- for (const t of targets) {
600
- const edgeKey = `${caller.id}|${t.id}`;
601
- if (t.id !== caller.id && !seenCallEdges.has(edgeKey)) {
602
- seenCallEdges.add(edgeKey);
603
- const confidence = computeConfidence(relPath, t.file, importedFrom ?? null);
604
- stmts.insertEdge.run(caller.id, t.id, 'calls', confidence, call.dynamic ? 1 : 0);
605
- edgesAdded++;
606
- }
607
- }
737
+ const targets = applyThisReceiverFallbacks(
738
+ call,
739
+ caller.callerName,
740
+ relPath,
741
+ typeMap,
742
+ lookup,
743
+ symbols.definePropertyReceivers,
744
+ initialTargets,
745
+ );
608
746
 
609
- if (
610
- call.receiver &&
611
- !BUILTIN_RECEIVERS.has(call.receiver) &&
612
- call.receiver !== 'this' &&
613
- call.receiver !== 'self' &&
614
- call.receiver !== 'super'
615
- ) {
616
- const recv = resolveReceiverEdge(
617
- lookup,
618
- { name: call.name, receiver: call.receiver },
619
- caller,
620
- relPath,
621
- typeMap,
622
- seenCallEdges,
623
- );
624
- if (recv) {
625
- stmts.insertEdge.run(recv.callerId, recv.receiverId, 'receiver', recv.confidence, 0);
626
- edgesAdded++;
627
- }
628
- }
747
+ edgesAdded += emitIncrementalCallEdges(
748
+ call,
749
+ caller,
750
+ targets,
751
+ importedFrom,
752
+ relPath,
753
+ typeMap,
754
+ lookup,
755
+ importedNames,
756
+ seenCallEdges,
757
+ stmts,
758
+ );
629
759
  }
630
760
  return edgesAdded;
631
761
  }
@@ -15,7 +15,14 @@ import {
15
15
  MIGRATIONS,
16
16
  openDb,
17
17
  } from '../../../db/index.js';
18
- import { detectWorkspaces, loadConfig } from '../../../infrastructure/config.js';
18
+ import {
19
+ computeConfigHash,
20
+ detectWorkspaces,
21
+ getLastAppliedGlobalConfig,
22
+ getLastAppliedGlobalPath,
23
+ loadConfig,
24
+ promptForConsentIfNeeded,
25
+ } from '../../../infrastructure/config.js';
19
26
  import { debug, info, warn } from '../../../infrastructure/logger.js';
20
27
  import { loadNative } from '../../../infrastructure/native.js';
21
28
  import { toErrorMessage } from '../../../shared/errors.js';
@@ -55,7 +62,9 @@ export {
55
62
 
56
63
  function initializeEngine(ctx: PipelineContext): void {
57
64
  ctx.engineOpts = {
58
- engine: ctx.opts.engine || 'auto',
65
+ // Priority: CLI --engine flag > .codegraphrc.json build.engine > 'auto'.
66
+ // ctx.config is already populated by the time initializeEngine is called.
67
+ engine: ctx.opts.engine ?? ctx.config.build.engine ?? 'auto',
59
68
  dataflow: ctx.opts.dataflow !== false,
60
69
  ast: ctx.opts.ast !== false,
61
70
  // nativeDb and WAL callbacks are set later when NativeDatabase is opened
@@ -114,6 +123,16 @@ function checkEngineSchemaMismatch(ctx: PipelineContext): void {
114
123
  );
115
124
  ctx.forceFullRebuild = true;
116
125
  }
126
+
127
+ // Config hash — promotes to full rebuild when build-relevant config changes
128
+ // (include/exclude/ignoreDirs/extensions/aliases/build.*).
129
+ // This closes the pre-existing config-change gap and covers the new global-config layer.
130
+ const currentConfigHash = computeConfigHash(ctx.config);
131
+ const prevConfigHash = meta('config_hash');
132
+ if (prevConfigHash && prevConfigHash !== currentConfigHash) {
133
+ info('Build-relevant config changed, promoting to full rebuild.');
134
+ ctx.forceFullRebuild = true;
135
+ }
117
136
  }
118
137
 
119
138
  function warnOnEmbeddingsWipe(ctx: PipelineContext): void {
@@ -157,8 +176,13 @@ function setupPipeline(ctx: PipelineContext): void {
157
176
  ? path.resolve(ctx.opts.dbPath)
158
177
  : path.join(ctx.rootDir, '.codegraph', 'graph.db');
159
178
 
179
+ // Load config first so build.engine from .codegraphrc.json is available for
180
+ // the engine-pref fallback below (ctx.opts.engine > config.build.engine > 'auto').
181
+ ctx.config = loadConfig(ctx.rootDir, { userConfig: ctx.opts.userConfig });
182
+
160
183
  // Detect whether native engine is available.
161
- const enginePref = ctx.opts.engine || 'auto';
184
+ // Priority: CLI --engine flag > .codegraphrc.json build.engine > 'auto'.
185
+ const enginePref = ctx.opts.engine ?? ctx.config.build.engine ?? 'auto';
162
186
  const native = enginePref !== 'wasm' ? loadNative() : null;
163
187
  ctx.nativeAvailable = !!native?.NativeDatabase;
164
188
 
@@ -171,8 +195,6 @@ function setupPipeline(ctx: PipelineContext): void {
171
195
  if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
172
196
  ctx.db = openDb(ctx.dbPath);
173
197
  initSchema(ctx.db);
174
-
175
- ctx.config = loadConfig(ctx.rootDir);
176
198
  // Merge caller-supplied excludes on top of the file-config excludes so
177
199
  // programmatic callers (e.g. benchmark scripts) can extend exclusion
178
200
  // without mutating .codegraphrc.json. Native orchestrator picks this up
@@ -186,6 +208,30 @@ function setupPipeline(ctx: PipelineContext): void {
186
208
  ctx.incremental =
187
209
  ctx.opts.incremental !== false && ctx.config.build && ctx.config.build.incremental !== false;
188
210
 
211
+ // ── Build-time global-config notice ──────────────────────────────
212
+ // Use the already-parsed and sanitized global config cached by loadConfig —
213
+ // avoids a second disk read and the TOCTOU window between loadConfig and here.
214
+ const appliedGlobalPath = getLastAppliedGlobalPath();
215
+ if (appliedGlobalPath) {
216
+ const buildAffectingKeys = [
217
+ 'include',
218
+ 'exclude',
219
+ 'ignoreDirs',
220
+ 'extensions',
221
+ 'aliases',
222
+ 'build',
223
+ ];
224
+ const globalData = getLastAppliedGlobalConfig();
225
+ if (globalData) {
226
+ const injectedKeys = buildAffectingKeys.filter((k) => k in globalData);
227
+ if (injectedKeys.length > 0) {
228
+ process.stderr.write(
229
+ `ℹ global config applied (${appliedGlobalPath}) — injecting: ${injectedKeys.join(', ')} · --no-user-config to ignore\n`,
230
+ );
231
+ }
232
+ }
233
+ }
234
+
189
235
  initializeEngine(ctx);
190
236
  checkEngineSchemaMismatch(ctx);
191
237
  warnOnEmbeddingsWipe(ctx);
@@ -348,6 +394,12 @@ export async function buildGraph(
348
394
  ctx.rootDir = rootDir;
349
395
 
350
396
  try {
397
+ // Interactive consent prompt — only fires when the caller opts in (build
398
+ // command with TTY), a global file exists, and the repo is undecided.
399
+ if (opts.promptForConsent) {
400
+ await promptForConsentIfNeeded(rootDir);
401
+ }
402
+
351
403
  setupPipeline(ctx);
352
404
 
353
405
  // ── JS-side fast-skip for native incremental (#1054) ──────────────
@@ -364,7 +416,8 @@ export async function buildGraph(
364
416
  // engineName, scope, etc.) we log the reason so the bench gate run
365
417
  // produces observable output even if `detectNoChanges` is never
366
418
  // entered.
367
- const fastSkipDiag = process.env.CODEGRAPH_FAST_SKIP_DIAG === '1';
419
+ // Reads from config (which applies CODEGRAPH_FAST_SKIP_DIAG via applyEnvOverrides).
420
+ const fastSkipDiag = ctx.config.build.fastSkipDiag;
368
421
  if (fastSkipDiag) {
369
422
  const reasons: string[] = [];
370
423
  if (!ctx.nativeAvailable) reasons.push('nativeAvailable=false');