@lzehrung/codegraph 2.3.30 → 2.4.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 (416) hide show
  1. package/README.md +30 -137
  2. package/codegraph-skill/codegraph/SKILL.md +5 -3
  3. package/dist/agent/artifact.d.ts +2 -0
  4. package/dist/agent/artifact.d.ts.map +1 -1
  5. package/dist/agent/artifact.js.map +1 -1
  6. package/dist/agent/search.d.ts.map +1 -1
  7. package/dist/agent/search.js +3 -0
  8. package/dist/agent/search.js.map +1 -1
  9. package/dist/agent/session.d.ts +3 -0
  10. package/dist/agent/session.d.ts.map +1 -1
  11. package/dist/agent/session.js +10 -2
  12. package/dist/agent/session.js.map +1 -1
  13. package/dist/bin/cli.js +42229 -28876
  14. package/dist/bin/query-index-worker.js +73 -11
  15. package/dist/cli/affected.d.ts.map +1 -1
  16. package/dist/cli/affected.js +4 -1
  17. package/dist/cli/affected.js.map +1 -1
  18. package/dist/cli/command-catalog.js +1 -1
  19. package/dist/cli/command-catalog.js.map +1 -1
  20. package/dist/cli/graph-queries.d.ts.map +1 -1
  21. package/dist/cli/graph-queries.js +27 -1
  22. package/dist/cli/graph-queries.js.map +1 -1
  23. package/dist/cli/help.d.ts +2 -2
  24. package/dist/cli/help.d.ts.map +1 -1
  25. package/dist/cli/help.js +4 -2
  26. package/dist/cli/help.js.map +1 -1
  27. package/dist/cli/options.js +2 -2
  28. package/dist/cli/options.js.map +1 -1
  29. package/dist/drift/artifact.d.ts.map +1 -1
  30. package/dist/drift/artifact.js +15 -18
  31. package/dist/drift/artifact.js.map +1 -1
  32. package/dist/drift/compare.js +1 -1
  33. package/dist/drift/compare.js.map +1 -1
  34. package/dist/drift/snapshot.d.ts.map +1 -1
  35. package/dist/drift/snapshot.js +5 -6
  36. package/dist/drift/snapshot.js.map +1 -1
  37. package/dist/drift/types.d.ts +2 -0
  38. package/dist/drift/types.d.ts.map +1 -1
  39. package/dist/drift/types.js.map +1 -1
  40. package/dist/graph-builder.d.ts.map +1 -1
  41. package/dist/graph-builder.js +4 -6
  42. package/dist/graph-builder.js.map +1 -1
  43. package/dist/graph-edge-collector.d.ts +3 -0
  44. package/dist/graph-edge-collector.d.ts.map +1 -1
  45. package/dist/graph-edge-collector.js +8 -5
  46. package/dist/graph-edge-collector.js.map +1 -1
  47. package/dist/graphs/angularjs.d.ts.map +1 -1
  48. package/dist/graphs/angularjs.js +2 -1
  49. package/dist/graphs/angularjs.js.map +1 -1
  50. package/dist/graphs/edge-resolution.d.ts +4 -1
  51. package/dist/graphs/edge-resolution.d.ts.map +1 -1
  52. package/dist/graphs/edge-resolution.js +26 -2
  53. package/dist/graphs/edge-resolution.js.map +1 -1
  54. package/dist/graphs/specifiers.d.ts.map +1 -1
  55. package/dist/graphs/specifiers.js +6 -2
  56. package/dist/graphs/specifiers.js.map +1 -1
  57. package/dist/graphs/symbol-graph-detailed/ast.d.ts +20 -0
  58. package/dist/graphs/symbol-graph-detailed/ast.d.ts.map +1 -1
  59. package/dist/graphs/symbol-graph-detailed/ast.js +154 -15
  60. package/dist/graphs/symbol-graph-detailed/ast.js.map +1 -1
  61. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +51 -8
  62. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
  63. package/dist/graphs/symbol-graph-detailed/edge-passes.js +823 -132
  64. package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
  65. package/dist/graphs/symbol-graph-detailed/import-aliases.d.ts +2 -1
  66. package/dist/graphs/symbol-graph-detailed/import-aliases.d.ts.map +1 -1
  67. package/dist/graphs/symbol-graph-detailed/import-aliases.js +139 -7
  68. package/dist/graphs/symbol-graph-detailed/import-aliases.js.map +1 -1
  69. package/dist/graphs/symbol-graph-detailed/member-chains.d.ts +1 -0
  70. package/dist/graphs/symbol-graph-detailed/member-chains.d.ts.map +1 -1
  71. package/dist/graphs/symbol-graph-detailed/member-chains.js +3 -1
  72. package/dist/graphs/symbol-graph-detailed/member-chains.js.map +1 -1
  73. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +128 -22
  74. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
  75. package/dist/graphs/symbol-graph-detailed/receiver-calls.js +872 -125
  76. package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
  77. package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
  78. package/dist/graphs/symbol-graph-detailed.js +434 -40
  79. package/dist/graphs/symbol-graph-detailed.js.map +1 -1
  80. package/dist/graphs/symbol-graph.d.ts +2 -0
  81. package/dist/graphs/symbol-graph.d.ts.map +1 -1
  82. package/dist/graphs/symbol-graph.js +34 -16
  83. package/dist/graphs/symbol-graph.js.map +1 -1
  84. package/dist/impact/call-compatibility/providers/index.d.ts +12 -0
  85. package/dist/impact/call-compatibility/providers/index.d.ts.map +1 -1
  86. package/dist/impact/call-compatibility/providers/index.js +16 -22
  87. package/dist/impact/call-compatibility/providers/index.js.map +1 -1
  88. package/dist/impact/call-compatibility/providers/types.d.ts +2 -0
  89. package/dist/impact/call-compatibility/providers/types.d.ts.map +1 -1
  90. package/dist/impact/call-compatibility/types.d.ts +6 -0
  91. package/dist/impact/call-compatibility/types.d.ts.map +1 -1
  92. package/dist/impact/call-compatibility.d.ts.map +1 -1
  93. package/dist/impact/call-compatibility.js +316 -552
  94. package/dist/impact/call-compatibility.js.map +1 -1
  95. package/dist/impact/map.js +1 -0
  96. package/dist/impact/map.js.map +1 -1
  97. package/dist/impact/member-resolution-coverage.d.ts.map +1 -1
  98. package/dist/impact/member-resolution-coverage.js +1 -1
  99. package/dist/impact/member-resolution-coverage.js.map +1 -1
  100. package/dist/impact/reference-cache.d.ts.map +1 -1
  101. package/dist/impact/reference-cache.js +2 -2
  102. package/dist/impact/reference-cache.js.map +1 -1
  103. package/dist/index.d.ts +1 -1
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +1 -1
  106. package/dist/index.js.map +1 -1
  107. package/dist/indexer/ambiguous-resolution.d.ts +11 -0
  108. package/dist/indexer/ambiguous-resolution.d.ts.map +1 -0
  109. package/dist/indexer/ambiguous-resolution.js +19 -0
  110. package/dist/indexer/ambiguous-resolution.js.map +1 -0
  111. package/dist/indexer/build-cache/module-cache.d.ts +38 -0
  112. package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
  113. package/dist/indexer/build-cache/module-cache.js +151 -9
  114. package/dist/indexer/build-cache/module-cache.js.map +1 -1
  115. package/dist/indexer/build-cache/options.d.ts +16 -43
  116. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  117. package/dist/indexer/build-cache/options.js +16 -43
  118. package/dist/indexer/build-cache/options.js.map +1 -1
  119. package/dist/indexer/build-cache/project-snapshot.d.ts +1 -0
  120. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  121. package/dist/indexer/build-cache/project-snapshot.js +117 -24
  122. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  123. package/dist/indexer/build-cache/resolver-environment.d.ts.map +1 -1
  124. package/dist/indexer/build-cache/resolver-environment.js +32 -2
  125. package/dist/indexer/build-cache/resolver-environment.js.map +1 -1
  126. package/dist/indexer/build-cache.d.ts +1 -1
  127. package/dist/indexer/build-cache.d.ts.map +1 -1
  128. package/dist/indexer/build-cache.js +1 -1
  129. package/dist/indexer/build-cache.js.map +1 -1
  130. package/dist/indexer/build-index.d.ts.map +1 -1
  131. package/dist/indexer/build-index.js +593 -22
  132. package/dist/indexer/build-index.js.map +1 -1
  133. package/dist/indexer/call-hierarchy.js +1 -1
  134. package/dist/indexer/call-hierarchy.js.map +1 -1
  135. package/dist/indexer/compilation-units.d.ts +101 -0
  136. package/dist/indexer/compilation-units.d.ts.map +1 -0
  137. package/dist/indexer/compilation-units.js +605 -0
  138. package/dist/indexer/compilation-units.js.map +1 -0
  139. package/dist/indexer/cpp-callables.d.ts +20 -0
  140. package/dist/indexer/cpp-callables.d.ts.map +1 -0
  141. package/dist/indexer/cpp-callables.js +554 -0
  142. package/dist/indexer/cpp-callables.js.map +1 -0
  143. package/dist/indexer/declaration-visibility.d.ts +36 -2
  144. package/dist/indexer/declaration-visibility.d.ts.map +1 -1
  145. package/dist/indexer/declaration-visibility.js +136 -2
  146. package/dist/indexer/declaration-visibility.js.map +1 -1
  147. package/dist/indexer/expand-star-imports.d.ts.map +1 -1
  148. package/dist/indexer/expand-star-imports.js +28 -6
  149. package/dist/indexer/expand-star-imports.js.map +1 -1
  150. package/dist/indexer/import-types.d.ts +37 -0
  151. package/dist/indexer/import-types.d.ts.map +1 -1
  152. package/dist/indexer/import-types.js +24 -1
  153. package/dist/indexer/import-types.js.map +1 -1
  154. package/dist/indexer/imports/binding-ranges.d.ts +1 -1
  155. package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
  156. package/dist/indexer/imports/context.d.ts +11 -1
  157. package/dist/indexer/imports/context.d.ts.map +1 -1
  158. package/dist/indexer/imports/import-binding-tables.d.ts +75 -0
  159. package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -0
  160. package/dist/indexer/imports/import-binding-tables.js +544 -0
  161. package/dist/indexer/imports/import-binding-tables.js.map +1 -0
  162. package/dist/indexer/imports/js-text-imports.js +4 -4
  163. package/dist/indexer/imports/js-text-imports.js.map +1 -1
  164. package/dist/indexer/imports/language-specific.d.ts +3 -22
  165. package/dist/indexer/imports/language-specific.d.ts.map +1 -1
  166. package/dist/indexer/imports/language-specific.js +29 -362
  167. package/dist/indexer/imports/language-specific.js.map +1 -1
  168. package/dist/indexer/imports/native-captures.d.ts.map +1 -1
  169. package/dist/indexer/imports/native-captures.js +18 -6
  170. package/dist/indexer/imports/native-captures.js.map +1 -1
  171. package/dist/indexer/imports/python.d.ts +10 -2
  172. package/dist/indexer/imports/python.d.ts.map +1 -1
  173. package/dist/indexer/imports/python.js +91 -40
  174. package/dist/indexer/imports/python.js.map +1 -1
  175. package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
  176. package/dist/indexer/imports/text-import-extractors.js +51 -12
  177. package/dist/indexer/imports/text-import-extractors.js.map +1 -1
  178. package/dist/indexer/imports.d.ts.map +1 -1
  179. package/dist/indexer/imports.js +25 -5
  180. package/dist/indexer/imports.js.map +1 -1
  181. package/dist/indexer/incremental-plan.d.ts +33 -0
  182. package/dist/indexer/incremental-plan.d.ts.map +1 -1
  183. package/dist/indexer/incremental-plan.js +187 -1
  184. package/dist/indexer/incremental-plan.js.map +1 -1
  185. package/dist/indexer/locals-and-exports.d.ts +2 -0
  186. package/dist/indexer/locals-and-exports.d.ts.map +1 -1
  187. package/dist/indexer/locals-and-exports.js +565 -54
  188. package/dist/indexer/locals-and-exports.js.map +1 -1
  189. package/dist/indexer/name-lookup-policies/c-family.d.ts +7 -0
  190. package/dist/indexer/name-lookup-policies/c-family.d.ts.map +1 -0
  191. package/dist/indexer/name-lookup-policies/c-family.js +117 -0
  192. package/dist/indexer/name-lookup-policies/c-family.js.map +1 -0
  193. package/dist/indexer/name-lookup-policies/csharp-using-static.d.ts +11 -0
  194. package/dist/indexer/name-lookup-policies/csharp-using-static.d.ts.map +1 -0
  195. package/dist/indexer/name-lookup-policies/csharp-using-static.js +136 -0
  196. package/dist/indexer/name-lookup-policies/csharp-using-static.js.map +1 -0
  197. package/dist/indexer/name-lookup-policies/implicit-self.d.ts +10 -0
  198. package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -0
  199. package/dist/indexer/name-lookup-policies/implicit-self.js +113 -0
  200. package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -0
  201. package/dist/indexer/name-lookup-policies/index.d.ts +3 -0
  202. package/dist/indexer/name-lookup-policies/index.d.ts.map +1 -0
  203. package/dist/indexer/name-lookup-policies/index.js +106 -0
  204. package/dist/indexer/name-lookup-policies/index.js.map +1 -0
  205. package/dist/indexer/name-lookup-policies/php.d.ts +3 -0
  206. package/dist/indexer/name-lookup-policies/php.d.ts.map +1 -0
  207. package/dist/indexer/name-lookup-policies/php.js +75 -0
  208. package/dist/indexer/name-lookup-policies/php.js.map +1 -0
  209. package/dist/indexer/name-resolution-types.d.ts +99 -0
  210. package/dist/indexer/name-resolution-types.d.ts.map +1 -0
  211. package/dist/indexer/name-resolution-types.js +2 -0
  212. package/dist/indexer/name-resolution-types.js.map +1 -0
  213. package/dist/indexer/name-resolution.d.ts +52 -0
  214. package/dist/indexer/name-resolution.d.ts.map +1 -0
  215. package/dist/indexer/name-resolution.js +189 -0
  216. package/dist/indexer/name-resolution.js.map +1 -0
  217. package/dist/indexer/navigation-cpp.d.ts +50 -0
  218. package/dist/indexer/navigation-cpp.d.ts.map +1 -0
  219. package/dist/indexer/navigation-cpp.js +654 -0
  220. package/dist/indexer/navigation-cpp.js.map +1 -0
  221. package/dist/indexer/navigation-goto.d.ts +107 -4
  222. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  223. package/dist/indexer/navigation-goto.js +2075 -137
  224. package/dist/indexer/navigation-goto.js.map +1 -1
  225. package/dist/indexer/navigation-local.d.ts +18 -2
  226. package/dist/indexer/navigation-local.d.ts.map +1 -1
  227. package/dist/indexer/navigation-local.js +498 -61
  228. package/dist/indexer/navigation-local.js.map +1 -1
  229. package/dist/indexer/navigation-php.d.ts +66 -0
  230. package/dist/indexer/navigation-php.d.ts.map +1 -1
  231. package/dist/indexer/navigation-php.js +287 -4
  232. package/dist/indexer/navigation-php.js.map +1 -1
  233. package/dist/indexer/navigation-references.d.ts +72 -5
  234. package/dist/indexer/navigation-references.d.ts.map +1 -1
  235. package/dist/indexer/navigation-references.js +620 -54
  236. package/dist/indexer/navigation-references.js.map +1 -1
  237. package/dist/indexer/navigation-resolve.d.ts +33 -2
  238. package/dist/indexer/navigation-resolve.d.ts.map +1 -1
  239. package/dist/indexer/navigation-resolve.js +446 -193
  240. package/dist/indexer/navigation-resolve.js.map +1 -1
  241. package/dist/indexer/navigation.d.ts +28 -2
  242. package/dist/indexer/navigation.d.ts.map +1 -1
  243. package/dist/indexer/navigation.js +1082 -151
  244. package/dist/indexer/navigation.js.map +1 -1
  245. package/dist/indexer/php-namespace-symbols.d.ts +66 -0
  246. package/dist/indexer/php-namespace-symbols.d.ts.map +1 -0
  247. package/dist/indexer/php-namespace-symbols.js +342 -0
  248. package/dist/indexer/php-namespace-symbols.js.map +1 -0
  249. package/dist/indexer/reference-context.d.ts +2 -0
  250. package/dist/indexer/reference-context.d.ts.map +1 -1
  251. package/dist/indexer/reference-context.js +4 -0
  252. package/dist/indexer/reference-context.js.map +1 -1
  253. package/dist/indexer/scope-nodes.d.ts +92 -13
  254. package/dist/indexer/scope-nodes.d.ts.map +1 -1
  255. package/dist/indexer/scope-nodes.js +212 -20
  256. package/dist/indexer/scope-nodes.js.map +1 -1
  257. package/dist/indexer/scope-types.d.ts +25 -1
  258. package/dist/indexer/scope-types.d.ts.map +1 -1
  259. package/dist/indexer/scope.d.ts.map +1 -1
  260. package/dist/indexer/scope.js +894 -45
  261. package/dist/indexer/scope.js.map +1 -1
  262. package/dist/indexer/shared-owner-identity.d.ts +53 -0
  263. package/dist/indexer/shared-owner-identity.d.ts.map +1 -0
  264. package/dist/indexer/shared-owner-identity.js +460 -0
  265. package/dist/indexer/shared-owner-identity.js.map +1 -0
  266. package/dist/indexer/shared.d.ts +1 -1
  267. package/dist/indexer/shared.d.ts.map +1 -1
  268. package/dist/indexer/shared.js +1 -1
  269. package/dist/indexer/shared.js.map +1 -1
  270. package/dist/indexer/star-import-precedence.d.ts +114 -0
  271. package/dist/indexer/star-import-precedence.d.ts.map +1 -0
  272. package/dist/indexer/star-import-precedence.js +396 -0
  273. package/dist/indexer/star-import-precedence.js.map +1 -0
  274. package/dist/indexer/symbols.d.ts +3 -1
  275. package/dist/indexer/symbols.d.ts.map +1 -1
  276. package/dist/indexer/symbols.js +58 -18
  277. package/dist/indexer/symbols.js.map +1 -1
  278. package/dist/indexer/ts-callables.d.ts +51 -0
  279. package/dist/indexer/ts-callables.d.ts.map +1 -0
  280. package/dist/indexer/ts-callables.js +264 -0
  281. package/dist/indexer/ts-callables.js.map +1 -0
  282. package/dist/indexer/types.d.ts +23 -1
  283. package/dist/indexer/types.d.ts.map +1 -1
  284. package/dist/indexer/unused-exports.d.ts +13 -0
  285. package/dist/indexer/unused-exports.d.ts.map +1 -0
  286. package/dist/indexer/unused-exports.js +159 -0
  287. package/dist/indexer/unused-exports.js.map +1 -0
  288. package/dist/indexer/workspace-symbols.d.ts.map +1 -1
  289. package/dist/indexer/workspace-symbols.js +3 -2
  290. package/dist/indexer/workspace-symbols.js.map +1 -1
  291. package/dist/indexer.d.ts +2 -2
  292. package/dist/indexer.d.ts.map +1 -1
  293. package/dist/indexer.js +1 -1
  294. package/dist/indexer.js.map +1 -1
  295. package/dist/languages/callable-arity.d.ts +202 -0
  296. package/dist/languages/callable-arity.d.ts.map +1 -0
  297. package/dist/languages/callable-arity.js +1182 -0
  298. package/dist/languages/callable-arity.js.map +1 -0
  299. package/dist/languages/definitions/c-family.d.ts.map +1 -1
  300. package/dist/languages/definitions/c-family.js +30 -1
  301. package/dist/languages/definitions/c-family.js.map +1 -1
  302. package/dist/languages/definitions/c.d.ts +4 -0
  303. package/dist/languages/definitions/c.d.ts.map +1 -1
  304. package/dist/languages/definitions/c.js +19 -0
  305. package/dist/languages/definitions/c.js.map +1 -1
  306. package/dist/languages/definitions/cpp.d.ts.map +1 -1
  307. package/dist/languages/definitions/cpp.js +12 -0
  308. package/dist/languages/definitions/cpp.js.map +1 -1
  309. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  310. package/dist/languages/definitions/csharp.js +2 -8
  311. package/dist/languages/definitions/csharp.js.map +1 -1
  312. package/dist/languages/definitions/go.d.ts.map +1 -1
  313. package/dist/languages/definitions/go.js +3 -0
  314. package/dist/languages/definitions/go.js.map +1 -1
  315. package/dist/languages/definitions/javascript.d.ts.map +1 -1
  316. package/dist/languages/definitions/javascript.js +10 -1
  317. package/dist/languages/definitions/javascript.js.map +1 -1
  318. package/dist/languages/definitions/js-family.d.ts +1 -1
  319. package/dist/languages/definitions/js-family.d.ts.map +1 -1
  320. package/dist/languages/definitions/js-family.js +7 -1
  321. package/dist/languages/definitions/js-family.js.map +1 -1
  322. package/dist/languages/definitions/php.d.ts.map +1 -1
  323. package/dist/languages/definitions/php.js +5 -1
  324. package/dist/languages/definitions/php.js.map +1 -1
  325. package/dist/languages/definitions/typescript.d.ts.map +1 -1
  326. package/dist/languages/definitions/typescript.js +8 -1
  327. package/dist/languages/definitions/typescript.js.map +1 -1
  328. package/dist/languages/definitions/zig.d.ts.map +1 -1
  329. package/dist/languages/definitions/zig.js +2 -0
  330. package/dist/languages/definitions/zig.js.map +1 -1
  331. package/dist/mcp/handlers.js +14 -7
  332. package/dist/mcp/handlers.js.map +1 -1
  333. package/dist/review/candidates.d.ts.map +1 -1
  334. package/dist/review/candidates.js +1 -1
  335. package/dist/review/candidates.js.map +1 -1
  336. package/dist/review/deleted.d.ts +3 -3
  337. package/dist/review/deleted.d.ts.map +1 -1
  338. package/dist/review/deleted.js +82 -32
  339. package/dist/review/deleted.js.map +1 -1
  340. package/dist/review/report.d.ts +1 -0
  341. package/dist/review/report.d.ts.map +1 -1
  342. package/dist/review/report.js +1 -1
  343. package/dist/review/report.js.map +1 -1
  344. package/dist/review.d.ts.map +1 -1
  345. package/dist/review.js +1 -0
  346. package/dist/review.js.map +1 -1
  347. package/dist/sql/navigation.d.ts.map +1 -1
  348. package/dist/sql/navigation.js +1 -0
  349. package/dist/sql/navigation.js.map +1 -1
  350. package/dist/sql/source-graph.d.ts.map +1 -1
  351. package/dist/sql/source-graph.js +2 -2
  352. package/dist/sql/source-graph.js.map +1 -1
  353. package/dist/sqlite/schema.d.ts +1 -1
  354. package/dist/sqlite/schema.d.ts.map +1 -1
  355. package/dist/sqlite/schema.js +8 -2
  356. package/dist/sqlite/schema.js.map +1 -1
  357. package/dist/sqlite/write.js +2 -2
  358. package/dist/sqlite/write.js.map +1 -1
  359. package/dist/types.d.ts +2 -0
  360. package/dist/types.d.ts.map +1 -1
  361. package/dist/util/bloom-filter.d.ts +7 -1
  362. package/dist/util/bloom-filter.d.ts.map +1 -1
  363. package/dist/util/bloom-filter.js +12 -2
  364. package/dist/util/bloom-filter.js.map +1 -1
  365. package/dist/util/dynamic-import-tables.d.ts +88 -0
  366. package/dist/util/dynamic-import-tables.d.ts.map +1 -0
  367. package/dist/util/dynamic-import-tables.js +100 -0
  368. package/dist/util/dynamic-import-tables.js.map +1 -0
  369. package/dist/util/graph-edges.d.ts +19 -1
  370. package/dist/util/graph-edges.d.ts.map +1 -1
  371. package/dist/util/graph-edges.js +30 -4
  372. package/dist/util/graph-edges.js.map +1 -1
  373. package/dist/util/identifiers.d.ts +15 -0
  374. package/dist/util/identifiers.d.ts.map +1 -1
  375. package/dist/util/identifiers.js +35 -0
  376. package/dist/util/identifiers.js.map +1 -1
  377. package/dist/util/member-access-tables.d.ts +129 -0
  378. package/dist/util/member-access-tables.d.ts.map +1 -0
  379. package/dist/util/member-access-tables.js +285 -0
  380. package/dist/util/member-access-tables.js.map +1 -0
  381. package/dist/util/member-access.d.ts +17 -0
  382. package/dist/util/member-access.d.ts.map +1 -1
  383. package/dist/util/member-access.js +138 -93
  384. package/dist/util/member-access.js.map +1 -1
  385. package/dist/util/resolution/cargo-targets.d.ts +11 -0
  386. package/dist/util/resolution/cargo-targets.d.ts.map +1 -1
  387. package/dist/util/resolution/cargo-targets.js +174 -13
  388. package/dist/util/resolution/cargo-targets.js.map +1 -1
  389. package/dist/util/resolution/csharp.d.ts +33 -1
  390. package/dist/util/resolution/csharp.d.ts.map +1 -1
  391. package/dist/util/resolution/csharp.js +145 -30
  392. package/dist/util/resolution/csharp.js.map +1 -1
  393. package/dist/util/resolution/php.d.ts.map +1 -1
  394. package/dist/util/resolution/php.js +35 -8
  395. package/dist/util/resolution/php.js.map +1 -1
  396. package/dist/util/resolution/python.d.ts +9 -0
  397. package/dist/util/resolution/python.d.ts.map +1 -1
  398. package/dist/util/resolution/python.js +46 -0
  399. package/dist/util/resolution/python.js.map +1 -1
  400. package/dist/util/resolution/rust.d.ts.map +1 -1
  401. package/dist/util/resolution/rust.js +95 -26
  402. package/dist/util/resolution/rust.js.map +1 -1
  403. package/dist/util/resolution-candidates.d.ts +5 -0
  404. package/dist/util/resolution-candidates.d.ts.map +1 -1
  405. package/dist/util/resolution-candidates.js +16 -3
  406. package/dist/util/resolution-candidates.js.map +1 -1
  407. package/dist/util/resolution.d.ts +2 -1
  408. package/dist/util/resolution.d.ts.map +1 -1
  409. package/dist/util/resolution.js +96 -5
  410. package/dist/util/resolution.js.map +1 -1
  411. package/dist/util/specifiers.d.ts +20 -0
  412. package/dist/util/specifiers.d.ts.map +1 -1
  413. package/dist/util/specifiers.js +39 -93
  414. package/dist/util/specifiers.js.map +1 -1
  415. package/docs/mcp.md +3 -2
  416. package/package.json +3 -3
@@ -9,7 +9,9 @@ import { loadWorkspaceConfig, resolveWorkspacePackage } from "../util/workspace.
9
9
  import { DEFAULT_PROJECT_PATTERNS, createProjectDiscoveryContext, discoverProjectFilesWithGitCandidates, listProjectFilesWithGitCandidates, } from "../util/project-files.js";
10
10
  import { getGitHead, isGitRepo, getGitBlobHashes, listChangedFiles } from "../util/git.js";
11
11
  import { clearResolutionCaches, loadNearestTsconfigFor, resolveSpecifier, } from "../util/resolution.js";
12
- import { collectCppDeclaredModules } from "../util/resolution/cpp.js";
12
+ import { collectCppDeclaredModules, isCppNamedModuleSpecifier } from "../util/resolution/cpp.js";
13
+ import { loadTsconfigResolutionInputsFor } from "../util/resolution/tsconfig.js";
14
+ import { resolveModuleSpecifierEdges } from "../graphs/edge-resolution.js";
13
15
  import { fileIdentityKey, initializeFileIdentityCaseSensitivity, isFilePathWithinRoot, normalizePath, } from "../util/paths.js";
14
16
  import { mapLimit } from "../util/concurrency.js";
15
17
  import { readConfinedUtf8File } from "../util/confined-file.js";
@@ -30,7 +32,7 @@ import { initNativeBackendReport } from "../native/native-backend-report.js";
30
32
  import { closeDuplicateUnitCacheDatabase } from "../duplicates.js";
31
33
  import { isNativeRequiredUnavailableError } from "../native/tree-sitter-native.js";
32
34
  import { isNodeSqliteUnavailableError } from "../sqlite-driver.js";
33
- import { buildBloomFilterForFile, cacheSignatureForFile, closeDiskCacheDatabase, diskModuleCacheExists, collectWorkspaceManifestDependencyEdges, computeConfigHash, createFallbackImportExtractionHandler, diffBuildOptions, fileSignature, fileSignatureFromSource, graphOptionsEqual, initFileReport, initManifestReport, loadManifest, normalizeGraphOptions, normalizeIndexedFileInputs, normalizeIndexedFileInputsWithinRoot, normalizeLanguageExtensions, projectSnapshotFilesSignature, recordConfigHashResult, recordFileFailure, sanitizeManifestEntriesForRoot, sanitizeManifestTransientFilesForRoot, tryLoadFromCache, tryLoadPersistedBloomFilters, tryLoadProjectIndexSnapshot, tryLoadProjectSnapshotModules, verifyManifestEntries, writeModulesToCache, writeProjectIndexSnapshot, } from "./build-cache.js";
35
+ import { buildBloomFilterForFile, cacheSignatureForFile, closeDiskCacheDatabase, diskModuleCacheExists, collectWorkspaceManifestDependencyEdges, computeConfigHash, createFallbackImportExtractionHandler, diffBuildOptions, fileSignature, fileSignatureFromSource, graphOptionsEqual, initFileReport, initManifestReport, loadManifest, normalizeGraphOptions, normalizeIndexedFileInputs, normalizeIndexedFileInputsWithinRoot, normalizeLanguageExtensions, projectSnapshotFilesSignature, recordConfigHashResult, recordFileFailure, sanitizeManifestEntriesForRoot, sanitizeManifestTransientFilesForRoot, listDiskCachedModuleFiles, listMemoryCachedModuleFiles, loadModuleFromCache, memoryCacheEvictionSerial, memoryCacheLostPayloads, peekCachedModule, removeModulesFromCache, settleMemoryCacheEvictions, tryLoadFromCache, tryLoadPersistedBloomFilters, tryLoadProjectIndexSnapshot, tryLoadProjectSnapshotModules, verifyManifestEntries, writeModulesToCache, writeProjectIndexSnapshot, } from "./build-cache.js";
34
36
  import { computeResolverEnvironmentFingerprint } from "./build-cache/resolver-environment.js";
35
37
  import { cacheRoot } from "./build-cache/location.js";
36
38
  import { SymbolKind, } from "./types.js";
@@ -39,7 +41,7 @@ import { buildSqlFactCache, buildSqlModuleIndex, sqlCorpusSignature } from "../s
39
41
  import { finalizeProjectIndex } from "./finalize.js";
40
42
  import { toManifestFileEntry, writeIndexManifestSnapshot } from "./build-manifest.js";
41
43
  import { prepareFileContextForBuild, countNativeWorkerEligibleFiles, emptyWorkerPoolSetup, setupWorkerPool, teardownWorkerPool, } from "./build-workers.js";
42
- import { buildIncrementalGitDiffOptions, canUseIncrementalDiscoveryFastPath, buildTrackedFileReverseDependencies, collectDeletedTrackedFileDependents, collectTrackedFileDependents, isMissingGitRevisionError, listUntrackedProjectFiles, partitionTrackedManifestFiles, probePathExistence, } from "./incremental-plan.js";
44
+ import { buildIncrementalGitDiffOptions, canUseIncrementalDiscoveryFastPath, buildTrackedFileReverseDependencies, addedResolutionStems, collectDeletedTrackedFileDependents, collectTrackedFileDependents, collectSpecifierEdgeCandidates, collectPythonPackageImporters, pythonImportersOfPackageInits, externalSpecifierMatchesAddedStem, tsconfigAliasMappedTails, isMissingGitRevisionError, listUntrackedProjectFiles, partitionTrackedManifestFiles, probePathExistence, } from "./incremental-plan.js";
43
45
  import { parsedCacheMaxEntries, setParsedCacheEntry } from "./parsed-cache.js";
44
46
  function initParserBackendDegradationReport(report) {
45
47
  if (!report)
@@ -147,6 +149,114 @@ function manifestDeclaredContainerIndex(manifest) {
147
149
  return new Map();
148
150
  return new Map(Object.entries(entries));
149
151
  }
152
+ /**
153
+ * Declared C++ modules of added or changed files. The cache cannot supply them.
154
+ * A regex over the source finds them without a parse.
155
+ * Without them, a second file that declares an existing module name goes unnoticed,
156
+ * and the importer keeps its old target.
157
+ */
158
+ async function collectCppMissDeclaredContainers(files, concurrency, confined) {
159
+ const byName = new Map();
160
+ await mapLimit([...files], concurrency, async (file) => {
161
+ let source = confined?.trustedSources?.get(file);
162
+ if (source === undefined) {
163
+ try {
164
+ source =
165
+ confined?.confinedRoot && confined?.projectRoot
166
+ ? await readConfinedUtf8File(confined.confinedRoot, confined.projectRoot, file)
167
+ : await fsp.readFile(file, "utf8");
168
+ }
169
+ catch {
170
+ return;
171
+ }
172
+ }
173
+ for (const name of collectCppDeclaredModules(source)) {
174
+ let bucket = byName.get(name);
175
+ if (!bucket)
176
+ byName.set(name, (bucket = new Set()));
177
+ bucket.add(normalizePath(file));
178
+ }
179
+ });
180
+ const index = new Map();
181
+ for (const [name, declaringFiles] of byName) {
182
+ index.set(name, [...declaringFiles].sort((left, right) => left.localeCompare(right)));
183
+ }
184
+ return index;
185
+ }
186
+ /** Declared C++ modules in the previous rows of changed files, as module name to declaring files. */
187
+ function previousCppDeclaredContainers(previousModules) {
188
+ const byName = new Map();
189
+ for (const [file, mod] of previousModules)
190
+ mergeDeclaredContainers(byName, file, mod.declaredContainers);
191
+ return byName;
192
+ }
193
+ /** Fold one file's declared containers into name-to-declaring-files buckets. */
194
+ function mergeDeclaredContainers(byName, file, declared) {
195
+ if (!declared || !declared.length)
196
+ return;
197
+ const normalized = normalizePath(file);
198
+ for (const name of declared) {
199
+ let bucket = byName.get(name);
200
+ if (!bucket)
201
+ byName.set(name, (bucket = new Set()));
202
+ bucket.add(normalized);
203
+ }
204
+ }
205
+ /** Sort name-to-declaring-files buckets into the shape declaredContainerNamesChanged compares. */
206
+ function sortedDeclaredContainerIndex(byName) {
207
+ const index = new Map();
208
+ for (const [name, files] of byName) {
209
+ index.set(name, [...files].sort((left, right) => left.localeCompare(right)));
210
+ }
211
+ return index;
212
+ }
213
+ /** Whether a cached module has an import binding the previous build left unresolved. */
214
+ function cachedModuleHasExternalImport(mod) {
215
+ return mod.imports.some((binding) => typeof binding.resolved !== "string");
216
+ }
217
+ /**
218
+ * Declaration-language files that have a cached row, are not in the build, and no longer exist.
219
+ * A deleted file leaves no cache miss, so importers that it satisfied would stay stale.
220
+ * The existence probe separates deleted files from files outside the build scope.
221
+ * The manifest path does not need this: the manifest lists the previous files.
222
+ */
223
+ async function collectNoManifestDeletedDeclarationFiles(args) {
224
+ const live = new Set(args.files.map(fileIdentityKey));
225
+ const rows = new Map();
226
+ for (const file of listMemoryCachedModuleFiles(args.projectRoot))
227
+ rows.set(fileIdentityKey(file), file);
228
+ if ((args.opts?.cache ?? "off") === "disk") {
229
+ const diskFiles = listDiskCachedModuleFiles(args.projectRoot, args.opts);
230
+ if (diskFiles) {
231
+ for (const relative of diskFiles) {
232
+ const file = normalizePath(path.resolve(args.projectRoot, relative));
233
+ // A cache row is persisted data. Ignore a row that names a path outside the project.
234
+ if (!isFilePathWithinRoot(args.projectRoot, file))
235
+ continue;
236
+ if (!rows.has(fileIdentityKey(file)))
237
+ rows.set(fileIdentityKey(file), file);
238
+ }
239
+ }
240
+ }
241
+ const candidates = [];
242
+ for (const [key, file] of rows) {
243
+ if (live.has(key))
244
+ continue;
245
+ const languageId = supportForFileWithoutHeaderSample(file, args.opts?.languageExtensions)?.id;
246
+ if (languageId && DECLARATION_RESOLVED_IMPORT_LANGUAGES.has(languageId))
247
+ candidates.push({ file, languageId });
248
+ }
249
+ if (!candidates.length)
250
+ return [];
251
+ const existence = await probePathExistence(candidates.map((candidate) => candidate.file), args.concurrency);
252
+ return candidates
253
+ .filter((candidate) => !existence.get(candidate.file))
254
+ .map((candidate) => ({
255
+ file: candidate.file,
256
+ languageId: candidate.languageId,
257
+ mod: peekCachedModule(args.projectRoot, candidate.file, args.opts)?.mod ?? null,
258
+ }));
259
+ }
150
260
  async function resolveCrossModuleSymbolExports(file, mod, support, projectRoot, graphOptions, workspaceConfig, matchPath) {
151
261
  if (!support.supportsCrossModuleSymbols || !isJsTsLanguage(support.id))
152
262
  return;
@@ -324,9 +434,102 @@ function ensureJsonModule(modules, filePath) {
324
434
  });
325
435
  }
326
436
  function graphEdgeKey(edge) {
327
- const from = fileIdentityKey(edge.from);
328
- const target = edge.to.type === "file" ? `file:${fileIdentityKey(edge.to.path)}` : `external:${edge.to.name}`;
329
- return `${from}::${target}::${edge.raw ?? ""}::${edge.typeOnly ? 1 : 0}`;
437
+ return edgeKey(edge, true, fileIdentityKey);
438
+ }
439
+ function externalEdgeTargetKey(to) {
440
+ return to.type === "file" ? `file:${fileIdentityKey(to.path)}` : `external:${to.name}`;
441
+ }
442
+ const PRECISE_SPECIFIER_RESOLUTION_LANGUAGES = {
443
+ c: true,
444
+ cpp: true,
445
+ js: true,
446
+ jsx: true,
447
+ python: true,
448
+ ts: true,
449
+ tsx: true,
450
+ };
451
+ async function specifierResolutionChanged(file, entry, projectRoot, workspaceConfig, graphOptions, languageExtensions, loadMatchPath, addedFiles, addedStemsForLanguage, loadTsconfigPaths) {
452
+ const support = supportForFileWithoutHeaderSample(file, languageExtensions);
453
+ if (!support)
454
+ return false;
455
+ // Declaration languages re-resolve through the extension rule in externalSpecifierMatchesAddedStem,
456
+ // so no filename stems are needed here.
457
+ const addedStems = addedStemsForLanguage(support.id);
458
+ const addedFileLanguageId = (file) => supportForFileWithoutHeaderSample(file, languageExtensions)?.id;
459
+ const specifierEdges = entry.edges;
460
+ if (!specifierEdges.length)
461
+ return false;
462
+ const specifierOf = (edge) => (edge.to.type === "external" ? edge.raw || edge.to.name : edge.raw);
463
+ const matching = [];
464
+ const needsAlias = [];
465
+ for (const edge of specifierEdges) {
466
+ const specifier = specifierOf(edge);
467
+ if (externalSpecifierMatchesAddedStem(specifier, support.id, addedStems, [], addedFiles, addedFileLanguageId)) {
468
+ matching.push(edge);
469
+ continue;
470
+ }
471
+ const relative = specifier.startsWith(".") || specifier.startsWith("/") || /^[A-Za-z]:[\\/]/.test(specifier);
472
+ if ((support.id === "ts" || support.id === "tsx") && specifier && !relative)
473
+ needsAlias.push(edge);
474
+ }
475
+ if (needsAlias.length) {
476
+ const paths = await loadTsconfigPaths(file);
477
+ if (paths && Object.keys(paths).length) {
478
+ for (const edge of needsAlias) {
479
+ const mapped = tsconfigAliasMappedTails(specifierOf(edge), paths);
480
+ if (mapped.length &&
481
+ externalSpecifierMatchesAddedStem(specifierOf(edge), support.id, addedStems, mapped, addedFiles, addedFileLanguageId)) {
482
+ matching.push(edge);
483
+ }
484
+ }
485
+ }
486
+ }
487
+ if (!matching.length)
488
+ return false;
489
+ // Stylesheet, document, and other unstored per-occurrence inputs cannot be
490
+ // re-resolved from the edge. The caller only reaches this on an add.
491
+ if (!PRECISE_SPECIFIER_RESOLUTION_LANGUAGES[support.id])
492
+ return true;
493
+ if ((support.id === "c" || support.id === "cpp") &&
494
+ matching.some((edge) => edge.includeForm === undefined && !isCppNamedModuleSpecifier(edge.raw))) {
495
+ return true;
496
+ }
497
+ const matchPath = support.id === "ts" || support.id === "tsx" ? await loadMatchPath(file) : undefined;
498
+ const groups = new Map();
499
+ for (const edge of matching) {
500
+ const key = `${edge.raw}\0${edge.includeForm ?? ""}\0${edge.typeOnly ? 1 : 0}`;
501
+ const group = groups.get(key);
502
+ if (group)
503
+ group.push(edge);
504
+ else
505
+ groups.set(key, [edge]);
506
+ }
507
+ for (const group of groups.values()) {
508
+ const sample = group[0];
509
+ const resolved = await resolveModuleSpecifierEdges({
510
+ spec: sample.raw,
511
+ ...(sample.typeOnly ? { typeOnly: true } : {}),
512
+ ...(sample.includeForm ? { includeForm: sample.includeForm } : {}),
513
+ }, {
514
+ support,
515
+ file,
516
+ projectRoot,
517
+ workspaceConfig,
518
+ matchPath,
519
+ resolveNodeModules: !!graphOptions.resolveNodeModules,
520
+ ...(graphOptions.resolutionHints ? { resolutionHints: graphOptions.resolutionHints } : {}),
521
+ ...(languageExtensions ? { languageExtensions } : {}),
522
+ });
523
+ const resolvedKeys = (resolved ?? []).map((item) => externalEdgeTargetKey(item.to)).sort();
524
+ const cachedKeys = group.map((edge) => externalEdgeTargetKey(edge.to)).sort();
525
+ if (resolvedKeys.length !== cachedKeys.length)
526
+ return true;
527
+ for (let index = 0; index < resolvedKeys.length; index += 1) {
528
+ if (resolvedKeys[index] !== cachedKeys[index])
529
+ return true;
530
+ }
531
+ }
532
+ return false;
330
533
  }
331
534
  async function moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint) {
332
535
  const baseSignature = await cacheSignatureForFile(file, sigInfo, opts);
@@ -551,6 +754,260 @@ async function prepareFileSignatures(args) {
551
754
  async function buildProjectIndexFromExport(projectRoot, opts, helperOpts) {
552
755
  return buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpts);
553
756
  }
757
+ /**
758
+ * Cached modules to extract again because something they depend on changed.
759
+ * A cached module is keyed by its own content, but its import bindings depend on other files.
760
+ * A module is stale when:
761
+ * - it changed;
762
+ * - an import or re-export target no longer exists;
763
+ * - an added file can satisfy one of its specifiers;
764
+ * - it resolves imports through namespace or package declarations, and a file it depends on changed.
765
+ *
766
+ * With a manifest, the manifest gives the previous files and edges.
767
+ * Without one (a memory cache, or a disk cache that no manifest-writing build has seen),
768
+ * the cached import bindings replace the edges.
769
+ */
770
+ async function collectStaleCachedModules(args) {
771
+ const { cachedModules, manifestFiles } = args;
772
+ if (!cachedModules.size)
773
+ return { stale: new Set(), deletedDeclarationFiles: [] };
774
+ const stale = await cachedModulesWithMissingTargets(cachedModules, args.concurrency);
775
+ const resolvesFromDeclarations = (file) => DECLARATION_RESOLVED_IMPORT_LANGUAGES.has(supportForFileWithoutHeaderSample(file, args.opts?.languageExtensions)?.id ?? "");
776
+ const loadTsconfigPaths = (importer) => loadTsconfigResolutionInputsFor(importer, args.projectRoot, args.opts?.logLevel).then((inputs) => inputs?.paths);
777
+ // Deleted declaration files. Only the no-manifest path fills this list.
778
+ // The manifest path retires deletions when it rewrites the manifest.
779
+ const deletedDeclarationFiles = [];
780
+ if (manifestFiles) {
781
+ const currentKeys = new Set(args.files.map(fileIdentityKey));
782
+ // A cache miss proves a change, even when a non-strict manifest signature (mtime:size) matches.
783
+ const changed = new Set(args.cacheMisses.changed);
784
+ const added = [];
785
+ for (const file of args.files) {
786
+ const entry = manifestFiles[file];
787
+ if (!entry)
788
+ added.push(file);
789
+ const sigInfo = args.signatures.get(file);
790
+ if (!sigInfo)
791
+ continue;
792
+ const matchesGitSig = !!entry?.gitSig && !!sigInfo.gitSig && entry.gitSig === sigInfo.gitSig;
793
+ if (!entry || !(matchesGitSig || entry.sig === sigInfo.sig))
794
+ changed.add(file);
795
+ }
796
+ // Cache hits do not hold the declarations of added or changed files.
797
+ // Add the C++ module declarations of those files before the comparison.
798
+ // Otherwise a second file that declares an existing module name changes nothing,
799
+ // and the importer keeps its old target.
800
+ const nextDeclaredContainers = declaredContainerIndexFromModules([...cachedModules.values()].map((cached) => cached.mod));
801
+ const cppMisses = [...new Set([...added, ...changed])].filter((file) => supportForFileWithoutHeaderSample(file, args.opts?.languageExtensions)?.id === "cpp");
802
+ if (cppMisses.length) {
803
+ const missDeclaredContainers = await collectCppMissDeclaredContainers(cppMisses, args.concurrency, {
804
+ ...(args.confinedRoot ? { confinedRoot: args.confinedRoot, projectRoot: args.projectRoot } : {}),
805
+ ...(args.trustedSources ? { trustedSources: args.trustedSources } : {}),
806
+ });
807
+ for (const [name, declaringFiles] of missDeclaredContainers) {
808
+ const merged = new Set([...(nextDeclaredContainers.get(name) ?? []), ...declaringFiles]);
809
+ nextDeclaredContainers.set(name, [...merged].sort((left, right) => left.localeCompare(right)));
810
+ }
811
+ }
812
+ const declaredContainerConsumers = collectDeclaredContainerConsumers(manifestFiles, declaredContainerNamesChanged(manifestDeclaredContainerIndex(args.manifest), nextDeclaredContainers));
813
+ const missingFromBuild = Object.keys(manifestFiles).filter((file) => !currentKeys.has(fileIdentityKey(file)));
814
+ const existence = await probePathExistence(missingFromBuild, args.concurrency);
815
+ const deleted = new Set(missingFromBuild.filter((file) => !existence.get(file)));
816
+ for (const file of [
817
+ ...changed,
818
+ ...collectDeletedTrackedFileDependents(manifestFiles, deleted),
819
+ ...declaredContainerConsumers,
820
+ ]) {
821
+ stale.add(file);
822
+ }
823
+ for (const file of collectTrackedFileDependents(manifestFiles, changed)) {
824
+ if (resolvesFromDeclarations(file))
825
+ stale.add(file);
826
+ }
827
+ // A changed or deleted declaration-language file can change which files declare a namespace
828
+ // or package that an importer names. A deleted duplicate can resolve an ambiguous import.
829
+ // Treat these files like added files.
830
+ const resolutionInputs = [...added, ...[...changed, ...deleted].filter((file) => resolvesFromDeclarations(file))];
831
+ if (resolutionInputs.length) {
832
+ const stemsByLanguage = new Map();
833
+ const addedStemsForLanguage = (languageId) => {
834
+ let stems = stemsByLanguage.get(languageId);
835
+ if (!stems)
836
+ stemsByLanguage.set(languageId, (stems = addedResolutionStems(resolutionInputs, languageId)));
837
+ return stems;
838
+ };
839
+ const candidates = [...collectSpecifierEdgeCandidates(manifestFiles, true)].filter((file) => cachedModules.has(file) && !stale.has(file));
840
+ const changedResolution = await mapLimit(candidates, args.concurrency, async (candidate) => specifierResolutionChanged(candidate, manifestFiles[candidate], args.projectRoot, args.workspaceConfig, args.graphOptions, args.opts?.languageExtensions, args.loadMatchPathForFile, resolutionInputs, addedStemsForLanguage, loadTsconfigPaths));
841
+ candidates.forEach((candidate, index) => {
842
+ if (changedResolution[index])
843
+ stale.add(candidate);
844
+ });
845
+ for (const importer of collectPythonPackageImporters(manifestFiles, added))
846
+ stale.add(importer);
847
+ }
848
+ }
849
+ else {
850
+ const added = [
851
+ ...args.cacheMisses.added,
852
+ ...args.cacheMisses.changed.filter((file) => resolvesFromDeclarations(file)),
853
+ ];
854
+ if (added.length) {
855
+ const stemsByLanguage = new Map();
856
+ for (const [file, { mod }] of cachedModules) {
857
+ if (stale.has(file))
858
+ continue;
859
+ const languageId = supportForFileWithoutHeaderSample(file, args.opts?.languageExtensions)?.id ?? "default";
860
+ let stems = stemsByLanguage.get(languageId);
861
+ if (!stems)
862
+ stemsByLanguage.set(languageId, (stems = addedResolutionStems(added, languageId)));
863
+ const tsconfigPaths = languageId === "ts" || languageId === "tsx" ? await loadTsconfigPaths(file) : undefined;
864
+ const addedCanSatisfy = cachedModuleSpecifiers(mod).some((specifier) => externalSpecifierMatchesAddedStem(specifier, languageId, stems, tsconfigPaths ? tsconfigAliasMappedTails(specifier, tsconfigPaths) : [], added, (file) => supportForFileWithoutHeaderSample(file, args.opts?.languageExtensions)?.id));
865
+ if (addedCanSatisfy)
866
+ stale.add(file);
867
+ }
868
+ // `from . import mod` targets `__init__.py`, so no specifier names an added `mod.py`.
869
+ // Find these importers through their cached targets.
870
+ const packageImporters = pythonImportersOfPackageInits(Array.from(cachedModules, ([file, { mod }]) => [file, cachedModuleTargets(mod)]), added);
871
+ for (const file of packageImporters)
872
+ stale.add(file);
873
+ }
874
+ // C++ module specifiers name declarations, not file stems. The stem check cannot see
875
+ // a second declarer, a file that stopped declaring a module, or a deleted declarer.
876
+ // A deleted file leaves no cache miss, so the rows of omitted files are scanned separately.
877
+ // Cache hits cancel out of the comparison. Only stale rows, deleted files, and misses change it.
878
+ const cppPrevious = previousCppDeclaredContainers(args.previousModules);
879
+ const unknownDeclarationLanguages = new Set();
880
+ for (const deleted of await collectNoManifestDeletedDeclarationFiles({
881
+ files: args.files,
882
+ projectRoot: args.projectRoot,
883
+ opts: args.opts,
884
+ concurrency: args.concurrency,
885
+ })) {
886
+ deletedDeclarationFiles.push(deleted.file);
887
+ if (deleted.languageId === "cpp" && deleted.mod && deleted.mod.declaredContainers) {
888
+ mergeDeclaredContainers(cppPrevious, deleted.file, deleted.mod.declaredContainers);
889
+ }
890
+ else {
891
+ unknownDeclarationLanguages.add(deleted.languageId);
892
+ }
893
+ }
894
+ // Some previous declarations are unknown when a payload was evicted,
895
+ // or when the old row of a changed file cannot be decoded.
896
+ // Re-resolve every cached importer of the affected languages.
897
+ // This is rare: eviction starts past the cache limit, where builds miss the cache anyway.
898
+ const unknownDeclarationHistory = new Set();
899
+ if ((args.opts?.cache ?? "off") === "memory" && memoryCacheLostPayloads(args.projectRoot)) {
900
+ for (const languageId of DECLARATION_RESOLVED_IMPORT_LANGUAGES)
901
+ unknownDeclarationHistory.add(languageId);
902
+ }
903
+ // An unmapped `.h` file is C or C++ by its content, so classify with `supportForFile`.
904
+ for (const file of args.previousUnavailable) {
905
+ const languageId = supportForFile(file, args.opts?.languageExtensions)?.id;
906
+ if (languageId && DECLARATION_RESOLVED_IMPORT_LANGUAGES.has(languageId)) {
907
+ unknownDeclarationHistory.add(languageId);
908
+ }
909
+ }
910
+ if (unknownDeclarationHistory.size) {
911
+ for (const [file, { mod }] of cachedModules) {
912
+ if (stale.has(file) || !mod.imports.length)
913
+ continue;
914
+ const languageId = supportForFile(file, args.opts?.languageExtensions)?.id ?? "";
915
+ if (unknownDeclarationHistory.has(languageId))
916
+ stale.add(file);
917
+ }
918
+ }
919
+ const cppAdded = added.filter((file) => supportForFileWithoutHeaderSample(file, args.opts?.languageExtensions)?.id === "cpp");
920
+ const missDeclaredContainers = cppAdded.length
921
+ ? await collectCppMissDeclaredContainers(cppAdded, args.concurrency, {
922
+ ...(args.confinedRoot ? { confinedRoot: args.confinedRoot, projectRoot: args.projectRoot } : {}),
923
+ ...(args.trustedSources ? { trustedSources: args.trustedSources } : {}),
924
+ })
925
+ : new Map();
926
+ const changedContainers = declaredContainerNamesChanged(sortedDeclaredContainerIndex(cppPrevious), missDeclaredContainers);
927
+ if (changedContainers.size || unknownDeclarationLanguages.size) {
928
+ for (const [file, { mod }] of cachedModules) {
929
+ if (stale.has(file))
930
+ continue;
931
+ if (changedContainers.size &&
932
+ cachedModuleSpecifiers(mod).some((specifier) => changedContainers.has(specifier))) {
933
+ stale.add(file);
934
+ continue;
935
+ }
936
+ if (unknownDeclarationLanguages.size) {
937
+ const languageId = supportForFile(file, args.opts?.languageExtensions)?.id ?? "default";
938
+ if (unknownDeclarationLanguages.has(languageId) && cachedModuleHasExternalImport(mod))
939
+ stale.add(file);
940
+ }
941
+ }
942
+ }
943
+ // The cached modules' own targets are the reverse dependencies.
944
+ const reverseDependencies = new Map();
945
+ for (const [file, { mod }] of cachedModules) {
946
+ for (const target of cachedModuleTargets(mod)) {
947
+ const key = fileIdentityKey(target);
948
+ let dependents = reverseDependencies.get(key);
949
+ if (!dependents)
950
+ reverseDependencies.set(key, (dependents = new Set()));
951
+ dependents.add(file);
952
+ }
953
+ }
954
+ const queue = args.cacheMisses.changed.map(fileIdentityKey);
955
+ const enqueued = new Set(queue);
956
+ for (let head = 0; head < queue.length; head += 1) {
957
+ for (const dependent of reverseDependencies.get(queue[head]) ?? []) {
958
+ if (resolvesFromDeclarations(dependent))
959
+ stale.add(dependent);
960
+ const key = fileIdentityKey(dependent);
961
+ if (enqueued.has(key))
962
+ continue;
963
+ enqueued.add(key);
964
+ queue.push(key);
965
+ }
966
+ }
967
+ }
968
+ return { stale, deletedDeclarationFiles };
969
+ }
970
+ /**
971
+ * Languages that resolve imports through the declarations of other files
972
+ * (C# namespaces, JVM packages, PHP namespaces, C++ named modules).
973
+ * A content change in a dependency can move the target.
974
+ */
975
+ const DECLARATION_RESOLVED_IMPORT_LANGUAGES = new Set(["cpp", "csharp", "java", "kotlin", "php"]);
976
+ /** Files a cached module resolved: import targets and re-export sources. */
977
+ function cachedModuleTargets(mod) {
978
+ const targets = mod.imports.flatMap((binding) => (typeof binding.resolved === "string" ? [binding.resolved] : []));
979
+ for (const entry of mod.exports) {
980
+ if (entry.type === "local" || !entry.moduleSpecifier || entry.fromModule === entry.moduleSpecifier)
981
+ continue;
982
+ targets.push(entry.fromModule);
983
+ }
984
+ return targets;
985
+ }
986
+ /** Specifiers a cached module wrote: import sources and re-export sources. */
987
+ function cachedModuleSpecifiers(mod) {
988
+ const specifiers = mod.imports.map((binding) => binding.from);
989
+ for (const entry of mod.exports) {
990
+ if (entry.type !== "local")
991
+ specifiers.push(entry.moduleSpecifier ?? entry.fromModule);
992
+ }
993
+ return specifiers;
994
+ }
995
+ /** Cached modules with a resolved import or re-export target that no longer exists. */
996
+ async function cachedModulesWithMissingTargets(cachedModules, concurrency) {
997
+ const targetsByFile = new Map();
998
+ for (const [file, { mod }] of cachedModules) {
999
+ const targets = cachedModuleTargets(mod);
1000
+ if (targets.length)
1001
+ targetsByFile.set(file, targets);
1002
+ }
1003
+ const targetExistence = await probePathExistence([...new Set([...targetsByFile.values()].flat())], concurrency);
1004
+ const missing = new Set();
1005
+ for (const [file, targets] of targetsByFile) {
1006
+ if (targets.some((target) => !targetExistence.get(target)))
1007
+ missing.add(file);
1008
+ }
1009
+ return missing;
1010
+ }
554
1011
  async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperOpts) {
555
1012
  clearResolutionCaches();
556
1013
  await initializeFileIdentityCaseSensitivity(projectRoot);
@@ -629,6 +1086,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
629
1086
  ? createCountedCheckProgress(opts, "Checking file cache", normalizedFiles.length)
630
1087
  : () => undefined;
631
1088
  const cacheProbeStart = performance.now();
1089
+ const evictionSerialAtStart = memoryCacheEvictionSerial();
632
1090
  const gitAvailable = await isGitRepo(projectRoot, helperOpts?.discoveryContext?.git);
633
1091
  const needsPersistentSignatures = cacheEnabled || useManifest;
634
1092
  const useGitSignatures = gitAvailable && needsPersistentSignatures;
@@ -702,10 +1160,10 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
702
1160
  ? await moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint)
703
1161
  : sigInfo.cacheSig;
704
1162
  const canReuseModuleCache = cacheEnabled && (!graphOptions.resolveNodeModules || resolverEnvironmentFingerprint !== null);
705
- const mod = canReuseModuleCache
706
- ? tryLoadFromCache(projectRoot, file, cacheSig, opts, report, moduleCacheAvailable)
707
- : null;
708
- return [file, { sigInfo, mod }];
1163
+ const loaded = canReuseModuleCache
1164
+ ? loadModuleFromCache(projectRoot, file, cacheSig, opts, report, moduleCacheAvailable)
1165
+ : { mod: null, previouslyCached: false, staleMod: null };
1166
+ return [file, { sigInfo, ...loaded }];
709
1167
  }
710
1168
  catch (error) {
711
1169
  return [file, { error }];
@@ -719,6 +1177,70 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
719
1177
  timings.cacheProbeMs = cacheProbeMs;
720
1178
  recordBuildTimingStep(timings, { name: "cache-probe", ms: cacheProbeMs });
721
1179
  }
1180
+ const tsconfigMatchPathByDirectory = new Map();
1181
+ const loadMatchPathForFile = (file) => {
1182
+ const directory = path.dirname(file);
1183
+ let matchPath = tsconfigMatchPathByDirectory.get(directory);
1184
+ if (!matchPath) {
1185
+ matchPath = loadNearestTsconfigFor(file, projectRoot, opts?.logLevel).then((tsconfig) => tsconfig.matchPath);
1186
+ tsconfigMatchPathByDirectory.set(directory, matchPath);
1187
+ }
1188
+ return matchPath;
1189
+ };
1190
+ let retiredDeletionFiles = [];
1191
+ // Set when a stale importer row could not be deleted. The build then keeps its previous disk
1192
+ // state (manifest, snapshot, deletion evidence), so the next build finds the same staleness.
1193
+ let staleRowRemovalFailed = false;
1194
+ if (cacheEnabled) {
1195
+ const cachedModules = new Map();
1196
+ const cacheMissesByState = { changed: [], added: [] };
1197
+ // The stale rows of changed files hold the previous declarations.
1198
+ // Deleted files leave no miss. The build finds their rows separately.
1199
+ const previousModules = new Map();
1200
+ const previousUnavailable = [];
1201
+ for (const [file, probe] of cacheProbes) {
1202
+ if ("error" in probe)
1203
+ continue;
1204
+ if (probe.mod)
1205
+ cachedModules.set(file, { sigInfo: probe.sigInfo, mod: probe.mod });
1206
+ else if (probe.previouslyCached) {
1207
+ cacheMissesByState.changed.push(file);
1208
+ if (probe.staleMod)
1209
+ previousModules.set(file, probe.staleMod);
1210
+ else
1211
+ previousUnavailable.push(file);
1212
+ }
1213
+ else
1214
+ cacheMissesByState.added.push(file);
1215
+ }
1216
+ const { stale: staleCachedModules, deletedDeclarationFiles: retiredDeletions } = await collectStaleCachedModules({
1217
+ files: normalizedFiles,
1218
+ cachedModules,
1219
+ cacheMisses: cacheMissesByState,
1220
+ previousModules,
1221
+ previousUnavailable,
1222
+ signatures: new Map(Array.from(cacheProbes, ([file, probe]) => ("error" in probe ? null : [file, probe.sigInfo])).filter((entry) => entry !== null)),
1223
+ manifestFiles: manifest ? manifestFiles : null,
1224
+ manifest,
1225
+ projectRoot,
1226
+ workspaceConfig,
1227
+ graphOptions,
1228
+ opts,
1229
+ loadMatchPathForFile,
1230
+ concurrency: conc,
1231
+ ...(confinedRoot ? { confinedRoot, trustedSources } : {}),
1232
+ });
1233
+ retiredDeletionFiles = retiredDeletions;
1234
+ // A stale importer's row still matches its source signature.
1235
+ // If the rebuild or the cache write fails, a later build would reuse the row. Delete it now.
1236
+ staleRowRemovalFailed = !removeModulesFromCache(projectRoot, [...staleCachedModules].filter((file) => cachedModules.has(file)), opts);
1237
+ for (const file of staleCachedModules) {
1238
+ const probe = cacheProbes.get(file);
1239
+ if (probe && !("error" in probe))
1240
+ cacheProbes.set(file, { ...probe, mod: null });
1241
+ cachedGraphEntries?.delete(file);
1242
+ }
1243
+ }
722
1244
  const cacheMisses = Array.from(cacheProbes, ([file, probe]) => !("error" in probe) && !probe.mod ? file : null).filter((file) => file !== null);
723
1245
  const workerSetup = await setupWorkerPool(opts, countNativeWorkerEligibleFiles(cacheMisses, opts?.languageExtensions));
724
1246
  try {
@@ -730,16 +1252,6 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
730
1252
  ? await tryLoadPersistedBloomFilters(projectRoot, opts, report)
731
1253
  : null;
732
1254
  const parsedMap = new Map();
733
- const tsconfigMatchPathByDirectory = new Map();
734
- const loadMatchPathForFile = (file) => {
735
- const directory = path.dirname(file);
736
- let matchPath = tsconfigMatchPathByDirectory.get(directory);
737
- if (!matchPath) {
738
- matchPath = loadNearestTsconfigFor(file, projectRoot, opts?.logLevel).then((tsconfig) => tsconfig.matchPath);
739
- tsconfigMatchPathByDirectory.set(directory, matchPath);
740
- }
741
- return matchPath;
742
- };
743
1255
  const parseStart = performance.now();
744
1256
  const graph = { nodes: new Set(normalizedFiles), edges: [] };
745
1257
  const onFileEdges = manifestEntries
@@ -942,6 +1454,16 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
942
1454
  writeModulesToCache(projectRoot, pendingCacheWrites, opts);
943
1455
  }
944
1456
  }
1457
+ // A full-discovery build re-resolved every importer and wrote its modules back.
1458
+ // Clear the eviction state, unless another payload was evicted during the build.
1459
+ if (opts?.cache === "memory" && projectFiles !== undefined) {
1460
+ settleMemoryCacheEvictions(projectRoot, evictionSerialAtStart);
1461
+ }
1462
+ // Delete the rows of confirmed-deleted declaration files, so the next unchanged build is fully warm.
1463
+ // Only a full-discovery build does this. A build over a file list can omit importers that still need the deletion.
1464
+ if (!manifest && projectFiles !== undefined && retiredDeletionFiles.length && !staleRowRemovalFailed) {
1465
+ removeModulesFromCache(projectRoot, retiredDeletionFiles, opts);
1466
+ }
945
1467
  const workspaceManifestEdges = await timeIndexBuildPhase({
946
1468
  opts,
947
1469
  timings,
@@ -970,7 +1492,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
970
1492
  });
971
1493
  }
972
1494
  }
973
- if (manifestEntries) {
1495
+ if (manifestEntries && !staleRowRemovalFailed) {
974
1496
  await timeIndexBuildPhase({
975
1497
  opts,
976
1498
  timings,
@@ -1029,7 +1551,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
1029
1551
  const finalizeMs = discoveredInsideFinalize ? Math.max(0, elapsed - discoveryMs) : elapsed;
1030
1552
  recordBuildTimingStep(timings, { name: "finalize", ms: finalizeMs });
1031
1553
  }
1032
- if (manifestEntries) {
1554
+ if (manifestEntries && !staleRowRemovalFailed) {
1033
1555
  await timeIndexBuildPhase({
1034
1556
  opts,
1035
1557
  timings,
@@ -1740,6 +2262,7 @@ export async function buildProjectIndexIncremental(projectRoot, rawOpts) {
1740
2262
  const bloomFilterCache = useBloomFilters
1741
2263
  ? new (await import("../util/bloom-filter.js")).BloomFilterCache()
1742
2264
  : undefined;
2265
+ const addedFiles = [];
1743
2266
  for (const file of allFiles) {
1744
2267
  const sigInfo = fileSignatures.get(file);
1745
2268
  if (!sigInfo)
@@ -1747,6 +2270,8 @@ export async function buildProjectIndexIncremental(projectRoot, rawOpts) {
1747
2270
  const entry = trackedEntries[file];
1748
2271
  const hasMatchingGitSig = !!entry?.gitSig && !!sigInfo.gitSig && entry.gitSig === sigInfo.gitSig;
1749
2272
  const hasMatchingSig = entry?.sig === sigInfo.sig;
2273
+ if (!entry)
2274
+ addedFiles.push(file);
1750
2275
  if (!entry || !(hasMatchingGitSig || hasMatchingSig)) {
1751
2276
  changedFiles.add(file);
1752
2277
  }
@@ -1818,6 +2343,52 @@ export async function buildProjectIndexIncremental(projectRoot, rawOpts) {
1818
2343
  }
1819
2344
  }
1820
2345
  invalidateCachedDependents();
2346
+ // A deletion cannot make an unresolved specifier start resolving. Dependents of a
2347
+ // deleted file are already rebuilt by collectDeletedTrackedFileDependents. An added
2348
+ // file can: re-resolve only specifiers whose stem matches an added file. Edges that
2349
+ // cannot round-trip (unstored resolution kind, or a C/C++ include with no form) are
2350
+ // reparsed instead of guessed.
2351
+ if (addedFiles.length) {
2352
+ const reparseCachedFile = (candidate) => {
2353
+ const key = fileIdentityKey(candidate);
2354
+ if (modules.has(key)) {
2355
+ modules.delete(key);
2356
+ if (fileReport) {
2357
+ fileReport.cached = Math.max(0, (fileReport.cached ?? 0) - 1);
2358
+ }
2359
+ }
2360
+ markAsChanged(candidate);
2361
+ };
2362
+ const addedStemsByLanguage = new Map();
2363
+ const addedStemsForLanguage = (languageId) => {
2364
+ const existing = addedStemsByLanguage.get(languageId);
2365
+ if (existing)
2366
+ return existing;
2367
+ const stems = addedResolutionStems(addedFiles, languageId);
2368
+ addedStemsByLanguage.set(languageId, stems);
2369
+ return stems;
2370
+ };
2371
+ const specifierEdgeCandidates = collectSpecifierEdgeCandidates(trackedEntries, true);
2372
+ if (specifierEdgeCandidates.size) {
2373
+ const candidateFiles = Array.from(specifierEdgeCandidates);
2374
+ const staleResolutions = await mapLimit(candidateFiles, conc, async (candidate) => {
2375
+ if (!allFiles.has(candidate) || changedFiles.has(candidate))
2376
+ return false;
2377
+ const entry = trackedEntries[candidate];
2378
+ if (!entry)
2379
+ return false;
2380
+ return specifierResolutionChanged(candidate, entry, projectRoot, workspaceConfig, graphOptions, opts?.languageExtensions, loadMatchPathForFile, addedFiles, addedStemsForLanguage, (importer) => loadTsconfigResolutionInputsFor(importer, projectRoot, opts?.logLevel).then((inputs) => inputs?.paths));
2381
+ });
2382
+ for (let index = 0; index < candidateFiles.length; index += 1) {
2383
+ if (staleResolutions[index])
2384
+ reparseCachedFile(candidateFiles[index]);
2385
+ }
2386
+ }
2387
+ for (const importer of collectPythonPackageImporters(trackedEntries, addedFiles)) {
2388
+ if (allFiles.has(importer) && !changedFiles.has(importer))
2389
+ reparseCachedFile(importer);
2390
+ }
2391
+ }
1821
2392
  const changedList = Array.from(changedFiles);
1822
2393
  // Sized by the work that remains rather than the size of the project: an incremental build
1823
2394
  // touching a handful of files gets a handful of threads, or none.