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.
- package/0.js +67 -62
- package/README.md +121 -82
- package/chunks/{adapt-loop-L77BWMNE.js → adapt-loop-P4HKONB5.js} +6 -5
- package/chunks/{artifact-scraper-BV67RAP5.js → artifact-scraper-IIRJNYKT.js} +4 -3
- package/chunks/{assumption-mining-RPVR77A3.js → assumption-mining-YA6VJ2V6.js} +22 -20
- package/chunks/{backend-connections-ACIXNYZN.js → backend-connections-64PKYKL7.js} +5 -4
- package/chunks/chunk-36J5ZLFE.js +18729 -0
- package/chunks/{chunk-ZM6ANQZJ.js → chunk-3MWQNNJU.js} +16180 -34467
- package/chunks/{chunk-GV5WXDHY.js → chunk-3VQ5EZKG.js} +11 -9
- package/chunks/chunk-5XOYTAOK.js +1546 -0
- package/chunks/{chunk-UJE4WOQS.js → chunk-6GV5G6U3.js} +1 -1
- package/chunks/{chunk-X2ZMSRTP.js → chunk-6SNOKNCS.js} +333 -3
- package/chunks/{chunk-BMDG6T7D.js → chunk-72PU46MS.js} +178 -133
- package/chunks/{chunk-KCA35IL3.js → chunk-7PUJI64A.js} +11 -9
- package/chunks/chunk-A7G6S5RA.js +90 -0
- package/chunks/chunk-ABKUI3QB.js +196 -0
- package/chunks/{chunk-5ETI27Q3.js → chunk-AFJ2UMPR.js} +3 -3
- package/chunks/{chunk-XA2IBHPB.js → chunk-B7XL6RON.js} +1 -1
- package/chunks/{chunk-TVS6WVSK.js → chunk-BM6EYP2D.js} +3 -3
- package/chunks/{chunk-7UHAXEOV.js → chunk-D4M5WURF.js} +226 -4
- package/chunks/{chunk-K74DRDC5.js → chunk-EHNVP6QB.js} +1 -1
- package/chunks/{chunk-I43YYHDU.js → chunk-FBZBJYZS.js} +5 -50
- package/chunks/{chunk-GXXX7AGH.js → chunk-GYEYTNHK.js} +144 -14
- package/chunks/{chunk-IJ6UPW3H.js → chunk-HS2NQ7K6.js} +393 -58
- package/chunks/chunk-HUZ2EC2R.js +196 -0
- package/chunks/{chunk-SU4IHQQI.js → chunk-IUUNIJPM.js} +1 -1
- package/chunks/chunk-JGDA6EIJ.js +49 -0
- package/chunks/{chunk-CJRZSWII.js → chunk-K3PTYN43.js} +3 -3
- package/chunks/{chunk-2NBZZFRG.js → chunk-KCABBZHN.js} +8 -10
- package/chunks/{chunk-3LPBJMHB.js → chunk-LRD5N2TQ.js} +1 -1
- package/chunks/{chunk-SQCBHFWN.js → chunk-LWMEJYCP.js} +2 -2
- package/chunks/chunk-MNK373HF.js +57 -0
- package/chunks/{chunk-R2XBH476.js → chunk-MOEVVXML.js} +2 -2
- package/chunks/{chunk-F2P25DJY.js → chunk-MOGWEHSC.js} +1448 -1050
- package/chunks/{chunk-6XMFCVJS.js → chunk-N7YCONYR.js} +1 -1
- package/chunks/{chunk-3WUPCZGF.js → chunk-NA3FKCI2.js} +1 -1
- package/chunks/{chunk-S2GITRD5.js → chunk-NABVDAAO.js} +2 -2
- package/chunks/{chunk-SZDD77KX.js → chunk-NNMOTHKC.js} +6 -10
- package/chunks/{chunk-LMP2T4G2.js → chunk-OILVEROI.js} +22 -172
- package/chunks/{chunk-YERUDEXT.js → chunk-PAE7ZAV6.js} +2780 -1255
- package/chunks/{chunk-NBV4I237.js → chunk-PAMJEXE2.js} +1 -1
- package/chunks/{chunk-PJU24AKR.js → chunk-R7VWEY45.js} +337 -257
- package/chunks/{chunk-QNRYOJEB.js → chunk-RZZ6VPRY.js} +1 -1
- package/chunks/{chunk-WUPN3D37.js → chunk-S4DFH2FJ.js} +26 -1
- package/chunks/{chunk-5WAHHZBF.js → chunk-SIR7XW2S.js} +61910 -30777
- package/chunks/{chunk-BD7WULFS.js → chunk-SSPP64FF.js} +3 -2
- package/chunks/{chunk-BOBIAHKA.js → chunk-STPHTPSD.js} +3 -333
- package/chunks/{chunk-Q7JKIKKF.js → chunk-UGCTPKJG.js} +89 -17
- package/chunks/{chunk-5PFRE522.js → chunk-ULRLUXSS.js} +1 -1
- package/chunks/{chunk-GZA7RGK7.js → chunk-UQS7XCBV.js} +2085 -1093
- package/chunks/{chunk-X2IPO5JO.js → chunk-V2KJQVYE.js} +2676 -2959
- package/chunks/{chunk-CGBDEST2.js → chunk-VJBEB2K6.js} +1 -1
- package/chunks/{chunk-ILRMLA6J.js → chunk-VWE36MUN.js} +1 -1
- package/chunks/{chunk-RURJYCWY.js → chunk-WNWDQ2TO.js} +1 -1
- package/chunks/{chunk-GTED3FSZ.js → chunk-WPJMA5AK.js} +4 -99
- package/chunks/{chunk-5NFIY2SJ.js → chunk-XJ2TBEV7.js} +3 -3
- package/chunks/{chunk-PVJUPIQG.js → chunk-XOVYV7TT.js} +6 -6
- package/chunks/{chunk-IXT64DV5.js → chunk-XPDJE537.js} +97 -1
- package/chunks/{chunk-YKWARO3T.js → chunk-YGYJ2FTH.js} +95 -21
- package/chunks/{chunk-JWSOUKFF.js → chunk-YJGPPPUB.js} +66 -21
- package/chunks/chunk-YP2DHYNI.js +650 -0
- package/chunks/{chunk-RVJVM5L4.js → chunk-Z2VLJEQJ.js} +5 -5
- package/chunks/chunk-ZPVSDB63.js +3839 -0
- package/chunks/{codex-models-6XVNFRXZ.js → codex-models-CI22KIHY.js} +9 -8
- package/chunks/{commands-FRPOFIO4.js → commands-C2WRSCNB.js} +909 -610
- package/chunks/dashboard-XO2X2SPD.js +75 -0
- package/chunks/{db-BXJNWUYJ.js → db-FU3OIGQK.js} +5 -4
- package/chunks/{deep-review-GSJEBLCG.js → deep-review-5AL6QYTK.js} +37 -38
- package/chunks/{disclose-OU6Z6GVT.js → disclose-YPV5KIUU.js} +6 -5
- package/chunks/{dist-M2X367VW.js → dist-JAZWL3SC.js} +3 -2
- package/chunks/{dist-TQMHMSBZ.js → dist-ONIRKDH6.js} +376 -333
- package/chunks/{dist-RKLQIXDT.js → dist-QLMPTFT7.js} +4 -3
- package/chunks/{dist-7KSYDDSG.js → dist-QXJKD743.js} +5 -2
- package/chunks/{dist-LNXGATR2.js → dist-WNAOCQGA.js} +5 -4
- package/chunks/eval-runner-D3RUCU3R.js +38 -0
- package/chunks/{exploit-agent-Y2P4GFIY.js → exploit-agent-4E4HXKUA.js} +1 -1
- package/chunks/{exploit-autoclimb-YRZ3TMS2.js → exploit-autoclimb-5GRXI6VQ.js} +1 -1
- package/chunks/{exploit-climb-4LEY4SDW.js → exploit-climb-AHQEJ2I2.js} +4 -3
- package/chunks/{fix-RQSIG75B.js → fix-CHD7LXDS.js} +9 -8
- package/chunks/{harness-3NVC3DDY.js → harness-E63KDHPG.js} +5 -4
- package/chunks/{http-conformance-U5F6GKYG.js → http-conformance-AXMUOE6C.js} +3 -2
- package/chunks/hunt-scan-ME2Z4CTC.js +43 -0
- package/chunks/{kernel-primitive-T47V3RD3.js → kernel-primitive-S566GXWP.js} +4 -3
- package/chunks/{kernel-vm-runner-AEL5E3SV.js → kernel-vm-runner-KREBY4DC.js} +4 -3
- package/chunks/{local-engine-ZCW4YC6E.js → local-engine-ZRTZVSSX.js} +7 -6
- package/chunks/managed-operation-ZMLLRCCQ.js +59 -0
- package/chunks/{memsafety-scan-L2Z7E7TE.js → memsafety-scan-Q2MBZEGJ.js} +1 -2
- package/chunks/{native-loop-26X2CHBV.js → native-loop-UV3Z4Z2F.js} +31 -16
- package/chunks/operator-services-JOCREEBA.js +79 -0
- package/chunks/orchestrate-ZF6ZTSIQ.js +62 -0
- package/chunks/{prepare-C3KGMBXT.js → prepare-PLDVGLDX.js} +7 -6
- package/chunks/{provider-model-discovery-QGUGL3XW.js → provider-model-discovery-3X6DON3Y.js} +7 -2
- package/chunks/{remote-workflow-runtime-DB52SINR.js → remote-workflow-runtime-GOI4TYP5.js} +4 -3
- package/chunks/routing-WCQLO5SP.js +61 -0
- package/chunks/{runtime-AUBLQUOH.js → runtime-6ZIXFTW5.js} +4 -3
- package/chunks/{runtime-U66JNSAY.js → runtime-TVH5ORUK.js} +13 -8
- package/chunks/{scan-stream-34F3LTPV.js → scan-stream-HJVTWZ44.js} +6 -4
- package/chunks/{scope-HSTG63TQ.js → scope-RCYXVGJR.js} +4 -3
- package/chunks/service-plugins-TN6KDX4L.js +63 -0
- package/chunks/{session-store-MKAAP3WL.js → session-store-6QR3CVUA.js} +8 -5
- package/chunks/{variant-candidates-LG767HWH.js → variant-candidates-SGLKPPHI.js} +9 -8
- package/chunks/{web-recon-prepass-NJP6J3E4.js → web-recon-prepass-GO7CTMVQ.js} +7 -6
- package/chunks/{workflow-runtime-AR627I26.js → workflow-runtime-CQTDASFA.js} +50 -49
- package/dashboard/assets/{abnfDiagram-VCTEODGH-Cq149Jpk.js → abnfDiagram-VCTEODGH-DDZsU70-.js} +1 -1
- package/dashboard/assets/{arc-CpP-3TRW.js → arc-iDXNTSL6.js} +1 -1
- package/dashboard/assets/architecture-7GRP2DOG-DJcY9RFg.js +1 -0
- package/dashboard/assets/architectureDiagram-5GKGNRK7-d0ZuOniQ.js +36 -0
- package/dashboard/assets/{blockDiagram-I7D4REHJ-CZYkRRDi.js → blockDiagram-I7D4REHJ-B-EWfMy1.js} +2 -2
- package/dashboard/assets/{c4Diagram-7LVT6UL2-CV7Iu3_Z.js → c4Diagram-7LVT6UL2-KcZRuXZC.js} +1 -1
- package/dashboard/assets/channel-CeWMIm0w.js +1 -0
- package/dashboard/assets/{chunk-4HAMMTFA-PKCyW4m-.js → chunk-4HAMMTFA-DXWulBlo.js} +1 -1
- package/dashboard/assets/{chunk-75Z2AOVW-C5MlFTc_.js → chunk-75Z2AOVW-RiLZItrz.js} +1 -1
- package/dashboard/assets/chunk-DU6HZSFF-MBcaIyTX.js +127 -0
- package/dashboard/assets/{chunk-F27PBJKO-DTAok0qM.js → chunk-F27PBJKO-kLWCBX_W.js} +1 -1
- package/dashboard/assets/{chunk-FOHPRMQF-DHwB1DNv.js → chunk-FOHPRMQF-COOliuUh.js} +14 -14
- package/dashboard/assets/{chunk-GMAD6QVW-CPsr2F33.js → chunk-GMAD6QVW-BeQeSjpW.js} +7 -7
- package/dashboard/assets/{chunk-GVQU2GXP-C2AXGf9A.js → chunk-GVQU2GXP-CjCMlOIB.js} +1 -1
- package/dashboard/assets/{chunk-IMKFNOWR-DMG6yD_O.js → chunk-IMKFNOWR-BwNst53D.js} +1 -1
- package/dashboard/assets/{chunk-L3NEJ4N5-BSvwdbXx.js → chunk-L3NEJ4N5-CHXWQrkL.js} +1 -1
- package/dashboard/assets/{chunk-OSK3NFVY-CfB8V7FU.js → chunk-OSK3NFVY-B2vd19Ed.js} +1 -1
- package/dashboard/assets/{chunk-P2QGCYS3-CvmZvq6n.js → chunk-P2QGCYS3-Dk7Fyh6n.js} +1 -1
- package/dashboard/assets/{chunk-POPQ4Y6H-D_TvwDxL.js → chunk-POPQ4Y6H-CPAgOvYe.js} +1 -1
- package/dashboard/assets/{chunk-PWAF6VOD-Da5GnuOY.js → chunk-PWAF6VOD-BotyfMha.js} +1 -1
- package/dashboard/assets/{chunk-SHT3W25Y-CcsMJpR-.js → chunk-SHT3W25Y-Buz5gLRP.js} +1 -1
- package/dashboard/assets/{chunk-SVP7TREG-COojjieJ.js → chunk-SVP7TREG-_rpYEZcs.js} +1 -1
- package/dashboard/assets/{chunk-TICWLB2K-nBAmJwx6.js → chunk-TICWLB2K-DOJxPoec.js} +2 -2
- package/dashboard/assets/{chunk-XXDRQBXY-r5HyhWDv.js → chunk-XXDRQBXY-EXxKJbAs.js} +1 -1
- package/dashboard/assets/classDiagram-ZZMXUADV-DV_h1NoS.js +1 -0
- package/dashboard/assets/classDiagram-v2-VYDZK3BY-DV_h1NoS.js +1 -0
- package/dashboard/assets/common-VLJRx-Jq.js +5 -0
- package/dashboard/assets/cose-bilkent-JH36ORCC-B1SVC57o.js +1 -0
- package/dashboard/assets/cynefin-OW5HDTMX-BzhRorj4.js +1 -0
- package/dashboard/assets/{cynefinDiagram-5FMLGOSQ-xodkuQtW.js → cynefinDiagram-5FMLGOSQ-JXzRmldX.js} +1 -1
- package/dashboard/assets/cytoscape.esm-BbBREfsg.js +321 -0
- package/dashboard/assets/dagre-D7JM2Yhv.js +1 -0
- package/dashboard/assets/dagre-GXQ25YYZ-1LZ-X0-Z.js +4 -0
- package/dashboard/assets/{diagram-S7CK7UJ4-DNoTMlCO.js → diagram-S7CK7UJ4-C_-J_LQ4.js} +2 -2
- package/dashboard/assets/{diagram-UQ7AKVKN-COccuyew.js → diagram-UQ7AKVKN-CnxL1k8g.js} +1 -1
- package/dashboard/assets/{diagram-VSXAHHWV-g6D1tWRb.js → diagram-VSXAHHWV-WzSb3aby.js} +1 -1
- package/dashboard/assets/{diagram-VX7I27RA-DhO4eVIC.js → diagram-VX7I27RA-DKhrMInE.js} +1 -1
- package/dashboard/assets/{diagram-Z3DM3KII-DeOQFexd.js → diagram-Z3DM3KII-CDhI2WGP.js} +1 -1
- package/dashboard/assets/{dist-BQYeOQg3.js → dist-B0bfBMeP.js} +1 -1
- package/dashboard/assets/{ebnfDiagram-PWID7BFC-MtkX2feM.js → ebnfDiagram-PWID7BFC-iL5NQ1PE.js} +1 -1
- package/dashboard/assets/{erDiagram-RLTQ6QDP-DIWSsoYZ.js → erDiagram-RLTQ6QDP-RK2Voa5O.js} +1 -1
- package/dashboard/assets/eventmodeling-NTZA5JFV-WgE7OJBb.js +1 -0
- package/dashboard/assets/flowDiagram-HODETNUW-B9YcQ0Aq.js +1 -0
- package/dashboard/assets/{ganttDiagram-EL5Y4UJY-DKggkJe0.js → ganttDiagram-EL5Y4UJY-D8CJXHRF.js} +1 -1
- package/dashboard/assets/gitGraph-4MIJSDKK-BuZ9Lg04.js +1 -0
- package/dashboard/assets/{gitGraphDiagram-WWUBYQGX-r_iR8Qzo.js → gitGraphDiagram-WWUBYQGX-LEJMh54j.js} +1 -1
- package/dashboard/assets/info-A6RAGUB7-BL5k3pev.js +1 -0
- package/dashboard/assets/{infoDiagram-27XIBGKW-ClQk7UyQ.js → infoDiagram-27XIBGKW-LJvntUnZ.js} +1 -1
- package/dashboard/assets/{ishikawaDiagram-5VMMS53U-tR7Vziog.js → ishikawaDiagram-5VMMS53U-BYTYgKCG.js} +2 -2
- package/dashboard/assets/{journeyDiagram-3NMN7TZE-Cpb9IqKL.js → journeyDiagram-3NMN7TZE-G25qgQgO.js} +1 -1
- package/dashboard/assets/{kanban-definition-UXKFOSKX-BzUuKbA9.js → kanban-definition-UXKFOSKX-Bk3uLl1i.js} +1 -1
- package/dashboard/assets/{katex-BdBmVSus.js → katex-nLxf_RlZ.js} +2 -2
- package/dashboard/assets/{line-BHY_tSHu.js → line-i4qHBaWO.js} +1 -1
- package/dashboard/assets/linear-DmrqRsKG.js +1 -0
- package/dashboard/assets/mermaid-parser.core-BxbKr4QF.js +7 -0
- package/dashboard/assets/{mermaid.core-D_QsUPU8.js → mermaid.core-Cltee6FS.js} +9 -9
- package/dashboard/assets/{mindmap-definition-YA3MSWOX-CtfLTPPJ.js → mindmap-definition-YA3MSWOX-DkzO2JgS.js} +1 -1
- package/dashboard/assets/operations-B4_timQX.css +1 -0
- package/dashboard/assets/operations-DwppJviL.js +199 -0
- package/dashboard/assets/packet-AYTQ26CC-uZQUKnrE.js +1 -0
- package/dashboard/assets/{pegDiagram-XKGWAZYB-C1Dclbzj.js → pegDiagram-XKGWAZYB-CrOEi00T.js} +1 -1
- package/dashboard/assets/pie-WAS4IAKB-Dn9_tpQT.js +1 -0
- package/dashboard/assets/{pieDiagram-E7YTZNPT-Cd7XwYo5.js → pieDiagram-E7YTZNPT-D-niUkzc.js} +1 -1
- package/dashboard/assets/{quadrantDiagram-AXDQQJYC-CaS-GQ4X.js → quadrantDiagram-AXDQQJYC-CJOTiG5V.js} +1 -1
- package/dashboard/assets/radar-RG4KPBEZ-DIIVz4e8.js +1 -0
- package/dashboard/assets/railroad-74A4TZTK-1kiqDEID.js +1 -0
- package/dashboard/assets/railroad-abnf-HS5TGJTU-DK6rQPZR.js +1 -0
- package/dashboard/assets/railroad-ebnf-LZEXJU2U-C6cOgYW4.js +1 -0
- package/dashboard/assets/railroad-peg-WCYAUIDC-CQ3ptKef.js +1 -0
- package/dashboard/assets/{railroadDiagram-O6MQD6OU-BeesTrqn.js → railroadDiagram-O6MQD6OU-nEfkpa-m.js} +1 -1
- package/dashboard/assets/{requirementDiagram-BXWQKSXE-IjyK0DhW.js → requirementDiagram-BXWQKSXE-CdFMY8tG.js} +1 -1
- package/dashboard/assets/{sankeyDiagram-P5KCCOFB-DmIluQqo.js → sankeyDiagram-P5KCCOFB-C0KxrFYv.js} +1 -1
- package/dashboard/assets/{sequenceDiagram-WJ2MYXX4-CUp8ZjTc.js → sequenceDiagram-WJ2MYXX4-DeZ5ATiu.js} +2 -2
- package/dashboard/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dashboard/assets/src-Cg-chcoE.js +1 -0
- package/dashboard/assets/{stateDiagram-D77RDMKH-Dy9TQb8P.js → stateDiagram-D77RDMKH-B9MwWL5B.js} +1 -1
- package/dashboard/assets/stateDiagram-v2-MP3YSRHH-SucFndhx.js +1 -0
- package/dashboard/assets/swimlanes-42K2YHIH-DB--fwQE.js +1 -0
- package/dashboard/assets/swimlanesDiagram-VR7AAH4N-BzH-rIaK.js +8 -0
- package/dashboard/assets/{timeline-definition-24CTP7MA-BGdXW-iY.js → timeline-definition-24CTP7MA-DLkkTbWb.js} +1 -1
- package/dashboard/assets/treeView-Q6P3EWNA-XkZ9rl9H.js +1 -0
- package/dashboard/assets/treemap-WGGIJYW6-JCtVKxCE.js +1 -0
- package/dashboard/assets/{vennDiagram-4TSXK5OY-DzKWHJsl.js → vennDiagram-4TSXK5OY-DEb-x29Z.js} +1 -1
- package/dashboard/assets/wardley-WFR3VGLG-DhI7ROY3.js +1 -0
- package/dashboard/assets/{wardleyDiagram-VM6X3IG4-DGsjYmNJ.js → wardleyDiagram-VM6X3IG4-KNckudc5.js} +1 -1
- package/dashboard/assets/{xychartDiagram-S5SC5T6Z-C7_T_tWt.js → xychartDiagram-S5SC5T6Z-D4c0ynCk.js} +1 -1
- package/dashboard/index.html +13 -2
- package/package.json +2 -5
- package/worker-assets/demo-target/README.md +7 -3
- package/chunks/chunk-2XGBEH53.js +0 -4304
- package/chunks/chunk-4ROZFLSR.js +0 -279
- package/chunks/chunk-56UTQKXO.js +0 -56
- package/chunks/chunk-BPU6M42R.js +0 -77
- package/chunks/chunk-H5QURBBK.js +0 -1123
- package/chunks/chunk-IIBNQTOK.js +0 -1532
- package/chunks/chunk-NJLKFC66.js +0 -4790
- package/chunks/chunk-OOMBOLAF.js +0 -295
- package/chunks/chunk-VIT5ALXF.js +0 -4054
- package/chunks/chunk-VU7V2SDW.js +0 -284
- package/chunks/chunk-W624J7NF.js +0 -117
- package/chunks/chunk-YSQWZ67M.js +0 -6027
- package/chunks/dashboard-5HDSNBAU.js +0 -76
- package/chunks/eval-runner-A2DIGVP7.js +0 -31
- package/chunks/hunt-scan-W246VWJC.js +0 -40
- package/chunks/managed-operation-6R2QPPW5.js +0 -60
- package/chunks/orchestrate-OBS37FWQ.js +0 -63
- package/chunks/run-MU3MFL2Z.js +0 -28242
- package/chunks/service-plugins-5B23PWXC.js +0 -64
- package/dashboard/assets/architecture-7GRP2DOG-z5EHYkyH.js +0 -1
- package/dashboard/assets/architectureDiagram-5GKGNRK7-ewtXpjR_.js +0 -36
- package/dashboard/assets/channel-CuYjfiC5.js +0 -1
- package/dashboard/assets/chunk-DU6HZSFF-3M37ulcO.js +0 -127
- package/dashboard/assets/classDiagram-ZZMXUADV-DCuOrWUV.js +0 -1
- package/dashboard/assets/classDiagram-v2-VYDZK3BY-DCuOrWUV.js +0 -1
- package/dashboard/assets/common-C6snVPsk.js +0 -5
- package/dashboard/assets/cose-bilkent-JH36ORCC-BLGcaZHk.js +0 -1
- package/dashboard/assets/cynefin-OW5HDTMX-DbZMK00I.js +0 -1
- package/dashboard/assets/cytoscape.esm-CGd-uY3x.js +0 -321
- package/dashboard/assets/dagre-GXQ25YYZ-CRk9qfSG.js +0 -4
- package/dashboard/assets/dagre-PrKaheQc.js +0 -1
- package/dashboard/assets/eventmodeling-NTZA5JFV-D_3ez4Gv.js +0 -1
- package/dashboard/assets/flowDiagram-HODETNUW-D2boyYEd.js +0 -1
- package/dashboard/assets/gitGraph-4MIJSDKK-DFOQYwXc.js +0 -1
- package/dashboard/assets/info-A6RAGUB7-DeednLoB.js +0 -1
- package/dashboard/assets/linear-naZZ1pHk.js +0 -1
- package/dashboard/assets/mermaid-parser.core-CPvd4cEx.js +0 -7
- package/dashboard/assets/operations-BwCzhVnT.js +0 -130
- package/dashboard/assets/operations-QjKT0Hwi.css +0 -1
- package/dashboard/assets/packet-AYTQ26CC-DDQbkT9I.js +0 -1
- package/dashboard/assets/pie-WAS4IAKB-LpU4ULAs.js +0 -1
- package/dashboard/assets/radar-RG4KPBEZ-CcxW3NJm.js +0 -1
- package/dashboard/assets/railroad-74A4TZTK-9P5Rl8fP.js +0 -1
- package/dashboard/assets/railroad-abnf-HS5TGJTU-CSfpwjna.js +0 -1
- package/dashboard/assets/railroad-ebnf-LZEXJU2U-D6R5qzr-.js +0 -1
- package/dashboard/assets/railroad-peg-WCYAUIDC-DKEX7ITG.js +0 -1
- package/dashboard/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
- package/dashboard/assets/src-r61wDjcA.js +0 -1
- package/dashboard/assets/stateDiagram-v2-MP3YSRHH-CQb0ZtPr.js +0 -1
- package/dashboard/assets/swimlanes-42K2YHIH-CZuDV7V5.js +0 -1
- package/dashboard/assets/swimlanesDiagram-VR7AAH4N-BxgWMq8X.js +0 -8
- package/dashboard/assets/treeView-Q6P3EWNA-DlRrayjM.js +0 -1
- package/dashboard/assets/treemap-WGGIJYW6-C6UqLKfI.js +0 -1
- 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-
|
|
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-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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-
|
|
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-
|
|
15
|
+
} from "./chunk-GYEYTNHK.js";
|
|
16
16
|
import {
|
|
17
17
|
external_exports
|
|
18
|
-
} from "./chunk-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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-
|
|
6
|
+
} from "./chunk-GYEYTNHK.js";
|
|
7
7
|
|
|
8
8
|
// packages/core/dist/events/bus.js
|
|
9
9
|
function presentationEventSink(sink, options = {}) {
|