0sec-cli 0.23.0 → 0.24.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 (213) hide show
  1. package/0.js +66 -67
  2. package/README.md +37 -11
  3. package/chunks/{adapt-loop-V3JFWOKC.js → adapt-loop-TEJPXWFG.js} +4 -4
  4. package/chunks/{artifact-scraper-NYKUF2M5.js → artifact-scraper-AJZ3LOQY.js} +2 -2
  5. package/chunks/{assumption-mining-ZX3YVWEH.js → assumption-mining-EATDC4BB.js} +18 -18
  6. package/chunks/{backend-connections-H52NIVH2.js → backend-connections-QE4NASAK.js} +3 -3
  7. package/chunks/chunk-3XLEDCFX.js +566 -0
  8. package/chunks/{chunk-I3OCJ2OA.js → chunk-3XLFB46W.js} +5 -3
  9. package/chunks/{chunk-TPUJZ74W.js → chunk-4TUR47H5.js} +2 -2
  10. package/chunks/{chunk-3ZNI7F42.js → chunk-4YRXIVPZ.js} +3 -3
  11. package/chunks/{chunk-A5QO7N3S.js → chunk-52AWIBCT.js} +1 -1
  12. package/chunks/{chunk-TO35Y326.js → chunk-554D4AYM.js} +5 -2
  13. package/chunks/{chunk-KHPOSLCF.js → chunk-5FHFG5P2.js} +174 -710
  14. package/chunks/{chunk-LT7BFGXA.js → chunk-5POT5OYF.js} +10 -10
  15. package/chunks/chunk-62PGWN7Y.js +700 -0
  16. package/chunks/{chunk-EH2WTNY7.js → chunk-A3EKBUEM.js} +1424 -859
  17. package/chunks/{chunk-YYS2H33A.js → chunk-A6AZZ6XX.js} +2 -2
  18. package/chunks/{chunk-A2ADXAC5.js → chunk-AV5BF4V7.js} +1288 -2313
  19. package/chunks/{chunk-NI6QYQSK.js → chunk-BIJPMYFA.js} +6 -6
  20. package/chunks/{chunk-JEYIWMGL.js → chunk-CIMN2AO6.js} +1 -1
  21. package/chunks/{chunk-P7KDN5PK.js → chunk-CSPF47S3.js} +14 -14
  22. package/chunks/{chunk-F344NYUN.js → chunk-DNV3ZMPX.js} +1 -1
  23. package/chunks/{chunk-YAEJAZYW.js → chunk-E42XEJTK.js} +2 -2
  24. package/chunks/{chunk-VDOWARMJ.js → chunk-ESM447R6.js} +15 -1
  25. package/chunks/{chunk-UZUELPFW.js → chunk-EXTN4SQV.js} +1 -1
  26. package/chunks/{chunk-BF5FIK7H.js → chunk-EYBMTELO.js} +108 -24
  27. package/chunks/chunk-FEOPHBMY.js +56 -0
  28. package/chunks/{chunk-XORZUR2H.js → chunk-FKGFHLLS.js} +1 -1
  29. package/chunks/chunk-G2EJ3R5I.js +5198 -0
  30. package/chunks/chunk-GHEBZKUS.js +5417 -0
  31. package/chunks/chunk-GNR3APR6.js +295 -0
  32. package/chunks/{chunk-EJH2TNVH.js → chunk-H76JYUPE.js} +3 -3
  33. package/chunks/{chunk-WIYNYNL2.js → chunk-HRBOZBMC.js} +1 -1
  34. package/chunks/{chunk-62ENS6XO.js → chunk-IIBNQTOK.js} +3 -2
  35. package/chunks/{chunk-UELXHK2Y.js → chunk-IK27KMVV.js} +16 -5
  36. package/chunks/{chunk-O6Z4XPOM.js → chunk-J6G73WYF.js} +1 -1
  37. package/chunks/chunk-JSTLXPJS.js +284 -0
  38. package/chunks/{chunk-K55B4OH4.js → chunk-O3ADFN2A.js} +1 -1
  39. package/chunks/chunk-O7Q2G2KW.js +117 -0
  40. package/chunks/{chunk-HFDSIHTE.js → chunk-QEA2VHBD.js} +202 -30
  41. package/chunks/{chunk-ITES7BCY.js → chunk-RBOMXUYL.js} +3 -111
  42. package/chunks/{chunk-T7ZEVY5G.js → chunk-RCHAFSWS.js} +815 -41
  43. package/chunks/{chunk-W5VNCB57.js → chunk-RD4FKFWR.js} +1 -1
  44. package/chunks/{chunk-LVGZGG63.js → chunk-RPTO5FY2.js} +1 -1
  45. package/chunks/{chunk-LTEE2JWK.js → chunk-RZR2XXAK.js} +251 -8
  46. package/chunks/chunk-SGILXLR3.js +289 -0
  47. package/chunks/{chunk-QMICC5O2.js → chunk-TOAAYJVN.js} +2 -2
  48. package/chunks/{chunk-PIR6BNE7.js → chunk-TOFIGQ63.js} +2 -2
  49. package/chunks/{chunk-V2BWXPZP.js → chunk-TTDFBFNZ.js} +6 -6
  50. package/chunks/{chunk-WYNZFNMF.js → chunk-TZRHWP7R.js} +289 -10
  51. package/chunks/chunk-UHUW45S3.js +164 -0
  52. package/chunks/{chunk-NX4H6L4M.js → chunk-V4BD7GSP.js} +2 -2
  53. package/chunks/{chunk-4HGGNBKK.js → chunk-V5I5GAQH.js} +2593 -1563
  54. package/chunks/{chunk-MQJVU2GZ.js → chunk-W6IYTSZH.js} +79 -9
  55. package/chunks/{chunk-OLSKXTQZ.js → chunk-WUPN3D37.js} +22 -248
  56. package/chunks/{chunk-AAA4PRWK.js → chunk-Y7KV7WV6.js} +2 -2
  57. package/chunks/{chunk-Y4HJRUFE.js → chunk-YERUDEXT.js} +876 -817
  58. package/chunks/{chunk-65H3MRBF.js → chunk-YJU7QACE.js} +1 -1
  59. package/chunks/{chunk-3E54JYS4.js → chunk-YORL5S5V.js} +1 -1
  60. package/chunks/{chunk-CP6HANBE.js → chunk-YYOQADBB.js} +4 -3
  61. package/chunks/{remote-workflow-runtime-RGQ5ECMN.js → chunk-ZPFBQ3SD.js} +39 -8
  62. package/chunks/{codex-models-Y457ND6Q.js → codex-models-FQPCWRPC.js} +7 -7
  63. package/chunks/{commands-PBDAOZKA.js → commands-I5L3VD2A.js} +1603 -6945
  64. package/chunks/dashboard-B2AEGCFM.js +76 -0
  65. package/chunks/{db-TPSI552V.js → db-P5EIKMLP.js} +3 -3
  66. package/chunks/{deep-review-DKED6EN5.js → deep-review-I7RD5QSS.js} +34 -33
  67. package/chunks/{disclose-LDNKAVRH.js → disclose-PFBWESVJ.js} +4 -2
  68. package/chunks/{dist-7Q5A6TQM.js → dist-3SWWY5FZ.js} +18 -2
  69. package/chunks/{dist-4LGRIBOC.js → dist-AJU25UXA.js} +99 -64
  70. package/chunks/{dist-RLPNLRZD.js → dist-VK2M4HNW.js} +33 -1
  71. package/chunks/eval-runner-XVRX3R2Y.js +31 -0
  72. package/chunks/{exploit-agent-RMFYNG7H.js → exploit-agent-A4RTIJ4J.js} +1 -1
  73. package/chunks/{exploit-autoclimb-2A2PQI4E.js → exploit-autoclimb-ABMMBC3M.js} +1 -1
  74. package/chunks/{exploit-climb-DEJ232QN.js → exploit-climb-BQ2SVU63.js} +2 -2
  75. package/chunks/{fix-JGBW7XUN.js → fix-4YCLHFDT.js} +7 -7
  76. package/chunks/{harness-CBOLMUHB.js → harness-DHWULEIZ.js} +3 -3
  77. package/chunks/{hunt-scan-MIRMABY4.js → hunt-scan-DXV5H6YN.js} +16 -16
  78. package/chunks/{kernel-primitive-NAPDMJC7.js → kernel-primitive-SF4NALVR.js} +2 -2
  79. package/chunks/{kernel-vm-runner-PR5OSDQ2.js → kernel-vm-runner-WEBEZEIC.js} +2 -2
  80. package/chunks/local-engine-XUG7XRKM.js +21 -0
  81. package/chunks/managed-operation-SQFMBWHG.js +60 -0
  82. package/chunks/{memsafety-scan-RPS446CD.js → memsafety-scan-L2Z7E7TE.js} +2 -2
  83. package/chunks/{native-loop-CGOJMNHV.js → native-loop-ZNAELJGB.js} +14 -13
  84. package/chunks/orchestrate-YHFJXGID.js +63 -0
  85. package/chunks/{prepare-YVNENPNL.js → prepare-SODWQN6O.js} +5 -5
  86. package/chunks/provider-model-discovery-QGUGL3XW.js +277 -0
  87. package/chunks/remote-workflow-runtime-XNNGI2PG.js +12 -0
  88. package/chunks/{run-VH4OIDKF.js → run-5T4Z3Q2D.js} +902 -322
  89. package/chunks/{runtime-4TAJFVF7.js → runtime-HFFRUOPL.js} +2 -2
  90. package/chunks/{runtime-HWL6HG7A.js → runtime-MB4GEFBY.js} +7 -7
  91. package/chunks/{scan-stream-HJAZJONE.js → scan-stream-GXBJHCDF.js} +3 -2
  92. package/chunks/{scope-Q5PIX2IS.js → scope-M7L3CD6X.js} +2 -2
  93. package/chunks/service-plugins-BGS6QKSZ.js +64 -0
  94. package/chunks/{session-store-2FEIZGSV.js → session-store-K7I4GLNH.js} +2 -2
  95. package/chunks/{variant-candidates-TX5V6XOT.js → variant-candidates-2KSP5EHH.js} +7 -7
  96. package/chunks/{web-recon-prepass-6HOUGF7Q.js → web-recon-prepass-RAXXTEWH.js} +5 -5
  97. package/chunks/workflow-runtime-V26HIJO3.js +178 -0
  98. package/dashboard/assets/{abnfDiagram-VCTEODGH-BuvumFYR.js → abnfDiagram-VCTEODGH-CGCueOp5.js} +1 -1
  99. package/dashboard/assets/{arc-DZzWDuCG.js → arc-BjZaQcCc.js} +1 -1
  100. package/dashboard/assets/architecture-7GRP2DOG-hcbO-9zX.js +1 -0
  101. package/dashboard/assets/{architectureDiagram-5GKGNRK7-Bw5el_EL.js → architectureDiagram-5GKGNRK7-DReOXTSq.js} +1 -1
  102. package/dashboard/assets/{blockDiagram-I7D4REHJ-BjVLEApp.js → blockDiagram-I7D4REHJ-C-byT12_.js} +1 -1
  103. package/dashboard/assets/{c4Diagram-7LVT6UL2-B9nNzx2J.js → c4Diagram-7LVT6UL2-DoYjz-Uv.js} +1 -1
  104. package/dashboard/assets/channel-CUURBnpZ.js +1 -0
  105. package/dashboard/assets/{chunk-4HAMMTFA-y72Q95nW.js → chunk-4HAMMTFA-NBNp2zdt.js} +1 -1
  106. package/dashboard/assets/{chunk-75Z2AOVW-BOhrOGMO.js → chunk-75Z2AOVW-BHmkuP0B.js} +1 -1
  107. package/dashboard/assets/{chunk-DU6HZSFF-B0EhAaNb.js → chunk-DU6HZSFF-DgfLNaL2.js} +2 -2
  108. package/dashboard/assets/{chunk-F27PBJKO-BR-hiDvM.js → chunk-F27PBJKO-3wwNFUgZ.js} +1 -1
  109. package/dashboard/assets/{chunk-GMAD6QVW-H15vJYXg.js → chunk-GMAD6QVW-Btg7huZW.js} +1 -1
  110. package/dashboard/assets/{chunk-GVQU2GXP-BRndps0o.js → chunk-GVQU2GXP-ihCURK5O.js} +1 -1
  111. package/dashboard/assets/{chunk-IMKFNOWR-CIzC_OWx.js → chunk-IMKFNOWR-FsXj7slg.js} +1 -1
  112. package/dashboard/assets/{chunk-L3NEJ4N5-NR4P1Vko.js → chunk-L3NEJ4N5-DorFIxJY.js} +1 -1
  113. package/dashboard/assets/{chunk-OSK3NFVY-DtjTDf8S.js → chunk-OSK3NFVY-DKun_KfC.js} +1 -1
  114. package/dashboard/assets/{chunk-P2QGCYS3-CYT11Qjx.js → chunk-P2QGCYS3-XGgiU1Bz.js} +1 -1
  115. package/dashboard/assets/{chunk-POPQ4Y6H-Duj2Ygwu.js → chunk-POPQ4Y6H-BTXEnGhJ.js} +1 -1
  116. package/dashboard/assets/{chunk-PWAF6VOD-z4p5Tf_y.js → chunk-PWAF6VOD-DYZcGkTL.js} +1 -1
  117. package/dashboard/assets/{chunk-SHT3W25Y-DYeLYLS3.js → chunk-SHT3W25Y-C4WQfwf8.js} +1 -1
  118. package/dashboard/assets/{chunk-SVP7TREG-BKowxCVI.js → chunk-SVP7TREG-C4nCh0-1.js} +1 -1
  119. package/dashboard/assets/{chunk-TICWLB2K-GDAwEFlH.js → chunk-TICWLB2K-DSB-IiGc.js} +1 -1
  120. package/dashboard/assets/{chunk-XXDRQBXY-DRD79Mjx.js → chunk-XXDRQBXY-CS6fjUcj.js} +1 -1
  121. package/dashboard/assets/classDiagram-ZZMXUADV-CD1Buc26.js +1 -0
  122. package/dashboard/assets/classDiagram-v2-VYDZK3BY-CD1Buc26.js +1 -0
  123. package/dashboard/assets/{common-vnzd7UOF.js → common-BMdQBwfR.js} +1 -1
  124. package/dashboard/assets/{cose-bilkent-JH36ORCC-GqCLsRyf.js → cose-bilkent-JH36ORCC-CUjQHTML.js} +1 -1
  125. package/dashboard/assets/{cynefin-OW5HDTMX-CJN9YwWN.js → cynefin-OW5HDTMX-BC7zCtFq.js} +1 -1
  126. package/dashboard/assets/{cynefinDiagram-5FMLGOSQ-DVJHCYQY.js → cynefinDiagram-5FMLGOSQ-CgDOOY67.js} +1 -1
  127. package/dashboard/assets/{dagre-GXQ25YYZ-BMCrrJJR.js → dagre-GXQ25YYZ-Dqc8FS9x.js} +1 -1
  128. package/dashboard/assets/{diagram-S7CK7UJ4-CLYDdOEm.js → diagram-S7CK7UJ4-CrKqRXZb.js} +1 -1
  129. package/dashboard/assets/{diagram-UQ7AKVKN-CnPuAZK7.js → diagram-UQ7AKVKN-Cu6Es0-v.js} +1 -1
  130. package/dashboard/assets/{diagram-VSXAHHWV-Cr2I2DnG.js → diagram-VSXAHHWV-eK4d8FwS.js} +1 -1
  131. package/dashboard/assets/{diagram-VX7I27RA-_mGW1wpp.js → diagram-VX7I27RA-bFxeFKOc.js} +1 -1
  132. package/dashboard/assets/{diagram-Z3DM3KII-igybB0l9.js → diagram-Z3DM3KII-C0ClmnhC.js} +1 -1
  133. package/dashboard/assets/{dist-Bb7_-x5y.js → dist-BZh8Kb3O.js} +1 -1
  134. package/dashboard/assets/{ebnfDiagram-PWID7BFC-CVCICf2R.js → ebnfDiagram-PWID7BFC-CUqxFPzf.js} +1 -1
  135. package/dashboard/assets/{erDiagram-RLTQ6QDP-CRjnfgxj.js → erDiagram-RLTQ6QDP-CcYM7pLi.js} +1 -1
  136. package/dashboard/assets/eventmodeling-NTZA5JFV-D8ZNnPkV.js +1 -0
  137. package/dashboard/assets/flowDiagram-HODETNUW-pDb1AYm8.js +1 -0
  138. package/dashboard/assets/{ganttDiagram-EL5Y4UJY-DppD7sD7.js → ganttDiagram-EL5Y4UJY-UmZfbMyD.js} +1 -1
  139. package/dashboard/assets/{gitGraph-4MIJSDKK-Tw0vNnQc.js → gitGraph-4MIJSDKK-mvNUo0ZA.js} +1 -1
  140. package/dashboard/assets/{gitGraphDiagram-WWUBYQGX-Cpf96-z3.js → gitGraphDiagram-WWUBYQGX-CvzeCxVy.js} +1 -1
  141. package/dashboard/assets/{info-A6RAGUB7-DLyt9arx.js → info-A6RAGUB7-DChKqZMi.js} +1 -1
  142. package/dashboard/assets/{infoDiagram-27XIBGKW-B6_piSNS.js → infoDiagram-27XIBGKW-DjkpNtVW.js} +1 -1
  143. package/dashboard/assets/{ishikawaDiagram-5VMMS53U-DvMO0B0X.js → ishikawaDiagram-5VMMS53U-8FhjJaWT.js} +1 -1
  144. package/dashboard/assets/{journeyDiagram-3NMN7TZE-f7ZK98b6.js → journeyDiagram-3NMN7TZE-DyNJ755f.js} +1 -1
  145. package/dashboard/assets/{kanban-definition-UXKFOSKX-Dso0nAxL.js → kanban-definition-UXKFOSKX-_jCmtaY1.js} +1 -1
  146. package/dashboard/assets/katex-BdBmVSus.js +257 -0
  147. package/dashboard/assets/{line-VcKaFG0G.js → line-Bf0nxyWf.js} +1 -1
  148. package/dashboard/assets/{linear-D7YnpiWh.js → linear-Bl6JKbf4.js} +1 -1
  149. package/dashboard/assets/{mermaid-parser.core-DriL2hrV.js → mermaid-parser.core-Cc6sgCzs.js} +3 -3
  150. package/dashboard/assets/{mermaid.core-DJWYDh_P.js → mermaid.core-B4yCwiN-.js} +4 -4
  151. package/dashboard/assets/{mindmap-definition-YA3MSWOX-DZsoIeac.js → mindmap-definition-YA3MSWOX-D5DjWyXj.js} +1 -1
  152. package/dashboard/assets/operations-B7JAWOi6.js +130 -0
  153. package/dashboard/assets/operations-QjKT0Hwi.css +1 -0
  154. package/dashboard/assets/{packet-AYTQ26CC-BQBIXKxk.js → packet-AYTQ26CC-bQXLDhQC.js} +1 -1
  155. package/dashboard/assets/{pegDiagram-XKGWAZYB-B0-lslgW.js → pegDiagram-XKGWAZYB-Bf6a1vaf.js} +1 -1
  156. package/dashboard/assets/{pie-WAS4IAKB-DoY6dwQs.js → pie-WAS4IAKB-DfzoABIi.js} +1 -1
  157. package/dashboard/assets/{pieDiagram-E7YTZNPT-ElmdRjp5.js → pieDiagram-E7YTZNPT-D0L1qbch.js} +1 -1
  158. package/dashboard/assets/{quadrantDiagram-AXDQQJYC-Ci1h98Q2.js → quadrantDiagram-AXDQQJYC-CbFyy2Pe.js} +1 -1
  159. package/dashboard/assets/{radar-RG4KPBEZ-DHod2WgB.js → radar-RG4KPBEZ-CZ2pyeUT.js} +1 -1
  160. package/dashboard/assets/{railroad-74A4TZTK-90JxB4xV.js → railroad-74A4TZTK-CP4Jazfd.js} +1 -1
  161. package/dashboard/assets/railroad-abnf-HS5TGJTU-3MvEiHwD.js +1 -0
  162. package/dashboard/assets/railroad-ebnf-LZEXJU2U-BWto6cXE.js +1 -0
  163. package/dashboard/assets/railroad-peg-WCYAUIDC-DasEjbyf.js +1 -0
  164. package/dashboard/assets/{railroadDiagram-O6MQD6OU-k3190A6L.js → railroadDiagram-O6MQD6OU-t7Gp9g2R.js} +1 -1
  165. package/dashboard/assets/{requirementDiagram-BXWQKSXE-C3-eR7I5.js → requirementDiagram-BXWQKSXE-LYmqeBXi.js} +1 -1
  166. package/dashboard/assets/{sankeyDiagram-P5KCCOFB-Bc86pi8w.js → sankeyDiagram-P5KCCOFB-DnpfA_94.js} +1 -1
  167. package/dashboard/assets/{sequenceDiagram-WJ2MYXX4-Bv_MvEmz.js → sequenceDiagram-WJ2MYXX4-C8s3pTUE.js} +1 -1
  168. package/dashboard/assets/{src-D7Dqq5yP.js → src-CaNUT1AQ.js} +1 -1
  169. package/dashboard/assets/{stateDiagram-D77RDMKH-Bq_GVmeW.js → stateDiagram-D77RDMKH-BMzm6fK1.js} +1 -1
  170. package/dashboard/assets/stateDiagram-v2-MP3YSRHH-B3REMjpY.js +1 -0
  171. package/dashboard/assets/{swimlanes-42K2YHIH-q0iK-e0P.js → swimlanes-42K2YHIH-uJE05Tt_.js} +1 -1
  172. package/dashboard/assets/swimlanesDiagram-VR7AAH4N-CIaVMZEy.js +8 -0
  173. package/dashboard/assets/{timeline-definition-24CTP7MA-CNfF07hM.js → timeline-definition-24CTP7MA-BfLJMVeG.js} +1 -1
  174. package/dashboard/assets/{treeView-Q6P3EWNA-m629ePnS.js → treeView-Q6P3EWNA-ZOE2enu2.js} +1 -1
  175. package/dashboard/assets/{treemap-WGGIJYW6-D9Cb2ETv.js → treemap-WGGIJYW6-yIZoPBF5.js} +1 -1
  176. package/dashboard/assets/{vennDiagram-4TSXK5OY-v4dKF-FE.js → vennDiagram-4TSXK5OY-BYJRHEaL.js} +1 -1
  177. package/dashboard/assets/{wardley-WFR3VGLG-DkwH_nRe.js → wardley-WFR3VGLG-D5V-jLbB.js} +1 -1
  178. package/dashboard/assets/{wardleyDiagram-VM6X3IG4-3ImohVu4.js → wardleyDiagram-VM6X3IG4-DgPN4nSe.js} +1 -1
  179. package/dashboard/assets/{xychartDiagram-S5SC5T6Z-QJu3dm7K.js → xychartDiagram-S5SC5T6Z-BhkAMAOT.js} +1 -1
  180. package/dashboard/index.html +3 -3
  181. package/package.json +3 -2
  182. package/worker-assets/demo-target/README.md +15 -0
  183. package/worker-assets/demo-target/include/decoder.h +27 -0
  184. package/worker-assets/demo-target/patched-decoder.c +40 -0
  185. package/worker-assets/demo-target/src/decoder.c +50 -0
  186. package/worker-assets/demo-target/witness-65537x1.bin +0 -0
  187. package/chunks/chunk-3P3XXSIJ.js +0 -463
  188. package/chunks/chunk-EWXOG6D3.js +0 -1695
  189. package/chunks/chunk-FXR3BT2G.js +0 -226
  190. package/chunks/chunk-R35KKJA4.js +0 -90
  191. package/chunks/eval-runner-RZKDOQ2G.js +0 -30
  192. package/chunks/managed-operation-YNQQEA5V.js +0 -59
  193. package/chunks/orchestrate-5NK34H3W.js +0 -62
  194. package/chunks/service-plugins-QYFITODK.js +0 -63
  195. package/chunks/workflow-runtime-ZEEBJFQG.js +0 -64
  196. package/dashboard/assets/architecture-7GRP2DOG-DK9bv1Md.js +0 -1
  197. package/dashboard/assets/channel-Ck17eKdX.js +0 -1
  198. package/dashboard/assets/classDiagram-ZZMXUADV-BaeZA6LE.js +0 -1
  199. package/dashboard/assets/classDiagram-v2-VYDZK3BY-BaeZA6LE.js +0 -1
  200. package/dashboard/assets/eventmodeling-NTZA5JFV-po5oDydv.js +0 -1
  201. package/dashboard/assets/flowDiagram-HODETNUW-TSV9s7q4.js +0 -1
  202. package/dashboard/assets/katex-CXMH3UgJ.js +0 -257
  203. package/dashboard/assets/operations-BIaUSnYv.js +0 -121
  204. package/dashboard/assets/operations-BeCdkT4S.css +0 -1
  205. package/dashboard/assets/railroad-abnf-HS5TGJTU-BkXGl114.js +0 -1
  206. package/dashboard/assets/railroad-ebnf-LZEXJU2U-QVAERn2C.js +0 -1
  207. package/dashboard/assets/railroad-peg-WCYAUIDC-B1-PM01z.js +0 -1
  208. package/dashboard/assets/stateDiagram-v2-MP3YSRHH-z1XRaftz.js +0 -1
  209. package/dashboard/assets/swimlanesDiagram-VR7AAH4N-C9L6XBQj.js +0 -8
  210. package/dashboard/assets/zero-connect-BGDY0PMZ.webp +0 -0
  211. package/dashboard/assets/zero-curious-DovTLOs8.webp +0 -0
  212. package/dashboard/assets/zero-peek-Dzm3MT3X.png +0 -0
  213. package/dashboard/assets/zero-planning-CBeHDrG_.webp +0 -0
@@ -3,10 +3,10 @@ import { createRequire as __0CreateRequire } from "node:module";
3
3
  const require = __0CreateRequire(import.meta.url);
4
4
  import {
5
5
  executeWorkflow
6
- } from "./chunk-4HGGNBKK.js";
6
+ } from "./chunk-V5I5GAQH.js";
7
7
  import {
8
8
  SecurityWorkflowStore
9
- } from "./chunk-T7ZEVY5G.js";
9
+ } from "./chunk-RCHAFSWS.js";
10
10
 
11
11
  // packages/cli/src/managed-operation.ts
12
12
  async function executeManagedOperation(options, dependencies = { store: (path) => new SecurityWorkflowStore(path) }) {
@@ -6,22 +6,22 @@ import {
6
6
  } from "./chunk-HLFS6WV2.js";
7
7
  import {
8
8
  agenticScan
9
- } from "./chunk-4HGGNBKK.js";
9
+ } from "./chunk-V5I5GAQH.js";
10
10
  import {
11
11
  runAgentLoop
12
- } from "./chunk-P7KDN5PK.js";
12
+ } from "./chunk-CSPF47S3.js";
13
13
  import {
14
14
  getToolsForRole
15
- } from "./chunk-EH2WTNY7.js";
15
+ } from "./chunk-A3EKBUEM.js";
16
16
  import {
17
17
  createRuntime
18
- } from "./chunk-UZUELPFW.js";
18
+ } from "./chunk-EXTN4SQV.js";
19
19
  import {
20
20
  osecDB
21
- } from "./chunk-T7ZEVY5G.js";
21
+ } from "./chunk-RCHAFSWS.js";
22
22
  import {
23
23
  LlmApiRuntime
24
- } from "./chunk-BF5FIK7H.js";
24
+ } from "./chunk-EYBMTELO.js";
25
25
 
26
26
  // packages/cli/src/commands/orchestrate.ts
27
27
  import { randomUUID } from "node:crypto";
@@ -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-T7ZEVY5G.js";
6
+ } from "./chunk-RCHAFSWS.js";
7
7
  import {
8
8
  BACKEND_PROTOCOL_VERSION,
9
9
  BackendDescriptorSchema,
@@ -12,15 +12,215 @@ import {
12
12
  backendCapabilitiesForApiPath,
13
13
  homeStateDir,
14
14
  parseBackendHandshake
15
- } from "./chunk-LTEE2JWK.js";
15
+ } from "./chunk-RZR2XXAK.js";
16
16
  import {
17
17
  external_exports
18
18
  } from "./chunk-VIT5ALXF.js";
19
19
 
20
+ // packages/cli/src/worker-deploy.ts
21
+ import { execFileSync, spawn, spawnSync } from "node:child_process";
22
+ import { createHash, randomBytes } from "node:crypto";
23
+ import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
24
+ import { dirname, join } from "node:path";
25
+ import { tmpdir } from "node:os";
26
+ import { fileURLToPath } from "node:url";
27
+ var REMOTE_DIR = "/tmp/zero-engine";
28
+ var REMOTE_DEPS = {
29
+ "drizzle-orm": "^0.45.2",
30
+ "node-sqlite3-wasm": "^0.8.55",
31
+ "pdfkit": "^0.15.2",
32
+ "playwright": "1.60.0",
33
+ "react": "^19.2.4",
34
+ "react-dom": "^19.2.4",
35
+ "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"
39
+ };
40
+ var SSH_HOST_PATTERN = /^[A-Za-z0-9._@-]+$/;
41
+ var LIMA_NAME_PATTERN = /^[\w.-]+$/;
42
+ var TARGET_GIT_PATTERN = /^[A-Za-z][A-Za-z0-9+.-]*:\/\/[^\s'"]+$/;
43
+ var sq = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
44
+ function resolveWorkerRepoRoot(moduleUrl = import.meta.url) {
45
+ let directory = dirname(fileURLToPath(moduleUrl));
46
+ while (true) {
47
+ if ((existsSync(join(directory, "dist/0.js")) || existsSync(join(directory, "0.js"))) && existsSync(join(directory, "vendor/tree-sitter-0.21.1-node24.tgz"))) return directory;
48
+ const parent = dirname(directory);
49
+ if (parent === directory) throw new Error("Worker deployment requires the built CLI dist/ and vendor/ assets. Run pnpm build first.");
50
+ directory = parent;
51
+ }
52
+ }
53
+ function validateWorkerOptions(options) {
54
+ if (options.enginePort !== void 0 && (!Number.isInteger(options.enginePort) || options.enginePort < 1 || options.enginePort > 65535)) throw new Error("enginePort must be 1-65535");
55
+ if (options.ssh && (!SSH_HOST_PATTERN.test(options.ssh) || options.ssh.startsWith("-"))) {
56
+ throw new Error("--ssh must be an OpenSSH host name or user@host (no options or shell characters)");
57
+ }
58
+ if (options.lima && !LIMA_NAME_PATTERN.test(options.lima)) throw new Error("--lima must be an instance name (letters, digits, ., _, -)");
59
+ if (options.targetGit && !TARGET_GIT_PATTERN.test(options.targetGit)) throw new Error("--target-git must be a URL without whitespace or quotes");
60
+ }
61
+ function createRunner(options) {
62
+ if (options.ssh) {
63
+ const host = options.ssh;
64
+ const configArgs = options.sshConfig ? ["-F", options.sshConfig] : [];
65
+ return {
66
+ label: host,
67
+ shell: (command, timeout = 3e5) => execFileSync("ssh", ["-o", "BatchMode=yes", "-o", "ConnectTimeout=15", ...configArgs, "--", host, "bash", "-s"], { input: command, encoding: "utf8", timeout }),
68
+ copy: (local, remote) => execFileSync("scp", ["-q", "-o", "BatchMode=yes", ...configArgs, "--", local, `${host}:${remote}`], { stdio: "inherit", timeout: 6e5 }),
69
+ tunnel: (port) => {
70
+ const child = spawn("ssh", ["-o", "BatchMode=yes", ...configArgs, "-N", "-L", `${port}:127.0.0.1:${port}`, "--", host], { stdio: "ignore", detached: true });
71
+ child.unref();
72
+ return child.pid;
73
+ }
74
+ };
75
+ }
76
+ const vm = options.lima ?? "zero-worker";
77
+ return {
78
+ label: vm,
79
+ shell: (command, timeout = 3e5) => execFileSync("limactl", ["shell", vm, "--", "bash", "-s"], { input: command, encoding: "utf8", timeout }),
80
+ copy: (local, remote) => execFileSync("limactl", ["copy", local, `${vm}:${remote}`], { stdio: "inherit", timeout: 6e5 }),
81
+ tunnel: (port) => {
82
+ const configPath = "/tmp/zero-worker-ssh.conf";
83
+ writeFileSync(configPath, execFileSync("limactl", ["show-ssh", "--format", "config", vm], { encoding: "utf8" }), { mode: 384 });
84
+ const child = spawn("ssh", ["-F", configPath, "-N", "-L", `${port}:127.0.0.1:${port}`, `lima-${vm}`], { stdio: "ignore", detached: true });
85
+ child.unref();
86
+ return child.pid;
87
+ }
88
+ };
89
+ }
90
+ async function deployWorker(options, runner = createRunner(options)) {
91
+ validateWorkerOptions(options);
92
+ const repoRoot = options.repoRoot ?? resolveWorkerRepoRoot();
93
+ const port = options.enginePort ?? 2e4 + Number.parseInt(createHash("sha256").update(runner.label).digest("hex").slice(0, 4), 16) % 2e4;
94
+ const token = createHash("sha256").update(randomBytes(32)).digest("hex");
95
+ const identity = createHash("sha256").update(`${options.ssh ? "ssh" : "lima"}:${runner.label}`).digest("hex").slice(0, 12);
96
+ const backendId = `${options.ssh ? "ssh" : "lima"}-worker-${identity}`;
97
+ const tokenEnv = `ZERO_WORKER_${identity.toUpperCase()}_TOKEN`;
98
+ const { shell } = runner;
99
+ if (!options.ssh) {
100
+ const status = execFileSync("limactl", ["list", "--format", "{{.Status}}", runner.label], { encoding: "utf8" }).trim();
101
+ if (status !== "Running") throw new Error(`VM ${runner.label} is ${status}; start it first`);
102
+ }
103
+ shell("uname -srm");
104
+ const nodeVersion = shell("command -v node >/dev/null && node --version || echo none").trim();
105
+ if (!(nodeVersion.startsWith("v2") && Number(nodeVersion.slice(1).split(".")[0]) >= 24)) {
106
+ const arch = shell("uname -m").trim() === "aarch64" ? "arm64" : "x64";
107
+ shell(`cd /tmp && curl -fsSL https://nodejs.org/dist/v24.14.0/node-v24.14.0-linux-${arch}.tar.xz -o node.tar.xz && sudo tar -xJf node.tar.xz -C /usr/local --strip-components=1 && node --version`, 6e5);
108
+ }
109
+ const clangVersion = shell("command -v clang >/dev/null && clang --version | head -1 || echo none").trim();
110
+ if (clangVersion === "none") {
111
+ shell("sudo apt-get update -qq && sudo apt-get install -y -qq clang build-essential python3 >/dev/null && clang --version | head -1", 9e5);
112
+ }
113
+ const staging = mkdtempSync(join(tmpdir(), "zero-worker-"));
114
+ try {
115
+ const bundleRoot = existsSync(join(repoRoot, "dist/0.js")) ? repoRoot : staging;
116
+ if (bundleRoot === staging) {
117
+ mkdirSync(join(staging, "dist"));
118
+ for (const asset of ["0.js", "cli-path-traversal-fixture.js", "chunks", "attacks", "dashboard", "worker-assets"]) {
119
+ if (existsSync(join(repoRoot, asset))) cpSync(join(repoRoot, asset), join(staging, "dist", asset), { recursive: true });
120
+ }
121
+ }
122
+ 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");
124
+ 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
+ shell(`for entry in /proc/[0-9]*/cwd; do
126
+ test "$(readlink "$entry" 2>/dev/null)" = "${REMOTE_DIR}" || continue
127
+ pid=$(echo "$entry" | cut -d/ -f3)
128
+ command=$(tr '\\000' ' ' < /proc/$pid/cmdline 2>/dev/null) || continue
129
+ case "$command" in 'node dist/0.js dashboard '*|'node /tmp/zero-engine/dist/0.js dashboard '*) kill "$pid" || true;; esac
130
+ done`);
131
+ shell(`rm -rf ${REMOTE_DIR} && mkdir -p ${REMOTE_DIR}/vendor`);
132
+ runner.copy(join(staging, "bundle.tar.gz"), `${REMOTE_DIR}/bundle.tar.gz`);
133
+ if (!options.targetGit) runner.copy(join(staging, "demo-target.tar.gz"), `${REMOTE_DIR}/demo-target.tar.gz`);
134
+ runner.copy(join(repoRoot, "vendor/tree-sitter-0.21.1-node24.tgz"), `${REMOTE_DIR}/vendor/tree-sitter-0.21.1-node24.tgz`);
135
+ shell(`cd ${REMOTE_DIR} && tar -xzf bundle.tar.gz && ${options.targetGit ? "ls dist/0.js" : "tar -xzf demo-target.tar.gz && ls dist/0.js demo-target/src/decoder.c"}`);
136
+ writeFileSync(join(staging, "package.json"), JSON.stringify({ name: "zero-engine-remote", private: true, dependencies: REMOTE_DEPS }, null, 2));
137
+ runner.copy(join(staging, "package.json"), `${REMOTE_DIR}/package.json`);
138
+ shell(`cd ${REMOTE_DIR} && PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --omit=dev --no-audit --no-fund > install.log 2>&1 || { tail -20 install.log; exit 1; }`, 9e5);
139
+ let targetPath;
140
+ if (options.targetGit) {
141
+ shell(`rm -rf ${REMOTE_DIR}/work && mkdir -p ${REMOTE_DIR}/work && git clone --depth 1 ${sq(options.targetGit)} ${REMOTE_DIR}/work/target`, 9e5);
142
+ targetPath = `${REMOTE_DIR}/work/target`;
143
+ } else {
144
+ shell(`rm -rf ${REMOTE_DIR}/work && mkdir -p ${REMOTE_DIR}/work && cp -R ${REMOTE_DIR}/demo-target ${REMOTE_DIR}/work/demo-target`);
145
+ targetPath = `${REMOTE_DIR}/work/demo-target`;
146
+ }
147
+ const providerEnv = options.forwardProviderKey && process.env.OPENAI_API_KEY ? `OPENAI_API_KEY=${sq(process.env.OPENAI_API_KEY)} ` : "";
148
+ try {
149
+ shell(`cd ${REMOTE_DIR} || exit 1; ${providerEnv}ZERO_WORKER_TOKEN=${token} setsid nohup node dist/0.js dashboard --host 127.0.0.1 --port ${port} --no-open --ready-json --engine-token-env ZERO_WORKER_TOKEN --engine-workspace ${REMOTE_DIR}/work > engine.log 2>&1 < /dev/null & echo $! > ${REMOTE_DIR}/engine.pid; echo started`, 3e4);
150
+ } catch {
151
+ }
152
+ const ready = shell(`for i in $(seq 1 30); do grep -q ZERO_DASHBOARD_READY ${REMOTE_DIR}/engine.log 2>/dev/null && echo ready && break; sleep 1; done; tail -2 ${REMOTE_DIR}/engine.log`, 6e4);
153
+ if (!ready.includes("ready")) throw new Error(`engine did not become ready: ${ready.trim()}`);
154
+ const tunnelPid = runner.tunnel(port);
155
+ const tunnelReady = Promise.withResolvers();
156
+ setTimeout(tunnelReady.resolve, 2e3);
157
+ await tunnelReady.promise;
158
+ execFileSync("curl", ["-sf", `http://127.0.0.1:${port}/`], { stdio: "ignore" });
159
+ const stateDir = join(homeStateDir(), "workers");
160
+ mkdirSync(stateDir, { recursive: true, mode: 448 });
161
+ const backendsConfig = options.backendsConfig ?? join(homeStateDir(), "backends.json");
162
+ let registry = { schemaVersion: 1, backends: [] };
163
+ try {
164
+ registry = JSON.parse(await (await import("node:fs/promises")).readFile(backendsConfig, "utf8"));
165
+ } catch {
166
+ }
167
+ registry.backends = [...registry.backends.filter((row) => row.id !== backendId), { id: backendId, name: `${runner.label} worker`, url: `http://127.0.0.1:${port}/`, bearerTokenEnv: tokenEnv }];
168
+ writeFileSync(backendsConfig, JSON.stringify(registry, null, 2) + "\n", { mode: 384 });
169
+ writeFileSync(join(stateDir, `${backendId}.env`), `${tokenEnv}=${token}
170
+ `, { 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 });
172
+ process.env[tokenEnv] = token;
173
+ return { backendId, engine: `http://127.0.0.1:${port}/`, target: targetPath, backendsConfig, tokenEnv };
174
+ } finally {
175
+ rmSync(staging, { recursive: true, force: true });
176
+ }
177
+ }
178
+ function loadManagedWorker(backendId) {
179
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(backendId)) throw new Error("Invalid worker ID.");
180
+ let worker;
181
+ try {
182
+ worker = JSON.parse(readFileSync(join(homeStateDir(), "workers", `${backendId}.json`), "utf8"));
183
+ } catch {
184
+ throw new Error("This connection has no managed deployment metadata. Stop its engine directly on the host.");
185
+ }
186
+ if (worker.schemaVersion !== 1 || worker.backendId !== backendId || worker.remoteDir !== REMOTE_DIR || !!worker.ssh === !!worker.lima) throw new Error("Invalid managed deployment metadata.");
187
+ validateWorkerOptions({ ...worker, enginePort: worker.port });
188
+ return worker;
189
+ }
190
+ function stopManagedTunnel(worker) {
191
+ if (!Number.isSafeInteger(worker.tunnelPid) || worker.tunnelPid <= 1) return false;
192
+ const result = spawnSync("ps", ["-p", String(worker.tunnelPid), "-o", "comm=", "-o", "args="], { encoding: "utf8" });
193
+ const command = result.stdout?.trim() ?? "";
194
+ const destination = worker.ssh ?? `lima-${worker.lima}`;
195
+ if (!/^\S*ssh\s/.test(command) || !command.includes(` ${worker.port}:127.0.0.1:${worker.port} `) || !command.endsWith(` ${destination}`)) return false;
196
+ try {
197
+ process.kill(worker.tunnelPid, "SIGTERM");
198
+ return true;
199
+ } catch {
200
+ return false;
201
+ }
202
+ }
203
+ async function stopWorker(backendId, suppliedRunner) {
204
+ const worker = loadManagedWorker(backendId);
205
+ const runner = suppliedRunner ?? createRunner(worker);
206
+ runner.shell(`set -eu
207
+ if test ! -f ${REMOTE_DIR}/engine.pid; then echo 'Managed engine PID is unavailable; engine was not stopped.' >&2; exit 1; fi
208
+ pid=$(cat ${REMOTE_DIR}/engine.pid)
209
+ case "$pid" in ''|*[!0-9]*) echo 'Invalid engine PID' >&2; exit 1;; esac
210
+ if test "$pid" -le 1; then echo 'Invalid engine PID' >&2; exit 1; fi
211
+ if test -e /proc/$pid/cmdline; then
212
+ if test "$(readlink /proc/$pid/cwd)" != "${REMOTE_DIR}"; then echo 'Engine working directory does not match managed Zero engine' >&2; exit 1; fi
213
+ command=$(tr '\\000' ' ' < /proc/$pid/cmdline)
214
+ case "$command" in 'node dist/0.js dashboard '*|'node /tmp/zero-engine/dist/0.js dashboard '*) kill "$pid";; *) echo 'Engine PID does not match managed Zero engine' >&2; exit 1;; esac
215
+ fi
216
+ rm -f ${REMOTE_DIR}/engine.pid`, 3e4);
217
+ return { stopped: true, tunnelStopped: stopManagedTunnel(worker), remoteFilesRemoved: false };
218
+ }
219
+
20
220
  // packages/cli/src/web/backend-connections.ts
21
221
  import { randomUUID } from "node:crypto";
22
- import { constants, closeSync, fstatSync, mkdirSync, openSync, readSync, writeFileSync } from "node:fs";
23
- import { dirname, join, resolve } from "node:path";
222
+ import { constants, closeSync, fstatSync, mkdirSync as mkdirSync2, openSync, readFileSync as readFileSync2, readSync, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "node:fs";
223
+ import { dirname as dirname2, join as join2, resolve } from "node:path";
24
224
  var BackendConnectionError = class extends Error {
25
225
  constructor(message, statusCode = 502) {
26
226
  super(message);
@@ -55,7 +255,7 @@ function endpoint(value) {
55
255
  return url;
56
256
  }
57
257
  function loadBackendConnectionConfig(configPath) {
58
- const path = configPath ?? join(homeStateDir(), "backends.json");
258
+ const path = configPath ?? join2(homeStateDir(), "backends.json");
59
259
  let fd;
60
260
  try {
61
261
  fd = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK);
@@ -87,9 +287,9 @@ function createBackendHandshake(dbPath, capabilities2 = []) {
87
287
  let engineId = `engine-${randomUUID()}`;
88
288
  if (db !== ":memory:") {
89
289
  const path = `${resolve(db)}.engine-id`;
90
- mkdirSync(dirname(path), { recursive: true, mode: 448 });
290
+ mkdirSync2(dirname2(path), { recursive: true, mode: 448 });
91
291
  try {
92
- writeFileSync(path, `${engineId}
292
+ writeFileSync2(path, `${engineId}
93
293
  `, { flag: "wx", mode: 384 });
94
294
  } catch (error) {
95
295
  if (error.code !== "EEXIST") throw error;
@@ -170,9 +370,13 @@ var BackendConnectionRegistry = class {
170
370
  #fetch;
171
371
  #local;
172
372
  #timeoutMs;
373
+ #configPath;
374
+ #reloadFromDisk;
173
375
  #abort = new AbortController();
174
376
  #active = 0;
175
377
  constructor(options = {}) {
378
+ this.#configPath = options.configPath;
379
+ this.#reloadFromDisk = options.connections === void 0;
176
380
  const rows = options.connections ?? loadBackendConnectionConfig(options.configPath);
177
381
  const parsed = configSchema.parse({ schemaVersion: 1, backends: rows }).backends;
178
382
  if (new Set(parsed.map((row) => row.id)).size !== parsed.length) throw new BackendConnectionError("Backend IDs must be unique.", 400);
@@ -182,7 +386,65 @@ var BackendConnectionRegistry = class {
182
386
  this.#timeoutMs = options.timeoutMs ?? 3e4;
183
387
  this.#local = parseBackendHandshake(options.localHandshake ?? createBackendHandshake());
184
388
  this.#descriptors.set("local", { id: "local", name: "Local engine", transport: "local", status: "connected", protocolVersion: this.#local.protocolVersion, capabilities: this.#local.capabilities, platform: this.#local.platform });
185
- for (const row of parsed) this.#descriptors.set(row.id, { id: row.id, name: row.name, transport: "http", status: "disconnected", capabilities: [] });
389
+ this.reload();
390
+ for (const row of parsed) if (!this.#descriptors.has(row.id)) this.#descriptors.set(row.id, { id: row.id, name: row.name, transport: "http", status: "disconnected", capabilities: [] });
391
+ }
392
+ reload() {
393
+ if (!this.#reloadFromDisk) return;
394
+ const rows = loadBackendConnectionConfig(this.#configPath);
395
+ for (const id of this.#connections.keys()) if (!rows.some((row) => row.id === id)) {
396
+ this.#connections.delete(id);
397
+ this.#descriptors.delete(id);
398
+ this.#handshakes.delete(id);
399
+ this.#pins.delete(id);
400
+ }
401
+ for (const row of rows) {
402
+ const normalized = { ...row, url: endpoint(row.url).href };
403
+ const previous = this.#connections.get(row.id);
404
+ if (JSON.stringify(previous) !== JSON.stringify(normalized)) {
405
+ this.#connections.set(row.id, normalized);
406
+ this.#handshakes.delete(row.id);
407
+ this.#pins.delete(row.id);
408
+ this.#descriptors.set(row.id, { id: row.id, name: row.name, transport: "http", status: "disconnected", capabilities: [] });
409
+ }
410
+ {
411
+ try {
412
+ const value = readFileSync2(join2(homeStateDir(), "workers", `${row.id}.env`), "utf8");
413
+ const token = value.split("\n").find((line) => line.startsWith(`${row.bearerTokenEnv}=`))?.slice(row.bearerTokenEnv.length + 1);
414
+ if (token) this.#env[row.bearerTokenEnv] = backendBearerFromEnv(row.bearerTokenEnv, { [row.bearerTokenEnv]: token });
415
+ } catch {
416
+ }
417
+ }
418
+ }
419
+ }
420
+ /** Remove this dashboard's trusted connection; remote engine files are untouched. */
421
+ remove(id) {
422
+ id = BackendDescriptorSchema.shape.id.parse(id);
423
+ if (id === "local") throw new BackendConnectionError("The local engine cannot be removed.", 400);
424
+ if (!this.#reloadFromDisk) throw new BackendConnectionError("This backend registry is not persisted.", 409);
425
+ const rows = loadBackendConnectionConfig(this.#configPath);
426
+ const row = rows.find((value) => value.id === id);
427
+ if (!row) throw new BackendConnectionError("Backend is not registered.", 404);
428
+ const path = this.#configPath ?? join2(homeStateDir(), "backends.json");
429
+ const temporary = `${path}.${randomUUID()}.tmp`;
430
+ try {
431
+ writeFileSync2(temporary, `${JSON.stringify({ schemaVersion: 1, backends: rows.filter((value) => value.id !== id) }, null, 2)}
432
+ `, { mode: 384, flag: "wx" });
433
+ renameSync(temporary, path);
434
+ } finally {
435
+ rmSync2(temporary, { force: true });
436
+ }
437
+ try {
438
+ stopManagedTunnel(loadManagedWorker(id));
439
+ } catch {
440
+ }
441
+ rmSync2(join2(homeStateDir(), "workers", `${id}.json`), { force: true });
442
+ rmSync2(join2(homeStateDir(), "workers", `${id}.env`), { force: true });
443
+ if (!rows.some((value) => value.id !== id && value.bearerTokenEnv === row.bearerTokenEnv)) delete this.#env[row.bearerTokenEnv];
444
+ this.#connections.delete(id);
445
+ this.#descriptors.delete(id);
446
+ this.#handshakes.delete(id);
447
+ this.#pins.delete(id);
186
448
  }
187
449
  list() {
188
450
  return structuredClone([...this.#descriptors.values()]);
@@ -337,7 +599,7 @@ var BackendConnectionRegistry = class {
337
599
  return new Response(body2, { status: response.status, headers: { "Content-Type": type, "X-0-Request-ID": requestId, ...response.headers.get("x-0-engine-id") ? { "X-0-Engine-ID": response.headers.get("x-0-engine-id") } : {} } });
338
600
  }
339
601
  const data = await boundedResponse(response, MAX_RESPONSE, signal);
340
- return new Response([204, 205, 304].includes(response.status) || method === "HEAD" ? null : data, { status: response.status, headers: { "Content-Type": type, "X-0-Request-ID": requestId, ...response.headers.get("x-0-engine-id") ? { "X-0-Engine-ID": response.headers.get("x-0-engine-id") } : {} } });
602
+ return new Response([204, 205, 304].includes(response.status) || method === "HEAD" ? null : data, { status: response.status, headers: { "Content-Type": type, ...attachmentHeaders(response.headers), "X-0-Request-ID": requestId, ...response.headers.get("x-0-engine-id") ? { "X-0-Engine-ID": response.headers.get("x-0-engine-id") } : {} } });
341
603
  } catch (error) {
342
604
  if (error instanceof BackendConnectionError) throw error;
343
605
  if (timeout.signal.aborted) throw new BackendConnectionError("Backend request timed out.", 504);
@@ -371,6 +633,11 @@ async function requestJson(req) {
371
633
  throw new BackendConnectionError("Backend request must contain valid JSON.", 400);
372
634
  }
373
635
  }
636
+ function attachmentHeaders(headers) {
637
+ const value = headers.get("content-disposition");
638
+ const match = value?.match(/^attachment;\s*filename="([A-Za-z0-9][A-Za-z0-9_.-]{0,159})"$/i);
639
+ return match ? { "Content-Disposition": `attachment; filename="${match[1]}"` } : {};
640
+ }
374
641
  function json(res, status, value) {
375
642
  res.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
376
643
  res.end(JSON.stringify(value));
@@ -378,6 +645,7 @@ function json(res, status, value) {
378
645
  async function handleBackendConnectionRequest(req, res, url, registry) {
379
646
  if (url.pathname === "/api/backends") {
380
647
  if (req.method !== "GET") throw new BackendConnectionError("Backend registry is read-only.", 405);
648
+ registry.reload();
381
649
  json(res, 200, { backends: registry.list() });
382
650
  return { handled: true };
383
651
  }
@@ -386,6 +654,13 @@ async function handleBackendConnectionRequest(req, res, url, registry) {
386
654
  json(res, 200, (await registry.handshake("local")).handshake);
387
655
  return { handled: true };
388
656
  }
657
+ const removal = url.pathname.match(/^\/api\/backends\/([^/]+)$/);
658
+ if (removal) {
659
+ if (req.method !== "DELETE") throw new BackendConnectionError("Use DELETE to remove a backend registration.", 405);
660
+ registry.remove(decodeURIComponent(removal[1]));
661
+ json(res, 200, { removed: true, remoteEngineRemoved: false });
662
+ return { handled: true };
663
+ }
389
664
  const match = url.pathname.match(/^\/api\/backends\/([^/]+)\/(handshake|proxy(?:\/.*)?)$/);
390
665
  if (!match) return { handled: false };
391
666
  const id = decodeURIComponent(match[1]);
@@ -405,7 +680,7 @@ async function handleBackendConnectionRequest(req, res, url, registry) {
405
680
  const stream = req.headers.accept?.includes("text/event-stream") === true;
406
681
  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 });
407
682
  if (res.destroyed) return { handled: true };
408
- res.writeHead(response.status, { "Content-Type": response.headers.get("content-type") ?? "application/json", "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" } : {} });
683
+ 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" } : {} });
409
684
  if (!response.body) {
410
685
  res.end();
411
686
  return { handled: true };
@@ -448,6 +723,10 @@ async function handleBackendConnectionRequest(req, res, url, registry) {
448
723
  }
449
724
 
450
725
  export {
726
+ validateWorkerOptions,
727
+ deployWorker,
728
+ loadManagedWorker,
729
+ stopWorker,
451
730
  BackendConnectionError,
452
731
  loadBackendConnectionConfig,
453
732
  createBackendHandshake,
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __0CreateRequire } from "node:module";
3
+ const require = __0CreateRequire(import.meta.url);
4
+ import {
5
+ createRemoteWorkflowRuntime
6
+ } from "./chunk-ZPFBQ3SD.js";
7
+ import {
8
+ BackendConnectionRegistry
9
+ } from "./chunk-TZRHWP7R.js";
10
+ import {
11
+ resolveOsecDbPath
12
+ } from "./chunk-RCHAFSWS.js";
13
+ import {
14
+ homeStateDir
15
+ } from "./chunk-RZR2XXAK.js";
16
+ import {
17
+ external_exports
18
+ } from "./chunk-VIT5ALXF.js";
19
+
20
+ // packages/cli/src/local-engine.ts
21
+ import { createHash, randomUUID } from "node:crypto";
22
+ import { constants, closeSync, fstatSync, lstatSync, mkdirSync, openSync, readSync, realpathSync, unlinkSync, writeFileSync } from "node:fs";
23
+ import { dirname, isAbsolute, join, resolve } from "node:path";
24
+ var MAX_DESCRIPTOR = 16 * 1024;
25
+ var HAS_POSIX_PERMISSIONS = process.platform !== "win32";
26
+ var schema = external_exports.object({
27
+ schemaVersion: external_exports.literal(1),
28
+ nonce: external_exports.string().uuid(),
29
+ url: external_exports.string().min(1).max(4096),
30
+ token: external_exports.string().min(32).max(4096).regex(/^[^\s\x00-\x1f\x7f]+$/),
31
+ engineId: external_exports.string().min(1).max(128),
32
+ serverInstanceId: external_exports.string().min(1).max(128),
33
+ pid: external_exports.number().int().positive(),
34
+ workspace: external_exports.string().min(1).max(4096)
35
+ }).strict();
36
+ function localEngineDescriptorPath(dbPath, homeDir) {
37
+ const db = resolveOsecDbPath(dbPath);
38
+ const key = createHash("sha256").update(db === ":memory:" ? db : resolve(db)).digest("hex");
39
+ return join(homeStateDir(homeDir), "engines", `${key}.json`);
40
+ }
41
+ function secureMetadata(path, create) {
42
+ const directory = dirname(path);
43
+ if (create) mkdirSync(directory, { recursive: true, mode: 448 });
44
+ let stat;
45
+ try {
46
+ stat = lstatSync(directory);
47
+ } catch (error) {
48
+ if (!create && error.code === "ENOENT") return false;
49
+ throw error;
50
+ }
51
+ if (!stat.isDirectory() || stat.isSymbolicLink() || HAS_POSIX_PERMISSIONS && (stat.mode & 63) !== 0 || process.getuid && stat.uid !== process.getuid()) throw new Error("Local engine discovery directory must be owned by this user with private permissions (0700).");
52
+ return true;
53
+ }
54
+ function loopbackUrl(value) {
55
+ const url = new URL(value);
56
+ if (!["http:", "https:"].includes(url.protocol) || !(url.hostname === "localhost" || url.hostname === "[::1]" || /^127\.(?:\d{1,3}\.){2}\d{1,3}$/.test(url.hostname)) || url.username || url.password || url.search || url.hash || url.pathname !== "/") throw new Error("Local engine discovery requires a credential-free loopback URL.");
57
+ return url.href;
58
+ }
59
+ function readDescriptor(path) {
60
+ if (!secureMetadata(path, false)) return null;
61
+ let fd;
62
+ try {
63
+ const entry = lstatSync(path);
64
+ if (entry.isSymbolicLink() || !entry.isFile()) throw new Error("Discovery metadata must be a regular file, never a symlink.");
65
+ fd = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK | constants.O_NOFOLLOW);
66
+ } catch (error) {
67
+ if (error.code === "ENOENT") return null;
68
+ throw new Error("Cannot safely read local engine discovery metadata.", { cause: error });
69
+ }
70
+ try {
71
+ const stat = fstatSync(fd);
72
+ if (!stat.isFile() || stat.size > MAX_DESCRIPTOR || HAS_POSIX_PERMISSIONS && (stat.mode & 63) !== 0 || process.getuid && stat.uid !== process.getuid()) throw new Error("Local engine descriptor must be a private regular file owned by this user, at most 16 KiB.");
73
+ const buffer = Buffer.alloc(MAX_DESCRIPTOR + 1);
74
+ let length = 0;
75
+ while (length < buffer.length) {
76
+ const bytes = readSync(fd, buffer, length, buffer.length - length, length);
77
+ if (!bytes) break;
78
+ length += bytes;
79
+ }
80
+ if (length > MAX_DESCRIPTOR) throw new Error("Local engine descriptor exceeds 16 KiB.");
81
+ const descriptor = schema.parse(JSON.parse(buffer.subarray(0, length).toString("utf8")));
82
+ loopbackUrl(descriptor.url);
83
+ if (!isAbsolute(descriptor.workspace) || /[\x00-\x1f]/.test(descriptor.workspace)) throw new Error("Local engine descriptor workspace must be an absolute path.");
84
+ return descriptor;
85
+ } finally {
86
+ closeSync(fd);
87
+ }
88
+ }
89
+ function deadPid(pid) {
90
+ try {
91
+ process.kill(pid, 0);
92
+ return false;
93
+ } catch (error) {
94
+ return error.code === "ESRCH";
95
+ }
96
+ }
97
+ function removeMatching(path, nonce) {
98
+ if (readDescriptor(path)?.nonce === nonce) unlinkSync(path);
99
+ }
100
+ function assertLocalEngineAvailable(dbPath, homeDir) {
101
+ if (resolveOsecDbPath(dbPath) === ":memory:") return;
102
+ const path = localEngineDescriptorPath(dbPath, homeDir);
103
+ const descriptor = readDescriptor(path);
104
+ if (!descriptor) return;
105
+ if (!deadPid(descriptor.pid)) throw new Error("A running local engine already owns this database. Attach to it or shut it down before starting another engine.");
106
+ removeMatching(path, descriptor.nonce);
107
+ }
108
+ function registerLocalEngine(input, dbPath, options = {}) {
109
+ if (resolveOsecDbPath(dbPath) === ":memory:") return () => {
110
+ };
111
+ const path = localEngineDescriptorPath(dbPath, options.homeDir);
112
+ secureMetadata(path, true);
113
+ const descriptor = schema.parse({ ...input, url: loopbackUrl(input.url), workspace: realpathSync(input.workspace), schemaVersion: 1, nonce: randomUUID() });
114
+ const previous = readDescriptor(path);
115
+ if (previous) {
116
+ if (!deadPid(previous.pid)) throw new Error("A local engine already owns this database. Attach to it or shut it down before starting another engine.");
117
+ removeMatching(path, previous.nonce);
118
+ }
119
+ writeFileSync(path, JSON.stringify(descriptor), { flag: "wx", mode: 384 });
120
+ return () => removeMatching(path, descriptor.nonce);
121
+ }
122
+ async function connectLocalEngine(options) {
123
+ if (resolveOsecDbPath(options.dbPath) === ":memory:") return null;
124
+ const path = localEngineDescriptorPath(options.dbPath, options.homeDir);
125
+ const descriptor = readDescriptor(path);
126
+ if (!descriptor) return null;
127
+ if (deadPid(descriptor.pid)) {
128
+ removeMatching(path, descriptor.nonce);
129
+ return null;
130
+ }
131
+ if (realpathSync(options.workspace) !== descriptor.workspace) throw new Error("The running local engine owns this database in another workspace. Select its workspace or a separate engine database.");
132
+ if (options.model !== void 0 || options.scopePath !== void 0 || options.allowApply === true) throw new Error("The running local engine owns model, scope and application permissions. Attach using its configuration instead of overriding it.");
133
+ const backendId = "discovered-local-engine";
134
+ const registry = new BackendConnectionRegistry({
135
+ connections: [{ id: backendId, name: "Running local engine", url: descriptor.url, bearerTokenEnv: "LOCAL_ENGINE_DISCOVERY_TOKEN", expectedEngineId: descriptor.engineId }],
136
+ env: { LOCAL_ENGINE_DISCOVERY_TOKEN: descriptor.token },
137
+ timeoutMs: 3e3,
138
+ localHandshake: { protocolVersion: 1, engineId: descriptor.engineId, serverInstanceId: descriptor.serverInstanceId, capabilities: [], platform: { os: process.platform, pathStyle: process.platform === "win32" ? "windows" : "posix" } }
139
+ });
140
+ try {
141
+ const runtime = await createRemoteWorkflowRuntime({ backendId }, {
142
+ handshake: async (id) => {
143
+ const connection = await registry.handshake(id);
144
+ if (connection.handshake?.serverInstanceId !== descriptor.serverInstanceId) throw new Error("The discovered local engine instance changed. Refresh its registration before attaching.");
145
+ return connection;
146
+ },
147
+ request: (id, path2, request) => registry.request(id, path2, request)
148
+ });
149
+ return { ...runtime, dispose: async () => {
150
+ await runtime.dispose();
151
+ registry.dispose();
152
+ } };
153
+ } catch (error) {
154
+ registry.dispose();
155
+ throw new Error("The registered local engine could not be reached or authenticated. Restart that engine; no replacement host was started.", { cause: error });
156
+ }
157
+ }
158
+
159
+ export {
160
+ localEngineDescriptorPath,
161
+ assertLocalEngineAvailable,
162
+ registerLocalEngine,
163
+ connectLocalEngine
164
+ };
@@ -4,10 +4,10 @@ const require = __0CreateRequire(import.meta.url);
4
4
  import {
5
5
  getToolsForRole,
6
6
  runNativeAgentLoop
7
- } from "./chunk-EH2WTNY7.js";
7
+ } from "./chunk-A3EKBUEM.js";
8
8
  import {
9
9
  LlmApiRuntime
10
- } from "./chunk-BF5FIK7H.js";
10
+ } from "./chunk-EYBMTELO.js";
11
11
 
12
12
  // packages/core/dist/eval-runner.js
13
13
  import { randomUUID } from "node:crypto";