@lzehrung/codegraph 2.1.0 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (426) hide show
  1. package/README.md +27 -29
  2. package/codegraph-skill/codegraph/SKILL.md +23 -21
  3. package/dist/agent/candidateTests.d.ts +12 -0
  4. package/dist/agent/candidateTests.d.ts.map +1 -0
  5. package/dist/agent/candidateTests.js +17 -0
  6. package/dist/agent/candidateTests.js.map +1 -0
  7. package/dist/agent/explore.d.ts.map +1 -1
  8. package/dist/agent/explore.js +9 -6
  9. package/dist/agent/explore.js.map +1 -1
  10. package/dist/agent/fileView.d.ts.map +1 -1
  11. package/dist/agent/fileView.js +113 -120
  12. package/dist/agent/fileView.js.map +1 -1
  13. package/dist/agent/orient.d.ts.map +1 -1
  14. package/dist/agent/orient.js +5 -4
  15. package/dist/agent/orient.js.map +1 -1
  16. package/dist/agent/query-index/candidates.d.ts +13 -2
  17. package/dist/agent/query-index/candidates.d.ts.map +1 -1
  18. package/dist/agent/query-index/candidates.js +28 -39
  19. package/dist/agent/query-index/candidates.js.map +1 -1
  20. package/dist/agent/query-index/schema.d.ts.map +1 -1
  21. package/dist/agent/query-index/schema.js.map +1 -1
  22. package/dist/agent/query-index/sessionStore.d.ts.map +1 -1
  23. package/dist/agent/query-index/sessionStore.js +42 -26
  24. package/dist/agent/query-index/sessionStore.js.map +1 -1
  25. package/dist/agent/query-index/store.d.ts +7 -0
  26. package/dist/agent/query-index/store.d.ts.map +1 -1
  27. package/dist/agent/query-index/store.js +71 -0
  28. package/dist/agent/query-index/store.js.map +1 -1
  29. package/dist/agent/refactorPlan.d.ts.map +1 -1
  30. package/dist/agent/refactorPlan.js +6 -14
  31. package/dist/agent/refactorPlan.js.map +1 -1
  32. package/dist/agent/renamePreview.d.ts +2 -5
  33. package/dist/agent/renamePreview.d.ts.map +1 -1
  34. package/dist/agent/renamePreview.js +82 -78
  35. package/dist/agent/renamePreview.js.map +1 -1
  36. package/dist/agent/search.d.ts.map +1 -1
  37. package/dist/agent/search.js +39 -17
  38. package/dist/agent/search.js.map +1 -1
  39. package/dist/agent/semanticSymbols.d.ts.map +1 -1
  40. package/dist/agent/semanticSymbols.js +2 -1
  41. package/dist/agent/semanticSymbols.js.map +1 -1
  42. package/dist/agent/session.d.ts +4 -0
  43. package/dist/agent/session.d.ts.map +1 -1
  44. package/dist/agent/session.js +19 -6
  45. package/dist/agent/session.js.map +1 -1
  46. package/dist/agent-tools.d.ts +1 -1
  47. package/dist/agent-tools.d.ts.map +1 -1
  48. package/dist/agent-tools.js +6 -15
  49. package/dist/agent-tools.js.map +1 -1
  50. package/dist/bin/cli.js +27556 -24941
  51. package/dist/bin/queryIndexWorker.js +47 -6
  52. package/dist/bin/rawQueryWorker.js +246 -0
  53. package/dist/chunking/chunkFile.d.ts +5 -0
  54. package/dist/chunking/chunkFile.d.ts.map +1 -1
  55. package/dist/chunking/chunkFile.js +14 -15
  56. package/dist/chunking/chunkFile.js.map +1 -1
  57. package/dist/cli/affected.d.ts.map +1 -1
  58. package/dist/cli/affected.js +17 -10
  59. package/dist/cli/affected.js.map +1 -1
  60. package/dist/cli/commandTable.d.ts.map +1 -1
  61. package/dist/cli/commandTable.js +15 -3
  62. package/dist/cli/commandTable.js.map +1 -1
  63. package/dist/cli/doctor.d.ts +7 -0
  64. package/dist/cli/doctor.d.ts.map +1 -1
  65. package/dist/cli/doctor.js +166 -0
  66. package/dist/cli/doctor.js.map +1 -1
  67. package/dist/cli/graph.d.ts +2 -1
  68. package/dist/cli/graph.d.ts.map +1 -1
  69. package/dist/cli/graph.js +8 -0
  70. package/dist/cli/graph.js.map +1 -1
  71. package/dist/cli/graphDelta.d.ts +2 -1
  72. package/dist/cli/graphDelta.d.ts.map +1 -1
  73. package/dist/cli/graphDelta.js +5 -0
  74. package/dist/cli/graphDelta.js.map +1 -1
  75. package/dist/cli/help.d.ts +34 -34
  76. package/dist/cli/help.d.ts.map +1 -1
  77. package/dist/cli/help.js +17 -8
  78. package/dist/cli/help.js.map +1 -1
  79. package/dist/cli/impact.d.ts +2 -1
  80. package/dist/cli/impact.d.ts.map +1 -1
  81. package/dist/cli/impact.js +5 -0
  82. package/dist/cli/impact.js.map +1 -1
  83. package/dist/cli/index.d.ts +2 -1
  84. package/dist/cli/index.d.ts.map +1 -1
  85. package/dist/cli/index.js +3 -0
  86. package/dist/cli/index.js.map +1 -1
  87. package/dist/cli/indexPolicy.d.ts.map +1 -1
  88. package/dist/cli/indexPolicy.js.map +1 -1
  89. package/dist/cli/inspect.d.ts +2 -1
  90. package/dist/cli/inspect.d.ts.map +1 -1
  91. package/dist/cli/inspect.js +25 -13
  92. package/dist/cli/inspect.js.map +1 -1
  93. package/dist/cli/invocationContext.d.ts.map +1 -1
  94. package/dist/cli/invocationContext.js +3 -0
  95. package/dist/cli/invocationContext.js.map +1 -1
  96. package/dist/cli/links.d.ts +2 -0
  97. package/dist/cli/links.d.ts.map +1 -1
  98. package/dist/cli/links.js +1 -1
  99. package/dist/cli/links.js.map +1 -1
  100. package/dist/cli/navigation.d.ts +41 -1
  101. package/dist/cli/navigation.d.ts.map +1 -1
  102. package/dist/cli/navigation.js +4 -1
  103. package/dist/cli/navigation.js.map +1 -1
  104. package/dist/cli/options.d.ts.map +1 -1
  105. package/dist/cli/options.js +9 -7
  106. package/dist/cli/options.js.map +1 -1
  107. package/dist/cli/review.d.ts +2 -1
  108. package/dist/cli/review.d.ts.map +1 -1
  109. package/dist/cli/review.js +5 -0
  110. package/dist/cli/review.js.map +1 -1
  111. package/dist/cli/skill.js +1 -1
  112. package/dist/cli/skill.js.map +1 -1
  113. package/dist/cli/viewer.d.ts.map +1 -1
  114. package/dist/cli/viewer.js +46 -34
  115. package/dist/cli/viewer.js.map +1 -1
  116. package/dist/config.d.ts +3 -0
  117. package/dist/config.d.ts.map +1 -1
  118. package/dist/config.js +35 -3
  119. package/dist/config.js.map +1 -1
  120. package/dist/documentLinks/check.d.ts +2 -1
  121. package/dist/documentLinks/check.d.ts.map +1 -1
  122. package/dist/documentLinks/check.js +2 -2
  123. package/dist/documentLinks/check.js.map +1 -1
  124. package/dist/duplicate-token-normalization.d.ts.map +1 -1
  125. package/dist/duplicate-token-normalization.js +10 -2
  126. package/dist/duplicate-token-normalization.js.map +1 -1
  127. package/dist/duplicates/scoring.d.ts +0 -10
  128. package/dist/duplicates/scoring.d.ts.map +1 -1
  129. package/dist/duplicates/scoring.js +9 -9
  130. package/dist/duplicates/scoring.js.map +1 -1
  131. package/dist/duplicates/unitCache.d.ts +15 -9
  132. package/dist/duplicates/unitCache.d.ts.map +1 -1
  133. package/dist/duplicates/unitCache.js +184 -33
  134. package/dist/duplicates/unitCache.js.map +1 -1
  135. package/dist/duplicates/units.d.ts +6 -15
  136. package/dist/duplicates/units.d.ts.map +1 -1
  137. package/dist/duplicates/units.js +36 -18
  138. package/dist/duplicates/units.js.map +1 -1
  139. package/dist/frameworks/angularjs.d.ts.map +1 -1
  140. package/dist/frameworks/angularjs.js +18 -12
  141. package/dist/frameworks/angularjs.js.map +1 -1
  142. package/dist/graph-builder.d.ts.map +1 -1
  143. package/dist/graph-builder.js +12 -9
  144. package/dist/graph-builder.js.map +1 -1
  145. package/dist/graph-edge-collector.d.ts +1 -0
  146. package/dist/graph-edge-collector.d.ts.map +1 -1
  147. package/dist/graph-edge-collector.js +1 -1
  148. package/dist/graph-edge-collector.js.map +1 -1
  149. package/dist/graphs/grep.d.ts.map +1 -1
  150. package/dist/graphs/grep.js +7 -2
  151. package/dist/graphs/grep.js.map +1 -1
  152. package/dist/graphs/specifiers.d.ts.map +1 -1
  153. package/dist/graphs/specifiers.js +8 -2
  154. package/dist/graphs/specifiers.js.map +1 -1
  155. package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
  156. package/dist/graphs/symbol-graph-detailed.js +3 -1
  157. package/dist/graphs/symbol-graph-detailed.js.map +1 -1
  158. package/dist/impact/analyzer.d.ts.map +1 -1
  159. package/dist/impact/analyzer.js +15 -1
  160. package/dist/impact/analyzer.js.map +1 -1
  161. package/dist/impact/call-compatibility/textScanner.d.ts +23 -0
  162. package/dist/impact/call-compatibility/textScanner.d.ts.map +1 -0
  163. package/dist/impact/call-compatibility/textScanner.js +615 -0
  164. package/dist/impact/call-compatibility/textScanner.js.map +1 -0
  165. package/dist/impact/callCompatibility.d.ts.map +1 -1
  166. package/dist/impact/callCompatibility.js +9 -570
  167. package/dist/impact/callCompatibility.js.map +1 -1
  168. package/dist/impact/direct.js +7 -6
  169. package/dist/impact/direct.js.map +1 -1
  170. package/dist/impact/index.d.ts +6 -0
  171. package/dist/impact/index.d.ts.map +1 -1
  172. package/dist/impact/index.js +0 -8
  173. package/dist/impact/index.js.map +1 -1
  174. package/dist/impact/map.js +2 -2
  175. package/dist/impact/map.js.map +1 -1
  176. package/dist/impact/memberResolutionCoverage.d.ts.map +1 -1
  177. package/dist/impact/memberResolutionCoverage.js +5 -1
  178. package/dist/impact/memberResolutionCoverage.js.map +1 -1
  179. package/dist/impact/parse.d.ts.map +1 -1
  180. package/dist/impact/parse.js +98 -36
  181. package/dist/impact/parse.js.map +1 -1
  182. package/dist/impact/referenceCache.js +1 -1
  183. package/dist/impact/referenceCache.js.map +1 -1
  184. package/dist/impact/report-suggestions.d.ts.map +1 -1
  185. package/dist/impact/report-suggestions.js +330 -61
  186. package/dist/impact/report-suggestions.js.map +1 -1
  187. package/dist/impact/reportCompact.js +7 -0
  188. package/dist/impact/reportCompact.js.map +1 -1
  189. package/dist/impact/streaming.d.ts +32 -2
  190. package/dist/impact/streaming.d.ts.map +1 -1
  191. package/dist/impact/streaming.js +61 -2
  192. package/dist/impact/streaming.js.map +1 -1
  193. package/dist/impact/suggestions.d.ts.map +1 -1
  194. package/dist/impact/suggestions.js +1 -1
  195. package/dist/impact/suggestions.js.map +1 -1
  196. package/dist/impact/types.d.ts +7 -20
  197. package/dist/impact/types.d.ts.map +1 -1
  198. package/dist/impact/types.js.map +1 -1
  199. package/dist/index.d.ts +2 -2
  200. package/dist/index.d.ts.map +1 -1
  201. package/dist/index.js +1 -1
  202. package/dist/index.js.map +1 -1
  203. package/dist/indexer/build-cache/location.d.ts +19 -0
  204. package/dist/indexer/build-cache/location.d.ts.map +1 -0
  205. package/dist/indexer/build-cache/location.js +132 -0
  206. package/dist/indexer/build-cache/location.js.map +1 -0
  207. package/dist/indexer/build-cache/manifest.d.ts +9 -3
  208. package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
  209. package/dist/indexer/build-cache/manifest.js +77 -20
  210. package/dist/indexer/build-cache/manifest.js.map +1 -1
  211. package/dist/indexer/build-cache/module-cache.d.ts +23 -2
  212. package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
  213. package/dist/indexer/build-cache/module-cache.js +92 -32
  214. package/dist/indexer/build-cache/module-cache.js.map +1 -1
  215. package/dist/indexer/build-cache/options.d.ts +3 -1
  216. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  217. package/dist/indexer/build-cache/options.js +10 -2
  218. package/dist/indexer/build-cache/options.js.map +1 -1
  219. package/dist/indexer/build-cache/project-snapshot.d.ts +32 -8
  220. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  221. package/dist/indexer/build-cache/project-snapshot.js +333 -44
  222. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  223. package/dist/indexer/build-cache/reports.d.ts.map +1 -1
  224. package/dist/indexer/build-cache/reports.js +10 -1
  225. package/dist/indexer/build-cache/reports.js.map +1 -1
  226. package/dist/indexer/build-cache/resolver-environment.d.ts +9 -0
  227. package/dist/indexer/build-cache/resolver-environment.d.ts.map +1 -0
  228. package/dist/indexer/build-cache/resolver-environment.js +133 -0
  229. package/dist/indexer/build-cache/resolver-environment.js.map +1 -0
  230. package/dist/indexer/build-cache.d.ts +4 -3
  231. package/dist/indexer/build-cache.d.ts.map +1 -1
  232. package/dist/indexer/build-cache.js +4 -3
  233. package/dist/indexer/build-cache.js.map +1 -1
  234. package/dist/indexer/build-index.d.ts.map +1 -1
  235. package/dist/indexer/build-index.js +154 -47
  236. package/dist/indexer/build-index.js.map +1 -1
  237. package/dist/indexer/build-manifest.d.ts +1 -0
  238. package/dist/indexer/build-manifest.d.ts.map +1 -1
  239. package/dist/indexer/build-manifest.js +12 -5
  240. package/dist/indexer/build-manifest.js.map +1 -1
  241. package/dist/indexer/call-hierarchy.d.ts.map +1 -1
  242. package/dist/indexer/call-hierarchy.js.map +1 -1
  243. package/dist/indexer/finalize.d.ts.map +1 -1
  244. package/dist/indexer/finalize.js +7 -4
  245. package/dist/indexer/finalize.js.map +1 -1
  246. package/dist/indexer/imports/jsTextImports.d.ts.map +1 -1
  247. package/dist/indexer/imports/jsTextImports.js +14 -6
  248. package/dist/indexer/imports/jsTextImports.js.map +1 -1
  249. package/dist/indexer/imports/languageSpecific.d.ts.map +1 -1
  250. package/dist/indexer/imports/languageSpecific.js +10 -5
  251. package/dist/indexer/imports/languageSpecific.js.map +1 -1
  252. package/dist/indexer/imports/nativeCaptures.d.ts.map +1 -1
  253. package/dist/indexer/imports/nativeCaptures.js +4 -1
  254. package/dist/indexer/imports/nativeCaptures.js.map +1 -1
  255. package/dist/indexer/imports/python.d.ts.map +1 -1
  256. package/dist/indexer/imports/python.js +7 -2
  257. package/dist/indexer/imports/python.js.map +1 -1
  258. package/dist/indexer/load-current-index.d.ts.map +1 -1
  259. package/dist/indexer/load-current-index.js.map +1 -1
  260. package/dist/indexer/locals-and-exports.d.ts.map +1 -1
  261. package/dist/indexer/locals-and-exports.js +52 -22
  262. package/dist/indexer/locals-and-exports.js.map +1 -1
  263. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  264. package/dist/indexer/navigation-goto.js +26 -16
  265. package/dist/indexer/navigation-goto.js.map +1 -1
  266. package/dist/indexer/navigation-local.d.ts.map +1 -1
  267. package/dist/indexer/navigation-local.js +7 -4
  268. package/dist/indexer/navigation-local.js.map +1 -1
  269. package/dist/indexer/navigation-references.d.ts +1 -1
  270. package/dist/indexer/navigation-references.d.ts.map +1 -1
  271. package/dist/indexer/navigation-references.js +27 -16
  272. package/dist/indexer/navigation-references.js.map +1 -1
  273. package/dist/indexer/navigation-resolve.d.ts.map +1 -1
  274. package/dist/indexer/navigation-resolve.js +116 -53
  275. package/dist/indexer/navigation-resolve.js.map +1 -1
  276. package/dist/indexer/navigation.d.ts +2 -1
  277. package/dist/indexer/navigation.d.ts.map +1 -1
  278. package/dist/indexer/navigation.js +24 -20
  279. package/dist/indexer/navigation.js.map +1 -1
  280. package/dist/indexer/parse-context.d.ts +1 -1
  281. package/dist/indexer/parse-context.d.ts.map +1 -1
  282. package/dist/indexer/parse-context.js +2 -2
  283. package/dist/indexer/parse-context.js.map +1 -1
  284. package/dist/indexer/reference-context.d.ts +2 -2
  285. package/dist/indexer/reference-context.d.ts.map +1 -1
  286. package/dist/indexer/reference-context.js +4 -2
  287. package/dist/indexer/reference-context.js.map +1 -1
  288. package/dist/indexer/scope-types.d.ts +3 -0
  289. package/dist/indexer/scope-types.d.ts.map +1 -1
  290. package/dist/indexer/scope.js +37 -38
  291. package/dist/indexer/scope.js.map +1 -1
  292. package/dist/indexer/shared.d.ts.map +1 -1
  293. package/dist/indexer/shared.js +3 -1
  294. package/dist/indexer/shared.js.map +1 -1
  295. package/dist/indexer/type-hierarchy.d.ts.map +1 -1
  296. package/dist/indexer/type-hierarchy.js +12 -8
  297. package/dist/indexer/type-hierarchy.js.map +1 -1
  298. package/dist/indexer/types.d.ts +22 -0
  299. package/dist/indexer/types.d.ts.map +1 -1
  300. package/dist/indexer/workspace-symbols.d.ts.map +1 -1
  301. package/dist/indexer/workspace-symbols.js +5 -3
  302. package/dist/indexer/workspace-symbols.js.map +1 -1
  303. package/dist/installer/locks.d.ts +10 -0
  304. package/dist/installer/locks.d.ts.map +1 -0
  305. package/dist/installer/locks.js +234 -0
  306. package/dist/installer/locks.js.map +1 -0
  307. package/dist/installer/registry.d.ts.map +1 -1
  308. package/dist/installer/registry.js +13 -230
  309. package/dist/installer/registry.js.map +1 -1
  310. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  311. package/dist/languages/definitions/csharp.js +8 -0
  312. package/dist/languages/definitions/csharp.js.map +1 -1
  313. package/dist/languages/definitions/java.d.ts.map +1 -1
  314. package/dist/languages/definitions/java.js +3 -0
  315. package/dist/languages/definitions/java.js.map +1 -1
  316. package/dist/languages/definitions/python.d.ts.map +1 -1
  317. package/dist/languages/definitions/python.js +2 -0
  318. package/dist/languages/definitions/python.js.map +1 -1
  319. package/dist/languages/definitions/rust.d.ts.map +1 -1
  320. package/dist/languages/definitions/rust.js +2 -0
  321. package/dist/languages/definitions/rust.js.map +1 -1
  322. package/dist/languages/importStatementParsers.d.ts +2 -0
  323. package/dist/languages/importStatementParsers.d.ts.map +1 -1
  324. package/dist/languages/importStatementParsers.js +24 -10
  325. package/dist/languages/importStatementParsers.js.map +1 -1
  326. package/dist/mcp/http.d.ts +3 -1
  327. package/dist/mcp/http.d.ts.map +1 -1
  328. package/dist/mcp/http.js +69 -20
  329. package/dist/mcp/http.js.map +1 -1
  330. package/dist/mcp/server.d.ts +43 -16
  331. package/dist/mcp/server.d.ts.map +1 -1
  332. package/dist/mcp/server.js +342 -127
  333. package/dist/mcp/server.js.map +1 -1
  334. package/dist/mcp/tools.d.ts +51 -1
  335. package/dist/mcp/tools.d.ts.map +1 -1
  336. package/dist/mcp/tools.js +121 -2
  337. package/dist/mcp/tools.js.map +1 -1
  338. package/dist/native/byteIndex.d.ts +26 -0
  339. package/dist/native/byteIndex.d.ts.map +1 -0
  340. package/dist/native/byteIndex.js +70 -0
  341. package/dist/native/byteIndex.js.map +1 -0
  342. package/dist/native/projectedTree.d.ts +3 -2
  343. package/dist/native/projectedTree.d.ts.map +1 -1
  344. package/dist/native/projectedTree.js +6 -50
  345. package/dist/native/projectedTree.js.map +1 -1
  346. package/dist/native/queryResults.d.ts +7 -1
  347. package/dist/native/queryResults.d.ts.map +1 -1
  348. package/dist/native/queryResults.js +13 -5
  349. package/dist/native/queryResults.js.map +1 -1
  350. package/dist/review/changes.d.ts +2 -0
  351. package/dist/review/changes.d.ts.map +1 -1
  352. package/dist/review/changes.js +10 -0
  353. package/dist/review/changes.js.map +1 -1
  354. package/dist/review/deleted.d.ts.map +1 -1
  355. package/dist/review/deleted.js +20 -2
  356. package/dist/review/deleted.js.map +1 -1
  357. package/dist/review/summaries.d.ts.map +1 -1
  358. package/dist/review/summaries.js +13 -10
  359. package/dist/review/summaries.js.map +1 -1
  360. package/dist/review.d.ts.map +1 -1
  361. package/dist/review.js +7 -2
  362. package/dist/review.js.map +1 -1
  363. package/dist/session.d.ts +20 -4
  364. package/dist/session.d.ts.map +1 -1
  365. package/dist/session.js +76 -16
  366. package/dist/session.js.map +1 -1
  367. package/dist/sql/types.d.ts.map +1 -1
  368. package/dist/sqlite/query.d.ts +29 -0
  369. package/dist/sqlite/query.d.ts.map +1 -1
  370. package/dist/sqlite/query.js +98 -11
  371. package/dist/sqlite/query.js.map +1 -1
  372. package/dist/sqlite/rawQueryWorker.d.ts +22 -0
  373. package/dist/sqlite/rawQueryWorker.d.ts.map +1 -0
  374. package/dist/sqlite/rawQueryWorker.js +31 -0
  375. package/dist/sqlite/rawQueryWorker.js.map +1 -0
  376. package/dist/sqlite/rawQueryWorkerPool.d.ts +66 -0
  377. package/dist/sqlite/rawQueryWorkerPool.d.ts.map +1 -0
  378. package/dist/sqlite/rawQueryWorkerPool.js +142 -0
  379. package/dist/sqlite/rawQueryWorkerPool.js.map +1 -0
  380. package/dist/sqlite/schema.d.ts.map +1 -1
  381. package/dist/sqlite/schema.js.map +1 -1
  382. package/dist/sqlite-driver.d.ts.map +1 -1
  383. package/dist/sqlite-driver.js +2 -1
  384. package/dist/sqlite-driver.js.map +1 -1
  385. package/dist/sqlite.d.ts +1 -1
  386. package/dist/sqlite.d.ts.map +1 -1
  387. package/dist/sqlite.js +1 -1
  388. package/dist/sqlite.js.map +1 -1
  389. package/dist/util/bloomFilter.d.ts +3 -2
  390. package/dist/util/bloomFilter.d.ts.map +1 -1
  391. package/dist/util/bloomFilter.js +8 -8
  392. package/dist/util/bloomFilter.js.map +1 -1
  393. package/dist/util/confinedFile.d.ts +41 -2
  394. package/dist/util/confinedFile.d.ts.map +1 -1
  395. package/dist/util/confinedFile.js +101 -2
  396. package/dist/util/confinedFile.js.map +1 -1
  397. package/dist/util/git.d.ts +2 -0
  398. package/dist/util/git.d.ts.map +1 -1
  399. package/dist/util/git.js +109 -26
  400. package/dist/util/git.js.map +1 -1
  401. package/dist/util/identifiers.d.ts +75 -0
  402. package/dist/util/identifiers.d.ts.map +1 -0
  403. package/dist/util/identifiers.js +82 -0
  404. package/dist/util/identifiers.js.map +1 -0
  405. package/dist/util/paths.d.ts.map +1 -1
  406. package/dist/util/paths.js.map +1 -1
  407. package/dist/util/projectFiles.d.ts.map +1 -1
  408. package/dist/util/projectFiles.js +43 -14
  409. package/dist/util/projectFiles.js.map +1 -1
  410. package/dist/util/resolution/jvm.d.ts.map +1 -1
  411. package/dist/util/resolution/jvm.js +9 -4
  412. package/dist/util/resolution/jvm.js.map +1 -1
  413. package/dist/util/resolution/php.d.ts.map +1 -1
  414. package/dist/util/resolution/php.js +6 -5
  415. package/dist/util/resolution/php.js.map +1 -1
  416. package/dist/util/rustTestModules.d.ts.map +1 -1
  417. package/dist/util/rustTestModules.js +4 -2
  418. package/dist/util/rustTestModules.js.map +1 -1
  419. package/dist/util/specifiers.d.ts.map +1 -1
  420. package/dist/util/specifiers.js +10 -3
  421. package/dist/util/specifiers.js.map +1 -1
  422. package/dist/util/sqliteSchema.d.ts.map +1 -1
  423. package/dist/util/sqliteSchema.js +10 -1
  424. package/dist/util/sqliteSchema.js.map +1 -1
  425. package/docs/mcp.md +32 -13
  426. package/package.json +3 -3
@@ -8,7 +8,7 @@ import { loadWorkspaceConfig, resolveWorkspacePackage } from "../util/workspace.
8
8
  import { DEFAULT_PROJECT_PATTERNS, discoverProjectFiles, listProjectFiles, } from "../util/projectFiles.js";
9
9
  import { getGitHead, isGitRepo, getGitBlobHashes, listChangedFiles } from "../util/git.js";
10
10
  import { clearImportResolutionCaches, resolveSpecifier } from "../util/resolution.js";
11
- import { assertFilePathWithinRoot, fileIdentityKey, initializeFileIdentityCaseSensitivity, normalizePath, } from "../util/paths.js";
11
+ import { assertFilePathWithinRoot, fileIdentityKey, initializeFileIdentityCaseSensitivity, isFilePathWithinRoot, normalizePath, } from "../util/paths.js";
12
12
  import { mapLimit } from "../util/concurrency.js";
13
13
  import { resolveWorkerThreadCount } from "../util/workerThreads.js";
14
14
  import { logWithLevel } from "../logging.js";
@@ -26,8 +26,9 @@ import { initNativeBackendReport } from "../native/nativeBackendReport.js";
26
26
  import { closeDuplicateUnitCacheDatabase } from "../duplicates.js";
27
27
  import { isNativeRequiredUnavailableError } from "../native/treeSitterNative.js";
28
28
  import { isNodeSqliteUnavailableError } from "../sqlite-driver.js";
29
- import { buildBloomFilterForFile, cacheSignatureForFile, closeDiskCacheDatabase, collectWorkspaceManifestDependencyEdges, computeConfigHash, createFallbackImportExtractionHandler, diffBuildOptions, fileSignature, graphOptionsEqual, initFileReport, initManifestReport, loadManifest, normalizeGraphOptions, normalizeIndexedFileInputs, normalizeLanguageExtensions, projectSnapshotFilesSignature, recordConfigHashResult, recordFileFailure, sanitizeManifestEntriesForRoot, sanitizeManifestTransientFilesForRoot, tryLoadFromCache, tryLoadPersistedBloomFilters, tryLoadProjectIndexSnapshot, verifyManifestEntries, writeProjectIndexSnapshot, writeToCache, } from "./build-cache.js";
30
- import { cacheRoot } from "./build-cache/module-cache.js";
29
+ import { buildBloomFilterForFile, cacheSignatureForFile, closeDiskCacheDatabase, collectWorkspaceManifestDependencyEdges, computeConfigHash, createFallbackImportExtractionHandler, diffBuildOptions, fileSignature, graphOptionsEqual, initFileReport, initManifestReport, loadManifest, normalizeGraphOptions, normalizeIndexedFileInputs, normalizeLanguageExtensions, projectSnapshotFilesSignature, recordConfigHashResult, recordFileFailure, sanitizeManifestEntriesForRoot, sanitizeManifestTransientFilesForRoot, tryLoadFromCache, tryLoadPersistedBloomFilters, tryLoadProjectIndexSnapshot, tryLoadProjectSnapshotModules, verifyManifestEntries, writeModulesToCache, writeProjectIndexSnapshot, writeToCache, } from "./build-cache.js";
30
+ import { computeResolverEnvironmentFingerprint } from "./build-cache/resolver-environment.js";
31
+ import { cacheRoot } from "./build-cache/location.js";
31
32
  import { SymbolKind, } from "./types.js";
32
33
  import { isNonNativeParserUnavailableError, isParserSyntaxTree } from "../parserBackend.js";
33
34
  import { isUnsupportedParserInputError } from "../languages/filePrep.js";
@@ -88,17 +89,21 @@ async function resolveCrossModuleSymbolExports(file, mod, support, projectRoot,
88
89
  continue;
89
90
  }
90
91
  if (entry.fromModule.startsWith(".")) {
92
+ entry.moduleSpecifier ??= entry.fromModule;
91
93
  const resolved = await resolveSpecifier(file, entry.fromModule, projectRoot, matchPath, workspaceConfig, {
92
94
  resolveNodeModules: !!graphOptions.resolveNodeModules,
93
95
  ...(graphOptions.resolutionHints ? { resolutionHints: graphOptions.resolutionHints } : {}),
94
96
  });
95
- if (typeof resolved === "string")
97
+ if (typeof resolved === "string" && isFilePathWithinRoot(projectRoot, resolved))
96
98
  entry.fromModule = resolved;
97
99
  continue;
98
100
  }
99
101
  const pkgResolved = await resolveWorkspacePackage(entry.fromModule, workspaceConfig);
100
- if (pkgResolved)
101
- entry.fromModule = pkgResolved;
102
+ if (pkgResolved) {
103
+ entry.moduleSpecifier ??= entry.fromModule;
104
+ if (isFilePathWithinRoot(projectRoot, pkgResolved))
105
+ entry.fromModule = pkgResolved;
106
+ }
102
107
  }
103
108
  }
104
109
  async function buildIndexedModuleForFile(args) {
@@ -108,7 +113,16 @@ async function buildIndexedModuleForFile(args) {
108
113
  let tree;
109
114
  const graphOnlyLanguage = isGraphOnlyLanguage(sup.id);
110
115
  if (prepared.syntaxTree) {
111
- tree = new ProjectedSyntaxTree(source, prepared.syntaxTree);
116
+ const parsedTree = new ProjectedSyntaxTree(source, prepared.syntaxTree);
117
+ tree = parsedTree;
118
+ setParsedCacheEntry(args.parsedMap, args.file, {
119
+ source,
120
+ tree: parsedTree,
121
+ sup,
122
+ ...(resolvedLang ? { lang: resolvedLang } : {}),
123
+ ...(embeddedBlocks ? { embeddedBlocks } : {}),
124
+ nativeQueries,
125
+ }, args.parsedCacheMaxEntries);
112
126
  }
113
127
  else if (!nativeQueries && !graphOnlyLanguage && sup.id !== "sql") {
114
128
  const parseAttempt = attemptParsePreparedFileContext(prepared);
@@ -135,13 +149,23 @@ async function buildIndexedModuleForFile(args) {
135
149
  if (parsed) {
136
150
  tree = parsed.tree;
137
151
  resolvedLang = parsed.lang ?? resolvedLang;
152
+ setParsedCacheEntry(args.parsedMap, args.file, parsed, args.parsedCacheMaxEntries);
138
153
  }
139
154
  }
140
155
  const lacksParserContext = !nativeQueries && !tree;
141
156
  if (args.bloomFilterCache) {
142
- const filter = buildBloomFilterFromSource(source, sup.id);
157
+ const filter = buildBloomFilterFromSource(source, sup);
143
158
  args.bloomFilterCache.set(args.file, filter);
144
159
  }
160
+ // Single builder so an option added here always reaches both the primary source and
161
+ // every embedded (SFC) block, instead of one path silently missing a future option.
162
+ const sharedImportOptions = {
163
+ graphOptions: args.graphOptions,
164
+ ...(args.opts?.native ? { native: args.opts.native } : {}),
165
+ ...(args.opts?.logLevel ? { logLevel: args.opts.logLevel } : {}),
166
+ ...(args.opts?.languageExtensions ? { languageExtensions: args.opts.languageExtensions } : {}),
167
+ ...(args.onFallbackImportExtraction ? { onFallbackImportExtraction: args.onFallbackImportExtraction } : {}),
168
+ };
145
169
  const imports = sup.id === "sql"
146
170
  ? []
147
171
  : await collectImportsForFile(args.file, args.projectRoot, {
@@ -150,21 +174,13 @@ async function buildIndexedModuleForFile(args) {
150
174
  sup,
151
175
  ...(resolvedLang ? { lang: resolvedLang } : {}),
152
176
  ...(nativeQueries !== undefined ? { nativeQueries } : {}),
153
- graphOptions: args.graphOptions,
154
- ...(args.opts?.native ? { native: args.opts.native } : {}),
155
- ...(args.opts?.logLevel ? { logLevel: args.opts.logLevel } : {}),
156
- ...(args.opts?.languageExtensions ? { languageExtensions: args.opts.languageExtensions } : {}),
157
- ...(args.onFallbackImportExtraction ? { onFallbackImportExtraction: args.onFallbackImportExtraction } : {}),
177
+ ...sharedImportOptions,
158
178
  });
159
179
  for (const block of embeddedBlocks ?? []) {
160
180
  imports.push(...(await collectImportsForFile(args.file, args.projectRoot, {
161
181
  source: block.source,
162
182
  sup: block.sup,
163
- graphOptions: args.graphOptions,
164
- ...(args.opts?.native ? { native: args.opts.native } : {}),
165
- ...(args.opts?.logLevel ? { logLevel: args.opts.logLevel } : {}),
166
- ...(args.opts?.languageExtensions ? { languageExtensions: args.opts.languageExtensions } : {}),
167
- ...(args.onFallbackImportExtraction ? { onFallbackImportExtraction: args.onFallbackImportExtraction } : {}),
183
+ ...sharedImportOptions,
168
184
  })));
169
185
  }
170
186
  collectJsonDependencies(imports, args.jsonDependencies);
@@ -187,14 +203,16 @@ async function buildIndexedModuleForFile(args) {
187
203
  await resolveCrossModuleSymbolExports(args.file, mod, sup, args.projectRoot, args.graphOptions, args.workspaceConfig, args.opts?.logLevel);
188
204
  const sigInfo = args.fileSignatures.get(args.file);
189
205
  const cacheable = !prepared.nativeFallbackReason && !lacksParserContext;
206
+ let cacheWrite;
190
207
  if (sigInfo && cacheable) {
191
208
  const cacheSig = args.cacheEnabled
192
- ? await moduleCacheSignatureForFile(args.file, sigInfo, args.opts)
209
+ ? await moduleCacheSignatureForFile(args.file, sigInfo, args.opts, args.resolverEnvironmentFingerprint)
193
210
  : sigInfo.cacheSig;
194
- writeToCache(args.projectRoot, args.file, cacheSig, mod, args.opts);
211
+ cacheWrite = { file: args.file, sig: cacheSig, mod };
195
212
  }
196
213
  return {
197
214
  module: mod,
215
+ ...(cacheWrite !== undefined ? { cacheWrite } : {}),
198
216
  graphContext: {
199
217
  source,
200
218
  sup,
@@ -242,19 +260,24 @@ function graphEdgeKey(edge) {
242
260
  const target = edge.to.type === "file" ? `file:${fileIdentityKey(edge.to.path)}` : `external:${edge.to.name}`;
243
261
  return `${from}::${target}::${edge.raw ?? ""}::${edge.typeOnly ? 1 : 0}`;
244
262
  }
245
- async function moduleCacheSignatureForFile(file, sigInfo, opts) {
263
+ async function moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint) {
246
264
  const baseSignature = await cacheSignatureForFile(file, sigInfo, opts);
247
265
  const normalizedExtensions = normalizeLanguageExtensions(opts?.languageExtensions);
248
- if (!normalizedExtensions)
266
+ const resolveNodeModules = normalizeGraphOptions(opts?.graph).resolveNodeModules;
267
+ if (!normalizedExtensions && !resolveNodeModules)
249
268
  return baseSignature;
250
269
  // Combine via a hash rather than raw concatenation: the disk cache stores this string in a
251
270
  // SQLite TEXT column, and node:sqlite's DatabaseSync silently truncates TEXT bind parameters
252
271
  // at embedded NUL bytes, so a raw separator character risks the stored and freshly-computed
253
272
  // signatures never matching (permanent cache miss) if either baseSignature or the serialized
254
- // extensions ever contained one.
273
+ // extensions ever contained one. A cached ModuleIndex's ImportBinding.resolved values differ
274
+ // depending on whether resolveNodeModules was on at write time (resolved node_modules targets
275
+ // vs. external), so that state and the environment that produced it must be part of the key.
255
276
  const hash = crypto.createHash("sha1");
256
277
  hash.update(baseSignature);
257
- hash.update(JSON.stringify(Object.entries(normalizedExtensions)));
278
+ hash.update(JSON.stringify(Object.entries(normalizedExtensions ?? {})));
279
+ hash.update(resolveNodeModules ? "\0resolveNodeModules" : "");
280
+ hash.update(resolverEnvironmentFingerprint === null ? "\0resolverEnvironmentTooLarge" : (resolverEnvironmentFingerprint ?? ""));
258
281
  return hash.digest("hex");
259
282
  }
260
283
  function projectPatternsForLanguageExtensions(opts) {
@@ -325,9 +348,14 @@ function expandStarImports(modules, opts) {
325
348
  }
326
349
  }
327
350
  function toProjectIndexManifestEntry(entry) {
351
+ // A git signature alone is already a strong content identity (`fileSignature()` derives
352
+ // `cacheSig` the same way: `gitSig ?? contentHash ?? sig`), so entries sourced from the disk
353
+ // manifest (which does not persist `cacheSig`) still get one whenever `gitSig` is available.
354
+ const cacheSig = entry.cacheSig ?? entry.gitSig;
328
355
  return {
329
356
  sig: entry.sig,
330
357
  ...(entry.gitSig ? { gitSig: entry.gitSig } : {}),
358
+ ...(cacheSig ? { cacheSig } : {}),
331
359
  };
332
360
  }
333
361
  function projectIndexManifestEntries(entries) {
@@ -339,7 +367,7 @@ function createIndexBuildRunState(projectRoot, opts, graphOptions = normalizeGra
339
367
  initNativeBackendReport(report);
340
368
  const cacheMode = opts?.cache ?? "off";
341
369
  return {
342
- normalizedProjectRoot: normalizePath(projectRoot),
370
+ normalizedProjectRoot: normalizePath(path.resolve(projectRoot)),
343
371
  report,
344
372
  timings: report?.timings,
345
373
  totalStart: performance.now(),
@@ -371,7 +399,7 @@ function buildConcurrency(opts) {
371
399
  async function prepareFileSignatures(args) {
372
400
  const entries = await mapLimit(args.files, args.concurrency, async (file) => {
373
401
  const gitSig = args.gitSigMap.get(file);
374
- const sigInfo = await fileSignature(file, args.opts?.cacheStrict, gitSig, {
402
+ const sigInfo = await fileSignature(file, args.needsContentHash ? args.opts?.cacheStrict : false, gitSig, {
375
403
  forceContentHash: args.cacheEnabled && !gitSig,
376
404
  });
377
405
  return [file, sigInfo];
@@ -403,6 +431,16 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
403
431
  const manifestOptionDiffs = manifest ? diffBuildOptions(manifest.buildOptions, opts) : [];
404
432
  const languageExtensionsChanged = manifestOptionDiffs.includes("languageExtensions");
405
433
  const implementationChanged = manifestOptionDiffs.includes("implementation");
434
+ let resolverEnvironmentFingerprint;
435
+ let resolverEnvironmentMatchesManifest = true;
436
+ if (cacheEnabled && graphOptions.resolveNodeModules) {
437
+ resolverEnvironmentFingerprint = await computeResolverEnvironmentFingerprint(projectRoot, normalizedFiles);
438
+ if (useManifest) {
439
+ resolverEnvironmentMatchesManifest =
440
+ resolverEnvironmentFingerprint !== null &&
441
+ manifest?.resolverEnvironmentFingerprint === resolverEnvironmentFingerprint;
442
+ }
443
+ }
406
444
  if (timings && useManifest) {
407
445
  timings.manifestMs = Math.round(performance.now() - manifestStart);
408
446
  }
@@ -426,6 +464,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
426
464
  const cachedGraphEntries = manifest &&
427
465
  !languageExtensionsChanged &&
428
466
  !implementationChanged &&
467
+ resolverEnvironmentMatchesManifest &&
429
468
  graphOptionsEqual(manifest.graphOptions, graphOptions)
430
469
  ? new Map(Object.entries(manifestFiles).filter(([file]) => !staleCachedEdgeFiles.has(file)))
431
470
  : undefined;
@@ -459,6 +498,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
459
498
  opts,
460
499
  gitSigMap,
461
500
  cacheEnabled,
501
+ needsContentHash: true,
462
502
  concurrency: conc,
463
503
  });
464
504
  const sqlCorpusSig = sqlCorpusSignature(sqlFiles, fileSignatures);
@@ -520,8 +560,13 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
520
560
  if (initialManifestEntry)
521
561
  manifestEntries.set(file, initialManifestEntry);
522
562
  }
523
- const cacheSig = cacheEnabled ? await moduleCacheSignatureForFile(file, sigInfo, opts) : sigInfo.cacheSig;
524
- let mod = cacheEnabled ? tryLoadFromCache(projectRoot, file, cacheSig, opts, report) : null;
563
+ const cacheSig = cacheEnabled
564
+ ? await moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint)
565
+ : sigInfo.cacheSig;
566
+ const canReuseModuleCache = cacheEnabled && (!graphOptions.resolveNodeModules || resolverEnvironmentFingerprint !== null);
567
+ let mod = canReuseModuleCache
568
+ ? tryLoadFromCache(projectRoot, file, cacheSig, opts, report)
569
+ : null;
525
570
  if (mod && fileReport) {
526
571
  fileReport.cached = (fileReport.cached ?? 0) + 1;
527
572
  }
@@ -555,7 +600,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
555
600
  ...(sqlFactCache ? { sqlFactCache } : {}),
556
601
  });
557
602
  if (bloomFilterCache) {
558
- const persistedFilter = persistedBloomFilters?.get(file);
603
+ const persistedFilter = persistedBloomFilters?.get(file, sigInfo);
559
604
  if (persistedFilter) {
560
605
  bloomFilterCache.set(file, persistedFilter);
561
606
  }
@@ -565,15 +610,16 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
565
610
  bloomFilterCache.set(file, filter);
566
611
  }
567
612
  }
568
- return [file, mod, edges];
613
+ return [file, mod, edges, undefined];
569
614
  }
570
615
  if (fileReport)
571
616
  fileReport.parsed = (fileReport.parsed ?? 0) + 1;
572
617
  const support = supportForFile(file, opts?.languageExtensions);
573
618
  if (!support)
574
- return [file, createEmptyModuleIndex(file), []];
619
+ return [file, createEmptyModuleIndex(file), [], undefined];
575
620
  ensureBuildProgressStarted();
576
621
  let graphContext;
622
+ let cacheWrite;
577
623
  if (!mod) {
578
624
  const built = await buildIndexedModuleForFile({
579
625
  file,
@@ -584,6 +630,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
584
630
  graphOptions,
585
631
  workspaceConfig,
586
632
  workerSetup,
633
+ ...(resolverEnvironmentFingerprint !== undefined ? { resolverEnvironmentFingerprint } : {}),
587
634
  parsedMap,
588
635
  parsedCacheMaxEntries: parsedCacheMaxEntries(opts),
589
636
  jsonDependencies,
@@ -594,6 +641,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
594
641
  });
595
642
  mod = built.module;
596
643
  graphContext = built.graphContext;
644
+ cacheWrite = built.cacheWrite;
597
645
  }
598
646
  else {
599
647
  collectJsonDependencies(mod.imports, jsonDependencies);
@@ -619,13 +667,13 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
619
667
  allFiles: normalizedFiles,
620
668
  ...(sqlFactCache ? { sqlFactCache } : {}),
621
669
  });
622
- return [file, mod ?? createEmptyModuleIndex(file), edges];
670
+ return [file, mod ?? createEmptyModuleIndex(file), edges, cacheWrite];
623
671
  }
624
672
  catch (error) {
625
673
  if (isNativeRequiredUnavailableError(error) || isNodeSqliteUnavailableError(error))
626
674
  throw error;
627
675
  if (isUnsupportedParserInputError(error) || isNonNativeParserUnavailableError(error)) {
628
- return [file, createEmptyModuleIndex(file), []];
676
+ return [file, createEmptyModuleIndex(file), [], undefined];
629
677
  }
630
678
  recordFileFailure(report, file, error);
631
679
  logWithLevel(opts?.logLevel, "warn", `Warning: Failed to process file ${file}:`, error);
@@ -662,11 +710,17 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
662
710
  graph.nodes.add(edge.to.path);
663
711
  }
664
712
  };
665
- for (const [file, mod, edges] of fileResults) {
713
+ const pendingCacheWrites = [];
714
+ for (const [file, mod, edges, cacheWrite] of fileResults) {
666
715
  modules.set(fileIdentityKey(file), mod);
667
716
  appendUniqueGraphEdges(edges);
717
+ if (cacheWrite)
718
+ pendingCacheWrites.push(cacheWrite);
719
+ }
720
+ if (pendingCacheWrites.length) {
721
+ writeModulesToCache(projectRoot, pendingCacheWrites, opts);
668
722
  }
669
- const workspaceManifestEdges = await collectWorkspaceManifestDependencyEdges(projectRoot, opts?.discovery, new Set(normalizedFiles), opts?.logLevel);
723
+ const workspaceManifestEdges = await collectWorkspaceManifestDependencyEdges(projectRoot, normalizedFiles.filter((file) => path.basename(file) === "package.json"), opts?.discovery, opts?.logLevel);
670
724
  appendUniqueGraphEdges(workspaceManifestEdges);
671
725
  if (timings)
672
726
  timings.graphMs = Math.round(performance.now() - graphStart);
@@ -679,6 +733,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
679
733
  projectRoot,
680
734
  opts,
681
735
  graphOptions,
736
+ ...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
682
737
  files: manifestEntries,
683
738
  timings,
684
739
  manifestReport: report?.manifest,
@@ -701,7 +756,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
701
756
  manifestEntries: manifestEntriesForIndex,
702
757
  });
703
758
  if (manifestEntries) {
704
- await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries));
759
+ await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries, projectRoot));
705
760
  }
706
761
  if (buildStartedAt !== undefined) {
707
762
  emitIndexLifecycleProgress(opts, "complete", "build", index.byFile.size, performance.now() - buildStartedAt);
@@ -907,8 +962,21 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
907
962
  const currentConfigHashResult = await computeConfigHash(projectRoot, opts?.logLevel);
908
963
  const currentConfigHash = recordConfigHashResult(manifestReport, currentConfigHashResult, opts?.logLevel);
909
964
  const configChanged = !!currentConfigHashResult.error || !manifest?.configHash || currentConfigHash !== manifest.configHash;
965
+ let resolverEnvironmentFingerprint;
966
+ let resolverEnvironmentMatchesManifest = true;
967
+ if (manifest && graphOptions.resolveNodeModules) {
968
+ resolverEnvironmentFingerprint = await computeResolverEnvironmentFingerprint(projectRoot, Object.keys(manifest.files));
969
+ resolverEnvironmentMatchesManifest =
970
+ resolverEnvironmentFingerprint !== null &&
971
+ manifest.resolverEnvironmentFingerprint === resolverEnvironmentFingerprint;
972
+ }
910
973
  const requiresFullRebuild = optionDiffs.some((diff) => diff === "discovery" || diff === "native" || diff === "implementation" || diff === "languageExtensions");
911
- if (!manifest || !graphOptionsEqual(manifest.graphOptions, graphOptions) || configChanged || requiresFullRebuild) {
974
+ const graphOptionsChanged = !graphOptionsEqual(manifest?.graphOptions, graphOptions);
975
+ if (!manifest ||
976
+ graphOptionsChanged ||
977
+ configChanged ||
978
+ requiresFullRebuild ||
979
+ !resolverEnvironmentMatchesManifest) {
912
980
  if (manifest && configChanged) {
913
981
  logWithLevel(opts?.logLevel, "warn", "Configuration changed, rebuilding index...");
914
982
  }
@@ -920,6 +988,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
920
988
  else if (configChanged) {
921
989
  reason = "configChanged";
922
990
  }
991
+ else if (!graphOptionsChanged && !resolverEnvironmentMatchesManifest) {
992
+ reason = "resolverEnvironmentChanged";
993
+ }
923
994
  manifestReport.reason = reason;
924
995
  manifestReport.reused = false;
925
996
  }
@@ -981,7 +1052,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
981
1052
  manifestFileKeys.some((file) => !Object.hasOwn(trackedEntries, file));
982
1053
  const explicitFiles = normalizeIndexedFileInputs(projectRoot, opts?.files ?? [], "Incremental file");
983
1054
  const additionalFiles = normalizeIndexedFileInputs(projectRoot, opts?.additionalFiles ?? [], "Additional index file");
984
- const previousTransientFiles = sanitizeManifestTransientFilesForRoot(projectRoot, manifest.transientFiles).filter((file) => Object.hasOwn(trackedEntries, file));
1055
+ const previousTransientFiles = sanitizeManifestTransientFilesForRoot(projectRoot, projectRoot, manifest.transientFiles).filter((file) => Object.hasOwn(trackedEntries, file));
985
1056
  const previousTransientFileSet = new Set(previousTransientFiles);
986
1057
  const needsGitScan = !!opts?.gitBase || !!opts?.changedSince;
987
1058
  const gitFiles = needsGitScan ? await listChangedFiles(projectRoot, buildIncrementalGitDiffOptions(opts)) : [];
@@ -1067,6 +1138,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1067
1138
  projectRoot,
1068
1139
  opts,
1069
1140
  graphOptions,
1141
+ ...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
1070
1142
  files: {},
1071
1143
  timings,
1072
1144
  manifestReport,
@@ -1087,6 +1159,10 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1087
1159
  };
1088
1160
  }
1089
1161
  const changedFiles = new Set();
1162
+ if (!resolverEnvironmentMatchesManifest) {
1163
+ for (const file of allFiles)
1164
+ changedFiles.add(file);
1165
+ }
1090
1166
  const markAsChanged = (file) => {
1091
1167
  if (allFiles.has(file))
1092
1168
  changedFiles.add(file);
@@ -1203,6 +1279,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1203
1279
  opts,
1204
1280
  gitSigMap,
1205
1281
  cacheEnabled,
1282
+ needsContentHash: cacheEnabled || manifestUsed || opts?.cacheStrict === true,
1206
1283
  concurrency: conc,
1207
1284
  });
1208
1285
  const modules = new Map();
@@ -1248,20 +1325,30 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1248
1325
  completeCheckProgress(allFiles.size);
1249
1326
  return unchangedSnapshot;
1250
1327
  }
1328
+ const snapshotModules = cacheEnabled
1329
+ ? await tryLoadProjectSnapshotModules(projectRoot, opts, fileSignatures)
1330
+ : null;
1251
1331
  const persistedBloomFilters = bloomFilterCache ? await tryLoadPersistedBloomFilters(projectRoot, opts) : null;
1252
1332
  for (const file of allFiles) {
1253
1333
  if (changedFiles.has(file))
1254
1334
  continue;
1255
1335
  const sigInfo = fileSignatures.get(file);
1256
- const cacheSig = cacheEnabled ? await moduleCacheSignatureForFile(file, sigInfo, opts) : sigInfo.cacheSig;
1257
- const cached = cacheEnabled ? tryLoadFromCache(projectRoot, file, cacheSig, opts, report) : null;
1336
+ let cached = null;
1337
+ const snapshotMod = snapshotModules?.get(fileIdentityKey(file));
1338
+ if (snapshotMod) {
1339
+ cached = snapshotMod;
1340
+ }
1341
+ else if (cacheEnabled) {
1342
+ const cacheSig = await moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint);
1343
+ cached = tryLoadFromCache(projectRoot, file, cacheSig, opts, report);
1344
+ }
1258
1345
  if (cached) {
1259
1346
  if (fileReport)
1260
1347
  fileReport.cached = (fileReport.cached ?? 0) + 1;
1261
1348
  modules.set(fileIdentityKey(file), cached);
1262
1349
  collectJsonDependencies(cached.imports, jsonDependencies);
1263
1350
  if (bloomFilterCache) {
1264
- const persistedFilter = persistedBloomFilters?.get(file);
1351
+ const persistedFilter = persistedBloomFilters?.get(file, sigInfo);
1265
1352
  if (persistedFilter) {
1266
1353
  bloomFilterCache.set(file, persistedFilter);
1267
1354
  }
@@ -1312,8 +1399,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1312
1399
  onFallbackImportExtraction,
1313
1400
  fileSignatures,
1314
1401
  cacheEnabled,
1402
+ ...(resolverEnvironmentFingerprint !== undefined ? { resolverEnvironmentFingerprint } : {}),
1315
1403
  });
1316
- return [file, built.module];
1404
+ return [file, built.module, built.cacheWrite];
1317
1405
  }
1318
1406
  catch (error) {
1319
1407
  if (isNativeRequiredUnavailableError(error) || isNodeSqliteUnavailableError(error))
@@ -1323,7 +1411,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1323
1411
  }
1324
1412
  recordFileFailure(report, file, error);
1325
1413
  logWithLevel(opts?.logLevel, "warn", `Warning: Failed to process file ${file}:`, error);
1326
- return [file, createEmptyModuleIndex(file)];
1414
+ return [file, createEmptyModuleIndex(file), undefined];
1327
1415
  }
1328
1416
  finally {
1329
1417
  if (opts?.onProgress) {
@@ -1338,8 +1426,14 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1338
1426
  }
1339
1427
  }
1340
1428
  });
1341
- for (const [file, mod] of fileResults) {
1429
+ const pendingIncrementalCacheWrites = [];
1430
+ for (const [file, mod, cacheWrite] of fileResults) {
1342
1431
  modules.set(fileIdentityKey(file), mod);
1432
+ if (cacheWrite)
1433
+ pendingIncrementalCacheWrites.push(cacheWrite);
1434
+ }
1435
+ if (pendingIncrementalCacheWrites.length) {
1436
+ writeModulesToCache(projectRoot, pendingIncrementalCacheWrites, opts);
1343
1437
  }
1344
1438
  if (timings)
1345
1439
  timings.parseMs = Math.round(performance.now() - parseStart);
@@ -1349,7 +1443,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1349
1443
  }
1350
1444
  expandStarImports(modules, opts);
1351
1445
  const retainedTrackedEntries = Object.entries(trackedEntries).filter(([file]) => !deletedTrackedFiles.has(file));
1352
- const cachedGraphEntries = new Map(retainedTrackedEntries);
1446
+ const cachedGraphEntries = resolverEnvironmentMatchesManifest
1447
+ ? new Map(retainedTrackedEntries)
1448
+ : new Map();
1353
1449
  const manifestEntries = new Map(cachedGraphEntries);
1354
1450
  const baseGraph = cachedGraphEntries.size > 0 ? { nodes: new Set(), edges: [] } : undefined;
1355
1451
  if (baseGraph) {
@@ -1406,6 +1502,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1406
1502
  projectRoot,
1407
1503
  opts,
1408
1504
  graphOptions,
1505
+ ...(resolverEnvironmentFingerprint ? { resolverEnvironmentFingerprint } : {}),
1409
1506
  files: manifestEntries,
1410
1507
  timings,
1411
1508
  manifestReport,
@@ -1422,10 +1519,20 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1422
1519
  modules,
1423
1520
  parsedMap,
1424
1521
  bloomFilterCache,
1425
- manifestEntries: projectIndexManifestEntries(manifestEntries),
1522
+ manifestEntries: projectIndexManifestEntries(
1523
+ // `manifestEntries` (a `ManifestFileEntry`) never carries `cacheSig` -- that field
1524
+ // only lives on `FileSignature`. Overlay each entry with the `cacheSig` this build
1525
+ // actually computed (content-hash-derived for non-git files, since caching is enabled
1526
+ // whenever this path runs) so incremental writes preserve the same strong identity a
1527
+ // cold build produces, instead of leaving snapshot/bloom reuse to fall back to the
1528
+ // weak `mtime:size` `sig`.
1529
+ Array.from(manifestEntries, ([file, entry]) => {
1530
+ const cacheSig = fileSignatures.get(file)?.cacheSig;
1531
+ return [file, { ...entry, ...(cacheSig ? { cacheSig } : {}) }];
1532
+ })),
1426
1533
  buildReport: report,
1427
1534
  });
1428
- await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries));
1535
+ await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries, projectRoot));
1429
1536
  if (updateStartedAt !== undefined) {
1430
1537
  emitIndexLifecycleProgress(opts, "complete", "update", index.byFile.size, performance.now() - updateStartedAt);
1431
1538
  }