@namzu/cli 37.0.1 → 37.1.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 (265) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +1 -1
  3. package/dist/analysis-host.js +55 -0
  4. package/dist/analysis-host.js.map +6 -0
  5. package/dist/bin.js +1 -1
  6. package/dist/chunks/{acp-KTJZTVUR.js → acp-T46275W3.js} +59 -47
  7. package/dist/chunks/acp-T46275W3.js.map +6 -0
  8. package/dist/chunks/{activity-command-UMTER4IK.js → activity-command-U3KHRDTY.js} +11 -10
  9. package/dist/chunks/activity-command-U3KHRDTY.js.map +6 -0
  10. package/dist/chunks/{add-AIDLR6U4.js → add-Q2HPE26F.js} +19 -19
  11. package/dist/chunks/{agent-C7TDIJ67.js → agent-KSRUGF37.js} +26 -24
  12. package/dist/chunks/agent-session-4G4PKPCR.js +51 -0
  13. package/dist/chunks/{archive-FKUQ77FG.js → archive-NQ527SKW.js} +9 -8
  14. package/dist/chunks/archive-NQ527SKW.js.map +6 -0
  15. package/dist/chunks/{bin-main-BLF3YOHJ.js → bin-main-72QPYEQ5.js} +5 -5
  16. package/dist/chunks/{browser-7P2TABJG.js → browser-NQAXUNRS.js} +7 -7
  17. package/dist/chunks/{chat-YN6WWBI6.js → chat-QSA5IBTG.js} +20 -19
  18. package/dist/chunks/chat-QSA5IBTG.js.map +6 -0
  19. package/dist/chunks/{chunk-Y3UE64PV.js → chunk-2GTBCI2R.js} +3 -3
  20. package/dist/chunks/chunk-3KMW53PV.js +108 -0
  21. package/dist/chunks/chunk-3KMW53PV.js.map +6 -0
  22. package/dist/chunks/{chunk-QCJU5KFR.js → chunk-3TGNRSKG.js} +6 -6
  23. package/dist/chunks/{chunk-3SGEHTJ4.js → chunk-4K3ABOWX.js} +6 -6
  24. package/dist/chunks/{chunk-MVGNG67O.js → chunk-4MZXZCPR.js} +2 -2
  25. package/dist/chunks/{chunk-EBFWNPMU.js → chunk-4WDWLAQ5.js} +11 -11
  26. package/dist/chunks/{chunk-YCVR5E2Z.js → chunk-5EQTZ4HK.js} +30 -4
  27. package/dist/chunks/{chunk-YCVR5E2Z.js.map → chunk-5EQTZ4HK.js.map} +1 -1
  28. package/dist/chunks/{chunk-XDAMUTVR.js → chunk-5LO5YWAO.js} +4 -4
  29. package/dist/chunks/{chunk-OVVIFOAR.js → chunk-5X7RU64G.js} +4 -4
  30. package/dist/chunks/{chunk-I3Q53U6H.js → chunk-6CD4ZJWY.js} +2 -2
  31. package/dist/chunks/{chunk-WRGY7MRU.js → chunk-6SKQVVXO.js} +33 -32
  32. package/dist/chunks/{chunk-WRGY7MRU.js.map → chunk-6SKQVVXO.js.map} +1 -1
  33. package/dist/chunks/{chunk-WWE4W2R6.js → chunk-6USAI7O7.js} +2 -2
  34. package/dist/chunks/{chunk-DFU5KG3V.js → chunk-7INJDLWA.js} +4 -4
  35. package/dist/chunks/chunk-7WKQQOKK.js +430 -0
  36. package/dist/chunks/chunk-7WKQQOKK.js.map +6 -0
  37. package/dist/chunks/{chunk-45MA2WMX.js → chunk-A3TBA7LQ.js} +3 -3
  38. package/dist/chunks/{chunk-5WDPVM7Q.js → chunk-ACJ37X25.js} +2 -2
  39. package/dist/chunks/{chunk-GR452YOE.js → chunk-ADJCEQGK.js} +2 -2
  40. package/dist/chunks/{chunk-SEKX6IR5.js → chunk-AEWKXISZ.js} +13 -13
  41. package/dist/chunks/{chunk-6CQJH56B.js → chunk-AHK44IOS.js} +2 -2
  42. package/dist/chunks/{chunk-74WE6T6M.js → chunk-CBNP2J2W.js} +9 -7
  43. package/dist/chunks/chunk-CBNP2J2W.js.map +6 -0
  44. package/dist/chunks/{chunk-3NCL3Y53.js → chunk-DPCUP4TI.js} +4 -4
  45. package/dist/chunks/{chunk-HHKKHUJK.js → chunk-EKSTG5ZQ.js} +3 -41
  46. package/dist/chunks/chunk-EKSTG5ZQ.js.map +6 -0
  47. package/dist/chunks/{chunk-F2JKDYHA.js → chunk-FUORCVIN.js} +4 -4
  48. package/dist/chunks/{chunk-5GOYK3IN.js → chunk-FXXP6QP6.js} +2 -2
  49. package/dist/chunks/{chunk-X3ZBCYV6.js → chunk-GEPGHAWO.js} +2 -2
  50. package/dist/chunks/{chunk-23SR4YFL.js → chunk-GSZCV2P3.js} +2 -2
  51. package/dist/chunks/{chunk-FKLDO6SF.js → chunk-GXQAMIQA.js} +3 -3
  52. package/dist/chunks/{chunk-HV4SSQ2Y.js → chunk-HKUWS2WO.js} +3 -3
  53. package/dist/chunks/{chunk-FLUVTAXY.js → chunk-HMORKNX3.js} +457 -128
  54. package/dist/chunks/chunk-HMORKNX3.js.map +6 -0
  55. package/dist/chunks/{chunk-2YPMHUI4.js → chunk-HTXPBXXP.js} +2 -2
  56. package/dist/chunks/{chunk-I6XWCKKW.js → chunk-IB7UOMAQ.js} +7 -5
  57. package/dist/chunks/chunk-IB7UOMAQ.js.map +6 -0
  58. package/dist/chunks/{chunk-4GDOFBZF.js → chunk-IVFJXA6P.js} +3 -3
  59. package/dist/chunks/chunk-J4IRSWAS.js +49 -0
  60. package/dist/chunks/chunk-J4IRSWAS.js.map +6 -0
  61. package/dist/chunks/{chunk-D7FPVZDC.js → chunk-KB7EM3DJ.js} +2 -2
  62. package/dist/chunks/{chunk-WMOYTZXD.js → chunk-KSQTOA6I.js} +17 -17
  63. package/dist/chunks/{chunk-BV2SDA2D.js → chunk-LCFHDWTA.js} +3 -3
  64. package/dist/chunks/{chunk-37A6M7P4.js → chunk-LVW3JXVJ.js} +4 -4
  65. package/dist/chunks/{chunk-DBBWIOQS.js → chunk-LZISO3TE.js} +3 -3
  66. package/dist/chunks/{chunk-NKERGDBZ.js → chunk-MB4SLACG.js} +2 -2
  67. package/dist/chunks/{chunk-KQM2NQ2W.js → chunk-MOI4XD5Z.js} +8 -8
  68. package/dist/chunks/{chunk-ZKI3Z4VR.js → chunk-MRQ2UQG5.js} +2 -2
  69. package/dist/chunks/{chunk-JH2O55TT.js → chunk-NIBOMW4E.js} +4 -4
  70. package/dist/chunks/{chunk-XYXPAVPG.js → chunk-OTTDC3KF.js} +4 -4
  71. package/dist/chunks/{chunk-BUQ7VMBS.js → chunk-OYJCMNOO.js} +32 -10
  72. package/dist/chunks/chunk-OYJCMNOO.js.map +6 -0
  73. package/dist/chunks/{chunk-UFZGVNFQ.js → chunk-Q2EWUIIT.js} +2 -2
  74. package/dist/chunks/{chunk-QVMTUMTW.js → chunk-QINC4TIT.js} +3 -3
  75. package/dist/chunks/{chunk-KSFS3BI7.js → chunk-S72MTTOC.js} +2 -2
  76. package/dist/chunks/{chunk-R23DP7S7.js → chunk-TGZ7OLDL.js} +17 -17
  77. package/dist/chunks/{chunk-ZRAALEF2.js → chunk-TI7LE6F5.js} +2 -2
  78. package/dist/chunks/{chunk-QU3LGVTZ.js → chunk-TTCXFX6V.js} +7 -7
  79. package/dist/chunks/{chunk-6HDBRUB7.js → chunk-UC3UARTL.js} +47 -30
  80. package/dist/chunks/chunk-UC3UARTL.js.map +6 -0
  81. package/dist/chunks/{chunk-ZRJYG2F2.js → chunk-VEOIRZH4.js} +2 -2
  82. package/dist/chunks/{chunk-MYRLRBZG.js → chunk-VSLHC665.js} +3 -3
  83. package/dist/chunks/{chunk-OKB66ICJ.js → chunk-WU5K7PF3.js} +13 -11
  84. package/dist/chunks/chunk-WU5K7PF3.js.map +6 -0
  85. package/dist/chunks/{chunk-HXFPEA6Z.js → chunk-XB7HBRSL.js} +2 -2
  86. package/dist/chunks/{chunk-2EDGH6Y3.js → chunk-ZGP5MF2Q.js} +3 -3
  87. package/dist/chunks/{chunk-L7Q7QNNE.js → chunk-ZNO7XIZU.js} +3 -3
  88. package/dist/chunks/{cli-runtime-74KKQHC7.js → cli-runtime-T6ZXKC2O.js} +7 -7
  89. package/dist/chunks/{commands-2Q7KPVLW.js → commands-3RJ5HAMM.js} +6 -6
  90. package/dist/chunks/{crash-report-KDVWQ2RR.js → crash-report-ZUP6NMRJ.js} +6 -6
  91. package/dist/chunks/{dist-674RS73L.js → dist-5D7BTPT2.js} +2 -2
  92. package/dist/chunks/{dist-4TGHKBRS.js → dist-72DFA26L.js} +2 -2
  93. package/dist/chunks/{dist-Q523V5L2.js → dist-GXQCJQ53.js} +2 -2
  94. package/dist/chunks/{dist-OMRUSJ5R.js → dist-HJCEE57U.js} +2 -2
  95. package/dist/chunks/{dist-25C2CYHP.js → dist-I2Q3FRR4.js} +2 -2
  96. package/dist/chunks/dist-KGLSBIES.js +2182 -0
  97. package/dist/chunks/dist-KGLSBIES.js.map +6 -0
  98. package/dist/chunks/{dist-UYD7IXG3.js → dist-PE6GSYDP.js} +2 -2
  99. package/dist/chunks/{dist-ZDSPMZ5S.js → dist-XFIOSXNS.js} +2 -2
  100. package/dist/chunks/{doctor-TFION64N.js → doctor-FPBYPOAK.js} +11 -9
  101. package/dist/chunks/{drain-3W3A4KPX.js → drain-N65CXI5H.js} +13 -13
  102. package/dist/chunks/{eval-TCUVH3S3.js → eval-SYKBFGGU.js} +2 -2
  103. package/dist/chunks/{exec-EIELDRPM.js → exec-INYAGY7Q.js} +30 -29
  104. package/dist/chunks/exec-INYAGY7Q.js.map +6 -0
  105. package/dist/chunks/{home-FYDAEWNW.js → home-FJS5AXFZ.js} +3 -3
  106. package/dist/chunks/{host-queries-WFWM672O.js → host-queries-Q3CDQ5R6.js} +14 -13
  107. package/dist/chunks/host-queries-Q3CDQ5R6.js.map +6 -0
  108. package/dist/chunks/{lifecycle-ALDBR656.js → lifecycle-5RWKT62M.js} +27 -26
  109. package/dist/chunks/{list-Z4XOJJ7V.js → list-FUOU75RU.js} +15 -15
  110. package/dist/chunks/{login-UZONOHHT.js → login-ELQCFAUF.js} +8 -8
  111. package/dist/chunks/{logs-O3NGOQFC.js → logs-OBL6KGPA.js} +5 -5
  112. package/dist/chunks/{mcp-YI6PL4TH.js → mcp-TFWJC56M.js} +16 -16
  113. package/dist/chunks/{message-command-QEQJ25KR.js → message-command-ZNMT76V5.js} +35 -33
  114. package/dist/chunks/message-command-ZNMT76V5.js.map +6 -0
  115. package/dist/chunks/{operator-tools-GKYGHHPM.js → operator-tools-C6OPS77I.js} +13 -12
  116. package/dist/chunks/operator-tools-C6OPS77I.js.map +6 -0
  117. package/dist/chunks/{output-schema-KXKCYDI4.js → output-schema-35YWLD2S.js} +3 -3
  118. package/dist/chunks/{pal-2EYYHPXC.js → pal-TN4YSFO6.js} +13 -13
  119. package/dist/chunks/{providers-JF5SWSTH.js → providers-KC7IQHF7.js} +6 -6
  120. package/dist/chunks/{resident-WHH7YQGZ.js → resident-JZ5AHFMO.js} +24 -23
  121. package/dist/chunks/resident-JZ5AHFMO.js.map +6 -0
  122. package/dist/chunks/resume-ZLGRUFA3.js +22 -0
  123. package/dist/chunks/{resume-command-A3HKQSRH.js → resume-command-5FDSKSZR.js} +4 -4
  124. package/dist/chunks/{schedule-QIJCYWIQ.js → schedule-ZVBIF6JZ.js} +8 -8
  125. package/dist/chunks/{service-IXPGBY3F.js → service-2MS37QMZ.js} +31 -30
  126. package/dist/chunks/service-2MS37QMZ.js.map +6 -0
  127. package/dist/chunks/session-step-XIYPMQA4.js +27 -0
  128. package/dist/chunks/{skills-AGU7FTRG.js → skills-B35Q357B.js} +11 -11
  129. package/dist/chunks/{state-MTHK7DUX.js → state-YXNTJW67.js} +2 -2
  130. package/dist/chunks/{store-EWEKEKSG.js → store-5BLKNUFX.js} +9 -8
  131. package/dist/chunks/{store-XPSGZANO.js → store-5YOZ57L2.js} +6 -6
  132. package/dist/chunks/{store-LPOET7IK.js → store-H5KCO6HN.js} +4 -4
  133. package/dist/chunks/{tui-YMBQLMGW.js → tui-NZUV74RQ.js} +79 -75
  134. package/dist/chunks/tui-NZUV74RQ.js.map +6 -0
  135. package/dist/chunks/{upgrade-3YOFSMAQ.js → upgrade-64USK7BM.js} +2 -2
  136. package/dist/chunks/{worktree-VPD2N53Y.js → worktree-COOGACI6.js} +11 -10
  137. package/dist/chunks/worktree-COOGACI6.js.map +6 -0
  138. package/dist/cli.d.ts.map +1 -1
  139. package/dist/config/load.d.ts +3 -1
  140. package/dist/config/load.d.ts.map +1 -1
  141. package/dist/config/schema.d.ts +16 -0
  142. package/dist/config/schema.d.ts.map +1 -1
  143. package/dist/doctor/checks/code-analysis.d.ts +9 -0
  144. package/dist/doctor/checks/code-analysis.d.ts.map +1 -0
  145. package/dist/doctor/checks/index.d.ts +2 -1
  146. package/dist/doctor/checks/index.d.ts.map +1 -1
  147. package/dist/index.js +16 -14
  148. package/dist/integrations/analysis/host-entry.d.ts +12 -0
  149. package/dist/integrations/analysis/host-entry.d.ts.map +1 -0
  150. package/dist/integrations/analysis/provider.d.ts +42 -0
  151. package/dist/integrations/analysis/provider.d.ts.map +1 -0
  152. package/dist/integrations/resident/runner-worker.js +19 -18
  153. package/dist/integrations/resident/runner-worker.js.map +1 -1
  154. package/dist/terminal/pty.d.ts +8 -0
  155. package/dist/terminal/pty.d.ts.map +1 -1
  156. package/dist/tui/App.d.ts.map +1 -1
  157. package/dist/tui/agent.d.ts +9 -1
  158. package/dist/tui/agent.d.ts.map +1 -1
  159. package/dist/tui/types.d.ts +3 -1
  160. package/dist/tui/types.d.ts.map +1 -1
  161. package/package.json +4 -2
  162. package/dist/chunks/acp-KTJZTVUR.js.map +0 -6
  163. package/dist/chunks/activity-command-UMTER4IK.js.map +0 -6
  164. package/dist/chunks/agent-session-D4Z3TOX3.js +0 -49
  165. package/dist/chunks/archive-FKUQ77FG.js.map +0 -6
  166. package/dist/chunks/chat-YN6WWBI6.js.map +0 -6
  167. package/dist/chunks/chunk-6HDBRUB7.js.map +0 -6
  168. package/dist/chunks/chunk-74WE6T6M.js.map +0 -6
  169. package/dist/chunks/chunk-BUQ7VMBS.js.map +0 -6
  170. package/dist/chunks/chunk-FLUVTAXY.js.map +0 -6
  171. package/dist/chunks/chunk-HHKKHUJK.js.map +0 -6
  172. package/dist/chunks/chunk-I6XWCKKW.js.map +0 -6
  173. package/dist/chunks/chunk-OKB66ICJ.js.map +0 -6
  174. package/dist/chunks/exec-EIELDRPM.js.map +0 -6
  175. package/dist/chunks/host-queries-WFWM672O.js.map +0 -6
  176. package/dist/chunks/message-command-QEQJ25KR.js.map +0 -6
  177. package/dist/chunks/operator-tools-GKYGHHPM.js.map +0 -6
  178. package/dist/chunks/resident-WHH7YQGZ.js.map +0 -6
  179. package/dist/chunks/resume-WR4KOI7Q.js +0 -21
  180. package/dist/chunks/service-IXPGBY3F.js.map +0 -6
  181. package/dist/chunks/session-step-ZZBENVGS.js +0 -26
  182. package/dist/chunks/tui-YMBQLMGW.js.map +0 -6
  183. package/dist/chunks/worktree-VPD2N53Y.js.map +0 -6
  184. /package/dist/chunks/{add-AIDLR6U4.js.map → add-Q2HPE26F.js.map} +0 -0
  185. /package/dist/chunks/{agent-C7TDIJ67.js.map → agent-KSRUGF37.js.map} +0 -0
  186. /package/dist/chunks/{agent-session-D4Z3TOX3.js.map → agent-session-4G4PKPCR.js.map} +0 -0
  187. /package/dist/chunks/{bin-main-BLF3YOHJ.js.map → bin-main-72QPYEQ5.js.map} +0 -0
  188. /package/dist/chunks/{browser-7P2TABJG.js.map → browser-NQAXUNRS.js.map} +0 -0
  189. /package/dist/chunks/{chunk-Y3UE64PV.js.map → chunk-2GTBCI2R.js.map} +0 -0
  190. /package/dist/chunks/{chunk-QCJU5KFR.js.map → chunk-3TGNRSKG.js.map} +0 -0
  191. /package/dist/chunks/{chunk-3SGEHTJ4.js.map → chunk-4K3ABOWX.js.map} +0 -0
  192. /package/dist/chunks/{chunk-MVGNG67O.js.map → chunk-4MZXZCPR.js.map} +0 -0
  193. /package/dist/chunks/{chunk-EBFWNPMU.js.map → chunk-4WDWLAQ5.js.map} +0 -0
  194. /package/dist/chunks/{chunk-XDAMUTVR.js.map → chunk-5LO5YWAO.js.map} +0 -0
  195. /package/dist/chunks/{chunk-OVVIFOAR.js.map → chunk-5X7RU64G.js.map} +0 -0
  196. /package/dist/chunks/{chunk-I3Q53U6H.js.map → chunk-6CD4ZJWY.js.map} +0 -0
  197. /package/dist/chunks/{chunk-WWE4W2R6.js.map → chunk-6USAI7O7.js.map} +0 -0
  198. /package/dist/chunks/{chunk-DFU5KG3V.js.map → chunk-7INJDLWA.js.map} +0 -0
  199. /package/dist/chunks/{chunk-45MA2WMX.js.map → chunk-A3TBA7LQ.js.map} +0 -0
  200. /package/dist/chunks/{chunk-5WDPVM7Q.js.map → chunk-ACJ37X25.js.map} +0 -0
  201. /package/dist/chunks/{chunk-GR452YOE.js.map → chunk-ADJCEQGK.js.map} +0 -0
  202. /package/dist/chunks/{chunk-SEKX6IR5.js.map → chunk-AEWKXISZ.js.map} +0 -0
  203. /package/dist/chunks/{chunk-6CQJH56B.js.map → chunk-AHK44IOS.js.map} +0 -0
  204. /package/dist/chunks/{chunk-3NCL3Y53.js.map → chunk-DPCUP4TI.js.map} +0 -0
  205. /package/dist/chunks/{chunk-F2JKDYHA.js.map → chunk-FUORCVIN.js.map} +0 -0
  206. /package/dist/chunks/{chunk-5GOYK3IN.js.map → chunk-FXXP6QP6.js.map} +0 -0
  207. /package/dist/chunks/{chunk-X3ZBCYV6.js.map → chunk-GEPGHAWO.js.map} +0 -0
  208. /package/dist/chunks/{chunk-23SR4YFL.js.map → chunk-GSZCV2P3.js.map} +0 -0
  209. /package/dist/chunks/{chunk-FKLDO6SF.js.map → chunk-GXQAMIQA.js.map} +0 -0
  210. /package/dist/chunks/{chunk-HV4SSQ2Y.js.map → chunk-HKUWS2WO.js.map} +0 -0
  211. /package/dist/chunks/{chunk-2YPMHUI4.js.map → chunk-HTXPBXXP.js.map} +0 -0
  212. /package/dist/chunks/{chunk-4GDOFBZF.js.map → chunk-IVFJXA6P.js.map} +0 -0
  213. /package/dist/chunks/{chunk-D7FPVZDC.js.map → chunk-KB7EM3DJ.js.map} +0 -0
  214. /package/dist/chunks/{chunk-WMOYTZXD.js.map → chunk-KSQTOA6I.js.map} +0 -0
  215. /package/dist/chunks/{chunk-BV2SDA2D.js.map → chunk-LCFHDWTA.js.map} +0 -0
  216. /package/dist/chunks/{chunk-37A6M7P4.js.map → chunk-LVW3JXVJ.js.map} +0 -0
  217. /package/dist/chunks/{chunk-DBBWIOQS.js.map → chunk-LZISO3TE.js.map} +0 -0
  218. /package/dist/chunks/{chunk-NKERGDBZ.js.map → chunk-MB4SLACG.js.map} +0 -0
  219. /package/dist/chunks/{chunk-KQM2NQ2W.js.map → chunk-MOI4XD5Z.js.map} +0 -0
  220. /package/dist/chunks/{chunk-ZKI3Z4VR.js.map → chunk-MRQ2UQG5.js.map} +0 -0
  221. /package/dist/chunks/{chunk-JH2O55TT.js.map → chunk-NIBOMW4E.js.map} +0 -0
  222. /package/dist/chunks/{chunk-XYXPAVPG.js.map → chunk-OTTDC3KF.js.map} +0 -0
  223. /package/dist/chunks/{chunk-UFZGVNFQ.js.map → chunk-Q2EWUIIT.js.map} +0 -0
  224. /package/dist/chunks/{chunk-QVMTUMTW.js.map → chunk-QINC4TIT.js.map} +0 -0
  225. /package/dist/chunks/{chunk-KSFS3BI7.js.map → chunk-S72MTTOC.js.map} +0 -0
  226. /package/dist/chunks/{chunk-R23DP7S7.js.map → chunk-TGZ7OLDL.js.map} +0 -0
  227. /package/dist/chunks/{chunk-ZRAALEF2.js.map → chunk-TI7LE6F5.js.map} +0 -0
  228. /package/dist/chunks/{chunk-QU3LGVTZ.js.map → chunk-TTCXFX6V.js.map} +0 -0
  229. /package/dist/chunks/{chunk-ZRJYG2F2.js.map → chunk-VEOIRZH4.js.map} +0 -0
  230. /package/dist/chunks/{chunk-MYRLRBZG.js.map → chunk-VSLHC665.js.map} +0 -0
  231. /package/dist/chunks/{chunk-HXFPEA6Z.js.map → chunk-XB7HBRSL.js.map} +0 -0
  232. /package/dist/chunks/{chunk-2EDGH6Y3.js.map → chunk-ZGP5MF2Q.js.map} +0 -0
  233. /package/dist/chunks/{chunk-L7Q7QNNE.js.map → chunk-ZNO7XIZU.js.map} +0 -0
  234. /package/dist/chunks/{cli-runtime-74KKQHC7.js.map → cli-runtime-T6ZXKC2O.js.map} +0 -0
  235. /package/dist/chunks/{commands-2Q7KPVLW.js.map → commands-3RJ5HAMM.js.map} +0 -0
  236. /package/dist/chunks/{crash-report-KDVWQ2RR.js.map → crash-report-ZUP6NMRJ.js.map} +0 -0
  237. /package/dist/chunks/{dist-674RS73L.js.map → dist-5D7BTPT2.js.map} +0 -0
  238. /package/dist/chunks/{dist-4TGHKBRS.js.map → dist-72DFA26L.js.map} +0 -0
  239. /package/dist/chunks/{dist-Q523V5L2.js.map → dist-GXQCJQ53.js.map} +0 -0
  240. /package/dist/chunks/{dist-OMRUSJ5R.js.map → dist-HJCEE57U.js.map} +0 -0
  241. /package/dist/chunks/{dist-25C2CYHP.js.map → dist-I2Q3FRR4.js.map} +0 -0
  242. /package/dist/chunks/{dist-UYD7IXG3.js.map → dist-PE6GSYDP.js.map} +0 -0
  243. /package/dist/chunks/{dist-ZDSPMZ5S.js.map → dist-XFIOSXNS.js.map} +0 -0
  244. /package/dist/chunks/{doctor-TFION64N.js.map → doctor-FPBYPOAK.js.map} +0 -0
  245. /package/dist/chunks/{drain-3W3A4KPX.js.map → drain-N65CXI5H.js.map} +0 -0
  246. /package/dist/chunks/{eval-TCUVH3S3.js.map → eval-SYKBFGGU.js.map} +0 -0
  247. /package/dist/chunks/{home-FYDAEWNW.js.map → home-FJS5AXFZ.js.map} +0 -0
  248. /package/dist/chunks/{lifecycle-ALDBR656.js.map → lifecycle-5RWKT62M.js.map} +0 -0
  249. /package/dist/chunks/{list-Z4XOJJ7V.js.map → list-FUOU75RU.js.map} +0 -0
  250. /package/dist/chunks/{login-UZONOHHT.js.map → login-ELQCFAUF.js.map} +0 -0
  251. /package/dist/chunks/{logs-O3NGOQFC.js.map → logs-OBL6KGPA.js.map} +0 -0
  252. /package/dist/chunks/{mcp-YI6PL4TH.js.map → mcp-TFWJC56M.js.map} +0 -0
  253. /package/dist/chunks/{output-schema-KXKCYDI4.js.map → output-schema-35YWLD2S.js.map} +0 -0
  254. /package/dist/chunks/{pal-2EYYHPXC.js.map → pal-TN4YSFO6.js.map} +0 -0
  255. /package/dist/chunks/{providers-JF5SWSTH.js.map → providers-KC7IQHF7.js.map} +0 -0
  256. /package/dist/chunks/{resume-WR4KOI7Q.js.map → resume-ZLGRUFA3.js.map} +0 -0
  257. /package/dist/chunks/{resume-command-A3HKQSRH.js.map → resume-command-5FDSKSZR.js.map} +0 -0
  258. /package/dist/chunks/{schedule-QIJCYWIQ.js.map → schedule-ZVBIF6JZ.js.map} +0 -0
  259. /package/dist/chunks/{session-step-ZZBENVGS.js.map → session-step-XIYPMQA4.js.map} +0 -0
  260. /package/dist/chunks/{skills-AGU7FTRG.js.map → skills-B35Q357B.js.map} +0 -0
  261. /package/dist/chunks/{state-MTHK7DUX.js.map → state-YXNTJW67.js.map} +0 -0
  262. /package/dist/chunks/{store-EWEKEKSG.js.map → store-5BLKNUFX.js.map} +0 -0
  263. /package/dist/chunks/{store-LPOET7IK.js.map → store-5YOZ57L2.js.map} +0 -0
  264. /package/dist/chunks/{store-XPSGZANO.js.map → store-H5KCO6HN.js.map} +0 -0
  265. /package/dist/chunks/{upgrade-3YOFSMAQ.js.map → upgrade-64USK7BM.js.map} +0 -0
@@ -0,0 +1,2182 @@
1
+ import { createRequire as __namzuCreateRequire } from 'node:module';
2
+ const require = __namzuCreateRequire(import.meta.url);
3
+ import {
4
+ EMPTY_ROWS,
5
+ ParserUnavailableError,
6
+ isDeclarationFile,
7
+ languageOf
8
+ } from "./chunk-7WKQQOKK.js";
9
+ import {
10
+ __name
11
+ } from "./chunk-76FLAFCG.js";
12
+
13
+ // ../analysis/dist/provider.js
14
+ import { lstat as lstat4, realpath as realpath3, stat as stat3 } from "node:fs/promises";
15
+
16
+ // ../analysis/dist/context.js
17
+ import { createHash as createHash3 } from "node:crypto";
18
+ import { lstat as lstat3 } from "node:fs/promises";
19
+ import { join as join4 } from "node:path";
20
+
21
+ // ../analysis/dist/fsafe.js
22
+ import { constants } from "node:fs";
23
+ import { lstat, open, readlink, realpath, stat } from "node:fs/promises";
24
+ import { sep } from "node:path";
25
+ function isInside(rootReal, candidate) {
26
+ return candidate === rootReal || candidate.startsWith(rootReal.endsWith(sep) ? rootReal : rootReal + sep);
27
+ }
28
+ __name(isInside, "isInside");
29
+ var NOFOLLOW = constants.O_NOFOLLOW ?? 0;
30
+ var NONBLOCK = constants.O_NONBLOCK ?? 0;
31
+ async function descriptorInside(rootReal, fd, path, opened) {
32
+ if (process.platform === "linux") {
33
+ try {
34
+ const target = await readlink(`/proc/self/fd/${fd}`);
35
+ return !target.endsWith(" (deleted)") && isInside(rootReal, target);
36
+ } catch {
37
+ }
38
+ }
39
+ try {
40
+ const canonical = await realpath(path);
41
+ if (!isInside(rootReal, canonical))
42
+ return false;
43
+ const now = await stat(canonical);
44
+ return now.ino === opened.ino && now.dev === opened.dev;
45
+ } catch {
46
+ return false;
47
+ }
48
+ }
49
+ __name(descriptorInside, "descriptorInside");
50
+ async function readRegular(rootReal, abs) {
51
+ let before;
52
+ try {
53
+ before = await lstat(abs);
54
+ } catch (err) {
55
+ return {
56
+ ok: false,
57
+ why: err.code === "ENOENT" ? "missing" : "unreadable"
58
+ };
59
+ }
60
+ if (before.isSymbolicLink())
61
+ return { ok: false, why: "link" };
62
+ if (!before.isFile())
63
+ return { ok: false, why: "not-file" };
64
+ try {
65
+ if (!isInside(rootReal, await realpath(abs)))
66
+ return { ok: false, why: "outside" };
67
+ const handle = await open(abs, constants.O_RDONLY | NOFOLLOW | NONBLOCK);
68
+ try {
69
+ const opened = await handle.stat();
70
+ if (!opened.isFile())
71
+ return { ok: false, why: "not-file" };
72
+ if (before.ino !== 0 && (opened.ino !== before.ino || opened.dev !== before.dev)) {
73
+ return { ok: false, why: "link" };
74
+ }
75
+ if (!await descriptorInside(rootReal, handle.fd, abs, opened))
76
+ return { ok: false, why: "outside" };
77
+ const buffer = await handle.readFile();
78
+ if (!isInside(rootReal, await realpath(abs)))
79
+ return { ok: false, why: "outside" };
80
+ return { ok: true, buffer, stat: opened };
81
+ } finally {
82
+ await handle.close();
83
+ }
84
+ } catch (err) {
85
+ const code = err.code;
86
+ if (code === "ELOOP")
87
+ return { ok: false, why: "link" };
88
+ if (code === "ENOENT")
89
+ return { ok: false, why: "missing" };
90
+ return { ok: false, why: "unreadable" };
91
+ }
92
+ }
93
+ __name(readRegular, "readRegular");
94
+ async function conditionOf(rootReal, abs, recorded) {
95
+ let s;
96
+ try {
97
+ s = await lstat(abs);
98
+ } catch {
99
+ return "deleted";
100
+ }
101
+ if (!s.isFile())
102
+ return "violation";
103
+ try {
104
+ if (!isInside(rootReal, await realpath(abs)))
105
+ return "violation";
106
+ } catch {
107
+ return "deleted";
108
+ }
109
+ return s.size === recorded.size && s.mtimeMs === recorded.mtimeMs ? "same" : "changed";
110
+ }
111
+ __name(conditionOf, "conditionOf");
112
+
113
+ // ../analysis/dist/indexer.js
114
+ import { createHash as createHash2 } from "node:crypto";
115
+ import { lstat as lstat2, readdir as readdir2, realpath as realpath2 } from "node:fs/promises";
116
+ import { join as join3, sep as sep3 } from "node:path";
117
+ import { setImmediate as nextTurn } from "node:timers/promises";
118
+ import { TextDecoder } from "node:util";
119
+
120
+ // ../analysis/dist/host.js
121
+ import { fork } from "node:child_process";
122
+ import { existsSync, realpathSync, writeFileSync } from "node:fs";
123
+ import { createRequire } from "node:module";
124
+ import { tmpdir } from "node:os";
125
+ import { dirname, resolve, sep as sep2 } from "node:path";
126
+ import { fileURLToPath } from "node:url";
127
+ var PARSE_TIMEOUT_MS = 12e4;
128
+ var MIN_PARSE_MS = 1e4;
129
+ var BOOT_TIMEOUT_MS = 15e3;
130
+ function hostScript(override) {
131
+ if (override !== void 0) {
132
+ if (existsSync(override))
133
+ return resolve(override);
134
+ throw new Error(`The indexer host script ${override} does not exist.`);
135
+ }
136
+ const beside = fileURLToPath(new URL("./indexer-host.js", import.meta.url));
137
+ if (existsSync(beside))
138
+ return beside;
139
+ const built = fileURLToPath(new URL("../dist/indexer-host.js", import.meta.url));
140
+ if (existsSync(built))
141
+ return built;
142
+ throw new Error("The indexer host (dist/indexer-host.js) is not built. Run the package build.");
143
+ }
144
+ __name(hostScript, "hostScript");
145
+ function childEnvironment(env = process.env) {
146
+ const keep = ["PATH", "TMPDIR", "TEMP", "TMP", "SYSTEMROOT", "SystemRoot", "LANG", "LC_ALL"];
147
+ const out = {};
148
+ for (const key of keep)
149
+ if (env[key] !== void 0)
150
+ out[key] = env[key];
151
+ return out;
152
+ }
153
+ __name(childEnvironment, "childEnvironment");
154
+ function withoutCoreDump(pid) {
155
+ if (process.platform !== "linux" || pid === void 0)
156
+ return;
157
+ try {
158
+ writeFileSync(`/proc/${pid}/coredump_filter`, "0");
159
+ } catch {
160
+ }
161
+ }
162
+ __name(withoutCoreDump, "withoutCoreDump");
163
+ function permissionArguments(script, parserModule) {
164
+ if (parserModule !== void 0)
165
+ return [];
166
+ try {
167
+ const real = realpathSync(createRequire(script).resolve("oxc-parser"));
168
+ const marker = `${sep2}node_modules${sep2}`;
169
+ const at = real.indexOf(marker);
170
+ if (at < 0)
171
+ return [];
172
+ const modules = real.slice(0, at + marker.length - 1);
173
+ const scriptDir = dirname(realpathSync(script));
174
+ return [
175
+ "--permission",
176
+ "--allow-addons",
177
+ `--allow-fs-read=${scriptDir}`,
178
+ `--allow-fs-read=${dirname(scriptDir)}`,
179
+ `--allow-fs-read=${modules}`
180
+ ];
181
+ } catch {
182
+ return [];
183
+ }
184
+ }
185
+ __name(permissionArguments, "permissionArguments");
186
+ var ParserHost = class {
187
+ static {
188
+ __name(this, "ParserHost");
189
+ }
190
+ script;
191
+ parserModule;
192
+ /** The child being started or running; only events from THIS one may reset state. */
193
+ current;
194
+ ready;
195
+ queue = Promise.resolve();
196
+ disposed = false;
197
+ /** Children this host killed on purpose, so their exit is not read as a crash. */
198
+ killed = /* @__PURE__ */ new WeakSet();
199
+ constructor(script, parserModule) {
200
+ this.script = script;
201
+ this.parserModule = parserModule;
202
+ }
203
+ spawn() {
204
+ if (this.disposed)
205
+ return Promise.reject(abortError());
206
+ this.ready ??= new Promise((resolve2, reject) => {
207
+ const script = hostScript(this.script);
208
+ const child = fork(script, this.parserModule !== void 0 ? [this.parserModule] : [], {
209
+ // Not the project: a crash handler that writes `core` into the
210
+ // crashed process's working directory must not write it there.
211
+ cwd: tmpdir(),
212
+ // A heap big enough for the AST of the largest file allowed, none of
213
+ // the parent's debugger / loader flags, and the permission model.
214
+ execArgv: ["--max-old-space-size=4096", ...permissionArguments(script, this.parserModule)],
215
+ env: childEnvironment(),
216
+ serialization: "advanced",
217
+ stdio: ["ignore", "ignore", "ignore", "ipc"]
218
+ });
219
+ withoutCoreDump(child.pid);
220
+ this.current = child;
221
+ const timer = setTimeout(() => {
222
+ this.kill(child);
223
+ reject(new Error("The indexer host did not start."));
224
+ }, BOOT_TIMEOUT_MS);
225
+ const onMessage = /* @__PURE__ */ __name((m) => {
226
+ if (m.t !== "ready")
227
+ return;
228
+ clearTimeout(timer);
229
+ child.off("message", onMessage);
230
+ this.idle(child);
231
+ resolve2(child);
232
+ }, "onMessage");
233
+ const forget = /* @__PURE__ */ __name(() => {
234
+ if (this.current === child) {
235
+ this.current = void 0;
236
+ this.ready = void 0;
237
+ }
238
+ }, "forget");
239
+ child.on("message", onMessage);
240
+ child.once("exit", () => {
241
+ clearTimeout(timer);
242
+ forget();
243
+ reject(new Error("The indexer host exited before it was ready."));
244
+ });
245
+ child.once("error", (err) => {
246
+ clearTimeout(timer);
247
+ forget();
248
+ reject(err);
249
+ });
250
+ });
251
+ return this.ready;
252
+ }
253
+ /** Between requests the child must not keep the parent's event loop alive. */
254
+ idle(child) {
255
+ child.unref();
256
+ child.channel?.unref();
257
+ }
258
+ busy(child) {
259
+ child.ref();
260
+ child.channel?.ref();
261
+ }
262
+ /**
263
+ * Parse one file's text in the child. Never throws for a crash; throws an
264
+ * abort error when cancelled or disposed. `timeoutMs` bounds this parse.
265
+ */
266
+ parse(job, signal, timeoutMs = PARSE_TIMEOUT_MS) {
267
+ const run = /* @__PURE__ */ __name(async () => {
268
+ if (signal?.aborted || this.disposed)
269
+ throw abortError();
270
+ const child = await this.spawn();
271
+ if (signal?.aborted || this.disposed)
272
+ throw abortError();
273
+ return await new Promise((resolve2, reject) => {
274
+ let started = false;
275
+ this.busy(child);
276
+ const cleanup = /* @__PURE__ */ __name(() => {
277
+ clearTimeout(timer);
278
+ child.off("message", onMessage);
279
+ child.off("exit", onExit);
280
+ signal?.removeEventListener("abort", onAbort);
281
+ if (!child.killed)
282
+ this.idle(child);
283
+ }, "cleanup");
284
+ const onMessage = /* @__PURE__ */ __name((m) => {
285
+ if (m.t === "start") {
286
+ started = true;
287
+ return;
288
+ }
289
+ if (m.t === "done" && m.rel === job.rel) {
290
+ cleanup();
291
+ resolve2({ kind: "rows", parseErrors: m.parseErrors, rows: m.rows });
292
+ } else if (m.t === "fail" && m.rel === job.rel) {
293
+ cleanup();
294
+ if (m.unavailable)
295
+ reject(new ParserUnavailableError(m.error));
296
+ else
297
+ resolve2({ kind: "error", error: m.error });
298
+ }
299
+ }, "onMessage");
300
+ const onExit = /* @__PURE__ */ __name((code, sig) => {
301
+ cleanup();
302
+ if (this.current === child) {
303
+ this.current = void 0;
304
+ this.ready = void 0;
305
+ }
306
+ if (this.killed.has(child)) {
307
+ reject(abortError());
308
+ return;
309
+ }
310
+ resolve2({
311
+ kind: "crash",
312
+ detail: `the parser process ended ${sig ? `with ${sig}` : `with exit code ${code}`}${started ? "" : " before it began"}`
313
+ });
314
+ }, "onExit");
315
+ const onAbort = /* @__PURE__ */ __name(() => {
316
+ cleanup();
317
+ this.kill(child);
318
+ reject(abortError());
319
+ }, "onAbort");
320
+ const limit = Math.min(timeoutMs, PARSE_TIMEOUT_MS);
321
+ const timer = setTimeout(() => {
322
+ cleanup();
323
+ this.kill(child);
324
+ resolve2({
325
+ kind: "crash",
326
+ detail: `the parser ran past ${Math.round(limit / 1e3)} seconds and was stopped`
327
+ });
328
+ }, limit);
329
+ child.on("message", onMessage);
330
+ child.once("exit", onExit);
331
+ signal?.addEventListener("abort", onAbort, { once: true });
332
+ child.send({ t: "parse", ...job });
333
+ });
334
+ }, "run");
335
+ const next = this.queue.then(run, run);
336
+ this.queue = next.catch(() => void 0);
337
+ return next;
338
+ }
339
+ kill(child) {
340
+ if (!child)
341
+ return;
342
+ this.killed.add(child);
343
+ if (this.current === child) {
344
+ this.current = void 0;
345
+ this.ready = void 0;
346
+ }
347
+ child.kill("SIGKILL");
348
+ }
349
+ /** Stop the child now, without closing the host: the next parse starts a new one. */
350
+ killChild() {
351
+ this.kill(this.current);
352
+ }
353
+ /** Close the host: nothing parses after this, and a parse in flight is cancelled. */
354
+ dispose() {
355
+ this.disposed = true;
356
+ this.kill(this.current);
357
+ }
358
+ };
359
+ function abortError() {
360
+ const err = new Error("The operation was cancelled.");
361
+ err.name = "AbortError";
362
+ return err;
363
+ }
364
+ __name(abortError, "abortError");
365
+
366
+ // ../analysis/dist/lines.js
367
+ function lineStarts(text) {
368
+ let count = 1;
369
+ for (let i = text.indexOf("\n"); i !== -1; i = text.indexOf("\n", i + 1))
370
+ count++;
371
+ const starts = new Uint32Array(count);
372
+ let n = 1;
373
+ for (let i = text.indexOf("\n"); i !== -1; i = text.indexOf("\n", i + 1))
374
+ starts[n++] = i + 1;
375
+ return starts;
376
+ }
377
+ __name(lineStarts, "lineStarts");
378
+ function position(starts, offset) {
379
+ let lo = 0;
380
+ let hi = starts.length - 1;
381
+ while (lo < hi) {
382
+ const mid = lo + hi + 1 >> 1;
383
+ if (starts[mid] <= offset)
384
+ lo = mid;
385
+ else
386
+ hi = mid - 1;
387
+ }
388
+ return { line: lo + 1, column: offset - starts[lo] + 1 };
389
+ }
390
+ __name(position, "position");
391
+ function offsetOf(starts, chars, line, column) {
392
+ if (!Number.isInteger(line) || line < 1 || line > starts.length) {
393
+ return { error: `line ${line} is outside the file, which has ${starts.length} line(s)` };
394
+ }
395
+ const lineStart = starts[line - 1];
396
+ const lineEnd = line < starts.length ? starts[line] - 1 : chars;
397
+ const width = lineEnd - lineStart;
398
+ if (!Number.isInteger(column) || column < 1 || column - 1 > width) {
399
+ return {
400
+ error: `column ${column} is outside line ${line}, which is ${width} character(s) wide (columns are one-based UTF-16 units)`
401
+ };
402
+ }
403
+ return { offset: lineStart + column - 1 };
404
+ }
405
+ __name(offsetOf, "offsetOf");
406
+ function encodeLineStarts(starts) {
407
+ return new Uint8Array(starts.buffer.slice(starts.byteOffset, starts.byteOffset + starts.byteLength));
408
+ }
409
+ __name(encodeLineStarts, "encodeLineStarts");
410
+ function decodeLineStarts(blob) {
411
+ return new Uint32Array(blob.slice().buffer);
412
+ }
413
+ __name(decodeLineStarts, "decodeLineStarts");
414
+
415
+ // ../analysis/dist/store.js
416
+ import { mkdirSync, rmSync } from "node:fs";
417
+ import { join as join2 } from "node:path";
418
+ import { setTimeout as sleep } from "node:timers/promises";
419
+
420
+ // ../analysis/dist/cache-key.js
421
+ import { createHash } from "node:crypto";
422
+ function cacheKey(root) {
423
+ return createHash("sha256").update(root).digest("hex").slice(0, 16);
424
+ }
425
+ __name(cacheKey, "cacheKey");
426
+
427
+ // ../analysis/dist/evict.js
428
+ import { readdir, rm, stat as stat2, utimes } from "node:fs/promises";
429
+ import { join } from "node:path";
430
+ var DEFAULT_CACHE_MAX_AGE_DAYS = 30;
431
+ var DEFAULT_CACHE_MAX_BYTES = 2 * 1024 * 1024 * 1024;
432
+ var RECENT_MS = 60 * 60 * 1e3;
433
+ async function touchCache(location) {
434
+ const now = /* @__PURE__ */ new Date();
435
+ await utimes(location, now, now).catch(() => void 0);
436
+ }
437
+ __name(touchCache, "touchCache");
438
+ async function evictCaches(cacheDir, keep, policy, now = Date.now()) {
439
+ const removed = [];
440
+ let names;
441
+ try {
442
+ names = (await readdir(cacheDir)).filter((n) => n.endsWith(".sqlite"));
443
+ } catch {
444
+ return removed;
445
+ }
446
+ const entries = [];
447
+ for (const name of names) {
448
+ try {
449
+ const main = await stat2(join(cacheDir, name));
450
+ const wal = await stat2(join(cacheDir, `${name}-wal`)).catch(() => void 0);
451
+ entries.push({ name, mtime: main.mtimeMs, bytes: main.size + (wal?.size ?? 0) });
452
+ } catch {
453
+ }
454
+ }
455
+ const drop = /* @__PURE__ */ __name(async (name) => {
456
+ for (const suffix of ["", "-wal", "-shm"])
457
+ await rm(join(cacheDir, `${name}${suffix}`), { force: true }).catch(() => void 0);
458
+ removed.push(name);
459
+ }, "drop");
460
+ const evictable = /* @__PURE__ */ __name((e) => e.name !== keep && now - e.mtime > RECENT_MS, "evictable");
461
+ const cutoff = now - policy.maxAgeDays * 24 * 60 * 60 * 1e3;
462
+ let live = entries;
463
+ for (const e of entries) {
464
+ if (evictable(e) && e.mtime < cutoff)
465
+ await drop(e.name);
466
+ }
467
+ live = entries.filter((e) => !removed.includes(e.name));
468
+ let total = live.reduce((sum, e) => sum + e.bytes, 0);
469
+ for (const e of [...live].sort((a, b) => a.mtime - b.mtime)) {
470
+ if (total <= policy.maxBytes)
471
+ break;
472
+ if (!evictable(e))
473
+ continue;
474
+ await drop(e.name);
475
+ total -= e.bytes;
476
+ }
477
+ return removed;
478
+ }
479
+ __name(evictCaches, "evictCaches");
480
+
481
+ // ../analysis/dist/store.js
482
+ var SCHEMA_VERSION = 1;
483
+ var sqlite;
484
+ async function loadSqlite() {
485
+ sqlite ??= import("node:sqlite").catch(() => void 0);
486
+ return await sqlite;
487
+ }
488
+ __name(loadSqlite, "loadSqlite");
489
+ var TABLES = `
490
+ CREATE TABLE IF NOT EXISTS meta(key TEXT PRIMARY KEY, value TEXT NOT NULL);
491
+ CREATE TABLE IF NOT EXISTS files(
492
+ id INTEGER PRIMARY KEY, path TEXT NOT NULL UNIQUE, chars INTEGER NOT NULL, lang TEXT NOT NULL,
493
+ parse_errors INTEGER NOT NULL, line_starts BLOB NOT NULL, size INTEGER NOT NULL,
494
+ mtime_ms REAL NOT NULL, hash TEXT NOT NULL);
495
+ CREATE TABLE IF NOT EXISTS dirs(path TEXT PRIMARY KEY, mtime_ms REAL NOT NULL);
496
+ CREATE TABLE IF NOT EXISTS functions(
497
+ id INTEGER PRIMARY KEY, file_id INTEGER NOT NULL, parent_id INTEGER, kind TEXT NOT NULL, name TEXT,
498
+ start INTEGER NOT NULL, "end" INTEGER NOT NULL, sline INTEGER NOT NULL, eline INTEGER NOT NULL);
499
+ CREATE TABLE IF NOT EXISTS strings(
500
+ id INTEGER PRIMARY KEY, file_id INTEGER NOT NULL, fn_id INTEGER, start INTEGER NOT NULL,
501
+ "end" INTEGER NOT NULL, kind TEXT NOT NULL, value TEXT NOT NULL);
502
+ CREATE TABLE IF NOT EXISTS calls(
503
+ file_id INTEGER NOT NULL, fn_id INTEGER, start INTEGER NOT NULL, "end" INTEGER NOT NULL,
504
+ callee TEXT NOT NULL, kind TEXT NOT NULL, nargs INTEGER NOT NULL);
505
+ CREATE TABLE IF NOT EXISTS imports(
506
+ file_id INTEGER NOT NULL, kind TEXT NOT NULL, source TEXT NOT NULL, names TEXT NOT NULL, start INTEGER NOT NULL);
507
+ CREATE TABLE IF NOT EXISTS exports(
508
+ file_id INTEGER NOT NULL, kind TEXT NOT NULL, name TEXT NOT NULL, source TEXT, start INTEGER NOT NULL);
509
+ `;
510
+ var SECONDARY_INDEXES = `
511
+ CREATE INDEX IF NOT EXISTS fn_file_start ON functions(file_id, start);
512
+ CREATE INDEX IF NOT EXISTS fn_name ON functions(name);
513
+ CREATE INDEX IF NOT EXISTS str_fn ON strings(fn_id);
514
+ CREATE INDEX IF NOT EXISTS str_file ON strings(file_id, start);
515
+ CREATE INDEX IF NOT EXISTS call_callee ON calls(callee);
516
+ CREATE INDEX IF NOT EXISTS call_file ON calls(file_id, start);
517
+ CREATE INDEX IF NOT EXISTS imp_file ON imports(file_id);
518
+ CREATE INDEX IF NOT EXISTS exp_file ON exports(file_id);
519
+ `;
520
+ var CRASHED = -1;
521
+ var WRITE_LOCK_WAIT_MS = 12e4;
522
+ function isBusy(err) {
523
+ const message = err instanceof Error ? err.message : String(err);
524
+ return /database is locked|database table is locked|SQLITE_BUSY|SQLITE_LOCKED/i.test(message);
525
+ }
526
+ __name(isBusy, "isBusy");
527
+ function isCorrupt(err) {
528
+ const message = err instanceof Error ? err.message : String(err);
529
+ return /file is not a database|database disk image is malformed|SQLITE_NOTADB|SQLITE_CORRUPT/i.test(message);
530
+ }
531
+ __name(isCorrupt, "isCorrupt");
532
+ var Store = class _Store {
533
+ static {
534
+ __name(this, "Store");
535
+ }
536
+ db;
537
+ persisted;
538
+ fts;
539
+ chain = Promise.resolve();
540
+ cache = /* @__PURE__ */ new Map();
541
+ constructor(db, persisted, fts) {
542
+ this.db = db;
543
+ this.persisted = persisted;
544
+ this.fts = fts;
545
+ }
546
+ /**
547
+ * Open (or create) the database for `root`.
548
+ *
549
+ * `cacheDir` of `undefined` is an in-memory database. A directory that
550
+ * cannot be written falls back to memory rather than failing the tool: an
551
+ * index that does not persist is slower next launch, not wrong.
552
+ */
553
+ static async open(root, cacheDir, allowFts = true, eviction) {
554
+ const mod = await loadSqlite();
555
+ if (!mod)
556
+ return void 0;
557
+ const fts = allowFts && probeFts(mod);
558
+ if (cacheDir !== void 0) {
559
+ const location = join2(cacheDir, `${cacheKey(root)}-v${SCHEMA_VERSION}-${fts ? "fts" : "scan"}.sqlite`);
560
+ const deadline = Date.now() + WRITE_LOCK_WAIT_MS;
561
+ let corruptSeen = false;
562
+ for (; ; ) {
563
+ try {
564
+ const store = _Store.openAt(mod, root, location, fts);
565
+ await touchCache(location);
566
+ if (eviction)
567
+ void evictCaches(cacheDir, location.slice(cacheDir.length + 1), eviction);
568
+ return store;
569
+ } catch (err) {
570
+ if (isBusy(err) && Date.now() < deadline) {
571
+ await sleep(50);
572
+ continue;
573
+ }
574
+ if (isCorrupt(err) && !corruptSeen) {
575
+ corruptSeen = true;
576
+ for (const suffix of ["", "-wal", "-shm"])
577
+ rmSync(`${location}${suffix}`, { force: true });
578
+ continue;
579
+ }
580
+ break;
581
+ }
582
+ }
583
+ }
584
+ return _Store.openAt(mod, root, void 0, fts);
585
+ }
586
+ static openAt(mod, root, location, fts) {
587
+ if (location !== void 0)
588
+ mkdirSync(join2(location, ".."), { recursive: true, mode: 448 });
589
+ const db = new mod.DatabaseSync(location ?? ":memory:");
590
+ try {
591
+ db.exec("PRAGMA busy_timeout=250");
592
+ if (location !== void 0)
593
+ db.exec("PRAGMA journal_mode=WAL; PRAGMA synchronous=NORMAL;");
594
+ const existing = readRoot(db);
595
+ if (existing !== void 0) {
596
+ if (existing !== root)
597
+ throw new Error("cache file belongs to a different root");
598
+ return new _Store(db, location !== void 0, fts);
599
+ }
600
+ db.exec("BEGIN IMMEDIATE");
601
+ try {
602
+ db.exec(TABLES);
603
+ if (fts) {
604
+ db.exec("CREATE VIRTUAL TABLE IF NOT EXISTS lit USING fts5(value, content='strings', content_rowid='id', tokenize='trigram');");
605
+ }
606
+ const put = db.prepare("INSERT OR IGNORE INTO meta(key, value) VALUES(?, ?)");
607
+ put.run("schema", String(SCHEMA_VERSION));
608
+ put.run("root", root);
609
+ put.run("fts", fts ? "1" : "0");
610
+ put.run("generation", "0");
611
+ put.run("next_fn_id", "1");
612
+ put.run("covered", "[]");
613
+ const stored = db.prepare("SELECT value FROM meta WHERE key = 'root'").get();
614
+ if (stored.value !== root)
615
+ throw new Error("cache file belongs to a different root");
616
+ db.exec("COMMIT");
617
+ } catch (err) {
618
+ try {
619
+ db.exec("ROLLBACK");
620
+ } catch {
621
+ }
622
+ throw err;
623
+ }
624
+ } catch (err) {
625
+ db.close();
626
+ throw err;
627
+ }
628
+ return new _Store(db, location !== void 0, fts);
629
+ }
630
+ /** Run `work` with this process's use of the database to itself; calls queue in order. */
631
+ run(work) {
632
+ const next = this.chain.then(work, work);
633
+ this.chain = next.catch(() => void 0);
634
+ return next;
635
+ }
636
+ /**
637
+ * Take the write lock, waiting for another process if it holds it.
638
+ *
639
+ * `BEGIN IMMEDIATE`: a deferred `BEGIN` reads first and fails with
640
+ * "database is locked" at the first write when another process got there,
641
+ * which is the shape the concurrent-refresh failures took.
642
+ */
643
+ async begin(signal) {
644
+ const deadline = Date.now() + WRITE_LOCK_WAIT_MS;
645
+ for (; ; ) {
646
+ if (signal?.aborted)
647
+ throw abortError();
648
+ try {
649
+ this.db.exec("BEGIN IMMEDIATE");
650
+ return;
651
+ } catch (err) {
652
+ if (!isBusy(err) || Date.now() >= deadline)
653
+ throw err;
654
+ await sleep(40, void 0, signal ? { signal } : void 0).catch(() => {
655
+ throw abortError();
656
+ });
657
+ }
658
+ }
659
+ }
660
+ commit() {
661
+ this.db.exec("COMMIT");
662
+ }
663
+ rollback() {
664
+ try {
665
+ this.db.exec("ROLLBACK");
666
+ } catch {
667
+ }
668
+ }
669
+ prepare(sql) {
670
+ let stmt = this.cache.get(sql);
671
+ if (!stmt) {
672
+ stmt = this.db.prepare(sql);
673
+ this.cache.set(sql, stmt);
674
+ }
675
+ return stmt;
676
+ }
677
+ all(sql, ...params) {
678
+ return this.prepare(sql).all(...params);
679
+ }
680
+ get(sql, ...params) {
681
+ return this.prepare(sql).get(...params);
682
+ }
683
+ exec(sql) {
684
+ this.db.exec(sql);
685
+ }
686
+ meta(key) {
687
+ const row = this.get("SELECT value FROM meta WHERE key = ?", key);
688
+ return row ? String(row.value) : void 0;
689
+ }
690
+ setMeta(key, value) {
691
+ this.prepare("INSERT OR REPLACE INTO meta(key, value) VALUES(?, ?)").run(key, value);
692
+ }
693
+ bumpGeneration() {
694
+ const next = Number(this.meta("generation") ?? "0") + 1;
695
+ this.setMeta("generation", String(next));
696
+ return next;
697
+ }
698
+ ensureIndexes() {
699
+ this.db.exec(SECONDARY_INDEXES);
700
+ }
701
+ /** Every stored file at or under `scope` (a relative path; empty is all), keyed by path. */
702
+ storedFiles(scope) {
703
+ const map = /* @__PURE__ */ new Map();
704
+ const rows = scope === "" ? this.all("SELECT id, path, size, mtime_ms, hash FROM files") : this.all("SELECT id, path, size, mtime_ms, hash FROM files WHERE path = ? OR (path >= ? AND path < ?)", scope, `${scope}/`, `${scope}0`);
705
+ for (const r of rows) {
706
+ map.set(String(r.path), {
707
+ id: Number(r.id),
708
+ size: Number(r.size),
709
+ mtimeMs: Number(r.mtime_ms),
710
+ hash: String(r.hash)
711
+ });
712
+ }
713
+ return map;
714
+ }
715
+ /** Remove a file and every row that hangs off it. */
716
+ removeFile(fileId) {
717
+ if (this.fts) {
718
+ this.prepare("INSERT INTO lit(lit, rowid, value) SELECT 'delete', id, value FROM strings WHERE file_id = ? AND length(value) >= 3").run(fileId);
719
+ }
720
+ for (const table of ["strings", "calls", "functions", "imports", "exports"]) {
721
+ this.prepare(`DELETE FROM ${table} WHERE file_id = ?`).run(fileId);
722
+ }
723
+ this.prepare("DELETE FROM files WHERE id = ?").run(fileId);
724
+ }
725
+ removeByPath(path) {
726
+ const row = this.get("SELECT id FROM files WHERE path = ?", path);
727
+ if (!row)
728
+ return false;
729
+ this.removeFile(Number(row.id));
730
+ return true;
731
+ }
732
+ /**
733
+ * Write one parsed file and return how many function ids it used.
734
+ *
735
+ * Must run inside a transaction that holds the write lock: the first id is
736
+ * read from `meta` here, so two processes can never hand out the same one,
737
+ * and a row another process wrote for this path in the meantime is replaced
738
+ * rather than colliding with it.
739
+ */
740
+ writeFile(record) {
741
+ const { rows, lineStarts: lineStarts2 } = record;
742
+ this.removeByPath(record.path);
743
+ const base = Number(this.meta("next_fn_id") ?? "1");
744
+ const lineOf = /* @__PURE__ */ __name((offset) => {
745
+ let lo = 0;
746
+ let hi = lineStarts2.length - 1;
747
+ while (lo < hi) {
748
+ const mid = lo + hi + 1 >> 1;
749
+ if (lineStarts2[mid] <= offset)
750
+ lo = mid;
751
+ else
752
+ hi = mid - 1;
753
+ }
754
+ return lo + 1;
755
+ }, "lineOf");
756
+ const result = this.prepare("INSERT INTO files(path, chars, lang, parse_errors, line_starts, size, mtime_ms, hash) VALUES(?,?,?,?,?,?,?,?)").run(record.path, record.chars, record.lang, record.parseErrors, encodeLineStarts(lineStarts2), record.size, record.mtimeMs, record.hash);
757
+ const id = Number(result.lastInsertRowid);
758
+ const remap = /* @__PURE__ */ __name((local) => local === null ? null : base + local, "remap");
759
+ const insFn = this.prepare("INSERT INTO functions VALUES(?,?,?,?,?,?,?,?,?)");
760
+ for (const f of rows.functions) {
761
+ insFn.run(base + f.id, id, remap(f.parentId), f.kind, f.name, f.start, f.end, lineOf(f.start), lineOf(f.end));
762
+ }
763
+ const insStr = this.prepare('INSERT INTO strings(file_id, fn_id, start, "end", kind, value) VALUES(?,?,?,?,?,?)');
764
+ const insLit = this.fts ? this.prepare("INSERT INTO lit(rowid, value) VALUES(?, ?)") : void 0;
765
+ for (const s of rows.strings) {
766
+ const r = insStr.run(id, remap(s.fnId), s.start, s.end, s.kind, s.value);
767
+ if (insLit && s.value.length >= 3)
768
+ insLit.run(Number(r.lastInsertRowid), s.value);
769
+ }
770
+ const insCall = this.prepare("INSERT INTO calls VALUES(?,?,?,?,?,?,?)");
771
+ for (const c of rows.calls)
772
+ insCall.run(id, remap(c.fnId), c.start, c.end, c.callee, c.kind, c.nargs);
773
+ const insImp = this.prepare("INSERT INTO imports VALUES(?,?,?,?,?)");
774
+ for (const i of rows.imports)
775
+ insImp.run(id, i.kind, i.source, i.names, i.start);
776
+ const insExp = this.prepare("INSERT INTO exports VALUES(?,?,?,?,?)");
777
+ for (const e of rows.exports)
778
+ insExp.run(id, e.kind, e.name, e.source, e.start);
779
+ this.setMeta("next_fn_id", String(base + rows.functions.length));
780
+ }
781
+ close() {
782
+ this.cache.clear();
783
+ try {
784
+ this.db.close();
785
+ } catch {
786
+ }
787
+ }
788
+ };
789
+ function readRoot(db) {
790
+ try {
791
+ const row = db.prepare("SELECT value FROM meta WHERE key = 'root'").get();
792
+ return row?.value;
793
+ } catch {
794
+ return void 0;
795
+ }
796
+ }
797
+ __name(readRoot, "readRoot");
798
+ function probeFts(mod) {
799
+ const db = new mod.DatabaseSync(":memory:");
800
+ try {
801
+ db.exec("CREATE VIRTUAL TABLE t USING fts5(x, tokenize='trigram')");
802
+ return true;
803
+ } catch {
804
+ return false;
805
+ } finally {
806
+ db.close();
807
+ }
808
+ }
809
+ __name(probeFts, "probeFts");
810
+
811
+ // ../analysis/dist/indexer.js
812
+ var DEFAULT_IGNORED_DIRS = [
813
+ "node_modules",
814
+ ".git",
815
+ ".hg",
816
+ ".svn",
817
+ ".namzu",
818
+ ".turbo",
819
+ ".cache",
820
+ "coverage"
821
+ ];
822
+ var DEFAULT_MAX_FILE_BYTES = 32 * 1024 * 1024;
823
+ var DEFAULT_MAX_FILES = 15e4;
824
+ var DEFAULT_MAX_DIRECTORIES = 2e4;
825
+ var DEFAULT_MAX_MILLIS = 45e3;
826
+ var SLICE_MS = 20;
827
+ var NAMED_LIMIT = 20;
828
+ var decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
829
+ function decodeText(buffer) {
830
+ const head = Math.min(buffer.length, 8192);
831
+ for (let i = 0; i < head; i++)
832
+ if (buffer[i] === 0)
833
+ return void 0;
834
+ try {
835
+ return decoder.decode(buffer);
836
+ } catch {
837
+ return void 0;
838
+ }
839
+ }
840
+ __name(decodeText, "decodeText");
841
+ function hashOf(buffer) {
842
+ return createHash2("sha1").update(buffer).digest("hex");
843
+ }
844
+ __name(hashOf, "hashOf");
845
+ function toRel(root, abs) {
846
+ if (abs === root)
847
+ return "";
848
+ const prefix = root.endsWith(sep3) ? root : root + sep3;
849
+ if (!abs.startsWith(prefix))
850
+ return void 0;
851
+ return abs.slice(prefix.length).split(sep3).join("/");
852
+ }
853
+ __name(toRel, "toRel");
854
+ function checkAbort(signal) {
855
+ if (signal?.aborted)
856
+ throw abortError();
857
+ }
858
+ __name(checkAbort, "checkAbort");
859
+ function overTime(b) {
860
+ return performance.now() - b.started > b.options.maxMillis;
861
+ }
862
+ __name(overTime, "overTime");
863
+ async function collect(root, start, b, skip) {
864
+ const walk = { files: [], dirs: [], truncated: void 0 };
865
+ const ignored = new Set(b.options.ignoreDirs);
866
+ let first;
867
+ try {
868
+ first = await lstat2(start);
869
+ } catch {
870
+ return walk;
871
+ }
872
+ const startRel = toRel(root, start) ?? "";
873
+ if (first.isSymbolicLink()) {
874
+ skip("symbolic link");
875
+ return walk;
876
+ }
877
+ if (first.isFile()) {
878
+ if (languageOf(start) !== void 0 && !isDeclarationFile(start))
879
+ walk.files.push({ rel: startRel, abs: start });
880
+ return walk;
881
+ }
882
+ if (!first.isDirectory())
883
+ return walk;
884
+ const pending = [{ abs: start, rel: startRel }];
885
+ let lastYield = performance.now();
886
+ let visited = 0;
887
+ while (pending.length > 0) {
888
+ checkAbort(b.signal);
889
+ if (visited >= b.options.maxDirectories) {
890
+ walk.truncated = `stopped after walking ${visited.toLocaleString("en-US")} directories`;
891
+ break;
892
+ }
893
+ if (overTime(b)) {
894
+ walk.truncated = `stopped after ${Math.round(b.options.maxMillis / 1e3)} seconds`;
895
+ break;
896
+ }
897
+ const dir = pending.pop();
898
+ visited++;
899
+ let entries;
900
+ try {
901
+ entries = await readdir2(dir.abs, { withFileTypes: true });
902
+ walk.dirs.push({ rel: dir.rel, mtimeMs: (await lstat2(dir.abs)).mtimeMs });
903
+ } catch {
904
+ skip("unreadable directory");
905
+ continue;
906
+ }
907
+ entries.sort((x, y) => x.name < y.name ? -1 : x.name > y.name ? 1 : 0);
908
+ const subdirs = [];
909
+ for (const entry of entries) {
910
+ const rel = dir.rel === "" ? entry.name : `${dir.rel}/${entry.name}`;
911
+ if (entry.isSymbolicLink()) {
912
+ if (languageOf(entry.name) !== void 0)
913
+ skip("symbolic link");
914
+ continue;
915
+ }
916
+ if (entry.isDirectory()) {
917
+ if (!ignored.has(entry.name))
918
+ subdirs.push({ abs: join3(dir.abs, entry.name), rel });
919
+ continue;
920
+ }
921
+ if (!entry.isFile() || languageOf(entry.name) === void 0)
922
+ continue;
923
+ if (isDeclarationFile(entry.name)) {
924
+ skip("declaration file");
925
+ continue;
926
+ }
927
+ if (walk.files.length >= b.options.maxFiles) {
928
+ walk.truncated = `stopped at the ${b.options.maxFiles.toLocaleString("en-US")}-file limit`;
929
+ break;
930
+ }
931
+ walk.files.push({ rel, abs: join3(dir.abs, entry.name) });
932
+ }
933
+ for (let i = subdirs.length - 1; i >= 0; i--)
934
+ pending.push(subdirs[i]);
935
+ if (walk.truncated)
936
+ break;
937
+ if (performance.now() - lastYield > SLICE_MS) {
938
+ await nextTurn();
939
+ lastYield = performance.now();
940
+ }
941
+ }
942
+ walk.files.sort((x, y) => x.rel < y.rel ? -1 : x.rel > y.rel ? 1 : 0);
943
+ return walk;
944
+ }
945
+ __name(collect, "collect");
946
+ function jsonList(store, key) {
947
+ try {
948
+ const parsed = JSON.parse(store.meta(key) ?? "[]");
949
+ return Array.isArray(parsed) ? parsed : [];
950
+ } catch {
951
+ return [];
952
+ }
953
+ }
954
+ __name(jsonList, "jsonList");
955
+ function noteNamed(store, key, rel) {
956
+ const list = jsonList(store, key);
957
+ if (!list.includes(rel))
958
+ store.setMeta(key, JSON.stringify([...list, rel].slice(-NAMED_LIMIT)));
959
+ }
960
+ __name(noteNamed, "noteNamed");
961
+ function unnote(store, key, rel) {
962
+ const list = jsonList(store, key);
963
+ if (list.includes(rel))
964
+ store.setMeta(key, JSON.stringify(list.filter((r) => r !== rel)));
965
+ }
966
+ __name(unnote, "unnote");
967
+ var FLUSH_FILES = 50;
968
+ var FLUSH_ROWS = 15e4;
969
+ async function refreshIndex(store, root, scopeAbs, options, host, signal) {
970
+ const skippedReasons = {};
971
+ const skip = /* @__PURE__ */ __name((reason) => {
972
+ skippedReasons[reason] = (skippedReasons[reason] ?? 0) + 1;
973
+ }, "skip");
974
+ const budget = { started: performance.now(), options, signal };
975
+ const scopeRel = toRel(root, scopeAbs) ?? "";
976
+ try {
977
+ if (!isInside(root, await realpath2(scopeAbs))) {
978
+ skip("path outside the root");
979
+ return outcomeOf(store, skippedReasons, 0, 0, 0, false, void 0);
980
+ }
981
+ } catch {
982
+ }
983
+ const walk = await collect(root, scopeAbs, budget, skip);
984
+ let truncated = walk.truncated;
985
+ const stored = store.storedFiles(scopeRel);
986
+ const seen = new Set(walk.files.map((f) => f.rel));
987
+ let parsed = 0;
988
+ let unchanged = 0;
989
+ let removed = 0;
990
+ let changed = false;
991
+ let dirty = false;
992
+ let lastYield = performance.now();
993
+ let pending = [];
994
+ let pendingRows = 0;
995
+ const flush = /* @__PURE__ */ __name(async () => {
996
+ if (pending.length === 0 && !dirty)
997
+ return;
998
+ await store.begin();
999
+ try {
1000
+ for (const write of pending)
1001
+ write();
1002
+ pending = [];
1003
+ pendingRows = 0;
1004
+ if (dirty) {
1005
+ store.bumpGeneration();
1006
+ dirty = false;
1007
+ }
1008
+ store.commit();
1009
+ } catch (err) {
1010
+ store.rollback();
1011
+ throw err;
1012
+ }
1013
+ }, "flush");
1014
+ const queue = /* @__PURE__ */ __name((write, rows = 0) => {
1015
+ pending.push(write);
1016
+ pendingRows += rows;
1017
+ dirty = true;
1018
+ }, "queue");
1019
+ const dropStored = /* @__PURE__ */ __name((before, rel, violation) => {
1020
+ if (!before)
1021
+ return;
1022
+ queue(() => {
1023
+ store.removeFile(before.id);
1024
+ if (violation)
1025
+ noteNamed(store, "violations", rel);
1026
+ });
1027
+ changed = true;
1028
+ }, "dropStored");
1029
+ try {
1030
+ if (scopeRel === "")
1031
+ queue(() => store.setMeta("violations", "[]"));
1032
+ for (const candidate of walk.files) {
1033
+ checkAbort(signal);
1034
+ if (overTime(budget)) {
1035
+ truncated ??= `stopped after ${Math.round(options.maxMillis / 1e3)} seconds`;
1036
+ break;
1037
+ }
1038
+ const before = stored.get(candidate.rel);
1039
+ let lst;
1040
+ try {
1041
+ lst = await lstat2(candidate.abs);
1042
+ } catch {
1043
+ skip("unreadable");
1044
+ continue;
1045
+ }
1046
+ if (!lst.isFile()) {
1047
+ skip("replaced by a link or not a regular file");
1048
+ dropStored(before, candidate.rel, true);
1049
+ seen.delete(candidate.rel);
1050
+ continue;
1051
+ }
1052
+ if (lst.size > options.maxFileBytes) {
1053
+ skip(`over the ${Math.round(options.maxFileBytes / 1048576)} MiB size limit`);
1054
+ dropStored(before, candidate.rel, false);
1055
+ continue;
1056
+ }
1057
+ if (!options.force && before && before.size === lst.size && before.mtimeMs === lst.mtimeMs) {
1058
+ unchanged++;
1059
+ continue;
1060
+ }
1061
+ const read = await readRegular(root, candidate.abs);
1062
+ if (!read.ok) {
1063
+ if (read.why === "link" || read.why === "outside" || read.why === "not-file") {
1064
+ skip("replaced by a link or not a regular file");
1065
+ dropStored(before, candidate.rel, true);
1066
+ seen.delete(candidate.rel);
1067
+ } else
1068
+ skip("unreadable");
1069
+ continue;
1070
+ }
1071
+ const hash = hashOf(read.buffer);
1072
+ if (!options.force && before && before.hash === hash) {
1073
+ const { size, mtimeMs } = read.stat;
1074
+ queue(() => {
1075
+ store.prepare("UPDATE files SET size = ?, mtime_ms = ? WHERE id = ?").run(size, mtimeMs, before.id);
1076
+ });
1077
+ unchanged++;
1078
+ continue;
1079
+ }
1080
+ const text = decodeText(read.buffer);
1081
+ if (text === void 0) {
1082
+ skip("binary or not UTF-8");
1083
+ dropStored(before, candidate.rel, false);
1084
+ continue;
1085
+ }
1086
+ const left = options.maxMillis - (performance.now() - budget.started);
1087
+ const result = await host.parse({ rel: candidate.rel, abs: candidate.abs, text }, signal, Math.max(left, MIN_PARSE_MS));
1088
+ const base = {
1089
+ path: candidate.rel,
1090
+ chars: text.length,
1091
+ lang: languageOf(candidate.abs) ?? "js",
1092
+ lineStarts: lineStarts(text),
1093
+ size: read.stat.size,
1094
+ mtimeMs: read.stat.mtimeMs,
1095
+ hash
1096
+ };
1097
+ if (result.kind === "rows") {
1098
+ const rowCount = result.rows.strings.length + result.rows.calls.length + result.rows.functions.length;
1099
+ queue(() => {
1100
+ store.writeFile({ ...base, parseErrors: result.parseErrors, rows: result.rows });
1101
+ unnote(store, "crashed", candidate.rel);
1102
+ }, rowCount);
1103
+ parsed++;
1104
+ } else if (result.kind === "crash") {
1105
+ queue(() => {
1106
+ store.writeFile({ ...base, parseErrors: CRASHED, rows: EMPTY_ROWS });
1107
+ noteNamed(store, "crashed", candidate.rel);
1108
+ });
1109
+ skip("parser crashed");
1110
+ } else {
1111
+ queue(() => store.writeFile({ ...base, parseErrors: 1, rows: EMPTY_ROWS }));
1112
+ skip("parser failure");
1113
+ }
1114
+ changed = true;
1115
+ if (pending.length >= FLUSH_FILES || pendingRows >= FLUSH_ROWS)
1116
+ await flush();
1117
+ if (performance.now() - lastYield > SLICE_MS) {
1118
+ await nextTurn();
1119
+ lastYield = performance.now();
1120
+ }
1121
+ }
1122
+ if (!walk.truncated) {
1123
+ for (const [path, file] of stored) {
1124
+ if (seen.has(path))
1125
+ continue;
1126
+ const gone = await lstat2(join3(root, ...path.split("/"))).catch(() => void 0);
1127
+ queue(() => {
1128
+ store.removeFile(file.id);
1129
+ if (gone?.isSymbolicLink())
1130
+ noteNamed(store, "violations", path);
1131
+ });
1132
+ removed++;
1133
+ changed = true;
1134
+ }
1135
+ }
1136
+ queue(() => {
1137
+ if (!walk.truncated)
1138
+ recordDirs(store, scopeRel, walk.dirs);
1139
+ store.ensureIndexes();
1140
+ recordCoverage(store, scopeRel, skippedReasons, truncated);
1141
+ });
1142
+ await flush();
1143
+ } catch (err) {
1144
+ if (err instanceof Error && err.name === "AbortError") {
1145
+ try {
1146
+ queue(() => recordCoverage(store, scopeRel, skippedReasons, "was cancelled before it finished", true));
1147
+ dirty = true;
1148
+ await flush();
1149
+ } catch {
1150
+ store.rollback();
1151
+ }
1152
+ } else {
1153
+ store.rollback();
1154
+ }
1155
+ throw err;
1156
+ }
1157
+ return outcomeOf(store, skippedReasons, parsed, unchanged, removed, changed, truncated);
1158
+ }
1159
+ __name(refreshIndex, "refreshIndex");
1160
+ function recordDirs(store, scopeRel, dirs) {
1161
+ if (scopeRel === "")
1162
+ store.exec("DELETE FROM dirs");
1163
+ else
1164
+ store.prepare("DELETE FROM dirs WHERE path = ? OR (path >= ? AND path < ?)").run(scopeRel, `${scopeRel}/`, `${scopeRel}0`);
1165
+ const insDir = store.prepare("INSERT OR REPLACE INTO dirs(path, mtime_ms) VALUES(?, ?)");
1166
+ for (const d of dirs)
1167
+ insDir.run(d.rel, d.mtimeMs);
1168
+ }
1169
+ __name(recordDirs, "recordDirs");
1170
+ function outcomeOf(store, skippedReasons, parsed, unchanged, removed, changed, truncated) {
1171
+ const counts = store.get("SELECT count(*) AS indexed, coalesce(sum(parse_errors > 0), 0) AS bad FROM files");
1172
+ return {
1173
+ parsed,
1174
+ unchanged,
1175
+ removed,
1176
+ skipped: Object.values(skippedReasons).reduce((a, b) => a + b, 0),
1177
+ skippedReasons,
1178
+ withParseErrors: Number(counts.bad),
1179
+ indexed: Number(counts.indexed),
1180
+ changed,
1181
+ ...truncated ? { truncated } : {}
1182
+ };
1183
+ }
1184
+ __name(outcomeOf, "outcomeOf");
1185
+ var MAX_COVERED_ENTRIES = 200;
1186
+ function readCovered(store) {
1187
+ try {
1188
+ const parsed = JSON.parse(store.meta("covered") ?? "[]");
1189
+ return Array.isArray(parsed) ? parsed : [];
1190
+ } catch {
1191
+ return [];
1192
+ }
1193
+ }
1194
+ __name(readCovered, "readCovered");
1195
+ function coveringEntry(covered, scopeRel) {
1196
+ let best;
1197
+ for (const e of covered) {
1198
+ if (!(e.s === "" || e.s === scopeRel || scopeRel.startsWith(`${e.s}/`)))
1199
+ continue;
1200
+ if (best === void 0 || e.s.length > best.s.length)
1201
+ best = e;
1202
+ }
1203
+ return best;
1204
+ }
1205
+ __name(coveringEntry, "coveringEntry");
1206
+ function recordCoverage(store, scopeRel, skipped, truncated, cancelled = false) {
1207
+ const mine = {
1208
+ s: scopeRel,
1209
+ c: truncated ? 0 : 1,
1210
+ ...truncated ? { r: truncated } : {},
1211
+ ...cancelled ? { k: "cancel" } : {}
1212
+ };
1213
+ let covered = readCovered(store);
1214
+ if (scopeRel === "") {
1215
+ covered = [mine];
1216
+ store.setMeta("skipped", JSON.stringify({ "": skipped }));
1217
+ } else {
1218
+ const without = covered.filter((e) => e.s !== scopeRel);
1219
+ covered = without.length < MAX_COVERED_ENTRIES ? [...without, mine] : without;
1220
+ let all = {};
1221
+ try {
1222
+ all = JSON.parse(store.meta("skipped") ?? "{}");
1223
+ } catch {
1224
+ all = {};
1225
+ }
1226
+ all[scopeRel] = skipped;
1227
+ store.setMeta("skipped", JSON.stringify(all));
1228
+ }
1229
+ store.setMeta("covered", JSON.stringify(covered));
1230
+ store.setMeta("refreshed_at", (/* @__PURE__ */ new Date()).toISOString());
1231
+ }
1232
+ __name(recordCoverage, "recordCoverage");
1233
+
1234
+ // ../analysis/dist/context.js
1235
+ async function refreshFile(env, rel) {
1236
+ await refreshIndex(env.store, env.root, join4(env.root, ...rel.split("/")), { ...env.options, force: false }, env.host, env.signal);
1237
+ }
1238
+ __name(refreshFile, "refreshFile");
1239
+ var DEFAULT_LIMIT = 50;
1240
+ var MAX_LIMIT = 200;
1241
+ var DEFAULT_MAX_CHARS = 2e4;
1242
+ var MIN_MAX_CHARS = 200;
1243
+ var MAX_MAX_CHARS = 2e5;
1244
+ var PREVIEW_CHARS = 200;
1245
+ function clampLimit(limit) {
1246
+ if (limit === void 0 || !Number.isFinite(limit))
1247
+ return DEFAULT_LIMIT;
1248
+ return Math.max(1, Math.min(MAX_LIMIT, Math.floor(limit)));
1249
+ }
1250
+ __name(clampLimit, "clampLimit");
1251
+ function clampChars(max) {
1252
+ if (max === void 0 || !Number.isFinite(max))
1253
+ return DEFAULT_MAX_CHARS;
1254
+ return Math.max(MIN_MAX_CHARS, Math.min(MAX_MAX_CHARS, Math.floor(max)));
1255
+ }
1256
+ __name(clampChars, "clampChars");
1257
+ function fingerprint(parts) {
1258
+ return createHash3("sha1").update(JSON.stringify(parts)).digest("hex").slice(0, 10);
1259
+ }
1260
+ __name(fingerprint, "fingerprint");
1261
+ function encodeCursor(body) {
1262
+ return Buffer.from(JSON.stringify(body)).toString("base64url");
1263
+ }
1264
+ __name(encodeCursor, "encodeCursor");
1265
+ function decodeCursor(cursor, generation, q) {
1266
+ if (cursor === void 0 || cursor === "")
1267
+ return { offset: 0 };
1268
+ let body;
1269
+ try {
1270
+ body = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
1271
+ if (!Number.isInteger(body.o) || body.o < 0 || !Number.isInteger(body.g) || typeof body.q !== "string") {
1272
+ throw new Error("shape");
1273
+ }
1274
+ } catch {
1275
+ return { error: "The cursor is not one this index issued. Repeat the query without it." };
1276
+ }
1277
+ if (body.q !== q) {
1278
+ return { error: "The cursor belongs to a different query. Repeat the query without it." };
1279
+ }
1280
+ if (body.g !== generation) {
1281
+ return {
1282
+ error: "The index changed since that page was produced, so its position no longer means anything. Repeat the query without a cursor."
1283
+ };
1284
+ }
1285
+ return { offset: body.o };
1286
+ }
1287
+ __name(decodeCursor, "decodeCursor");
1288
+ var StaleIndexError = class extends Error {
1289
+ static {
1290
+ __name(this, "StaleIndexError");
1291
+ }
1292
+ name = "StaleIndexError";
1293
+ };
1294
+ var Files = class {
1295
+ static {
1296
+ __name(this, "Files");
1297
+ }
1298
+ store;
1299
+ root;
1300
+ byId = /* @__PURE__ */ new Map();
1301
+ constructor(store, root) {
1302
+ this.store = store;
1303
+ this.root = root;
1304
+ }
1305
+ from(row) {
1306
+ const rel = String(row.path);
1307
+ return {
1308
+ id: Number(row.id),
1309
+ rel,
1310
+ abs: join4(this.root, ...rel.split("/")),
1311
+ chars: Number(row.chars),
1312
+ parseErrors: Number(row.parse_errors),
1313
+ size: Number(row.size),
1314
+ mtimeMs: Number(row.mtime_ms),
1315
+ hash: String(row.hash),
1316
+ starts: decodeLineStarts(row.line_starts)
1317
+ };
1318
+ }
1319
+ byIdOrThrow(id) {
1320
+ let info = this.byId.get(id);
1321
+ if (!info) {
1322
+ const row = this.store.get("SELECT * FROM files WHERE id = ?", id);
1323
+ if (!row)
1324
+ throw new StaleIndexError(`file ${id} is not in the index`);
1325
+ info = this.from(row);
1326
+ this.byId.set(id, info);
1327
+ }
1328
+ return info;
1329
+ }
1330
+ byPath(rel) {
1331
+ const row = this.store.get("SELECT * FROM files WHERE path = ?", rel);
1332
+ if (!row)
1333
+ return void 0;
1334
+ const info = this.from(row);
1335
+ this.byId.set(info.id, info);
1336
+ return info;
1337
+ }
1338
+ forget(id) {
1339
+ this.byId.delete(id);
1340
+ }
1341
+ };
1342
+ async function checkFreshness(store, files, root, candidates) {
1343
+ const marks = /* @__PURE__ */ new Map();
1344
+ const dropped = [];
1345
+ for (const id of new Set(candidates)) {
1346
+ const info = files.byIdOrThrow(id);
1347
+ const condition = await conditionOf(root, info.abs, info);
1348
+ if (condition === "changed" || condition === "deleted")
1349
+ marks.set(id, condition);
1350
+ else if (condition === "violation")
1351
+ dropped.push(info.rel);
1352
+ }
1353
+ if (dropped.length > 0)
1354
+ await dropFiles(store, files, dropped);
1355
+ return { marks, dropped };
1356
+ }
1357
+ __name(checkFreshness, "checkFreshness");
1358
+ async function dropFiles(store, files, rels) {
1359
+ await store.begin();
1360
+ try {
1361
+ for (const rel of rels) {
1362
+ const info = files.byPath(rel);
1363
+ if (info) {
1364
+ store.removeFile(info.id);
1365
+ files.forget(info.id);
1366
+ }
1367
+ noteNamed(store, "violations", rel);
1368
+ }
1369
+ store.bumpGeneration();
1370
+ store.commit();
1371
+ } catch (err) {
1372
+ store.rollback();
1373
+ throw err;
1374
+ }
1375
+ }
1376
+ __name(dropFiles, "dropFiles");
1377
+ function markReasons(marks) {
1378
+ const reasons = [];
1379
+ const changed = [...marks.values()].filter((m) => m === "changed").length;
1380
+ const deleted = marks.size - changed;
1381
+ if (changed > 0) {
1382
+ reasons.push(`${changed} file(s) changed on disk since they were indexed; positions from them may be off. Run the index operation to refresh`);
1383
+ }
1384
+ if (deleted > 0) {
1385
+ reasons.push(`${deleted} file(s) behind these results were deleted since they were indexed`);
1386
+ }
1387
+ return reasons;
1388
+ }
1389
+ __name(markReasons, "markReasons");
1390
+ async function readVerified(env, files, info, options) {
1391
+ const { store, root } = env;
1392
+ const read = await readRegular(root, info.abs);
1393
+ if (!read.ok) {
1394
+ if (read.why === "link" || read.why === "outside" || read.why === "not-file") {
1395
+ await dropFiles(store, files, [info.rel]);
1396
+ return {
1397
+ error: `${info.rel} is no longer a regular file inside the indexed root (it is a link or resolves elsewhere), so it was dropped from the index and nothing was read from it.`
1398
+ };
1399
+ }
1400
+ await refreshFile(env, info.rel);
1401
+ files.forget(info.id);
1402
+ return { error: `${info.rel} no longer exists, so nothing can be read from it.` };
1403
+ }
1404
+ if (hashOf(read.buffer) === info.hash) {
1405
+ const text2 = decodeText(read.buffer);
1406
+ if (text2 === void 0)
1407
+ return { error: `${info.rel} is no longer readable as text.` };
1408
+ return { info, text: text2, refreshed: false };
1409
+ }
1410
+ await refreshFile(env, info.rel);
1411
+ files.forget(info.id);
1412
+ if (!options.refresh) {
1413
+ return {
1414
+ error: `${info.rel} changed since it was indexed, and function ids are re-issued when a file is re-read. The index has been refreshed; look the function up again.`
1415
+ };
1416
+ }
1417
+ const next = files.byPath(info.rel);
1418
+ if (!next)
1419
+ return { error: `${info.rel} changed and can no longer be indexed.` };
1420
+ const again = await readRegular(root, next.abs);
1421
+ if (!again.ok)
1422
+ return { error: `${info.rel} changed while it was being read.` };
1423
+ const text = decodeText(again.buffer);
1424
+ if (text === void 0)
1425
+ return { error: `${info.rel} is not readable as text.` };
1426
+ return { info: next, text, refreshed: true };
1427
+ }
1428
+ __name(readVerified, "readVerified");
1429
+ function toFunction(row, info) {
1430
+ const start = Number(row.start);
1431
+ const at = position(info.starts, start);
1432
+ return {
1433
+ id: Number(row.id),
1434
+ name: row.name === null || row.name === void 0 ? null : String(row.name),
1435
+ kind: String(row.kind),
1436
+ path: info.abs,
1437
+ line: at.line,
1438
+ column: at.column,
1439
+ endLine: Number(row.eline),
1440
+ start,
1441
+ end: Number(row.end)
1442
+ };
1443
+ }
1444
+ __name(toFunction, "toFunction");
1445
+ function parentsOf(store, files, parentId) {
1446
+ const out = [];
1447
+ let next = parentId;
1448
+ while (next !== null && out.length < 64) {
1449
+ const row = store.get("SELECT * FROM functions WHERE id = ?", next);
1450
+ if (!row)
1451
+ break;
1452
+ out.push(toFunction(row, files.byIdOrThrow(Number(row.file_id))));
1453
+ next = row.parent_id === null ? null : Number(row.parent_id);
1454
+ }
1455
+ return out;
1456
+ }
1457
+ __name(parentsOf, "parentsOf");
1458
+ function sliceOf(text, start, end, maxChars) {
1459
+ const chars = end - start;
1460
+ if (chars <= maxChars)
1461
+ return { text: text.slice(start, end), chars, truncated: false };
1462
+ let stop = start + maxChars;
1463
+ const last = text.charCodeAt(stop - 1);
1464
+ if (last >= 55296 && last <= 56319)
1465
+ stop--;
1466
+ return { text: text.slice(start, stop), chars, truncated: true };
1467
+ }
1468
+ __name(sliceOf, "sliceOf");
1469
+ var BENIGN_SKIPS = /* @__PURE__ */ new Set(["declaration file", "symbolic link"]);
1470
+ function listOf(store, key) {
1471
+ try {
1472
+ const v = JSON.parse(store.meta(key) ?? "[]");
1473
+ return Array.isArray(v) ? v : [];
1474
+ } catch {
1475
+ return [];
1476
+ }
1477
+ }
1478
+ __name(listOf, "listOf");
1479
+ function named(list) {
1480
+ return list.length > 3 ? `${list.slice(0, 3).join(", ")} and ${list.length - 3} more` : list.join(", ");
1481
+ }
1482
+ __name(named, "named");
1483
+ function workspaceGaps(store, scopeRel = "") {
1484
+ const reasons = [];
1485
+ const covered = readCovered(store);
1486
+ const covering = coveringEntry(covered, scopeRel);
1487
+ if (scopeRel === "") {
1488
+ if (!covering) {
1489
+ const parts = covered.map((e) => e.s === "" ? "the root" : e.s);
1490
+ reasons.push(`only part of the root is indexed (${named(parts)}); call the index operation with a path to cover another part`);
1491
+ }
1492
+ }
1493
+ for (const e of covered) {
1494
+ if (e.c === 0 && (scopeRel === "" || e === covering)) {
1495
+ const where = e.s === "" ? "the root" : e.s;
1496
+ reasons.push(e.k === "cancel" ? `indexing ${where} ${e.r}, so what was indexed is partial. Call the index operation to continue` : `indexing ${where} ${e.r ?? "stopped at a limit"}, so what was indexed is partial. Call the index operation with a narrower path to cover more`);
1497
+ }
1498
+ }
1499
+ let skipped = {};
1500
+ try {
1501
+ skipped = JSON.parse(store.meta("skipped") ?? "{}");
1502
+ } catch {
1503
+ skipped = {};
1504
+ }
1505
+ const totals = /* @__PURE__ */ new Map();
1506
+ for (const [scope, reasonsFor] of Object.entries(skipped)) {
1507
+ if (scopeRel !== "" && scope !== "" && scope !== scopeRel && !scopeRel.startsWith(`${scope}/`))
1508
+ continue;
1509
+ for (const [why, n] of Object.entries(reasonsFor)) {
1510
+ if (!BENIGN_SKIPS.has(why))
1511
+ totals.set(why, (totals.get(why) ?? 0) + n);
1512
+ }
1513
+ }
1514
+ if (totals.size > 0) {
1515
+ reasons.push(`not indexed: ${[...totals].map(([why, n]) => `${n} ${why}`).join(", ")}`);
1516
+ }
1517
+ const crashed = listOf(store, "crashed");
1518
+ if (crashed.length > 0) {
1519
+ reasons.push(`the parser crashed on ${crashed.length} file(s) (${named(crashed)}), which are recorded with no rows`);
1520
+ }
1521
+ const violations = listOf(store, "violations");
1522
+ if (violations.length > 0) {
1523
+ reasons.push(`${violations.length} file(s) (${named(violations)}) became a link or resolved outside the root after they were indexed, and were dropped without being read`);
1524
+ }
1525
+ const bad = store.get("SELECT count(*) AS n FROM files WHERE parse_errors > 0");
1526
+ if (bad && Number(bad.n) > 0) {
1527
+ reasons.push(`${bad.n} file(s) had syntax errors; the parser kept whatever tree it could recover, often none, so rows from them may be missing`);
1528
+ }
1529
+ return reasons;
1530
+ }
1531
+ __name(workspaceGaps, "workspaceGaps");
1532
+ var NEW_FILE_CHECK_DIRS = 400;
1533
+ async function newFileReasons(store, root, scopeRel) {
1534
+ const rows = scopeRel === "" ? store.all("SELECT path, mtime_ms FROM dirs ORDER BY path LIMIT ?", NEW_FILE_CHECK_DIRS + 1) : store.all("SELECT path, mtime_ms FROM dirs WHERE path = ? OR (path >= ? AND path < ?) ORDER BY path LIMIT ?", scopeRel, `${scopeRel}/`, `${scopeRel}0`, NEW_FILE_CHECK_DIRS + 1);
1535
+ const changed = [];
1536
+ for (const row of rows.slice(0, NEW_FILE_CHECK_DIRS)) {
1537
+ const rel = String(row.path);
1538
+ try {
1539
+ const s = await lstat3(join4(root, ...rel.split("/").filter(Boolean)));
1540
+ if (s.mtimeMs !== Number(row.mtime_ms))
1541
+ changed.push(rel === "" ? "." : rel);
1542
+ } catch {
1543
+ changed.push(rel === "" ? "." : rel);
1544
+ }
1545
+ }
1546
+ const reasons = [];
1547
+ if (changed.length > 0) {
1548
+ reasons.push(`${changed.length} director${changed.length === 1 ? "y" : "ies"} changed since the index was built (${named(changed)}), so files added there may be missing. Run the index operation to pick them up`);
1549
+ }
1550
+ if (rows.length > NEW_FILE_CHECK_DIRS) {
1551
+ reasons.push(`only the first ${NEW_FILE_CHECK_DIRS} directories were checked for new files`);
1552
+ }
1553
+ return reasons;
1554
+ }
1555
+ __name(newFileReasons, "newFileReasons");
1556
+ function coverageOf(reasons) {
1557
+ return reasons.length === 0 ? { status: "complete" } : { status: "partial", reasons };
1558
+ }
1559
+ __name(coverageOf, "coverageOf");
1560
+
1561
+ // ../analysis/dist/provider.js
1562
+ var failed = /* @__PURE__ */ __name((error) => ({ kind: "failed", error }), "failed");
1563
+ function explain(err) {
1564
+ if (err instanceof ParserUnavailableError)
1565
+ return { kind: "unsupported", reason: err.message };
1566
+ if (err instanceof Error && err.name === "AbortError") {
1567
+ return failed("The call was cancelled. Anything already indexed is kept, so the next call continues from there.");
1568
+ }
1569
+ return failed(err instanceof Error ? err.message : String(err));
1570
+ }
1571
+ __name(explain, "explain");
1572
+ function createCodeAnalysisProvider(options = {}) {
1573
+ const opened = /* @__PURE__ */ new Map();
1574
+ const host = new ParserHost(options.hostScript, options.parserModule);
1575
+ const lifetime = new AbortController();
1576
+ const withLifetime = /* @__PURE__ */ __name((signal) => signal ? AbortSignal.any([lifetime.signal, signal]) : lifetime.signal, "withLifetime");
1577
+ const indexOptions = /* @__PURE__ */ __name((force) => ({
1578
+ ignoreDirs: options.ignoreDirs ?? DEFAULT_IGNORED_DIRS,
1579
+ maxFileBytes: options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES,
1580
+ maxFiles: options.maxFiles ?? DEFAULT_MAX_FILES,
1581
+ maxDirectories: options.maxDirectories ?? DEFAULT_MAX_DIRECTORIES,
1582
+ maxMillis: options.maxMillis ?? DEFAULT_MAX_MILLIS,
1583
+ force
1584
+ }), "indexOptions");
1585
+ const envOf = /* @__PURE__ */ __name((o, signal, force = false) => ({
1586
+ store: o.store,
1587
+ root: o.root,
1588
+ host,
1589
+ options: indexOptions(force),
1590
+ signal
1591
+ }), "envOf");
1592
+ async function open2(rootInput) {
1593
+ let root;
1594
+ try {
1595
+ root = await realpath3(rootInput);
1596
+ if (!(await stat3(root)).isDirectory())
1597
+ return { error: `${rootInput} is not a directory.` };
1598
+ } catch {
1599
+ return { error: `${rootInput} does not exist.` };
1600
+ }
1601
+ let pending = opened.get(root);
1602
+ if (!pending) {
1603
+ pending = (async () => {
1604
+ const store = await Store.open(root, options.cacheDir, options.substringIndex !== "off", {
1605
+ maxAgeDays: options.cacheMaxAgeDays ?? DEFAULT_CACHE_MAX_AGE_DAYS,
1606
+ maxBytes: options.cacheMaxBytes ?? DEFAULT_CACHE_MAX_BYTES
1607
+ });
1608
+ if (!store) {
1609
+ return {
1610
+ error: "node:sqlite is not available in this Node.js, so there is nowhere to keep an index. It needs Node 22.5 or newer."
1611
+ };
1612
+ }
1613
+ return { store, root };
1614
+ })();
1615
+ opened.set(root, pending);
1616
+ void pending.then((r) => {
1617
+ if ("error" in r)
1618
+ opened.delete(root);
1619
+ }, () => opened.delete(root));
1620
+ }
1621
+ return await pending;
1622
+ }
1623
+ __name(open2, "open");
1624
+ async function queued(o, signal, work) {
1625
+ const guarded = o.store.run(async () => {
1626
+ if (signal?.aborted)
1627
+ throw abortError();
1628
+ return await work();
1629
+ });
1630
+ if (!signal)
1631
+ return await guarded.catch(explain);
1632
+ let onAbort;
1633
+ const cancelled = new Promise((resolve2) => {
1634
+ onAbort = /* @__PURE__ */ __name(() => resolve2(explain(abortError())), "onAbort");
1635
+ if (signal.aborted)
1636
+ onAbort();
1637
+ else
1638
+ signal.addEventListener("abort", onAbort, { once: true });
1639
+ });
1640
+ try {
1641
+ return await Promise.race([guarded.catch(explain), cancelled]);
1642
+ } finally {
1643
+ if (onAbort)
1644
+ signal.removeEventListener("abort", onAbort);
1645
+ }
1646
+ }
1647
+ __name(queued, "queued");
1648
+ async function ensureCovered(env, scopeAbs) {
1649
+ const rel = toRel(env.root, scopeAbs);
1650
+ if (rel === void 0)
1651
+ return void 0;
1652
+ if (coveringEntry(readCovered(env.store), rel))
1653
+ return void 0;
1654
+ if (rel !== "" && !await lstat4(scopeAbs).then(() => true, () => false))
1655
+ return void 0;
1656
+ const started = performance.now();
1657
+ const out = await refreshIndex(env.store, env.root, scopeAbs, env.options, env.host, env.signal);
1658
+ return `${rel === "" ? `the index for ${env.root}` : `${rel}`} was not indexed and was built for this call: ${out.indexed} files in ${Math.round(performance.now() - started)} ms${out.truncated ? ` (${out.truncated})` : ""}`;
1659
+ }
1660
+ __name(ensureCovered, "ensureCovered");
1661
+ const evidence = /* @__PURE__ */ __name((observed, inferred, gaps, built) => ({
1662
+ observed: built ? [...observed, built] : observed,
1663
+ inferred,
1664
+ coverage: coverageOf(gaps)
1665
+ }), "evidence");
1666
+ function fileAt(o, files, abs) {
1667
+ const rel = toRel(o.root, abs);
1668
+ if (rel === void 0 || rel === "") {
1669
+ return { error: `${abs} is not a file under the indexed root ${o.root}.` };
1670
+ }
1671
+ const info = files.byPath(rel);
1672
+ if (info)
1673
+ return info;
1674
+ return {
1675
+ error: `${rel} is not in the index. Only .js .mjs .cjs .jsx .ts .mts .cts .tsx files are indexed, and not declaration files, symbolic links, files in ignored directories (${(options.ignoreDirs ?? DEFAULT_IGNORED_DIRS).join(", ")}), or files that are binary, too large or unparseable.`
1676
+ };
1677
+ }
1678
+ __name(fileAt, "fileAt");
1679
+ function scopeSql(o, files, path, column) {
1680
+ if (path === void 0)
1681
+ return { sql: "", params: [], rel: "" };
1682
+ const rel = toRel(o.root, path);
1683
+ if (rel === void 0)
1684
+ return { error: `${path} is outside the indexed root ${o.root}.` };
1685
+ if (rel === "")
1686
+ return { sql: "", params: [], rel };
1687
+ const file = files.byPath(rel);
1688
+ if (file)
1689
+ return { sql: ` AND ${column} = ?`, params: [file.id], rel };
1690
+ return {
1691
+ sql: ` AND ${column} IN (SELECT id FROM files WHERE path >= ? AND path < ?)`,
1692
+ params: [`${rel}/`, `${rel}0`],
1693
+ rel
1694
+ };
1695
+ }
1696
+ __name(scopeSql, "scopeSql");
1697
+ async function withScope(rootInput, scopeAbs, signal, body) {
1698
+ const o = await open2(rootInput);
1699
+ if ("error" in o)
1700
+ return { kind: "unsupported", reason: o.error };
1701
+ const lifetimeSignal = withLifetime(signal);
1702
+ return await queued(o, lifetimeSignal, async () => {
1703
+ const env = envOf(o, lifetimeSignal);
1704
+ const built = await ensureCovered(env, scopeAbs ?? o.root);
1705
+ for (let attempt = 0; ; attempt++) {
1706
+ try {
1707
+ return await body(o, env, built);
1708
+ } catch (err) {
1709
+ if (!(err instanceof StaleIndexError) || attempt >= 4)
1710
+ throw err;
1711
+ }
1712
+ }
1713
+ });
1714
+ }
1715
+ __name(withScope, "withScope");
1716
+ const provider = {
1717
+ async index(request) {
1718
+ const o = await open2(request.root);
1719
+ if ("error" in o)
1720
+ return { kind: "unsupported", reason: o.error };
1721
+ const signal = withLifetime(request.signal);
1722
+ return await queued(o, signal, async () => {
1723
+ const started = performance.now();
1724
+ const scopeAbs = request.scope ?? o.root;
1725
+ const scopeRel = toRel(o.root, scopeAbs);
1726
+ if (scopeRel === void 0)
1727
+ return failed(`${scopeAbs} is outside the indexed root ${o.root}.`);
1728
+ const out = await refreshIndex(o.store, o.root, scopeAbs, indexOptions(request.force === true), host, signal);
1729
+ const count = /* @__PURE__ */ __name((table) => Number(o.store.get(`SELECT count(*) AS n FROM ${table}`).n), "count");
1730
+ const summary = {
1731
+ root: o.root,
1732
+ persisted: o.store.persisted,
1733
+ files: {
1734
+ indexed: out.indexed,
1735
+ parsed: out.parsed,
1736
+ unchanged: out.unchanged,
1737
+ removed: out.removed,
1738
+ skipped: out.skipped,
1739
+ withParseErrors: out.withParseErrors
1740
+ },
1741
+ skippedReasons: out.skippedReasons,
1742
+ functions: count("functions"),
1743
+ strings: count("strings"),
1744
+ calls: count("calls"),
1745
+ durationMs: Math.round(performance.now() - started),
1746
+ ...out.truncated ? {
1747
+ truncated: `Indexing ${scopeRel === "" ? "the root" : scopeRel} ${out.truncated}, so the index is partial. Index a narrower path to cover the rest; what was indexed is kept and answers queries now.`
1748
+ } : {}
1749
+ };
1750
+ return {
1751
+ kind: "ok",
1752
+ value: summary,
1753
+ evidence: evidence([
1754
+ `walked ${scopeRel === "" ? o.root : scopeRel}: ${out.parsed} file(s) parsed, ${out.unchanged} unchanged by size, mtime or content hash, ${out.removed} removed`
1755
+ ], o.store.fts ? [] : [
1756
+ "this Node.js has no FTS5, so find_literal scans every literal instead of using a substring index; answers are the same, slower"
1757
+ ], workspaceGaps(o.store, scopeRel))
1758
+ };
1759
+ });
1760
+ },
1761
+ findLiteral: /* @__PURE__ */ __name((request) => withScope(request.root, request.path, request.signal, async (o, _env, built) => {
1762
+ const files = new Files(o.store, o.root);
1763
+ const scope = scopeSql(o, files, request.path, "s.file_id");
1764
+ if ("error" in scope)
1765
+ return failed(scope.error);
1766
+ const limit = clampLimit(request.limit);
1767
+ const insensitive = request.caseSensitive === false;
1768
+ const codePoints = Array.from(request.text).length;
1769
+ const useFts = o.store.fts && codePoints >= 3;
1770
+ const test = insensitive ? "instr(lower(s.value), lower(?)) > 0" : "instr(s.value, ?) > 0";
1771
+ const prefilter = useFts ? " AND s.id IN (SELECT rowid FROM lit WHERE lit MATCH ?)" : "";
1772
+ const where = `WHERE ${test}${prefilter}${scope.sql}`;
1773
+ const params = [
1774
+ request.text,
1775
+ ...useFts ? [`"${request.text.replaceAll('"', '""')}"`] : [],
1776
+ ...scope.params
1777
+ ];
1778
+ let offset = 0;
1779
+ let rows = [];
1780
+ let total = 0;
1781
+ let generation = 0;
1782
+ let q = "";
1783
+ let fresh = await checkFreshness(o.store, files, o.root, []);
1784
+ for (let attempt = 0; attempt < 3; attempt++) {
1785
+ generation = Number(o.store.meta("generation") ?? "0");
1786
+ q = fingerprint(["find", o.root, request.text, request.path ?? null, insensitive]);
1787
+ const cursor = decodeCursor(request.cursor, generation, q);
1788
+ if ("error" in cursor)
1789
+ return failed(cursor.error);
1790
+ offset = cursor.offset;
1791
+ total = Number(o.store.get(`SELECT count(*) AS n FROM strings s ${where}`, ...params).n);
1792
+ rows = o.store.all(`SELECT s.id, s.file_id, s.fn_id, s.start, s."end", s.kind, s.value FROM strings s ${where} ORDER BY s.id LIMIT ? OFFSET ?`, ...params, limit, offset);
1793
+ fresh = await checkFreshness(o.store, files, o.root, rows.map((r) => Number(r.file_id)));
1794
+ if (fresh.dropped.length === 0)
1795
+ break;
1796
+ }
1797
+ const fnCache = /* @__PURE__ */ new Map();
1798
+ const items = rows.map((r) => {
1799
+ const fileId = Number(r.file_id);
1800
+ const info = files.byIdOrThrow(fileId);
1801
+ const at = position(info.starts, Number(r.start));
1802
+ const value = String(r.value);
1803
+ let fn;
1804
+ if (r.fn_id !== null && r.fn_id !== void 0) {
1805
+ const id = Number(r.fn_id);
1806
+ fn = fnCache.get(id);
1807
+ if (!fn) {
1808
+ const fr = o.store.get("SELECT * FROM functions WHERE id = ?", id);
1809
+ if (fr) {
1810
+ fn = toFunction(fr, info);
1811
+ fnCache.set(id, fn);
1812
+ }
1813
+ }
1814
+ }
1815
+ const mark = fresh.marks.get(fileId);
1816
+ return {
1817
+ path: info.abs,
1818
+ line: at.line,
1819
+ column: at.column,
1820
+ start: Number(r.start),
1821
+ end: Number(r.end),
1822
+ kind: String(r.kind),
1823
+ value: value.length > PREVIEW_CHARS ? value.slice(0, PREVIEW_CHARS) : value,
1824
+ valueTruncated: value.length > PREVIEW_CHARS,
1825
+ ...fn ? { function: fn } : {},
1826
+ ...mark ? { stale: mark } : {}
1827
+ };
1828
+ });
1829
+ const next = offset + items.length;
1830
+ const page = {
1831
+ items,
1832
+ total,
1833
+ ...next < total ? { nextCursor: encodeCursor({ g: generation, o: next, q }) } : {}
1834
+ };
1835
+ return {
1836
+ kind: "ok",
1837
+ value: page,
1838
+ evidence: evidence([
1839
+ `${total} string or template literal(s) contain ${JSON.stringify(request.text)}${insensitive ? " (ASCII case-insensitive)" : ""}`,
1840
+ "each hit lists the innermost function whose source range contains it"
1841
+ ], [
1842
+ "literals are indexed up to 4096 characters, and a template literal is indexed per static chunk, so a match cannot span a ${...} or sit past the cut"
1843
+ ], [
1844
+ ...workspaceGaps(o.store, scope.rel),
1845
+ ...markReasons(fresh.marks),
1846
+ ...await newFileReasons(o.store, o.root, scope.rel)
1847
+ ], built)
1848
+ };
1849
+ }), "findLiteral"),
1850
+ enclosingFunction: /* @__PURE__ */ __name((request) => withScope(request.root, request.path, request.signal, async (o, env, built) => {
1851
+ const files = new Files(o.store, o.root);
1852
+ const found = fileAt(o, files, request.path);
1853
+ if ("error" in found)
1854
+ return failed(found.error);
1855
+ const verified = await readVerified(env, files, found, { refresh: true });
1856
+ if ("error" in verified)
1857
+ return failed(verified.error);
1858
+ const { info, text } = verified;
1859
+ const at = offsetOf(info.starts, info.chars, request.line, request.column ?? 1);
1860
+ if ("error" in at)
1861
+ return failed(`${info.rel}: ${at.error}`);
1862
+ const row = o.store.get('SELECT * FROM functions WHERE file_id = ? AND start <= ? AND "end" > ? ORDER BY start DESC, "end" ASC, id DESC LIMIT 1', info.id, at.offset, at.offset);
1863
+ const gaps = fileGaps(info);
1864
+ const notes = [
1865
+ ...verified.refreshed ? [`${info.rel} had changed since it was indexed and was re-read`] : [],
1866
+ ...built ? [built] : []
1867
+ ];
1868
+ if (!row) {
1869
+ return {
1870
+ kind: "ok",
1871
+ value: { function: null, parents: [] },
1872
+ evidence: {
1873
+ observed: [
1874
+ `${info.rel}:${request.line}:${request.column ?? 1} lies in no function body; it is at the top level of the file`,
1875
+ ...notes
1876
+ ],
1877
+ inferred: [],
1878
+ coverage: coverageOf(gaps)
1879
+ }
1880
+ };
1881
+ }
1882
+ const fn = toFunction(row, info);
1883
+ const parents = parentsOf(o.store, files, row.parent_id === null ? null : Number(row.parent_id));
1884
+ return {
1885
+ kind: "ok",
1886
+ value: {
1887
+ function: fn,
1888
+ parents,
1889
+ source: sliceOf(text, fn.start, fn.end, clampChars(request.maxChars))
1890
+ },
1891
+ evidence: {
1892
+ observed: [
1893
+ `offset ${at.offset} lies in [${fn.start}, ${fn.end}) of ${info.rel}, the innermost function range that contains it`,
1894
+ "the source is the exact slice of the file, verified against its content hash",
1895
+ ...notes
1896
+ ],
1897
+ inferred: fn.name === null ? [
1898
+ "the function has no name of its own and none could be inferred from its context"
1899
+ ] : [],
1900
+ coverage: coverageOf(gaps)
1901
+ }
1902
+ };
1903
+ }), "enclosingFunction"),
1904
+ functionSource: /* @__PURE__ */ __name((request) => withScope(
1905
+ request.root,
1906
+ // An id names a function the index already holds; only a path asks for a build.
1907
+ request.id === void 0 ? request.path : void 0,
1908
+ request.signal,
1909
+ async (o, env, built) => {
1910
+ const files = new Files(o.store, o.root);
1911
+ const maxChars = clampChars(request.maxChars);
1912
+ const limit = clampLimit(request.limit);
1913
+ const generation = Number(o.store.meta("generation") ?? "0");
1914
+ const q = fingerprint([
1915
+ "source",
1916
+ o.root,
1917
+ request.id ?? null,
1918
+ request.path ?? null,
1919
+ request.name ?? null,
1920
+ maxChars
1921
+ ]);
1922
+ const cursor = decodeCursor(request.cursor, generation, q);
1923
+ if ("error" in cursor)
1924
+ return failed(cursor.error);
1925
+ let rows;
1926
+ let total;
1927
+ let info;
1928
+ if (request.id !== void 0) {
1929
+ const row = o.store.get("SELECT * FROM functions WHERE id = ?", request.id);
1930
+ if (!row) {
1931
+ return failed(`There is no function with id ${request.id}. Ids are re-issued when a file is re-read; look the function up again.`);
1932
+ }
1933
+ info = files.byIdOrThrow(Number(row.file_id));
1934
+ rows = [row];
1935
+ total = 1;
1936
+ } else if (request.path !== void 0 && request.name !== void 0) {
1937
+ const found = fileAt(o, files, request.path);
1938
+ if ("error" in found)
1939
+ return failed(found.error);
1940
+ const fresh = await readVerified(env, files, found, { refresh: true });
1941
+ if ("error" in fresh)
1942
+ return failed(fresh.error);
1943
+ info = fresh.info;
1944
+ total = Number(o.store.get("SELECT count(*) AS n FROM functions WHERE file_id = ? AND name = ?", info.id, request.name).n);
1945
+ rows = o.store.all("SELECT * FROM functions WHERE file_id = ? AND name = ? ORDER BY start LIMIT ? OFFSET ?", info.id, request.name, limit, cursor.offset);
1946
+ } else {
1947
+ return failed("functionSource needs `id`, or `path` together with `name`.");
1948
+ }
1949
+ const verified = await readVerified(env, files, info, {
1950
+ refresh: request.id === void 0
1951
+ });
1952
+ if ("error" in verified)
1953
+ return failed(verified.error);
1954
+ const items = rows.map((row) => {
1955
+ const fn = toFunction(row, verified.info);
1956
+ return {
1957
+ function: fn,
1958
+ parents: parentsOf(o.store, files, row.parent_id === null ? null : Number(row.parent_id)),
1959
+ source: sliceOf(verified.text, fn.start, fn.end, maxChars)
1960
+ };
1961
+ });
1962
+ const next = cursor.offset + items.length;
1963
+ return {
1964
+ kind: "ok",
1965
+ value: {
1966
+ items,
1967
+ total,
1968
+ ...next < total ? { nextCursor: encodeCursor({ g: generation, o: next, q }) } : {}
1969
+ },
1970
+ evidence: evidence([
1971
+ `${total} function(s) ${request.id !== void 0 ? `with id ${request.id}` : `named ${JSON.stringify(request.name)} in ${info.rel}`}`,
1972
+ "the source is the exact slice of the file, verified against its content hash"
1973
+ ], request.id === void 0 ? [
1974
+ "a function is matched by the name the index inferred for it, which for an unnamed function is the variable or property it was assigned to"
1975
+ ] : [], fileGaps(info), built)
1976
+ };
1977
+ }
1978
+ ), "functionSource"),
1979
+ callersOf: /* @__PURE__ */ __name((request) => {
1980
+ const scope = request.scope ?? "file";
1981
+ return withScope(request.root, request.path, request.signal, async (o, env, built) => {
1982
+ const files = new Files(o.store, o.root);
1983
+ const member = request.match === "member";
1984
+ let scoped;
1985
+ let scopeRel = "";
1986
+ const gaps = [];
1987
+ const notes = [];
1988
+ if (scope === "file") {
1989
+ if (request.path === void 0) {
1990
+ return failed('callersOf with the default file scope needs `path`. Ask for scope "workspace" to search the whole index.');
1991
+ }
1992
+ const found = fileAt(o, files, request.path);
1993
+ if ("error" in found)
1994
+ return failed(found.error);
1995
+ const fresh = await readVerified(env, files, found, { refresh: true });
1996
+ if ("error" in fresh)
1997
+ return failed(fresh.error);
1998
+ if (fresh.refreshed)
1999
+ notes.push(`${fresh.info.rel} had changed since it was indexed and was re-read`);
2000
+ gaps.push(...fileGaps(fresh.info));
2001
+ scoped = { sql: " AND c.file_id = ?", params: [fresh.info.id] };
2002
+ } else {
2003
+ const s = scopeSql(o, files, request.path, "c.file_id");
2004
+ if ("error" in s)
2005
+ return failed(s.error);
2006
+ scoped = s;
2007
+ scopeRel = s.rel;
2008
+ }
2009
+ const limit = clampLimit(request.limit);
2010
+ const test = member ? "(c.callee = ? OR (length(c.callee) > length(?) AND substr(c.callee, -(length(?) + 1)) = '.' || ?))" : "c.callee = ?";
2011
+ const testParams = member ? [request.name, request.name, request.name, request.name] : [request.name];
2012
+ const where = `WHERE ${test}${scoped.sql}`;
2013
+ const params = [...testParams, ...scoped.params];
2014
+ let offset = 0;
2015
+ let rows = [];
2016
+ let total = 0;
2017
+ let generation = 0;
2018
+ let q = "";
2019
+ let freshness = await checkFreshness(o.store, files, o.root, []);
2020
+ for (let attempt = 0; attempt < 3; attempt++) {
2021
+ generation = Number(o.store.meta("generation") ?? "0");
2022
+ q = fingerprint(["callers", o.root, request.name, scope, request.path ?? null, member]);
2023
+ const cursor = decodeCursor(request.cursor, generation, q);
2024
+ if ("error" in cursor)
2025
+ return failed(cursor.error);
2026
+ offset = cursor.offset;
2027
+ total = Number(o.store.get(`SELECT count(*) AS n FROM calls c ${where}`, ...params).n);
2028
+ rows = o.store.all(`SELECT c.rowid AS rid, c.file_id, c.fn_id, c.start, c.callee, c.kind, c.nargs FROM calls c ${where} ORDER BY c.rowid LIMIT ? OFFSET ?`, ...params, limit, offset);
2029
+ freshness = await checkFreshness(o.store, files, o.root, rows.map((r) => Number(r.file_id)));
2030
+ if (freshness.dropped.length === 0)
2031
+ break;
2032
+ }
2033
+ const fnCache = /* @__PURE__ */ new Map();
2034
+ const items = rows.map((r) => {
2035
+ const fileId = Number(r.file_id);
2036
+ const info = files.byIdOrThrow(fileId);
2037
+ const at = position(info.starts, Number(r.start));
2038
+ let caller;
2039
+ if (r.fn_id !== null && r.fn_id !== void 0) {
2040
+ const id = Number(r.fn_id);
2041
+ caller = fnCache.get(id);
2042
+ if (!caller) {
2043
+ const fr = o.store.get("SELECT * FROM functions WHERE id = ?", id);
2044
+ if (fr) {
2045
+ caller = toFunction(fr, info);
2046
+ fnCache.set(id, caller);
2047
+ }
2048
+ }
2049
+ }
2050
+ const mark = freshness.marks.get(fileId);
2051
+ return {
2052
+ path: info.abs,
2053
+ line: at.line,
2054
+ column: at.column,
2055
+ callee: String(r.callee),
2056
+ kind: String(r.kind),
2057
+ argumentCount: Number(r.nargs),
2058
+ ...caller ? { caller } : {},
2059
+ ...mark ? { stale: mark } : {}
2060
+ };
2061
+ });
2062
+ if (scope === "workspace") {
2063
+ gaps.push(...workspaceGaps(o.store, scopeRel), ...markReasons(freshness.marks), ...await newFileReasons(o.store, o.root, scopeRel));
2064
+ } else {
2065
+ gaps.push(...markReasons(freshness.marks));
2066
+ }
2067
+ const distinct = Number(o.store.get(`SELECT count(DISTINCT c.file_id) AS n FROM calls c ${where}`, ...params).n);
2068
+ const next = offset + items.length;
2069
+ return {
2070
+ kind: "ok",
2071
+ value: {
2072
+ items,
2073
+ total,
2074
+ ...next < total ? { nextCursor: encodeCursor({ g: generation, o: next, q }) } : {}
2075
+ },
2076
+ evidence: evidence([
2077
+ `${total} call expression(s) whose callee text is ${member ? `${JSON.stringify(request.name)} or ends in .${request.name}` : JSON.stringify(request.name)}, in ${distinct} file(s)`,
2078
+ ...notes
2079
+ ], [
2080
+ "callers are matched by the callee TEXT, not by scope or binding: two unrelated functions called by the same name are the same callee here",
2081
+ "a call through an alias, a destructured binding, .call/.apply or computed access (obj[name]()) is not matched",
2082
+ ...scope === "workspace" && distinct > 1 ? [
2083
+ `the matches span ${distinct} files and may be different functions that share a name`
2084
+ ] : []
2085
+ ], gaps, built)
2086
+ };
2087
+ });
2088
+ }, "callersOf"),
2089
+ imports: /* @__PURE__ */ __name((request) => withScope(request.root, request.path, request.signal, async (o, env, built) => {
2090
+ const files = new Files(o.store, o.root);
2091
+ const found = fileAt(o, files, request.path);
2092
+ if ("error" in found)
2093
+ return failed(found.error);
2094
+ const fresh = await readVerified(env, files, found, { refresh: true });
2095
+ if ("error" in fresh)
2096
+ return failed(fresh.error);
2097
+ const info = fresh.info;
2098
+ const limit = clampLimit(request.limit);
2099
+ const generation = Number(o.store.meta("generation") ?? "0");
2100
+ const q = fingerprint(["imports", o.root, request.path]);
2101
+ const cursor = decodeCursor(request.cursor, generation, q);
2102
+ if ("error" in cursor)
2103
+ return failed(cursor.error);
2104
+ const edges = [
2105
+ ...o.store.all("SELECT * FROM imports WHERE file_id = ? ORDER BY start", info.id).map((r) => {
2106
+ const at = position(info.starts, Number(r.start));
2107
+ return {
2108
+ direction: "import",
2109
+ kind: String(r.kind),
2110
+ source: String(r.source),
2111
+ names: String(r.names) === "" ? [] : String(r.names).split(","),
2112
+ line: at.line,
2113
+ column: at.column
2114
+ };
2115
+ }),
2116
+ ...o.store.all("SELECT * FROM exports WHERE file_id = ? ORDER BY start", info.id).map((r) => {
2117
+ const at = position(info.starts, Number(r.start));
2118
+ return {
2119
+ direction: "export",
2120
+ kind: String(r.kind),
2121
+ name: String(r.name),
2122
+ ...r.source !== null && r.source !== void 0 ? { source: String(r.source) } : {},
2123
+ line: at.line,
2124
+ column: at.column
2125
+ };
2126
+ })
2127
+ ];
2128
+ const items = edges.slice(cursor.offset, cursor.offset + limit);
2129
+ const next = cursor.offset + items.length;
2130
+ const imports = edges.filter((e) => e.direction === "import").length;
2131
+ return {
2132
+ kind: "ok",
2133
+ value: {
2134
+ items,
2135
+ total: edges.length,
2136
+ ...next < edges.length ? { nextCursor: encodeCursor({ g: generation, o: next, q }) } : {}
2137
+ },
2138
+ evidence: evidence([
2139
+ `${imports} import(s) and ${edges.length - imports} export(s) in ${info.rel}`,
2140
+ ...fresh.refreshed ? [`${info.rel} had changed since it was indexed and was re-read`] : []
2141
+ ], ["require() and import() are recorded only when their argument is a string literal"], fileGaps(info), built)
2142
+ };
2143
+ }), "imports"),
2144
+ async dispose() {
2145
+ const all = [...opened.values()];
2146
+ opened.clear();
2147
+ lifetime.abort();
2148
+ host.dispose();
2149
+ for (const pending of all) {
2150
+ const o = await pending.catch(() => void 0);
2151
+ if (!o || "error" in o)
2152
+ continue;
2153
+ await o.store.run(async () => o.store.close()).catch(() => void 0);
2154
+ }
2155
+ }
2156
+ };
2157
+ return provider;
2158
+ }
2159
+ __name(createCodeAnalysisProvider, "createCodeAnalysisProvider");
2160
+ function fileGaps(info) {
2161
+ if (info.parseErrors < 0) {
2162
+ return [
2163
+ `${info.rel} crashed the parser and is recorded with no rows, so nothing can be answered from it`
2164
+ ];
2165
+ }
2166
+ if (info.parseErrors > 0) {
2167
+ return [
2168
+ `${info.rel} had syntax errors; the parser kept whatever tree it could recover, which is often none, so rows from it may be missing`
2169
+ ];
2170
+ }
2171
+ return [];
2172
+ }
2173
+ __name(fileGaps, "fileGaps");
2174
+ export {
2175
+ DEFAULT_IGNORED_DIRS,
2176
+ DEFAULT_MAX_DIRECTORIES,
2177
+ DEFAULT_MAX_FILES,
2178
+ DEFAULT_MAX_FILE_BYTES,
2179
+ DEFAULT_MAX_MILLIS,
2180
+ createCodeAnalysisProvider
2181
+ };
2182
+ //# sourceMappingURL=dist-KGLSBIES.js.map