0sec-cli 0.24.1 → 0.26.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 (246) hide show
  1. package/0.js +67 -62
  2. package/README.md +121 -82
  3. package/chunks/{adapt-loop-L77BWMNE.js → adapt-loop-P4HKONB5.js} +6 -5
  4. package/chunks/{artifact-scraper-BV67RAP5.js → artifact-scraper-IIRJNYKT.js} +4 -3
  5. package/chunks/{assumption-mining-RPVR77A3.js → assumption-mining-YA6VJ2V6.js} +22 -20
  6. package/chunks/{backend-connections-ACIXNYZN.js → backend-connections-64PKYKL7.js} +5 -4
  7. package/chunks/chunk-36J5ZLFE.js +18729 -0
  8. package/chunks/{chunk-ZM6ANQZJ.js → chunk-3MWQNNJU.js} +16180 -34467
  9. package/chunks/{chunk-GV5WXDHY.js → chunk-3VQ5EZKG.js} +11 -9
  10. package/chunks/chunk-5XOYTAOK.js +1546 -0
  11. package/chunks/{chunk-UJE4WOQS.js → chunk-6GV5G6U3.js} +1 -1
  12. package/chunks/{chunk-X2ZMSRTP.js → chunk-6SNOKNCS.js} +333 -3
  13. package/chunks/{chunk-BMDG6T7D.js → chunk-72PU46MS.js} +178 -133
  14. package/chunks/{chunk-KCA35IL3.js → chunk-7PUJI64A.js} +11 -9
  15. package/chunks/chunk-A7G6S5RA.js +90 -0
  16. package/chunks/chunk-ABKUI3QB.js +196 -0
  17. package/chunks/{chunk-5ETI27Q3.js → chunk-AFJ2UMPR.js} +3 -3
  18. package/chunks/{chunk-XA2IBHPB.js → chunk-B7XL6RON.js} +1 -1
  19. package/chunks/{chunk-TVS6WVSK.js → chunk-BM6EYP2D.js} +3 -3
  20. package/chunks/{chunk-7UHAXEOV.js → chunk-D4M5WURF.js} +226 -4
  21. package/chunks/{chunk-K74DRDC5.js → chunk-EHNVP6QB.js} +1 -1
  22. package/chunks/{chunk-I43YYHDU.js → chunk-FBZBJYZS.js} +5 -50
  23. package/chunks/{chunk-GXXX7AGH.js → chunk-GYEYTNHK.js} +144 -14
  24. package/chunks/{chunk-IJ6UPW3H.js → chunk-HS2NQ7K6.js} +393 -58
  25. package/chunks/chunk-HUZ2EC2R.js +196 -0
  26. package/chunks/{chunk-SU4IHQQI.js → chunk-IUUNIJPM.js} +1 -1
  27. package/chunks/chunk-JGDA6EIJ.js +49 -0
  28. package/chunks/{chunk-CJRZSWII.js → chunk-K3PTYN43.js} +3 -3
  29. package/chunks/{chunk-2NBZZFRG.js → chunk-KCABBZHN.js} +8 -10
  30. package/chunks/{chunk-3LPBJMHB.js → chunk-LRD5N2TQ.js} +1 -1
  31. package/chunks/{chunk-SQCBHFWN.js → chunk-LWMEJYCP.js} +2 -2
  32. package/chunks/chunk-MNK373HF.js +57 -0
  33. package/chunks/{chunk-R2XBH476.js → chunk-MOEVVXML.js} +2 -2
  34. package/chunks/{chunk-F2P25DJY.js → chunk-MOGWEHSC.js} +1448 -1050
  35. package/chunks/{chunk-6XMFCVJS.js → chunk-N7YCONYR.js} +1 -1
  36. package/chunks/{chunk-3WUPCZGF.js → chunk-NA3FKCI2.js} +1 -1
  37. package/chunks/{chunk-S2GITRD5.js → chunk-NABVDAAO.js} +2 -2
  38. package/chunks/{chunk-SZDD77KX.js → chunk-NNMOTHKC.js} +6 -10
  39. package/chunks/{chunk-LMP2T4G2.js → chunk-OILVEROI.js} +22 -172
  40. package/chunks/{chunk-YERUDEXT.js → chunk-PAE7ZAV6.js} +2780 -1255
  41. package/chunks/{chunk-NBV4I237.js → chunk-PAMJEXE2.js} +1 -1
  42. package/chunks/{chunk-PJU24AKR.js → chunk-R7VWEY45.js} +337 -257
  43. package/chunks/{chunk-QNRYOJEB.js → chunk-RZZ6VPRY.js} +1 -1
  44. package/chunks/{chunk-WUPN3D37.js → chunk-S4DFH2FJ.js} +26 -1
  45. package/chunks/{chunk-5WAHHZBF.js → chunk-SIR7XW2S.js} +61910 -30777
  46. package/chunks/{chunk-BD7WULFS.js → chunk-SSPP64FF.js} +3 -2
  47. package/chunks/{chunk-BOBIAHKA.js → chunk-STPHTPSD.js} +3 -333
  48. package/chunks/{chunk-Q7JKIKKF.js → chunk-UGCTPKJG.js} +89 -17
  49. package/chunks/{chunk-5PFRE522.js → chunk-ULRLUXSS.js} +1 -1
  50. package/chunks/{chunk-GZA7RGK7.js → chunk-UQS7XCBV.js} +2085 -1093
  51. package/chunks/{chunk-X2IPO5JO.js → chunk-V2KJQVYE.js} +2676 -2959
  52. package/chunks/{chunk-CGBDEST2.js → chunk-VJBEB2K6.js} +1 -1
  53. package/chunks/{chunk-ILRMLA6J.js → chunk-VWE36MUN.js} +1 -1
  54. package/chunks/{chunk-RURJYCWY.js → chunk-WNWDQ2TO.js} +1 -1
  55. package/chunks/{chunk-GTED3FSZ.js → chunk-WPJMA5AK.js} +4 -99
  56. package/chunks/{chunk-5NFIY2SJ.js → chunk-XJ2TBEV7.js} +3 -3
  57. package/chunks/{chunk-PVJUPIQG.js → chunk-XOVYV7TT.js} +6 -6
  58. package/chunks/{chunk-IXT64DV5.js → chunk-XPDJE537.js} +97 -1
  59. package/chunks/{chunk-YKWARO3T.js → chunk-YGYJ2FTH.js} +95 -21
  60. package/chunks/{chunk-JWSOUKFF.js → chunk-YJGPPPUB.js} +66 -21
  61. package/chunks/chunk-YP2DHYNI.js +650 -0
  62. package/chunks/{chunk-RVJVM5L4.js → chunk-Z2VLJEQJ.js} +5 -5
  63. package/chunks/chunk-ZPVSDB63.js +3839 -0
  64. package/chunks/{codex-models-6XVNFRXZ.js → codex-models-CI22KIHY.js} +9 -8
  65. package/chunks/{commands-FRPOFIO4.js → commands-C2WRSCNB.js} +909 -610
  66. package/chunks/dashboard-XO2X2SPD.js +75 -0
  67. package/chunks/{db-BXJNWUYJ.js → db-FU3OIGQK.js} +5 -4
  68. package/chunks/{deep-review-GSJEBLCG.js → deep-review-5AL6QYTK.js} +37 -38
  69. package/chunks/{disclose-OU6Z6GVT.js → disclose-YPV5KIUU.js} +6 -5
  70. package/chunks/{dist-M2X367VW.js → dist-JAZWL3SC.js} +3 -2
  71. package/chunks/{dist-TQMHMSBZ.js → dist-ONIRKDH6.js} +376 -333
  72. package/chunks/{dist-RKLQIXDT.js → dist-QLMPTFT7.js} +4 -3
  73. package/chunks/{dist-7KSYDDSG.js → dist-QXJKD743.js} +5 -2
  74. package/chunks/{dist-LNXGATR2.js → dist-WNAOCQGA.js} +5 -4
  75. package/chunks/eval-runner-D3RUCU3R.js +38 -0
  76. package/chunks/{exploit-agent-Y2P4GFIY.js → exploit-agent-4E4HXKUA.js} +1 -1
  77. package/chunks/{exploit-autoclimb-YRZ3TMS2.js → exploit-autoclimb-5GRXI6VQ.js} +1 -1
  78. package/chunks/{exploit-climb-4LEY4SDW.js → exploit-climb-AHQEJ2I2.js} +4 -3
  79. package/chunks/{fix-RQSIG75B.js → fix-CHD7LXDS.js} +9 -8
  80. package/chunks/{harness-3NVC3DDY.js → harness-E63KDHPG.js} +5 -4
  81. package/chunks/{http-conformance-U5F6GKYG.js → http-conformance-AXMUOE6C.js} +3 -2
  82. package/chunks/hunt-scan-ME2Z4CTC.js +43 -0
  83. package/chunks/{kernel-primitive-T47V3RD3.js → kernel-primitive-S566GXWP.js} +4 -3
  84. package/chunks/{kernel-vm-runner-AEL5E3SV.js → kernel-vm-runner-KREBY4DC.js} +4 -3
  85. package/chunks/{local-engine-ZCW4YC6E.js → local-engine-ZRTZVSSX.js} +7 -6
  86. package/chunks/managed-operation-ZMLLRCCQ.js +59 -0
  87. package/chunks/{memsafety-scan-L2Z7E7TE.js → memsafety-scan-Q2MBZEGJ.js} +1 -2
  88. package/chunks/{native-loop-26X2CHBV.js → native-loop-UV3Z4Z2F.js} +31 -16
  89. package/chunks/operator-services-JOCREEBA.js +79 -0
  90. package/chunks/orchestrate-ZF6ZTSIQ.js +62 -0
  91. package/chunks/{prepare-C3KGMBXT.js → prepare-PLDVGLDX.js} +7 -6
  92. package/chunks/{provider-model-discovery-QGUGL3XW.js → provider-model-discovery-3X6DON3Y.js} +7 -2
  93. package/chunks/{remote-workflow-runtime-DB52SINR.js → remote-workflow-runtime-GOI4TYP5.js} +4 -3
  94. package/chunks/routing-WCQLO5SP.js +61 -0
  95. package/chunks/{runtime-AUBLQUOH.js → runtime-6ZIXFTW5.js} +4 -3
  96. package/chunks/{runtime-U66JNSAY.js → runtime-TVH5ORUK.js} +13 -8
  97. package/chunks/{scan-stream-34F3LTPV.js → scan-stream-HJVTWZ44.js} +6 -4
  98. package/chunks/{scope-HSTG63TQ.js → scope-RCYXVGJR.js} +4 -3
  99. package/chunks/service-plugins-TN6KDX4L.js +63 -0
  100. package/chunks/{session-store-MKAAP3WL.js → session-store-6QR3CVUA.js} +8 -5
  101. package/chunks/{variant-candidates-LG767HWH.js → variant-candidates-SGLKPPHI.js} +9 -8
  102. package/chunks/{web-recon-prepass-NJP6J3E4.js → web-recon-prepass-GO7CTMVQ.js} +7 -6
  103. package/chunks/{workflow-runtime-AR627I26.js → workflow-runtime-CQTDASFA.js} +50 -49
  104. package/dashboard/assets/{abnfDiagram-VCTEODGH-Cq149Jpk.js → abnfDiagram-VCTEODGH-DDZsU70-.js} +1 -1
  105. package/dashboard/assets/{arc-CpP-3TRW.js → arc-iDXNTSL6.js} +1 -1
  106. package/dashboard/assets/architecture-7GRP2DOG-DJcY9RFg.js +1 -0
  107. package/dashboard/assets/architectureDiagram-5GKGNRK7-d0ZuOniQ.js +36 -0
  108. package/dashboard/assets/{blockDiagram-I7D4REHJ-CZYkRRDi.js → blockDiagram-I7D4REHJ-B-EWfMy1.js} +2 -2
  109. package/dashboard/assets/{c4Diagram-7LVT6UL2-CV7Iu3_Z.js → c4Diagram-7LVT6UL2-KcZRuXZC.js} +1 -1
  110. package/dashboard/assets/channel-CeWMIm0w.js +1 -0
  111. package/dashboard/assets/{chunk-4HAMMTFA-PKCyW4m-.js → chunk-4HAMMTFA-DXWulBlo.js} +1 -1
  112. package/dashboard/assets/{chunk-75Z2AOVW-C5MlFTc_.js → chunk-75Z2AOVW-RiLZItrz.js} +1 -1
  113. package/dashboard/assets/chunk-DU6HZSFF-MBcaIyTX.js +127 -0
  114. package/dashboard/assets/{chunk-F27PBJKO-DTAok0qM.js → chunk-F27PBJKO-kLWCBX_W.js} +1 -1
  115. package/dashboard/assets/{chunk-FOHPRMQF-DHwB1DNv.js → chunk-FOHPRMQF-COOliuUh.js} +14 -14
  116. package/dashboard/assets/{chunk-GMAD6QVW-CPsr2F33.js → chunk-GMAD6QVW-BeQeSjpW.js} +7 -7
  117. package/dashboard/assets/{chunk-GVQU2GXP-C2AXGf9A.js → chunk-GVQU2GXP-CjCMlOIB.js} +1 -1
  118. package/dashboard/assets/{chunk-IMKFNOWR-DMG6yD_O.js → chunk-IMKFNOWR-BwNst53D.js} +1 -1
  119. package/dashboard/assets/{chunk-L3NEJ4N5-BSvwdbXx.js → chunk-L3NEJ4N5-CHXWQrkL.js} +1 -1
  120. package/dashboard/assets/{chunk-OSK3NFVY-CfB8V7FU.js → chunk-OSK3NFVY-B2vd19Ed.js} +1 -1
  121. package/dashboard/assets/{chunk-P2QGCYS3-CvmZvq6n.js → chunk-P2QGCYS3-Dk7Fyh6n.js} +1 -1
  122. package/dashboard/assets/{chunk-POPQ4Y6H-D_TvwDxL.js → chunk-POPQ4Y6H-CPAgOvYe.js} +1 -1
  123. package/dashboard/assets/{chunk-PWAF6VOD-Da5GnuOY.js → chunk-PWAF6VOD-BotyfMha.js} +1 -1
  124. package/dashboard/assets/{chunk-SHT3W25Y-CcsMJpR-.js → chunk-SHT3W25Y-Buz5gLRP.js} +1 -1
  125. package/dashboard/assets/{chunk-SVP7TREG-COojjieJ.js → chunk-SVP7TREG-_rpYEZcs.js} +1 -1
  126. package/dashboard/assets/{chunk-TICWLB2K-nBAmJwx6.js → chunk-TICWLB2K-DOJxPoec.js} +2 -2
  127. package/dashboard/assets/{chunk-XXDRQBXY-r5HyhWDv.js → chunk-XXDRQBXY-EXxKJbAs.js} +1 -1
  128. package/dashboard/assets/classDiagram-ZZMXUADV-DV_h1NoS.js +1 -0
  129. package/dashboard/assets/classDiagram-v2-VYDZK3BY-DV_h1NoS.js +1 -0
  130. package/dashboard/assets/common-VLJRx-Jq.js +5 -0
  131. package/dashboard/assets/cose-bilkent-JH36ORCC-B1SVC57o.js +1 -0
  132. package/dashboard/assets/cynefin-OW5HDTMX-BzhRorj4.js +1 -0
  133. package/dashboard/assets/{cynefinDiagram-5FMLGOSQ-xodkuQtW.js → cynefinDiagram-5FMLGOSQ-JXzRmldX.js} +1 -1
  134. package/dashboard/assets/cytoscape.esm-BbBREfsg.js +321 -0
  135. package/dashboard/assets/dagre-D7JM2Yhv.js +1 -0
  136. package/dashboard/assets/dagre-GXQ25YYZ-1LZ-X0-Z.js +4 -0
  137. package/dashboard/assets/{diagram-S7CK7UJ4-DNoTMlCO.js → diagram-S7CK7UJ4-C_-J_LQ4.js} +2 -2
  138. package/dashboard/assets/{diagram-UQ7AKVKN-COccuyew.js → diagram-UQ7AKVKN-CnxL1k8g.js} +1 -1
  139. package/dashboard/assets/{diagram-VSXAHHWV-g6D1tWRb.js → diagram-VSXAHHWV-WzSb3aby.js} +1 -1
  140. package/dashboard/assets/{diagram-VX7I27RA-DhO4eVIC.js → diagram-VX7I27RA-DKhrMInE.js} +1 -1
  141. package/dashboard/assets/{diagram-Z3DM3KII-DeOQFexd.js → diagram-Z3DM3KII-CDhI2WGP.js} +1 -1
  142. package/dashboard/assets/{dist-BQYeOQg3.js → dist-B0bfBMeP.js} +1 -1
  143. package/dashboard/assets/{ebnfDiagram-PWID7BFC-MtkX2feM.js → ebnfDiagram-PWID7BFC-iL5NQ1PE.js} +1 -1
  144. package/dashboard/assets/{erDiagram-RLTQ6QDP-DIWSsoYZ.js → erDiagram-RLTQ6QDP-RK2Voa5O.js} +1 -1
  145. package/dashboard/assets/eventmodeling-NTZA5JFV-WgE7OJBb.js +1 -0
  146. package/dashboard/assets/flowDiagram-HODETNUW-B9YcQ0Aq.js +1 -0
  147. package/dashboard/assets/{ganttDiagram-EL5Y4UJY-DKggkJe0.js → ganttDiagram-EL5Y4UJY-D8CJXHRF.js} +1 -1
  148. package/dashboard/assets/gitGraph-4MIJSDKK-BuZ9Lg04.js +1 -0
  149. package/dashboard/assets/{gitGraphDiagram-WWUBYQGX-r_iR8Qzo.js → gitGraphDiagram-WWUBYQGX-LEJMh54j.js} +1 -1
  150. package/dashboard/assets/info-A6RAGUB7-BL5k3pev.js +1 -0
  151. package/dashboard/assets/{infoDiagram-27XIBGKW-ClQk7UyQ.js → infoDiagram-27XIBGKW-LJvntUnZ.js} +1 -1
  152. package/dashboard/assets/{ishikawaDiagram-5VMMS53U-tR7Vziog.js → ishikawaDiagram-5VMMS53U-BYTYgKCG.js} +2 -2
  153. package/dashboard/assets/{journeyDiagram-3NMN7TZE-Cpb9IqKL.js → journeyDiagram-3NMN7TZE-G25qgQgO.js} +1 -1
  154. package/dashboard/assets/{kanban-definition-UXKFOSKX-BzUuKbA9.js → kanban-definition-UXKFOSKX-Bk3uLl1i.js} +1 -1
  155. package/dashboard/assets/{katex-BdBmVSus.js → katex-nLxf_RlZ.js} +2 -2
  156. package/dashboard/assets/{line-BHY_tSHu.js → line-i4qHBaWO.js} +1 -1
  157. package/dashboard/assets/linear-DmrqRsKG.js +1 -0
  158. package/dashboard/assets/mermaid-parser.core-BxbKr4QF.js +7 -0
  159. package/dashboard/assets/{mermaid.core-D_QsUPU8.js → mermaid.core-Cltee6FS.js} +9 -9
  160. package/dashboard/assets/{mindmap-definition-YA3MSWOX-CtfLTPPJ.js → mindmap-definition-YA3MSWOX-DkzO2JgS.js} +1 -1
  161. package/dashboard/assets/operations-B4_timQX.css +1 -0
  162. package/dashboard/assets/operations-DwppJviL.js +199 -0
  163. package/dashboard/assets/packet-AYTQ26CC-uZQUKnrE.js +1 -0
  164. package/dashboard/assets/{pegDiagram-XKGWAZYB-C1Dclbzj.js → pegDiagram-XKGWAZYB-CrOEi00T.js} +1 -1
  165. package/dashboard/assets/pie-WAS4IAKB-Dn9_tpQT.js +1 -0
  166. package/dashboard/assets/{pieDiagram-E7YTZNPT-Cd7XwYo5.js → pieDiagram-E7YTZNPT-D-niUkzc.js} +1 -1
  167. package/dashboard/assets/{quadrantDiagram-AXDQQJYC-CaS-GQ4X.js → quadrantDiagram-AXDQQJYC-CJOTiG5V.js} +1 -1
  168. package/dashboard/assets/radar-RG4KPBEZ-DIIVz4e8.js +1 -0
  169. package/dashboard/assets/railroad-74A4TZTK-1kiqDEID.js +1 -0
  170. package/dashboard/assets/railroad-abnf-HS5TGJTU-DK6rQPZR.js +1 -0
  171. package/dashboard/assets/railroad-ebnf-LZEXJU2U-C6cOgYW4.js +1 -0
  172. package/dashboard/assets/railroad-peg-WCYAUIDC-CQ3ptKef.js +1 -0
  173. package/dashboard/assets/{railroadDiagram-O6MQD6OU-BeesTrqn.js → railroadDiagram-O6MQD6OU-nEfkpa-m.js} +1 -1
  174. package/dashboard/assets/{requirementDiagram-BXWQKSXE-IjyK0DhW.js → requirementDiagram-BXWQKSXE-CdFMY8tG.js} +1 -1
  175. package/dashboard/assets/{sankeyDiagram-P5KCCOFB-DmIluQqo.js → sankeyDiagram-P5KCCOFB-C0KxrFYv.js} +1 -1
  176. package/dashboard/assets/{sequenceDiagram-WJ2MYXX4-CUp8ZjTc.js → sequenceDiagram-WJ2MYXX4-DeZ5ATiu.js} +2 -2
  177. package/dashboard/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
  178. package/dashboard/assets/src-Cg-chcoE.js +1 -0
  179. package/dashboard/assets/{stateDiagram-D77RDMKH-Dy9TQb8P.js → stateDiagram-D77RDMKH-B9MwWL5B.js} +1 -1
  180. package/dashboard/assets/stateDiagram-v2-MP3YSRHH-SucFndhx.js +1 -0
  181. package/dashboard/assets/swimlanes-42K2YHIH-DB--fwQE.js +1 -0
  182. package/dashboard/assets/swimlanesDiagram-VR7AAH4N-BzH-rIaK.js +8 -0
  183. package/dashboard/assets/{timeline-definition-24CTP7MA-BGdXW-iY.js → timeline-definition-24CTP7MA-DLkkTbWb.js} +1 -1
  184. package/dashboard/assets/treeView-Q6P3EWNA-XkZ9rl9H.js +1 -0
  185. package/dashboard/assets/treemap-WGGIJYW6-JCtVKxCE.js +1 -0
  186. package/dashboard/assets/{vennDiagram-4TSXK5OY-DzKWHJsl.js → vennDiagram-4TSXK5OY-DEb-x29Z.js} +1 -1
  187. package/dashboard/assets/wardley-WFR3VGLG-DhI7ROY3.js +1 -0
  188. package/dashboard/assets/{wardleyDiagram-VM6X3IG4-DGsjYmNJ.js → wardleyDiagram-VM6X3IG4-KNckudc5.js} +1 -1
  189. package/dashboard/assets/{xychartDiagram-S5SC5T6Z-C7_T_tWt.js → xychartDiagram-S5SC5T6Z-D4c0ynCk.js} +1 -1
  190. package/dashboard/index.html +13 -2
  191. package/package.json +2 -5
  192. package/worker-assets/demo-target/README.md +7 -3
  193. package/chunks/chunk-2XGBEH53.js +0 -4304
  194. package/chunks/chunk-4ROZFLSR.js +0 -279
  195. package/chunks/chunk-56UTQKXO.js +0 -56
  196. package/chunks/chunk-BPU6M42R.js +0 -77
  197. package/chunks/chunk-H5QURBBK.js +0 -1123
  198. package/chunks/chunk-IIBNQTOK.js +0 -1532
  199. package/chunks/chunk-NJLKFC66.js +0 -4790
  200. package/chunks/chunk-OOMBOLAF.js +0 -295
  201. package/chunks/chunk-VIT5ALXF.js +0 -4054
  202. package/chunks/chunk-VU7V2SDW.js +0 -284
  203. package/chunks/chunk-W624J7NF.js +0 -117
  204. package/chunks/chunk-YSQWZ67M.js +0 -6027
  205. package/chunks/dashboard-5HDSNBAU.js +0 -76
  206. package/chunks/eval-runner-A2DIGVP7.js +0 -31
  207. package/chunks/hunt-scan-W246VWJC.js +0 -40
  208. package/chunks/managed-operation-6R2QPPW5.js +0 -60
  209. package/chunks/orchestrate-OBS37FWQ.js +0 -63
  210. package/chunks/run-MU3MFL2Z.js +0 -28242
  211. package/chunks/service-plugins-5B23PWXC.js +0 -64
  212. package/dashboard/assets/architecture-7GRP2DOG-z5EHYkyH.js +0 -1
  213. package/dashboard/assets/architectureDiagram-5GKGNRK7-ewtXpjR_.js +0 -36
  214. package/dashboard/assets/channel-CuYjfiC5.js +0 -1
  215. package/dashboard/assets/chunk-DU6HZSFF-3M37ulcO.js +0 -127
  216. package/dashboard/assets/classDiagram-ZZMXUADV-DCuOrWUV.js +0 -1
  217. package/dashboard/assets/classDiagram-v2-VYDZK3BY-DCuOrWUV.js +0 -1
  218. package/dashboard/assets/common-C6snVPsk.js +0 -5
  219. package/dashboard/assets/cose-bilkent-JH36ORCC-BLGcaZHk.js +0 -1
  220. package/dashboard/assets/cynefin-OW5HDTMX-DbZMK00I.js +0 -1
  221. package/dashboard/assets/cytoscape.esm-CGd-uY3x.js +0 -321
  222. package/dashboard/assets/dagre-GXQ25YYZ-CRk9qfSG.js +0 -4
  223. package/dashboard/assets/dagre-PrKaheQc.js +0 -1
  224. package/dashboard/assets/eventmodeling-NTZA5JFV-D_3ez4Gv.js +0 -1
  225. package/dashboard/assets/flowDiagram-HODETNUW-D2boyYEd.js +0 -1
  226. package/dashboard/assets/gitGraph-4MIJSDKK-DFOQYwXc.js +0 -1
  227. package/dashboard/assets/info-A6RAGUB7-DeednLoB.js +0 -1
  228. package/dashboard/assets/linear-naZZ1pHk.js +0 -1
  229. package/dashboard/assets/mermaid-parser.core-CPvd4cEx.js +0 -7
  230. package/dashboard/assets/operations-BwCzhVnT.js +0 -130
  231. package/dashboard/assets/operations-QjKT0Hwi.css +0 -1
  232. package/dashboard/assets/packet-AYTQ26CC-DDQbkT9I.js +0 -1
  233. package/dashboard/assets/pie-WAS4IAKB-LpU4ULAs.js +0 -1
  234. package/dashboard/assets/radar-RG4KPBEZ-CcxW3NJm.js +0 -1
  235. package/dashboard/assets/railroad-74A4TZTK-9P5Rl8fP.js +0 -1
  236. package/dashboard/assets/railroad-abnf-HS5TGJTU-CSfpwjna.js +0 -1
  237. package/dashboard/assets/railroad-ebnf-LZEXJU2U-D6R5qzr-.js +0 -1
  238. package/dashboard/assets/railroad-peg-WCYAUIDC-DKEX7ITG.js +0 -1
  239. package/dashboard/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
  240. package/dashboard/assets/src-r61wDjcA.js +0 -1
  241. package/dashboard/assets/stateDiagram-v2-MP3YSRHH-CQb0ZtPr.js +0 -1
  242. package/dashboard/assets/swimlanes-42K2YHIH-CZuDV7V5.js +0 -1
  243. package/dashboard/assets/swimlanesDiagram-VR7AAH4N-BxgWMq8X.js +0 -8
  244. package/dashboard/assets/treeView-Q6P3EWNA-DlRrayjM.js +0 -1
  245. package/dashboard/assets/treemap-WGGIJYW6-C6UqLKfI.js +0 -1
  246. package/dashboard/assets/wardley-WFR3VGLG-thmyHKb0.js +0 -1
@@ -3,14 +3,14 @@ import { createRequire as __0CreateRequire } from "node:module";
3
3
  const require = __0CreateRequire(import.meta.url);
4
4
  import {
5
5
  eventBus
6
- } from "./chunk-5PFRE522.js";
6
+ } from "./chunk-ULRLUXSS.js";
7
7
  import {
8
8
  compareFindingsByBusinessPriority,
9
9
  estimateCost,
10
10
  modelProvider,
11
11
  splitCost,
12
12
  validateScanPlan
13
- } from "./chunk-GXXX7AGH.js";
13
+ } from "./chunk-GYEYTNHK.js";
14
14
 
15
15
  // packages/core/dist/agent/cost-ledger.js
16
16
  var recordedResults = /* @__PURE__ */ new WeakMap();
@@ -209,6 +209,7 @@ function budgetNativeRuntime(runtime, ledger, signal, ceiling, plan) {
209
209
  resolvedProvider: runtime.resolvedProvider?.bind(runtime),
210
210
  resolvedPricingModel: runtime.resolvedPricingModel?.bind(runtime),
211
211
  accessibleModels: runtime.accessibleModels?.bind(runtime),
212
+ modelSelection: runtime.modelSelection?.bind(runtime),
212
213
  reconfigure: runtime.reconfigure?.bind(runtime),
213
214
  forkForSubagent: runtime.forkForSubagent ? async (timeout, selection) => budgetNativeRuntime(await runtime.forkForSubagent(timeout, selection), ledger, signal, ceiling, plan) : void 0,
214
215
  async executeNative(system, messages, tools, callbacks, callSignal) {
@@ -2,335 +2,9 @@
2
2
  import { createRequire as __0CreateRequire } from "node:module";
3
3
  const require = __0CreateRequire(import.meta.url);
4
4
  import {
5
- jitterFor
6
- } from "./chunk-X2ZMSRTP.js";
7
- import {
8
- scanExecutionSignal
9
- } from "./chunk-BD7WULFS.js";
10
-
11
- // packages/core/dist/scope/rate-limit.js
12
- var TokenBucket = class {
13
- state;
14
- nowFn;
15
- sleepFn;
16
- jitter;
17
- constructor(rps, capacity = rps, nowFn = () => Date.now(), sleepFn = defaultSleep, jitter) {
18
- if (!Number.isFinite(rps) || rps <= 0) {
19
- throw new Error(`TokenBucket: rps must be a positive finite number, got ${rps}`);
20
- }
21
- if (!Number.isFinite(capacity) || capacity <= 0) {
22
- throw new Error(`TokenBucket: capacity must be a positive finite number, got ${capacity}`);
23
- }
24
- this.nowFn = nowFn;
25
- this.sleepFn = sleepFn;
26
- this.jitter = jitter && jitter.baseMs > 0 ? jitter : void 0;
27
- this.state = {
28
- tokens: capacity,
29
- refillRatePerMs: rps / 1e3,
30
- capacity,
31
- lastRefill: nowFn(),
32
- retryUntil: 0
33
- };
34
- }
35
- refill() {
36
- const now = this.nowFn();
37
- const elapsed = now - this.state.lastRefill;
38
- if (elapsed > 0) {
39
- this.state.tokens = Math.min(this.state.capacity, this.state.tokens + elapsed * this.state.refillRatePerMs);
40
- this.state.lastRefill = now;
41
- }
42
- }
43
- /**
44
- * Non-blocking. Returns true and consumes `n` tokens if available;
45
- * returns false and consumes nothing otherwise. Blocked during 429
46
- * cool-off (returns false until park expires).
47
- */
48
- tryConsume(n = 1) {
49
- if (this.nowFn() < this.state.retryUntil)
50
- return false;
51
- this.refill();
52
- if (this.state.tokens >= n) {
53
- this.state.tokens -= n;
54
- return true;
55
- }
56
- return false;
57
- }
58
- /**
59
- * Block until `n` tokens are available, then consume them. Honours
60
- * the 429 park deadline first, then refill-and-spin with sleeps
61
- * sized to the exact next-token-available time.
62
- */
63
- async acquire(n = 1, signal = scanExecutionSignal()) {
64
- signal?.throwIfAborted();
65
- if (n > this.state.capacity) {
66
- n = this.state.capacity;
67
- }
68
- while (this.nowFn() < this.state.retryUntil) {
69
- const wait = this.state.retryUntil - this.nowFn();
70
- await this.sleepFn(Math.max(1, Math.min(wait, 1e3)), signal);
71
- }
72
- while (true) {
73
- signal?.throwIfAborted();
74
- this.refill();
75
- if (this.state.tokens >= n) {
76
- this.state.tokens -= n;
77
- await this.pace(signal);
78
- return;
79
- }
80
- const tokensNeeded = n - this.state.tokens;
81
- const waitMs = Math.max(1, Math.ceil(tokensNeeded / this.state.refillRatePerMs));
82
- await this.sleepFn(waitMs, signal);
83
- }
84
- }
85
- /**
86
- * Sleep the configured full-jitter delay. No-op (and no `await`-visible
87
- * sleep) when no jitter is configured, so the default path is unchanged.
88
- *
89
- * Reuses `jitterFor` from `waf-detect.ts` — attempt 0 with an injected rng
90
- * yields full jitter in `[0, baseMs]` — rather than growing a second
91
- * jitter implementation.
92
- */
93
- async pace(signal = scanExecutionSignal()) {
94
- signal?.throwIfAborted();
95
- if (!this.jitter)
96
- return;
97
- const ms = jitterFor(0, this.jitter.baseMs, this.jitter.rng ?? Math.random);
98
- if (ms > 0)
99
- await this.sleepFn(ms, signal);
100
- }
101
- /**
102
- * Park the bucket until `deadline` (ms since epoch). Subsequent
103
- * `acquire`/`tryConsume` calls block until the deadline passes.
104
- * Idempotent in the "later wins" sense: a longer park overrides a
105
- * shorter one, but a shorter park does NOT shorten an existing one.
106
- */
107
- markRetryUntil(deadline) {
108
- if (deadline > this.state.retryUntil) {
109
- this.state.retryUntil = deadline;
110
- }
111
- }
112
- /** Test introspection. */
113
- _peek() {
114
- this.refill();
115
- return {
116
- tokens: this.state.tokens,
117
- retryUntil: this.state.retryUntil,
118
- capacity: this.state.capacity
119
- };
120
- }
121
- };
122
- var RateLimiter = class _RateLimiter {
123
- buckets = /* @__PURE__ */ new Map();
124
- defaultCfg;
125
- perHost;
126
- jitter;
127
- nowFn;
128
- sleepFn;
129
- /**
130
- * Conservative cool-off floor when a 429 lands without a useful
131
- * `Retry-After`, or with a tiny one. 60s matches the PoC-runtime
132
- * precedent in #206 — a target that just told us to slow down has
133
- * earned more than a one-second pause.
134
- */
135
- static RETRY_AFTER_FLOOR_MS = 6e4;
136
- /**
137
- * Optional observer invoked once whenever a fetch is actually throttled:
138
- * either an `acquire` that had to block because the bucket was dry, or a
139
- * 429 response parking the host. Used by the http_audit enforcement
140
- * tracker to populate `rate_limited_count`. No-op when unset, so the
141
- * normal scan path is unaffected.
142
- */
143
- onThrottle;
144
- constructor(config, opts = {}) {
145
- this.defaultCfg = config.default;
146
- this.jitter = config.jitter;
147
- this.perHost = {};
148
- if (config.perHost) {
149
- for (const [host, cfg] of Object.entries(config.perHost)) {
150
- this.perHost[host.toLowerCase()] = cfg;
151
- }
152
- }
153
- this.nowFn = opts.nowFn ?? (() => Date.now());
154
- this.sleepFn = opts.sleepFn ?? defaultSleep;
155
- this.onThrottle = opts.onThrottle;
156
- }
157
- /**
158
- * Normalize a URL or host string to a bucket key. Lowercased,
159
- * port-stripped, IPv6 brackets retained on the literal but dropped
160
- * from the port suffix (e.g. `[::1]:443` → `[::1]`).
161
- */
162
- hostKey(urlOrHost) {
163
- let host;
164
- try {
165
- host = new URL(urlOrHost).hostname;
166
- } catch {
167
- const trimmed = urlOrHost.trim();
168
- if (!trimmed)
169
- return null;
170
- if (trimmed.startsWith("[")) {
171
- const close = trimmed.indexOf("]");
172
- if (close < 0)
173
- return null;
174
- host = trimmed.slice(0, close + 1);
175
- } else {
176
- host = trimmed.split(":")[0];
177
- }
178
- }
179
- return host.toLowerCase();
180
- }
181
- getBucket(host) {
182
- let bucket = this.buckets.get(host);
183
- if (!bucket) {
184
- const cfg = this.perHost[host] ?? this.defaultCfg;
185
- bucket = new TokenBucket(cfg.rps, cfg.burst ?? cfg.rps, this.nowFn, this.sleepFn, this.jitter);
186
- this.buckets.set(host, bucket);
187
- }
188
- return bucket;
189
- }
190
- /**
191
- * Block until a token is available for `urlOrHost`'s host, then
192
- * consume it. Unparseable input is treated as a no-op (returns
193
- * immediately) — callers should not rely on rate-limiting unknowable
194
- * hosts. The fetch sites that wire this up always pass full URLs.
195
- */
196
- async acquire(urlOrHost, n = 1, signal = scanExecutionSignal()) {
197
- signal?.throwIfAborted();
198
- const host = this.hostKey(urlOrHost);
199
- if (!host)
200
- return;
201
- const bucket = this.getBucket(host);
202
- if (bucket.tryConsume(n)) {
203
- await bucket.pace(signal);
204
- return;
205
- }
206
- this.onThrottle?.();
207
- await bucket.acquire(n, signal);
208
- }
209
- /**
210
- * Non-blocking variant. Returns true and consumes if available,
211
- * false otherwise. Used by callers that want to fall through to a
212
- * fast-path / degrade rather than wait.
213
- */
214
- tryAcquire(urlOrHost, n = 1) {
215
- const host = this.hostKey(urlOrHost);
216
- if (!host)
217
- return true;
218
- return this.getBucket(host).tryConsume(n);
219
- }
220
- /**
221
- * Inspect a fetch response and, if it's a 429, park the host's
222
- * bucket until `Retry-After` (or 60s, whichever is longer). The
223
- * parsed value supports both delta-seconds (RFC 7231 §7.1.3) and
224
- * HTTP-date forms; anything else falls back to the floor.
225
- *
226
- * No-ops on non-429 responses, or on hosts with no bucket yet
227
- * (which can't happen if the caller acquired before fetching, but
228
- * we don't depend on that).
229
- */
230
- noteResponse(urlOrHost, res) {
231
- if (res.status !== 429)
232
- return;
233
- const host = this.hostKey(urlOrHost);
234
- if (!host)
235
- return;
236
- this.onThrottle?.();
237
- const bucket = this.getBucket(host);
238
- const retryAfter = readHeader(res.headers, "retry-after");
239
- const delayMs = parseRetryAfter(retryAfter, this.nowFn());
240
- const deadline = this.nowFn() + Math.max(delayMs, _RateLimiter.RETRY_AFTER_FLOOR_MS);
241
- bucket.markRetryUntil(deadline);
242
- }
243
- /** Test-only. Reset all buckets. */
244
- _reset() {
245
- this.buckets.clear();
246
- }
247
- };
248
- function defaultSleep(ms, signal) {
249
- signal?.throwIfAborted();
250
- const { promise, resolve, reject } = Promise.withResolvers();
251
- const timer = setTimeout(() => {
252
- signal?.removeEventListener("abort", abort);
253
- resolve();
254
- }, ms);
255
- const abort = () => {
256
- clearTimeout(timer);
257
- reject(signal?.reason ?? new Error("Rate-limit wait cancelled."));
258
- };
259
- signal?.addEventListener("abort", abort, { once: true });
260
- return promise;
261
- }
262
- function readHeader(headers, name) {
263
- if (typeof headers.get === "function") {
264
- return headers.get(name);
265
- }
266
- return null;
267
- }
268
- function parseRetryAfter(value, now) {
269
- if (!value)
270
- return 0;
271
- const trimmed = value.trim();
272
- if (!trimmed)
273
- return 0;
274
- if (/^\d+$/.test(trimmed)) {
275
- const seconds = parseInt(trimmed, 10);
276
- return Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : 0;
277
- }
278
- const date = Date.parse(trimmed);
279
- if (Number.isFinite(date)) {
280
- return Math.max(0, date - now);
281
- }
282
- return 0;
283
- }
284
- function parseRateLimitFlag(spec, fallbackRps = 5) {
285
- const trimmed = spec.trim();
286
- if (!trimmed) {
287
- return { default: { rps: fallbackRps } };
288
- }
289
- const parts = trimmed.split(",").map((p) => p.trim()).filter(Boolean);
290
- let defaultCfg = null;
291
- const perHost = {};
292
- for (const part of parts) {
293
- const eq = part.indexOf("=");
294
- if (eq < 0) {
295
- const cfg = parseRpsBurst(part);
296
- defaultCfg = cfg;
297
- } else {
298
- const host = part.slice(0, eq).trim().toLowerCase();
299
- const cfg = parseRpsBurst(part.slice(eq + 1));
300
- if (!host) {
301
- throw new Error(`--rate-limit: empty host in "${part}"`);
302
- }
303
- perHost[host] = cfg;
304
- }
305
- }
306
- return {
307
- default: defaultCfg ?? { rps: fallbackRps },
308
- perHost: Object.keys(perHost).length > 0 ? perHost : void 0
309
- };
310
- }
311
- function parseRpsBurst(s) {
312
- const trimmed = s.trim();
313
- if (!trimmed) {
314
- throw new Error(`--rate-limit: empty rps value`);
315
- }
316
- const colon = trimmed.indexOf(":");
317
- if (colon < 0) {
318
- const rps2 = Number(trimmed);
319
- if (!Number.isFinite(rps2) || rps2 <= 0) {
320
- throw new Error(`--rate-limit: invalid rps "${trimmed}"`);
321
- }
322
- return { rps: rps2 };
323
- }
324
- const rps = Number(trimmed.slice(0, colon));
325
- const burst = Number(trimmed.slice(colon + 1));
326
- if (!Number.isFinite(rps) || rps <= 0) {
327
- throw new Error(`--rate-limit: invalid rps "${trimmed.slice(0, colon)}"`);
328
- }
329
- if (!Number.isFinite(burst) || burst <= 0) {
330
- throw new Error(`--rate-limit: invalid burst "${trimmed.slice(colon + 1)}"`);
331
- }
332
- return { rps, burst };
333
- }
5
+ RateLimiter,
6
+ parseRateLimitFlag
7
+ } from "./chunk-6SNOKNCS.js";
334
8
 
335
9
  // packages/core/dist/stages/web.js
336
10
  import { randomUUID } from "node:crypto";
@@ -923,10 +597,6 @@ function summarizeWebStackFingerprint(result) {
923
597
  }
924
598
 
925
599
  export {
926
- TokenBucket,
927
- RateLimiter,
928
- parseRetryAfter,
929
- parseRateLimitFlag,
930
600
  runWebDiscoveryProbe,
931
601
  runBaselineWebChecks,
932
602
  fingerprintWebStack,
@@ -3,7 +3,7 @@ import { createRequire as __0CreateRequire } from "node:module";
3
3
  const require = __0CreateRequire(import.meta.url);
4
4
  import {
5
5
  resolveOsecDbPath
6
- } from "./chunk-BMDG6T7D.js";
6
+ } from "./chunk-72PU46MS.js";
7
7
  import {
8
8
  BACKEND_PROTOCOL_VERSION,
9
9
  BackendDescriptorSchema,
@@ -12,10 +12,10 @@ import {
12
12
  backendCapabilitiesForApiPath,
13
13
  homeStateDir,
14
14
  parseBackendHandshake
15
- } from "./chunk-GXXX7AGH.js";
15
+ } from "./chunk-GYEYTNHK.js";
16
16
  import {
17
17
  external_exports
18
- } from "./chunk-VIT5ALXF.js";
18
+ } from "./chunk-5XOYTAOK.js";
19
19
 
20
20
  // packages/cli/src/worker-deploy.ts
21
21
  import { execFileSync, spawn, spawnSync } from "node:child_process";
@@ -30,12 +30,8 @@ var REMOTE_DEPS = {
30
30
  "node-sqlite3-wasm": "^0.8.55",
31
31
  "pdfkit": "^0.15.2",
32
32
  "playwright": "1.60.0",
33
- "react": "^19.2.4",
34
- "react-dom": "^19.2.4",
35
33
  "tree-sitter": `file:${REMOTE_DIR}/vendor/tree-sitter-0.21.1-node24.tgz`,
36
- "tree-sitter-c": "0.21.4",
37
- "@opentui/core": "0.5.4",
38
- "@opentui/react": "0.5.4"
34
+ "tree-sitter-c": "0.21.4"
39
35
  };
40
36
  var SSH_HOST_PATTERN = /^[A-Za-z0-9._@-]+$/;
41
37
  var LIMA_NAME_PATTERN = /^[\w.-]+$/;
@@ -50,6 +46,9 @@ function resolveWorkerRepoRoot(moduleUrl = import.meta.url) {
50
46
  directory = parent;
51
47
  }
52
48
  }
49
+ function resolveWorkerDemoRoot(repoRoot, bundleRoot) {
50
+ return existsSync(join(bundleRoot, "dist/worker-assets/demo-target")) ? join(bundleRoot, "dist/worker-assets") : join(repoRoot, "assets/worker-demo");
51
+ }
53
52
  function validateWorkerOptions(options) {
54
53
  if (options.enginePort !== void 0 && (!Number.isInteger(options.enginePort) || options.enginePort < 1 || options.enginePort > 65535)) throw new Error("enginePort must be 1-65535");
55
54
  if (options.ssh && (!SSH_HOST_PATTERN.test(options.ssh) || options.ssh.startsWith("-"))) {
@@ -64,10 +63,10 @@ function createRunner(options) {
64
63
  const configArgs = options.sshConfig ? ["-F", options.sshConfig] : [];
65
64
  return {
66
65
  label: host,
67
- shell: (command, timeout = 3e5) => execFileSync("ssh", ["-o", "BatchMode=yes", "-o", "ConnectTimeout=15", ...configArgs, "--", host, "bash", "-s"], { input: command, encoding: "utf8", timeout }),
66
+ shell: (command, timeout = 3e5) => execFileSync("ssh", ["-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=yes", "-o", "ConnectTimeout=15", ...configArgs, "--", host, "bash", "-s"], { input: command, encoding: "utf8", timeout }),
68
67
  copy: (local, remote) => execFileSync("scp", ["-q", "-o", "BatchMode=yes", ...configArgs, "--", local, `${host}:${remote}`], { stdio: "inherit", timeout: 6e5 }),
69
68
  tunnel: (port) => {
70
- const child = spawn("ssh", ["-o", "BatchMode=yes", ...configArgs, "-N", "-L", `${port}:127.0.0.1:${port}`, "--", host], { stdio: "ignore", detached: true });
69
+ const child = spawn("ssh", ["-o", "BatchMode=yes", "-o", "StrictHostKeyChecking=yes", "-o", "ExitOnForwardFailure=yes", ...configArgs, "-N", "-L", `${port}:127.0.0.1:${port}`, "--", host], { stdio: "ignore", detached: true });
71
70
  child.unref();
72
71
  return child.pid;
73
72
  }
@@ -120,7 +119,7 @@ async function deployWorker(options, runner = createRunner(options)) {
120
119
  }
121
120
  }
122
121
  execFileSync("tar", ["-czf", join(staging, "bundle.tar.gz"), "-C", bundleRoot, "dist"], { stdio: "inherit", env: { ...process.env, COPYFILE_DISABLE: "1" } });
123
- const demoRoot = existsSync(join(bundleRoot, "dist/worker-assets/demo-target")) ? join(bundleRoot, "dist/worker-assets") : join(repoRoot, "research/counterexample-decoder");
122
+ const demoRoot = resolveWorkerDemoRoot(repoRoot, bundleRoot);
124
123
  if (!options.targetGit) execFileSync("tar", ["-czf", join(staging, "demo-target.tar.gz"), "-C", demoRoot, "demo-target"], { stdio: "inherit", env: { ...process.env, COPYFILE_DISABLE: "1" } });
125
124
  shell(`for entry in /proc/[0-9]*/cwd; do
126
125
  test "$(readlink "$entry" 2>/dev/null)" = "${REMOTE_DIR}" || continue
@@ -168,7 +167,12 @@ async function deployWorker(options, runner = createRunner(options)) {
168
167
  writeFileSync(backendsConfig, JSON.stringify(registry, null, 2) + "\n", { mode: 384 });
169
168
  writeFileSync(join(stateDir, `${backendId}.env`), `${tokenEnv}=${token}
170
169
  `, { mode: 384 });
171
- writeFileSync(join(stateDir, `${backendId}.json`), JSON.stringify({ schemaVersion: 1, backendId, ssh: options.ssh, lima: options.ssh ? void 0 : options.lima ?? "zero-worker", sshConfig: options.sshConfig, port, tunnelPid, remoteDir: REMOTE_DIR }, null, 2) + "\n", { mode: 384 });
170
+ let previousMetadata = {};
171
+ try {
172
+ previousMetadata = JSON.parse(readFileSync(join(stateDir, `${backendId}.json`), "utf8"));
173
+ } catch {
174
+ }
175
+ writeFileSync(join(stateDir, `${backendId}.json`), JSON.stringify({ ...previousMetadata, schemaVersion: 1, backendId, autoReconnect: true, ssh: options.ssh, lima: options.ssh ? void 0 : options.lima ?? "zero-worker", sshConfig: options.sshConfig, port, tunnelPid, remoteDir: REMOTE_DIR }, null, 2) + "\n", { mode: 384 });
172
176
  process.env[tokenEnv] = token;
173
177
  return { backendId, engine: `http://127.0.0.1:${port}/`, target: targetPath, backendsConfig, tokenEnv };
174
178
  } finally {
@@ -183,7 +187,7 @@ function loadManagedWorker(backendId) {
183
187
  } catch {
184
188
  throw new Error("This connection has no managed deployment metadata. Stop its engine directly on the host.");
185
189
  }
186
- if (worker.schemaVersion !== 1 || worker.backendId !== backendId || worker.remoteDir !== REMOTE_DIR || !!worker.ssh === !!worker.lima) throw new Error("Invalid managed deployment metadata.");
190
+ if (worker.schemaVersion !== 1 || worker.backendId !== backendId || worker.remoteDir !== REMOTE_DIR || !!worker.ssh === !!worker.lima || worker.autoReconnect !== void 0 && typeof worker.autoReconnect !== "boolean") throw new Error("Invalid managed deployment metadata.");
187
191
  validateWorkerOptions({ ...worker, enginePort: worker.port });
188
192
  return worker;
189
193
  }
@@ -202,6 +206,7 @@ function stopManagedTunnel(worker) {
202
206
  }
203
207
  async function stopWorker(backendId, suppliedRunner) {
204
208
  const worker = loadManagedWorker(backendId);
209
+ writeFileSync(join(homeStateDir(), "workers", `${backendId}.json`), JSON.stringify({ ...worker, autoReconnect: false }, null, 2) + "\n", { mode: 384 });
205
210
  const runner = suppliedRunner ?? createRunner(worker);
206
211
  runner.shell(`set -eu
207
212
  if test ! -f ${REMOTE_DIR}/engine.pid; then echo 'Managed engine PID is unavailable; engine was not stopped.' >&2; exit 1; fi
@@ -216,6 +221,64 @@ fi
216
221
  rm -f ${REMOTE_DIR}/engine.pid`, 3e4);
217
222
  return { stopped: true, tunnelStopped: stopManagedTunnel(worker), remoteFilesRemoved: false };
218
223
  }
224
+ async function repairWorker(backendId, suppliedRunner, probe = (port) => {
225
+ try {
226
+ execFileSync("curl", ["-sf", "--connect-timeout", "2", "--max-time", "3", `http://127.0.0.1:${port}/`], { stdio: "ignore" });
227
+ return true;
228
+ } catch {
229
+ return false;
230
+ }
231
+ }) {
232
+ const worker = loadManagedWorker(backendId);
233
+ const credential = readFileSync(join(homeStateDir(), "workers", `${backendId}.env`), "utf8").trim();
234
+ const match = /^(ZERO_WORKER_[A-F0-9]+_TOKEN)=([a-f0-9]{64})$/.exec(credential);
235
+ if (!match) throw new Error("Managed worker credential is unavailable. Deploy this host again.");
236
+ writeFileSync(join(homeStateDir(), "workers", `${backendId}.json`), JSON.stringify({ ...worker, autoReconnect: true }, null, 2) + "\n", { mode: 384 });
237
+ const runner = suppliedRunner ?? createRunner(worker);
238
+ const result = runner.shell(`set -eu
239
+ cd ${REMOTE_DIR}
240
+ test -f dist/0.js && test -d work || { echo 'Managed engine files are missing. Deploy this host again.' >&2; exit 1; }
241
+ command -v node >/dev/null || { echo 'Node is unavailable on this host.' >&2; exit 1; }
242
+ running=0
243
+ if test -f engine.pid; then
244
+ pid=$(cat engine.pid)
245
+ case "$pid" in ''|*[!0-9]*) echo 'Invalid managed engine PID.' >&2; exit 1;; esac
246
+ if test "$pid" -gt 1 && kill -0 "$pid" 2>/dev/null; then
247
+ test "$(readlink /proc/$pid/cwd)" = "${REMOTE_DIR}" || { echo 'Managed engine PID belongs to another process.' >&2; exit 1; }
248
+ command=$(tr '\\000' ' ' < /proc/$pid/cmdline)
249
+ case "$command" in 'node dist/0.js dashboard '*|'node /tmp/zero-engine/dist/0.js dashboard '*) running=1;; *) echo 'Managed engine PID does not match Zero.' >&2; exit 1;; esac
250
+ fi
251
+ fi
252
+ if test "$running" = 0; then
253
+ if ss -ltn 2>/dev/null | grep -q ':${worker.port} '; then echo 'Engine port is occupied. No process was replaced.' >&2; exit 1; fi
254
+ ZERO_WORKER_TOKEN=${match[2]} setsid nohup node dist/0.js dashboard --host 127.0.0.1 --port ${worker.port} --no-open --ready-json --engine-token-env ZERO_WORKER_TOKEN --engine-workspace ${REMOTE_DIR}/work > engine.log 2>&1 < /dev/null &
255
+ echo $! > engine.pid
256
+ echo ENGINE_STARTED
257
+ fi
258
+ for i in $(seq 1 20); do
259
+ if curl -sf --max-time 1 http://127.0.0.1:${worker.port}/ >/dev/null; then echo ENGINE_READY; exit 0; fi
260
+ sleep 1
261
+ done
262
+ echo 'Managed engine did not become ready.' >&2; exit 1`, 3e4);
263
+ if (!result.includes("ENGINE_READY")) throw new Error("Managed engine did not become ready.");
264
+ process.env[match[1]] = match[2];
265
+ if (!probe(worker.port)) {
266
+ stopManagedTunnel(worker);
267
+ const tunnelPid = runner.tunnel(worker.port);
268
+ if (!Number.isSafeInteger(tunnelPid) || tunnelPid <= 1) throw new Error("Could not start the SSH tunnel.");
269
+ writeFileSync(join(homeStateDir(), "workers", `${backendId}.json`), JSON.stringify({ ...loadManagedWorker(backendId), tunnelPid }, null, 2) + "\n", { mode: 384 });
270
+ let ready = false;
271
+ for (let attempt = 0; attempt < 12; attempt++) {
272
+ if (probe(worker.port)) {
273
+ ready = true;
274
+ break;
275
+ }
276
+ await new Promise((resolve2) => setTimeout(resolve2, 250));
277
+ }
278
+ if (!ready) throw new Error("Remote engine is ready, but its SSH tunnel could not reconnect.");
279
+ }
280
+ return { backendId, reconnected: true, engineStarted: result.includes("ENGINE_STARTED") };
281
+ }
219
282
 
220
283
  // packages/cli/src/web/backend-connections.ts
221
284
  import { randomUUID } from "node:crypto";
@@ -365,6 +428,9 @@ var BackendConnectionRegistry = class {
365
428
  #descriptors = /* @__PURE__ */ new Map();
366
429
  #pins = /* @__PURE__ */ new Map();
367
430
  #handshakes = /* @__PURE__ */ new Map();
431
+ // Bind the safe classification to the exact returned view, so concurrent
432
+ // reprobes cannot replace another caller's failure. No cause crosses the API.
433
+ #disconnectedStatuses = /* @__PURE__ */ new WeakMap();
368
434
  #pending = /* @__PURE__ */ new Map();
369
435
  #env;
370
436
  #fetch;
@@ -469,7 +535,7 @@ var BackendConnectionRegistry = class {
469
535
  delete descriptor.error;
470
536
  try {
471
537
  const response = await this.#send(row, "/api/backend/handshake", {});
472
- if (!response.ok) throw new BackendConnectionError("Backend handshake was rejected.", response.status === 401 || response.status === 403 ? 403 : 502);
538
+ if (!response.ok) throw new BackendConnectionError("Backend handshake was rejected.", response.status);
473
539
  const raw = BackendHandshakeSchema.parse(await response.json());
474
540
  descriptor.protocolVersion = raw.protocolVersion;
475
541
  if (raw.protocolVersion !== BACKEND_PROTOCOL_VERSION) {
@@ -489,7 +555,9 @@ var BackendConnectionRegistry = class {
489
555
  if (descriptor.status !== "incompatible") descriptor.status = "disconnected";
490
556
  descriptor.error = error instanceof BackendConnectionError ? error.message : "Backend connection failed.";
491
557
  this.#handshakes.delete(id);
492
- return { backend: structuredClone(descriptor), error: descriptor.error };
558
+ const backend = structuredClone(descriptor);
559
+ this.#disconnectedStatuses.set(backend, error instanceof BackendConnectionError ? error.statusCode : 502);
560
+ return { backend, error: descriptor.error };
493
561
  }
494
562
  }
495
563
  async request(id, path, options = {}) {
@@ -499,7 +567,7 @@ var BackendConnectionRegistry = class {
499
567
  const canonical = apiPath(path);
500
568
  const cached = this.#handshakes.get(id);
501
569
  const view = cached && Date.now() - cached.at < 5e3 ? { backend: this.#descriptors.get(id) } : await this.handshake(id);
502
- if (view.backend.status !== "connected") throw new BackendConnectionError(view.backend.error ?? "Backend is disconnected.", view.backend.status === "incompatible" ? 409 : 503);
570
+ if (view.backend.status !== "connected") throw new BackendConnectionError(view.backend.error ?? "Backend is disconnected.", this.#disconnectedStatuses.get(view.backend) ?? (view.backend.status === "incompatible" ? 409 : 503));
503
571
  for (const required of capabilities(canonical)) if (!view.backend.capabilities.includes(required)) throw new BackendConnectionError(`Backend does not support ${required}.`, 409);
504
572
  try {
505
573
  return await this.#send(row, canonical, options);
@@ -642,7 +710,7 @@ function json(res, status, value) {
642
710
  res.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
643
711
  res.end(JSON.stringify(value));
644
712
  }
645
- async function handleBackendConnectionRequest(req, res, url, registry) {
713
+ async function handleBackendConnectionRequest(req, res, url, registry, onSessionClosed) {
646
714
  if (url.pathname === "/api/backends") {
647
715
  if (req.method !== "GET") throw new BackendConnectionError("Backend registry is read-only.", 405);
648
716
  registry.reload();
@@ -670,6 +738,7 @@ async function handleBackendConnectionRequest(req, res, url, registry) {
670
738
  return { handled: true };
671
739
  }
672
740
  const path = apiPath(`${url.pathname.slice(url.pathname.indexOf("/proxy/") + "/proxy".length)}${url.search}`);
741
+ if (new URL(path, "http://backend.invalid").pathname.startsWith("/api/console/provider-relays")) throw new BackendConnectionError("Provider relay grants are managed by the local engine.", 403);
673
742
  if (id === "local") return { handled: false, localPath: path };
674
743
  const abort = new AbortController();
675
744
  const disconnect = () => abort.abort();
@@ -679,6 +748,8 @@ async function handleBackendConnectionRequest(req, res, url, registry) {
679
748
  const body = ["GET", "HEAD"].includes(req.method ?? "GET") ? void 0 : await requestJson(req);
680
749
  const stream = req.headers.accept?.includes("text/event-stream") === true;
681
750
  const response = await registry.request(id, path, { method: req.method, body, stream, signal: abort.signal, lastEventId: typeof req.headers["last-event-id"] === "string" ? req.headers["last-event-id"] : void 0, requestId: typeof req.headers["x-0-request-id"] === "string" ? req.headers["x-0-request-id"] : void 0 });
751
+ const closedSession = /^\/api\/console\/sessions\/([^/]+)(\/delete)?$/.exec(new URL(path, "http://backend.invalid").pathname);
752
+ if (response.ok && closedSession && (req.method === "DELETE" && !closedSession[2] || req.method === "POST" && closedSession[2])) await onSessionClosed?.(id, decodeURIComponent(closedSession[1]));
682
753
  if (res.destroyed) return { handled: true };
683
754
  res.writeHead(response.status, { "Content-Type": response.headers.get("content-type") ?? "application/json", ...attachmentHeaders(response.headers), "Cache-Control": "no-store", "X-0-Request-ID": response.headers.get("x-0-request-id") ?? randomUUID(), ...response.headers.get("x-0-engine-id") ? { "X-0-Engine-ID": response.headers.get("x-0-engine-id") } : {}, "X-Content-Type-Options": "nosniff", ...stream ? { "X-Accel-Buffering": "no" } : {} });
684
755
  if (!response.body) {
@@ -727,6 +798,7 @@ export {
727
798
  deployWorker,
728
799
  loadManagedWorker,
729
800
  stopWorker,
801
+ repairWorker,
730
802
  BackendConnectionError,
731
803
  loadBackendConnectionConfig,
732
804
  createBackendHandshake,
@@ -3,7 +3,7 @@ import { createRequire as __0CreateRequire } from "node:module";
3
3
  const require = __0CreateRequire(import.meta.url);
4
4
  import {
5
5
  createPresentationEvent
6
- } from "./chunk-GXXX7AGH.js";
6
+ } from "./chunk-GYEYTNHK.js";
7
7
 
8
8
  // packages/core/dist/events/bus.js
9
9
  function presentationEventSink(sink, options = {}) {