@lzehrung/codegraph 2.1.1 → 2.2.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 (494) hide show
  1. package/README.md +2 -2
  2. package/codegraph-skill/codegraph/SKILL.md +25 -7
  3. package/dist/agent/artifact.d.ts.map +1 -1
  4. package/dist/agent/artifact.js +105 -14
  5. package/dist/agent/artifact.js.map +1 -1
  6. package/dist/agent/explain.d.ts +3 -0
  7. package/dist/agent/explain.d.ts.map +1 -1
  8. package/dist/agent/explain.js +8 -0
  9. package/dist/agent/explain.js.map +1 -1
  10. package/dist/agent/explore.d.ts.map +1 -1
  11. package/dist/agent/explore.js +8 -1
  12. package/dist/agent/explore.js.map +1 -1
  13. package/dist/agent/handles.d.ts.map +1 -1
  14. package/dist/agent/handles.js +2 -8
  15. package/dist/agent/handles.js.map +1 -1
  16. package/dist/agent/orient.js +2 -16
  17. package/dist/agent/orient.js.map +1 -1
  18. package/dist/agent/packet.d.ts.map +1 -1
  19. package/dist/agent/packet.js +5 -12
  20. package/dist/agent/packet.js.map +1 -1
  21. package/dist/agent/query-index/content.d.ts +1 -1
  22. package/dist/agent/query-index/content.js +4 -4
  23. package/dist/agent/query-index/content.js.map +1 -1
  24. package/dist/agent/query-index/store.d.ts +5 -4
  25. package/dist/agent/query-index/store.d.ts.map +1 -1
  26. package/dist/agent/query-index/store.js +56 -18
  27. package/dist/agent/query-index/store.js.map +1 -1
  28. package/dist/agent/query-index/update.d.ts.map +1 -1
  29. package/dist/agent/query-index/update.js +24 -9
  30. package/dist/agent/query-index/update.js.map +1 -1
  31. package/dist/agent/renamePreview.d.ts.map +1 -1
  32. package/dist/agent/renamePreview.js +51 -2
  33. package/dist/agent/renamePreview.js.map +1 -1
  34. package/dist/agent/search.d.ts +3 -1
  35. package/dist/agent/search.d.ts.map +1 -1
  36. package/dist/agent/search.js +64 -18
  37. package/dist/agent/search.js.map +1 -1
  38. package/dist/agent/session.d.ts.map +1 -1
  39. package/dist/agent/session.js +4 -4
  40. package/dist/agent/session.js.map +1 -1
  41. package/dist/agent-tools.js +6 -6
  42. package/dist/agent-tools.js.map +1 -1
  43. package/dist/bin/cli.js +9242 -6344
  44. package/dist/bin/queryIndexWorker.js +437 -86
  45. package/dist/bin/rawQueryWorker.js +26 -2
  46. package/dist/chunking/chunkSplit.js +0 -15
  47. package/dist/chunking/chunkSplit.js.map +1 -1
  48. package/dist/cli/callHierarchy.d.ts.map +1 -1
  49. package/dist/cli/callHierarchy.js +9 -2
  50. package/dist/cli/callHierarchy.js.map +1 -1
  51. package/dist/cli/commandCatalog.d.ts.map +1 -1
  52. package/dist/cli/commandCatalog.js +1 -0
  53. package/dist/cli/commandCatalog.js.map +1 -1
  54. package/dist/cli/commandTable.d.ts.map +1 -1
  55. package/dist/cli/commandTable.js +18 -1
  56. package/dist/cli/commandTable.js.map +1 -1
  57. package/dist/cli/compileCache.d.ts +5 -0
  58. package/dist/cli/compileCache.d.ts.map +1 -1
  59. package/dist/cli/compileCache.js +18 -0
  60. package/dist/cli/compileCache.js.map +1 -1
  61. package/dist/cli/context.d.ts.map +1 -1
  62. package/dist/cli/context.js +0 -1
  63. package/dist/cli/context.js.map +1 -1
  64. package/dist/cli/graph.d.ts.map +1 -1
  65. package/dist/cli/graph.js +52 -16
  66. package/dist/cli/graph.js.map +1 -1
  67. package/dist/cli/grep.d.ts +1 -1
  68. package/dist/cli/grep.d.ts.map +1 -1
  69. package/dist/cli/grep.js +14 -4
  70. package/dist/cli/grep.js.map +1 -1
  71. package/dist/cli/help.d.ts +2 -1
  72. package/dist/cli/help.d.ts.map +1 -1
  73. package/dist/cli/help.js +23 -2
  74. package/dist/cli/help.js.map +1 -1
  75. package/dist/cli/indexPolicy.d.ts.map +1 -1
  76. package/dist/cli/indexPolicy.js +1 -0
  77. package/dist/cli/indexPolicy.js.map +1 -1
  78. package/dist/cli/inspect.d.ts.map +1 -1
  79. package/dist/cli/inspect.js +5 -2
  80. package/dist/cli/inspect.js.map +1 -1
  81. package/dist/cli/install.js +1 -1
  82. package/dist/cli/install.js.map +1 -1
  83. package/dist/cli/options.d.ts +1 -1
  84. package/dist/cli/options.d.ts.map +1 -1
  85. package/dist/cli/options.js +54 -5
  86. package/dist/cli/options.js.map +1 -1
  87. package/dist/cli/renamePreview.d.ts.map +1 -1
  88. package/dist/cli/renamePreview.js +7 -1
  89. package/dist/cli/renamePreview.js.map +1 -1
  90. package/dist/cli/rootPolicy.d.ts.map +1 -1
  91. package/dist/cli/rootPolicy.js +36 -3
  92. package/dist/cli/rootPolicy.js.map +1 -1
  93. package/dist/cli/server.d.ts +59 -0
  94. package/dist/cli/server.d.ts.map +1 -0
  95. package/dist/cli/server.js +906 -0
  96. package/dist/cli/server.js.map +1 -0
  97. package/dist/cli/skill.js +1 -1
  98. package/dist/cli/skill.js.map +1 -1
  99. package/dist/cli/sql.js +1 -1
  100. package/dist/cli/symbols.d.ts.map +1 -1
  101. package/dist/cli/symbols.js +4 -2
  102. package/dist/cli/symbols.js.map +1 -1
  103. package/dist/cli.d.ts +1 -1
  104. package/dist/cli.d.ts.map +1 -1
  105. package/dist/cli.js +37 -16
  106. package/dist/cli.js.map +1 -1
  107. package/dist/documentLinks/check.d.ts.map +1 -1
  108. package/dist/documentLinks/check.js +20 -9
  109. package/dist/documentLinks/check.js.map +1 -1
  110. package/dist/documentLinks.d.ts.map +1 -1
  111. package/dist/documentLinks.js +0 -1
  112. package/dist/documentLinks.js.map +1 -1
  113. package/dist/drift/snapshot.js +1 -1
  114. package/dist/drift/snapshot.js.map +1 -1
  115. package/dist/duplicates/scoring.d.ts.map +1 -1
  116. package/dist/duplicates/scoring.js.map +1 -1
  117. package/dist/duplicates/types.d.ts +2 -0
  118. package/dist/duplicates/types.d.ts.map +1 -1
  119. package/dist/duplicates/unitCache.d.ts.map +1 -1
  120. package/dist/duplicates/unitCache.js +1 -1
  121. package/dist/duplicates/unitCache.js.map +1 -1
  122. package/dist/duplicates/units.d.ts.map +1 -1
  123. package/dist/duplicates/units.js +8 -5
  124. package/dist/duplicates/units.js.map +1 -1
  125. package/dist/duplicates.d.ts.map +1 -1
  126. package/dist/duplicates.js +59 -6
  127. package/dist/duplicates.js.map +1 -1
  128. package/dist/graph-edge-collector.d.ts +0 -2
  129. package/dist/graph-edge-collector.d.ts.map +1 -1
  130. package/dist/graph-edge-collector.js +2 -4
  131. package/dist/graph-edge-collector.js.map +1 -1
  132. package/dist/graphs/edgeResolution.d.ts.map +1 -1
  133. package/dist/graphs/specifiers.d.ts +1 -1
  134. package/dist/graphs/specifiers.d.ts.map +1 -1
  135. package/dist/graphs/specifiers.js +1 -1
  136. package/dist/graphs/specifiers.js.map +1 -1
  137. package/dist/graphs/symbol-graph-detailed.d.ts +10 -1
  138. package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
  139. package/dist/graphs/symbol-graph-detailed.js +18 -5
  140. package/dist/graphs/symbol-graph-detailed.js.map +1 -1
  141. package/dist/impact/analyzer.d.ts.map +1 -1
  142. package/dist/impact/analyzer.js +4 -1
  143. package/dist/impact/analyzer.js.map +1 -1
  144. package/dist/impact/budgets.d.ts.map +1 -1
  145. package/dist/impact/budgets.js +5 -3
  146. package/dist/impact/budgets.js.map +1 -1
  147. package/dist/impact/callCompatibility.d.ts +8 -1
  148. package/dist/impact/callCompatibility.d.ts.map +1 -1
  149. package/dist/impact/callCompatibility.js +55 -17
  150. package/dist/impact/callCompatibility.js.map +1 -1
  151. package/dist/impact/context.d.ts.map +1 -1
  152. package/dist/impact/context.js +4 -1
  153. package/dist/impact/context.js.map +1 -1
  154. package/dist/impact/direct.d.ts +1 -1
  155. package/dist/impact/direct.d.ts.map +1 -1
  156. package/dist/impact/parse.d.ts.map +1 -1
  157. package/dist/impact/parse.js +10 -1
  158. package/dist/impact/parse.js.map +1 -1
  159. package/dist/impact/report-suggestions.d.ts.map +1 -1
  160. package/dist/impact/report-suggestions.js +17 -11
  161. package/dist/impact/report-suggestions.js.map +1 -1
  162. package/dist/impact/report.d.ts.map +1 -1
  163. package/dist/impact/report.js +13 -2
  164. package/dist/impact/report.js.map +1 -1
  165. package/dist/impact/reportCompact.d.ts.map +1 -1
  166. package/dist/impact/reportCompact.js +1 -0
  167. package/dist/impact/reportCompact.js.map +1 -1
  168. package/dist/impact/reportFull.d.ts.map +1 -1
  169. package/dist/impact/reportFull.js +1 -0
  170. package/dist/impact/reportFull.js.map +1 -1
  171. package/dist/impact/reportParts.d.ts +9 -0
  172. package/dist/impact/reportParts.d.ts.map +1 -1
  173. package/dist/impact/severity.d.ts +3 -2
  174. package/dist/impact/severity.d.ts.map +1 -1
  175. package/dist/impact/severity.js +16 -5
  176. package/dist/impact/severity.js.map +1 -1
  177. package/dist/impact/streaming.d.ts.map +1 -1
  178. package/dist/impact/streaming.js +5 -5
  179. package/dist/impact/streaming.js.map +1 -1
  180. package/dist/impact/transitive.d.ts.map +1 -1
  181. package/dist/impact/transitive.js +13 -5
  182. package/dist/impact/transitive.js.map +1 -1
  183. package/dist/impact/types.d.ts +14 -0
  184. package/dist/impact/types.d.ts.map +1 -1
  185. package/dist/impact/types.js.map +1 -1
  186. package/dist/index.d.ts +1 -1
  187. package/dist/index.d.ts.map +1 -1
  188. package/dist/index.js.map +1 -1
  189. package/dist/indexer/build-cache/manifest.d.ts +5 -3
  190. package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
  191. package/dist/indexer/build-cache/manifest.js +122 -15
  192. package/dist/indexer/build-cache/manifest.js.map +1 -1
  193. package/dist/indexer/build-cache/module-cache.d.ts +1 -0
  194. package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
  195. package/dist/indexer/build-cache/module-cache.js +7 -1
  196. package/dist/indexer/build-cache/module-cache.js.map +1 -1
  197. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  198. package/dist/indexer/build-cache/options.js +0 -2
  199. package/dist/indexer/build-cache/options.js.map +1 -1
  200. package/dist/indexer/build-cache/project-snapshot.d.ts +15 -11
  201. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  202. package/dist/indexer/build-cache/project-snapshot.js +167 -79
  203. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  204. package/dist/indexer/build-cache/resolver-environment.d.ts +2 -2
  205. package/dist/indexer/build-cache/resolver-environment.d.ts.map +1 -1
  206. package/dist/indexer/build-cache/resolver-environment.js +33 -6
  207. package/dist/indexer/build-cache/resolver-environment.js.map +1 -1
  208. package/dist/indexer/build-cache.d.ts +2 -2
  209. package/dist/indexer/build-cache.d.ts.map +1 -1
  210. package/dist/indexer/build-cache.js +2 -2
  211. package/dist/indexer/build-cache.js.map +1 -1
  212. package/dist/indexer/build-index.d.ts.map +1 -1
  213. package/dist/indexer/build-index.js +164 -84
  214. package/dist/indexer/build-index.js.map +1 -1
  215. package/dist/indexer/build-manifest.d.ts.map +1 -1
  216. package/dist/indexer/build-manifest.js +3 -0
  217. package/dist/indexer/build-manifest.js.map +1 -1
  218. package/dist/indexer/build-workers.d.ts +30 -3
  219. package/dist/indexer/build-workers.d.ts.map +1 -1
  220. package/dist/indexer/build-workers.js +111 -45
  221. package/dist/indexer/build-workers.js.map +1 -1
  222. package/dist/indexer/call-hierarchy.d.ts.map +1 -1
  223. package/dist/indexer/import-types.d.ts +8 -0
  224. package/dist/indexer/import-types.d.ts.map +1 -1
  225. package/dist/indexer/imports/python.d.ts.map +1 -1
  226. package/dist/indexer/imports/python.js +13 -8
  227. package/dist/indexer/imports/python.js.map +1 -1
  228. package/dist/indexer/imports.d.ts +0 -3
  229. package/dist/indexer/imports.d.ts.map +1 -1
  230. package/dist/indexer/imports.js +1 -1
  231. package/dist/indexer/imports.js.map +1 -1
  232. package/dist/indexer/incremental-plan.d.ts +2 -1
  233. package/dist/indexer/incremental-plan.d.ts.map +1 -1
  234. package/dist/indexer/incremental-plan.js +7 -4
  235. package/dist/indexer/incremental-plan.js.map +1 -1
  236. package/dist/indexer/locals-and-exports.d.ts +2 -2
  237. package/dist/indexer/locals-and-exports.d.ts.map +1 -1
  238. package/dist/indexer/locals-and-exports.js +27 -3
  239. package/dist/indexer/locals-and-exports.js.map +1 -1
  240. package/dist/indexer/navigation-local.d.ts +2 -2
  241. package/dist/indexer/navigation-local.d.ts.map +1 -1
  242. package/dist/indexer/navigation-local.js +2 -2
  243. package/dist/indexer/navigation-local.js.map +1 -1
  244. package/dist/indexer/navigation-references.d.ts +1 -2
  245. package/dist/indexer/navigation-references.d.ts.map +1 -1
  246. package/dist/indexer/navigation-references.js +8 -2
  247. package/dist/indexer/navigation-references.js.map +1 -1
  248. package/dist/indexer/navigation.d.ts.map +1 -1
  249. package/dist/indexer/navigation.js +12 -4
  250. package/dist/indexer/navigation.js.map +1 -1
  251. package/dist/indexer/parse-context.d.ts +2 -5
  252. package/dist/indexer/parse-context.d.ts.map +1 -1
  253. package/dist/indexer/parse-context.js +34 -8
  254. package/dist/indexer/parse-context.js.map +1 -1
  255. package/dist/indexer/scope.d.ts +2 -2
  256. package/dist/indexer/scope.d.ts.map +1 -1
  257. package/dist/indexer/scope.js +1 -1
  258. package/dist/indexer/scope.js.map +1 -1
  259. package/dist/indexer/types.d.ts +5 -1
  260. package/dist/indexer/types.d.ts.map +1 -1
  261. package/dist/indexer.d.ts +3 -6
  262. package/dist/indexer.d.ts.map +1 -1
  263. package/dist/indexer.js +5 -8
  264. package/dist/indexer.js.map +1 -1
  265. package/dist/installer/locks.d.ts.map +1 -1
  266. package/dist/installer/locks.js +1 -3
  267. package/dist/installer/locks.js.map +1 -1
  268. package/dist/installer/registry.d.ts.map +1 -1
  269. package/dist/installer/registry.js +63 -32
  270. package/dist/installer/registry.js.map +1 -1
  271. package/dist/languages/definitions/c.d.ts.map +1 -1
  272. package/dist/languages/definitions/c.js +0 -1
  273. package/dist/languages/definitions/c.js.map +1 -1
  274. package/dist/languages/definitions/cFamily.d.ts +0 -1
  275. package/dist/languages/definitions/cFamily.d.ts.map +1 -1
  276. package/dist/languages/definitions/cFamily.js +0 -2
  277. package/dist/languages/definitions/cFamily.js.map +1 -1
  278. package/dist/languages/definitions/cpp.d.ts.map +1 -1
  279. package/dist/languages/definitions/cpp.js +0 -1
  280. package/dist/languages/definitions/cpp.js.map +1 -1
  281. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  282. package/dist/languages/definitions/csharp.js +0 -2
  283. package/dist/languages/definitions/csharp.js.map +1 -1
  284. package/dist/languages/definitions/css.d.ts.map +1 -1
  285. package/dist/languages/definitions/css.js +0 -2
  286. package/dist/languages/definitions/css.js.map +1 -1
  287. package/dist/languages/definitions/go.d.ts.map +1 -1
  288. package/dist/languages/definitions/go.js +0 -2
  289. package/dist/languages/definitions/go.js.map +1 -1
  290. package/dist/languages/definitions/html.d.ts.map +1 -1
  291. package/dist/languages/definitions/html.js +0 -2
  292. package/dist/languages/definitions/html.js.map +1 -1
  293. package/dist/languages/definitions/htmlStub.d.ts.map +1 -1
  294. package/dist/languages/definitions/htmlStub.js +0 -2
  295. package/dist/languages/definitions/htmlStub.js.map +1 -1
  296. package/dist/languages/definitions/java.d.ts.map +1 -1
  297. package/dist/languages/definitions/java.js +0 -2
  298. package/dist/languages/definitions/java.js.map +1 -1
  299. package/dist/languages/definitions/javascript.d.ts.map +1 -1
  300. package/dist/languages/definitions/javascript.js +0 -2
  301. package/dist/languages/definitions/javascript.js.map +1 -1
  302. package/dist/languages/definitions/kotlin.d.ts.map +1 -1
  303. package/dist/languages/definitions/kotlin.js +0 -2
  304. package/dist/languages/definitions/kotlin.js.map +1 -1
  305. package/dist/languages/definitions/less.d.ts.map +1 -1
  306. package/dist/languages/definitions/less.js +0 -2
  307. package/dist/languages/definitions/less.js.map +1 -1
  308. package/dist/languages/definitions/php.d.ts.map +1 -1
  309. package/dist/languages/definitions/php.js +0 -2
  310. package/dist/languages/definitions/php.js.map +1 -1
  311. package/dist/languages/definitions/python.d.ts.map +1 -1
  312. package/dist/languages/definitions/python.js +0 -2
  313. package/dist/languages/definitions/python.js.map +1 -1
  314. package/dist/languages/definitions/ruby.d.ts.map +1 -1
  315. package/dist/languages/definitions/ruby.js +0 -2
  316. package/dist/languages/definitions/ruby.js.map +1 -1
  317. package/dist/languages/definitions/rust.d.ts.map +1 -1
  318. package/dist/languages/definitions/rust.js +0 -2
  319. package/dist/languages/definitions/rust.js.map +1 -1
  320. package/dist/languages/definitions/scss.d.ts.map +1 -1
  321. package/dist/languages/definitions/scss.js +0 -2
  322. package/dist/languages/definitions/scss.js.map +1 -1
  323. package/dist/languages/definitions/sql.d.ts.map +1 -1
  324. package/dist/languages/definitions/sql.js +0 -2
  325. package/dist/languages/definitions/sql.js.map +1 -1
  326. package/dist/languages/definitions/svelte.d.ts.map +1 -1
  327. package/dist/languages/definitions/svelte.js +0 -2
  328. package/dist/languages/definitions/svelte.js.map +1 -1
  329. package/dist/languages/definitions/swift.d.ts.map +1 -1
  330. package/dist/languages/definitions/swift.js +0 -2
  331. package/dist/languages/definitions/swift.js.map +1 -1
  332. package/dist/languages/definitions/typescript.d.ts.map +1 -1
  333. package/dist/languages/definitions/typescript.js +0 -3
  334. package/dist/languages/definitions/typescript.js.map +1 -1
  335. package/dist/languages/definitions/vue.d.ts.map +1 -1
  336. package/dist/languages/definitions/vue.js +0 -2
  337. package/dist/languages/definitions/vue.js.map +1 -1
  338. package/dist/languages/definitions/zig.d.ts.map +1 -1
  339. package/dist/languages/definitions/zig.js +0 -2
  340. package/dist/languages/definitions/zig.js.map +1 -1
  341. package/dist/languages/filePrep.d.ts +0 -2
  342. package/dist/languages/filePrep.d.ts.map +1 -1
  343. package/dist/languages/filePrep.js +0 -1
  344. package/dist/languages/filePrep.js.map +1 -1
  345. package/dist/languages/types.d.ts +19 -5
  346. package/dist/languages/types.d.ts.map +1 -1
  347. package/dist/languages.d.ts +1 -3
  348. package/dist/languages.d.ts.map +1 -1
  349. package/dist/languages.js +0 -7
  350. package/dist/languages.js.map +1 -1
  351. package/dist/lifecycle/manifest.d.ts.map +1 -1
  352. package/dist/lifecycle/manifest.js +21 -4
  353. package/dist/lifecycle/manifest.js.map +1 -1
  354. package/dist/mcp/handlers.d.ts +275 -0
  355. package/dist/mcp/handlers.d.ts.map +1 -0
  356. package/dist/mcp/handlers.js +657 -0
  357. package/dist/mcp/handlers.js.map +1 -0
  358. package/dist/mcp/httpTransport.d.ts +14 -0
  359. package/dist/mcp/httpTransport.d.ts.map +1 -0
  360. package/dist/mcp/httpTransport.js +185 -0
  361. package/dist/mcp/httpTransport.js.map +1 -0
  362. package/dist/mcp/legacySessions.d.ts +38 -0
  363. package/dist/mcp/legacySessions.d.ts.map +1 -0
  364. package/dist/mcp/legacySessions.js +264 -0
  365. package/dist/mcp/legacySessions.js.map +1 -0
  366. package/dist/mcp/lifecycleHealth.d.ts +12 -0
  367. package/dist/mcp/lifecycleHealth.d.ts.map +1 -0
  368. package/dist/mcp/lifecycleHealth.js +37 -0
  369. package/dist/mcp/lifecycleHealth.js.map +1 -0
  370. package/dist/mcp/protocol.d.ts +35 -0
  371. package/dist/mcp/protocol.d.ts.map +1 -0
  372. package/dist/mcp/protocol.js +577 -0
  373. package/dist/mcp/protocol.js.map +1 -0
  374. package/dist/mcp/server.d.ts +9 -291
  375. package/dist/mcp/server.d.ts.map +1 -1
  376. package/dist/mcp/server.js +13 -1517
  377. package/dist/mcp/server.js.map +1 -1
  378. package/dist/mcp/tools.d.ts.map +1 -1
  379. package/dist/mcp/tools.js +8 -1
  380. package/dist/mcp/tools.js.map +1 -1
  381. package/dist/native/bindingLoader.d.ts +27 -0
  382. package/dist/native/bindingLoader.d.ts.map +1 -1
  383. package/dist/native/bindingLoader.js +18 -1
  384. package/dist/native/bindingLoader.js.map +1 -1
  385. package/dist/native/contracts.d.ts +59 -12
  386. package/dist/native/contracts.d.ts.map +1 -1
  387. package/dist/native/execution.d.ts +10 -1
  388. package/dist/native/execution.d.ts.map +1 -1
  389. package/dist/native/execution.js +59 -3
  390. package/dist/native/execution.js.map +1 -1
  391. package/dist/native/projectedTree.d.ts +20 -5
  392. package/dist/native/projectedTree.d.ts.map +1 -1
  393. package/dist/native/projectedTree.js +100 -48
  394. package/dist/native/projectedTree.js.map +1 -1
  395. package/dist/native/runtime.d.ts +47 -1
  396. package/dist/native/runtime.d.ts.map +1 -1
  397. package/dist/native/runtime.js +151 -8
  398. package/dist/native/runtime.js.map +1 -1
  399. package/dist/native/runtimeCache.d.ts +92 -0
  400. package/dist/native/runtimeCache.d.ts.map +1 -1
  401. package/dist/native/runtimeCache.js +443 -13
  402. package/dist/native/runtimeCache.js.map +1 -1
  403. package/dist/native/treeShape.d.ts +21 -0
  404. package/dist/native/treeShape.d.ts.map +1 -0
  405. package/dist/native/treeShape.js +28 -0
  406. package/dist/native/treeShape.js.map +1 -0
  407. package/dist/native/treeSitterNative.d.ts +3 -3
  408. package/dist/native/treeSitterNative.d.ts.map +1 -1
  409. package/dist/native/treeSitterNative.js +2 -2
  410. package/dist/native/treeSitterNative.js.map +1 -1
  411. package/dist/presets.d.ts +7 -1
  412. package/dist/presets.d.ts.map +1 -1
  413. package/dist/presets.js +4 -0
  414. package/dist/presets.js.map +1 -1
  415. package/dist/review/candidates.d.ts.map +1 -1
  416. package/dist/review/candidates.js +4 -1
  417. package/dist/review/candidates.js.map +1 -1
  418. package/dist/review/deleted.js +2 -2
  419. package/dist/review/deleted.js.map +1 -1
  420. package/dist/review/summaries.d.ts +5 -0
  421. package/dist/review/summaries.d.ts.map +1 -1
  422. package/dist/review/summaries.js +19 -11
  423. package/dist/review/summaries.js.map +1 -1
  424. package/dist/review/types.d.ts +3 -1
  425. package/dist/review/types.d.ts.map +1 -1
  426. package/dist/review/types.js +8 -1
  427. package/dist/review/types.js.map +1 -1
  428. package/dist/review.d.ts.map +1 -1
  429. package/dist/review.js +7 -3
  430. package/dist/review.js.map +1 -1
  431. package/dist/sql/extractFacts.d.ts.map +1 -1
  432. package/dist/sql/extractFacts.js +1 -1
  433. package/dist/sql/extractFacts.js.map +1 -1
  434. package/dist/sqlite/schema.d.ts +2 -1
  435. package/dist/sqlite/schema.d.ts.map +1 -1
  436. package/dist/sqlite/schema.js +15 -1
  437. package/dist/sqlite/schema.js.map +1 -1
  438. package/dist/sqlite/write.d.ts.map +1 -1
  439. package/dist/sqlite/write.js +15 -0
  440. package/dist/sqlite/write.js.map +1 -1
  441. package/dist/sqlite-driver.d.ts +11 -0
  442. package/dist/sqlite-driver.d.ts.map +1 -1
  443. package/dist/sqlite-driver.js +27 -2
  444. package/dist/sqlite-driver.js.map +1 -1
  445. package/dist/util/concurrency.d.ts +1 -0
  446. package/dist/util/concurrency.d.ts.map +1 -1
  447. package/dist/util/concurrency.js +9 -2
  448. package/dist/util/concurrency.js.map +1 -1
  449. package/dist/util/confinedFile.d.ts +1 -0
  450. package/dist/util/confinedFile.d.ts.map +1 -1
  451. package/dist/util/confinedFile.js +17 -5
  452. package/dist/util/confinedFile.js.map +1 -1
  453. package/dist/util/errors.d.ts +2 -0
  454. package/dist/util/errors.d.ts.map +1 -1
  455. package/dist/util/errors.js +18 -0
  456. package/dist/util/errors.js.map +1 -1
  457. package/dist/util/git.d.ts.map +1 -1
  458. package/dist/util/git.js +72 -7
  459. package/dist/util/git.js.map +1 -1
  460. package/dist/util/lazySymbols.js +1 -1
  461. package/dist/util/lazySymbols.js.map +1 -1
  462. package/dist/util/paths.d.ts.map +1 -1
  463. package/dist/util/paths.js +45 -9
  464. package/dist/util/paths.js.map +1 -1
  465. package/dist/util/resolution/jvm.d.ts.map +1 -1
  466. package/dist/util/resolution/jvm.js +14 -8
  467. package/dist/util/resolution/jvm.js.map +1 -1
  468. package/dist/util/resolution/php.d.ts.map +1 -1
  469. package/dist/util/resolution/php.js +0 -1
  470. package/dist/util/resolution/php.js.map +1 -1
  471. package/dist/util/resolution/tsconfig.d.ts.map +1 -1
  472. package/dist/util/resolution/tsconfig.js +26 -12
  473. package/dist/util/resolution/tsconfig.js.map +1 -1
  474. package/dist/util/resolution.d.ts.map +1 -1
  475. package/dist/util/resolution.js +5 -5
  476. package/dist/util/resolution.js.map +1 -1
  477. package/dist/worker/nativeExtractWorker.d.ts +14 -6
  478. package/dist/worker/nativeExtractWorker.d.ts.map +1 -1
  479. package/dist/worker/nativeExtractWorker.js +67 -14
  480. package/dist/worker/nativeExtractWorker.js.map +1 -1
  481. package/dist/worker/nativeWorkerPool.d.ts +4 -0
  482. package/dist/worker/nativeWorkerPool.d.ts.map +1 -1
  483. package/dist/worker/nativeWorkerPool.js +6 -1
  484. package/dist/worker/nativeWorkerPool.js.map +1 -1
  485. package/docs/mcp.md +22 -6
  486. package/package.json +3 -3
  487. package/dist/languages/definitions/loadLanguage.d.ts +0 -2
  488. package/dist/languages/definitions/loadLanguage.d.ts.map +0 -1
  489. package/dist/languages/definitions/loadLanguage.js +0 -2
  490. package/dist/languages/definitions/loadLanguage.js.map +0 -1
  491. package/dist/parserBackend.d.ts +0 -57
  492. package/dist/parserBackend.d.ts.map +0 -1
  493. package/dist/parserBackend.js +0 -33
  494. package/dist/parserBackend.js.map +0 -1
@@ -4,12 +4,14 @@ import fsp from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { performance } from "node:perf_hooks";
6
6
  import { languageExtensionPatterns, supportForFile } from "../languages.js";
7
+ import { isJsTsLanguage } from "../languages/js-family.js";
7
8
  import { loadWorkspaceConfig, resolveWorkspacePackage } from "../util/workspace.js";
8
9
  import { DEFAULT_PROJECT_PATTERNS, discoverProjectFiles, listProjectFiles, } from "../util/projectFiles.js";
9
10
  import { getGitHead, isGitRepo, getGitBlobHashes, listChangedFiles } from "../util/git.js";
10
- import { clearImportResolutionCaches, resolveSpecifier } from "../util/resolution.js";
11
- import { assertFilePathWithinRoot, fileIdentityKey, initializeFileIdentityCaseSensitivity, isFilePathWithinRoot, normalizePath, } from "../util/paths.js";
11
+ import { clearResolutionCaches, resolveSpecifier } from "../util/resolution.js";
12
+ import { fileIdentityKey, initializeFileIdentityCaseSensitivity, isFilePathWithinRoot, normalizePath, } from "../util/paths.js";
12
13
  import { mapLimit } from "../util/concurrency.js";
14
+ import { readConfinedUtf8File } from "../util/confinedFile.js";
13
15
  import { resolveWorkerThreadCount } from "../util/workerThreads.js";
14
16
  import { logWithLevel } from "../logging.js";
15
17
  import { collectGraph } from "../graph-builder.js";
@@ -26,17 +28,16 @@ import { initNativeBackendReport } from "../native/nativeBackendReport.js";
26
28
  import { closeDuplicateUnitCacheDatabase } from "../duplicates.js";
27
29
  import { isNativeRequiredUnavailableError } from "../native/treeSitterNative.js";
28
30
  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, tryLoadProjectSnapshotModules, verifyManifestEntries, writeModulesToCache, writeProjectIndexSnapshot, writeToCache, } from "./build-cache.js";
31
+ import { buildBloomFilterForFile, cacheSignatureForFile, closeDiskCacheDatabase, 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";
30
32
  import { computeResolverEnvironmentFingerprint } from "./build-cache/resolver-environment.js";
31
33
  import { cacheRoot } from "./build-cache/location.js";
32
34
  import { SymbolKind, } from "./types.js";
33
- import { isNonNativeParserUnavailableError, isParserSyntaxTree } from "../parserBackend.js";
34
35
  import { isUnsupportedParserInputError } from "../languages/filePrep.js";
35
36
  import { buildSqlFactCache, buildSqlModuleIndex, sqlCorpusSignature } from "../sql/sourceGraph.js";
36
37
  import { finalizeProjectIndex } from "./finalize.js";
37
38
  import { toManifestFileEntry, writeIndexManifestSnapshot } from "./build-manifest.js";
38
- import { prepareFileContextForBuild, setupWorkerPool, teardownWorkerPool, } from "./build-workers.js";
39
- import { buildIncrementalGitDiffOptions, canUseIncrementalDiscoveryFastPath, collectDeletedTrackedFileDependents, collectTrackedFileDependents, isMissingGitRevisionError, listUntrackedProjectFiles, partitionTrackedManifestFiles, probePathExistence, } from "./incremental-plan.js";
39
+ import { prepareFileContextForBuild, countNativeWorkerEligibleFiles, emptyWorkerPoolSetup, setupWorkerPool, teardownWorkerPool, } from "./build-workers.js";
40
+ import { buildIncrementalGitDiffOptions, canUseIncrementalDiscoveryFastPath, buildTrackedFileReverseDependencies, collectDeletedTrackedFileDependents, collectTrackedFileDependents, isMissingGitRevisionError, listUntrackedProjectFiles, partitionTrackedManifestFiles, probePathExistence, } from "./incremental-plan.js";
40
41
  import { parsedCacheMaxEntries, setParsedCacheEntry } from "./parsed-cache.js";
41
42
  function initParserBackendDegradationReport(report) {
42
43
  if (!report)
@@ -75,13 +76,17 @@ function recordParserBackendDegradation(report, entry) {
75
76
  return;
76
77
  parserReport.files.push(entry);
77
78
  }
79
+ function isConfinedFileReadError(error) {
80
+ return (error instanceof Error &&
81
+ /outside project root|possible path confinement race|changed between verification and open|confined file target/u.test(error.message));
82
+ }
78
83
  function createEmptyModuleIndex(file) {
79
84
  return { file, exports: [], imports: [], locals: [] };
80
85
  }
81
86
  async function resolveCrossModuleSymbolExports(file, mod, support, projectRoot, graphOptions, workspaceConfig, logLevel) {
82
87
  if (!support.supportsCrossModuleSymbols)
83
88
  return;
84
- if (support.id !== "ts" && support.id !== "js")
89
+ if (!isJsTsLanguage(support.id))
85
90
  return;
86
91
  const { matchPath } = await import("../util/resolution.js").then((mod) => mod.loadNearestTsconfigFor(file, projectRoot, logLevel));
87
92
  for (const entry of mod.exports) {
@@ -107,11 +112,11 @@ async function resolveCrossModuleSymbolExports(file, mod, support, projectRoot,
107
112
  }
108
113
  }
109
114
  async function buildIndexedModuleForFile(args) {
110
- const prepared = await prepareFileContextForBuild(args.file, args.support, args.opts, args.workerSetup, args.report);
115
+ const prepared = await prepareFileContextForBuild(args.file, args.support, args.opts, args.workerSetup, args.report, args.confinedRoot, args.projectRoot, args.trustedSource);
111
116
  const { source, sup, nativeQueries, embeddedBlocks } = prepared;
112
- let resolvedLang = prepared.lang;
113
117
  let tree;
114
- const graphOnlyLanguage = isGraphOnlyLanguage(sup.id);
118
+ const graphOnlyLanguage = isGraphOnlyLanguage(sup.id), nativeSourceLimitFallback = prepared.nativeFallbackReason === "queryFailure" &&
119
+ !!prepared.nativeError?.startsWith("source exceeds native byte limit");
115
120
  if (prepared.syntaxTree) {
116
121
  const parsedTree = new ProjectedSyntaxTree(source, prepared.syntaxTree);
117
122
  tree = parsedTree;
@@ -119,17 +124,15 @@ async function buildIndexedModuleForFile(args) {
119
124
  source,
120
125
  tree: parsedTree,
121
126
  sup,
122
- ...(resolvedLang ? { lang: resolvedLang } : {}),
123
127
  ...(embeddedBlocks ? { embeddedBlocks } : {}),
124
128
  nativeQueries,
125
129
  }, args.parsedCacheMaxEntries);
126
130
  }
127
- else if (!nativeQueries && !graphOnlyLanguage && sup.id !== "sql") {
131
+ else if (!nativeQueries && !graphOnlyLanguage && sup.id !== "sql" && !nativeSourceLimitFallback) {
128
132
  const parseAttempt = attemptParsePreparedFileContext(prepared);
129
133
  const parsed = parseAttempt.parsed;
130
134
  if (parsed) {
131
135
  tree = parsed.tree;
132
- resolvedLang = parsed.lang;
133
136
  setParsedCacheEntry(args.parsedMap, args.file, parsed, args.parsedCacheMaxEntries);
134
137
  }
135
138
  else {
@@ -148,12 +151,11 @@ async function buildIndexedModuleForFile(args) {
148
151
  const parsed = parseAttempt.parsed;
149
152
  if (parsed) {
150
153
  tree = parsed.tree;
151
- resolvedLang = parsed.lang ?? resolvedLang;
152
154
  setParsedCacheEntry(args.parsedMap, args.file, parsed, args.parsedCacheMaxEntries);
153
155
  }
154
156
  }
155
157
  const lacksParserContext = !nativeQueries && !tree;
156
- if (args.bloomFilterCache) {
158
+ if (args.bloomFilterCache && !nativeSourceLimitFallback) {
157
159
  const filter = buildBloomFilterFromSource(source, sup);
158
160
  args.bloomFilterCache.set(args.file, filter);
159
161
  }
@@ -166,13 +168,11 @@ async function buildIndexedModuleForFile(args) {
166
168
  ...(args.opts?.languageExtensions ? { languageExtensions: args.opts.languageExtensions } : {}),
167
169
  ...(args.onFallbackImportExtraction ? { onFallbackImportExtraction: args.onFallbackImportExtraction } : {}),
168
170
  };
169
- const imports = sup.id === "sql"
171
+ const imports = nativeSourceLimitFallback || sup.id === "sql"
170
172
  ? []
171
173
  : await collectImportsForFile(args.file, args.projectRoot, {
172
174
  source,
173
- ...(tree && isParserSyntaxTree(tree) ? { tree } : {}),
174
175
  sup,
175
- ...(resolvedLang ? { lang: resolvedLang } : {}),
176
176
  ...(nativeQueries !== undefined ? { nativeQueries } : {}),
177
177
  ...sharedImportOptions,
178
178
  });
@@ -192,7 +192,7 @@ async function buildIndexedModuleForFile(args) {
192
192
  mod = { ...createEmptyModuleIndex(args.file), imports };
193
193
  }
194
194
  else {
195
- mod = collectLocalsAndExportsFromSource(args.file, source, sup, resolvedLang, imports, {
195
+ mod = collectLocalsAndExportsFromSource(args.file, source, sup, imports, {
196
196
  ...(tree ? { tree } : {}),
197
197
  ...(nativeQueries !== undefined ? { nativeQueries } : {}),
198
198
  ...(args.opts?.native ? { nativeMode: args.opts.native } : {}),
@@ -216,7 +216,6 @@ async function buildIndexedModuleForFile(args) {
216
216
  graphContext: {
217
217
  source,
218
218
  sup,
219
- ...(resolvedLang ? { lang: resolvedLang } : {}),
220
219
  ...(nativeQueries !== undefined ? { nativeQueries } : {}),
221
220
  ...(tree ? { tree } : {}),
222
221
  ...(embeddedBlocks ? { embeddedBlocks } : {}),
@@ -362,9 +361,8 @@ function projectIndexManifestEntries(entries) {
362
361
  return new Map(Array.from(entries, ([file, entry]) => [file, toProjectIndexManifestEntry(entry)]));
363
362
  }
364
363
  function createIndexBuildRunState(projectRoot, opts, graphOptions = normalizeGraphOptions(opts?.graph)) {
365
- const report = opts?.report;
366
- if (report)
367
- initNativeBackendReport(report);
364
+ const report = opts?.report ?? { timings: {} };
365
+ initNativeBackendReport(report);
368
366
  const cacheMode = opts?.cache ?? "off";
369
367
  return {
370
368
  normalizedProjectRoot: normalizePath(path.resolve(projectRoot)),
@@ -399,6 +397,13 @@ function buildConcurrency(opts) {
399
397
  async function prepareFileSignatures(args) {
400
398
  const entries = await mapLimit(args.files, args.concurrency, async (file) => {
401
399
  const gitSig = args.gitSigMap.get(file);
400
+ const source = args.confinedRoot
401
+ ? await readConfinedUtf8File(args.confinedRoot, args.projectRoot, file)
402
+ : undefined;
403
+ if (source !== undefined) {
404
+ args.trustedSources?.set(file, source);
405
+ return [file, fileSignatureFromSource(source, gitSig)];
406
+ }
402
407
  const sigInfo = await fileSignature(file, args.needsContentHash ? args.opts?.cacheStrict : false, gitSig, {
403
408
  forceContentHash: args.cacheEnabled && !gitSig,
404
409
  });
@@ -410,7 +415,7 @@ async function buildProjectIndexFromExport(projectRoot, opts, helperOpts) {
410
415
  return buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpts);
411
416
  }
412
417
  async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperOpts) {
413
- clearImportResolutionCaches();
418
+ clearResolutionCaches();
414
419
  await initializeFileIdentityCaseSensitivity(projectRoot);
415
420
  const { normalizedProjectRoot, report, timings, totalStart, cacheMode, cacheEnabled, graphOptions, onFallbackImportExtraction, } = createIndexBuildRunState(projectRoot, opts);
416
421
  const manifestMode = helperOpts?.manifestMode ?? "off";
@@ -418,7 +423,11 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
418
423
  const shouldWriteManifest = manifestMode === "read-write";
419
424
  const projectFiles = helperOpts?.projectFiles;
420
425
  initManifestReport(report, useManifest, false);
421
- const normalizedFiles = Array.from(new Set(normalizeIndexedFileInputs(projectRoot, rawFiles ?? [], "Index file")));
426
+ const confinedRoot = helperOpts?.confineReads ? await fsp.realpath(projectRoot) : undefined;
427
+ const [trustedSources, normalizedFiles] = [
428
+ confinedRoot ? new Map() : undefined,
429
+ Array.from(new Set(normalizeIndexedFileInputs(projectRoot, rawFiles ?? [], "Index file"))),
430
+ ];
422
431
  if (!normalizedFiles.length && helperOpts?.warnNoFilesMessage) {
423
432
  logWithLevel(opts?.logLevel, "warn", helperOpts.warnNoFilesMessage);
424
433
  }
@@ -426,7 +435,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
426
435
  if (fileReport)
427
436
  fileReport.total = normalizedFiles.length;
428
437
  const manifestStart = performance.now();
429
- const manifest = useManifest && !helperOpts?.ignoreExistingManifest ? await loadManifest(projectRoot, opts) : null;
438
+ const manifest = useManifest && !helperOpts?.ignoreExistingManifest ? await loadManifest(projectRoot, opts, report) : null;
430
439
  const manifestFiles = sanitizeManifestEntriesForRoot(projectRoot, manifest?.files);
431
440
  const manifestOptionDiffs = manifest ? diffBuildOptions(manifest.buildOptions, opts) : [];
432
441
  const languageExtensionsChanged = manifestOptionDiffs.includes("languageExtensions");
@@ -468,10 +477,10 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
468
477
  graphOptionsEqual(manifest.graphOptions, graphOptions)
469
478
  ? new Map(Object.entries(manifestFiles).filter(([file]) => !staleCachedEdgeFiles.has(file)))
470
479
  : undefined;
480
+ const manifestEntries = shouldWriteManifest ? new Map() : undefined;
471
481
  if (report?.manifest) {
472
482
  report.manifest.reused = !!cachedGraphEntries;
473
483
  }
474
- const manifestEntries = shouldWriteManifest ? new Map() : undefined;
475
484
  const manifestEntriesForIndex = useManifest
476
485
  ? projectIndexManifestEntries(cachedGraphEntries ?? [])
477
486
  : new Map();
@@ -494,12 +503,14 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
494
503
  })
495
504
  .sort((left, right) => left.localeCompare(right));
496
505
  const fileSignatures = await prepareFileSignatures({
506
+ projectRoot,
497
507
  files: sqlFiles,
498
508
  opts,
499
509
  gitSigMap,
500
510
  cacheEnabled,
501
511
  needsContentHash: true,
502
512
  concurrency: conc,
513
+ ...(confinedRoot ? { confinedRoot, trustedSources } : {}),
503
514
  });
504
515
  const sqlCorpusSig = sqlCorpusSignature(sqlFiles, fileSignatures);
505
516
  let sqlFactCachePromise;
@@ -516,13 +527,53 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
516
527
  return !(matchesGitSig || cachedEdgesEntry.sig === sigInfo.sig);
517
528
  };
518
529
  const jsonDependencies = new Map();
519
- const workerSetup = await setupWorkerPool(opts, normalizedFiles.length);
530
+ // Cache lookup determines the work a full build will actually parse. Complete that cheap phase
531
+ // before starting Piscina, so a warm build does not bootstrap workers and partial hits bound
532
+ // the pool to real parse misses rather than the input file list.
533
+ const cacheProbes = new Map(await mapLimit(normalizedFiles, conc, async (file) => {
534
+ try {
535
+ let sigInfo = fileSignatures.get(file);
536
+ if (!sigInfo) {
537
+ const gitSig = gitSigMap.get(file);
538
+ const source = confinedRoot ? await readConfinedUtf8File(confinedRoot, projectRoot, file) : undefined;
539
+ if (source !== undefined) {
540
+ trustedSources?.set(file, source);
541
+ sigInfo = fileSignatureFromSource(source, gitSig);
542
+ }
543
+ else {
544
+ sigInfo = await fileSignature(file, opts?.cacheStrict, gitSig, {
545
+ forceContentHash: cacheEnabled && !gitSig,
546
+ });
547
+ }
548
+ fileSignatures.set(file, sigInfo);
549
+ }
550
+ manifestEntriesForIndex.set(file, toProjectIndexManifestEntry(sigInfo));
551
+ if (manifestEntries) {
552
+ const initialManifestEntry = toManifestFileEntry({ ...sigInfo, edges: [] });
553
+ if (initialManifestEntry)
554
+ manifestEntries.set(file, initialManifestEntry);
555
+ }
556
+ const cacheSig = cacheEnabled
557
+ ? await moduleCacheSignatureForFile(file, sigInfo, opts, resolverEnvironmentFingerprint)
558
+ : sigInfo.cacheSig;
559
+ const canReuseModuleCache = cacheEnabled && (!graphOptions.resolveNodeModules || resolverEnvironmentFingerprint !== null);
560
+ const mod = canReuseModuleCache ? tryLoadFromCache(projectRoot, file, cacheSig, opts, report) : null;
561
+ return [file, { sigInfo, mod }];
562
+ }
563
+ catch (error) {
564
+ return [file, { error }];
565
+ }
566
+ }));
567
+ const cacheMisses = Array.from(cacheProbes, ([file, probe]) => !("error" in probe) && !probe.mod ? file : null).filter((file) => file !== null);
568
+ const workerSetup = await setupWorkerPool(opts, countNativeWorkerEligibleFiles(cacheMisses, opts?.languageExtensions));
520
569
  try {
521
570
  const useBloomFilters = opts?.useBloomFilters ?? true;
522
571
  const bloomFilterCache = useBloomFilters
523
572
  ? new (await import("../util/bloomFilter.js")).BloomFilterCache()
524
573
  : undefined;
525
- const persistedBloomFilters = bloomFilterCache ? await tryLoadPersistedBloomFilters(projectRoot, opts) : null;
574
+ const persistedBloomFilters = bloomFilterCache
575
+ ? await tryLoadPersistedBloomFilters(projectRoot, opts, report)
576
+ : null;
526
577
  const parsedMap = new Map();
527
578
  const workspaceConfig = await loadWorkspaceConfig(projectRoot);
528
579
  const parseStart = performance.now();
@@ -546,27 +597,13 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
546
597
  };
547
598
  const fileResults = await mapLimit(normalizedFiles, conc, async (file) => {
548
599
  try {
549
- let sigInfo = fileSignatures.get(file);
550
- if (!sigInfo) {
551
- const gitSig = gitSigMap.get(file);
552
- sigInfo = await fileSignature(file, opts?.cacheStrict, gitSig, {
553
- forceContentHash: cacheEnabled && !gitSig,
554
- });
555
- fileSignatures.set(file, sigInfo);
556
- }
557
- manifestEntriesForIndex.set(file, toProjectIndexManifestEntry(sigInfo));
558
- if (manifestEntries) {
559
- const initialManifestEntry = toManifestFileEntry({ ...sigInfo, edges: [] });
560
- if (initialManifestEntry)
561
- manifestEntries.set(file, initialManifestEntry);
562
- }
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;
600
+ const cacheProbe = cacheProbes.get(file);
601
+ if (!cacheProbe)
602
+ throw new Error(`Missing module cache probe for ${file}`);
603
+ if ("error" in cacheProbe)
604
+ throw cacheProbe.error;
605
+ const { sigInfo } = cacheProbe;
606
+ let mod = cacheProbe.mod;
570
607
  if (mod && fileReport) {
571
608
  fileReport.cached = (fileReport.cached ?? 0) + 1;
572
609
  }
@@ -638,6 +675,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
638
675
  onFallbackImportExtraction,
639
676
  fileSignatures,
640
677
  cacheEnabled,
678
+ ...(confinedRoot ? { confinedRoot, trustedSource: trustedSources?.get(file) } : {}),
641
679
  });
642
680
  mod = built.module;
643
681
  graphContext = built.graphContext;
@@ -672,7 +710,9 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
672
710
  catch (error) {
673
711
  if (isNativeRequiredUnavailableError(error) || isNodeSqliteUnavailableError(error))
674
712
  throw error;
675
- if (isUnsupportedParserInputError(error) || isNonNativeParserUnavailableError(error)) {
713
+ if (isConfinedFileReadError(error))
714
+ throw error;
715
+ if (isUnsupportedParserInputError(error)) {
676
716
  return [file, createEmptyModuleIndex(file), [], undefined];
677
717
  }
678
718
  recordFileFailure(report, file, error);
@@ -728,6 +768,17 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
728
768
  ensureJsonModule(modules, jsonPath);
729
769
  }
730
770
  expandStarImports(modules, opts);
771
+ if (manifestEntries) {
772
+ for (const [file, signature] of fileSignatures) {
773
+ if (manifestEntries.has(file))
774
+ continue;
775
+ manifestEntries.set(file, {
776
+ sig: signature.sig,
777
+ ...(signature.gitSig ? { gitSig: signature.gitSig } : {}),
778
+ edges: [],
779
+ });
780
+ }
781
+ }
731
782
  if (manifestEntries) {
732
783
  await writeIndexManifestSnapshot({
733
784
  projectRoot,
@@ -741,6 +792,12 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
741
792
  ...(helperOpts?.symlinkDirectories !== undefined ? { symlinkDirectories: helperOpts.symlinkDirectories } : {}),
742
793
  });
743
794
  }
795
+ const indexManifestEntries = manifestEntries
796
+ ? projectIndexManifestEntries(Array.from(manifestEntries, ([file, entry]) => {
797
+ const cacheSig = fileSignatures.get(file)?.cacheSig;
798
+ return [file, { ...entry, ...(cacheSig ? { cacheSig } : {}) }];
799
+ }))
800
+ : manifestEntriesForIndex;
744
801
  const index = await finalizeProjectIndex({
745
802
  projectRoot,
746
803
  normalizedProjectRoot,
@@ -753,7 +810,7 @@ async function buildIndexFromFileListShared(projectRoot, rawFiles, opts, helperO
753
810
  bloomFilterCache,
754
811
  ...(projectFiles !== undefined ? { projectFiles } : {}),
755
812
  buildReport: report,
756
- manifestEntries: manifestEntriesForIndex,
813
+ manifestEntries: indexManifestEntries,
757
814
  });
758
815
  if (manifestEntries) {
759
816
  await writeProjectIndexSnapshot(projectRoot, opts, index, projectSnapshotFilesSignature(manifestEntries, projectRoot));
@@ -776,34 +833,29 @@ async function buildProjectIndexWithManifestOptions(projectRoot, opts, helperOpt
776
833
  // full-tree symlink probe. Off and memory modes never read or write this disk
777
834
  // manifest, keeping read-only builds from mutating the project root. A missing or
778
835
  // unusable manifest falls back to probing once.
779
- // A symlink hint never expires on its own: `knownSymlinkDirectories` disables probing entirely, so
780
- // a directory symlinked in after the hint was recorded (e.g. `npm link`) would
781
- // otherwise never be discovered. `--cache-strict`/`--cache-verify` are explicit asks
782
- // for maximum correctness over speed, so both force a fresh probe here too.
836
+ // The manifest records the project-root directory mtime alongside symlink hints. A changed
837
+ // root mtime triggers the cheap full-tree probe, while strict modes always probe.
783
838
  const wantsMaxSymlinkCorrectness = !!opts?.cacheStrict || !!opts?.cacheVerify;
784
839
  const symlinkHintManifest = helperOpts?.ignoreExistingManifest || wantsMaxSymlinkCorrectness || !useDiskCache
785
840
  ? null
786
841
  : await loadManifest(projectRoot, opts);
787
- const knownSymlinkDirectories = symlinkHintManifest?.symlinkDirectories;
842
+ const rootMtime = symlinkHintManifest ? (await fsp.stat(projectRoot)).mtimeMs : undefined;
843
+ const symlinkHintIsFresh = symlinkHintManifest?.symlinkDirectoriesRootMtimeMs !== undefined &&
844
+ rootMtime === symlinkHintManifest.symlinkDirectoriesRootMtimeMs;
845
+ const knownSymlinkDirectories = symlinkHintIsFresh ? symlinkHintManifest?.symlinkDirectories : undefined;
788
846
  let discoveredSymlinkDirectories = knownSymlinkDirectories;
789
847
  const onSymlinkDirectoriesDiscovered = (directories) => {
790
848
  discoveredSymlinkDirectories = Array.from(directories);
791
849
  };
792
850
  // When the hint is unknown, listProjectFiles() and discoverProjectFiles() must run
793
- // sequentially rather than in Promise.all: both would otherwise start their own
794
- // full-tree symlink probe concurrently, since the callback only reports back after
795
- // listProjectFiles() resolves, too late to inform a probe discoverProjectFiles()
796
- // already started on its own. Sequencing costs a little parallelism on that one
797
- // cold-start case, but avoids paying for two full-tree walks instead of one. Once a
798
- // hint is known (the common warm case), both calls skip probing entirely, so running
799
- // them sequentially here costs no meaningful time either way.
851
+ // sequentially rather than in Promise.all to avoid duplicate full-tree probes.
800
852
  const discoveredFiles = await listProjectFiles(projectRoot, projectPatternsForLanguageExtensions(opts), {
801
853
  ...opts?.discovery,
802
854
  ...(opts?.logLevel ? { logLevel: opts.logLevel } : {}),
803
855
  ...(knownSymlinkDirectories !== undefined ? { knownSymlinkDirectories } : {}),
804
856
  onSymlinkDirectoriesDiscovered,
805
857
  });
806
- const additionalFileCandidates = normalizeIndexedFileInputs(projectRoot, opts?.additionalFiles ?? [], "Additional index file");
858
+ const additionalFileCandidates = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.additionalFiles ?? [], "Additional index file");
807
859
  const additionalFileExistence = await probePathExistence(additionalFileCandidates, buildConcurrency(opts));
808
860
  const additionalFiles = additionalFileCandidates.filter((file) => additionalFileExistence.get(file));
809
861
  const discoveredFileSet = new Set(discoveredFiles);
@@ -850,9 +902,11 @@ export async function buildProjectIndex(projectRoot, opts) {
850
902
  export async function buildProjectIndexFromFiles(projectRoot, inputFiles, opts) {
851
903
  try {
852
904
  const useDiskCache = (opts?.cache ?? "off") === "disk";
853
- return await buildIndexFromFileListShared(projectRoot, inputFiles, opts, {
905
+ const normalizedInputFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, inputFiles, "Index file");
906
+ return await buildIndexFromFileListShared(projectRoot, normalizedInputFiles, opts, {
854
907
  manifestMode: useDiskCache ? "read-only" : "off",
855
908
  warnNoFilesMessage: `Warning: No files provided for indexing in ${projectRoot}. Check the explicit file list and include/ignore filters. Diagnostic: codegraph doctor`,
909
+ confineReads: true,
856
910
  });
857
911
  }
858
912
  finally {
@@ -893,7 +947,7 @@ async function buildDeclaredScopeIndex(projectRoot, scopeFiles, opts) {
893
947
  */
894
948
  export async function buildProjectIndexIncremental(projectRoot, opts) {
895
949
  await initializeFileIdentityCaseSensitivity(projectRoot);
896
- clearImportResolutionCaches();
950
+ clearResolutionCaches();
897
951
  const graphOptions = normalizeGraphOptions(opts?.graph);
898
952
  const strictIncremental = opts?.incrementalStrict ?? false;
899
953
  if (strictIncremental && graphOptions.fast)
@@ -944,7 +998,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
944
998
  }
945
999
  startCheckProgress();
946
1000
  const manifestStart = performance.now();
947
- const manifest = await loadManifest(projectRoot, opts);
1001
+ const manifest = await loadManifest(projectRoot, opts, report);
948
1002
  if (timings)
949
1003
  timings.manifestMs = Math.round(performance.now() - manifestStart);
950
1004
  const manifestUsed = !!manifest;
@@ -1050,8 +1104,8 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1050
1104
  const trackedEntryKeys = Object.keys(trackedEntries);
1051
1105
  let manifestRequiresSanitization = manifestFileKeys.length !== trackedEntryKeys.length ||
1052
1106
  manifestFileKeys.some((file) => !Object.hasOwn(trackedEntries, file));
1053
- const explicitFiles = normalizeIndexedFileInputs(projectRoot, opts?.files ?? [], "Incremental file");
1054
- const additionalFiles = normalizeIndexedFileInputs(projectRoot, opts?.additionalFiles ?? [], "Additional index file");
1107
+ const explicitFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.files ?? [], "Incremental file");
1108
+ const additionalFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.additionalFiles ?? [], "Additional index file");
1055
1109
  const previousTransientFiles = sanitizeManifestTransientFilesForRoot(projectRoot, projectRoot, manifest.transientFiles).filter((file) => Object.hasOwn(trackedEntries, file));
1056
1110
  const previousTransientFileSet = new Set(previousTransientFiles);
1057
1111
  const needsGitScan = !!opts?.gitBase || !!opts?.changedSince;
@@ -1185,7 +1239,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1185
1239
  const explicitFileSet = new Set(explicitFiles);
1186
1240
  const explicitFilesCoverAllFiles = explicitFileSet.size === allFiles.size && [...allFiles].every((file) => explicitFileSet.has(file));
1187
1241
  const explicitFilesAreChangeInputs = !opts?.filesAreProjectScope;
1188
- if (explicitFileSet.size && explicitFilesAreChangeInputs && (!explicitFilesCoverAllFiles || report)) {
1242
+ if (explicitFileSet.size && explicitFilesAreChangeInputs && (!explicitFilesCoverAllFiles || opts?.report)) {
1189
1243
  explicitFileSet.forEach(markAsChanged);
1190
1244
  }
1191
1245
  dependentFilesOfDeletedTracked.forEach(markAsChanged);
@@ -1195,7 +1249,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1195
1249
  if (changedFiles.size || deletedTrackedFiles.size || manifestRequiresSanitization)
1196
1250
  return null;
1197
1251
  const manifestEntryMap = new Map(Object.entries(trackedEntries));
1198
- const snapshotLoad = await tryLoadProjectIndexSnapshot(projectRoot, opts, manifestEntryMap);
1252
+ const snapshotLoad = await tryLoadProjectIndexSnapshot(projectRoot, opts, manifestEntryMap, report);
1199
1253
  if (!snapshotLoad)
1200
1254
  return null;
1201
1255
  const snapshot = snapshotLoad.index;
@@ -1265,7 +1319,10 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1265
1319
  }
1266
1320
  const workspaceConfig = await loadWorkspaceConfig(projectRoot);
1267
1321
  const conc = buildConcurrency(opts);
1268
- const workerSetup = await setupWorkerPool(opts, allFiles.size);
1322
+ // Created below, once the changed-file set is known. Building it here would spawn a full
1323
+ // pool before the signature pass and the unchanged-snapshot early return, so a warm
1324
+ // no-change run paid for threads that never received a task.
1325
+ let workerSetup = emptyWorkerPoolSetup();
1269
1326
  try {
1270
1327
  const useGitSignatures = gitAvailable;
1271
1328
  const gitSigMap = useGitSignatures
@@ -1275,6 +1332,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1275
1332
  })
1276
1333
  : new Map();
1277
1334
  const fileSignatures = await prepareFileSignatures({
1335
+ projectRoot,
1278
1336
  files: Array.from(allFiles),
1279
1337
  opts,
1280
1338
  gitSigMap,
@@ -1300,8 +1358,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1300
1358
  changedFiles.add(file);
1301
1359
  }
1302
1360
  }
1361
+ const reverseDeps = buildTrackedFileReverseDependencies(trackedEntries);
1303
1362
  const invalidateCachedDependents = () => {
1304
- const dependentFilesOfChanged = collectTrackedFileDependents(trackedEntries, changedFiles);
1363
+ const dependentFilesOfChanged = collectTrackedFileDependents(trackedEntries, changedFiles, reverseDeps);
1305
1364
  for (const file of dependentFilesOfChanged) {
1306
1365
  const key = fileIdentityKey(file);
1307
1366
  if (modules.has(key)) {
@@ -1326,9 +1385,11 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1326
1385
  return unchangedSnapshot;
1327
1386
  }
1328
1387
  const snapshotModules = cacheEnabled
1329
- ? await tryLoadProjectSnapshotModules(projectRoot, opts, fileSignatures)
1388
+ ? await tryLoadProjectSnapshotModules(projectRoot, opts, fileSignatures, report)
1389
+ : null;
1390
+ const persistedBloomFilters = bloomFilterCache
1391
+ ? await tryLoadPersistedBloomFilters(projectRoot, opts, report)
1330
1392
  : null;
1331
- const persistedBloomFilters = bloomFilterCache ? await tryLoadPersistedBloomFilters(projectRoot, opts) : null;
1332
1393
  for (const file of allFiles) {
1333
1394
  if (changedFiles.has(file))
1334
1395
  continue;
@@ -1365,6 +1426,9 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1365
1426
  }
1366
1427
  invalidateCachedDependents();
1367
1428
  const changedList = Array.from(changedFiles);
1429
+ // Sized by the work that remains rather than the size of the project: an incremental build
1430
+ // touching a handful of files gets a handful of threads, or none.
1431
+ workerSetup = await setupWorkerPool(opts, countNativeWorkerEligibleFiles(changedList, opts?.languageExtensions));
1368
1432
  let updateStartedAt;
1369
1433
  if (changedList.length || deletedTrackedFiles.size) {
1370
1434
  updateStartedAt = performance.now();
@@ -1406,7 +1470,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1406
1470
  catch (error) {
1407
1471
  if (isNativeRequiredUnavailableError(error) || isNodeSqliteUnavailableError(error))
1408
1472
  throw error;
1409
- if (isUnsupportedParserInputError(error) || isNonNativeParserUnavailableError(error)) {
1473
+ if (isUnsupportedParserInputError(error)) {
1410
1474
  return [file, createEmptyModuleIndex(file)];
1411
1475
  }
1412
1476
  recordFileFailure(report, file, error);
@@ -1481,6 +1545,7 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1481
1545
  dynamicImportHeuristics: !!graphOptions.dynamicImportHeuristics,
1482
1546
  ...(opts?.native ? { native: opts.native } : {}),
1483
1547
  ...(opts?.languageExtensions ? { languageExtensions: opts.languageExtensions } : {}),
1548
+ threads: conc,
1484
1549
  ...(opts?.logLevel ? { logLevel: opts.logLevel } : {}),
1485
1550
  ...(graphOptions.resolutionHints ? { resolutionHints: graphOptions.resolutionHints } : {}),
1486
1551
  allFiles: Array.from(allFiles),
@@ -1498,6 +1563,16 @@ export async function buildProjectIndexIncremental(projectRoot, opts) {
1498
1563
  });
1499
1564
  if (timings)
1500
1565
  timings.graphMs = Math.round(performance.now() - graphStart);
1566
+ for (const file of new Set([...changedFiles, ...transientFiles])) {
1567
+ const signature = fileSignatures.get(file);
1568
+ if (!signature || manifestEntries.has(file))
1569
+ continue;
1570
+ manifestEntries.set(file, {
1571
+ sig: signature.sig,
1572
+ ...(signature.gitSig ? { gitSig: signature.gitSig } : {}),
1573
+ edges: [],
1574
+ });
1575
+ }
1501
1576
  await writeIndexManifestSnapshot({
1502
1577
  projectRoot,
1503
1578
  opts,
@@ -1565,8 +1640,8 @@ export async function buildGraphDelta(projectRoot, opts) {
1565
1640
  const strictIncremental = opts?.incrementalStrict ?? false;
1566
1641
  if (strictIncremental && graphOptions.fast)
1567
1642
  graphOptions.fast = false;
1568
- const explicitFiles = normalizeIndexedFileInputs(projectRoot, opts?.files ?? [], "Graph delta file");
1569
- const additionalFiles = normalizeIndexedFileInputs(projectRoot, opts?.additionalFiles ?? [], "Additional graph delta file");
1643
+ const explicitFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.files ?? [], "Graph delta file");
1644
+ const additionalFiles = await normalizeIndexedFileInputsWithinRoot(projectRoot, opts?.additionalFiles ?? [], "Additional graph delta file");
1570
1645
  const needsGitScan = !!opts?.gitBase || !!opts?.changedSince;
1571
1646
  const gitFiles = needsGitScan ? await listChangedFiles(projectRoot, buildIncrementalGitDiffOptions(opts)) : [];
1572
1647
  const { trackedFiles } = await partitionTrackedManifestFiles(trackedEntries);
@@ -1591,14 +1666,19 @@ export async function buildGraphDelta(projectRoot, opts) {
1591
1666
  }
1592
1667
  const candidateExistence = await probePathExistence([...explicitFiles, ...additionalFiles, ...manifestDiffFiles, ...gitFiles], buildConcurrency(opts));
1593
1668
  const existsInCandidateSnapshot = (file) => candidateExistence.get(file) ?? false;
1594
- const existingExplicitFiles = explicitFiles.filter(existsInCandidateSnapshot);
1669
+ const normalizeChangedFiles = (files) => files.map((file) => {
1670
+ if (!existsInCandidateSnapshot(file))
1671
+ return file;
1672
+ const [normalizedFile] = normalizeIndexedFileInputs(projectRoot, [file], "Graph delta file");
1673
+ return normalizedFile ?? file;
1674
+ }), normalizedManifestDiffFiles = normalizeChangedFiles(manifestDiffFiles), normalizedGitFiles = normalizeChangedFiles(gitFiles), existingExplicitFiles = explicitFiles.filter(existsInCandidateSnapshot);
1595
1675
  const existingAdditionalFiles = additionalFiles.filter(existsInCandidateSnapshot);
1596
1676
  const allFiles = new Set([
1597
1677
  ...trackedFiles,
1598
1678
  ...existingExplicitFiles,
1599
1679
  ...existingAdditionalFiles,
1600
- ...manifestDiffFiles.filter(existsInCandidateSnapshot),
1601
- ...gitFiles.filter(existsInCandidateSnapshot),
1680
+ ...normalizedManifestDiffFiles.filter((_, index) => existsInCandidateSnapshot(manifestDiffFiles[index])),
1681
+ ...normalizedGitFiles.filter((_, index) => existsInCandidateSnapshot(gitFiles[index])),
1602
1682
  ]);
1603
1683
  const changedFiles = new Set();
1604
1684
  const changedFileKeys = new Set();
@@ -1610,8 +1690,8 @@ export async function buildGraphDelta(projectRoot, opts) {
1610
1690
  changedFiles.add(file);
1611
1691
  };
1612
1692
  existingExplicitFiles.forEach(addChangedFile);
1613
- manifestDiffFiles.forEach(addChangedFile);
1614
- gitFiles.forEach(addChangedFile);
1693
+ normalizedManifestDiffFiles.forEach(addChangedFile);
1694
+ normalizedGitFiles.forEach(addChangedFile);
1615
1695
  if (languageExtensionsChanged) {
1616
1696
  for (const file of trackedFiles) {
1617
1697
  if (languageSupportChangedForFile(file))