gitnexus 1.6.5-rc.8 → 1.6.5

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 (335) hide show
  1. package/dist/_shared/scope-resolution/finalize-algorithm.js +10 -2
  2. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  3. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +26 -0
  4. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -1
  5. package/dist/_shared/scope-resolution/method-dispatch-index.js +22 -3
  6. package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -1
  7. package/dist/_shared/scope-resolution/registries/lookup-core.js +18 -1
  8. package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
  9. package/dist/_shared/scope-resolution/symbol-definition.d.ts +2 -0
  10. package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
  11. package/dist/cli/ai-context.d.ts +1 -0
  12. package/dist/cli/ai-context.js +70 -16
  13. package/dist/cli/analyze.d.ts +30 -2
  14. package/dist/cli/analyze.js +45 -5
  15. package/dist/cli/index.js +8 -1
  16. package/dist/cli/setup.js +18 -0
  17. package/dist/cli/wiki.d.ts +2 -0
  18. package/dist/cli/wiki.js +11 -0
  19. package/dist/core/augmentation/engine.js +24 -4
  20. package/dist/core/embeddings/http-client.js +22 -6
  21. package/dist/core/incremental/shadow-candidates.d.ts +44 -0
  22. package/dist/core/incremental/shadow-candidates.js +74 -0
  23. package/dist/core/incremental/subgraph-extract.d.ts +64 -0
  24. package/dist/core/incremental/subgraph-extract.js +111 -0
  25. package/dist/core/ingestion/call-processor.d.ts +12 -1
  26. package/dist/core/ingestion/call-processor.js +183 -47
  27. package/dist/core/ingestion/class-extractors/configs/c-cpp.js +38 -0
  28. package/dist/core/ingestion/class-extractors/generic.js +8 -0
  29. package/dist/core/ingestion/class-types.d.ts +15 -0
  30. package/dist/core/ingestion/community-processor.js +18 -0
  31. package/dist/core/ingestion/import-resolvers/standard.d.ts +5 -0
  32. package/dist/core/ingestion/import-resolvers/standard.js +31 -1
  33. package/dist/core/ingestion/import-resolvers/utils.js +4 -0
  34. package/dist/core/ingestion/languages/c-cpp.js +20 -2
  35. package/dist/core/ingestion/languages/cpp/adl.d.ts +141 -0
  36. package/dist/core/ingestion/languages/cpp/adl.js +478 -0
  37. package/dist/core/ingestion/languages/cpp/arity-metadata.d.ts +18 -0
  38. package/dist/core/ingestion/languages/cpp/arity-metadata.js +170 -0
  39. package/dist/core/ingestion/languages/cpp/arity.d.ts +17 -0
  40. package/dist/core/ingestion/languages/cpp/arity.js +31 -0
  41. package/dist/core/ingestion/languages/cpp/captures.d.ts +2 -0
  42. package/dist/core/ingestion/languages/cpp/captures.js +1131 -0
  43. package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +31 -0
  44. package/dist/core/ingestion/languages/cpp/conversion-rank.js +47 -0
  45. package/dist/core/ingestion/languages/cpp/file-local-linkage.d.ts +118 -0
  46. package/dist/core/ingestion/languages/cpp/file-local-linkage.js +266 -0
  47. package/dist/core/ingestion/languages/cpp/header-scan.d.ts +8 -0
  48. package/dist/core/ingestion/languages/cpp/header-scan.js +50 -0
  49. package/dist/core/ingestion/languages/cpp/import-decomposer.d.ts +19 -0
  50. package/dist/core/ingestion/languages/cpp/import-decomposer.js +111 -0
  51. package/dist/core/ingestion/languages/cpp/import-target.d.ts +10 -0
  52. package/dist/core/ingestion/languages/cpp/import-target.js +13 -0
  53. package/dist/core/ingestion/languages/cpp/index.d.ts +11 -0
  54. package/dist/core/ingestion/languages/cpp/index.js +11 -0
  55. package/dist/core/ingestion/languages/cpp/inline-namespaces.d.ts +67 -0
  56. package/dist/core/ingestion/languages/cpp/inline-namespaces.js +176 -0
  57. package/dist/core/ingestion/languages/cpp/interpret.d.ts +35 -0
  58. package/dist/core/ingestion/languages/cpp/interpret.js +113 -0
  59. package/dist/core/ingestion/languages/cpp/merge-bindings.d.ts +13 -0
  60. package/dist/core/ingestion/languages/cpp/merge-bindings.js +29 -0
  61. package/dist/core/ingestion/languages/cpp/query.d.ts +3 -0
  62. package/dist/core/ingestion/languages/cpp/query.js +508 -0
  63. package/dist/core/ingestion/languages/cpp/range-bindings.d.ts +20 -0
  64. package/dist/core/ingestion/languages/cpp/range-bindings.js +212 -0
  65. package/dist/core/ingestion/languages/cpp/scope-resolver.d.ts +17 -0
  66. package/dist/core/ingestion/languages/cpp/scope-resolver.js +246 -0
  67. package/dist/core/ingestion/languages/cpp/simple-hooks.d.ts +24 -0
  68. package/dist/core/ingestion/languages/cpp/simple-hooks.js +62 -0
  69. package/dist/core/ingestion/languages/cpp/two-phase-lookup.d.ts +76 -0
  70. package/dist/core/ingestion/languages/cpp/two-phase-lookup.js +195 -0
  71. package/dist/core/ingestion/languages/java/arity-metadata.d.ts +18 -0
  72. package/dist/core/ingestion/languages/java/arity-metadata.js +40 -0
  73. package/dist/core/ingestion/languages/java/arity.d.ts +10 -0
  74. package/dist/core/ingestion/languages/java/arity.js +24 -0
  75. package/dist/core/ingestion/languages/java/cache-stats.d.ts +15 -0
  76. package/dist/core/ingestion/languages/java/cache-stats.js +26 -0
  77. package/dist/core/ingestion/languages/java/captures.d.ts +17 -0
  78. package/dist/core/ingestion/languages/java/captures.js +187 -0
  79. package/dist/core/ingestion/languages/java/import-decomposer.d.ts +18 -0
  80. package/dist/core/ingestion/languages/java/import-decomposer.js +85 -0
  81. package/dist/core/ingestion/languages/java/import-target.d.ts +17 -0
  82. package/dist/core/ingestion/languages/java/import-target.js +100 -0
  83. package/dist/core/ingestion/languages/java/index.d.ts +29 -0
  84. package/dist/core/ingestion/languages/java/index.js +29 -0
  85. package/dist/core/ingestion/languages/java/interpret.d.ts +13 -0
  86. package/dist/core/ingestion/languages/java/interpret.js +131 -0
  87. package/dist/core/ingestion/languages/java/merge-bindings.d.ts +12 -0
  88. package/dist/core/ingestion/languages/java/merge-bindings.js +40 -0
  89. package/dist/core/ingestion/languages/java/query.d.ts +30 -0
  90. package/dist/core/ingestion/languages/java/query.js +192 -0
  91. package/dist/core/ingestion/languages/java/receiver-binding.d.ts +11 -0
  92. package/dist/core/ingestion/languages/java/receiver-binding.js +95 -0
  93. package/dist/core/ingestion/languages/java/scope-resolver.d.ts +50 -0
  94. package/dist/core/ingestion/languages/java/scope-resolver.js +74 -0
  95. package/dist/core/ingestion/languages/java/simple-hooks.d.ts +13 -0
  96. package/dist/core/ingestion/languages/java/simple-hooks.js +34 -0
  97. package/dist/core/ingestion/languages/java.js +11 -0
  98. package/dist/core/ingestion/languages/php/arity-metadata.d.ts +28 -0
  99. package/dist/core/ingestion/languages/php/arity-metadata.js +63 -0
  100. package/dist/core/ingestion/languages/php/arity.d.ts +25 -0
  101. package/dist/core/ingestion/languages/php/arity.js +40 -0
  102. package/dist/core/ingestion/languages/php/cache-stats.d.ts +15 -0
  103. package/dist/core/ingestion/languages/php/cache-stats.js +26 -0
  104. package/dist/core/ingestion/languages/php/captures.d.ts +34 -0
  105. package/dist/core/ingestion/languages/php/captures.js +739 -0
  106. package/dist/core/ingestion/languages/php/import-decomposer.d.ts +28 -0
  107. package/dist/core/ingestion/languages/php/import-decomposer.js +265 -0
  108. package/dist/core/ingestion/languages/php/import-target.d.ts +47 -0
  109. package/dist/core/ingestion/languages/php/import-target.js +100 -0
  110. package/dist/core/ingestion/languages/php/index.d.ts +68 -0
  111. package/dist/core/ingestion/languages/php/index.js +72 -0
  112. package/dist/core/ingestion/languages/php/interpret.d.ts +36 -0
  113. package/dist/core/ingestion/languages/php/interpret.js +241 -0
  114. package/dist/core/ingestion/languages/php/merge-bindings.d.ts +19 -0
  115. package/dist/core/ingestion/languages/php/merge-bindings.js +47 -0
  116. package/dist/core/ingestion/languages/php/namespace-siblings.d.ts +51 -0
  117. package/dist/core/ingestion/languages/php/namespace-siblings.js +288 -0
  118. package/dist/core/ingestion/languages/php/query.d.ts +32 -0
  119. package/dist/core/ingestion/languages/php/query.js +326 -0
  120. package/dist/core/ingestion/languages/php/receiver-binding.d.ts +36 -0
  121. package/dist/core/ingestion/languages/php/receiver-binding.js +128 -0
  122. package/dist/core/ingestion/languages/php/scope-resolver.d.ts +23 -0
  123. package/dist/core/ingestion/languages/php/scope-resolver.js +358 -0
  124. package/dist/core/ingestion/languages/php/simple-hooks.d.ts +42 -0
  125. package/dist/core/ingestion/languages/php/simple-hooks.js +111 -0
  126. package/dist/core/ingestion/languages/php.d.ts +0 -7
  127. package/dist/core/ingestion/languages/php.js +15 -0
  128. package/dist/core/ingestion/markdown-processor.js +6 -1
  129. package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
  130. package/dist/core/ingestion/model/symbol-table.js +3 -0
  131. package/dist/core/ingestion/parsing-processor.d.ts +22 -2
  132. package/dist/core/ingestion/parsing-processor.js +123 -50
  133. package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +54 -2
  134. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +5 -0
  135. package/dist/core/ingestion/pipeline-phases/parse-impl.js +119 -11
  136. package/dist/core/ingestion/pipeline-phases/parse.d.ts +14 -0
  137. package/dist/core/ingestion/pipeline.d.ts +13 -0
  138. package/dist/core/ingestion/registry-primary-flag.js +2 -0
  139. package/dist/core/ingestion/scope-extractor.js +4 -0
  140. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +167 -0
  141. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +3 -0
  142. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +1 -0
  143. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +12 -0
  144. package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.d.ts +1 -1
  145. package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +12 -2
  146. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +16 -0
  147. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +36 -0
  148. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +204 -13
  149. package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +1 -1
  150. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +55 -4
  151. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +186 -5
  152. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +10 -1
  153. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +207 -9
  154. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +13 -1
  155. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +6 -0
  156. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +17 -0
  157. package/dist/core/ingestion/scope-resolution/pipeline/run.js +86 -8
  158. package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +30 -0
  159. package/dist/core/ingestion/scope-resolution/scope/walkers.js +90 -8
  160. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  161. package/dist/core/ingestion/tree-sitter-queries.js +23 -0
  162. package/dist/core/ingestion/utils/ast-helpers.js +6 -1
  163. package/dist/core/ingestion/utils/template-arguments.d.ts +11 -0
  164. package/dist/core/ingestion/utils/template-arguments.js +65 -0
  165. package/dist/core/ingestion/workers/parse-worker.d.ts +3 -0
  166. package/dist/core/ingestion/workers/parse-worker.js +42 -1
  167. package/dist/core/lbug/lbug-adapter.d.ts +39 -0
  168. package/dist/core/lbug/lbug-adapter.js +348 -48
  169. package/dist/core/run-analyze.d.ts +2 -0
  170. package/dist/core/run-analyze.js +323 -29
  171. package/dist/core/search/hybrid-search.d.ts +3 -0
  172. package/dist/core/search/hybrid-search.js +23 -6
  173. package/dist/core/wiki/generator.js +4 -3
  174. package/dist/core/wiki/html-viewer.js +2 -1
  175. package/dist/core/wiki/llm-client.d.ts +4 -0
  176. package/dist/core/wiki/llm-client.js +3 -3
  177. package/dist/core/wiki/mermaid-sanitizer.d.ts +2 -0
  178. package/dist/core/wiki/mermaid-sanitizer.js +100 -0
  179. package/dist/mcp/local/local-backend.js +20 -7
  180. package/dist/storage/file-hash.d.ts +47 -0
  181. package/dist/storage/file-hash.js +86 -0
  182. package/dist/storage/parse-cache.d.ts +73 -0
  183. package/dist/storage/parse-cache.js +253 -0
  184. package/dist/storage/repo-manager.d.ts +41 -1
  185. package/dist/storage/repo-manager.js +61 -6
  186. package/hooks/claude/gitnexus-hook.cjs +42 -4
  187. package/hooks/claude/hook-db-lock-probe.cjs +238 -0
  188. package/hooks/claude/hook-lock.cjs +119 -0
  189. package/hooks/claude/win-rm-list-json.ps1 +76 -0
  190. package/package.json +1 -1
  191. package/scripts/build.js +6 -2
  192. package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +16 -16
  193. package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +16 -16
  194. package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +16 -16
  195. package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +16 -16
  196. package/web/assets/{agent-BpHQleHE.js → agent-D2kLt6Dl.js} +91 -91
  197. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +1 -0
  198. package/web/assets/architectureDiagram-UL44E2DR-DvIkEGkp.js +36 -0
  199. package/web/assets/blockDiagram-7IZFK4PR-B4niSLvR.js +132 -0
  200. package/web/assets/{c4Diagram-DFAF54RM-DeJV1rCn.js → c4Diagram-Y2BXMSZH-DIzEXalR.js} +6 -6
  201. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +4 -0
  202. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +1 -0
  203. package/web/assets/{chunk-7RZVMHOQ-BdIU-RGO.js → chunk-3SSMPTDK-BzGeeheI.js} +1 -1
  204. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +159 -0
  205. package/web/assets/chunk-5IMINLNL-CnTLsXIV.js +1 -0
  206. package/web/assets/chunk-5VCL7Z4A-w1BCx98Z.js +1 -0
  207. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +1 -0
  208. package/web/assets/chunk-67TQ5CYL-CChC2cAv.js +124 -0
  209. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +10 -0
  210. package/web/assets/chunk-7W6UQGC5-CgFyfZ6k.js +1 -0
  211. package/web/assets/chunk-AQ6EADP3-CCFje6lL.js +1 -0
  212. package/web/assets/{chunk-KSICW3F5-C2tZmXwv.js → chunk-AZZRMDJM-5E9ARdDQ.js} +1 -1
  213. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +1 -0
  214. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +1 -0
  215. package/web/assets/chunk-INKRHTLW-ELpfuk9h.js +70 -0
  216. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +1 -0
  217. package/web/assets/{chunk-AEOMTBSW-D7qjBMHW.js → chunk-JQRUD6KW-Dcq_Qnyy.js} +1 -1
  218. package/web/assets/chunk-KGFNY3KK-W-VR57xb.js +62 -0
  219. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +1 -0
  220. package/web/assets/chunk-KNLZD3CH-BuZBOcso.js +1 -0
  221. package/web/assets/chunk-KRXBNO2N-DH2NPM7I.js +1 -0
  222. package/web/assets/chunk-LCXTWHL2-CqJ0oo1x.js +231 -0
  223. package/web/assets/chunk-LII3EMHJ-3X33tCpU.js +1 -0
  224. package/web/assets/chunk-QA3QBVWF-D5Ha3GgB.js +2 -0
  225. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +1 -0
  226. package/web/assets/chunk-RG4AUYOV-D0M6vdq9.js +206 -0
  227. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +1 -0
  228. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +1 -0
  229. package/web/assets/chunk-T2UQINTJ-kGYG7ppP.js +1 -0
  230. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +1 -0
  231. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +1 -0
  232. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +1 -0
  233. package/web/assets/chunk-UY5QBCOK-Du-c56gs.js +1 -0
  234. package/web/assets/chunk-W44A43WB-lrCpuupA.js +1 -0
  235. package/web/assets/chunk-ZXARS5L4-CSZRiyOf.js +1 -0
  236. package/web/assets/classDiagram-KGZ6W3CR-BB-saqC1.js +1 -0
  237. package/web/assets/classDiagram-v2-72OJOZXJ-Bp2bAlS5.js +1 -0
  238. package/web/assets/cose-bilkent-UX7MHV2Q-BHv2bbtl.js +1 -0
  239. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +4 -0
  240. package/web/assets/diagram-3NCE3AQN-BUxnDPOY.js +43 -0
  241. package/web/assets/diagram-GF46GFSD-BJTyqqvI.js +24 -0
  242. package/web/assets/diagram-HNR7UZ2L-fUWreZzx.js +3 -0
  243. package/web/assets/diagram-QXG6HAR7-DilMHamP.js +24 -0
  244. package/web/assets/diagram-WEQXMOUZ-8KUrarg1.js +10 -0
  245. package/web/assets/erDiagram-L5TCEMPS-Doj9mSiW.js +85 -0
  246. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +1 -0
  247. package/web/assets/{flowDiagram-OTCZ4VVT-aAZw4c_M.js → flowDiagram-H6V6AXG4-BOSR-i3p.js} +12 -12
  248. package/web/assets/ganttDiagram-JCBTUEKG-BHQssTz6.js +292 -0
  249. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +1 -0
  250. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +106 -0
  251. package/web/assets/index-j4-NuleT.js +623 -0
  252. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +1 -0
  253. package/web/assets/infoDiagram-3YFTVSEB-Ce_TvtaV.js +2 -0
  254. package/web/assets/{ishikawaDiagram-YMYX4NHK-BF8AtDaj.js → ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js} +6 -6
  255. package/web/assets/journeyDiagram-M6C3CM3L-DNPYCpvq.js +139 -0
  256. package/web/assets/kanban-definition-75IXJCU3-yYdfm8Kk.js +89 -0
  257. package/web/assets/{katex-GD7MH7QM-CJiOjBBJ.js → katex-K3KEBU37-CrVLz8l7.js} +1 -1
  258. package/web/assets/mindmap-definition-2TDM6QVE-DFNEKM77.js +96 -0
  259. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +1 -0
  260. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +1 -0
  261. package/web/assets/pieDiagram-CU6KROY3-iZAqpvhd.js +30 -0
  262. package/web/assets/quadrantDiagram-VICAPDV7-bAm6Hi_5.js +7 -0
  263. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +1 -0
  264. package/web/assets/requirementDiagram-JXO7QTGE-CtDijhnf.js +84 -0
  265. package/web/assets/sankeyDiagram-URQDO5SZ-LFJz53u5.js +40 -0
  266. package/web/assets/sequenceDiagram-VS2MUI6T-BdjvyCHM.js +162 -0
  267. package/web/assets/stateDiagram-7D4R322I-e5odN9fG.js +1 -0
  268. package/web/assets/stateDiagram-v2-36443NZ5-vPsvjR2D.js +1 -0
  269. package/web/assets/timeline-definition-O6YCAMPW-DPAksNQp.js +120 -0
  270. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +1 -0
  271. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +1 -0
  272. package/web/assets/vennDiagram-MWXL3ELB-Dtlfdt7J.js +34 -0
  273. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +1 -0
  274. package/web/assets/wardleyDiagram-CUQ6CDDI-B23uRMUC.js +78 -0
  275. package/web/assets/{xychartDiagram-ZHJ5623Y-DZ7fP1_3.js → xychartDiagram-N2JHSOCM-DxwHeksW.js} +6 -6
  276. package/web/index.html +13 -2
  277. package/web/assets/architecture-YZFGNWBL-S5CXDPWN-BUzkWgDl.js +0 -1
  278. package/web/assets/architectureDiagram-EMZXCZ2Q-CXbzok1G.js +0 -36
  279. package/web/assets/blockDiagram-IGV67L2C-DA1QJ4ZB.js +0 -132
  280. package/web/assets/chunk-3GS5O3IE-B8hpnia8.js +0 -231
  281. package/web/assets/chunk-3YCYZ6SJ-B-BVu21C.js +0 -1
  282. package/web/assets/chunk-6NTNNK5N-DW-jYSDr.js +0 -1
  283. package/web/assets/chunk-A34GCYZU-BbZl-IKy.js +0 -1
  284. package/web/assets/chunk-DJ7UZH7F-B5tMfF87.js +0 -1
  285. package/web/assets/chunk-DKKBVRCY-Djm-6K_e.js +0 -4
  286. package/web/assets/chunk-DU5LTGQ6-QPoynYcp.js +0 -1
  287. package/web/assets/chunk-FXACKDTF-jieSmbe2.js +0 -159
  288. package/web/assets/chunk-H3VCZNTA-8EMHZ3SV.js +0 -1
  289. package/web/assets/chunk-HN6EAY2L-CgE_agsD.js +0 -1
  290. package/web/assets/chunk-O5ABG6QK-DEZV1O19.js +0 -1
  291. package/web/assets/chunk-PK6DOVAG-BXv0JnsJ.js +0 -206
  292. package/web/assets/chunk-RNJOYNJ4-BiBkF9dN.js +0 -1
  293. package/web/assets/chunk-RWUO3TPN-DTWzAhQ1.js +0 -1
  294. package/web/assets/chunk-TBF5ZNIQ-BSl6s9lT.js +0 -1
  295. package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +0 -1
  296. package/web/assets/chunk-TYMNRAUI-D1NDLIMG.js +0 -1
  297. package/web/assets/chunk-VELTKBKT-C9dVN39o.js +0 -1
  298. package/web/assets/chunk-W7ZLLLMY-Bu-cdLzs.js +0 -1
  299. package/web/assets/chunk-WSB5WSVC-Dor71SOz.js +0 -1
  300. package/web/assets/chunk-XGPFEOL4-CUonLRle.js +0 -1
  301. package/web/assets/classDiagram-PPOCWD7C-Cdd6UdVv.js +0 -1
  302. package/web/assets/classDiagram-v2-23LJLIIU-DNhxY2Ib.js +0 -1
  303. package/web/assets/cose-bilkent-PNC4W37J-DdZq7Qz_.js +0 -1
  304. package/web/assets/dagre-E77IOHMT-Cfj_6e17.js +0 -4
  305. package/web/assets/diagram-H7BISOXX-BNvpsrBv.js +0 -43
  306. package/web/assets/diagram-JC5VWROH-Cn0rtDbJ.js +0 -24
  307. package/web/assets/diagram-LXUTUG65-CHfoVKNm.js +0 -10
  308. package/web/assets/diagram-WEHSV5V5-BLxHksnu.js +0 -24
  309. package/web/assets/erDiagram-GCSMX5X6-DfdN6iqF.js +0 -85
  310. package/web/assets/ganttDiagram-MUNLMDZQ-BEfC_7Or.js +0 -292
  311. package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-B6ZeRLP0.js +0 -1
  312. package/web/assets/gitGraphDiagram-3HKGZ4G3-CG0kC8Q5.js +0 -106
  313. package/web/assets/index-3NUCUW2s.js +0 -886
  314. package/web/assets/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +0 -1
  315. package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +0 -2
  316. package/web/assets/journeyDiagram-SO5T7YLQ-BW8oKa3N.js +0 -139
  317. package/web/assets/kanban-definition-LJHFXRCJ-DzbOsR-2.js +0 -89
  318. package/web/assets/mindmap-definition-2EUWGEK5-BIXGQALq.js +0 -96
  319. package/web/assets/packet-4T2RLAQJ-EV4IVRXR-Bs7ysNMU.js +0 -1
  320. package/web/assets/pie-ZZUOXDRM-N23DN5KN-Csi8nnbH.js +0 -1
  321. package/web/assets/pieDiagram-3IATQBI2-QY-u7P6a.js +0 -30
  322. package/web/assets/quadrantDiagram-E256RVCF-Di4aNiU8.js +0 -7
  323. package/web/assets/radar-PYXPWWZC-P6TP7ZYP-DJlyXh2-.js +0 -1
  324. package/web/assets/requirementDiagram-M5DCFWZL-CzUUrhQD.js +0 -84
  325. package/web/assets/sankeyDiagram-L3NBLAOT-D2fbMiIU.js +0 -10
  326. package/web/assets/sequenceDiagram-ZOUHS735-BNdkqguh.js +0 -157
  327. package/web/assets/stateDiagram-MLPALWAM-51_Q2w2L.js +0 -1
  328. package/web/assets/stateDiagram-v2-B5LQ5ZB2-8nHs2aNE.js +0 -1
  329. package/web/assets/timeline-definition-5SPVSISX-DkMiGj4Z.js +0 -120
  330. package/web/assets/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +0 -1
  331. package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +0 -1
  332. package/web/assets/vennDiagram-IE5QUKF5-BCxMmf9q.js +0 -34
  333. package/web/assets/wardley-RL74JXVD-BCRCBASE-CMStJhpn.js +0 -1
  334. package/web/assets/wardleyDiagram-XU3VSMPF-ijlLF77s.js +0 -20
  335. /package/web/assets/{context-builder-CqQNhRj1.js → context-builder-_HS0v2ma.js} +0 -0
@@ -86,6 +86,20 @@ function ensureHeap() {
86
86
  }
87
87
  return true;
88
88
  }
89
+ /**
90
+ * Whether the post-index skill step should run.
91
+ *
92
+ * The gated block does two things in sequence: (1) generates the community
93
+ * skill files from `--skills`, and (2) re-runs `generateAIContextFiles` so
94
+ * AGENTS.md/CLAUDE.md can reference the freshly written skills. Both are
95
+ * suppressed together — `--index-only` drops the entire step, not just the
96
+ * community-skill write. Name retained for the test contract; see call site
97
+ * in `analyzeCommand` for the AGENTS.md/CLAUDE.md re-generation it also gates.
98
+ *
99
+ * Kept as a pure helper so the `--index-only --skills` contract is unit-tested
100
+ * without booting the full analyze pipeline (#742 review).
101
+ */
102
+ export const shouldGenerateCommunitySkillFiles = (options, pipelineResult) => Boolean(options?.skills && pipelineResult && !options?.indexOnly);
89
103
  export const analyzeCommand = async (inputPath, options) => {
90
104
  if (ensureHeap())
91
105
  return;
@@ -151,6 +165,15 @@ export const analyzeCommand = async (inputPath, options) => {
151
165
  process.env.GITNEXUS_EMBEDDING_DEVICE = options.embeddingDevice;
152
166
  }
153
167
  console.log('\n GitNexus Analyzer\n');
168
+ // `--index-only` is the stronger contract — it suppresses every form of file
169
+ // injection, including community skill writes that `--skills` would normally
170
+ // produce. Surface the override explicitly so users don't wonder why a
171
+ // pipeline re-index ran but no skill files appeared. The pipeline still
172
+ // re-runs (see `force: options?.force || options?.skills` below); the warning
173
+ // is purely about the dropped post-index write step.
174
+ if (options?.indexOnly && options?.skills) {
175
+ console.log(' Note: --index-only overrides --skills; community skill files will not be written.\n');
176
+ }
154
177
  let repoPath;
155
178
  if (inputPath) {
156
179
  repoPath = path.resolve(inputPath);
@@ -285,6 +308,9 @@ export const analyzeCommand = async (inputPath, options) => {
285
308
  const t0 = Date.now();
286
309
  // ── Run shared analysis orchestrator ───────────────────────────────
287
310
  try {
311
+ const skipAll = options?.indexOnly;
312
+ const skipAgentsMd = skipAll || options?.skipAgentsMd;
313
+ const skipSkills = skipAll || options?.skipSkills;
288
314
  const result = await runFullAnalysis(repoPath, {
289
315
  // Pipeline re-index — OR'd with --skills because skill generation
290
316
  // needs a fresh pipelineResult. Has no bearing on the registry
@@ -294,8 +320,14 @@ export const analyzeCommand = async (inputPath, options) => {
294
320
  embeddingsNodeLimit,
295
321
  dropEmbeddings: options?.dropEmbeddings,
296
322
  skipGit: options?.skipGit,
297
- skipAgentsMd: options?.skipAgentsMd,
298
- noStats: options?.noStats,
323
+ skipAgentsMd,
324
+ skipSkills,
325
+ // commander.js `.option('--no-stats', …)` registers the flag as
326
+ // `options.stats` (boolean, default true; `false` when the user
327
+ // passed --no-stats). Reading `options?.noStats` here returns
328
+ // undefined every time, so the flag was a no-op on the markdown
329
+ // rewrite path before this fix. See #1477.
330
+ noStats: options?.stats === false,
299
331
  registryName: options?.name,
300
332
  // Registry-collision bypass — its own CLI flag, intentionally NOT
301
333
  // overloading --force. A user who hits the collision guard should
@@ -335,8 +367,10 @@ export const analyzeCommand = async (inputPath, options) => {
335
367
  // exit code and an actionable error instead of being mistaken for
336
368
  // a healthy index.
337
369
  await assertAnalysisFinalized(repoPath);
338
- // Skill generation (CLI-only, uses pipeline result from analysis)
339
- if (options?.skills && result.pipelineResult) {
370
+ // Skill generation (CLI-only, uses pipeline result from analysis).
371
+ // Gated so `--index-only --skills` skips community skill writes too
372
+ // (`shouldGenerateCommunitySkillFiles` — see unit test).
373
+ if (shouldGenerateCommunitySkillFiles(options, result.pipelineResult)) {
340
374
  updateBar(99, 'Generating skill files...');
341
375
  try {
342
376
  const { generateSkillFiles } = await import('./skill-gen.js');
@@ -364,7 +398,13 @@ export const analyzeCommand = async (inputPath, options) => {
364
398
  communities: s.communities,
365
399
  clusters: aggregatedClusterCount,
366
400
  processes: s.processes,
367
- }, skillResult.skills, { skipAgentsMd: options?.skipAgentsMd, noStats: options?.noStats });
401
+ }, skillResult.skills, {
402
+ skipAgentsMd,
403
+ skipSkills,
404
+ // Mirror runFullAnalysis `noStats` bridge (#1477) — same expression;
405
+ // exercised on the `--skills` path by analyze-no-stats-bridge.test.ts.
406
+ noStats: options?.stats === false,
407
+ });
368
408
  }
369
409
  }
370
410
  catch {
package/dist/cli/index.js CHANGED
@@ -21,9 +21,14 @@ program
21
21
  'Optional [limit] overrides the 50,000-node safety cap; pass 0 to disable the cap entirely.')
22
22
  .option('--drop-embeddings', 'Drop existing embeddings on rebuild. By default, an `analyze` without `--embeddings` ' +
23
23
  'preserves any embeddings already present in the index.')
24
- .option('--skills', 'Generate repo-specific skill files from detected communities')
24
+ .option('--skills', 'Generate repo-specific skill files from detected communities ' +
25
+ '(no-op when --index-only is also set).')
25
26
  .option('--skip-agents-md', 'Skip updating the gitnexus section in AGENTS.md and CLAUDE.md')
26
27
  .option('--no-stats', 'Omit volatile file/symbol counts from AGENTS.md and CLAUDE.md')
28
+ .option('--skip-skills', 'Skip installing standard GitNexus skill files under .claude/skills/gitnexus/. ' +
29
+ 'Does not suppress community skills from --skills (those use .claude/skills/generated/). ' +
30
+ 'Use --index-only to skip all AI-context file injection.')
31
+ .option('--index-only', 'Pure index mode: skip all file injection (AGENTS.md, CLAUDE.md, skills)')
27
32
  .option('--skip-git', 'Treat the provided path/cwd as the index root and skip parent git-root discovery')
28
33
  .option('--name <alias>', 'Register this repo under a custom name in ~/.gitnexus/registry.json ' +
29
34
  '(disambiguates repos whose paths share a basename, e.g. two different .../app folders)')
@@ -98,6 +103,8 @@ program
98
103
  .option('--reasoning-model', 'Mark deployment as reasoning model (o1/o3/o4-mini) — strips temperature, uses max_completion_tokens')
99
104
  .option('--no-reasoning-model', 'Disable reasoning model mode (overrides saved config)')
100
105
  .option('--concurrency <n>', 'Parallel LLM calls (default: 3)', '3')
106
+ .option('--timeout <seconds>', 'Per-attempt LLM request timeout in seconds (default: 60)')
107
+ .option('--retries <n>', 'Max LLM retry attempts per request (default: 3)')
101
108
  .option('--gist', 'Publish wiki as a public GitHub Gist after generation')
102
109
  .option('-v, --verbose', 'Enable verbose output (show LLM commands and responses)')
103
110
  .option('--review', 'Stop after grouping to review module structure before generating pages')
package/dist/cli/setup.js CHANGED
@@ -308,6 +308,24 @@ async function installClaudeCodeHooks(result) {
308
308
  catch {
309
309
  // Script not found in source — skip
310
310
  }
311
+ try {
312
+ await fs.copyFile(path.join(pluginHooksPath, 'hook-lock.cjs'), path.join(destHooksDir, 'hook-lock.cjs'));
313
+ }
314
+ catch {
315
+ // Helper not found in source — skip
316
+ }
317
+ try {
318
+ await fs.copyFile(path.join(pluginHooksPath, 'hook-db-lock-probe.cjs'), path.join(destHooksDir, 'hook-db-lock-probe.cjs'));
319
+ }
320
+ catch {
321
+ // Helper not found in source — skip
322
+ }
323
+ try {
324
+ await fs.copyFile(path.join(pluginHooksPath, 'win-rm-list-json.ps1'), path.join(destHooksDir, 'win-rm-list-json.ps1'));
325
+ }
326
+ catch {
327
+ // Helper not found in source — skip
328
+ }
311
329
  const hookPath = path.join(destHooksDir, 'gitnexus-hook.cjs').replace(/\\/g, '/');
312
330
  // Escape backslashes FIRST, then quotes (CodeQL js/incomplete-sanitization).
313
331
  // The previous shape `replace(/"/g, '\\"')` alone would let `path\with"quote`
@@ -17,5 +17,7 @@ export interface WikiCommandOptions {
17
17
  provider?: LLMProvider;
18
18
  verbose?: boolean;
19
19
  review?: boolean;
20
+ timeout?: string;
21
+ retries?: string;
20
22
  }
21
23
  export declare const wikiCommand: (inputPath?: string, options?: WikiCommandOptions) => Promise<void>;
package/dist/cli/wiki.js CHANGED
@@ -304,6 +304,17 @@ export const wikiCommand = async (inputPath, options) => {
304
304
  }
305
305
  }
306
306
  }
307
+ // ── Apply per-run overrides not saved to config ────────────────────
308
+ if (options?.timeout) {
309
+ const secs = parseInt(options.timeout, 10);
310
+ if (!isNaN(secs) && secs > 0)
311
+ llmConfig.requestTimeoutMs = secs * 1000;
312
+ }
313
+ if (options?.retries) {
314
+ const n = parseInt(options.retries, 10);
315
+ if (!isNaN(n) && n > 0)
316
+ llmConfig.maxAttempts = n;
317
+ }
307
318
  // ── Setup progress bar with elapsed timer ──────────────────────────
308
319
  const bar = new cliProgress.SingleBar({
309
320
  format: ' {bar} {percentage}% | {phase}',
@@ -76,6 +76,9 @@ async function findRepoForCwd(cwd) {
76
76
  export async function augment(pattern, cwd) {
77
77
  if (!pattern || pattern.length < 3)
78
78
  return '';
79
+ const patternFirstWord = pattern.trim().replace(/'/g, "''").split(/\s+/)[0];
80
+ if (!patternFirstWord || patternFirstWord.length < 2)
81
+ return '';
79
82
  const workDir = cwd || process.cwd();
80
83
  try {
81
84
  const repo = await findRepoForCwd(workDir);
@@ -90,9 +93,7 @@ export async function augment(pattern, cwd) {
90
93
  await initLbug(repoId, repo.lbugPath);
91
94
  }
92
95
  // Step 1: BM25 search (fast, no embeddings)
93
- const { results: bm25Results } = await searchFTSFromLbug(pattern, 10, repoId);
94
- if (bm25Results.length === 0)
95
- return '';
96
+ const { results: bm25Results, ftsAvailable } = await searchFTSFromLbug(pattern, 10, repoId);
96
97
  // Step 2: Map BM25 file results to symbols
97
98
  const symbolMatches = [];
98
99
  for (const result of bm25Results.slice(0, 5)) {
@@ -100,7 +101,7 @@ export async function augment(pattern, cwd) {
100
101
  try {
101
102
  const symbols = await executeQuery(repoId, `
102
103
  MATCH (n) WHERE n.filePath = '${escaped}'
103
- AND n.name CONTAINS '${pattern.replace(/'/g, "''").split(/\s+/)[0]}'
104
+ AND n.name CONTAINS '${patternFirstWord}'
104
105
  RETURN n.id AS id, n.name AS name, labels(n)[0] AS type, n.filePath AS filePath
105
106
  LIMIT 3
106
107
  `);
@@ -118,6 +119,25 @@ export async function augment(pattern, cwd) {
118
119
  /* skip */
119
120
  }
120
121
  }
122
+ // When FTS indexes are unavailable (read-only DB, first run before indexes are built),
123
+ // fall back to a direct name CONTAINS query so enrichment still works.
124
+ if (symbolMatches.length === 0 && !ftsAvailable) {
125
+ const fallbackRows = await executeQuery(repoId, `
126
+ MATCH (n)
127
+ WHERE n.name CONTAINS '${patternFirstWord}'
128
+ RETURN n.id AS id, n.name AS name, labels(n)[0] AS type, n.filePath AS filePath
129
+ LIMIT 5
130
+ `).catch(() => []);
131
+ for (const sym of fallbackRows) {
132
+ symbolMatches.push({
133
+ nodeId: sym.id || sym[0],
134
+ name: sym.name || sym[1],
135
+ type: sym.type || sym[2],
136
+ filePath: sym.filePath || sym[3],
137
+ score: 1.0,
138
+ });
139
+ }
140
+ }
121
141
  if (symbolMatches.length === 0)
122
142
  return '';
123
143
  // Step 3: Batch-fetch callers/callees/processes/cohesion for top matches
@@ -30,8 +30,11 @@ const readConfig = () => {
30
30
  const rawDims = process.env.GITNEXUS_EMBEDDING_DIMS;
31
31
  let dimensions;
32
32
  if (rawDims !== undefined) {
33
+ if (!/^\d+$/.test(rawDims)) {
34
+ throw new Error(`GITNEXUS_EMBEDDING_DIMS must be a positive integer, got "${rawDims}"`);
35
+ }
33
36
  const parsed = parseInt(rawDims, 10);
34
- if (Number.isNaN(parsed) || parsed <= 0) {
37
+ if (parsed <= 0) {
35
38
  throw new Error(`GITNEXUS_EMBEDDING_DIMS must be a positive integer, got "${rawDims}"`);
36
39
  }
37
40
  dimensions = parsed;
@@ -73,9 +76,22 @@ const safeUrl = (url) => {
73
76
  * @param model - Model name for the request body
74
77
  * @param apiKey - Bearer token (only used in Authorization header)
75
78
  * @param batchIndex - Logical batch number (for error context)
76
- * @param attempt - Current retry attempt (internal)
79
+ * @param dimensions - Optional output-vector size. When provided, sent as
80
+ * the `dimensions` field in the request body. Endpoints that implement
81
+ * Matryoshka truncation (OpenAI text-embedding-3-*, Cohere embed-v3,
82
+ * Voyage) return a truncated vector at that size; endpoints that do not
83
+ * recognise the field may ignore it or return 400. Leave
84
+ * `GITNEXUS_EMBEDDING_DIMS` unset for strict backends that reject
85
+ * unknown fields.
77
86
  */
78
- const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0) => {
87
+ const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0, dimensions) => {
88
+ const requestBody = {
89
+ input: batch,
90
+ model,
91
+ };
92
+ if (dimensions !== undefined) {
93
+ requestBody.dimensions = dimensions;
94
+ }
79
95
  let resp;
80
96
  try {
81
97
  resp = await resilientFetch(url, {
@@ -85,7 +101,7 @@ const httpEmbedBatch = async (url, batch, model, apiKey, batchIndex = 0) => {
85
101
  'Content-Type': 'application/json',
86
102
  Authorization: `Bearer ${apiKey}`,
87
103
  },
88
- body: JSON.stringify({ input: batch, model }),
104
+ body: JSON.stringify(requestBody),
89
105
  }, {
90
106
  breakerKey: HTTP_BREAKER_KEY,
91
107
  retry: { maxAttempts: HTTP_MAX_RETRIES + 1, baseDelayMs: HTTP_RETRY_BACKOFF_MS },
@@ -130,7 +146,7 @@ export const httpEmbed = async (texts) => {
130
146
  for (let i = 0; i < texts.length; i += HTTP_BATCH_SIZE) {
131
147
  const batch = texts.slice(i, i + HTTP_BATCH_SIZE);
132
148
  const batchIndex = Math.floor(i / HTTP_BATCH_SIZE);
133
- const items = await httpEmbedBatch(url, batch, config.model, config.apiKey, batchIndex);
149
+ const items = await httpEmbedBatch(url, batch, config.model, config.apiKey, batchIndex, config.dimensions);
134
150
  if (items.length !== batch.length) {
135
151
  throw new Error(`Embedding endpoint returned ${items.length} vectors for ${batch.length} texts ` +
136
152
  `(${safeUrl(url)}, batch ${batchIndex})`);
@@ -164,7 +180,7 @@ export const httpEmbedQuery = async (text) => {
164
180
  if (!config)
165
181
  throw new Error('HTTP embedding not configured');
166
182
  const url = `${config.baseUrl}/embeddings`;
167
- const items = await httpEmbedBatch(url, [text], config.model, config.apiKey);
183
+ const items = await httpEmbedBatch(url, [text], config.model, config.apiKey, 0, config.dimensions);
168
184
  if (!items.length) {
169
185
  throw new Error(`Embedding endpoint returned empty response (${safeUrl(url)})`);
170
186
  }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Shadow-candidate path derivation for incremental indexing.
3
+ *
4
+ * Background — Bugbot review on PR #1479:
5
+ * queryImporters() on a NEWLY ADDED file returns 0 importers in the
6
+ * pre-pipeline DB, because the new file's IMPORTS rows haven't been
7
+ * written yet. But pre-existing files may have IMPORTS edges that
8
+ * *resolved to a sibling path*, and the newcomer can now steal that
9
+ * resolution under standard JS/TS module-resolution rules. Without
10
+ * pulling those pre-existing files into the writable set, their
11
+ * stale CALLS edges remain pointing at the OLD resolution target.
12
+ *
13
+ * Given an added file path, this helper enumerates the pre-existing
14
+ * file paths whose import-resolution claim the newcomer can steal.
15
+ * Caller filters the candidates against the prior-run `fileHashes`
16
+ * map so we only query importers of paths that actually existed.
17
+ *
18
+ * Shadow patterns covered (resolution-priority-aware):
19
+ *
20
+ * (a) Same basename, different extension —
21
+ * added `foo/bar.ts` shadows `foo/bar.{tsx,js,jsx,mjs,cjs,d.ts}`.
22
+ * (b) Bare-file beats directory-style index —
23
+ * added `foo/bar.ts` shadows `foo/bar/index.{ts,tsx,...}`.
24
+ * (c) Directory-index beats bare-file —
25
+ * added `foo/index.ts` shadows `foo.{ts,tsx,...}` (rare but real,
26
+ * e.g. converting a single-file module into a directory module).
27
+ *
28
+ * Resolution-order priority is conservatively wide: we enumerate ALL
29
+ * common extensions because we don't know which the importer actually
30
+ * specified, and over-seeding is harmless (extra BFS work, but the
31
+ * subgraph extract still gates write-back by file membership).
32
+ *
33
+ * Cross-platform path separators: candidates are emitted with both `/`
34
+ * and `\` for shadow pattern (b), since the caller's prior fileHashes
35
+ * map may use either depending on the OS that wrote it.
36
+ */
37
+ /**
38
+ * Enumerate pre-existing paths whose import-resolution `added` can steal.
39
+ *
40
+ * @param added — repo-relative path of a newly-added file
41
+ * @returns deduplicated list of candidate paths (NOT filtered against
42
+ * any known-files set — caller does that)
43
+ */
44
+ export declare const shadowCandidatesFor: (added: string) => string[];
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Shadow-candidate path derivation for incremental indexing.
3
+ *
4
+ * Background — Bugbot review on PR #1479:
5
+ * queryImporters() on a NEWLY ADDED file returns 0 importers in the
6
+ * pre-pipeline DB, because the new file's IMPORTS rows haven't been
7
+ * written yet. But pre-existing files may have IMPORTS edges that
8
+ * *resolved to a sibling path*, and the newcomer can now steal that
9
+ * resolution under standard JS/TS module-resolution rules. Without
10
+ * pulling those pre-existing files into the writable set, their
11
+ * stale CALLS edges remain pointing at the OLD resolution target.
12
+ *
13
+ * Given an added file path, this helper enumerates the pre-existing
14
+ * file paths whose import-resolution claim the newcomer can steal.
15
+ * Caller filters the candidates against the prior-run `fileHashes`
16
+ * map so we only query importers of paths that actually existed.
17
+ *
18
+ * Shadow patterns covered (resolution-priority-aware):
19
+ *
20
+ * (a) Same basename, different extension —
21
+ * added `foo/bar.ts` shadows `foo/bar.{tsx,js,jsx,mjs,cjs,d.ts}`.
22
+ * (b) Bare-file beats directory-style index —
23
+ * added `foo/bar.ts` shadows `foo/bar/index.{ts,tsx,...}`.
24
+ * (c) Directory-index beats bare-file —
25
+ * added `foo/index.ts` shadows `foo.{ts,tsx,...}` (rare but real,
26
+ * e.g. converting a single-file module into a directory module).
27
+ *
28
+ * Resolution-order priority is conservatively wide: we enumerate ALL
29
+ * common extensions because we don't know which the importer actually
30
+ * specified, and over-seeding is harmless (extra BFS work, but the
31
+ * subgraph extract still gates write-back by file membership).
32
+ *
33
+ * Cross-platform path separators: candidates are emitted with both `/`
34
+ * and `\` for shadow pattern (b), since the caller's prior fileHashes
35
+ * map may use either depending on the OS that wrote it.
36
+ */
37
+ const SHADOW_EXTS = ['.d.ts', '.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs'];
38
+ /**
39
+ * Enumerate pre-existing paths whose import-resolution `added` can steal.
40
+ *
41
+ * @param added — repo-relative path of a newly-added file
42
+ * @returns deduplicated list of candidate paths (NOT filtered against
43
+ * any known-files set — caller does that)
44
+ */
45
+ export const shadowCandidatesFor = (added) => {
46
+ const ext = SHADOW_EXTS.find((e) => added.endsWith(e));
47
+ if (!ext)
48
+ return [];
49
+ const noExt = added.slice(0, -ext.length);
50
+ const out = new Set();
51
+ // (a) Same basename, different extension.
52
+ for (const alt of SHADOW_EXTS) {
53
+ if (alt !== ext)
54
+ out.add(noExt + alt);
55
+ }
56
+ // (b) Bare file beats sibling directory-style index.
57
+ for (const idx of SHADOW_EXTS) {
58
+ out.add(`${noExt}/index${idx}`);
59
+ out.add(`${noExt}\\index${idx}`);
60
+ }
61
+ // (c) New `foo/index.ext` shadows old `foo.ext`.
62
+ const idxSuffixSlash = '/index';
63
+ const idxSuffixBack = '\\index';
64
+ let dir = null;
65
+ if (noExt.endsWith(idxSuffixSlash))
66
+ dir = noExt.slice(0, -idxSuffixSlash.length);
67
+ else if (noExt.endsWith(idxSuffixBack))
68
+ dir = noExt.slice(0, -idxSuffixBack.length);
69
+ if (dir !== null) {
70
+ for (const alt of SHADOW_EXTS)
71
+ out.add(dir + alt);
72
+ }
73
+ return [...out];
74
+ };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Subgraph extraction for incremental DB writeback.
3
+ *
4
+ * Given the FULL ctx.graph produced by the pipeline (all files parsed,
5
+ * all phases run) and the set of file paths whose DB rows must be
6
+ * replaced, produce a smaller KnowledgeGraph that contains:
7
+ *
8
+ * - Every node whose `properties.filePath` is in `toWriteSet`.
9
+ * - Every graph-wide node (Community, Process) — these are regenerated
10
+ * each run by the communities/processes phases and must be fully
11
+ * rewritten.
12
+ * - Every relationship where AT LEAST ONE endpoint is in the writable
13
+ * set above. Relationships entirely between unchanged-file nodes
14
+ * are skipped — their rows are still in the DB and re-inserting
15
+ * them would PK-conflict at COPY time.
16
+ *
17
+ * The resulting subgraph is what gets passed to `loadGraphToLbug` after
18
+ * the orchestrator has deleted the corresponding DB rows. Hydrated
19
+ * unchanged-file rows are never touched in the DB.
20
+ *
21
+ * # Cross-file edge consistency (Finding 1)
22
+ *
23
+ * `extractChangedSubgraph` intentionally does NOT expand the set it is
24
+ * given — expansion is the orchestrator's job, so the SAME expanded set
25
+ * can be fed to both `deleteNodesForFile` and this function (asymmetry
26
+ * between the delete set and the write set silently corrupts the DB).
27
+ * `computeEffectiveWriteSet` below performs the boundary-crossing 1-hop
28
+ * walk; the orchestrator composes it with its importer-BFS expansion and
29
+ * passes the result here.
30
+ *
31
+ * Why the 1-hop walk is needed: consider a barrel re-export change —
32
+ * file C (a barrel) shifts `export { foo } from './b'` to
33
+ * `export { foo } from './d'`. After scope resolution, file A's CALLS
34
+ * edge to `foo` resolves to D instead of B, even though A's content is
35
+ * byte-for-byte identical:
36
+ *
37
+ * - Old A→B edge survives in DB (neither A nor B is changed → not deleted)
38
+ * - New A→D edge is missing (neither A nor D in writable set → skipped)
39
+ *
40
+ * Pulling the unchanged-side file of every writable-boundary-crossing
41
+ * edge into the write set fixes both halves: the orchestrator's
42
+ * `DETACH DELETE` cleans up the stale unchanged-side rows, and the new
43
+ * cross-file edges land because at least one endpoint is now writable.
44
+ *
45
+ * Limitation (documented): if a file X *stopped* importing from a
46
+ * changed file C, X has no edge to C in the new graph, so this 1-hop
47
+ * walk doesn't catch it. The orchestrator's importer-BFS (which reads
48
+ * IMPORTS from the pre-pipeline DB) covers that case instead.
49
+ */
50
+ import type { KnowledgeGraph } from '../graph/types.js';
51
+ export declare const extractChangedSubgraph: (fullGraph: KnowledgeGraph, toWriteSet: ReadonlySet<string>) => KnowledgeGraph;
52
+ /**
53
+ * Public — derive the EFFECTIVE write-set: `toWriteSet` expanded by one
54
+ * hop along every edge in the new graph that crosses the writable
55
+ * boundary (one endpoint in a writable file, the other in an unchanged
56
+ * file). The unchanged-side file is pulled in so its stale rows are
57
+ * deleted + rewritten in lockstep with the changed side.
58
+ *
59
+ * Single pass over the edge list. Does NOT mutate `toWriteSet`. The
60
+ * orchestrator MUST feed the returned set to both `deleteNodesForFile`
61
+ * and `extractChangedSubgraph` — feeding the unexpanded set to either
62
+ * one leaves stale rows or PK-conflicts at COPY time.
63
+ */
64
+ export declare const computeEffectiveWriteSet: (fullGraph: KnowledgeGraph, toWriteSet: ReadonlySet<string>) => Set<string>;
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Subgraph extraction for incremental DB writeback.
3
+ *
4
+ * Given the FULL ctx.graph produced by the pipeline (all files parsed,
5
+ * all phases run) and the set of file paths whose DB rows must be
6
+ * replaced, produce a smaller KnowledgeGraph that contains:
7
+ *
8
+ * - Every node whose `properties.filePath` is in `toWriteSet`.
9
+ * - Every graph-wide node (Community, Process) — these are regenerated
10
+ * each run by the communities/processes phases and must be fully
11
+ * rewritten.
12
+ * - Every relationship where AT LEAST ONE endpoint is in the writable
13
+ * set above. Relationships entirely between unchanged-file nodes
14
+ * are skipped — their rows are still in the DB and re-inserting
15
+ * them would PK-conflict at COPY time.
16
+ *
17
+ * The resulting subgraph is what gets passed to `loadGraphToLbug` after
18
+ * the orchestrator has deleted the corresponding DB rows. Hydrated
19
+ * unchanged-file rows are never touched in the DB.
20
+ *
21
+ * # Cross-file edge consistency (Finding 1)
22
+ *
23
+ * `extractChangedSubgraph` intentionally does NOT expand the set it is
24
+ * given — expansion is the orchestrator's job, so the SAME expanded set
25
+ * can be fed to both `deleteNodesForFile` and this function (asymmetry
26
+ * between the delete set and the write set silently corrupts the DB).
27
+ * `computeEffectiveWriteSet` below performs the boundary-crossing 1-hop
28
+ * walk; the orchestrator composes it with its importer-BFS expansion and
29
+ * passes the result here.
30
+ *
31
+ * Why the 1-hop walk is needed: consider a barrel re-export change —
32
+ * file C (a barrel) shifts `export { foo } from './b'` to
33
+ * `export { foo } from './d'`. After scope resolution, file A's CALLS
34
+ * edge to `foo` resolves to D instead of B, even though A's content is
35
+ * byte-for-byte identical:
36
+ *
37
+ * - Old A→B edge survives in DB (neither A nor B is changed → not deleted)
38
+ * - New A→D edge is missing (neither A nor D in writable set → skipped)
39
+ *
40
+ * Pulling the unchanged-side file of every writable-boundary-crossing
41
+ * edge into the write set fixes both halves: the orchestrator's
42
+ * `DETACH DELETE` cleans up the stale unchanged-side rows, and the new
43
+ * cross-file edges land because at least one endpoint is now writable.
44
+ *
45
+ * Limitation (documented): if a file X *stopped* importing from a
46
+ * changed file C, X has no edge to C in the new graph, so this 1-hop
47
+ * walk doesn't catch it. The orchestrator's importer-BFS (which reads
48
+ * IMPORTS from the pre-pipeline DB) covers that case instead.
49
+ */
50
+ import { createKnowledgeGraph } from '../graph/graph.js';
51
+ const isGraphWide = (label) => label === 'Community' || label === 'Process';
52
+ /**
53
+ * Build a Map<nodeId, filePath> for every File-bound node in the graph.
54
+ * Graph-wide nodes (Community/Process) have no filePath and are filtered.
55
+ */
56
+ const indexNodeFilePaths = (fullGraph) => {
57
+ const idx = new Map();
58
+ fullGraph.forEachNode((n) => {
59
+ const fp = n.properties?.filePath;
60
+ if (fp)
61
+ idx.set(n.id, fp);
62
+ });
63
+ return idx;
64
+ };
65
+ export const extractChangedSubgraph = (fullGraph, toWriteSet) => {
66
+ const sub = createKnowledgeGraph();
67
+ const writableNodeIds = new Set();
68
+ fullGraph.forEachNode((n) => {
69
+ const filePath = n.properties?.filePath;
70
+ const include = (filePath && toWriteSet.has(filePath)) || isGraphWide(n.label);
71
+ if (include) {
72
+ sub.addNode(n);
73
+ writableNodeIds.add(n.id);
74
+ }
75
+ });
76
+ fullGraph.forEachRelationship((r) => {
77
+ if (writableNodeIds.has(r.sourceId) || writableNodeIds.has(r.targetId)) {
78
+ sub.addRelationship(r);
79
+ }
80
+ });
81
+ return sub;
82
+ };
83
+ /**
84
+ * Public — derive the EFFECTIVE write-set: `toWriteSet` expanded by one
85
+ * hop along every edge in the new graph that crosses the writable
86
+ * boundary (one endpoint in a writable file, the other in an unchanged
87
+ * file). The unchanged-side file is pulled in so its stale rows are
88
+ * deleted + rewritten in lockstep with the changed side.
89
+ *
90
+ * Single pass over the edge list. Does NOT mutate `toWriteSet`. The
91
+ * orchestrator MUST feed the returned set to both `deleteNodesForFile`
92
+ * and `extractChangedSubgraph` — feeding the unexpanded set to either
93
+ * one leaves stale rows or PK-conflicts at COPY time.
94
+ */
95
+ export const computeEffectiveWriteSet = (fullGraph, toWriteSet) => {
96
+ const nodeFilePaths = indexNodeFilePaths(fullGraph);
97
+ const expanded = new Set(toWriteSet);
98
+ fullGraph.forEachRelationship((r) => {
99
+ const sourcePath = nodeFilePaths.get(r.sourceId);
100
+ const targetPath = nodeFilePaths.get(r.targetId);
101
+ if (!sourcePath || !targetPath)
102
+ return; // skip edges to graph-wide nodes
103
+ const sourceWritable = toWriteSet.has(sourcePath);
104
+ const targetWritable = toWriteSet.has(targetPath);
105
+ if (sourceWritable && !targetWritable)
106
+ expanded.add(targetPath);
107
+ else if (targetWritable && !sourceWritable)
108
+ expanded.add(sourcePath);
109
+ });
110
+ return expanded;
111
+ };
@@ -2,8 +2,10 @@ import { KnowledgeGraph } from '../graph/types.js';
2
2
  import { ASTCache } from './ast-cache.js';
3
3
  import type { SymbolDefinition } from '../../_shared/index.js';
4
4
  import type { SymbolTableReader, HeritageMap, ExtractedHeritage } from './model/index.js';
5
+ import Parser from 'tree-sitter';
5
6
  import type { ResolutionContext } from './model/resolution-context.js';
6
7
  import type { TieredCandidates } from './model/resolution-context.js';
8
+ import { SupportedLanguages } from '../../_shared/index.js';
7
9
  import type { TypeEnvironment } from './type-env.js';
8
10
  import type { BindingAccumulator } from './binding-accumulator.js';
9
11
  import type { ExtractedCall, ExtractedAssignment, ExtractedRoute, ExtractedFetchCall, FileConstructorBindings } from './workers/parse-worker.js';
@@ -73,7 +75,16 @@ importedBindingsMap?: ReadonlyMap<string, ReadonlyMap<string, string>>,
73
75
  * Consulted ONLY when SymbolTable has no unambiguous match (local-first principle). */
74
76
  importedReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>,
75
77
  /** Phase 14 E3: cross-file RAW return types for for-loop element extraction. Keyed by filePath → Map<calleeName, rawReturnType>. */
76
- importedRawReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>, heritageMap?: HeritageMap, bindingAccumulator?: BindingAccumulator) => Promise<ExtractedHeritage[]>;
78
+ importedRawReturnTypesMap?: ReadonlyMap<string, ReadonlyMap<string, string>>, heritageMap?: HeritageMap, bindingAccumulator?: BindingAccumulator,
79
+ /**
80
+ * Optional cache for compiled `Parser.Query` objects keyed by language name.
81
+ * When provided, compiled queries are reused across calls instead of being
82
+ * re-compiled from the query string for every file. Callers that invoke
83
+ * `processCalls` many times with single-file batches (e.g. the cross-file
84
+ * propagation phase) should pass a long-lived map here to avoid O(N)
85
+ * query recompilation overhead.
86
+ */
87
+ compiledQueryCache?: Map<SupportedLanguages, Parser.Query>) => Promise<ExtractedHeritage[]>;
77
88
  /** Per-file cache for module-alias widening. Cleared between files. */
78
89
  type WidenCache = Map<string, readonly SymbolDefinition[]>;
79
90
  /**