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
|
@@ -1,100 +1,90 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __0CreateRequire } from "node:module";
|
|
3
3
|
const require = __0CreateRequire(import.meta.url);
|
|
4
|
+
import {
|
|
5
|
+
registerDeepReviewCommand
|
|
6
|
+
} from "./chunk-3VQ5EZKG.js";
|
|
4
7
|
import {
|
|
5
8
|
registerOrchestrateCommand
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-NNMOTHKC.js";
|
|
7
10
|
import {
|
|
8
11
|
registerDbCommand
|
|
9
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-WNWDQ2TO.js";
|
|
10
13
|
import {
|
|
11
14
|
discoverSshHosts,
|
|
12
15
|
hashTeamPassword,
|
|
13
16
|
registerDashboardCommand,
|
|
14
17
|
registerWorkbenchCommand
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import {
|
|
17
|
-
registerVerifyCommand
|
|
18
|
-
} from "./chunk-GZA7RGK7.js";
|
|
19
|
-
import "./chunk-RVJVM5L4.js";
|
|
20
|
-
import "./chunk-CJRZSWII.js";
|
|
21
|
-
import {
|
|
22
|
-
registerLensSynthCommand
|
|
23
|
-
} from "./chunk-VU7V2SDW.js";
|
|
24
|
-
import "./chunk-W624J7NF.js";
|
|
18
|
+
} from "./chunk-MOGWEHSC.js";
|
|
25
19
|
import {
|
|
26
20
|
buildFindingChatPrompt,
|
|
27
21
|
buildFindingConsoleCommand,
|
|
28
22
|
createLocalConsoleSession,
|
|
29
23
|
loadFindingFocus,
|
|
24
|
+
localZeroverseRuntime,
|
|
25
|
+
registerVerifyCommand,
|
|
30
26
|
resolveFindingChatIntent,
|
|
31
27
|
runUnified
|
|
32
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-UQS7XCBV.js";
|
|
29
|
+
import "./chunk-Z2VLJEQJ.js";
|
|
30
|
+
import "./chunk-K3PTYN43.js";
|
|
33
31
|
import {
|
|
34
32
|
TIMELINE_FORMATS,
|
|
35
33
|
formatTimeline,
|
|
36
|
-
getRuntimeAvailability,
|
|
37
34
|
isTimelineFormat,
|
|
38
35
|
renderReplay
|
|
39
|
-
} from "./chunk-
|
|
40
|
-
import
|
|
36
|
+
} from "./chunk-FBZBJYZS.js";
|
|
37
|
+
import {
|
|
38
|
+
registerRoutingCommand
|
|
39
|
+
} from "./chunk-JGDA6EIJ.js";
|
|
41
40
|
import {
|
|
42
41
|
executeManagedOperation
|
|
43
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-MOEVVXML.js";
|
|
43
|
+
import "./chunk-YJGPPPUB.js";
|
|
44
|
+
import "./chunk-ZPVSDB63.js";
|
|
44
45
|
import {
|
|
45
|
-
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import "./chunk-
|
|
46
|
+
getRuntimeAvailability
|
|
47
|
+
} from "./chunk-MNK373HF.js";
|
|
48
|
+
import "./chunk-KCABBZHN.js";
|
|
48
49
|
import {
|
|
50
|
+
BackendConnectionError,
|
|
51
|
+
BackendConnectionRegistry,
|
|
52
|
+
backendBearerFromEnv,
|
|
49
53
|
deployWorker,
|
|
54
|
+
loadBackendConnectionConfig,
|
|
55
|
+
repairWorker,
|
|
50
56
|
stopWorker,
|
|
51
57
|
validateWorkerOptions
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import {
|
|
54
|
-
performAutoUpdate
|
|
55
|
-
} from "./chunk-7UHAXEOV.js";
|
|
56
|
-
import {
|
|
57
|
-
Command,
|
|
58
|
-
InvalidArgumentError,
|
|
59
|
-
Option
|
|
60
|
-
} from "./chunk-WUPN3D37.js";
|
|
58
|
+
} from "./chunk-UGCTPKJG.js";
|
|
61
59
|
import {
|
|
62
60
|
consolePresentationOutput,
|
|
61
|
+
performAutoUpdate,
|
|
63
62
|
processPresentationOutput,
|
|
64
63
|
writePresentationLine
|
|
65
|
-
} from "./chunk-
|
|
66
|
-
import "./chunk-56UTQKXO.js";
|
|
64
|
+
} from "./chunk-D4M5WURF.js";
|
|
67
65
|
import {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
Command,
|
|
67
|
+
InvalidArgumentError,
|
|
68
|
+
Option
|
|
69
|
+
} from "./chunk-S4DFH2FJ.js";
|
|
70
|
+
import "./chunk-A7G6S5RA.js";
|
|
71
|
+
import "./chunk-OILVEROI.js";
|
|
71
72
|
import {
|
|
72
73
|
source_default
|
|
73
74
|
} from "./chunk-HLFS6WV2.js";
|
|
74
75
|
import {
|
|
75
|
-
|
|
76
|
+
DEFAULT_SETTINGS,
|
|
76
77
|
SETTING_DEFS,
|
|
77
|
-
THEMES,
|
|
78
|
-
THEME_NAMES,
|
|
79
|
-
installedThemeEntries,
|
|
80
|
-
installedThemesDir,
|
|
81
|
-
isKnownTheme,
|
|
82
|
-
isSafeThemeId,
|
|
83
78
|
loadGlobalSettings,
|
|
84
79
|
loadLayeredSettings,
|
|
85
|
-
loadSettings,
|
|
86
80
|
normalizeSettings,
|
|
87
81
|
projectSettingsFilePath,
|
|
88
82
|
readProjectOverrides,
|
|
89
|
-
reloadInstalledThemes,
|
|
90
|
-
removeInstalledTheme,
|
|
91
83
|
sanitizeOverrides,
|
|
92
84
|
saveProjectOverrides,
|
|
93
85
|
saveSettings,
|
|
94
|
-
settingsFilePath
|
|
95
|
-
|
|
96
|
-
writeInstalledTheme
|
|
97
|
-
} from "./chunk-X2IPO5JO.js";
|
|
86
|
+
settingsFilePath
|
|
87
|
+
} from "./chunk-V2KJQVYE.js";
|
|
98
88
|
import {
|
|
99
89
|
CraftMemoryStore,
|
|
100
90
|
DEFAULT_MAX_TOOL_ITERATIONS,
|
|
@@ -107,91 +97,48 @@ import {
|
|
|
107
97
|
H1NetworkError,
|
|
108
98
|
H1RateLimitError,
|
|
109
99
|
McpServer,
|
|
110
|
-
ObjectiveOracle,
|
|
111
100
|
ReadBuffer,
|
|
112
|
-
agentActionConfigurationChanges,
|
|
113
|
-
agentActionManifestSha256,
|
|
114
|
-
agenticScan,
|
|
115
|
-
appendLedgerEntry,
|
|
116
|
-
approveObservation,
|
|
117
101
|
atlasTechniquesForEvent,
|
|
118
102
|
automationVerdict,
|
|
119
|
-
captureObservation,
|
|
120
|
-
compareScorecards,
|
|
121
103
|
consolidateMemory,
|
|
122
|
-
corpusV1Path,
|
|
123
|
-
createAgenticScanAdapter,
|
|
124
|
-
createBenchIntegrationRegistry,
|
|
125
104
|
createConsoleRuntime,
|
|
126
|
-
createCoreBenchIntegration,
|
|
127
|
-
createVariantExecutionFactory,
|
|
128
105
|
defaultCraftCandidateReviewer,
|
|
129
|
-
digestBenchManifest,
|
|
130
106
|
enumerateTargetModelFromKext,
|
|
131
|
-
evaluateRegression,
|
|
132
|
-
formatTournamentSummary,
|
|
133
107
|
generateInputsForSelector,
|
|
134
108
|
generateSyzChoiceWeights,
|
|
135
109
|
getProgram,
|
|
136
110
|
getStructuredScopes,
|
|
137
|
-
|
|
138
|
-
lastGreen,
|
|
139
|
-
listObservations,
|
|
111
|
+
inspectLensRegistry,
|
|
140
112
|
listPrograms,
|
|
141
113
|
listProjectReviewChecks,
|
|
142
114
|
loadH1Credentials,
|
|
143
|
-
loadLedger,
|
|
144
|
-
loadManifest,
|
|
145
115
|
makeRng,
|
|
146
|
-
mcpAgentTarget,
|
|
147
|
-
objectiveOracleEvaluatorAttestation,
|
|
148
|
-
objectiveOracleEvaluatorCodeBytes,
|
|
149
|
-
objectiveOracleEvaluatorConfigJson,
|
|
150
|
-
pairwiseDeltas,
|
|
151
|
-
parseApprovedObservationShape,
|
|
152
|
-
parseEnsembleModels,
|
|
153
|
-
parseManifest,
|
|
154
|
-
parseObservationInput,
|
|
155
|
-
pickChampion,
|
|
156
116
|
planSingleShardRun,
|
|
157
117
|
preseedMemory,
|
|
158
|
-
projectResearchExecutionEvidence,
|
|
159
|
-
projectResearchImprovementResult,
|
|
160
118
|
radarCandidatesToSeedFindings,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
researchExecutionEvidenceRef,
|
|
164
|
-
runAgentActionAssurance,
|
|
165
|
-
runEnsembleCraft,
|
|
119
|
+
retireArchetype,
|
|
120
|
+
runLensSynthesisLoop,
|
|
166
121
|
runSecureProject,
|
|
167
|
-
runTournament,
|
|
168
|
-
saveLedger,
|
|
169
122
|
scan,
|
|
170
123
|
scanRepoCommitsWithJev,
|
|
171
124
|
selectorModelToLine,
|
|
172
125
|
serializeMessage,
|
|
173
|
-
snapshotBenchVariant,
|
|
174
|
-
subsetManifest,
|
|
175
126
|
summariseScopes,
|
|
176
127
|
syzChoiceWeightsFromPlan,
|
|
177
128
|
techniquesForEvent,
|
|
178
129
|
toScopeFile,
|
|
179
|
-
updateProjectReviewChecks
|
|
180
|
-
|
|
181
|
-
writeAgentActionEvidenceBundle
|
|
182
|
-
} from "./chunk-ZM6ANQZJ.js";
|
|
130
|
+
updateProjectReviewChecks
|
|
131
|
+
} from "./chunk-3MWQNNJU.js";
|
|
183
132
|
import {
|
|
184
133
|
formatSarif
|
|
185
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-YP2DHYNI.js";
|
|
186
135
|
import {
|
|
187
136
|
adaptAndVerify
|
|
188
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-XJ2TBEV7.js";
|
|
189
138
|
import {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
} from "./chunk-BOBIAHKA.js";
|
|
194
|
-
import "./chunk-ILRMLA6J.js";
|
|
139
|
+
enumerateJsChunkUrls
|
|
140
|
+
} from "./chunk-STPHTPSD.js";
|
|
141
|
+
import "./chunk-VWE36MUN.js";
|
|
195
142
|
import {
|
|
196
143
|
createLiveHttpSender
|
|
197
144
|
} from "./chunk-GVD6SJGH.js";
|
|
@@ -203,8 +150,7 @@ import {
|
|
|
203
150
|
import {
|
|
204
151
|
getEvalCategories,
|
|
205
152
|
runEval
|
|
206
|
-
} from "./chunk-
|
|
207
|
-
import "./chunk-IIBNQTOK.js";
|
|
153
|
+
} from "./chunk-NABVDAAO.js";
|
|
208
154
|
import {
|
|
209
155
|
runNpmDynamicDiscovery
|
|
210
156
|
} from "./chunk-2WNCI664.js";
|
|
@@ -216,74 +162,122 @@ import {
|
|
|
216
162
|
DETECTOR_REGISTRY,
|
|
217
163
|
resolveDetectors
|
|
218
164
|
} from "./chunk-DQTNI3KY.js";
|
|
219
|
-
import "./chunk-
|
|
220
|
-
import "./chunk-UJE4WOQS.js";
|
|
165
|
+
import "./chunk-NA3FKCI2.js";
|
|
221
166
|
import {
|
|
222
167
|
prepare
|
|
223
|
-
} from "./chunk-
|
|
224
|
-
import "./chunk-
|
|
225
|
-
import "./chunk-
|
|
226
|
-
import "./chunk-TVS6WVSK.js";
|
|
227
|
-
import "./chunk-YSQWZ67M.js";
|
|
168
|
+
} from "./chunk-HUZ2EC2R.js";
|
|
169
|
+
import "./chunk-N7YCONYR.js";
|
|
170
|
+
import "./chunk-BM6EYP2D.js";
|
|
228
171
|
import {
|
|
172
|
+
ObjectiveOracle,
|
|
229
173
|
ToolExecutor,
|
|
174
|
+
agentActionConfigurationChanges,
|
|
175
|
+
agentActionManifestSha256,
|
|
176
|
+
agenticScan,
|
|
230
177
|
aggregateScorecard,
|
|
178
|
+
appendLedgerEntry,
|
|
231
179
|
approveEvolutionCandidate,
|
|
180
|
+
approveObservation,
|
|
232
181
|
bucketInScope,
|
|
182
|
+
captureObservation,
|
|
233
183
|
classifyTakeover,
|
|
184
|
+
compareScorecards,
|
|
185
|
+
corpusV1Path,
|
|
186
|
+
createAgenticScanAdapter,
|
|
187
|
+
createBenchIntegrationRegistry,
|
|
188
|
+
createCoreBenchIntegration,
|
|
189
|
+
createVariantExecutionFactory,
|
|
234
190
|
describeEngagementPosture,
|
|
191
|
+
digestBenchManifest,
|
|
192
|
+
evaluateRegression,
|
|
235
193
|
executeEvolutionVersion,
|
|
236
194
|
extractAttributionFromScopeJson,
|
|
237
195
|
extractEngagementFromScopeJson,
|
|
238
196
|
fetchScoped,
|
|
197
|
+
formatTournamentSummary,
|
|
239
198
|
getToolsForRole,
|
|
199
|
+
harvestMissesFromLedgerEntry,
|
|
200
|
+
httpActionOracle,
|
|
201
|
+
lastGreen,
|
|
202
|
+
listObservations,
|
|
240
203
|
loadEvolutionCampaign,
|
|
241
204
|
loadEvolutionRegistry,
|
|
205
|
+
loadLedger,
|
|
206
|
+
loadManifest,
|
|
207
|
+
makeFinderLensProbe,
|
|
208
|
+
mcpAgentTarget,
|
|
209
|
+
mergeHarvestedMisses,
|
|
242
210
|
networkScopeRequiredRefusal,
|
|
211
|
+
objectiveOracleEvaluatorAttestation,
|
|
212
|
+
objectiveOracleEvaluatorCodeBytes,
|
|
213
|
+
objectiveOracleEvaluatorConfigJson,
|
|
214
|
+
pairwiseDeltas,
|
|
215
|
+
parseApprovedObservationShape,
|
|
216
|
+
parseEnsembleModels,
|
|
217
|
+
parseManifest,
|
|
218
|
+
parseObservationInput,
|
|
219
|
+
pickChampion,
|
|
243
220
|
probeS3Bucket,
|
|
221
|
+
projectResearchExecutionEvidence,
|
|
222
|
+
projectResearchImprovementResult,
|
|
244
223
|
reconcileCampaignDispatch,
|
|
224
|
+
releaseClaim,
|
|
225
|
+
renderScoreboard,
|
|
226
|
+
researchExecutionEvidenceRef,
|
|
245
227
|
resolveAttribution,
|
|
246
228
|
resolveEngagementProfile,
|
|
247
229
|
rollbackEvolutionVersion,
|
|
230
|
+
runAgentActionAssurance,
|
|
231
|
+
runEnsembleCraft,
|
|
248
232
|
runEvolution,
|
|
249
233
|
runJsRecon,
|
|
250
234
|
runRecon,
|
|
251
235
|
runSmolvmPocSteps,
|
|
236
|
+
runTournament,
|
|
237
|
+
saveLedger,
|
|
238
|
+
snapshotBenchVariant,
|
|
239
|
+
subsetManifest,
|
|
252
240
|
targetRequiresScope,
|
|
253
241
|
validateAwsCredentials,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
242
|
+
withVariantFeatureFlags,
|
|
243
|
+
workflowPolicyRuntime,
|
|
244
|
+
writeAgentActionEvidenceBundle
|
|
245
|
+
} from "./chunk-SIR7XW2S.js";
|
|
246
|
+
import "./chunk-LRD5N2TQ.js";
|
|
257
247
|
import "./chunk-K2PWUPUI.js";
|
|
258
248
|
import {
|
|
249
|
+
RateLimiter,
|
|
259
250
|
buildIntelDossier,
|
|
260
251
|
lookupCve,
|
|
252
|
+
parseRateLimitFlag,
|
|
261
253
|
searchAdvisories,
|
|
262
254
|
searchSimilar,
|
|
263
255
|
searchTargetHistory
|
|
264
|
-
} from "./chunk-
|
|
265
|
-
import "./chunk-
|
|
256
|
+
} from "./chunk-6SNOKNCS.js";
|
|
257
|
+
import "./chunk-PAE7ZAV6.js";
|
|
266
258
|
import "./chunk-UEX7PFSE.js";
|
|
267
|
-
import "./chunk-
|
|
259
|
+
import "./chunk-6GV5G6U3.js";
|
|
260
|
+
import "./chunk-R7VWEY45.js";
|
|
268
261
|
import {
|
|
269
262
|
budgetNativeRuntime
|
|
270
|
-
} from "./chunk-
|
|
271
|
-
import "./chunk-
|
|
263
|
+
} from "./chunk-SSPP64FF.js";
|
|
264
|
+
import "./chunk-AZ7L3HFD.js";
|
|
265
|
+
import "./chunk-B7XL6RON.js";
|
|
272
266
|
import {
|
|
273
267
|
runSourceFix
|
|
274
|
-
} from "./chunk-
|
|
268
|
+
} from "./chunk-AFJ2UMPR.js";
|
|
275
269
|
import {
|
|
276
270
|
appendImprovementLedgerEntry,
|
|
277
271
|
evaluateImprovementPromotion,
|
|
278
272
|
loadEvolutionConfigFile,
|
|
279
273
|
verifyImprovementLedger
|
|
280
|
-
} from "./chunk-
|
|
274
|
+
} from "./chunk-YGYJ2FTH.js";
|
|
281
275
|
import {
|
|
282
276
|
runHttpConformanceCheck
|
|
283
|
-
} from "./chunk-
|
|
277
|
+
} from "./chunk-LWMEJYCP.js";
|
|
284
278
|
import {
|
|
285
279
|
createRuntime
|
|
286
|
-
} from "./chunk-
|
|
280
|
+
} from "./chunk-EHNVP6QB.js";
|
|
287
281
|
import "./chunk-O6KPVYOI.js";
|
|
288
282
|
import {
|
|
289
283
|
buildAdGraph,
|
|
@@ -303,7 +297,7 @@ import {
|
|
|
303
297
|
resolveOsecDbPath,
|
|
304
298
|
resolveOsecRunStorage,
|
|
305
299
|
writeOsecRunReport
|
|
306
|
-
} from "./chunk-
|
|
300
|
+
} from "./chunk-72PU46MS.js";
|
|
307
301
|
import {
|
|
308
302
|
DISCLOSURE_STATUSES,
|
|
309
303
|
IncompleteEvidenceError,
|
|
@@ -322,46 +316,48 @@ import {
|
|
|
322
316
|
renderReproducibilityManifest,
|
|
323
317
|
renderVendorNotificationMarkdown,
|
|
324
318
|
transition
|
|
325
|
-
} from "./chunk-
|
|
319
|
+
} from "./chunk-WPJMA5AK.js";
|
|
326
320
|
import {
|
|
327
321
|
executePocSteps
|
|
328
|
-
} from "./chunk-
|
|
322
|
+
} from "./chunk-XPDJE537.js";
|
|
329
323
|
import {
|
|
330
324
|
findCveArtifacts,
|
|
331
325
|
normaliseCveId
|
|
332
|
-
} from "./chunk-
|
|
333
|
-
import "./chunk-
|
|
334
|
-
import "./chunk-
|
|
326
|
+
} from "./chunk-IUUNIJPM.js";
|
|
327
|
+
import "./chunk-ABKUI3QB.js";
|
|
328
|
+
import "./chunk-PAMJEXE2.js";
|
|
335
329
|
import {
|
|
336
330
|
LlmApiRuntime,
|
|
337
331
|
features
|
|
338
|
-
} from "./chunk-
|
|
332
|
+
} from "./chunk-HS2NQ7K6.js";
|
|
339
333
|
import {
|
|
340
334
|
isAdmittedSmolvmWorkbench
|
|
341
|
-
} from "./chunk-
|
|
335
|
+
} from "./chunk-XOVYV7TT.js";
|
|
342
336
|
import {
|
|
343
337
|
eventBus
|
|
344
|
-
} from "./chunk-
|
|
338
|
+
} from "./chunk-ULRLUXSS.js";
|
|
345
339
|
import "./chunk-RS4MAN3Q.js";
|
|
346
340
|
import {
|
|
347
341
|
EmptyPocError,
|
|
348
342
|
detectVersionRange,
|
|
349
343
|
renderAdvisoryMarkdown,
|
|
350
344
|
verifyAgainstRef
|
|
351
|
-
} from "./chunk-
|
|
345
|
+
} from "./chunk-VJBEB2K6.js";
|
|
352
346
|
import {
|
|
353
347
|
ScopePolicy,
|
|
354
348
|
getScopeEnforcementState,
|
|
355
349
|
isScopeEnforcementEnabled,
|
|
356
350
|
loadScope
|
|
357
|
-
} from "./chunk-
|
|
351
|
+
} from "./chunk-RZZ6VPRY.js";
|
|
358
352
|
import "./chunk-5IBCBQEH.js";
|
|
359
353
|
import {
|
|
360
354
|
AgentActionScenarioSchema,
|
|
355
|
+
BACKEND_PROTOCOL_VERSION,
|
|
361
356
|
DEFAULT_AUTONOMY_MODE,
|
|
362
357
|
DEFAULT_SEVERITY_FLOOR,
|
|
363
358
|
SecurityWorkflowBindingsSchema,
|
|
364
359
|
VERSION,
|
|
360
|
+
backendCapabilitiesForApiPath,
|
|
365
361
|
compareFindingsByBusinessPriority,
|
|
366
362
|
createJevEvaluator,
|
|
367
363
|
findingSchema,
|
|
@@ -371,15 +367,131 @@ import {
|
|
|
371
367
|
meetsSeverityFloor,
|
|
372
368
|
parseAgentActionEvidenceManifest,
|
|
373
369
|
pocStepArraySchema,
|
|
374
|
-
reportSummarySchema
|
|
375
|
-
|
|
370
|
+
reportSummarySchema,
|
|
371
|
+
validateScanPlan
|
|
372
|
+
} from "./chunk-GYEYTNHK.js";
|
|
376
373
|
import {
|
|
377
374
|
external_exports
|
|
378
|
-
} from "./chunk-
|
|
375
|
+
} from "./chunk-5XOYTAOK.js";
|
|
376
|
+
import "./chunk-36J5ZLFE.js";
|
|
379
377
|
import "./chunk-VCSFCHAJ.js";
|
|
380
378
|
|
|
381
379
|
// packages/cli/src/commands/scan.ts
|
|
382
380
|
import { readFileSync, existsSync } from "node:fs";
|
|
381
|
+
|
|
382
|
+
// packages/cli/src/guided-scan.ts
|
|
383
|
+
import { createInterface } from "node:readline/promises";
|
|
384
|
+
|
|
385
|
+
// packages/cli/src/tui/scan-plan.ts
|
|
386
|
+
function recommendedScanGoal(kind) {
|
|
387
|
+
if (kind === "package") return "known-vulnerabilities";
|
|
388
|
+
if (kind === "web") return "misconfigurations";
|
|
389
|
+
return "unknown-vulnerabilities";
|
|
390
|
+
}
|
|
391
|
+
function recommendedScanDepth(goal) {
|
|
392
|
+
return goal === "unknown-vulnerabilities" ? "deep" : "default";
|
|
393
|
+
}
|
|
394
|
+
function recommendedTimeCapMs(kind, depth) {
|
|
395
|
+
if (kind === "web") {
|
|
396
|
+
return depth === "deep" ? 3e5 : depth === "default" ? 6e4 : 3e4;
|
|
397
|
+
}
|
|
398
|
+
return depth === "deep" ? 18e5 : depth === "default" ? 6e5 : 3e5;
|
|
399
|
+
}
|
|
400
|
+
function formatTimeCap(ms) {
|
|
401
|
+
if (ms < 6e4) return `${Math.round(ms / 1e3)}s`;
|
|
402
|
+
const minutes = ms / 6e4;
|
|
403
|
+
return Number.isInteger(minutes) ? `${minutes}m` : `${minutes.toFixed(1)}m`;
|
|
404
|
+
}
|
|
405
|
+
function formatGoal(goal) {
|
|
406
|
+
return goal === "known-vulnerabilities" ? "known vulnerabilities" : goal === "unknown-vulnerabilities" ? "unknown vulnerabilities" : "misconfigurations";
|
|
407
|
+
}
|
|
408
|
+
function scanDepthExplanation(goal) {
|
|
409
|
+
return goal === "unknown-vulnerabilities" ? "Deep is suggested for broader investigation and reproduction; it takes more effort. Your selected limits still apply." : "Default is suggested for focused checks and reproduction without the effort of a deep investigation.";
|
|
410
|
+
}
|
|
411
|
+
var SCAN_RUNS_HELP = "Start with 1 run. Extra runs repeat the selected scope; each run can already use subagents. All runs share the same limits.";
|
|
412
|
+
var SCAN_MODE_HELP = "Sequential is suggested for lower concurrency. Parallel overlaps runs and may finish sooner, but can consume the shared budget sooner.";
|
|
413
|
+
var SCAN_COST_HELP = "Estimated USD limit shared by every run and subagent. In-flight requests can exceed it before usage is reported. Unknown cost is not zero; this is not a guaranteed provider charge ceiling.";
|
|
414
|
+
|
|
415
|
+
// packages/cli/src/guided-scan.ts
|
|
416
|
+
var SCAN_MODEL_ROLES = ["discovery", "attack", "verify", "report"];
|
|
417
|
+
function parseScanModelAssignments(values) {
|
|
418
|
+
const assignments = {};
|
|
419
|
+
for (const value of values) {
|
|
420
|
+
const separator = value.indexOf("=");
|
|
421
|
+
const role = value.slice(0, separator);
|
|
422
|
+
const model = value.slice(separator + 1).trim();
|
|
423
|
+
if (separator < 1 || !SCAN_MODEL_ROLES.includes(role) || !model || model === "auto" || /[\r\n\0]/.test(model)) {
|
|
424
|
+
throw new Error("--task-model requires discovery|attack|verify|report=MODEL (an explicit model ID).");
|
|
425
|
+
}
|
|
426
|
+
if (Object.hasOwn(assignments, role)) throw new Error(`Duplicate task model for ${role}.`);
|
|
427
|
+
assignments[role] = model;
|
|
428
|
+
}
|
|
429
|
+
return assignments;
|
|
430
|
+
}
|
|
431
|
+
function scanRoutingSummary(model, assignments = {}, singleModel = false) {
|
|
432
|
+
const fallback = model ?? "configured session model";
|
|
433
|
+
return SCAN_MODEL_ROLES.map((role) => `${role}: ${singleModel ? fallback : assignments[role] ?? fallback}`).join(" \xB7 ");
|
|
434
|
+
}
|
|
435
|
+
async function collectGuidedScanPlan(options, io) {
|
|
436
|
+
const choose = async (label, choices, recommended) => {
|
|
437
|
+
while (true) {
|
|
438
|
+
const answer = (await io.question(`${label} (${choices.join(" / ")}) [${recommended}]: `)).trim();
|
|
439
|
+
if (!answer) return recommended;
|
|
440
|
+
if (choices.includes(answer)) return answer;
|
|
441
|
+
io.write("Choose one of the listed values.\n");
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
const positive2 = async (label, fallback, integer = false, max = Infinity) => {
|
|
445
|
+
while (true) {
|
|
446
|
+
const raw = (await io.question(`${label} [${fallback}]: `)).trim();
|
|
447
|
+
const value = raw ? Number(raw) : fallback;
|
|
448
|
+
if (Number.isFinite(value) && value > 0 && value <= max && (!integer || Number.isSafeInteger(value))) return value;
|
|
449
|
+
io.write(`Enter a positive ${integer ? "integer" : "number"}${max < Infinity ? ` no greater than ${max}` : ""}.
|
|
450
|
+
`);
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
io.write(`Scope: ${options.target}
|
|
454
|
+
Recommendations keep this scope unchanged.
|
|
455
|
+
`);
|
|
456
|
+
const goal = await choose("Goal", ["known-vulnerabilities", "unknown-vulnerabilities", "misconfigurations"], recommendedScanGoal("web"));
|
|
457
|
+
io.write(`${scanDepthExplanation(goal)} Unknown vulnerabilities are an objective, not a promised result.
|
|
458
|
+
`);
|
|
459
|
+
const depth = await choose("Depth", ["quick", "default", "deep"], options.depth ?? recommendedScanDepth(goal));
|
|
460
|
+
io.write(`${SCAN_RUNS_HELP}
|
|
461
|
+
`);
|
|
462
|
+
const runCount = await positive2("Separate runs", 1, true, 16);
|
|
463
|
+
io.write(`${SCAN_MODE_HELP}
|
|
464
|
+
`);
|
|
465
|
+
const executionMode = await choose("Execution", ["sequential", "parallel"], "sequential");
|
|
466
|
+
io.write("This planner supports up to 24 hours and $1,000 estimated for the whole plan.\n");
|
|
467
|
+
const timeCapMs = await positive2("Total wall-clock cap (minutes)", recommendedTimeCapMs("web", depth) / 6e4, false, 1440) * 6e4;
|
|
468
|
+
io.write(`${SCAN_COST_HELP}
|
|
469
|
+
`);
|
|
470
|
+
const costCapUsd = await positive2("Total estimated cost cap (USD)", Math.min(options.costCapUsd ?? 5, 1e3), false, 1e3);
|
|
471
|
+
const plan = { goal, depth, runCount, executionMode, timeCapMs, costCapUsd };
|
|
472
|
+
validateScanPlan(plan);
|
|
473
|
+
io.write(`
|
|
474
|
+
${options.target} \xB7 ${formatGoal(goal)} \xB7 ${depth} \xB7 ${runCount} separate run(s) \xB7 ${executionMode} \xB7 ${formatTimeCap(timeCapMs)} total \xB7 $${costCapUsd} total estimated
|
|
475
|
+
`);
|
|
476
|
+
const routing = options.singleModel ? void 0 : options.recommendRouting?.(plan);
|
|
477
|
+
if (routing) for (const role of SCAN_MODEL_ROLES) io.write(`${role}: ${routing.reasons[role]}
|
|
478
|
+
`);
|
|
479
|
+
io.write(`${scanRoutingSummary(options.model, routing?.assignments ?? options.agentModels, options.singleModel)}
|
|
480
|
+
Configured models are operator choices; no task-specific superiority is assumed. Override with --task-model ROLE=MODEL or --single-model.
|
|
481
|
+
`);
|
|
482
|
+
const confirmed = (await io.question("Start this plan? [y/N]: ")).trim().toLowerCase();
|
|
483
|
+
return confirmed === "y" || confirmed === "yes" ? plan : void 0;
|
|
484
|
+
}
|
|
485
|
+
async function guidedScanPlan(options) {
|
|
486
|
+
const readline = createInterface({ input: process.stdin, output: process.stderr });
|
|
487
|
+
try {
|
|
488
|
+
return await collectGuidedScanPlan(options, { question: (prompt) => readline.question(prompt), write: (text2) => process.stderr.write(text2) });
|
|
489
|
+
} finally {
|
|
490
|
+
readline.close();
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// packages/cli/src/commands/scan.ts
|
|
383
495
|
function parseAuthFlag(value) {
|
|
384
496
|
let raw;
|
|
385
497
|
if (!value.trimStart().startsWith("{") && existsSync(value)) {
|
|
@@ -431,16 +543,27 @@ function parseIdentitiesFile(path) {
|
|
|
431
543
|
}
|
|
432
544
|
}
|
|
433
545
|
var fixtureSchema = external_exports.array(external_exports.object({
|
|
434
|
-
url: external_exports.string().url().refine((url) =>
|
|
546
|
+
url: external_exports.string().url().max(8192).refine((url) => {
|
|
547
|
+
const parsed = new URL(url);
|
|
548
|
+
return /^https?:/.test(url) && !parsed.username && !parsed.password;
|
|
549
|
+
}),
|
|
435
550
|
ownerIdentity: external_exports.string().min(1),
|
|
436
551
|
comparisonIdentities: external_exports.array(external_exports.string().min(1)).min(1).max(16),
|
|
437
|
-
ownershipMarker: external_exports.string().min(16).max(500)
|
|
438
|
-
|
|
552
|
+
ownershipMarker: external_exports.string().min(16).max(500),
|
|
553
|
+
stateChange: external_exports.object({
|
|
554
|
+
disposable: external_exports.literal(true),
|
|
555
|
+
jsonPointer: external_exports.string().regex(/^(?:\/(?:[^~]|~[01])*)?$/),
|
|
556
|
+
stepUrls: external_exports.array(external_exports.string().url().max(8192).refine((url) => /^https?:/.test(url))).min(1).max(10)
|
|
557
|
+
}).strict().optional()
|
|
558
|
+
}).strict().refine((fixture) => !fixture.stateChange || fixture.stateChange.stepUrls.every((url) => {
|
|
559
|
+
const step = new URL(url), observation = new URL(fixture.url);
|
|
560
|
+
return step.origin === observation.origin && !step.username && !step.password;
|
|
561
|
+
}))).min(1).max(100);
|
|
439
562
|
function parseAccessControlFixturesFile(path) {
|
|
440
563
|
try {
|
|
441
564
|
return fixtureSchema.parse(JSON.parse(readFileSync(path, "utf8")));
|
|
442
565
|
} catch {
|
|
443
|
-
throw new Error("Invalid --access-control-fixtures file: expected
|
|
566
|
+
throw new Error("Invalid --access-control-fixtures file: expected ownership fixtures with URLs, owner/comparison labels, private markers and valid optional disposable-state contracts");
|
|
444
567
|
}
|
|
445
568
|
}
|
|
446
569
|
function parseStringArrayEnv(name, raw) {
|
|
@@ -505,14 +628,14 @@ var PRESET_TOKENS = /* @__PURE__ */ new Set([
|
|
|
505
628
|
"moat"
|
|
506
629
|
]);
|
|
507
630
|
function registerScanCommand(program) {
|
|
508
|
-
program.command("scan").description("Run autonomous pentest against a URL, web app, or MCP server").requiredOption("--target <target>", "Target URL or mcp:// endpoint").option("--depth <depth>", "Scan depth: quick, default, deep", "default").option("--format <format>", "Output format: terminal, json, md, html, sarif, pdf", "terminal").option("--runtime <runtime>", "Model provider: auto, api, claude, codex, gemini", "auto").option("--mode <mode>", "Scan mode: probe, deep, mcp, web, http_audit (http_audit reads ZERO_TARGET_* env config)").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--db-path <path>", "Path to SQLite database").option("--api-key <key>", "API key for LLM provider").option("-m, --model <model>", "LLM model to use").option("--repo <path>", "Source code path for white-box scanning").option("--access-control-fixtures <file>", "JSON file of known private resource ownership fixtures for IDOR verification").option("--identities <file>", "Restricted JSON file with named test identities for access-control replay").option("--auth <json>", "Auth credentials: JSON string or path (bearer, cookie, basic, header)").option("--scope <path>", "Path to a JSON scope policy (enable with `0 plugin enable scope`)").option("--allow-scanners", "Expose generic scanner tools in scope-enforced scans", false).option("--require-scope", "Refuse unscoped scans while the scope plugin is enabled", false).option(
|
|
631
|
+
program.command("scan").description("Run autonomous pentest against a URL, web app, or MCP server").requiredOption("--target <target>", "Target URL or mcp:// endpoint").option("--depth <depth>", "Scan depth: quick, default, deep", "default").option("--format <format>", "Output format: terminal, json, md, html, sarif, pdf", "terminal").option("--runtime <runtime>", "Model provider: auto, api, claude, codex, gemini", "auto").option("--mode <mode>", "Scan mode: probe, deep, mcp, web, http_audit (http_audit reads ZERO_TARGET_* env config)").option("--timeout <ms>", "Request timeout in milliseconds", "30000").option("--db-path <path>", "Path to SQLite database").option("--api-key <key>", "API key for LLM provider").option("-m, --model <model>", "LLM model to use").option("--task-model <role=model>", "Explicit task model: discovery, attack, verify, report (repeatable)", (value, previous = []) => [...previous, value]).option("--routing-report <file>", "Reviewed model-api task qualification report; opt-in recommendations only").option("--routing-model <model>", "Approve a model candidate for the reviewed routing plan (repeatable)", (value, previous = []) => [...previous, value]).option("--routing-review-ref <ref>", "Review reference confirming provider/workflow authorization and model evidence limitations").option("--goal <goal>", "Noninteractive routing goal: known-vulnerabilities, unknown-vulnerabilities, misconfigurations").option("--plan-time-cap <ms>", "Overall wall-clock cap required for a noninteractive routing plan").option("--single-model", "Use the selected model for every task, ignoring task assignments").option("--no-guided", "Skip interactive scan planning and use explicit command options").option("--repo <path>", "Source code path for white-box scanning").option("--access-control-fixtures <file>", "JSON file of known private resource ownership fixtures for IDOR verification").option("--identities <file>", "Restricted JSON file with named test identities for access-control replay").option("--auth <json>", "Auth credentials: JSON string or path (bearer, cookie, basic, header)").option("--scope <path>", "Path to a JSON scope policy (enable with `0 plugin enable scope`)").option("--allow-scanners", "Expose generic scanner tools in scope-enforced scans", false).option("--require-scope", "Refuse unscoped scans while the scope plugin is enabled", false).option(
|
|
509
632
|
"--attribution-header <name=value>",
|
|
510
633
|
"Header to attach to in-scope requests (repeatable); never sent out-of-scope",
|
|
511
634
|
(value, prev = []) => [...prev, value]
|
|
512
635
|
).option(
|
|
513
636
|
"--attribution-ua <token>",
|
|
514
637
|
"Engagement token to embed in the User-Agent on in-scope traffic"
|
|
515
|
-
).option("--api-spec <path>", "Path to an OpenAPI/Swagger spec for endpoint knowledge").option("--export <target>", "Export findings to issue tracker (e.g. github:owner/repo)").addOption(new Option("--race", "Best-of-N strategy racing (benchmark/CTF only)").default(false).hideHelp()).addOption(new Option("--egats", "Evidence-gated attack tree search").default(false).hideHelp()).option("--cost-ceiling <usd>", "
|
|
638
|
+
).option("--api-spec <path>", "Path to an OpenAPI/Swagger spec for endpoint knowledge").option("--export <target>", "Export findings to issue tracker (e.g. github:owner/repo)").addOption(new Option("--race", "Best-of-N strategy racing (benchmark/CTF only)").default(false).hideHelp()).addOption(new Option("--egats", "Evidence-gated attack tree search").default(false).hideHelp()).option("--cost-ceiling <usd>", "Estimated USD stopping threshold; in-flight usage may overshoot, partial findings retained").option(
|
|
516
639
|
"--rate-limit <spec>",
|
|
517
640
|
"Per-host requests/sec cap, e.g. '5' or 'host=5,*=3' (default 5)"
|
|
518
641
|
).option(
|
|
@@ -521,16 +644,16 @@ function registerScanCommand(program) {
|
|
|
521
644
|
).option(
|
|
522
645
|
"--no-waf-evasion",
|
|
523
646
|
"Disable adaptive WAF-evasion retries"
|
|
524
|
-
).option(
|
|
647
|
+
).option(
|
|
525
648
|
"--features <list>",
|
|
526
649
|
"Comma-separated feature flags to enable, e.g. 'fp-moat'"
|
|
527
650
|
).addOption(new Option("--no-decoy-detection", "Disable the anti-honeypot flag validator").hideHelp()).addOption(new Option("--dispatch <mode>", "Tool-call protocol: json, xml, auto (legacy loop only)").default("auto").hideHelp()).option(
|
|
528
651
|
"--emit <target>",
|
|
529
652
|
"Emit mode: 'pr' opens a GitHub PR per reproduced finding"
|
|
530
|
-
).option("--base <branch>", "Base branch for `--emit pr` (default: main)").option("--dry-run", "With `--emit pr`: print git/gh commands instead of running them", false).option("--emit-out-dir <path>", "Directory for `--emit pr` rollup files (default: system temp)").option("--resume <run-id>", "Resume a previous run from its on-disk journal").addOption(new Option("--branch-from <entry-index>", "Branch the journal at an entry index before resuming (with --resume)").hideHelp()).option("--verbose", "Show detailed output", false).addOption(new Option("--replay", "Replay the last scan's results").default(false).hideHelp()).action(async (opts) => {
|
|
653
|
+
).option("--base <branch>", "Base branch for `--emit pr` (default: main)").option("--dry-run", "With `--emit pr`: print git/gh commands instead of running them", false).option("--emit-out-dir <path>", "Directory for `--emit pr` rollup files (default: system temp)").option("--resume <run-id>", "Resume a previous run from its on-disk journal").addOption(new Option("--branch-from <entry-index>", "Branch the journal at an entry index before resuming (with --resume)").hideHelp()).option("--verbose", "Show detailed output", false).addOption(new Option("--replay", "Replay the last scan's results").default(false).hideHelp()).action(async (opts, command) => {
|
|
531
654
|
if (opts.replay) {
|
|
532
655
|
try {
|
|
533
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
656
|
+
const { osecDB: osecDB2 } = await import("./dist-QLMPTFT7.js");
|
|
534
657
|
const db = new osecDB2(opts.dbPath);
|
|
535
658
|
const scans = db.listScans(1);
|
|
536
659
|
if (scans.length === 0) {
|
|
@@ -682,7 +805,7 @@ function registerScanCommand(program) {
|
|
|
682
805
|
process.exit(2);
|
|
683
806
|
}
|
|
684
807
|
try {
|
|
685
|
-
const { loadScope: loadScope2 } = await import("./dist-
|
|
808
|
+
const { loadScope: loadScope2 } = await import("./dist-ONIRKDH6.js");
|
|
686
809
|
const policy = loadScope2(scopeFile);
|
|
687
810
|
const verdict = scopeEnforcement.enabled ? policy.match(String(opts.target)) : void 0;
|
|
688
811
|
if (verdict && !verdict.allowed) {
|
|
@@ -709,7 +832,7 @@ function registerScanCommand(program) {
|
|
|
709
832
|
loadScope: loadScope2,
|
|
710
833
|
resolveAttribution: resolveAttribution2,
|
|
711
834
|
extractAttributionFromScopeJson: extractAttributionFromScopeJson2
|
|
712
|
-
} = await import("./dist-
|
|
835
|
+
} = await import("./dist-ONIRKDH6.js");
|
|
713
836
|
const policy = scopeFile ? loadScope2(scopeFile) : void 0;
|
|
714
837
|
resolveAttribution2({
|
|
715
838
|
scopeFileBlock: policy ? extractAttributionFromScopeJson2(policy.raw) : void 0,
|
|
@@ -727,7 +850,7 @@ function registerScanCommand(program) {
|
|
|
727
850
|
loadScope: loadScope2,
|
|
728
851
|
resolveEngagementProfile: resolveEngagementProfile2,
|
|
729
852
|
extractEngagementFromScopeJson: extractEngagementFromScopeJson2
|
|
730
|
-
} = await import("./dist-
|
|
853
|
+
} = await import("./dist-ONIRKDH6.js");
|
|
731
854
|
const policy = scopeFile ? loadScope2(scopeFile) : void 0;
|
|
732
855
|
resolveEngagementProfile2({
|
|
733
856
|
scopeFileBlock: policy ? extractEngagementFromScopeJson2(policy.raw) : void 0,
|
|
@@ -756,13 +879,41 @@ function registerScanCommand(program) {
|
|
|
756
879
|
const rateLimit = opts.rateLimit;
|
|
757
880
|
if (rateLimit !== void 0 && rateLimit !== "") {
|
|
758
881
|
try {
|
|
759
|
-
const { parseRateLimitFlag: parseRateLimitFlag2 } = await import("./dist-
|
|
882
|
+
const { parseRateLimitFlag: parseRateLimitFlag2 } = await import("./dist-ONIRKDH6.js");
|
|
760
883
|
parseRateLimitFlag2(rateLimit);
|
|
761
884
|
} catch (err) {
|
|
762
885
|
console.error(source_default.red(err instanceof Error ? err.message : String(err)));
|
|
763
886
|
process.exit(2);
|
|
764
887
|
}
|
|
765
888
|
}
|
|
889
|
+
const manualModels = parseScanModelAssignments(opts.taskModel ?? []);
|
|
890
|
+
let agentModels = manualModels;
|
|
891
|
+
let recommendRouting;
|
|
892
|
+
if (opts.routingReport && !opts.singleModel) {
|
|
893
|
+
if (opts.runtime !== "api") throw new Error("Reviewed routing requires --runtime api; no unsupported runtime or provider substitution.");
|
|
894
|
+
if (!opts.routingReviewRef || !opts.routingModel?.length) throw new Error("--routing-report requires --routing-model approvals and --routing-review-ref confirming the workflow/provider review.");
|
|
895
|
+
const { readRoutingJson } = await import("./routing-WCQLO5SP.js");
|
|
896
|
+
const { recommendQualifiedRouting, LlmApiRuntime: LlmApiRuntime2 } = await import("./dist-ONIRKDH6.js");
|
|
897
|
+
const raw = readRoutingJson(String(opts.routingReport));
|
|
898
|
+
const current = new LlmApiRuntime2({ type: "api", timeout: parseInt(opts.timeout, 10), model: opts.model });
|
|
899
|
+
recommendRouting = (selectedPlan) => {
|
|
900
|
+
const result = recommendQualifiedRouting(raw, { approvedModels: opts.routingModel, provider: current.resolvedProvider(), reviewRef: String(opts.routingReviewRef), workflow: { targetKind: "web", goal: selectedPlan.goal, depth: selectedPlan.depth }, minimumRepeats: 2 });
|
|
901
|
+
agentModels = { ...result.assignments, ...manualModels };
|
|
902
|
+
return { assignments: agentModels, reasons: Object.fromEntries(Object.entries(result.reasons).map(([role, reason]) => [role, manualModels[role] ? `Operator override: ${manualModels[role]}.` : reason])) };
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
const interactivePlanning = opts.guided !== false && opts.format === "terminal" && process.stdin.isTTY && process.stdout.isTTY && !opts.resume;
|
|
906
|
+
let plan = interactivePlanning ? await guidedScanPlan({ target: opts.target, depth: command.getOptionValueSource("depth") === "cli" ? opts.depth : void 0, costCapUsd: costCeilingUsd, model: opts.model, agentModels, singleModel: opts.singleModel, ...recommendRouting ? { recommendRouting } : {} }) : void 0;
|
|
907
|
+
if (interactivePlanning && !plan) return;
|
|
908
|
+
if (!interactivePlanning && recommendRouting) {
|
|
909
|
+
if (!opts.goal || !opts.planTimeCap || costCeilingUsd === void 0) throw new Error("Noninteractive reviewed routing requires --goal, --plan-time-cap and --cost-ceiling.");
|
|
910
|
+
plan = { goal: opts.goal, depth: opts.depth, runCount: 1, executionMode: "sequential", timeCapMs: Number(opts.planTimeCap), costCapUsd: costCeilingUsd };
|
|
911
|
+
const { validateScanPlan: validateScanPlan2 } = await import("./dist-QXJKD743.js");
|
|
912
|
+
validateScanPlan2(plan);
|
|
913
|
+
const routing = recommendRouting(plan);
|
|
914
|
+
for (const [role, model] of Object.entries(routing.assignments)) console.error(`${role}: ${model} \u2014 ${routing.reasons[role]}`);
|
|
915
|
+
}
|
|
916
|
+
const hasAssignments = Object.keys(agentModels).length > 0;
|
|
766
917
|
const branchFrom = opts.branchFrom;
|
|
767
918
|
await runUnified({
|
|
768
919
|
target: opts.target,
|
|
@@ -770,7 +921,10 @@ function registerScanCommand(program) {
|
|
|
770
921
|
resumeScanId: opts.resume,
|
|
771
922
|
branchFromEntry: branchFrom !== void 0 ? parseInt(branchFrom, 10) : void 0,
|
|
772
923
|
mode,
|
|
773
|
-
depth: opts.depth,
|
|
924
|
+
depth: plan?.depth ?? opts.depth,
|
|
925
|
+
plan,
|
|
926
|
+
...hasAssignments ? { agentModels } : {},
|
|
927
|
+
...opts.singleModel !== void 0 ? { singleModel: opts.singleModel } : {},
|
|
774
928
|
format: opts.format === "md" ? "markdown" : opts.format,
|
|
775
929
|
runtime: opts.runtime ?? "auto",
|
|
776
930
|
timeout: parseInt(opts.timeout, 10),
|
|
@@ -786,9 +940,8 @@ function registerScanCommand(program) {
|
|
|
786
940
|
exportTarget: opts.export,
|
|
787
941
|
race: opts.race,
|
|
788
942
|
egats: opts.egats,
|
|
789
|
-
costCeilingUsd,
|
|
943
|
+
costCeilingUsd: plan?.costCapUsd ?? costCeilingUsd,
|
|
790
944
|
rateLimit,
|
|
791
|
-
tui: opts.tui,
|
|
792
945
|
scopeFile,
|
|
793
946
|
allowScanners: opts.allowScanners,
|
|
794
947
|
attributionHeaders: opts.attributionHeader,
|
|
@@ -927,7 +1080,7 @@ function registerResumeCommand(program) {
|
|
|
927
1080
|
|
|
928
1081
|
// packages/cli/src/commands/replay.ts
|
|
929
1082
|
async function replayScan(opts) {
|
|
930
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
1083
|
+
const { osecDB: osecDB2 } = await import("./dist-QLMPTFT7.js");
|
|
931
1084
|
const db = new osecDB2(opts.dbPath);
|
|
932
1085
|
const requestedScan = opts.scan;
|
|
933
1086
|
let scanRecord;
|
|
@@ -992,14 +1145,8 @@ async function replayScan(opts) {
|
|
|
992
1145
|
});
|
|
993
1146
|
}
|
|
994
1147
|
function registerReplayCommand(program) {
|
|
995
|
-
program.command("replay").description("
|
|
1148
|
+
program.command("replay").description("Print a replay of the last scan's attack chain").option("--db-path <path>", "Path to SQLite database").option("--scan <scanId>", "Replay a specific scan by ID (default: last scan)").action(async (opts) => {
|
|
996
1149
|
try {
|
|
997
|
-
const { isBunRuntime, canUseOpenTui } = await import("./runtime-AUBLQUOH.js");
|
|
998
|
-
if (isBunRuntime() && canUseOpenTui()) {
|
|
999
|
-
const { showOpenTuiReplay } = await import("./run-MU3MFL2Z.js");
|
|
1000
|
-
await showOpenTuiReplay({ dbPath: opts.dbPath, scanId: opts.scan });
|
|
1001
|
-
return;
|
|
1002
|
-
}
|
|
1003
1150
|
await replayScan(opts);
|
|
1004
1151
|
} catch (err) {
|
|
1005
1152
|
console.error(
|
|
@@ -1013,14 +1160,14 @@ function registerReplayCommand(program) {
|
|
|
1013
1160
|
// packages/cli/src/commands/history.ts
|
|
1014
1161
|
import { existsSync as existsSync2 } from "node:fs";
|
|
1015
1162
|
function registerHistoryCommand(program) {
|
|
1016
|
-
program.command("history").description("Show past scan history from run-local SQLite databases").option("--db-path <path>", "Path to one SQLite database").option("--limit <n>", "Number of scans to show",
|
|
1017
|
-
const limit2 = Number
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1163
|
+
program.command("history").description("Show past scan history from run-local SQLite databases").option("--db-path <path>", "Path to one SQLite database").option("--limit <n>", "Number of scans to show", (value) => {
|
|
1164
|
+
const limit2 = Number(value);
|
|
1165
|
+
if (!/^\d+$/.test(value) || !Number.isSafeInteger(limit2) || limit2 < 1) {
|
|
1166
|
+
throw new InvalidArgumentError("must be a positive integer");
|
|
1167
|
+
}
|
|
1168
|
+
return limit2;
|
|
1169
|
+
}, 10).action(async (opts) => {
|
|
1170
|
+
const limit2 = opts.limit ?? 10;
|
|
1024
1171
|
const dbPaths = opts.dbPath ? [opts.dbPath] : listOsecRunDatabasePaths();
|
|
1025
1172
|
const legacyDbPath = resolveOsecDbPath();
|
|
1026
1173
|
if (!opts.dbPath && existsSync2(legacyDbPath) && !dbPaths.includes(legacyDbPath)) {
|
|
@@ -1223,46 +1370,12 @@ function registerFindingsCommand(program) {
|
|
|
1223
1370
|
{ defaultLimit: "50" }
|
|
1224
1371
|
).option("--all", "Show raw finding rows instead of grouped fingerprints", false).action(async (opts, command) => {
|
|
1225
1372
|
const resolved = resolveFindingsOptions(opts, command);
|
|
1226
|
-
const limit2 = Number.parseInt(resolved.limit ?? "50", 10);
|
|
1227
|
-
const selectedDbPath = resolveDbPath(resolved);
|
|
1228
|
-
const { isBunRuntime, canUseOpenTui } = await import("./runtime-AUBLQUOH.js");
|
|
1229
|
-
if (selectedDbPath && isBunRuntime() && canUseOpenTui()) {
|
|
1230
|
-
const { showOpenTuiFindings } = await import("./run-MU3MFL2Z.js");
|
|
1231
|
-
await showOpenTuiFindings({
|
|
1232
|
-
dbPath: selectedDbPath,
|
|
1233
|
-
scan: resolved.scan,
|
|
1234
|
-
severity: resolved.severity,
|
|
1235
|
-
category: resolved.category,
|
|
1236
|
-
status: resolved.status,
|
|
1237
|
-
triage: resolved.triage,
|
|
1238
|
-
limit: limit2,
|
|
1239
|
-
all: resolved.all
|
|
1240
|
-
});
|
|
1241
|
-
return;
|
|
1242
|
-
}
|
|
1243
1373
|
await renderFindingsList(resolved);
|
|
1244
1374
|
});
|
|
1245
1375
|
withFindingsListOptions(
|
|
1246
1376
|
findingsCmd.command("list").description("List findings from the database")
|
|
1247
1377
|
).action(async (opts, command) => {
|
|
1248
1378
|
const resolved = resolveFindingsOptions(opts, command);
|
|
1249
|
-
const limit2 = Number.parseInt(resolved.limit ?? "50", 10);
|
|
1250
|
-
const selectedDbPath = resolveDbPath(resolved);
|
|
1251
|
-
const { isBunRuntime, canUseOpenTui } = await import("./runtime-AUBLQUOH.js");
|
|
1252
|
-
if (selectedDbPath && isBunRuntime() && canUseOpenTui()) {
|
|
1253
|
-
const { showOpenTuiFindings } = await import("./run-MU3MFL2Z.js");
|
|
1254
|
-
await showOpenTuiFindings({
|
|
1255
|
-
dbPath: selectedDbPath,
|
|
1256
|
-
scan: resolved.scan,
|
|
1257
|
-
severity: resolved.severity,
|
|
1258
|
-
category: resolved.category,
|
|
1259
|
-
status: resolved.status,
|
|
1260
|
-
triage: resolved.triage,
|
|
1261
|
-
limit: limit2,
|
|
1262
|
-
all: resolved.all
|
|
1263
|
-
});
|
|
1264
|
-
return;
|
|
1265
|
-
}
|
|
1266
1379
|
await renderFindingsList(resolved);
|
|
1267
1380
|
});
|
|
1268
1381
|
findingsCmd.command("show").description("Show detailed information about a finding").argument("<id>", "Finding ID (full or prefix)").option("--db-path <path>", "Path to SQLite database").action(async (id, opts, command) => {
|
|
@@ -1308,7 +1421,7 @@ function registerFindingsCommand(program) {
|
|
|
1308
1421
|
console.log(` ${source_default.dim(finding.evidenceAnalysis)}`);
|
|
1309
1422
|
}
|
|
1310
1423
|
{
|
|
1311
|
-
const { summarizeTriageProvenance, formatTriageProvenance } = await import("./dist-
|
|
1424
|
+
const { summarizeTriageProvenance, formatTriageProvenance } = await import("./dist-ONIRKDH6.js");
|
|
1312
1425
|
const provenance = summarizeTriageProvenance({
|
|
1313
1426
|
...finding,
|
|
1314
1427
|
layerVerdicts: parseLayerVerdicts(finding.layerVerdicts)
|
|
@@ -1371,7 +1484,7 @@ function positiveAmount(value) {
|
|
|
1371
1484
|
return parsed;
|
|
1372
1485
|
}
|
|
1373
1486
|
function registerSecureCommand(program) {
|
|
1374
|
-
program.command("secure").description("Find, reproduce, fix, and verify vulnerabilities in a repo; optionally open repair PRs").argument("<repo>", "Local Git repository or HTTPS Git URL; execution occurs in the current worker, not a newly provisioned sandbox").requiredOption("--test-command <command>", "Operator-approved regression command; must pass before and after repair").option("--setup-command <command>", "Operator-approved setup/build command run in each disposable checkout").option("--state-dir <path>", "Persistent run directory; defaults to a stable per-repository path so learnings accumulate").option("--runtime <runtime>", "Native repair runtime: auto or api", "api").option("-m, --model <model>", "Model for investigation and repair; inherits configured provider when omitted").option("--timeout <ms>", "Whole workflow deadline in milliseconds", positiveInteger, 36e5).option("--cost-ceiling <usd>", "Whole workflow model cost ceiling in USD", positiveAmount).option("--max-findings <n>", "Maximum findings to repair; remaining findings keep the run blocked", positiveInteger, 10).option("--max-attempts <n>", "Maximum repair candidates per finding", positiveInteger, 3).option("--max-turns <n>", "Maximum model turns per repair phase", positiveInteger, 30).option("--resume", "Resume the compatible persisted run for this repository; never blindly replays publication", false).option("--publish", "Publish verified patches as PRs using authorized repository credentials; never merge or deploy", false).option("--rules <text>", 'Plain-English team repair standards (e.g. "minimal diffs, no new dependencies")').option("--format <format>", "Output format: json", "json").action(async (repo, options) => {
|
|
1487
|
+
program.command("secure").description("Find, reproduce, fix, and verify vulnerabilities in a repo; optionally open repair PRs").argument("<repo>", "Local Git repository or HTTPS Git URL; execution occurs in the current worker, not a newly provisioned sandbox").requiredOption("--test-command <command>", "Operator-approved regression command; must pass before and after repair").option("--source-path <path>", "Repository-relative folder to investigate and repair; setup and tests run at the repository root").option("--setup-command <command>", "Operator-approved setup/build command run in each disposable checkout").option("--state-dir <path>", "Persistent run directory; defaults to a stable per-repository path so learnings accumulate").option("--runtime <runtime>", "Native repair runtime: auto or api", "api").option("-m, --model <model>", "Model for investigation and repair; inherits configured provider when omitted").option("--timeout <ms>", "Whole workflow deadline in milliseconds", positiveInteger, 36e5).option("--cost-ceiling <usd>", "Whole workflow model cost ceiling in USD", positiveAmount).option("--max-findings <n>", "Maximum findings to repair; remaining findings keep the run blocked", positiveInteger, 10).option("--max-attempts <n>", "Maximum repair candidates per finding", positiveInteger, 3).option("--max-turns <n>", "Maximum model turns per repair phase", positiveInteger, 30).option("--resume", "Resume the compatible persisted run for this repository; never blindly replays publication", false).option("--publish", "Publish verified patches as PRs using authorized repository credentials; never merge or deploy", false).option("--rules <text>", 'Plain-English team repair standards (e.g. "minimal diffs, no new dependencies")').option("--format <format>", "Output format: json", "json").action(async (repo, options) => {
|
|
1375
1488
|
if (options.format !== "json") throw new InvalidArgumentError("--format must be json.");
|
|
1376
1489
|
if (!["api", "auto"].includes(options.runtime)) throw new InvalidArgumentError("--runtime must be api or auto.");
|
|
1377
1490
|
if (!options.testCommand.trim()) throw new InvalidArgumentError("--test-command cannot be blank.");
|
|
@@ -1392,6 +1505,7 @@ function registerSecureCommand(program) {
|
|
|
1392
1505
|
try {
|
|
1393
1506
|
const result = await runSecureProject({
|
|
1394
1507
|
repoRoot: repo,
|
|
1508
|
+
sourcePath: options.sourcePath,
|
|
1395
1509
|
stateDir,
|
|
1396
1510
|
testCommand: options.testCommand,
|
|
1397
1511
|
setupCommand: options.setupCommand,
|
|
@@ -1428,7 +1542,7 @@ import { existsSync as existsSync3 } from "node:fs";
|
|
|
1428
1542
|
var VALID_BUILD_SYSTEMS = /* @__PURE__ */ new Set(["autotools", "cmake", "meson", "auto"]);
|
|
1429
1543
|
var VALID_SANITIZERS = /* @__PURE__ */ new Set(["asan", "ubsan", "msan"]);
|
|
1430
1544
|
async function runHarnessTier2(args2) {
|
|
1431
|
-
const { buildTier2Harness, extractCorpus } = await import("./dist-
|
|
1545
|
+
const { buildTier2Harness, extractCorpus } = await import("./dist-ONIRKDH6.js");
|
|
1432
1546
|
const repoAbs = resolve2(args2.repo);
|
|
1433
1547
|
if (!existsSync3(repoAbs)) {
|
|
1434
1548
|
throw new Error(`Tier-2: repo path '${repoAbs}' does not exist.`);
|
|
@@ -1524,7 +1638,7 @@ async function runHarnessTier3(args2) {
|
|
|
1524
1638
|
buildTier2Harness,
|
|
1525
1639
|
extractCorpus,
|
|
1526
1640
|
runTier3Validation
|
|
1527
|
-
} = await import("./dist-
|
|
1641
|
+
} = await import("./dist-ONIRKDH6.js");
|
|
1528
1642
|
const repoAbs = resolve3(args2.repo);
|
|
1529
1643
|
if (!existsSync4(repoAbs)) {
|
|
1530
1644
|
throw new Error(`Tier-3: repo path '${repoAbs}' does not exist.`);
|
|
@@ -1642,7 +1756,7 @@ function normalizeReviewProfile(value, flag) {
|
|
|
1642
1756
|
);
|
|
1643
1757
|
}
|
|
1644
1758
|
function registerReviewCommand(program) {
|
|
1645
|
-
program.command("review").description("Deep source code security review of a repository").argument("<repo>", "Local path or git URL to review").option("--depth <depth>", "Review depth: quick, default, deep", "default").option("--format <format>", "Output format: terminal, json, md, html, sarif, pdf", "terminal").option("--runtime <runtime>", "Runtime: auto, claude, codex, gemini, api, ollama", "auto").option("--db-path <path>", "Path to SQLite database").option("--api-key <key>", "API key for LLM provider").option("-m, --model <model>", "LLM model to use").option("--cost-ceiling <usd>", "Hard per-review USD cost ceiling. Aborts cleanly with partial findings if exceeded.").option("--
|
|
1759
|
+
program.command("review").description("Deep source code security review of a repository").argument("<repo>", "Local path or git URL to review").option("--depth <depth>", "Review depth: quick, default, deep", "default").option("--format <format>", "Output format: terminal, json, md, html, sarif, pdf", "terminal").option("--runtime <runtime>", "Runtime: auto, claude, codex, gemini, api, ollama", "auto").option("--db-path <path>", "Path to SQLite database").option("--api-key <key>", "API key for LLM provider").option("-m, --model <model>", "LLM model to use").option("--cost-ceiling <usd>", "Hard per-review USD cost ceiling. Aborts cleanly with partial findings if exceeded.").option("--diff-base <ref>", "Git base ref to review against (for diff-aware review)").option("--changed-only", "Restrict static scanner leads + prioritization to changed files", false).option(
|
|
1646
1760
|
"--profile <profile>",
|
|
1647
1761
|
"Review profile: default (web/JS/TS/Python), c-library (C/C++ memory safety, tier-1/2/3 harness), linux-kernel (kernel-aware static review), cardano-onchain (Aiken/Plutus validator logic), solana-onchain (Anchor/native Rust account-model authorization), evm-onchain (Solidity/Foundry/Hardhat DeFi/bridge \u2014 reentrancy, oracle manipulation, cross-chain replay), cairo-onchain (Cairo/Starknet DeFi \u2014 caller-auth gaps, share-rounding, L1\u2194L2 messages), move-onchain (Sui/Aptos Move \u2014 object/capability binding, shared-math overflow, reward-index accounting), cardano-haskell (first-party Cardano Haskell node stack \u2014 ledger/plutus/ouroboros/cardano-base), xnu-kernel (Apple XNU macOS/iOS source review), or xnu-re (decompiled Apple kext pseudo-C)",
|
|
1648
1762
|
"default"
|
|
@@ -1744,7 +1858,7 @@ function registerReviewCommand(program) {
|
|
|
1744
1858
|
let seedFindings;
|
|
1745
1859
|
const seedPath = opts.seedFindings;
|
|
1746
1860
|
if (seedPath) {
|
|
1747
|
-
const { readSeedFindings } = await import("./dist-
|
|
1861
|
+
const { readSeedFindings } = await import("./dist-ONIRKDH6.js");
|
|
1748
1862
|
seedFindings = readSeedFindings(seedPath);
|
|
1749
1863
|
console.log(
|
|
1750
1864
|
source_default.cyan(
|
|
@@ -1760,7 +1874,7 @@ function registerReviewCommand(program) {
|
|
|
1760
1874
|
);
|
|
1761
1875
|
}
|
|
1762
1876
|
if (fixCommit) {
|
|
1763
|
-
const { huntAppFixVariants, appFixVariantsToSeedFindings } = await import("./dist-
|
|
1877
|
+
const { huntAppFixVariants, appFixVariantsToSeedFindings } = await import("./dist-ONIRKDH6.js");
|
|
1764
1878
|
const result = huntAppFixVariants({
|
|
1765
1879
|
repoPath: repo,
|
|
1766
1880
|
fixCommit
|
|
@@ -1874,7 +1988,6 @@ function registerReviewCommand(program) {
|
|
|
1874
1988
|
conversation: opts.conversation,
|
|
1875
1989
|
priorFindings,
|
|
1876
1990
|
npmDynamicDiscovery: opts.npmDynamic,
|
|
1877
|
-
tui: opts.tui,
|
|
1878
1991
|
seedFindings,
|
|
1879
1992
|
seedOnly: opts.seedOnly,
|
|
1880
1993
|
emit,
|
|
@@ -2035,7 +2148,7 @@ function registerAuditCommand(program) {
|
|
|
2035
2148
|
program.command("audit").description("Run a package security workflow (compatibility shortcut)").argument("<package>", "package name (e.g. lodash, express, requests)").option("--ecosystem <ecosystem>", "Package ecosystem: npm, pypi, cargo, oci", "npm").option(
|
|
2036
2149
|
"--package-version <version>",
|
|
2037
2150
|
"Specific package version to audit (default: latest)"
|
|
2038
|
-
).option("--pkg-version <version>", "Alias for --package-version").option("--ver <version>", "Alias for --package-version").option("--depth <depth>", "Audit depth: quick, default, deep", "default").option("--format <format>", "Output format: terminal, json, md, html, sarif, pdf", "terminal").option("--runtime <runtime>", "Runtime: auto, claude, codex, gemini, api", "auto").option("--db-path <path>", "Path to SQLite database").option("--api-key <key>", "API key for LLM provider").option("-m, --model <model>", "LLM model to use").option("--cost-ceiling <usd>", "Hard per-audit USD cost ceiling. Aborts cleanly with partial findings if exceeded.").option("--
|
|
2151
|
+
).option("--pkg-version <version>", "Alias for --package-version").option("--ver <version>", "Alias for --package-version").option("--depth <depth>", "Audit depth: quick, default, deep", "default").option("--format <format>", "Output format: terminal, json, md, html, sarif, pdf", "terminal").option("--runtime <runtime>", "Runtime: auto, claude, codex, gemini, api", "auto").option("--db-path <path>", "Path to SQLite database").option("--api-key <key>", "API key for LLM provider").option("-m, --model <model>", "LLM model to use").option("--cost-ceiling <usd>", "Hard per-audit USD cost ceiling. Aborts cleanly with partial findings if exceeded.").option("--resume <run-id>", "Resume a previous run from its journal on disk (0#374)").option("--branch-from <entry-index>", "Branch the journal at the given entry index before resuming (requires --resume).").option("--verbose", "Show detailed output", false).option("--timeout <ms>", "AI agent timeout in milliseconds", "600000").action(async (packageName, opts) => {
|
|
2039
2152
|
const ecosystem = (opts.ecosystem ?? "npm").trim().toLowerCase();
|
|
2040
2153
|
if (!SUPPORTED_AUDIT_ECOSYSTEMS.has(ecosystem)) {
|
|
2041
2154
|
throw new Error(`Unsupported ecosystem '${ecosystem}'. Valid: npm, pypi, cargo, oci.`);
|
|
@@ -2064,8 +2177,7 @@ function registerAuditCommand(program) {
|
|
|
2064
2177
|
model: opts.model,
|
|
2065
2178
|
// Read in priority: --package-version, --pkg-version, --ver.
|
|
2066
2179
|
packageVersion: opts.packageVersion ?? opts.pkgVersion ?? opts.ver,
|
|
2067
|
-
costCeilingUsd
|
|
2068
|
-
tui: opts.tui
|
|
2180
|
+
costCeilingUsd
|
|
2069
2181
|
});
|
|
2070
2182
|
});
|
|
2071
2183
|
}
|
|
@@ -2073,12 +2185,7 @@ function registerAuditCommand(program) {
|
|
|
2073
2185
|
// packages/cli/src/commands/doctor.ts
|
|
2074
2186
|
function registerDoctorCommand(program) {
|
|
2075
2187
|
program.command("doctor").description("Check local runtime prerequisites and suggest the next command").action(async () => {
|
|
2076
|
-
const {
|
|
2077
|
-
if (isBunRuntime() && canUseOpenTui()) {
|
|
2078
|
-
const { showOpenTuiDoctor } = await import("./run-MU3MFL2Z.js");
|
|
2079
|
-
await showOpenTuiDoctor();
|
|
2080
|
-
return;
|
|
2081
|
-
}
|
|
2188
|
+
const { getRuntimeMetadata } = await import("./runtime-6ZIXFTW5.js");
|
|
2082
2189
|
const { hasApiKey, availableRuntimes, apiRuntime } = await getRuntimeAvailability();
|
|
2083
2190
|
const runtime = getRuntimeMetadata();
|
|
2084
2191
|
const nodeMajor = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10);
|
|
@@ -2114,8 +2221,9 @@ function registerDoctorCommand(program) {
|
|
|
2114
2221
|
|
|
2115
2222
|
// packages/cli/src/commands/tui.ts
|
|
2116
2223
|
function registerTuiCommand(program) {
|
|
2117
|
-
program.command("tui").alias("watch").description("Retired terminal UI; use 0 web for interactive work").action(() => {
|
|
2118
|
-
console.
|
|
2224
|
+
program.command("tui", { hidden: true }).alias("watch").description("Retired terminal UI; use 0 web for interactive work").action(() => {
|
|
2225
|
+
console.error("The terminal UI has been removed. Run 0 web to open the browser console at http://127.0.0.1:48123, or use 0 chat --prompt for scripts.");
|
|
2226
|
+
process.exitCode = 2;
|
|
2119
2227
|
});
|
|
2120
2228
|
}
|
|
2121
2229
|
|
|
@@ -2123,7 +2231,7 @@ function registerTuiCommand(program) {
|
|
|
2123
2231
|
import { randomUUID } from "node:crypto";
|
|
2124
2232
|
import { isAbsolute } from "node:path";
|
|
2125
2233
|
|
|
2126
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@
|
|
2234
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
2127
2235
|
import process2 from "node:process";
|
|
2128
2236
|
var StdioServerTransport = class {
|
|
2129
2237
|
constructor(_stdin = process2.stdin, _stdout = process2.stdout, options) {
|
|
@@ -2180,12 +2288,12 @@ var StdioServerTransport = class {
|
|
|
2180
2288
|
this.onclose?.();
|
|
2181
2289
|
}
|
|
2182
2290
|
send(message) {
|
|
2183
|
-
return new Promise((
|
|
2291
|
+
return new Promise((resolve29) => {
|
|
2184
2292
|
const json = serializeMessage(message);
|
|
2185
2293
|
if (this._stdout.write(json)) {
|
|
2186
|
-
|
|
2294
|
+
resolve29();
|
|
2187
2295
|
} else {
|
|
2188
|
-
this._stdout.once("drain",
|
|
2296
|
+
this._stdout.once("drain", resolve29);
|
|
2189
2297
|
}
|
|
2190
2298
|
});
|
|
2191
2299
|
}
|
|
@@ -2293,7 +2401,7 @@ function zodForParam(param) {
|
|
|
2293
2401
|
} else if (param.type === "boolean") {
|
|
2294
2402
|
schema = external_exports.boolean();
|
|
2295
2403
|
} else if (param.type === "object") {
|
|
2296
|
-
schema = external_exports.record(external_exports.unknown());
|
|
2404
|
+
schema = external_exports.record(external_exports.string(), external_exports.unknown());
|
|
2297
2405
|
} else {
|
|
2298
2406
|
schema = external_exports.string();
|
|
2299
2407
|
}
|
|
@@ -2325,9 +2433,9 @@ function toolResultToMcp(result) {
|
|
|
2325
2433
|
return toTextResult(text2, { success: true, output: result.output });
|
|
2326
2434
|
}
|
|
2327
2435
|
function withToolTimeout(task, timeoutMs) {
|
|
2328
|
-
return new Promise((
|
|
2436
|
+
return new Promise((resolve29) => {
|
|
2329
2437
|
const timer = setTimeout(() => {
|
|
2330
|
-
|
|
2438
|
+
resolve29({
|
|
2331
2439
|
success: false,
|
|
2332
2440
|
output: null,
|
|
2333
2441
|
error: `MCP tool timed out after ${timeoutMs}ms`
|
|
@@ -2336,11 +2444,11 @@ function withToolTimeout(task, timeoutMs) {
|
|
|
2336
2444
|
task.then(
|
|
2337
2445
|
(result) => {
|
|
2338
2446
|
clearTimeout(timer);
|
|
2339
|
-
|
|
2447
|
+
resolve29(result);
|
|
2340
2448
|
},
|
|
2341
2449
|
(error) => {
|
|
2342
2450
|
clearTimeout(timer);
|
|
2343
|
-
|
|
2451
|
+
resolve29({
|
|
2344
2452
|
success: false,
|
|
2345
2453
|
output: null,
|
|
2346
2454
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -2372,7 +2480,7 @@ function clampRateLimitToPosture(cfg, posture) {
|
|
|
2372
2480
|
}
|
|
2373
2481
|
var workflowInputsSchema = SecurityWorkflowBindingsSchema;
|
|
2374
2482
|
async function registerWorkflowTools(server, selected, opts) {
|
|
2375
|
-
const runtime = opts.backend || opts.engineUrl ? await (await import("./remote-workflow-runtime-
|
|
2483
|
+
const runtime = opts.backend || opts.engineUrl ? await (await import("./remote-workflow-runtime-GOI4TYP5.js")).createRemoteWorkflowRuntime({ backendId: opts.backend, configPath: opts.backendsConfig, sessionId: opts.session, engineUrl: opts.engineUrl, engineTokenEnv: opts.engineTokenEnv }) : await (await import("./workflow-runtime-CQTDASFA.js")).createCliWorkflowRuntime({
|
|
2376
2484
|
ownerId: `mcp:${randomUUID()}`,
|
|
2377
2485
|
workspace: opts.workspace,
|
|
2378
2486
|
target: opts.target,
|
|
@@ -2396,13 +2504,13 @@ async function registerWorkflowTools(server, selected, opts) {
|
|
|
2396
2504
|
{ name: "resume_scan", description: "Resume a retained scan in a selected session; this does not restart a workflow graph.", schema: external_exports.object({ sessionId: id, scanId: id, branchFromEntry: external_exports.number().int().nonnegative().optional(), timeCapMs: external_exports.number().int().positive().max(864e5).optional(), costCapUsd: external_exports.number().positive().max(1e3).optional() }).strict(), run: (args2) => sessionRuntime.resumeScan(args2) },
|
|
2397
2505
|
{ name: "get_session_events", description: "Read session events after an engine event cursor.", schema: external_exports.object({ sessionId: id, after: external_exports.number().int().nonnegative().optional() }).strict(), run: (args2) => sessionRuntime.getSessionEvents(args2.sessionId, args2.after) },
|
|
2398
2506
|
{ name: "list_sessions", description: "List live sessions on the selected engine.", schema: external_exports.object({}).strict(), run: () => sessionRuntime.listSessions() },
|
|
2399
|
-
{ name: "create_session", description: "Create a session within the engine's configured admission grants.", schema: external_exports.object({ config: external_exports.record(external_exports.unknown()).optional() }).strict(), run: (args2) => sessionRuntime.createSession(args2.config) },
|
|
2507
|
+
{ name: "create_session", description: "Create a session within the engine's configured admission grants.", schema: external_exports.object({ config: external_exports.record(external_exports.string(), external_exports.unknown()).optional() }).strict(), run: (args2) => sessionRuntime.createSession(args2.config) },
|
|
2400
2508
|
{ name: "attach_session", description: "Attach to an existing engine session without recreating it.", schema: external_exports.object({ sessionId: id }).strict(), run: (args2) => sessionRuntime.attachSession(args2.sessionId) },
|
|
2401
2509
|
{ name: "get_session", description: "Read an existing engine session.", schema: external_exports.object({ sessionId: id }).strict(), run: (args2) => sessionRuntime.getSession(args2.sessionId) },
|
|
2402
2510
|
{ name: "send_message", description: "Send a message to an engine session.", schema: external_exports.object({ sessionId: id, text: external_exports.string().min(1).max(65536) }).strict(), run: (args2) => sessionRuntime.sendMessage(args2.sessionId, args2.text) },
|
|
2403
2511
|
{ name: "continue_session", description: "Continue an engine session.", schema: external_exports.object({ sessionId: id, text: external_exports.string().max(65536).optional() }).strict(), run: (args2) => sessionRuntime.continueSession(args2.sessionId, args2.text) },
|
|
2404
2512
|
{ name: "cancel_session", description: "Explicitly cancel an engine session's active work.", schema: external_exports.object({ sessionId: id }).strict(), run: (args2) => sessionRuntime.cancelSession(args2.sessionId) },
|
|
2405
|
-
{ name: "resolve_decision", description: "Respond to a pending engine session decision.", schema: external_exports.object({ sessionId: id, decisionId: id, response: external_exports.record(external_exports.unknown()) }).strict(), run: (args2) => sessionRuntime.resolveDecision(args2.sessionId, args2.decisionId, args2.response) },
|
|
2513
|
+
{ name: "resolve_decision", description: "Respond to a pending engine session decision.", schema: external_exports.object({ sessionId: id, decisionId: id, response: external_exports.record(external_exports.string(), external_exports.unknown()) }).strict(), run: (args2) => sessionRuntime.resolveDecision(args2.sessionId, args2.decisionId, args2.response) },
|
|
2406
2514
|
{ name: "list_saved_sessions", description: "List retained session snapshots on the engine.", schema: external_exports.object({}).strict(), run: () => sessionRuntime.listSavedSessions() },
|
|
2407
2515
|
{ name: "resume_session", description: "Resume a saved snapshot as a new session; admission grants are revalidated.", schema: external_exports.object({ savedSessionId: id }).strict(), run: (args2) => sessionRuntime.resumeSession(args2.savedSessionId) },
|
|
2408
2516
|
{ name: "list_templates", description: "List workflow templates and supported target types.", schema: external_exports.object({}).strict(), run: () => runtime.listTemplates() },
|
|
@@ -2410,7 +2518,7 @@ async function registerWorkflowTools(server, selected, opts) {
|
|
|
2410
2518
|
{ name: "list_runs", description: "List workflow runs visible to this execution owner on the selected engine.", schema: external_exports.object({}).strict(), run: () => runtime.listRuns() },
|
|
2411
2519
|
{ name: "list_workflows", description: "List saved workflow definitions.", schema: external_exports.object({}).strict(), run: () => runtime.listWorkflows() },
|
|
2412
2520
|
{ name: "get_workflow", description: "Read a saved workflow and its revision.", schema: external_exports.object({ id }).strict(), run: (args2) => runtime.getWorkflow(args2.id) },
|
|
2413
|
-
{ name: "save_workflow", description: "Validate and save a workflow definition with optional revision protection.", schema: external_exports.object({ definition: external_exports.record(external_exports.unknown()), expectedRevision: external_exports.number().int().positive().optional() }).strict(), run: (args2) => runtime.saveWorkflow(args2.definition, args2.expectedRevision) },
|
|
2521
|
+
{ name: "save_workflow", description: "Validate and save a workflow definition with optional revision protection.", schema: external_exports.object({ definition: external_exports.record(external_exports.string(), external_exports.unknown()), expectedRevision: external_exports.number().int().positive().optional() }).strict(), run: (args2) => runtime.saveWorkflow(args2.definition, args2.expectedRevision) },
|
|
2414
2522
|
{ name: "start_run", description: "Start a template or saved workflow using 0's configured model provider. Returns a run ID promptly. Target must be within the server's authorized workspace or live scope.", schema: external_exports.object({ sessionId: id.optional(), templateId: id.optional(), workflowId: id.optional(), revision: external_exports.number().int().positive().optional(), target: external_exports.string().trim().min(1).max(4096), idempotencyKey: id.optional(), inputs: workflowInputsSchema.optional(), allowApply: external_exports.boolean().optional(), timeCapMs: external_exports.number().int().positive().max(864e5).optional(), costCapUsd: external_exports.number().positive().max(1e3).optional() }).strict(), run: (args2) => {
|
|
2415
2523
|
if (Boolean(args2.templateId) === Boolean(args2.workflowId)) throw new Error("Select exactly one templateId or workflowId.");
|
|
2416
2524
|
if (args2.workflowId && !args2.revision) throw new Error("Saved workflow runs require a pinned revision.");
|
|
@@ -2670,11 +2778,11 @@ function rowToFinding(row) {
|
|
|
2670
2778
|
};
|
|
2671
2779
|
}
|
|
2672
2780
|
async function openStore(dbPath) {
|
|
2673
|
-
const { MemoryStore } = await import("./dist-
|
|
2781
|
+
const { MemoryStore } = await import("./dist-ONIRKDH6.js");
|
|
2674
2782
|
return new MemoryStore(dbPath);
|
|
2675
2783
|
}
|
|
2676
2784
|
async function loadFinding2(dbPath, findingId) {
|
|
2677
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
2785
|
+
const { osecDB: osecDB2 } = await import("./dist-QLMPTFT7.js");
|
|
2678
2786
|
const db = new osecDB2(dbPath);
|
|
2679
2787
|
try {
|
|
2680
2788
|
const rows = db.listFindings({ limit: 5e3 });
|
|
@@ -2749,7 +2857,7 @@ async function runMemoryRemove(id, dbPath) {
|
|
|
2749
2857
|
async function runMarkFp(findingId, opts) {
|
|
2750
2858
|
const row = await loadFinding2(opts.dbPath, findingId);
|
|
2751
2859
|
const finding = rowToFinding(row);
|
|
2752
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
2860
|
+
const { osecDB: osecDB2 } = await import("./dist-QLMPTFT7.js");
|
|
2753
2861
|
const db = new osecDB2(opts.dbPath);
|
|
2754
2862
|
try {
|
|
2755
2863
|
db.updateFindingTriage(row.id, "suppressed", opts.reason);
|
|
@@ -6464,7 +6572,7 @@ function registerIngestCommand(program) {
|
|
|
6464
6572
|
reviewKernelCrashSubsystems,
|
|
6465
6573
|
verifyStandaloneKernelReproducer,
|
|
6466
6574
|
verifyKernelCrash
|
|
6467
|
-
} = await import("./dist-
|
|
6575
|
+
} = await import("./dist-ONIRKDH6.js");
|
|
6468
6576
|
let kernelBuild;
|
|
6469
6577
|
if (opts.kernelTree) {
|
|
6470
6578
|
kernelBuild = prepareKernelVmArtifacts({
|
|
@@ -6887,7 +6995,7 @@ function registerKernelCommand(program) {
|
|
|
6887
6995
|
checkAlreadyFixed,
|
|
6888
6996
|
rankKernelHypothesesWithJev,
|
|
6889
6997
|
verifyStaticKernelFinding
|
|
6890
|
-
} = await import("./dist-
|
|
6998
|
+
} = await import("./dist-ONIRKDH6.js");
|
|
6891
6999
|
const noveltyExcluded = opts.upstreamTree ? findings.flatMap((finding) => {
|
|
6892
7000
|
const path = finding.reviewAnnotation?.path ?? finding.evidence.request.match(/([^\s:]+\.[ch]):\d+/)?.[1];
|
|
6893
7001
|
if (!path) return [];
|
|
@@ -6934,7 +7042,7 @@ function registerKernelCommand(program) {
|
|
|
6934
7042
|
try {
|
|
6935
7043
|
const config = jevConfigFromEnvironment("kernel", process.env);
|
|
6936
7044
|
if (!config) throw new Error("Jev commit prepass requires ZERO_JEV_FEATURES=kernel and a configured provider");
|
|
6937
|
-
const { rankKernelCommitsWithJev } = await import("./dist-
|
|
7045
|
+
const { rankKernelCommitsWithJev } = await import("./dist-ONIRKDH6.js");
|
|
6938
7046
|
const result = await rankKernelCommitsWithJev({
|
|
6939
7047
|
tree: opts.tree,
|
|
6940
7048
|
evaluator: createJevEvaluator(config),
|
|
@@ -6958,7 +7066,7 @@ function registerKernelCommand(program) {
|
|
|
6958
7066
|
try {
|
|
6959
7067
|
const config = jevConfigFromEnvironment("kernel", process.env);
|
|
6960
7068
|
if (!config) throw new Error("Jev source prepass requires ZERO_JEV_FEATURES=kernel and a configured provider");
|
|
6961
|
-
const { runKernelSourceJevPrepass } = await import("./dist-
|
|
7069
|
+
const { runKernelSourceJevPrepass } = await import("./dist-ONIRKDH6.js");
|
|
6962
7070
|
const result = await runKernelSourceJevPrepass({
|
|
6963
7071
|
tree: opts.tree,
|
|
6964
7072
|
subtree: opts.subtree,
|
|
@@ -6992,7 +7100,7 @@ function registerKernelCommand(program) {
|
|
|
6992
7100
|
if (crashes.length === 0) throw new Error("Crash input must be a CrashRecord[] or an object with a crashes array");
|
|
6993
7101
|
const records = crashes.filter((c) => !!c && typeof c === "object" && "id" in c && "summary" in c && typeof c.id === "string" && typeof c.summary === "string");
|
|
6994
7102
|
if (records.length !== crashes.length) throw new Error("Every crash record requires string id and summary fields");
|
|
6995
|
-
const { rankCrashesWithJev, crashSummaryFromTriage } = await import("./dist-
|
|
7103
|
+
const { rankCrashesWithJev, crashSummaryFromTriage } = await import("./dist-ONIRKDH6.js");
|
|
6996
7104
|
const result = await rankCrashesWithJev(
|
|
6997
7105
|
records,
|
|
6998
7106
|
createJevEvaluator(config)
|
|
@@ -7020,7 +7128,7 @@ function registerKernelCommand(program) {
|
|
|
7020
7128
|
const details = parsePositiveInt(opts.details, "--details", 100);
|
|
7021
7129
|
const detailDelayMs = parsePositiveInt(opts.detailDelay, "--detail-delay", 5e3);
|
|
7022
7130
|
const subsystems = opts.subsystems.split(",").map((value) => value.trim()).filter(Boolean);
|
|
7023
|
-
const { defaultSyzbotFetcher, mineSyzbotQueue, toHuntCandidates } = await import("./dist-
|
|
7131
|
+
const { defaultSyzbotFetcher, mineSyzbotQueue, toHuntCandidates } = await import("./dist-ONIRKDH6.js");
|
|
7024
7132
|
const result = await mineSyzbotQueue({
|
|
7025
7133
|
fetch: defaultSyzbotFetcher,
|
|
7026
7134
|
fetchDetail: defaultSyzbotFetcher,
|
|
@@ -7078,7 +7186,7 @@ function registerKernelCommand(program) {
|
|
|
7078
7186
|
`Invalid output format '${opts.output}'. Valid: ${VALID_OUTPUT_FORMATS2.join(", ")}`
|
|
7079
7187
|
);
|
|
7080
7188
|
}
|
|
7081
|
-
const { runKernelVariantHunt } = await import("./dist-
|
|
7189
|
+
const { runKernelVariantHunt } = await import("./dist-ONIRKDH6.js");
|
|
7082
7190
|
const report = await runKernelVariantHunt({
|
|
7083
7191
|
tree: opts.tree,
|
|
7084
7192
|
advisory: opts.advisory,
|
|
@@ -7181,7 +7289,7 @@ function resolveOutputDir(opts, scanId) {
|
|
|
7181
7289
|
return join9(homedir2(), "0", "disclosures", `scan-${scanId.slice(0, 8)}`);
|
|
7182
7290
|
}
|
|
7183
7291
|
async function disclose(findingId, opts) {
|
|
7184
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
7292
|
+
const { osecDB: osecDB2 } = await import("./dist-QLMPTFT7.js");
|
|
7185
7293
|
const db = new osecDB2(opts.dbPath);
|
|
7186
7294
|
try {
|
|
7187
7295
|
let routeDroppedFinding2 = function(args2) {
|
|
@@ -7633,7 +7741,7 @@ async function runExploit(opts) {
|
|
|
7633
7741
|
classifyPrimitiveFromDmesg,
|
|
7634
7742
|
describeKernelPrimitive,
|
|
7635
7743
|
runWeaponization
|
|
7636
|
-
} = await import("./dist-
|
|
7744
|
+
} = await import("./dist-ONIRKDH6.js");
|
|
7637
7745
|
const rawFinding = readJson(opts.findingPath, "finding");
|
|
7638
7746
|
let finding;
|
|
7639
7747
|
try {
|
|
@@ -7696,7 +7804,7 @@ async function runExploit(opts) {
|
|
|
7696
7804
|
}
|
|
7697
7805
|
async function exploitAction(opts) {
|
|
7698
7806
|
if (opts.agent) {
|
|
7699
|
-
const { agentFromExploitOpts } = await import("./exploit-agent-
|
|
7807
|
+
const { agentFromExploitOpts } = await import("./exploit-agent-4E4HXKUA.js");
|
|
7700
7808
|
process.exitCode = await agentFromExploitOpts({
|
|
7701
7809
|
...opts.task ? { task: opts.task } : {},
|
|
7702
7810
|
...opts.flagPath ? { flagPath: opts.flagPath } : {},
|
|
@@ -7711,7 +7819,7 @@ async function exploitAction(opts) {
|
|
|
7711
7819
|
return;
|
|
7712
7820
|
}
|
|
7713
7821
|
if (opts.autoclimb) {
|
|
7714
|
-
const { autoclimbFromExploitOpts } = await import("./exploit-autoclimb-
|
|
7822
|
+
const { autoclimbFromExploitOpts } = await import("./exploit-autoclimb-5GRXI6VQ.js");
|
|
7715
7823
|
process.exitCode = await autoclimbFromExploitOpts({
|
|
7716
7824
|
...opts.bugSpec ? { bugSpec: opts.bugSpec } : {},
|
|
7717
7825
|
...opts.bootScript ? { bootScript: opts.bootScript } : {},
|
|
@@ -7725,7 +7833,7 @@ async function exploitAction(opts) {
|
|
|
7725
7833
|
throw new Error("missing required flag: --finding <path>");
|
|
7726
7834
|
}
|
|
7727
7835
|
if (opts.climb) {
|
|
7728
|
-
const { runClimb } = await import("./exploit-climb-
|
|
7836
|
+
const { runClimb } = await import("./exploit-climb-AHQEJ2I2.js");
|
|
7729
7837
|
let loopBoots = 8;
|
|
7730
7838
|
if (opts.loopBoots !== void 0) {
|
|
7731
7839
|
loopBoots = parseInt(opts.loopBoots, 10);
|
|
@@ -7898,7 +8006,7 @@ async function runHunt(opts) {
|
|
|
7898
8006
|
makeLloreJudge,
|
|
7899
8007
|
makeHuntProveStage,
|
|
7900
8008
|
prepare: prepare2
|
|
7901
|
-
} = await import("./dist-
|
|
8009
|
+
} = await import("./dist-ONIRKDH6.js");
|
|
7902
8010
|
const log = opts.log ?? (() => {
|
|
7903
8011
|
});
|
|
7904
8012
|
const runtime = opts.runtime ?? "api";
|
|
@@ -8246,7 +8354,7 @@ function parseWitnessMode(raw) {
|
|
|
8246
8354
|
}
|
|
8247
8355
|
async function recencyAction(opts) {
|
|
8248
8356
|
if (!opts.tree) throw new Error("missing required flag: --tree <kernel source tree>");
|
|
8249
|
-
const { runRecencyHunt, renderRecencyReportMarkdown } = await import("./dist-
|
|
8357
|
+
const { runRecencyHunt, renderRecencyReportMarkdown } = await import("./dist-ONIRKDH6.js");
|
|
8250
8358
|
const tree = resolve14(opts.tree);
|
|
8251
8359
|
const runtime = opts.runtime ?? "api";
|
|
8252
8360
|
const modelDir = opts.modelDir ? resolve14(opts.modelDir) : join10(tree, ".recency-models");
|
|
@@ -8323,9 +8431,271 @@ function registerRecencyHuntCommand(program) {
|
|
|
8323
8431
|
});
|
|
8324
8432
|
}
|
|
8325
8433
|
|
|
8434
|
+
// packages/cli/src/commands/lens-synth.ts
|
|
8435
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
8436
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
8437
|
+
import { resolve as resolve15 } from "node:path";
|
|
8438
|
+
function isRecord(value) {
|
|
8439
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8440
|
+
}
|
|
8441
|
+
function parseFixtures(value, label) {
|
|
8442
|
+
if (value === void 0) return [];
|
|
8443
|
+
if (!Array.isArray(value)) throw new Error(`${label} must be an array`);
|
|
8444
|
+
return value.map((entry, i) => {
|
|
8445
|
+
if (!isRecord(entry)) throw new Error(`${label}[${i}] must be an object`);
|
|
8446
|
+
const id = entry.id;
|
|
8447
|
+
const path = entry.path;
|
|
8448
|
+
if (typeof id !== "string" || id.trim() === "") throw new Error(`${label}[${i}].id must be a non-empty string`);
|
|
8449
|
+
if (typeof path !== "string" || path.trim() === "") throw new Error(`${label}[${i}].path must be a non-empty string`);
|
|
8450
|
+
const fixture = { id, path };
|
|
8451
|
+
if (typeof entry.note === "string") fixture.note = entry.note;
|
|
8452
|
+
if (typeof entry.expectedCwe === "string") fixture.expectedCwe = entry.expectedCwe;
|
|
8453
|
+
if (typeof entry.expectedFile === "string") fixture.expectedFile = entry.expectedFile;
|
|
8454
|
+
if (typeof entry.expectedLine === "number" && Number.isFinite(entry.expectedLine)) {
|
|
8455
|
+
fixture.expectedLine = entry.expectedLine;
|
|
8456
|
+
}
|
|
8457
|
+
if (Array.isArray(entry.expectedRange) && entry.expectedRange.length === 2 && typeof entry.expectedRange[0] === "number" && typeof entry.expectedRange[1] === "number") {
|
|
8458
|
+
fixture.expectedRange = [entry.expectedRange[0], entry.expectedRange[1]];
|
|
8459
|
+
}
|
|
8460
|
+
if (typeof entry.contentDigest === "string") fixture.contentDigest = entry.contentDigest;
|
|
8461
|
+
if (typeof entry.cleanProvenance === "string") fixture.cleanProvenance = entry.cleanProvenance;
|
|
8462
|
+
return fixture;
|
|
8463
|
+
});
|
|
8464
|
+
}
|
|
8465
|
+
function parseMissInputFile(raw) {
|
|
8466
|
+
if (!isRecord(raw)) throw new Error("miss-input must be a JSON object");
|
|
8467
|
+
const missesRaw = isRecord(raw.misses) ? raw.misses : {};
|
|
8468
|
+
const corpusRaw = isRecord(raw.corpus) ? raw.corpus : {};
|
|
8469
|
+
const misses = {
|
|
8470
|
+
...Array.isArray(missesRaw.confirmedMisses) ? { confirmedMisses: missesRaw.confirmedMisses } : {},
|
|
8471
|
+
...Array.isArray(missesRaw.incompleteCoverage) ? { incompleteCoverage: missesRaw.incompleteCoverage } : {},
|
|
8472
|
+
...Array.isArray(missesRaw.curatedCandidates) ? { curatedCandidates: missesRaw.curatedCandidates } : {}
|
|
8473
|
+
};
|
|
8474
|
+
const heldOutFixtures = parseFixtures(corpusRaw.heldOut, "corpus.heldOut");
|
|
8475
|
+
const corpus = {
|
|
8476
|
+
positives: parseFixtures(corpusRaw.positives, "corpus.positives"),
|
|
8477
|
+
negativeControls: parseFixtures(corpusRaw.negativeControls, "corpus.negativeControls"),
|
|
8478
|
+
...heldOutFixtures.length > 0 ? { heldOut: heldOutFixtures } : {},
|
|
8479
|
+
...typeof corpusRaw.baselineDigest === "string" ? { baselineDigest: corpusRaw.baselineDigest } : {}
|
|
8480
|
+
};
|
|
8481
|
+
if (corpus.positives.length === 0) {
|
|
8482
|
+
throw new Error("corpus.positives must contain at least one fixture (the seeded miss) \u2014 the loop is fail-closed without it");
|
|
8483
|
+
}
|
|
8484
|
+
if (corpus.negativeControls.length === 0) {
|
|
8485
|
+
throw new Error("corpus.negativeControls must contain at least one fixture \u2014 the loop cannot measure FP regression without it");
|
|
8486
|
+
}
|
|
8487
|
+
if (!corpus.heldOut || corpus.heldOut.length === 0) {
|
|
8488
|
+
throw new Error("corpus.heldOut must contain at least one fixture \u2014 held-out positives are required to demonstrate generalisation beyond development misses");
|
|
8489
|
+
}
|
|
8490
|
+
return { misses, corpus };
|
|
8491
|
+
}
|
|
8492
|
+
async function harvestBenchMisses(fromBench, manifestPath) {
|
|
8493
|
+
const ledger = await loadLedger(resolve15(fromBench));
|
|
8494
|
+
const entry = lastGreen(ledger) ?? ledger.entries[ledger.entries.length - 1];
|
|
8495
|
+
if (!entry) throw new Error(`--from-bench: ledger ${fromBench} has no entries to harvest`);
|
|
8496
|
+
const manifest = await loadManifest(resolve15(manifestPath));
|
|
8497
|
+
const result = harvestMissesFromLedgerEntry(entry, manifest);
|
|
8498
|
+
return { misses: result.misses, result };
|
|
8499
|
+
}
|
|
8500
|
+
function trialCount(value) {
|
|
8501
|
+
const count = value ?? 2;
|
|
8502
|
+
if (!Number.isSafeInteger(count) || count < 2 || count > 10) throw new Error("--trials must be an integer between 2 and 10");
|
|
8503
|
+
return count;
|
|
8504
|
+
}
|
|
8505
|
+
async function runLensSynthesisInput(input, opts, deps = {}) {
|
|
8506
|
+
const trials = trialCount(opts.trials);
|
|
8507
|
+
const log = deps.log ?? (() => {
|
|
8508
|
+
});
|
|
8509
|
+
const probe = deps.probe ?? makeFinderLensProbe({ log });
|
|
8510
|
+
return runLensSynthesisLoop(input, {
|
|
8511
|
+
...deps.model ? { model: deps.model } : {},
|
|
8512
|
+
...opts.model ? { modelId: opts.model } : {},
|
|
8513
|
+
probe,
|
|
8514
|
+
...opts.registry ? { registryPath: resolve15(opts.registry) } : {},
|
|
8515
|
+
maxRegistrations: opts.maxRegister ?? 1,
|
|
8516
|
+
dryRun: !opts.promote,
|
|
8517
|
+
trials,
|
|
8518
|
+
...opts.signal ? { signal: opts.signal } : {},
|
|
8519
|
+
log
|
|
8520
|
+
});
|
|
8521
|
+
}
|
|
8522
|
+
async function runLensSynthCommand(opts, deps = {}) {
|
|
8523
|
+
const raw = JSON.parse(readFileSync13(resolve15(opts.missInput), "utf8"));
|
|
8524
|
+
let input = parseMissInputFile(raw);
|
|
8525
|
+
if (opts.fromBench) {
|
|
8526
|
+
if (!opts.manifest) throw new Error("--from-bench requires --manifest");
|
|
8527
|
+
const { misses } = await harvestBenchMisses(opts.fromBench, opts.manifest);
|
|
8528
|
+
input = { ...input, misses: mergeHarvestedMisses(input.misses, misses) };
|
|
8529
|
+
deps.log?.(`[lens-synth] harvested ${misses.length} bench miss(es) from ${opts.fromBench}`);
|
|
8530
|
+
}
|
|
8531
|
+
return runLensSynthesisInput(input, opts, deps);
|
|
8532
|
+
}
|
|
8533
|
+
async function watchLensSynthCommand(opts, deps = {}) {
|
|
8534
|
+
const inputPath = resolve15(opts.missInput);
|
|
8535
|
+
const log = deps.log ?? (() => {
|
|
8536
|
+
});
|
|
8537
|
+
const requestedInterval = opts.pollIntervalMs ?? 2e3;
|
|
8538
|
+
const pollIntervalMs = Number.isFinite(requestedInterval) ? Math.max(100, Math.floor(requestedInterval)) : 2e3;
|
|
8539
|
+
const sleep = deps.sleep ?? ((milliseconds) => new Promise((done) => setTimeout(done, milliseconds)));
|
|
8540
|
+
let previousRevision;
|
|
8541
|
+
while (!deps.signal?.aborted) {
|
|
8542
|
+
try {
|
|
8543
|
+
const bytes = readFileSync13(inputPath);
|
|
8544
|
+
const revision2 = createHash5("sha256").update(bytes).digest("hex");
|
|
8545
|
+
if (revision2 !== previousRevision) {
|
|
8546
|
+
previousRevision = revision2;
|
|
8547
|
+
const input = parseMissInputFile(JSON.parse(bytes.toString("utf8")));
|
|
8548
|
+
const result = await runLensSynthesisInput(input, opts, deps);
|
|
8549
|
+
deps.onResult?.(result);
|
|
8550
|
+
}
|
|
8551
|
+
} catch (cause) {
|
|
8552
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
8553
|
+
const revision2 = `error:${error.name}:${error.message}`;
|
|
8554
|
+
if (revision2 !== previousRevision) {
|
|
8555
|
+
previousRevision = revision2;
|
|
8556
|
+
if (deps.onError) deps.onError(error);
|
|
8557
|
+
else log(`[lens-synth] input revision rejected: ${error.message}`);
|
|
8558
|
+
}
|
|
8559
|
+
}
|
|
8560
|
+
if (deps.signal?.aborted) return;
|
|
8561
|
+
const signal = deps.signal;
|
|
8562
|
+
if (!signal) {
|
|
8563
|
+
await sleep(pollIntervalMs);
|
|
8564
|
+
continue;
|
|
8565
|
+
}
|
|
8566
|
+
if (signal.aborted) return;
|
|
8567
|
+
await new Promise((resume) => {
|
|
8568
|
+
const onAbort = () => {
|
|
8569
|
+
signal.removeEventListener("abort", onAbort);
|
|
8570
|
+
resume();
|
|
8571
|
+
};
|
|
8572
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
8573
|
+
void sleep(pollIntervalMs).then(() => {
|
|
8574
|
+
signal.removeEventListener("abort", onAbort);
|
|
8575
|
+
resume();
|
|
8576
|
+
});
|
|
8577
|
+
});
|
|
8578
|
+
}
|
|
8579
|
+
}
|
|
8580
|
+
function formatLensSynthResult(result, dryRun2) {
|
|
8581
|
+
const lines = [
|
|
8582
|
+
`captured ${result.candidatesCaptured} miss candidate(s) \u2192 ${result.clusters} cluster(s) \u2192 ${result.synthesized.length} synthesized`
|
|
8583
|
+
];
|
|
8584
|
+
for (const validation of result.validations) {
|
|
8585
|
+
lines.push(` validate ${validation.lensId}: ${validation.passed ? "CHAMPION" : "rejected"} \u2014 ${validation.reason}`);
|
|
8586
|
+
}
|
|
8587
|
+
if (dryRun2) {
|
|
8588
|
+
lines.push(`dry-run: ${result.validations.filter((validation) => validation.passed).length} champion(s) would register (nothing written)`);
|
|
8589
|
+
} else {
|
|
8590
|
+
lines.push(
|
|
8591
|
+
result.registered.length > 0 ? `REGISTERED ${result.registered.length} lens(es): ${result.registered.map((registered) => registered.uid).join(", ")}` : "registered 0 lenses"
|
|
8592
|
+
);
|
|
8593
|
+
}
|
|
8594
|
+
for (const rejected of result.rejected) lines.push(` rejected ${rejected.id}: ${rejected.reason}`);
|
|
8595
|
+
for (const warning of result.warnings) lines.push(` warning: ${warning}`);
|
|
8596
|
+
return lines.join("\n");
|
|
8597
|
+
}
|
|
8598
|
+
function formatLensRegistryStatus(status) {
|
|
8599
|
+
const lines = [
|
|
8600
|
+
`registry: ${status.path}`,
|
|
8601
|
+
`state: ${status.valid ? "valid" : "INVALID"}`,
|
|
8602
|
+
`exists: ${status.exists ? "yes" : "no"}`,
|
|
8603
|
+
`active lenses: ${status.activeLensCount}`,
|
|
8604
|
+
`ledger entries: ${status.ledgerEntries}`,
|
|
8605
|
+
`unbound archetypes: ${status.unboundArchetypes}`
|
|
8606
|
+
];
|
|
8607
|
+
if (status.error) lines.push(`error: ${status.error}`);
|
|
8608
|
+
return lines.join("\n");
|
|
8609
|
+
}
|
|
8610
|
+
function registerLensSynthCommand(program) {
|
|
8611
|
+
program.command("lens-synth").description("Improve appsec detection coverage from curated missed findings").option("--miss-input <path>", "curated miss-input JSON ({ misses, corpus })").option("--registry <path>", "durable overlay path (default: ~/.0/lenses/appsec-archetypes.json)").option("--max-register <n>", "cap promoted champions per input revision", (value) => Number.parseInt(value, 10)).option("-m, --model <id>", "synthesis model override").option("--promote", "persist a validated champion to the durable overlay", false).option("--trials <n>", "repeated validation trials (2\u201310; default 2)", Number).option("--from-bench <ledger>", "harvest the champion's false-negatives from a benchmark ledger into the curated misses (requires --manifest)").option("--manifest <path>", "bench manifest path (ground-truth vuln class + sink); required with --from-bench").option("--watch", "poll the miss-input and process each new content revision", false).option("--poll-interval <ms>", "watch polling interval (minimum 100ms)", "2000").option("--status", "show the active durable overlay and promotion ledger", false).option("--rollback <lens-id>", "retire one previously promoted overlay lens").option("--json", "print machine-readable output", false).action(async (opts) => {
|
|
8612
|
+
try {
|
|
8613
|
+
const registry = opts.registry ? resolve15(opts.registry) : void 0;
|
|
8614
|
+
if (opts.status && opts.rollback) throw new Error("--status and --rollback cannot be combined");
|
|
8615
|
+
if (opts.status) {
|
|
8616
|
+
const status = inspectLensRegistry(registry);
|
|
8617
|
+
process.stdout.write(opts.json ? `${JSON.stringify(status, null, 2)}
|
|
8618
|
+
` : `${formatLensRegistryStatus(status)}
|
|
8619
|
+
`);
|
|
8620
|
+
if (!status.valid) process.exitCode = 3;
|
|
8621
|
+
return;
|
|
8622
|
+
}
|
|
8623
|
+
if (opts.rollback) {
|
|
8624
|
+
const outcome = retireArchetype(String(opts.rollback), { ...registry ? { registryPath: registry } : {} });
|
|
8625
|
+
process.stdout.write(
|
|
8626
|
+
opts.json ? `${JSON.stringify(outcome, null, 2)}
|
|
8627
|
+
` : outcome.retired ? `RETIRED ${outcome.id} from ${outcome.registryPath}
|
|
8628
|
+
` : `not retired ${outcome.id}: ${outcome.reason ?? "unknown reason"}
|
|
8629
|
+
`
|
|
8630
|
+
);
|
|
8631
|
+
if (!outcome.retired) process.exitCode = 3;
|
|
8632
|
+
return;
|
|
8633
|
+
}
|
|
8634
|
+
if (!opts.missInput) throw new Error("--miss-input is required unless --status or --rollback is used");
|
|
8635
|
+
if (opts.maxRegister !== void 0 && (!Number.isInteger(opts.maxRegister) || opts.maxRegister < 0)) {
|
|
8636
|
+
throw new Error("--max-register must be a non-negative integer");
|
|
8637
|
+
}
|
|
8638
|
+
if (opts.fromBench && !opts.manifest) throw new Error("--from-bench requires --manifest");
|
|
8639
|
+
if (opts.fromBench && opts.watch) throw new Error("--from-bench cannot be combined with --watch");
|
|
8640
|
+
const pollIntervalMs = Number.parseInt(opts.pollInterval ?? "2000", 10);
|
|
8641
|
+
if (!Number.isInteger(pollIntervalMs) || pollIntervalMs < 100) {
|
|
8642
|
+
throw new Error("--poll-interval must be an integer of at least 100ms");
|
|
8643
|
+
}
|
|
8644
|
+
const request = {
|
|
8645
|
+
missInput: String(opts.missInput),
|
|
8646
|
+
...registry ? { registry } : {},
|
|
8647
|
+
...opts.maxRegister !== void 0 ? { maxRegister: opts.maxRegister } : {},
|
|
8648
|
+
...opts.model ? { model: String(opts.model) } : {},
|
|
8649
|
+
promote: Boolean(opts.promote),
|
|
8650
|
+
trials: trialCount(opts.trials),
|
|
8651
|
+
...opts.fromBench ? { fromBench: String(opts.fromBench) } : {},
|
|
8652
|
+
...opts.manifest ? { manifest: resolve15(String(opts.manifest)) } : {}
|
|
8653
|
+
};
|
|
8654
|
+
const printResult = (result) => {
|
|
8655
|
+
process.stdout.write(
|
|
8656
|
+
opts.json ? `${JSON.stringify(result, null, 2)}
|
|
8657
|
+
` : `${formatLensSynthResult(result, !opts.promote)}
|
|
8658
|
+
`
|
|
8659
|
+
);
|
|
8660
|
+
};
|
|
8661
|
+
const log = (message) => {
|
|
8662
|
+
process.stderr.write(`${message}
|
|
8663
|
+
`);
|
|
8664
|
+
};
|
|
8665
|
+
if (!opts.watch) {
|
|
8666
|
+
printResult(await runLensSynthCommand(request, { log }));
|
|
8667
|
+
return;
|
|
8668
|
+
}
|
|
8669
|
+
const controller = new AbortController();
|
|
8670
|
+
const stop = () => controller.abort();
|
|
8671
|
+
process.once("SIGINT", stop);
|
|
8672
|
+
process.once("SIGTERM", stop);
|
|
8673
|
+
try {
|
|
8674
|
+
await watchLensSynthCommand(
|
|
8675
|
+
{ ...request, pollIntervalMs },
|
|
8676
|
+
{
|
|
8677
|
+
log,
|
|
8678
|
+
signal: controller.signal,
|
|
8679
|
+
onResult: printResult,
|
|
8680
|
+
onError: (error) => process.stderr.write(`lens-synth watch: ${error.message}
|
|
8681
|
+
`)
|
|
8682
|
+
}
|
|
8683
|
+
);
|
|
8684
|
+
} finally {
|
|
8685
|
+
process.off("SIGINT", stop);
|
|
8686
|
+
process.off("SIGTERM", stop);
|
|
8687
|
+
}
|
|
8688
|
+
} catch (error) {
|
|
8689
|
+
process.stderr.write(`lens-synth: ${error instanceof Error ? error.message : String(error)}
|
|
8690
|
+
`);
|
|
8691
|
+
process.exitCode = 3;
|
|
8692
|
+
}
|
|
8693
|
+
});
|
|
8694
|
+
}
|
|
8695
|
+
|
|
8326
8696
|
// packages/cli/src/commands/memsafety.ts
|
|
8327
8697
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, realpathSync, writeFileSync as writeFileSync10 } from "node:fs";
|
|
8328
|
-
import { resolve as
|
|
8698
|
+
import { resolve as resolve16, join as join11, sep } from "node:path";
|
|
8329
8699
|
var VALID_LANGUAGES = /* @__PURE__ */ new Set(["c", "cpp", "rust"]);
|
|
8330
8700
|
var VALID_BUILD_SYSTEMS3 = /* @__PURE__ */ new Set([
|
|
8331
8701
|
"cargo",
|
|
@@ -8350,7 +8720,7 @@ function detectMemSafetyBuild(sourceRoot, exists2 = existsSync12) {
|
|
|
8350
8720
|
function resolveArtifactDir(value, sourceRoot) {
|
|
8351
8721
|
const raw = value?.trim();
|
|
8352
8722
|
if (!raw) return void 0;
|
|
8353
|
-
const artifactDir =
|
|
8723
|
+
const artifactDir = resolve16(raw);
|
|
8354
8724
|
const preparedRoot = realpathSync(sourceRoot);
|
|
8355
8725
|
mkdirSync8(artifactDir, { recursive: true, mode: 448 });
|
|
8356
8726
|
const canonicalArtifactDir = realpathSync(artifactDir);
|
|
@@ -8362,7 +8732,7 @@ function resolveArtifactDir(value, sourceRoot) {
|
|
|
8362
8732
|
return canonicalArtifactDir;
|
|
8363
8733
|
}
|
|
8364
8734
|
async function runMemSafety(opts) {
|
|
8365
|
-
const { prepare: prepare2, runMemSafetyScan } = await import("./dist-
|
|
8735
|
+
const { prepare: prepare2, runMemSafetyScan } = await import("./dist-ONIRKDH6.js");
|
|
8366
8736
|
const log = opts.log ?? (() => {
|
|
8367
8737
|
});
|
|
8368
8738
|
const prepared = await prepare2(
|
|
@@ -8373,11 +8743,11 @@ async function runMemSafety(opts) {
|
|
|
8373
8743
|
if (e.message) log(`[memsafety:source] ${e.message}`);
|
|
8374
8744
|
}
|
|
8375
8745
|
);
|
|
8376
|
-
const sourceRoot =
|
|
8746
|
+
const sourceRoot = resolve16(prepared.resolvedTarget);
|
|
8377
8747
|
try {
|
|
8378
8748
|
let scopeRoot = sourceRoot;
|
|
8379
8749
|
if (opts.subsystem && opts.subsystem.trim() !== "") {
|
|
8380
|
-
const scoped =
|
|
8750
|
+
const scoped = resolve16(join11(sourceRoot, opts.subsystem));
|
|
8381
8751
|
if (scoped !== sourceRoot && !scoped.startsWith(sourceRoot + sep)) {
|
|
8382
8752
|
throw new Error(`--subsystem '${opts.subsystem}' escapes the source tree`);
|
|
8383
8753
|
}
|
|
@@ -8502,7 +8872,7 @@ function parseArtifactOptions(opts) {
|
|
|
8502
8872
|
throw new Error("--artifact-max-bytes must be at least 65536");
|
|
8503
8873
|
}
|
|
8504
8874
|
return {
|
|
8505
|
-
artifactDir:
|
|
8875
|
+
artifactDir: resolve16(artifactDir),
|
|
8506
8876
|
artifactMaxBytes: maxBytes
|
|
8507
8877
|
};
|
|
8508
8878
|
}
|
|
@@ -8526,7 +8896,7 @@ async function memsafetyAction(target, opts) {
|
|
|
8526
8896
|
log: (m) => process.stderr.write(m + "\n")
|
|
8527
8897
|
});
|
|
8528
8898
|
const json = JSON.stringify(outcome.result, null, 2);
|
|
8529
|
-
if (opts.output) writeFileSync10(
|
|
8899
|
+
if (opts.output) writeFileSync10(resolve16(opts.output), json + "\n", "utf8");
|
|
8530
8900
|
else process.stdout.write(json + "\n");
|
|
8531
8901
|
process.exitCode = outcome.exitCode;
|
|
8532
8902
|
}
|
|
@@ -8546,9 +8916,9 @@ function registerMemsafetyCommand(program) {
|
|
|
8546
8916
|
const reason = err instanceof Error ? err.message : String(err);
|
|
8547
8917
|
const json = JSON.stringify({ mode: "memsafety", error: reason }, null, 2);
|
|
8548
8918
|
if (opts.output) {
|
|
8549
|
-
const { writeFileSync:
|
|
8919
|
+
const { writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
8550
8920
|
try {
|
|
8551
|
-
|
|
8921
|
+
writeFileSync18(resolve16(opts.output), json + "\n", "utf8");
|
|
8552
8922
|
} catch {
|
|
8553
8923
|
process.stderr.write(json + "\n");
|
|
8554
8924
|
}
|
|
@@ -8559,7 +8929,7 @@ function registerMemsafetyCommand(program) {
|
|
|
8559
8929
|
}
|
|
8560
8930
|
|
|
8561
8931
|
// packages/cli/src/commands/assumption-hunt.ts
|
|
8562
|
-
import { resolve as
|
|
8932
|
+
import { resolve as resolve17 } from "node:path";
|
|
8563
8933
|
function parseWitnessMode2(raw) {
|
|
8564
8934
|
if (raw === void 0) return void 0;
|
|
8565
8935
|
const m = raw.trim();
|
|
@@ -8569,16 +8939,16 @@ function parseWitnessMode2(raw) {
|
|
|
8569
8939
|
return m;
|
|
8570
8940
|
}
|
|
8571
8941
|
async function runAssumptionHuntCli(sourceRoot, opts) {
|
|
8572
|
-
const { runAssumptionHunt, makeSkepticVerifier } = await import("./dist-
|
|
8942
|
+
const { runAssumptionHunt, makeSkepticVerifier } = await import("./dist-ONIRKDH6.js");
|
|
8573
8943
|
const log = (m) => process.stderr.write(m + "\n");
|
|
8574
8944
|
const runtime = opts.runtime ?? "api";
|
|
8575
|
-
const root =
|
|
8945
|
+
const root = resolve17(sourceRoot);
|
|
8576
8946
|
const subsystem = opts.subsystem?.trim() || "subsystem";
|
|
8577
8947
|
const files = (opts.files ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
8578
8948
|
if (files.length === 0) {
|
|
8579
8949
|
throw new Error("--files is required: a comma-separated list of subsystem source files (repo-relative to <source-root>)");
|
|
8580
8950
|
}
|
|
8581
|
-
const modelPath = opts.modelPath ?
|
|
8951
|
+
const modelPath = opts.modelPath ? resolve17(opts.modelPath) : resolve17(root, `.0/assumption-models/${subsystem.replaceAll("/", "_")}.json`);
|
|
8582
8952
|
const models = opts.models ? opts.models.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
8583
8953
|
const verify = opts.skipHunt || opts.noVerify ? void 0 : (
|
|
8584
8954
|
// `finderModels` decorrelates the refute pass from the finder fan-out
|
|
@@ -8604,7 +8974,7 @@ async function runAssumptionHuntCli(sourceRoot, opts) {
|
|
|
8604
8974
|
...models ? { finderModels: models } : {},
|
|
8605
8975
|
...opts.finderTargeting === false ? { finderTargeting: false } : {},
|
|
8606
8976
|
...opts.dualView === false ? { dualView: false } : {},
|
|
8607
|
-
...opts.excerptDir ? { excerptDir:
|
|
8977
|
+
...opts.excerptDir ? { excerptDir: resolve17(opts.excerptDir) } : {},
|
|
8608
8978
|
...opts.dynamicWitness ? {
|
|
8609
8979
|
dynamicWitness: {
|
|
8610
8980
|
runtime,
|
|
@@ -8687,8 +9057,8 @@ function registerAssumptionHuntCommand(program) {
|
|
|
8687
9057
|
const outcome = await runAssumptionHuntCli(sourceRoot, opts);
|
|
8688
9058
|
const json = JSON.stringify(outcome.result, null, 2);
|
|
8689
9059
|
if (opts.output) {
|
|
8690
|
-
const { writeFileSync:
|
|
8691
|
-
|
|
9060
|
+
const { writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
9061
|
+
writeFileSync18(resolve17(opts.output), json + "\n", "utf8");
|
|
8692
9062
|
} else process.stdout.write(json + "\n");
|
|
8693
9063
|
process.exitCode = outcome.exitCode;
|
|
8694
9064
|
} catch (err) {
|
|
@@ -8700,8 +9070,8 @@ function registerAssumptionHuntCommand(program) {
|
|
|
8700
9070
|
}
|
|
8701
9071
|
|
|
8702
9072
|
// packages/cli/src/commands/specdrift.ts
|
|
8703
|
-
import { readFileSync as
|
|
8704
|
-
import { basename as basename4, resolve as
|
|
9073
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "node:fs";
|
|
9074
|
+
import { basename as basename4, resolve as resolve18 } from "node:path";
|
|
8705
9075
|
function parsePositive4(flag, raw, dflt) {
|
|
8706
9076
|
if (raw === void 0) return dflt;
|
|
8707
9077
|
const n = parseInt(raw, 10);
|
|
@@ -8711,8 +9081,8 @@ function parsePositive4(flag, raw, dflt) {
|
|
|
8711
9081
|
async function runSpecdriftExtract(opts) {
|
|
8712
9082
|
if (!opts.spec) throw new Error("missing required flag: --spec <path>");
|
|
8713
9083
|
const maxInvariants = parsePositive4("--max-invariants", opts.maxInvariants, 40);
|
|
8714
|
-
const specPath =
|
|
8715
|
-
const specText =
|
|
9084
|
+
const specPath = resolve18(opts.spec);
|
|
9085
|
+
const specText = readFileSync14(specPath, "utf8");
|
|
8716
9086
|
return extractSpecInvariants({
|
|
8717
9087
|
specName: opts.specName ?? basename4(specPath),
|
|
8718
9088
|
specText,
|
|
@@ -8733,8 +9103,8 @@ async function runSpecdriftSourceWorkflow(opts, stage) {
|
|
|
8733
9103
|
const maxCandidatesPerInvariant = parsePositive4("--max-candidates-per-invariant", opts.maxCandidatesPerInvariant, 5);
|
|
8734
9104
|
const maxHypotheses = parsePositive4("--max-hypotheses", opts.maxHypotheses, 20);
|
|
8735
9105
|
const timeout = parsePositive4("--timeout", opts.timeout, 6e5);
|
|
8736
|
-
const specPath =
|
|
8737
|
-
const specText =
|
|
9106
|
+
const specPath = resolve18(opts.spec);
|
|
9107
|
+
const specText = readFileSync14(specPath, "utf8");
|
|
8738
9108
|
const prepared = await prepare(opts.source, "source-code", { timeout }, (e) => {
|
|
8739
9109
|
if (e.message) process.stderr.write(`[specdrift:source] ${e.message}
|
|
8740
9110
|
`);
|
|
@@ -8743,7 +9113,7 @@ async function runSpecdriftSourceWorkflow(opts, stage) {
|
|
|
8743
9113
|
const input = {
|
|
8744
9114
|
specName: opts.specName ?? basename4(specPath),
|
|
8745
9115
|
specText,
|
|
8746
|
-
sourceRoot:
|
|
9116
|
+
sourceRoot: resolve18(prepared.resolvedTarget),
|
|
8747
9117
|
maxInvariants,
|
|
8748
9118
|
maxFiles,
|
|
8749
9119
|
maxCandidatesPerInvariant
|
|
@@ -8757,14 +9127,14 @@ async function writeJsonResult(fn, output2, stage = "extract") {
|
|
|
8757
9127
|
try {
|
|
8758
9128
|
const result = await fn();
|
|
8759
9129
|
const json = JSON.stringify(result, null, 2);
|
|
8760
|
-
if (output2) writeFileSync11(
|
|
9130
|
+
if (output2) writeFileSync11(resolve18(output2), json + "\n", "utf8");
|
|
8761
9131
|
else process.stdout.write(json + "\n");
|
|
8762
9132
|
} catch (err) {
|
|
8763
9133
|
const reason = err instanceof Error ? err.message : String(err);
|
|
8764
9134
|
const json = JSON.stringify({ mode: "specdrift", stage, error: reason }, null, 2);
|
|
8765
9135
|
if (output2) {
|
|
8766
9136
|
try {
|
|
8767
|
-
writeFileSync11(
|
|
9137
|
+
writeFileSync11(resolve18(output2), json + "\n", "utf8");
|
|
8768
9138
|
} catch {
|
|
8769
9139
|
process.stderr.write(json + "\n");
|
|
8770
9140
|
}
|
|
@@ -8786,8 +9156,8 @@ function registerSpecdriftCommand(program) {
|
|
|
8786
9156
|
}
|
|
8787
9157
|
|
|
8788
9158
|
// packages/cli/src/commands/protocol-check.ts
|
|
8789
|
-
import { readFileSync as
|
|
8790
|
-
import { resolve as
|
|
9159
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
9160
|
+
import { resolve as resolve19 } from "node:path";
|
|
8791
9161
|
function resolveNativeRuntime(runtimeFlag) {
|
|
8792
9162
|
const choice = (runtimeFlag ?? "auto").toLowerCase();
|
|
8793
9163
|
const timeout = 6e4;
|
|
@@ -8806,9 +9176,9 @@ function resolveNativeRuntime(runtimeFlag) {
|
|
|
8806
9176
|
return rt;
|
|
8807
9177
|
}
|
|
8808
9178
|
function readExcerpt(path, label) {
|
|
8809
|
-
const abs =
|
|
9179
|
+
const abs = resolve19(path);
|
|
8810
9180
|
try {
|
|
8811
|
-
return
|
|
9181
|
+
return readFileSync15(abs, "utf8");
|
|
8812
9182
|
} catch (err) {
|
|
8813
9183
|
throw new Error(
|
|
8814
9184
|
`failed to read ${label} from ${abs}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -8932,8 +9302,8 @@ function registerProtocolCheckCommand(program) {
|
|
|
8932
9302
|
}
|
|
8933
9303
|
|
|
8934
9304
|
// packages/cli/src/commands/cve.ts
|
|
8935
|
-
import { readFileSync as
|
|
8936
|
-
import { resolve as
|
|
9305
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
9306
|
+
import { resolve as resolve20 } from "node:path";
|
|
8937
9307
|
var VALID_FORMATS2 = ["json", "table"];
|
|
8938
9308
|
var EXIT_OK = 0;
|
|
8939
9309
|
var EXIT_USER_ERROR = 1;
|
|
@@ -8965,10 +9335,10 @@ function parseAttempts(input, fallback = 5) {
|
|
|
8965
9335
|
return parsed;
|
|
8966
9336
|
}
|
|
8967
9337
|
function loadArtifactsFile(path) {
|
|
8968
|
-
const abs =
|
|
9338
|
+
const abs = resolve20(path);
|
|
8969
9339
|
let raw;
|
|
8970
9340
|
try {
|
|
8971
|
-
raw =
|
|
9341
|
+
raw = readFileSync16(abs, "utf-8");
|
|
8972
9342
|
} catch (err) {
|
|
8973
9343
|
throw new Error(`failed to read --artifacts ${abs}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8974
9344
|
}
|
|
@@ -9944,7 +10314,7 @@ function resolveConsoleAutonomyMode(opts) {
|
|
|
9944
10314
|
function registerConsoleCommand(program) {
|
|
9945
10315
|
program.command("console").alias("chat").description(
|
|
9946
10316
|
"Run a headless chat prompt; interactive conversations use 0 web"
|
|
9947
|
-
).option("--target <url>", "Engagement target the tools operate against (optional; can be named in-chat)").option("--scope <file>", "Initial policy for the optional scope plugin; activate with `0 plugin enable scope`").option("--finding <id>", "Focus the chat on one persisted finding").option("--finding-intent <intent>", "Finding workflow: investigate, verify, or draft_fix").option("--db-path <path>", "Persistent findings database (defaults to ZERO_DB_PATH or the local store)").option("-m, --model <id>", "Override the LLM model id (else provider default)").option("--role <role>", "Tool set to expose: audit|review|discovery|attack|verify (default audit = every tool)").option("--mode <mode>", "Approval mode: standard|recon|copilot|yolo (default yolo)").option("--yolo", "Shortcut for --mode yolo (no per-action prompts; independent credential, private-network and sandbox protections remain).").option("--autonomy <mode>", "Alias of --mode (standard|copilot|yolo|recon); --mode/--yolo take precedence.").option("--max-tool-calls <n>", "
|
|
10317
|
+
).option("--target <url>", "Engagement target the tools operate against (optional; can be named in-chat)").option("--scope <file>", "Initial policy for the optional scope plugin; activate with `0 plugin enable scope`").option("--finding <id>", "Focus the chat on one persisted finding").option("--finding-intent <intent>", "Finding workflow: investigate, verify, or draft_fix").option("--db-path <path>", "Persistent findings database (defaults to ZERO_DB_PATH or the local store)").option("-m, --model <id>", "Override the LLM model id (else provider default)").option("--role <role>", "Tool set to expose: audit|review|discovery|attack|verify (default audit = every tool)").option("--mode <mode>", "Approval mode: standard|recon|copilot|yolo (default yolo)").option("--yolo", "Shortcut for --mode yolo (no per-action prompts; independent credential, private-network and sandbox protections remain).").option("--autonomy <mode>", "Alias of --mode (standard|copilot|yolo|recon); --mode/--yolo take precedence.").option("--max-tool-calls <n>", "Optional tool-call round limit per message (unlimited by default)").option("--allow-scanners", "Expose generic-scanner tool wrappers (sqlmap/nikto/\u2026); default off").option("--resume [id]", "With a headless prompt, reopen a saved session by id or unique prefix; use browser history for a picker.").option("--continue", "With a headless prompt, continue the most recent saved console session.").option("-p, --print [prompt]", "Non-interactive: run ONE prompt through the engine, print the result, and exit. Reads the prompt from the argument or piped stdin. Combine with --continue/--resume to query a saved session. Also reachable as `0 -p <prompt>`.").option("--prompt <text>", "Run one headless prompt (alias for --print)").action(async (opts) => {
|
|
9948
10318
|
if (opts.prompt !== void 0) opts.print = opts.prompt;
|
|
9949
10319
|
if (opts.print === void 0) {
|
|
9950
10320
|
console.log('Interactive conversations are in the browser. Run 0 web (no account required). For automation use 0 chat --prompt "your request" or 0 -p "your request".');
|
|
@@ -10022,7 +10392,7 @@ function registerConsoleCommand(program) {
|
|
|
10022
10392
|
let resumedModel;
|
|
10023
10393
|
let resumedTarget;
|
|
10024
10394
|
if (opts.continue || opts.resume !== void 0) {
|
|
10025
|
-
const { listSessions, loadSession } = await import("./session-store-
|
|
10395
|
+
const { listSessions, loadSession } = await import("./session-store-6QR3CVUA.js");
|
|
10026
10396
|
const idArg = typeof opts.resume === "string" ? opts.resume.trim() : "";
|
|
10027
10397
|
if (idArg || opts.continue) {
|
|
10028
10398
|
let stored = idArg ? loadSession(idArg) : null;
|
|
@@ -10136,7 +10506,7 @@ async function runTurn(session, text2, output2) {
|
|
|
10136
10506
|
engine error: ${outcome.error ?? "unknown"}
|
|
10137
10507
|
`), "console.turn.error");
|
|
10138
10508
|
if (/ChatGPT.*model.*not supported/i.test(outcome.error ?? "")) {
|
|
10139
|
-
output2.stderr(source_default.dim("Choose an available account/provider model with --model; the
|
|
10509
|
+
output2.stderr(source_default.dim("Choose an available account/provider model with --model; the browser model picker lists the current account catalog. Alternatively configure a provider that supports the requested model. No replacement model was selected.\n"), "console.turn.model_unavailable");
|
|
10140
10510
|
}
|
|
10141
10511
|
}
|
|
10142
10512
|
return outcome;
|
|
@@ -11013,7 +11383,7 @@ function loadScopeOrExit(path) {
|
|
|
11013
11383
|
}
|
|
11014
11384
|
|
|
11015
11385
|
// packages/cli/src/commands/xnu-fuzz.ts
|
|
11016
|
-
import { readFileSync as
|
|
11386
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync12 } from "node:fs";
|
|
11017
11387
|
function enumerateAction(opts) {
|
|
11018
11388
|
const bundle = opts.bundle ?? "com.apple.unknown";
|
|
11019
11389
|
const model = enumerateTargetModelFromKext(opts.kext, { kext: bundle, source: opts.kext });
|
|
@@ -11050,7 +11420,7 @@ function pickClient(model, name) {
|
|
|
11050
11420
|
return model.userClients[0];
|
|
11051
11421
|
}
|
|
11052
11422
|
function genAction(opts) {
|
|
11053
|
-
const model = JSON.parse(
|
|
11423
|
+
const model = JSON.parse(readFileSync17(opts.model, "utf8"));
|
|
11054
11424
|
const uc = pickClient(model, opts.class);
|
|
11055
11425
|
if (!uc) {
|
|
11056
11426
|
process.stderr.write("no user client in model\n");
|
|
@@ -11136,10 +11506,10 @@ function registerXnuFuzzCommand(program) {
|
|
|
11136
11506
|
}
|
|
11137
11507
|
|
|
11138
11508
|
// packages/cli/src/commands/research.ts
|
|
11139
|
-
import { readFileSync as
|
|
11140
|
-
import { resolve as
|
|
11509
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
11510
|
+
import { resolve as resolve21 } from "node:path";
|
|
11141
11511
|
async function managedResearch(adapter, target, options, engine) {
|
|
11142
|
-
const { executeManagedOperation: executeManagedOperation2 } = await import("./managed-operation-
|
|
11512
|
+
const { executeManagedOperation: executeManagedOperation2 } = await import("./managed-operation-ZMLLRCCQ.js");
|
|
11143
11513
|
const started = Date.now();
|
|
11144
11514
|
return executeManagedOperation2({
|
|
11145
11515
|
type: "research",
|
|
@@ -11191,7 +11561,7 @@ function print(value) {
|
|
|
11191
11561
|
function registerResearchCommand(program) {
|
|
11192
11562
|
const research = program.command("research").description("Run target-specific research engines");
|
|
11193
11563
|
research.command("pipeline").description("Run the existing web/AI/source/package pipeline through the shared evidence plane").requiredOption("--target <target>", "URL, local path, repository, package, or image").option("--target-type <type>", "url, web-app, source-code, npm-package, pypi-package, cargo-package, or oci-image").option("--profile <profile>", "Source review profile").option("--depth <depth>", "quick, default, or deep", "default").option("--runtime <runtime>", "auto, api, claude, codex, gemini, or ollama", "auto").option("--artifact-root <path>", "Research artifact root", ".0-research").action(async (opts) => {
|
|
11194
|
-
const { UnifiedPipelineResearchAdapter, runResearch } = await import("./dist-
|
|
11564
|
+
const { UnifiedPipelineResearchAdapter, runResearch } = await import("./dist-ONIRKDH6.js");
|
|
11195
11565
|
const allowedTypes = /* @__PURE__ */ new Set(["url", "web-app", "source-code", "npm-package", "pypi-package", "cargo-package", "oci-image"]);
|
|
11196
11566
|
if (opts.targetType && !allowedTypes.has(opts.targetType)) throw new Error(`unsupported --target-type ${opts.targetType}`);
|
|
11197
11567
|
print(await managedResearch(
|
|
@@ -11210,12 +11580,12 @@ function registerResearchCommand(program) {
|
|
|
11210
11580
|
}
|
|
11211
11581
|
}
|
|
11212
11582
|
},
|
|
11213
|
-
{ artifactRoot:
|
|
11583
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11214
11584
|
runResearch
|
|
11215
11585
|
));
|
|
11216
11586
|
});
|
|
11217
11587
|
research.command("counterexample").description("Search a C/C++ source target for sanitizer-confirmed counterexample inputs; optional mitigation replay").requiredOption("--source <dir>", "C/C++ source tree root").requiredOption("--fn <name>", "Suspect function name").requiredOption("--header <path>", "Header declaring the suspect function").requiredOption("--declaration <decl>", "C declaration of the suspect function").option("--input-shape <shape>", "bytesAndLen, bytesPtr, or bytesAndLenOut", "bytesAndLen").option("--build-system <system>", "auto, autotools, cmake, or meson", "auto").option("--timeout <sec>", "Fuzz wall-clock budget in seconds").option("--mitigation-source <files...>", "Reference-mitigation source file(s) for replay").option("--mitigation-include <dirs...>", "Extra include directories for the mitigation build").option("--witness <files...>", "Finding-proposed witness input file(s) to replay through the sanitizer build").option("--artifact-root <path>", "Research artifact root", ".0-research").action(async (opts) => {
|
|
11218
|
-
const { UserspaceCounterexampleResearchAdapter, runResearch } = await import("./dist-
|
|
11588
|
+
const { UserspaceCounterexampleResearchAdapter, runResearch } = await import("./dist-ONIRKDH6.js");
|
|
11219
11589
|
const SHAPES = { bytesAndLen: true, bytesPtr: true, bytesAndLenOut: true };
|
|
11220
11590
|
if (!SHAPES[opts.inputShape]) throw new Error(`unsupported --input-shape ${opts.inputShape}`);
|
|
11221
11591
|
const SYSTEMS = { auto: true, autotools: true, cmake: true, meson: true };
|
|
@@ -11225,9 +11595,9 @@ function registerResearchCommand(program) {
|
|
|
11225
11595
|
{
|
|
11226
11596
|
kind: "userspace.counterexample",
|
|
11227
11597
|
id: `counterexample:${opts.source}:${opts.fn}`,
|
|
11228
|
-
location:
|
|
11598
|
+
location: resolve21(opts.source),
|
|
11229
11599
|
config: {
|
|
11230
|
-
sourceRoot:
|
|
11600
|
+
sourceRoot: resolve21(opts.source),
|
|
11231
11601
|
buildSystem: opts.buildSystem,
|
|
11232
11602
|
suspectFunction: {
|
|
11233
11603
|
header: opts.header,
|
|
@@ -11235,43 +11605,43 @@ function registerResearchCommand(program) {
|
|
|
11235
11605
|
declaration: opts.declaration,
|
|
11236
11606
|
inputShape: opts.inputShape
|
|
11237
11607
|
},
|
|
11238
|
-
...opts.witness?.length ? { witnessInputs: opts.witness.map((path) =>
|
|
11608
|
+
...opts.witness?.length ? { witnessInputs: opts.witness.map((path) => resolve21(path)) } : {},
|
|
11239
11609
|
...opts.timeout ? { timeoutSec: Number.parseInt(opts.timeout, 10) } : {},
|
|
11240
11610
|
...opts.mitigationSource?.length ? { mitigation: { sourceFiles: opts.mitigationSource, ...opts.mitigationInclude?.length ? { includeDirs: opts.mitigationInclude } : {} } } : {}
|
|
11241
11611
|
}
|
|
11242
11612
|
},
|
|
11243
|
-
{ artifactRoot:
|
|
11613
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11244
11614
|
runResearch
|
|
11245
11615
|
));
|
|
11246
11616
|
});
|
|
11247
11617
|
research.command("mobile").description("Run passive mobile intake; indicators remain hypotheses and only scoped adapters may hand off targets").requiredOption("--target <path>", "Extracted APK/IPA directory or metadata file").option("--artifact-root <path>", "Research artifact root", ".0-research").action(async (opts) => {
|
|
11248
|
-
const { MobileStaticResearchAdapter, runResearch } = await import("./dist-
|
|
11249
|
-
const targetPath =
|
|
11618
|
+
const { MobileStaticResearchAdapter, runResearch } = await import("./dist-ONIRKDH6.js");
|
|
11619
|
+
const targetPath = resolve21(opts.target);
|
|
11250
11620
|
print(await managedResearch(
|
|
11251
11621
|
new MobileStaticResearchAdapter(),
|
|
11252
11622
|
{ kind: "mobile.static-intake", id: `mobile:${targetPath}`, location: targetPath, config: {} },
|
|
11253
|
-
{ artifactRoot:
|
|
11623
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11254
11624
|
runResearch
|
|
11255
11625
|
));
|
|
11256
11626
|
});
|
|
11257
11627
|
research.command("linux-matrix").description("Import externally executed vulnerable-vs-patched boot logs; 0 validates and hashes them but does not execute boots").requiredOption("--matrix <path>", "Versioned external boot-matrix manifest JSON").requiredOption("--finding <path>", "Existing Finding JSON to bind the proof to").option("--artifact-root <path>", "Research artifact root", ".0-research").action(async (opts) => {
|
|
11258
|
-
const { LinuxBootMatrixImportAdapter, runResearch } = await import("./dist-
|
|
11259
|
-
const matrix =
|
|
11260
|
-
const finding = JSON.parse(
|
|
11628
|
+
const { LinuxBootMatrixImportAdapter, runResearch } = await import("./dist-ONIRKDH6.js");
|
|
11629
|
+
const matrix = resolve21(opts.matrix);
|
|
11630
|
+
const finding = JSON.parse(readFileSync18(resolve21(opts.finding), "utf8"));
|
|
11261
11631
|
const result = await managedResearch(
|
|
11262
11632
|
new LinuxBootMatrixImportAdapter(),
|
|
11263
11633
|
{ kind: "linux.kernel-boot-matrix-import", id: `linux-matrix:${finding.id}`, location: matrix, config: { finding } },
|
|
11264
|
-
{ artifactRoot:
|
|
11634
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11265
11635
|
runResearch
|
|
11266
11636
|
);
|
|
11267
11637
|
if (result.candidates.length === 0) throw new Error("external boot-matrix manifest failed validation");
|
|
11268
11638
|
print(result);
|
|
11269
11639
|
});
|
|
11270
11640
|
research.command("linux").description("Run a supplied Linux kernel reproducer through the shared N-boot evidence gate").requiredOption("--kernel-tree <path>", "Linux source tree").requiredOption("--reproducer <path>", "C reproducer or syzkaller .syz program").requiredOption("--finding <path>", "Existing Finding JSON to bind the proof to").requiredOption("--expected-signature <literal>", "Literal crash signature that every counted boot must contain").option("--boots <n>", "Fresh boots", "3").option("--min-hits <n>", "Required reproducing boots", "2").option("--artifact-root <path>", "Research artifact root", ".0-research").action(async (opts) => {
|
|
11271
|
-
const { LinuxKernelResearchAdapter, runResearch } = await import("./dist-
|
|
11272
|
-
const kernelTree =
|
|
11273
|
-
const reproducer =
|
|
11274
|
-
const finding = JSON.parse(
|
|
11641
|
+
const { LinuxKernelResearchAdapter, runResearch } = await import("./dist-ONIRKDH6.js");
|
|
11642
|
+
const kernelTree = resolve21(opts.kernelTree);
|
|
11643
|
+
const reproducer = resolve21(opts.reproducer);
|
|
11644
|
+
const finding = JSON.parse(readFileSync18(resolve21(opts.finding), "utf8"));
|
|
11275
11645
|
const boots = Number.parseInt(opts.boots, 10);
|
|
11276
11646
|
const minHits = Number.parseInt(opts.minHits, 10);
|
|
11277
11647
|
if (!Number.isFinite(boots) || boots < 1 || !Number.isFinite(minHits) || minHits < 1 || minHits > boots) {
|
|
@@ -11287,7 +11657,7 @@ function registerResearchCommand(program) {
|
|
|
11287
11657
|
location: kernelTree,
|
|
11288
11658
|
config: { finding, verify }
|
|
11289
11659
|
},
|
|
11290
|
-
{ artifactRoot:
|
|
11660
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11291
11661
|
runResearch
|
|
11292
11662
|
);
|
|
11293
11663
|
if (result.findings.length === 0) {
|
|
@@ -11314,6 +11684,9 @@ function registerWorkerCommand(program) {
|
|
|
11314
11684
|
});
|
|
11315
11685
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
11316
11686
|
});
|
|
11687
|
+
worker.command("repair <backend-id>").description("Reconnect a managed worker tunnel and start its retained engine when needed").action(async (backendId) => {
|
|
11688
|
+
process.stdout.write(JSON.stringify(await repairWorker(backendId)) + "\n");
|
|
11689
|
+
});
|
|
11317
11690
|
worker.command("stop <backend-id>").description("Stop a managed worker engine and its owned tunnel; retain remote files and registration").action(async (backendId) => {
|
|
11318
11691
|
process.stdout.write(JSON.stringify(await stopWorker(backendId)) + "\n");
|
|
11319
11692
|
});
|
|
@@ -11332,7 +11705,7 @@ function registerWorkerCommand(program) {
|
|
|
11332
11705
|
// packages/cli/src/commands/radar.ts
|
|
11333
11706
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
11334
11707
|
import { writeFileSync as writeFileSync13 } from "node:fs";
|
|
11335
|
-
import { resolve as
|
|
11708
|
+
import { resolve as resolve22 } from "node:path";
|
|
11336
11709
|
function parsePositive5(flag, raw, dflt) {
|
|
11337
11710
|
if (raw === void 0) return dflt;
|
|
11338
11711
|
const n = parseInt(raw, 10);
|
|
@@ -11341,7 +11714,7 @@ function parsePositive5(flag, raw, dflt) {
|
|
|
11341
11714
|
}
|
|
11342
11715
|
async function radarAction(opts) {
|
|
11343
11716
|
if (!opts.repo) throw new Error("missing required flag: --repo <path>");
|
|
11344
|
-
const repo =
|
|
11717
|
+
const repo = resolve22(opts.repo);
|
|
11345
11718
|
try {
|
|
11346
11719
|
execFileSync2("git", ["-C", repo, "rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
|
|
11347
11720
|
} catch {
|
|
@@ -11366,14 +11739,14 @@ async function radarAction(opts) {
|
|
|
11366
11739
|
});
|
|
11367
11740
|
const rankedJson = JSON.stringify(result, null, 2);
|
|
11368
11741
|
if (opts.out) {
|
|
11369
|
-
writeFileSync13(
|
|
11742
|
+
writeFileSync13(resolve22(opts.out), rankedJson + "\n", "utf8");
|
|
11370
11743
|
} else {
|
|
11371
11744
|
process.stdout.write(rankedJson + "\n");
|
|
11372
11745
|
}
|
|
11373
11746
|
if (opts.seedsOut) {
|
|
11374
|
-
const repo2 =
|
|
11747
|
+
const repo2 = resolve22(opts.repo);
|
|
11375
11748
|
const seeds = radarCandidatesToSeedFindings(result, repo2);
|
|
11376
|
-
writeFileSync13(
|
|
11749
|
+
writeFileSync13(resolve22(opts.seedsOut), JSON.stringify(seeds, null, 2) + "\n", "utf8");
|
|
11377
11750
|
}
|
|
11378
11751
|
process.exitCode = 0;
|
|
11379
11752
|
}
|
|
@@ -11430,7 +11803,7 @@ function registerTimelineCommand(program) {
|
|
|
11430
11803
|
process.exitCode = 2;
|
|
11431
11804
|
return;
|
|
11432
11805
|
}
|
|
11433
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
11806
|
+
const { osecDB: osecDB2 } = await import("./dist-QLMPTFT7.js");
|
|
11434
11807
|
const db = new osecDB2(opts.dbPath);
|
|
11435
11808
|
let scan2;
|
|
11436
11809
|
let rows;
|
|
@@ -11717,12 +12090,12 @@ function strArray(value) {
|
|
|
11717
12090
|
}
|
|
11718
12091
|
|
|
11719
12092
|
// packages/cli/src/commands/agent-assure.ts
|
|
11720
|
-
import { createHash as
|
|
11721
|
-
import { readFileSync as
|
|
12093
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
12094
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
11722
12095
|
function readScenario(path) {
|
|
11723
12096
|
let raw;
|
|
11724
12097
|
try {
|
|
11725
|
-
raw = JSON.parse(
|
|
12098
|
+
raw = JSON.parse(readFileSync19(path, "utf8"));
|
|
11726
12099
|
} catch (error) {
|
|
11727
12100
|
const message = error instanceof Error ? error.message : String(error);
|
|
11728
12101
|
throw new Error(`agent-assure: failed to read scenario ${path}: ${message}`);
|
|
@@ -11733,7 +12106,7 @@ function readHeaders(path, field) {
|
|
|
11733
12106
|
if (!path) return {};
|
|
11734
12107
|
let raw;
|
|
11735
12108
|
try {
|
|
11736
|
-
raw = JSON.parse(
|
|
12109
|
+
raw = JSON.parse(readFileSync19(path, "utf8"));
|
|
11737
12110
|
} catch (error) {
|
|
11738
12111
|
const message = error instanceof Error ? error.message : String(error);
|
|
11739
12112
|
throw new Error(`agent-assure: failed to read ${field} file ${path}: ${message}`);
|
|
@@ -11782,7 +12155,7 @@ function assertInScope(scope, endpoint, label) {
|
|
|
11782
12155
|
}
|
|
11783
12156
|
}
|
|
11784
12157
|
function readBaseline(path) {
|
|
11785
|
-
const raw =
|
|
12158
|
+
const raw = readFileSync19(path, "utf8");
|
|
11786
12159
|
return {
|
|
11787
12160
|
manifest: parseAgentActionEvidenceManifest(JSON.parse(raw)),
|
|
11788
12161
|
sha256: agentActionManifestSha256(raw)
|
|
@@ -11800,11 +12173,11 @@ function registerAgentAssureCommand(program) {
|
|
|
11800
12173
|
assertInScope(scope, opts.mcpEndpoint, "MCP endpoint");
|
|
11801
12174
|
assertInScope(scope, opts.oracleEndpoint, "oracle endpoint");
|
|
11802
12175
|
const baseline = opts.baseline ? readBaseline(opts.baseline) : void 0;
|
|
11803
|
-
const scenarioPayloadSha256 =
|
|
12176
|
+
const scenarioPayloadSha256 = createHash6("sha256").update(scenario.payload).digest("hex");
|
|
11804
12177
|
if (baseline && (baseline.manifest.scenario.id !== scenario.id || baseline.manifest.scenario.payload_sha256 !== scenarioPayloadSha256)) {
|
|
11805
12178
|
throw new Error("agent-assure: --baseline must describe the same scenario id and payload");
|
|
11806
12179
|
}
|
|
11807
|
-
const scopeRaw = opts.scope ?
|
|
12180
|
+
const scopeRaw = opts.scope ? readFileSync19(opts.scope, "utf8") : "";
|
|
11808
12181
|
const timeoutMs = parsePositiveMilliseconds(opts.timeout, "--timeout");
|
|
11809
12182
|
const oracleTimeoutMs = parsePositiveMilliseconds(opts.oracleTimeout, "--oracle-timeout");
|
|
11810
12183
|
const run2 = await runAgentActionAssurance({
|
|
@@ -11824,7 +12197,7 @@ function registerAgentAssureCommand(program) {
|
|
|
11824
12197
|
}),
|
|
11825
12198
|
scenario,
|
|
11826
12199
|
targetConfig: {
|
|
11827
|
-
scopeSha256:
|
|
12200
|
+
scopeSha256: createHash6("sha256").update(scopeRaw).digest("hex"),
|
|
11828
12201
|
environment: opts.environment,
|
|
11829
12202
|
agentEndpoint: opts.agentEndpoint,
|
|
11830
12203
|
mcpEndpoint: opts.mcpEndpoint,
|
|
@@ -11868,7 +12241,7 @@ function registerAgentAssureCommand(program) {
|
|
|
11868
12241
|
// packages/cli/src/commands/binary.ts
|
|
11869
12242
|
import { spawn, spawnSync as spawnSync2 } from "node:child_process";
|
|
11870
12243
|
import { existsSync as existsSync13 } from "node:fs";
|
|
11871
|
-
import { dirname as dirname6, join as join14, resolve as
|
|
12244
|
+
import { dirname as dirname6, join as join14, resolve as resolve23 } from "node:path";
|
|
11872
12245
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
11873
12246
|
var BINARY_MODES = ["triage", "run", "scan"];
|
|
11874
12247
|
function locateOverseDir(startDir) {
|
|
@@ -11950,7 +12323,9 @@ function resolveBinaryRun(target, opts, passthrough, deps = { isUvAvailable, loc
|
|
|
11950
12323
|
ok: true,
|
|
11951
12324
|
exitCode: 0,
|
|
11952
12325
|
overseDir,
|
|
11953
|
-
|
|
12326
|
+
// The subprocess runs from the engine checkout, so anchor the input before
|
|
12327
|
+
// changing cwd. Relative targets belong to the caller's workspace.
|
|
12328
|
+
argv: buildOverseArgv(mode, resolve23(target), opts, passthrough)
|
|
11954
12329
|
};
|
|
11955
12330
|
}
|
|
11956
12331
|
function registerBinaryCommand(program) {
|
|
@@ -11966,9 +12341,11 @@ function registerBinaryCommand(program) {
|
|
|
11966
12341
|
return;
|
|
11967
12342
|
}
|
|
11968
12343
|
const overseDir = resolution.overseDir;
|
|
11969
|
-
const
|
|
11970
|
-
const
|
|
11971
|
-
|
|
12344
|
+
const local = localZeroverseRuntime(process.cwd());
|
|
12345
|
+
const argv = local ? ["-m", "zeroverse.cli", ...resolution.argv ?? []] : ["run", "--frozen", "0verse", ...resolution.argv ?? []];
|
|
12346
|
+
const child = spawn(local?.pythonPath ?? "uv", argv, {
|
|
12347
|
+
cwd: local?.cwd ?? resolve23(overseDir),
|
|
12348
|
+
...local ? { env: { ...process.env, ...local.env } } : {},
|
|
11972
12349
|
stdio: "inherit",
|
|
11973
12350
|
shell: false
|
|
11974
12351
|
});
|
|
@@ -11993,9 +12370,9 @@ import { constants as constants3, closeSync as closeSync3, fchmodSync, lstatSync
|
|
|
11993
12370
|
import { join as join16 } from "node:path";
|
|
11994
12371
|
|
|
11995
12372
|
// packages/cli/src/commands/hackstore.ts
|
|
11996
|
-
import { createHash as
|
|
11997
|
-
import { constants as constants2, closeSync as closeSync2, existsSync as existsSync14, fstatSync as fstatSync2, lstatSync as lstatSync2, mkdirSync as mkdirSync9, openSync as openSync2, readdirSync as readdirSync2, readFileSync as
|
|
11998
|
-
import { dirname as dirname7, join as join15, resolve as
|
|
12373
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
12374
|
+
import { constants as constants2, closeSync as closeSync2, existsSync as existsSync14, fstatSync as fstatSync2, lstatSync as lstatSync2, mkdirSync as mkdirSync9, openSync as openSync2, readdirSync as readdirSync2, readFileSync as readFileSync20, rmSync as rmSync4, writeFileSync as writeFileSync14 } from "node:fs";
|
|
12375
|
+
import { dirname as dirname7, join as join15, resolve as resolve24 } from "node:path";
|
|
11999
12376
|
var HACKSTORE_REGISTRY_REPO = "github.com/0sec-labs/hackstore";
|
|
12000
12377
|
var HACKSTORE_SCHEMA_ID = "https://raw.githubusercontent.com/0sec-labs/hackstore/main/hackstore-manifest.schema.json";
|
|
12001
12378
|
var MANIFEST_FILE = "manifest.json";
|
|
@@ -12006,7 +12383,7 @@ var MAX_SOURCE_BYTES = 4 * 1024 * 1024;
|
|
|
12006
12383
|
var cachedCore;
|
|
12007
12384
|
async function defaultCorePort() {
|
|
12008
12385
|
if (cachedCore) return cachedCore;
|
|
12009
|
-
const mod = await import("./dist-
|
|
12386
|
+
const mod = await import("./dist-ONIRKDH6.js");
|
|
12010
12387
|
cachedCore = {
|
|
12011
12388
|
validatePluginManifest: mod.validatePluginManifest,
|
|
12012
12389
|
reservedToolNames: Object.values(mod.TOOL_DEFINITIONS).map((tool) => tool.name),
|
|
@@ -12015,7 +12392,7 @@ async function defaultCorePort() {
|
|
|
12015
12392
|
return cachedCore;
|
|
12016
12393
|
}
|
|
12017
12394
|
function resolveManifestPath2(pathArg) {
|
|
12018
|
-
const target =
|
|
12395
|
+
const target = resolve24(pathArg);
|
|
12019
12396
|
try {
|
|
12020
12397
|
const stat3 = lstatSync2(target);
|
|
12021
12398
|
if (stat3.isSymbolicLink()) return { ok: false, error: `refusing symbolic link: ${target}` };
|
|
@@ -12030,7 +12407,7 @@ function readAuthorFile(file, maxBytes) {
|
|
|
12030
12407
|
const stat3 = fstatSync2(fd);
|
|
12031
12408
|
if (!stat3.isFile()) throw new Error(`${file} is not a regular file`);
|
|
12032
12409
|
if (stat3.size > maxBytes) throw new Error(`${file} exceeds ${maxBytes} bytes`);
|
|
12033
|
-
return
|
|
12410
|
+
return readFileSync20(fd, "utf8");
|
|
12034
12411
|
} finally {
|
|
12035
12412
|
closeSync2(fd);
|
|
12036
12413
|
}
|
|
@@ -12220,7 +12597,7 @@ input.on("line", (line) => {
|
|
|
12220
12597
|
`;
|
|
12221
12598
|
}
|
|
12222
12599
|
function runInit(name, deps) {
|
|
12223
|
-
const base = deps.dir ?
|
|
12600
|
+
const base = deps.dir ? resolve24(deps.dir) : process.cwd();
|
|
12224
12601
|
if (!name.trim() || name.length > 2e3 || name === "." || name === ".." || /[/\\\0]/.test(name)) {
|
|
12225
12602
|
console.error(source_default.red("Extension name must be a single non-empty directory name (at most 2000 characters)."));
|
|
12226
12603
|
process.exitCode = EXIT_USER_ERROR3;
|
|
@@ -12288,7 +12665,7 @@ function runPrepareSubmission(pathArg, deps) {
|
|
|
12288
12665
|
process.exitCode = EXIT_USER_ERROR3;
|
|
12289
12666
|
return;
|
|
12290
12667
|
}
|
|
12291
|
-
const output2 =
|
|
12668
|
+
const output2 = resolve24(deps.out ?? `${extension.manifest.id}-submission`);
|
|
12292
12669
|
let created = false;
|
|
12293
12670
|
try {
|
|
12294
12671
|
const readme = readAuthorFile(join15(extension.dir, "README.md"), MAX_MANIFEST_BYTES);
|
|
@@ -12312,7 +12689,7 @@ function runPrepareSubmission(pathArg, deps) {
|
|
|
12312
12689
|
}
|
|
12313
12690
|
console.log(source_default.green(`Prepared ${extension.manifest.id}@${extension.manifest.version}: ${target}`));
|
|
12314
12691
|
for (const [name, content] of Object.entries(files)) {
|
|
12315
|
-
console.log(` SHA-256 ${name}: ${
|
|
12692
|
+
console.log(` SHA-256 ${name}: ${createHash7("sha256").update(content).digest("hex")}`);
|
|
12316
12693
|
}
|
|
12317
12694
|
console.log("Not published. No code was executed and nothing was uploaded.");
|
|
12318
12695
|
console.log(`Fork and clone https://${HACKSTORE_REGISTRY_REPO}, then copy this extensions directory into your fork.`);
|
|
@@ -12345,13 +12722,13 @@ function registerHackstoreCommand(program) {
|
|
|
12345
12722
|
var cachedCore2;
|
|
12346
12723
|
async function defaultCorePort2() {
|
|
12347
12724
|
if (cachedCore2) return cachedCore2;
|
|
12348
|
-
const mod = await import("./dist-
|
|
12725
|
+
const mod = await import("./dist-ONIRKDH6.js");
|
|
12349
12726
|
cachedCore2 = mod;
|
|
12350
12727
|
return mod;
|
|
12351
12728
|
}
|
|
12352
12729
|
var EXIT_OK4 = 0;
|
|
12353
12730
|
var EXIT_USER_ERROR4 = 1;
|
|
12354
|
-
function
|
|
12731
|
+
function resolve25(deps) {
|
|
12355
12732
|
return {
|
|
12356
12733
|
core: deps.core,
|
|
12357
12734
|
fetchImpl: deps.fetchImpl ?? fetch,
|
|
@@ -12384,7 +12761,7 @@ function installedViews(d) {
|
|
|
12384
12761
|
return out;
|
|
12385
12762
|
}
|
|
12386
12763
|
function runList(deps) {
|
|
12387
|
-
const d =
|
|
12764
|
+
const d = resolve25(deps);
|
|
12388
12765
|
const installed = installedViews(d);
|
|
12389
12766
|
const record2 = d.core.readEnablement(d.projectPath, d.homeDir);
|
|
12390
12767
|
const reconciled = d.core.reconcile(record2, installed);
|
|
@@ -12415,7 +12792,7 @@ function runList(deps) {
|
|
|
12415
12792
|
process.exitCode = EXIT_OK4;
|
|
12416
12793
|
}
|
|
12417
12794
|
async function runSearch(query, deps) {
|
|
12418
|
-
const d =
|
|
12795
|
+
const d = resolve25(deps);
|
|
12419
12796
|
if (d.registryUrl.trim().length === 0) {
|
|
12420
12797
|
d.out("The Hackstore is disabled (registry URL is empty), so there is nothing to search.");
|
|
12421
12798
|
d.out(" The default community Hackstore lives at github.com/0sec-labs/hackstore.");
|
|
@@ -12452,7 +12829,7 @@ async function runSearch(query, deps) {
|
|
|
12452
12829
|
process.exitCode = EXIT_OK4;
|
|
12453
12830
|
}
|
|
12454
12831
|
async function runInstall(id, deps) {
|
|
12455
|
-
const d =
|
|
12832
|
+
const d = resolve25(deps);
|
|
12456
12833
|
if (deps.local === true) {
|
|
12457
12834
|
const local = readLocalExtension(id, {
|
|
12458
12835
|
validatePluginManifest: d.core.validatePluginManifest,
|
|
@@ -12588,7 +12965,7 @@ function writePluginFiles(d, root, entry) {
|
|
|
12588
12965
|
}
|
|
12589
12966
|
}
|
|
12590
12967
|
function runEnable(id, deps) {
|
|
12591
|
-
const d =
|
|
12968
|
+
const d = resolve25(deps);
|
|
12592
12969
|
if (!d.core.isSafePluginId(id)) {
|
|
12593
12970
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12594
12971
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12641,7 +13018,7 @@ function runEnable(id, deps) {
|
|
|
12641
13018
|
process.exitCode = EXIT_OK4;
|
|
12642
13019
|
}
|
|
12643
13020
|
function runDisable(id, deps) {
|
|
12644
|
-
const d =
|
|
13021
|
+
const d = resolve25(deps);
|
|
12645
13022
|
if (!d.core.isSafePluginId(id)) {
|
|
12646
13023
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12647
13024
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12666,7 +13043,7 @@ function runDisable(id, deps) {
|
|
|
12666
13043
|
process.exitCode = EXIT_OK4;
|
|
12667
13044
|
}
|
|
12668
13045
|
function runInfo(id, deps) {
|
|
12669
|
-
const d =
|
|
13046
|
+
const d = resolve25(deps);
|
|
12670
13047
|
if (!d.core.isSafePluginId(id)) {
|
|
12671
13048
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12672
13049
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12738,7 +13115,7 @@ function parseRunArgs(pairs, jsonArgs) {
|
|
|
12738
13115
|
return { ok: true, args: args2 };
|
|
12739
13116
|
}
|
|
12740
13117
|
async function runRun(id, tool, pairs, deps) {
|
|
12741
|
-
const d =
|
|
13118
|
+
const d = resolve25(deps);
|
|
12742
13119
|
if (!d.core.isSafePluginId(id)) {
|
|
12743
13120
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12744
13121
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12890,220 +13267,18 @@ function registerPluginCommand(program) {
|
|
|
12890
13267
|
}
|
|
12891
13268
|
|
|
12892
13269
|
// packages/cli/src/commands/theme.ts
|
|
12893
|
-
import { writeFileSync as writeFileSync16 } from "node:fs";
|
|
12894
|
-
var EXIT_OK5 = 0;
|
|
12895
13270
|
var EXIT_USER_ERROR5 = 1;
|
|
12896
|
-
var cachedCore3;
|
|
12897
|
-
async function defaultThemeCorePort() {
|
|
12898
|
-
if (cachedCore3) return cachedCore3;
|
|
12899
|
-
const mod = await import("./dist-TQMHMSBZ.js");
|
|
12900
|
-
cachedCore3 = mod;
|
|
12901
|
-
return mod;
|
|
12902
|
-
}
|
|
12903
|
-
function outOf(deps) {
|
|
12904
|
-
return deps.out ?? ((l) => console.log(l));
|
|
12905
|
-
}
|
|
12906
|
-
function errOf(deps) {
|
|
12907
|
-
return deps.err ?? ((l) => console.error(l));
|
|
12908
|
-
}
|
|
12909
|
-
function registryUrlOf(deps, core) {
|
|
12910
|
-
return (deps.registryUrl ?? process.env["ZERO_REGISTRY_URL"] ?? core.DEFAULT_REGISTRY_URL ?? "").trim();
|
|
12911
|
-
}
|
|
12912
|
-
function runThemeList(deps = {}) {
|
|
12913
|
-
const out = outOf(deps);
|
|
12914
|
-
reloadInstalledThemes(deps.homeDir);
|
|
12915
|
-
const active = loadSettings(deps.homeDir, deps.projectDir).theme;
|
|
12916
|
-
const mark = (name) => {
|
|
12917
|
-
const tags = [];
|
|
12918
|
-
if (name === active) tags.push(source_default.cyan("active"));
|
|
12919
|
-
if (name === DEFAULT_THEME_NAME) tags.push(source_default.green("default"));
|
|
12920
|
-
return tags.length > 0 ? ` (${tags.join(", ")})` : "";
|
|
12921
|
-
};
|
|
12922
|
-
const line = (entry) => {
|
|
12923
|
-
out(` ${entry.name}${mark(entry.name)}`);
|
|
12924
|
-
out(source_default.dim(` ${entry.label} \u2014 ${entry.description}`));
|
|
12925
|
-
};
|
|
12926
|
-
out(source_default.bold("Built-in console themes"));
|
|
12927
|
-
for (const name of THEME_NAMES) line(THEMES[name]);
|
|
12928
|
-
const installed = installedThemeEntries(deps.homeDir);
|
|
12929
|
-
out("");
|
|
12930
|
-
if (installed.length === 0) {
|
|
12931
|
-
out(source_default.dim(`Installed themes: none (${installedThemesDir(deps.homeDir)})`));
|
|
12932
|
-
} else {
|
|
12933
|
-
out(source_default.bold(`Installed themes (${installedThemesDir(deps.homeDir)})`));
|
|
12934
|
-
for (const entry of installed) line(entry);
|
|
12935
|
-
}
|
|
12936
|
-
out("");
|
|
12937
|
-
out(source_default.dim("Apply one with `0 theme apply <id>`; install more with `0 theme install <id>`."));
|
|
12938
|
-
process.exitCode = EXIT_OK5;
|
|
12939
|
-
}
|
|
12940
|
-
async function runThemeInstall(id, deps = {}) {
|
|
12941
|
-
const out = outOf(deps);
|
|
12942
|
-
const err = errOf(deps);
|
|
12943
|
-
const core = deps.core ?? await defaultThemeCorePort();
|
|
12944
|
-
if (!isSafeThemeId(id)) {
|
|
12945
|
-
err(source_default.red(`"${id}" is not a valid theme id; refused before any filesystem access.`));
|
|
12946
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
12947
|
-
return;
|
|
12948
|
-
}
|
|
12949
|
-
const registryUrl = registryUrlOf(deps, core);
|
|
12950
|
-
if (registryUrl.length === 0) {
|
|
12951
|
-
err(source_default.red("The Hackstore is disabled (registry URL is empty), so nothing can be installed."));
|
|
12952
|
-
err(" Unset ZERO_REGISTRY_URL for the default community Hackstore, or point --registry at a theme index URL you trust.");
|
|
12953
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
12954
|
-
return;
|
|
12955
|
-
}
|
|
12956
|
-
const fetched = await core.fetchRegistryIndex(registryUrl, {
|
|
12957
|
-
fetchImpl: deps.fetchImpl ?? fetch,
|
|
12958
|
-
verifier: deps.verifier ?? core.unconfiguredVerifier
|
|
12959
|
-
});
|
|
12960
|
-
if (!fetched.ok) {
|
|
12961
|
-
err(source_default.red(`Registry error: ${fetched.error}`));
|
|
12962
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
12963
|
-
return;
|
|
12964
|
-
}
|
|
12965
|
-
const artifact = fetched.result.artifacts.find(
|
|
12966
|
-
(a) => a.kind === "theme" && a.id === id
|
|
12967
|
-
);
|
|
12968
|
-
if (!artifact) {
|
|
12969
|
-
err(source_default.red(`Theme "${id}" is not available in the configured registry.`));
|
|
12970
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
12971
|
-
return;
|
|
12972
|
-
}
|
|
12973
|
-
const palette = artifact.manifest.theme.palette;
|
|
12974
|
-
const issues = validateTheme(palette);
|
|
12975
|
-
if (issues.length > 0) {
|
|
12976
|
-
err(source_default.red(`Theme "${id}" has an invalid palette; refusing to install:`));
|
|
12977
|
-
for (const issue of issues) err(source_default.dim(` - ${issue.message}`));
|
|
12978
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
12979
|
-
return;
|
|
12980
|
-
}
|
|
12981
|
-
const written = writeInstalledTheme(
|
|
12982
|
-
{
|
|
12983
|
-
id,
|
|
12984
|
-
label: artifact.manifest.theme.label,
|
|
12985
|
-
description: artifact.manifest.theme.description,
|
|
12986
|
-
mode: artifact.manifest.theme.mode,
|
|
12987
|
-
palette
|
|
12988
|
-
},
|
|
12989
|
-
deps.homeDir
|
|
12990
|
-
);
|
|
12991
|
-
if (!written.ok) {
|
|
12992
|
-
err(source_default.red(`Could not install "${id}": ${written.error}`));
|
|
12993
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
12994
|
-
return;
|
|
12995
|
-
}
|
|
12996
|
-
reloadInstalledThemes(deps.homeDir);
|
|
12997
|
-
out(source_default.green(`Installed theme ${id}@${artifact.version}.`));
|
|
12998
|
-
out(` Written to: ${written.path}`);
|
|
12999
|
-
out(` Signature: ${artifact.signatureState}`);
|
|
13000
|
-
out(source_default.dim(" No code ran \u2014 a theme is data (a palette), never an executable plugin."));
|
|
13001
|
-
out(` Apply it with:`);
|
|
13002
|
-
out(source_default.cyan(` 0 theme apply ${id}`));
|
|
13003
|
-
process.exitCode = EXIT_OK5;
|
|
13004
|
-
}
|
|
13005
|
-
function runThemeApply(id, deps = {}) {
|
|
13006
|
-
const out = outOf(deps);
|
|
13007
|
-
const err = errOf(deps);
|
|
13008
|
-
configureSettingsStore({ homeDir: deps.homeDir, projectDir: deps.projectDir });
|
|
13009
|
-
reloadInstalledThemes(deps.homeDir);
|
|
13010
|
-
if (!isKnownTheme(id)) {
|
|
13011
|
-
err(source_default.red(`"${id}" is not a known theme (neither a built-in nor an installed id).`));
|
|
13012
|
-
err(" See `0 theme list`, or install it with `0 theme install <id>`.");
|
|
13013
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
13014
|
-
return;
|
|
13015
|
-
}
|
|
13016
|
-
const saved = updateSetting("theme", id, deps.scope ? { scope: deps.scope } : {});
|
|
13017
|
-
if (!saved) {
|
|
13018
|
-
err(source_default.yellow(`Applied "${id}" for this session, but could not persist it to disk.`));
|
|
13019
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
13020
|
-
return;
|
|
13021
|
-
}
|
|
13022
|
-
out(source_default.green(`Theme set to "${id}".`));
|
|
13023
|
-
process.exitCode = EXIT_OK5;
|
|
13024
|
-
}
|
|
13025
|
-
function themeManifestFor(id, homeDir) {
|
|
13026
|
-
reloadInstalledThemes(homeDir);
|
|
13027
|
-
if (!isKnownTheme(id)) return null;
|
|
13028
|
-
const entry = THEME_NAMES.includes(id) ? THEMES[id] : installedThemeEntries(homeDir).find((e) => e.name === id);
|
|
13029
|
-
if (!entry) return null;
|
|
13030
|
-
return {
|
|
13031
|
-
kind: "theme",
|
|
13032
|
-
id,
|
|
13033
|
-
name: entry.label,
|
|
13034
|
-
version: "1.0.0",
|
|
13035
|
-
theme: {
|
|
13036
|
-
label: entry.label,
|
|
13037
|
-
description: entry.description,
|
|
13038
|
-
mode: entry.mode,
|
|
13039
|
-
palette: { ...entry.palette }
|
|
13040
|
-
}
|
|
13041
|
-
};
|
|
13042
|
-
}
|
|
13043
|
-
function runThemeExport(id, file, deps = {}) {
|
|
13044
|
-
const out = outOf(deps);
|
|
13045
|
-
const err = errOf(deps);
|
|
13046
|
-
const manifest = themeManifestFor(id, deps.homeDir);
|
|
13047
|
-
if (!manifest) {
|
|
13048
|
-
err(source_default.red(`"${id}" is not a known theme.`));
|
|
13049
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
13050
|
-
return;
|
|
13051
|
-
}
|
|
13052
|
-
const json = `${JSON.stringify(manifest, null, 2)}
|
|
13053
|
-
`;
|
|
13054
|
-
if (!file) {
|
|
13055
|
-
out(json.trimEnd());
|
|
13056
|
-
process.exitCode = EXIT_OK5;
|
|
13057
|
-
return;
|
|
13058
|
-
}
|
|
13059
|
-
try {
|
|
13060
|
-
writeFileSync16(file, json, "utf8");
|
|
13061
|
-
out(source_default.green(`Exported theme "${id}" to ${file}.`));
|
|
13062
|
-
process.exitCode = EXIT_OK5;
|
|
13063
|
-
} catch (e) {
|
|
13064
|
-
err(source_default.red(`Could not write ${file}: ${e instanceof Error ? e.message : String(e)}`));
|
|
13065
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
13066
|
-
}
|
|
13067
|
-
}
|
|
13068
|
-
function runThemeRemove(id, deps = {}) {
|
|
13069
|
-
const out = outOf(deps);
|
|
13070
|
-
const err = errOf(deps);
|
|
13071
|
-
reloadInstalledThemes(deps.homeDir);
|
|
13072
|
-
const result = removeInstalledTheme(id, deps.homeDir);
|
|
13073
|
-
if (!result.ok) {
|
|
13074
|
-
err(source_default.red(`Could not remove "${id}": ${result.error}`));
|
|
13075
|
-
process.exitCode = EXIT_USER_ERROR5;
|
|
13076
|
-
return;
|
|
13077
|
-
}
|
|
13078
|
-
reloadInstalledThemes(deps.homeDir);
|
|
13079
|
-
out(source_default.green(`Removed installed theme "${id}".`));
|
|
13080
|
-
out(source_default.dim(" If it was the active theme, the console falls back to the default until you apply another."));
|
|
13081
|
-
process.exitCode = EXIT_OK5;
|
|
13082
|
-
}
|
|
13083
13271
|
function registerThemeCommand(program) {
|
|
13084
|
-
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
});
|
|
13088
|
-
theme.command("install <id>").description("Fetch + validate + write a theme from the configured registry (installs data; runs no code)").option("--registry <url>", "Theme registry index URL (https)").action(async (id, opts) => {
|
|
13089
|
-
await runThemeInstall(id, { registryUrl: opts.registry });
|
|
13090
|
-
});
|
|
13091
|
-
theme.command("apply <id>").description("Set the console theme (a built-in name or an installed id)").option("--project", "Write the choice to the per-project override instead of the global config").option("--global", "Write the choice to the global config").action((id, opts) => {
|
|
13092
|
-
const scope = opts.project ? "project" : opts.global ? "global" : void 0;
|
|
13093
|
-
runThemeApply(id, scope ? { scope } : {});
|
|
13094
|
-
});
|
|
13095
|
-
theme.command("export <id> [file]").description("Emit a built-in or installed theme as a shareable theme manifest JSON (stdout if no file)").action((id, file) => {
|
|
13096
|
-
runThemeExport(id, file);
|
|
13097
|
-
});
|
|
13098
|
-
theme.command("remove <id>").description("Delete an installed theme (built-ins cannot be removed)").action((id) => {
|
|
13099
|
-
runThemeRemove(id);
|
|
13272
|
+
program.command("theme", { hidden: true }).argument("[legacy...]").allowUnknownOption(true).description("Retired terminal theme command; use browser Settings").action(() => {
|
|
13273
|
+
console.error("Terminal themes are no longer used. Run 0 web and open Settings \u2192 Appearance. Existing theme files have not been changed.");
|
|
13274
|
+
process.exitCode = EXIT_USER_ERROR5;
|
|
13100
13275
|
});
|
|
13101
13276
|
}
|
|
13102
13277
|
|
|
13103
13278
|
// packages/cli/src/commands/evolve.ts
|
|
13104
|
-
import { readFileSync as
|
|
13105
|
-
import { resolve as
|
|
13106
|
-
var
|
|
13279
|
+
import { readFileSync as readFileSync21, existsSync as existsSync15 } from "node:fs";
|
|
13280
|
+
import { resolve as resolve26 } from "node:path";
|
|
13281
|
+
var EXIT_OK5 = 0;
|
|
13107
13282
|
var EXIT_USER_ERROR6 = 1;
|
|
13108
13283
|
var EXIT_RUNTIME_ERROR = 2;
|
|
13109
13284
|
var EXIT_INTERRUPT = 3;
|
|
@@ -13237,7 +13412,7 @@ function registerEvolveCommand(program) {
|
|
|
13237
13412
|
else formatEvaluationResult(result, Boolean(opts.json), out);
|
|
13238
13413
|
if (result.iterations.length === 0) break;
|
|
13239
13414
|
}
|
|
13240
|
-
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT :
|
|
13415
|
+
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT : EXIT_OK5;
|
|
13241
13416
|
} catch (error) {
|
|
13242
13417
|
const message = error instanceof Error ? error.message : String(error);
|
|
13243
13418
|
if (opts.json) out(JSON.stringify({ error: message }));
|
|
@@ -13249,7 +13424,7 @@ function registerEvolveCommand(program) {
|
|
|
13249
13424
|
});
|
|
13250
13425
|
evolve.command("status").description("Show active and canary versions, snapshot identities, and registry events").option("--store <path>", "Required path to evolution store directory").option("--json", "Output structured JSON").action(async (opts) => {
|
|
13251
13426
|
try {
|
|
13252
|
-
const storePath = opts.store ?
|
|
13427
|
+
const storePath = opts.store ? resolve26(opts.store) : void 0;
|
|
13253
13428
|
if (!storePath) {
|
|
13254
13429
|
console.error(source_default.red("--store <path> is required. Point it to the evolution store directory containing registry.json."));
|
|
13255
13430
|
process.exitCode = EXIT_USER_ERROR6;
|
|
@@ -13278,7 +13453,7 @@ function registerEvolveCommand(program) {
|
|
|
13278
13453
|
if (campaign.status === "blocked" || campaign.status === "exhausted") console.log(` ${campaign.resumeReason}`);
|
|
13279
13454
|
}
|
|
13280
13455
|
}
|
|
13281
|
-
process.exitCode =
|
|
13456
|
+
process.exitCode = EXIT_OK5;
|
|
13282
13457
|
} catch (error) {
|
|
13283
13458
|
const message = error instanceof Error ? error.message : String(error);
|
|
13284
13459
|
if (opts.json) {
|
|
@@ -13291,9 +13466,9 @@ function registerEvolveCommand(program) {
|
|
|
13291
13466
|
});
|
|
13292
13467
|
evolve.command("reconcile").description("Reconcile an interrupted dispatch using observed cost and an immutable receipt digest").requiredOption("--store <path>", "Path to evolution store directory").requiredOption("--dispatch <id>", "Unresolved dispatch reservation ID").requiredOption("--cost-usd <amount>", "Actual provider/execution charge", Number).requiredOption("--receipt-digest <sha256>", "Immutable observed cost receipt digest").option("--json", "Output structured campaign ledger").action((opts) => {
|
|
13293
13468
|
try {
|
|
13294
|
-
const ledger = reconcileCampaignDispatch(
|
|
13469
|
+
const ledger = reconcileCampaignDispatch(resolve26(opts.store), opts.dispatch, opts.costUsd, opts.receiptDigest);
|
|
13295
13470
|
console.log(opts.json ? JSON.stringify(ledger) : `Reconciled ${opts.dispatch}; campaign ${ledger.status}`);
|
|
13296
|
-
process.exitCode =
|
|
13471
|
+
process.exitCode = EXIT_OK5;
|
|
13297
13472
|
} catch (error) {
|
|
13298
13473
|
const message = error instanceof Error ? error.message : String(error);
|
|
13299
13474
|
if (opts.json) console.log(JSON.stringify({ error: message }));
|
|
@@ -13306,10 +13481,10 @@ function registerEvolveCommand(program) {
|
|
|
13306
13481
|
const interrupt = () => controller.abort();
|
|
13307
13482
|
process.once("SIGINT", interrupt);
|
|
13308
13483
|
try {
|
|
13309
|
-
const result = await approveEvolutionCandidate(
|
|
13484
|
+
const result = await approveEvolutionCandidate(resolve26(opts.store), opts.version, { signal: controller.signal });
|
|
13310
13485
|
if (opts.json) console.log(JSON.stringify(result));
|
|
13311
13486
|
else console.log(`Promoted ${result.versionId}; canary cost $${result.evaluationCostUsd.toFixed(4)}`);
|
|
13312
|
-
process.exitCode =
|
|
13487
|
+
process.exitCode = EXIT_OK5;
|
|
13313
13488
|
} catch (error) {
|
|
13314
13489
|
const message = error instanceof Error ? error.message : String(error);
|
|
13315
13490
|
if (opts.json) console.log(JSON.stringify({ error: message }));
|
|
@@ -13321,7 +13496,7 @@ function registerEvolveCommand(program) {
|
|
|
13321
13496
|
});
|
|
13322
13497
|
evolve.command("rollback").description("Retire an active or canary evolution version and restore its parent").requiredOption("--store <path>", "Path to evolution store directory").requiredOption("--version <id>", "Active or canary version ID to retire").option("--reason <text>", "Reason for rollback", "operator rollback").action(async (opts) => {
|
|
13323
13498
|
try {
|
|
13324
|
-
const storePath =
|
|
13499
|
+
const storePath = resolve26(opts.store);
|
|
13325
13500
|
if (!existsSync15(storePath)) {
|
|
13326
13501
|
console.error(source_default.red(`store directory not found: ${storePath}`));
|
|
13327
13502
|
process.exitCode = EXIT_USER_ERROR6;
|
|
@@ -13337,7 +13512,7 @@ function registerEvolveCommand(program) {
|
|
|
13337
13512
|
await rollbackEvolutionVersion(storePath, opts.version, opts.reason);
|
|
13338
13513
|
console.log(source_default.green(`Retired ${opts.version.slice(0, 12)}\u2026; restored ${loadEvolutionRegistry(storePath).activeId}`));
|
|
13339
13514
|
console.log(` Reason: ${opts.reason}`);
|
|
13340
|
-
process.exitCode =
|
|
13515
|
+
process.exitCode = EXIT_OK5;
|
|
13341
13516
|
} catch (error) {
|
|
13342
13517
|
const message = error instanceof Error ? error.message : String(error);
|
|
13343
13518
|
console.error(source_default.red(`Rollback failed: ${message}`));
|
|
@@ -13372,7 +13547,7 @@ function registerEvolveCommand(program) {
|
|
|
13372
13547
|
if (exec.error) err(source_default.red(` ${exec.error}`));
|
|
13373
13548
|
}
|
|
13374
13549
|
formatExecResult(executionResult.versionId, executionResult, Boolean(opts.json), out);
|
|
13375
|
-
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT : hasError ? EXIT_RUNTIME_ERROR :
|
|
13550
|
+
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT : hasError ? EXIT_RUNTIME_ERROR : EXIT_OK5;
|
|
13376
13551
|
} catch (error) {
|
|
13377
13552
|
const message = error instanceof Error ? error.message : String(error);
|
|
13378
13553
|
if (opts.json) {
|
|
@@ -13389,12 +13564,12 @@ function registerEvolveCommand(program) {
|
|
|
13389
13564
|
const feedback = evolve.command("feedback").description("Capture, approve, and inspect evolution feedback candidates");
|
|
13390
13565
|
feedback.command("capture").description("Capture an evidence-backed observation from a JSON file; does not confirm a finding").requiredOption("--input <path>", "Observation JSON file with source revision and evidence references").option("--store <path>", "Feedback queue JSON file").option("--allow-source-access", "Explicitly consent to source use for this observation").action((opts) => {
|
|
13391
13566
|
try {
|
|
13392
|
-
const input = parseObservationInput(JSON.parse(
|
|
13567
|
+
const input = parseObservationInput(JSON.parse(readFileSync21(resolve26(opts.input), "utf8")));
|
|
13393
13568
|
const result = captureObservation({ ...input, consent: opts.allowSourceAccess === true }, {
|
|
13394
|
-
...opts.store ? { storePath:
|
|
13569
|
+
...opts.store ? { storePath: resolve26(opts.store) } : {}
|
|
13395
13570
|
});
|
|
13396
13571
|
console.log(JSON.stringify(result, null, 2));
|
|
13397
|
-
process.exitCode =
|
|
13572
|
+
process.exitCode = EXIT_OK5;
|
|
13398
13573
|
} catch (error) {
|
|
13399
13574
|
console.error(source_default.red(`Feedback capture failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
13400
13575
|
process.exitCode = EXIT_RUNTIME_ERROR;
|
|
@@ -13402,14 +13577,14 @@ function registerEvolveCommand(program) {
|
|
|
13402
13577
|
});
|
|
13403
13578
|
feedback.command("approve").description("Approve independent positive, held-out, and negative fixtures for an observation").requiredOption("--id <feedback-id>", "Full observation ID").requiredOption("--fixtures <path>", "Curation JSON containing positives, heldOut, and negativeControls").option("--store <path>", "Feedback queue JSON file").option("--allow-source-access", "Explicitly consent to source use for synthesis").action((opts) => {
|
|
13404
13579
|
try {
|
|
13405
|
-
const shape = parseApprovedObservationShape(JSON.parse(
|
|
13580
|
+
const shape = parseApprovedObservationShape(JSON.parse(readFileSync21(resolve26(opts.fixtures), "utf8")));
|
|
13406
13581
|
const result = approveObservation(opts.id, shape, {
|
|
13407
|
-
...opts.store ? { storePath:
|
|
13582
|
+
...opts.store ? { storePath: resolve26(opts.store) } : {},
|
|
13408
13583
|
...opts.allowSourceAccess === true ? { allowModelSourceAccess: true } : {}
|
|
13409
13584
|
});
|
|
13410
13585
|
if (!result) throw new Error("observation was not found or is not pending");
|
|
13411
13586
|
console.log(JSON.stringify(result, null, 2));
|
|
13412
|
-
process.exitCode =
|
|
13587
|
+
process.exitCode = EXIT_OK5;
|
|
13413
13588
|
} catch (error) {
|
|
13414
13589
|
console.error(source_default.red(`Feedback approval failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
13415
13590
|
process.exitCode = EXIT_RUNTIME_ERROR;
|
|
@@ -13417,11 +13592,11 @@ function registerEvolveCommand(program) {
|
|
|
13417
13592
|
});
|
|
13418
13593
|
feedback.command("release").description("Release a stale processing claim after its worker has stopped").requiredOption("--id <feedback-id>", "Full observation ID").requiredOption("--claim-token <token>", "Exact claim token shown by feedback status --json").option("--store <path>", "Feedback queue JSON file").action((opts) => {
|
|
13419
13594
|
try {
|
|
13420
|
-
if (!releaseClaim(opts.id, opts.claimToken, opts.store ? { storePath:
|
|
13595
|
+
if (!releaseClaim(opts.id, opts.claimToken, opts.store ? { storePath: resolve26(opts.store) } : {})) {
|
|
13421
13596
|
throw new Error("observation or processing claim no longer matches");
|
|
13422
13597
|
}
|
|
13423
13598
|
console.log(`Released feedback claim ${opts.id}`);
|
|
13424
|
-
process.exitCode =
|
|
13599
|
+
process.exitCode = EXIT_OK5;
|
|
13425
13600
|
} catch (error) {
|
|
13426
13601
|
console.error(`Feedback release failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
13427
13602
|
process.exitCode = EXIT_USER_ERROR6;
|
|
@@ -13429,11 +13604,11 @@ function registerEvolveCommand(program) {
|
|
|
13429
13604
|
});
|
|
13430
13605
|
feedback.command("status").description("Show retained observations and their approval/processing status").option("--store <path>", "Feedback queue JSON file").option("--json", "Output structured JSON").action((opts) => {
|
|
13431
13606
|
try {
|
|
13432
|
-
const observations = listObservations(void 0, { ...opts.store ? { storePath:
|
|
13607
|
+
const observations = listObservations(void 0, { ...opts.store ? { storePath: resolve26(opts.store) } : {} });
|
|
13433
13608
|
if (opts.json) console.log(JSON.stringify(observations, null, 2));
|
|
13434
13609
|
else if (observations.length === 0) console.log("No feedback observations.");
|
|
13435
13610
|
else for (const observation of observations) console.log(`${observation.id} ${observation.status} ${observation.classHint}`);
|
|
13436
|
-
process.exitCode =
|
|
13611
|
+
process.exitCode = EXIT_OK5;
|
|
13437
13612
|
} catch (error) {
|
|
13438
13613
|
console.error(source_default.red(`Feedback status failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
13439
13614
|
process.exitCode = EXIT_RUNTIME_ERROR;
|
|
@@ -13443,11 +13618,11 @@ function registerEvolveCommand(program) {
|
|
|
13443
13618
|
|
|
13444
13619
|
// packages/cli/src/commands/learning.ts
|
|
13445
13620
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
13446
|
-
import { isAbsolute as isAbsolute3, resolve as
|
|
13621
|
+
import { isAbsolute as isAbsolute3, resolve as resolve27 } from "node:path";
|
|
13447
13622
|
import { homedir as homedir3 } from "node:os";
|
|
13448
13623
|
async function defaultService() {
|
|
13449
|
-
const { LearningService, HuntMemoryStore } = await import("./dist-
|
|
13450
|
-
const { SecurityWorkflowStore: SecurityWorkflowStore2, learningProjectId } = await import("./dist-
|
|
13624
|
+
const { LearningService, HuntMemoryStore } = await import("./dist-ONIRKDH6.js");
|
|
13625
|
+
const { SecurityWorkflowStore: SecurityWorkflowStore2, learningProjectId } = await import("./dist-QLMPTFT7.js");
|
|
13451
13626
|
const workflows = new SecurityWorkflowStore2();
|
|
13452
13627
|
const store = workflows.learningStore();
|
|
13453
13628
|
const service = new LearningService(store, { workflows });
|
|
@@ -13461,7 +13636,7 @@ async function defaultService() {
|
|
|
13461
13636
|
if (isAbsolute3(source) || /^\.{1,2}\//.test(source) || source.startsWith("~/")) {
|
|
13462
13637
|
let root;
|
|
13463
13638
|
try {
|
|
13464
|
-
root = realpathSync3(source.startsWith("~/") ?
|
|
13639
|
+
root = realpathSync3(source.startsWith("~/") ? resolve27(homedir3(), source.slice(2)) : source);
|
|
13465
13640
|
} catch {
|
|
13466
13641
|
}
|
|
13467
13642
|
if (root) service.importCodebaseNotes(project(selected), root, new HuntMemoryStore());
|
|
@@ -13549,16 +13724,34 @@ function registerLearningCommand(program, deps = {}) {
|
|
|
13549
13724
|
}
|
|
13550
13725
|
|
|
13551
13726
|
// packages/cli/src/commands/config.ts
|
|
13552
|
-
import { readFileSync as
|
|
13553
|
-
var
|
|
13727
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync16 } from "node:fs";
|
|
13728
|
+
var EXIT_OK6 = 0;
|
|
13554
13729
|
var EXIT_USER_ERROR7 = 1;
|
|
13730
|
+
var CLI_CONFIG_KEYS = [
|
|
13731
|
+
"busyInputMode",
|
|
13732
|
+
"autoCompaction",
|
|
13733
|
+
"compactionThreshold",
|
|
13734
|
+
"allowSubagentPeerMessaging",
|
|
13735
|
+
"allowSubagentOperatorMessaging",
|
|
13736
|
+
"allowModelSelfExtension",
|
|
13737
|
+
"allowDevSourceUpdates",
|
|
13738
|
+
"executionProfile",
|
|
13739
|
+
"analyticsLevel",
|
|
13740
|
+
"diagnosticReporting",
|
|
13741
|
+
"updatePolicy"
|
|
13742
|
+
];
|
|
13743
|
+
var PUBLIC_CONFIG_KEYS = new Set(CLI_CONFIG_KEYS);
|
|
13744
|
+
var INTERNAL_CONFIG_KEYS = /* @__PURE__ */ new Set(["onboardingCompleted", "diagnosticReportingPrompted", "modelPreference"]);
|
|
13745
|
+
function publicConfig(settings) {
|
|
13746
|
+
return Object.fromEntries(CLI_CONFIG_KEYS.map((key) => [key, settings[key]]));
|
|
13747
|
+
}
|
|
13555
13748
|
var SECURITY_KEYS = SETTING_DEFS.filter(
|
|
13556
13749
|
(d) => d.group === "Security"
|
|
13557
13750
|
).map((d) => d.key);
|
|
13558
|
-
function
|
|
13751
|
+
function outOf(deps) {
|
|
13559
13752
|
return deps.out ?? ((l) => console.log(l));
|
|
13560
13753
|
}
|
|
13561
|
-
function
|
|
13754
|
+
function errOf(deps) {
|
|
13562
13755
|
return deps.err ?? ((l) => console.error(l));
|
|
13563
13756
|
}
|
|
13564
13757
|
function renderValue(value) {
|
|
@@ -13567,39 +13760,39 @@ function renderValue(value) {
|
|
|
13567
13760
|
return String(value);
|
|
13568
13761
|
}
|
|
13569
13762
|
function runConfigShow(deps = {}) {
|
|
13570
|
-
const out =
|
|
13763
|
+
const out = outOf(deps);
|
|
13571
13764
|
const { settings, sources } = loadLayeredSettings({
|
|
13572
13765
|
homeDir: deps.homeDir,
|
|
13573
13766
|
projectDir: deps.projectDir
|
|
13574
13767
|
});
|
|
13575
|
-
out(source_default.bold("Effective
|
|
13768
|
+
out(source_default.bold("Effective engine configuration"));
|
|
13576
13769
|
out(source_default.dim(` global: ${settingsFilePath(deps.homeDir)}`));
|
|
13577
13770
|
out(source_default.dim(` project: ${projectSettingsFilePath(deps.projectDir)}`));
|
|
13578
13771
|
out("");
|
|
13579
|
-
const keys =
|
|
13772
|
+
const keys = CLI_CONFIG_KEYS;
|
|
13580
13773
|
const width = Math.max(...keys.map((k) => k.length));
|
|
13581
13774
|
for (const key of keys) {
|
|
13582
13775
|
const layer = sources[key];
|
|
13583
13776
|
const tag = layer === "project" ? source_default.cyan("[project]") : layer === "global" ? source_default.green("[global]") : source_default.dim("[default]");
|
|
13584
13777
|
out(` ${key.padEnd(width)} ${renderValue(settings[key]).padEnd(11)} ${tag}`);
|
|
13585
13778
|
}
|
|
13586
|
-
process.exitCode =
|
|
13779
|
+
process.exitCode = EXIT_OK6;
|
|
13587
13780
|
}
|
|
13588
13781
|
function runConfigExport(file, deps = {}) {
|
|
13589
|
-
const out =
|
|
13590
|
-
const err =
|
|
13782
|
+
const out = outOf(deps);
|
|
13783
|
+
const err = errOf(deps);
|
|
13591
13784
|
const settings = deps.global ? loadGlobalSettings(deps.homeDir) : loadLayeredSettings({ homeDir: deps.homeDir, projectDir: deps.projectDir }).settings;
|
|
13592
|
-
const json = `${JSON.stringify(settings, null, 2)}
|
|
13785
|
+
const json = `${JSON.stringify(publicConfig(settings), null, 2)}
|
|
13593
13786
|
`;
|
|
13594
13787
|
if (!file) {
|
|
13595
13788
|
out(json.trimEnd());
|
|
13596
|
-
process.exitCode =
|
|
13789
|
+
process.exitCode = EXIT_OK6;
|
|
13597
13790
|
return;
|
|
13598
13791
|
}
|
|
13599
13792
|
try {
|
|
13600
|
-
|
|
13793
|
+
writeFileSync16(file, json, "utf8");
|
|
13601
13794
|
out(source_default.green(`Exported ${deps.global ? "global" : "effective"} config to ${file}.`));
|
|
13602
|
-
process.exitCode =
|
|
13795
|
+
process.exitCode = EXIT_OK6;
|
|
13603
13796
|
} catch (e) {
|
|
13604
13797
|
err(source_default.red(`Could not write ${file}: ${e instanceof Error ? e.message : String(e)}`));
|
|
13605
13798
|
process.exitCode = EXIT_USER_ERROR7;
|
|
@@ -13612,24 +13805,32 @@ function extractConfigBag(parsed) {
|
|
|
13612
13805
|
return parsed;
|
|
13613
13806
|
}
|
|
13614
13807
|
function runConfigImport(file, deps = {}) {
|
|
13615
|
-
const out =
|
|
13616
|
-
const err =
|
|
13808
|
+
const out = outOf(deps);
|
|
13809
|
+
const err = errOf(deps);
|
|
13617
13810
|
const scope = deps.scope ?? "global";
|
|
13618
13811
|
let parsed;
|
|
13619
13812
|
try {
|
|
13620
|
-
parsed = JSON.parse(
|
|
13813
|
+
parsed = JSON.parse(readFileSync22(file, "utf8"));
|
|
13621
13814
|
} catch (e) {
|
|
13622
13815
|
err(source_default.red(`Could not read ${file}: ${e instanceof Error ? e.message : String(e)}`));
|
|
13623
13816
|
process.exitCode = EXIT_USER_ERROR7;
|
|
13624
13817
|
return;
|
|
13625
13818
|
}
|
|
13626
13819
|
const bag = extractConfigBag(parsed);
|
|
13820
|
+
const legacyKeys = typeof bag === "object" && bag !== null && !Array.isArray(bag) ? Object.keys(bag).filter((key) => Object.hasOwn(DEFAULT_SETTINGS, key) && !PUBLIC_CONFIG_KEYS.has(key) && !INTERNAL_CONFIG_KEYS.has(key)) : [];
|
|
13821
|
+
if (legacyKeys.length) {
|
|
13822
|
+
err(source_default.red(`Retired terminal settings cannot be imported: ${legacyKeys.join(", ")}. Nothing was written.`));
|
|
13823
|
+
err("Use 0 web \u2192 Settings for browser appearance. Remove retired keys to import engine settings.");
|
|
13824
|
+
process.exitCode = EXIT_USER_ERROR7;
|
|
13825
|
+
return;
|
|
13826
|
+
}
|
|
13627
13827
|
const patch = sanitizeOverrides(bag);
|
|
13628
13828
|
const profile = typeof bag === "object" && bag !== null ? bag["executionProfile"] : void 0;
|
|
13629
13829
|
const profileChoices = SETTING_DEFS.find((def) => def.key === "executionProfile")?.choices;
|
|
13630
13830
|
if (scope === "global" && typeof profile === "string" && profileChoices?.includes(profile)) {
|
|
13631
13831
|
patch.executionProfile = profile;
|
|
13632
13832
|
}
|
|
13833
|
+
for (const key of Object.keys(patch)) if (!PUBLIC_CONFIG_KEYS.has(key)) delete patch[key];
|
|
13633
13834
|
const patchKeys = Object.keys(patch);
|
|
13634
13835
|
const skipped = typeof bag === "object" && bag !== null && !Array.isArray(bag) ? Object.keys(bag).filter((k) => !patchKeys.includes(k)) : [];
|
|
13635
13836
|
if (patchKeys.length === 0) {
|
|
@@ -13670,10 +13871,10 @@ function runConfigImport(file, deps = {}) {
|
|
|
13670
13871
|
}
|
|
13671
13872
|
if (changes.length === 0) out(source_default.dim(" (all imported values already matched the current config)"));
|
|
13672
13873
|
if (skipped.length > 0) out(source_default.dim(` Skipped unknown/invalid keys: ${skipped.join(", ")}`));
|
|
13673
|
-
process.exitCode =
|
|
13874
|
+
process.exitCode = EXIT_OK6;
|
|
13674
13875
|
}
|
|
13675
13876
|
function registerConfigCommand(program) {
|
|
13676
|
-
const config = program.command("config").description("Inspect, export, and import
|
|
13877
|
+
const config = program.command("config").description("Inspect, export, and import engine configuration (global and project layers)");
|
|
13677
13878
|
config.command("show").description("Show the effective config with the source layer (default/global/project) per key").action(() => {
|
|
13678
13879
|
runConfigShow();
|
|
13679
13880
|
});
|
|
@@ -13731,16 +13932,16 @@ function registerReviewChecksCommand(program) {
|
|
|
13731
13932
|
import { open } from "node:fs/promises";
|
|
13732
13933
|
import { constants as constants4 } from "node:fs";
|
|
13733
13934
|
var defaults = {
|
|
13734
|
-
createRemoteRuntime: async (options) => (await import("./remote-workflow-runtime-
|
|
13935
|
+
createRemoteRuntime: async (options) => (await import("./remote-workflow-runtime-GOI4TYP5.js")).createRemoteWorkflowRuntime(options),
|
|
13735
13936
|
createRuntime: async (options) => {
|
|
13736
|
-
const { createCliWorkflowRuntime } = await import("./workflow-runtime-
|
|
13937
|
+
const { createCliWorkflowRuntime } = await import("./workflow-runtime-CQTDASFA.js");
|
|
13737
13938
|
return await createCliWorkflowRuntime(options);
|
|
13738
13939
|
},
|
|
13739
13940
|
out: (text2) => process.stdout.write(`${text2}
|
|
13740
13941
|
`),
|
|
13741
13942
|
err: (text2) => process.stderr.write(`${text2}
|
|
13742
13943
|
`),
|
|
13743
|
-
sleep: () => new Promise((
|
|
13944
|
+
sleep: () => new Promise((resolve29) => setTimeout(resolve29, 100))
|
|
13744
13945
|
};
|
|
13745
13946
|
function positive(value, name, integer = false) {
|
|
13746
13947
|
if (value === void 0) return void 0;
|
|
@@ -13941,9 +14142,9 @@ function registerWorkflowCommand(program, deps = defaults) {
|
|
|
13941
14142
|
}
|
|
13942
14143
|
|
|
13943
14144
|
// packages/cli/src/commands/team.ts
|
|
13944
|
-
import { constants as constants5, closeSync as closeSync4, fstatSync as fstatSync3, openSync as openSync4, readFileSync as
|
|
14145
|
+
import { constants as constants5, closeSync as closeSync4, fstatSync as fstatSync3, openSync as openSync4, readFileSync as readFileSync23, renameSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync17 } from "node:fs";
|
|
13945
14146
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
13946
|
-
import { resolve as
|
|
14147
|
+
import { resolve as resolve28 } from "node:path";
|
|
13947
14148
|
import { emitKeypressEvents } from "node:readline";
|
|
13948
14149
|
var memberSchema = external_exports.object({ id: external_exports.string().trim().min(1).max(160), name: external_exports.string().trim().min(1).max(160), role: external_exports.enum(["owner", "editor", "viewer"]), passwordHash: external_exports.string().regex(/^scrypt\$[a-f0-9]{32}\$[a-f0-9]{128}$/).optional(), oidcSub: external_exports.string().min(1).optional() }).strict();
|
|
13949
14150
|
var configSchema = external_exports.object({ workspace: external_exports.object({ id: external_exports.string().min(1), name: external_exports.string().trim().min(1).max(160) }).strict(), users: external_exports.array(memberSchema).min(1).max(1e3), oidc: external_exports.object({ issuer: external_exports.string().url(), clientId: external_exports.string().min(1), clientSecretEnv: external_exports.string().min(1).optional(), redirectUri: external_exports.string().url() }).strict().optional() }).strict();
|
|
@@ -13953,7 +14154,7 @@ function readPrivateConfig(path) {
|
|
|
13953
14154
|
const stat3 = fstatSync3(fd);
|
|
13954
14155
|
if (!stat3.isFile() || (stat3.mode & 63) !== 0) throw new Error("Team configuration must be a private regular file (chmod 600)");
|
|
13955
14156
|
if (stat3.size > 1024 * 1024) throw new Error("Team configuration is too large");
|
|
13956
|
-
const cfg = configSchema.parse(JSON.parse(
|
|
14157
|
+
const cfg = configSchema.parse(JSON.parse(readFileSync23(fd, "utf8")));
|
|
13957
14158
|
if (new Set(cfg.users.map((user) => user.id)).size !== cfg.users.length) throw new Error("Team user IDs must be unique");
|
|
13958
14159
|
return cfg;
|
|
13959
14160
|
} finally {
|
|
@@ -14005,7 +14206,7 @@ async function readPassword() {
|
|
|
14005
14206
|
function writeNew(path, config) {
|
|
14006
14207
|
const fd = openSync4(path, "wx", 384);
|
|
14007
14208
|
try {
|
|
14008
|
-
|
|
14209
|
+
writeFileSync17(fd, `${JSON.stringify(config, null, 2)}
|
|
14009
14210
|
`, "utf8");
|
|
14010
14211
|
} catch (error) {
|
|
14011
14212
|
try {
|
|
@@ -14036,11 +14237,11 @@ function registerTeamCommand(program, dependencies = {}) {
|
|
|
14036
14237
|
const opts = init.opts();
|
|
14037
14238
|
const member = memberSchema.parse({ id: opts.owner, name: opts.displayName, role: "owner" });
|
|
14038
14239
|
const workspace = configSchema.shape.workspace.parse({ id: randomUUID3(), name: opts.name });
|
|
14039
|
-
const path =
|
|
14240
|
+
const path = resolve28(opts.config);
|
|
14040
14241
|
const fd = openSync4(path, "wx", 384);
|
|
14041
14242
|
try {
|
|
14042
14243
|
member.passwordHash = await hashTeamPassword(await password());
|
|
14043
|
-
|
|
14244
|
+
writeFileSync17(fd, `${JSON.stringify({ workspace, users: [member] }, null, 2)}
|
|
14044
14245
|
`, "utf8");
|
|
14045
14246
|
} catch (failure) {
|
|
14046
14247
|
try {
|
|
@@ -14057,7 +14258,7 @@ function registerTeamCommand(program, dependencies = {}) {
|
|
|
14057
14258
|
add.action(perform(async () => {
|
|
14058
14259
|
const opts = add.opts();
|
|
14059
14260
|
const member = memberSchema.parse({ id: opts.user, name: opts.displayName, role: opts.role });
|
|
14060
|
-
const path =
|
|
14261
|
+
const path = resolve28(opts.config);
|
|
14061
14262
|
const lock = `${path}.lock`;
|
|
14062
14263
|
const lockFD = openSync4(lock, "wx", 384);
|
|
14063
14264
|
const temporary = `${path}.${randomUUID3()}.tmp`;
|
|
@@ -14081,13 +14282,110 @@ function registerTeamCommand(program, dependencies = {}) {
|
|
|
14081
14282
|
}));
|
|
14082
14283
|
const list = team.command("list").description("List workspace accounts without credentials").requiredOption("--config <path>", "Team configuration");
|
|
14083
14284
|
list.action(perform(() => {
|
|
14084
|
-
const config = readPrivateConfig(
|
|
14285
|
+
const config = readPrivateConfig(resolve28(list.opts().config));
|
|
14085
14286
|
out(JSON.stringify({ workspace: config.workspace, users: config.users.map(({ id, name, role }) => ({ id, name, role })) }, null, 2));
|
|
14086
14287
|
}));
|
|
14087
14288
|
}
|
|
14289
|
+
|
|
14290
|
+
// packages/cli/src/commands/api.ts
|
|
14291
|
+
import { constants as constants6 } from "node:fs";
|
|
14292
|
+
import { open as open2 } from "node:fs/promises";
|
|
14293
|
+
var MAX_BODY = 1e6;
|
|
14294
|
+
var METHODS = ["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD"];
|
|
14295
|
+
async function parseBody(input) {
|
|
14296
|
+
if (input === void 0) return void 0;
|
|
14297
|
+
let text2 = input;
|
|
14298
|
+
if (input.startsWith("@")) {
|
|
14299
|
+
if (input.length === 1) throw new Error("--data @file requires a file path.");
|
|
14300
|
+
const file = await open2(input.slice(1), constants6.O_RDONLY | constants6.O_NONBLOCK);
|
|
14301
|
+
try {
|
|
14302
|
+
const stat3 = await file.stat();
|
|
14303
|
+
if (!stat3.isFile() || stat3.size > MAX_BODY) throw new Error("API data must be a regular JSON file of at most 1 MB.");
|
|
14304
|
+
const buffer = Buffer.alloc(MAX_BODY + 1);
|
|
14305
|
+
let length = 0;
|
|
14306
|
+
while (length < buffer.length) {
|
|
14307
|
+
const { bytesRead } = await file.read(buffer, length, buffer.length - length, length);
|
|
14308
|
+
if (!bytesRead) break;
|
|
14309
|
+
length += bytesRead;
|
|
14310
|
+
}
|
|
14311
|
+
if (length > MAX_BODY) throw new Error("API data exceeds 1 MB.");
|
|
14312
|
+
text2 = buffer.subarray(0, length).toString("utf8");
|
|
14313
|
+
} finally {
|
|
14314
|
+
await file.close();
|
|
14315
|
+
}
|
|
14316
|
+
}
|
|
14317
|
+
if (Buffer.byteLength(text2) > MAX_BODY) throw new Error("API data exceeds 1 MB.");
|
|
14318
|
+
let body;
|
|
14319
|
+
try {
|
|
14320
|
+
body = JSON.parse(text2);
|
|
14321
|
+
} catch {
|
|
14322
|
+
throw new Error("--data must contain valid JSON, or @file containing JSON.");
|
|
14323
|
+
}
|
|
14324
|
+
if (Buffer.byteLength(JSON.stringify(body)) > MAX_BODY) throw new Error("API data exceeds 1 MB.");
|
|
14325
|
+
return body;
|
|
14326
|
+
}
|
|
14327
|
+
async function runApiCommand(path, options, deps = {}) {
|
|
14328
|
+
const out = deps.out ?? ((text2) => {
|
|
14329
|
+
process.stdout.write(`${text2}
|
|
14330
|
+
`);
|
|
14331
|
+
});
|
|
14332
|
+
const err = deps.err ?? ((text2) => {
|
|
14333
|
+
process.stderr.write(`${text2}
|
|
14334
|
+
`);
|
|
14335
|
+
});
|
|
14336
|
+
const fail2 = deps.setExitCode ?? ((code) => {
|
|
14337
|
+
process.exitCode = code;
|
|
14338
|
+
});
|
|
14339
|
+
let registry;
|
|
14340
|
+
try {
|
|
14341
|
+
const method = (options.method ?? "GET").toUpperCase();
|
|
14342
|
+
if (!METHODS.includes(method)) throw new Error(`--method must be one of ${METHODS.join(", ")}.`);
|
|
14343
|
+
if (options.data !== void 0 && (method === "GET" || method === "HEAD")) throw new Error("GET and HEAD cannot include --data.");
|
|
14344
|
+
if (options.engineUrl && (options.backend || options.backendsConfig)) throw new Error("--engine-url cannot be combined with --backend or --backends-config.");
|
|
14345
|
+
if (Boolean(options.engineUrl) !== Boolean(options.engineTokenEnv)) throw new Error("Direct attachment requires both --engine-url and --engine-token-env.");
|
|
14346
|
+
if (!options.engineUrl && !options.backend) throw new Error("Select --backend or --engine-url with --engine-token-env explicitly.");
|
|
14347
|
+
if (options.backend === "local") throw new Error("Use an explicit HTTP engine URL or registered HTTP backend; local is not an API transport.");
|
|
14348
|
+
const requestPath = path ?? "/api/backend/handshake";
|
|
14349
|
+
if (requestPath.includes("#")) throw new Error("API paths cannot contain fragments.");
|
|
14350
|
+
if (!requestPath.startsWith("/api/") || requestPath.split("?")[0] !== "/api/backend/handshake" && !backendCapabilitiesForApiPath(requestPath.split("?")[0]).length) throw new Error("Supply an admitted /api/ path.");
|
|
14351
|
+
const body = await parseBody(options.data);
|
|
14352
|
+
const env = deps.env ?? process.env;
|
|
14353
|
+
const backendId = options.backend ?? "attached-engine";
|
|
14354
|
+
const connections = options.engineUrl ? [{ id: backendId, name: "Attached engine", url: options.engineUrl, bearerTokenEnv: options.engineTokenEnv }] : loadBackendConnectionConfig(options.backendsConfig);
|
|
14355
|
+
const connection = connections.find((row) => row.id === backendId);
|
|
14356
|
+
if (!connection) throw new Error("Backend is not registered.");
|
|
14357
|
+
if (options.engineUrl) backendBearerFromEnv(connection.bearerTokenEnv, env);
|
|
14358
|
+
const localHandshake = { protocolVersion: BACKEND_PROTOCOL_VERSION, engineId: "api-client", capabilities: [], platform: { os: process.platform, pathStyle: process.platform === "win32" ? "windows" : "posix" } };
|
|
14359
|
+
registry = new BackendConnectionRegistry({ ...options.engineUrl ? { connections } : { configPath: options.backendsConfig }, env, ...deps.fetch ? { fetch: deps.fetch } : {}, localHandshake });
|
|
14360
|
+
const response = await registry.request(backendId, requestPath, { method, ...body !== void 0 ? { body } : {} });
|
|
14361
|
+
const text2 = method === "HEAD" || response.status === 204 ? "" : await response.text();
|
|
14362
|
+
let data = text2 || null;
|
|
14363
|
+
if (text2 && /(?:application\/json|\+json)(?:;|$)/i.test(response.headers.get("content-type") ?? "")) {
|
|
14364
|
+
try {
|
|
14365
|
+
data = JSON.parse(text2);
|
|
14366
|
+
} catch {
|
|
14367
|
+
throw new Error(`Engine returned malformed JSON (HTTP ${response.status}).`);
|
|
14368
|
+
}
|
|
14369
|
+
}
|
|
14370
|
+
out(JSON.stringify({ ok: response.ok, status: response.status, data }));
|
|
14371
|
+
if (!response.ok) {
|
|
14372
|
+
err(JSON.stringify({ ok: false, status: response.status, error: `Engine request failed (HTTP ${response.status}).` }));
|
|
14373
|
+
fail2(2);
|
|
14374
|
+
}
|
|
14375
|
+
} catch (error) {
|
|
14376
|
+
err(JSON.stringify({ ok: false, status: error instanceof BackendConnectionError ? error.statusCode : null, error: error instanceof Error ? error.message : "API request failed." }));
|
|
14377
|
+
fail2(2);
|
|
14378
|
+
} finally {
|
|
14379
|
+
registry?.dispose();
|
|
14380
|
+
}
|
|
14381
|
+
}
|
|
14382
|
+
function registerApiCommand(program, deps = {}) {
|
|
14383
|
+
program.command("api [path]").description("Call a trusted engine API with deterministic JSON output (defaults to its handshake)").option("--method <method>", "GET, POST, PATCH, PUT, DELETE or HEAD", "GET").option("--data <json-or-@file>", "JSON body, or @regular-file containing JSON (at most 1 MB)").option("--backend <id>", "Registered HTTP engine ID").option("--backends-config <path>", "Operator backend registry JSON file").option("--engine-url <url>", "Attach directly to a trusted HTTP engine").option("--engine-token-env <name>", "Environment variable containing its engine token").action((path, options) => runApiCommand(path, options, deps));
|
|
14384
|
+
}
|
|
14088
14385
|
export {
|
|
14089
14386
|
registerAdGraphCommand,
|
|
14090
14387
|
registerAgentAssureCommand,
|
|
14388
|
+
registerApiCommand,
|
|
14091
14389
|
registerAssumptionHuntCommand,
|
|
14092
14390
|
registerAuditCommand,
|
|
14093
14391
|
registerBenchCommand,
|
|
@@ -14133,6 +14431,7 @@ export {
|
|
|
14133
14431
|
registerResumeCommand,
|
|
14134
14432
|
registerReviewChecksCommand,
|
|
14135
14433
|
registerReviewCommand,
|
|
14434
|
+
registerRoutingCommand,
|
|
14136
14435
|
registerScanCommand,
|
|
14137
14436
|
registerSecureCommand,
|
|
14138
14437
|
registerSpecdriftCommand,
|