0sec-cli 0.24.0 → 0.25.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 +64 -60
- package/README.md +121 -82
- package/chunks/{adapt-loop-TEJPXWFG.js → adapt-loop-L2PXCD4J.js} +6 -5
- package/chunks/{artifact-scraper-AJZ3LOQY.js → artifact-scraper-W3LGLXBM.js} +4 -3
- package/chunks/{assumption-mining-EATDC4BB.js → assumption-mining-7IJ6ZWZE.js} +22 -20
- package/chunks/{backend-connections-QE4NASAK.js → backend-connections-MYH4QRQG.js} +5 -4
- package/chunks/{chunk-RBOMXUYL.js → chunk-27SXCYWH.js} +1 -1
- package/chunks/{chunk-E42XEJTK.js → chunk-2J3STRJT.js} +337 -257
- package/chunks/chunk-36J5ZLFE.js +18729 -0
- package/chunks/chunk-3DF55BWV.js +49 -0
- package/chunks/{chunk-GHEBZKUS.js → chunk-3HMO42M2.js} +1426 -321
- package/chunks/{chunk-BIJPMYFA.js → chunk-3T5R7P4T.js} +6 -6
- package/chunks/{chunk-RD4FKFWR.js → chunk-5H2PXZ7Q.js} +1 -1
- package/chunks/chunk-5XOYTAOK.js +1546 -0
- package/chunks/{chunk-QEA2VHBD.js → chunk-6TA3CWND.js} +2656 -2960
- package/chunks/{chunk-H76JYUPE.js → chunk-76CLUI54.js} +3 -3
- package/chunks/{chunk-KCA35IL3.js → chunk-7PUJI64A.js} +11 -9
- package/chunks/{chunk-W6IYTSZH.js → chunk-7TIWL6E5.js} +8 -10
- package/chunks/chunk-ABKUI3QB.js +196 -0
- package/chunks/{chunk-YORL5S5V.js → chunk-ACYZMJHC.js} +1 -1
- package/chunks/{chunk-5FHFG5P2.js → chunk-AL32F74R.js} +1 -1
- package/chunks/{chunk-J6G73WYF.js → chunk-B5TIXHCO.js} +1 -1
- package/chunks/{chunk-G2EJ3R5I.js → chunk-BWUW6ZQR.js} +2052 -1075
- package/chunks/{chunk-3XLEDCFX.js → chunk-C6ZMPXN2.js} +5 -50
- package/chunks/{chunk-4TUR47H5.js → chunk-D4IBEO2K.js} +1 -1
- package/chunks/{chunk-EXTN4SQV.js → chunk-DHNYJ2ML.js} +1 -1
- package/chunks/{chunk-Y7KV7WV6.js → chunk-DJGJECBV.js} +93 -20
- package/chunks/{chunk-UHUW45S3.js → chunk-DMDWIW3E.js} +5 -5
- package/chunks/{chunk-V5I5GAQH.js → chunk-EEP6GBUO.js} +16037 -34417
- package/chunks/{chunk-EYBMTELO.js → chunk-EIONVEFN.js} +208 -29
- package/chunks/chunk-EQBC2ZWL.js +2481 -0
- package/chunks/{chunk-FKGFHLLS.js → chunk-FI2H6HV2.js} +1 -1
- package/chunks/{chunk-4YRXIVPZ.js → chunk-FI5YL4R2.js} +3 -3
- package/chunks/{chunk-DNV3ZMPX.js → chunk-FOLTHXRH.js} +1 -1
- package/chunks/{chunk-ZPFBQ3SD.js → chunk-GOUGG7IQ.js} +3 -3
- package/chunks/{chunk-O3ADFN2A.js → chunk-GXSECFUE.js} +1 -1
- package/chunks/{chunk-YYOQADBB.js → chunk-HDJSHLRM.js} +3 -2
- package/chunks/{chunk-A3EKBUEM.js → chunk-HFUOUT2B.js} +61232 -30665
- package/chunks/chunk-HJKJ4NQP.js +196 -0
- package/chunks/{chunk-RPTO5FY2.js → chunk-I4VIAQHM.js} +1 -1
- package/chunks/{chunk-A6AZZ6XX.js → chunk-ITEMDJAB.js} +3 -3
- package/chunks/chunk-ITHDAIRY.js +57 -0
- package/chunks/{chunk-TOFIGQ63.js → chunk-JCRQV4FE.js} +2 -2
- package/chunks/{chunk-SQCBHFWN.js → chunk-LWMEJYCP.js} +2 -2
- package/chunks/{chunk-52AWIBCT.js → chunk-MY44EZKD.js} +1 -1
- package/chunks/{chunk-SGILXLR3.js → chunk-NBLKIQCW.js} +226 -4
- package/chunks/chunk-NO543ZBU.js +90 -0
- package/chunks/{chunk-CIMN2AO6.js → chunk-OFPF26WL.js} +333 -3
- package/chunks/{chunk-YERUDEXT.js → chunk-PAE7ZAV6.js} +2780 -1255
- package/chunks/{chunk-V4BD7GSP.js → chunk-PMAKX6KP.js} +2 -2
- package/chunks/{chunk-62PGWN7Y.js → chunk-RBTJYREN.js} +8 -171
- package/chunks/{chunk-IK27KMVV.js → chunk-RFK5F45W.js} +1 -1
- package/chunks/{chunk-554D4AYM.js → chunk-S2WCYEK2.js} +4 -99
- package/chunks/{chunk-RZR2XXAK.js → chunk-S3B6HFSM.js} +144 -14
- package/chunks/{chunk-WUPN3D37.js → chunk-S4DFH2FJ.js} +26 -1
- package/chunks/{chunk-TZRHWP7R.js → chunk-SEWZ76MN.js} +77 -13
- package/chunks/{chunk-HRBOZBMC.js → chunk-TFKY6D7O.js} +1 -1
- package/chunks/{chunk-TOAAYJVN.js → chunk-WK6VUCKK.js} +3 -333
- package/chunks/{chunk-IXT64DV5.js → chunk-XPDJE537.js} +97 -1
- package/chunks/{chunk-RCHAFSWS.js → chunk-YXTV2FRE.js} +113 -22
- package/chunks/{chunk-TTDFBFNZ.js → chunk-YYFODVZG.js} +6 -10
- package/chunks/{chunk-3XLFB46W.js → chunk-ZWAWZU6C.js} +30 -13
- package/chunks/{chunk-5POT5OYF.js → chunk-ZZV56ACK.js} +11 -9
- package/chunks/{codex-models-FQPCWRPC.js → codex-models-KCUIVS3R.js} +9 -8
- package/chunks/{commands-I5L3VD2A.js → commands-MPPAADGY.js} +798 -608
- package/chunks/dashboard-MN7GZLLX.js +75 -0
- package/chunks/{db-P5EIKMLP.js → db-R2AQSESC.js} +5 -4
- package/chunks/{deep-review-I7RD5QSS.js → deep-review-Q6BJKEV4.js} +37 -38
- package/chunks/{disclose-PFBWESVJ.js → disclose-GGULOW27.js} +6 -5
- package/chunks/{dist-AJU25UXA.js → dist-6RNAVFAY.js} +376 -333
- package/chunks/{dist-VK2M4HNW.js → dist-DWN7U5OV.js} +5 -2
- package/chunks/{dist-M2X367VW.js → dist-JAZWL3SC.js} +3 -2
- package/chunks/{dist-3SWWY5FZ.js → dist-OLGNKDB2.js} +4 -3
- package/chunks/{dist-LNXGATR2.js → dist-WNAOCQGA.js} +5 -4
- package/chunks/eval-runner-WCTTIYN4.js +38 -0
- package/chunks/{exploit-agent-A4RTIJ4J.js → exploit-agent-M3KUMZJH.js} +1 -1
- package/chunks/{exploit-autoclimb-ABMMBC3M.js → exploit-autoclimb-QTTWC5WM.js} +1 -1
- package/chunks/{exploit-climb-BQ2SVU63.js → exploit-climb-E4KDELTN.js} +4 -3
- package/chunks/{fix-4YCLHFDT.js → fix-U5FFJD4F.js} +9 -8
- package/chunks/{harness-DHWULEIZ.js → harness-FMKIMEH5.js} +5 -4
- package/chunks/{http-conformance-U5F6GKYG.js → http-conformance-AXMUOE6C.js} +3 -2
- package/chunks/hunt-scan-RYPWRUQD.js +43 -0
- package/chunks/{kernel-primitive-SF4NALVR.js → kernel-primitive-CVG2E7MJ.js} +4 -3
- package/chunks/{kernel-vm-runner-WEBEZEIC.js → kernel-vm-runner-62KISULQ.js} +4 -3
- package/chunks/{local-engine-XUG7XRKM.js → local-engine-WP3I7K7G.js} +7 -6
- package/chunks/managed-operation-642WPTLC.js +59 -0
- package/chunks/{memsafety-scan-L2Z7E7TE.js → memsafety-scan-Q2MBZEGJ.js} +1 -2
- package/chunks/{native-loop-ZNAELJGB.js → native-loop-HC77R5NQ.js} +31 -16
- package/chunks/operator-services-E2NONBQS.js +79 -0
- package/chunks/orchestrate-Z3DW265M.js +62 -0
- package/chunks/{prepare-SODWQN6O.js → prepare-7DTS6RJT.js} +7 -6
- package/chunks/{remote-workflow-runtime-XNNGI2PG.js → remote-workflow-runtime-6CEVRZXS.js} +4 -3
- package/chunks/routing-ITJZBJIU.js +61 -0
- package/chunks/{runtime-MB4GEFBY.js → runtime-PZJ77QES.js} +9 -8
- package/chunks/{runtime-HFFRUOPL.js → runtime-W6JNDQRO.js} +4 -3
- package/chunks/{scan-stream-GXBJHCDF.js → scan-stream-6VOJTHTR.js} +6 -4
- package/chunks/{scope-M7L3CD6X.js → scope-FHXW6EX6.js} +4 -3
- package/chunks/service-plugins-CN6Q2NSN.js +63 -0
- package/chunks/{session-store-K7I4GLNH.js → session-store-DBBI544Y.js} +8 -5
- package/chunks/{variant-candidates-2KSP5EHH.js → variant-candidates-DPR6DJ3N.js} +9 -8
- package/chunks/{web-recon-prepass-RAXXTEWH.js → web-recon-prepass-HWDHDQMN.js} +7 -6
- package/chunks/{workflow-runtime-V26HIJO3.js → workflow-runtime-PLB32XC3.js} +50 -49
- package/dashboard/assets/{abnfDiagram-VCTEODGH-CGCueOp5.js → abnfDiagram-VCTEODGH-6e39CQKz.js} +1 -1
- package/dashboard/assets/{arc-BjZaQcCc.js → arc-ClYun86B.js} +1 -1
- package/dashboard/assets/architecture-7GRP2DOG-rM-lWo7E.js +1 -0
- package/dashboard/assets/architectureDiagram-5GKGNRK7-C9gEGZIU.js +36 -0
- package/dashboard/assets/{blockDiagram-I7D4REHJ-C-byT12_.js → blockDiagram-I7D4REHJ-Dgh2n5Lf.js} +2 -2
- package/dashboard/assets/{c4Diagram-7LVT6UL2-DoYjz-Uv.js → c4Diagram-7LVT6UL2-CsorW08z.js} +1 -1
- package/dashboard/assets/channel-BBlDqIBl.js +1 -0
- package/dashboard/assets/{chunk-4HAMMTFA-NBNp2zdt.js → chunk-4HAMMTFA-4_b_LGGQ.js} +1 -1
- package/dashboard/assets/{chunk-75Z2AOVW-BHmkuP0B.js → chunk-75Z2AOVW-qzNlKGCp.js} +1 -1
- package/dashboard/assets/chunk-DU6HZSFF-SAPICW28.js +127 -0
- package/dashboard/assets/{chunk-F27PBJKO-3wwNFUgZ.js → chunk-F27PBJKO-DlLotIQx.js} +1 -1
- package/dashboard/assets/{chunk-FOHPRMQF-DHwB1DNv.js → chunk-FOHPRMQF-COOliuUh.js} +14 -14
- package/dashboard/assets/{chunk-GMAD6QVW-Btg7huZW.js → chunk-GMAD6QVW-DNnr65Nb.js} +7 -7
- package/dashboard/assets/{chunk-GVQU2GXP-ihCURK5O.js → chunk-GVQU2GXP-DTwv0VfU.js} +1 -1
- package/dashboard/assets/{chunk-IMKFNOWR-FsXj7slg.js → chunk-IMKFNOWR-B1fk1q_W.js} +1 -1
- package/dashboard/assets/{chunk-L3NEJ4N5-DorFIxJY.js → chunk-L3NEJ4N5-ByVjFIox.js} +1 -1
- package/dashboard/assets/{chunk-OSK3NFVY-DKun_KfC.js → chunk-OSK3NFVY-DUDCzjbh.js} +1 -1
- package/dashboard/assets/{chunk-P2QGCYS3-XGgiU1Bz.js → chunk-P2QGCYS3-D_D5qEso.js} +1 -1
- package/dashboard/assets/{chunk-POPQ4Y6H-BTXEnGhJ.js → chunk-POPQ4Y6H-CetM-tVm.js} +1 -1
- package/dashboard/assets/{chunk-PWAF6VOD-DYZcGkTL.js → chunk-PWAF6VOD-BcJX4exl.js} +1 -1
- package/dashboard/assets/{chunk-SHT3W25Y-C4WQfwf8.js → chunk-SHT3W25Y-BWQql238.js} +1 -1
- package/dashboard/assets/{chunk-SVP7TREG-C4nCh0-1.js → chunk-SVP7TREG-BSLOD1JE.js} +1 -1
- package/dashboard/assets/{chunk-TICWLB2K-DSB-IiGc.js → chunk-TICWLB2K-DReOl-g_.js} +2 -2
- package/dashboard/assets/{chunk-XXDRQBXY-CS6fjUcj.js → chunk-XXDRQBXY-DSdSMeei.js} +1 -1
- package/dashboard/assets/classDiagram-ZZMXUADV-CRH2kB8G.js +1 -0
- package/dashboard/assets/classDiagram-v2-VYDZK3BY-CRH2kB8G.js +1 -0
- package/dashboard/assets/common-CRRsylCH.js +5 -0
- package/dashboard/assets/cose-bilkent-JH36ORCC-fg-DIBqt.js +1 -0
- package/dashboard/assets/cynefin-OW5HDTMX-XmrbEIFh.js +1 -0
- package/dashboard/assets/{cynefinDiagram-5FMLGOSQ-CgDOOY67.js → cynefinDiagram-5FMLGOSQ-CoQ7QEPl.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-qtQtsg6c.js +4 -0
- package/dashboard/assets/{diagram-S7CK7UJ4-CrKqRXZb.js → diagram-S7CK7UJ4-B_ts4_58.js} +2 -2
- package/dashboard/assets/{diagram-UQ7AKVKN-Cu6Es0-v.js → diagram-UQ7AKVKN-DwHbbxFy.js} +1 -1
- package/dashboard/assets/{diagram-VSXAHHWV-eK4d8FwS.js → diagram-VSXAHHWV-2Tg_RG89.js} +1 -1
- package/dashboard/assets/{diagram-VX7I27RA-bFxeFKOc.js → diagram-VX7I27RA-BFYp-YjF.js} +1 -1
- package/dashboard/assets/{diagram-Z3DM3KII-C0ClmnhC.js → diagram-Z3DM3KII-DrPiS4V0.js} +1 -1
- package/dashboard/assets/{dist-BZh8Kb3O.js → dist-cbVssBvx.js} +1 -1
- package/dashboard/assets/{ebnfDiagram-PWID7BFC-CUqxFPzf.js → ebnfDiagram-PWID7BFC-DCMOZtU2.js} +1 -1
- package/dashboard/assets/{erDiagram-RLTQ6QDP-CcYM7pLi.js → erDiagram-RLTQ6QDP-CW4rUJGU.js} +1 -1
- package/dashboard/assets/eventmodeling-NTZA5JFV-C2q-Aaav.js +1 -0
- package/dashboard/assets/flowDiagram-HODETNUW-3NOabgG3.js +1 -0
- package/dashboard/assets/{ganttDiagram-EL5Y4UJY-UmZfbMyD.js → ganttDiagram-EL5Y4UJY-C1AqcwIF.js} +1 -1
- package/dashboard/assets/gitGraph-4MIJSDKK-DYR76gtd.js +1 -0
- package/dashboard/assets/{gitGraphDiagram-WWUBYQGX-CvzeCxVy.js → gitGraphDiagram-WWUBYQGX-B7hL98CE.js} +1 -1
- package/dashboard/assets/info-A6RAGUB7-TXB43LiH.js +1 -0
- package/dashboard/assets/{infoDiagram-27XIBGKW-DjkpNtVW.js → infoDiagram-27XIBGKW-Dk5dXmh_.js} +1 -1
- package/dashboard/assets/{ishikawaDiagram-5VMMS53U-8FhjJaWT.js → ishikawaDiagram-5VMMS53U-BQDuNMka.js} +2 -2
- package/dashboard/assets/{journeyDiagram-3NMN7TZE-DyNJ755f.js → journeyDiagram-3NMN7TZE-DkustddD.js} +1 -1
- package/dashboard/assets/{kanban-definition-UXKFOSKX-_jCmtaY1.js → kanban-definition-UXKFOSKX-BW7Ann84.js} +1 -1
- package/dashboard/assets/{katex-BdBmVSus.js → katex-nLxf_RlZ.js} +2 -2
- package/dashboard/assets/{line-Bf0nxyWf.js → line-DVxcLeru.js} +1 -1
- package/dashboard/assets/linear-DOM_l9bO.js +1 -0
- package/dashboard/assets/mermaid-parser.core-CKg9fDvJ.js +7 -0
- package/dashboard/assets/{mermaid.core-B4yCwiN-.js → mermaid.core-DruW_5-Y.js} +9 -9
- package/dashboard/assets/{mindmap-definition-YA3MSWOX-D5DjWyXj.js → mindmap-definition-YA3MSWOX-Di5W5VB3.js} +1 -1
- package/dashboard/assets/operations-B-t_k60U.js +194 -0
- package/dashboard/assets/operations-D2ZKZFOF.css +1 -0
- package/dashboard/assets/packet-AYTQ26CC-BABwqtNu.js +1 -0
- package/dashboard/assets/{pegDiagram-XKGWAZYB-Bf6a1vaf.js → pegDiagram-XKGWAZYB-Cx4ABT6q.js} +1 -1
- package/dashboard/assets/pie-WAS4IAKB-CNdXyrze.js +1 -0
- package/dashboard/assets/{pieDiagram-E7YTZNPT-D0L1qbch.js → pieDiagram-E7YTZNPT-BilfQbIs.js} +1 -1
- package/dashboard/assets/{quadrantDiagram-AXDQQJYC-CbFyy2Pe.js → quadrantDiagram-AXDQQJYC-BVmMQHE5.js} +1 -1
- package/dashboard/assets/radar-RG4KPBEZ-fKNmDeoK.js +1 -0
- package/dashboard/assets/railroad-74A4TZTK-DhcvDCOh.js +1 -0
- package/dashboard/assets/railroad-abnf-HS5TGJTU-BTRVAmf0.js +1 -0
- package/dashboard/assets/railroad-ebnf-LZEXJU2U-CwS8fgC_.js +1 -0
- package/dashboard/assets/railroad-peg-WCYAUIDC-CXuhXlNp.js +1 -0
- package/dashboard/assets/{railroadDiagram-O6MQD6OU-t7Gp9g2R.js → railroadDiagram-O6MQD6OU-DnBru-jf.js} +1 -1
- package/dashboard/assets/{requirementDiagram-BXWQKSXE-LYmqeBXi.js → requirementDiagram-BXWQKSXE-FwdvUZ7_.js} +1 -1
- package/dashboard/assets/{sankeyDiagram-P5KCCOFB-DnpfA_94.js → sankeyDiagram-P5KCCOFB-BQvDORai.js} +1 -1
- package/dashboard/assets/{sequenceDiagram-WJ2MYXX4-C8s3pTUE.js → sequenceDiagram-WJ2MYXX4-FWYQLzcY.js} +2 -2
- package/dashboard/assets/sizeCapture-INFHLROL-3uHXrFqA.js +1 -0
- package/dashboard/assets/src-BwkPhlcp.js +1 -0
- package/dashboard/assets/{stateDiagram-D77RDMKH-BMzm6fK1.js → stateDiagram-D77RDMKH-CjPBd_Sa.js} +1 -1
- package/dashboard/assets/stateDiagram-v2-MP3YSRHH-DHmenujm.js +1 -0
- package/dashboard/assets/swimlanes-42K2YHIH-SQLNsa4J.js +1 -0
- package/dashboard/assets/swimlanesDiagram-VR7AAH4N-D1bH4ETZ.js +8 -0
- package/dashboard/assets/{timeline-definition-24CTP7MA-BfLJMVeG.js → timeline-definition-24CTP7MA-BxCf20k1.js} +1 -1
- package/dashboard/assets/treeView-Q6P3EWNA-BGLYAyGp.js +1 -0
- package/dashboard/assets/treemap-WGGIJYW6-BlzAwncU.js +1 -0
- package/dashboard/assets/{vennDiagram-4TSXK5OY-BYJRHEaL.js → vennDiagram-4TSXK5OY-D76RIZLz.js} +1 -1
- package/dashboard/assets/wardley-WFR3VGLG-Ba_reiVw.js +1 -0
- package/dashboard/assets/{wardleyDiagram-VM6X3IG4-DgPN4nSe.js → wardleyDiagram-VM6X3IG4-Cux4coOD.js} +1 -1
- package/dashboard/assets/{xychartDiagram-S5SC5T6Z-BhkAMAOT.js → xychartDiagram-S5SC5T6Z-Ch5mvnlH.js} +1 -1
- package/dashboard/index.html +2 -2
- package/package.json +2 -5
- package/chunks/chunk-AV5BF4V7.js +0 -4304
- package/chunks/chunk-CSPF47S3.js +0 -6027
- package/chunks/chunk-ESM447R6.js +0 -77
- package/chunks/chunk-FEOPHBMY.js +0 -56
- package/chunks/chunk-GNR3APR6.js +0 -295
- package/chunks/chunk-IIBNQTOK.js +0 -1532
- package/chunks/chunk-JSTLXPJS.js +0 -284
- package/chunks/chunk-NJLKFC66.js +0 -4790
- package/chunks/chunk-O7Q2G2KW.js +0 -117
- package/chunks/chunk-VIT5ALXF.js +0 -4054
- package/chunks/chunk-YJU7QACE.js +0 -279
- package/chunks/dashboard-B2AEGCFM.js +0 -76
- package/chunks/eval-runner-XVRX3R2Y.js +0 -31
- package/chunks/hunt-scan-DXV5H6YN.js +0 -40
- package/chunks/managed-operation-SQFMBWHG.js +0 -60
- package/chunks/orchestrate-YHFJXGID.js +0 -63
- package/chunks/run-5T4Z3Q2D.js +0 -28242
- package/chunks/service-plugins-BGS6QKSZ.js +0 -64
- package/dashboard/assets/architecture-7GRP2DOG-hcbO-9zX.js +0 -1
- package/dashboard/assets/architectureDiagram-5GKGNRK7-DReOXTSq.js +0 -36
- package/dashboard/assets/channel-CUURBnpZ.js +0 -1
- package/dashboard/assets/chunk-DU6HZSFF-DgfLNaL2.js +0 -127
- package/dashboard/assets/classDiagram-ZZMXUADV-CD1Buc26.js +0 -1
- package/dashboard/assets/classDiagram-v2-VYDZK3BY-CD1Buc26.js +0 -1
- package/dashboard/assets/common-BMdQBwfR.js +0 -5
- package/dashboard/assets/cose-bilkent-JH36ORCC-CUjQHTML.js +0 -1
- package/dashboard/assets/cynefin-OW5HDTMX-BC7zCtFq.js +0 -1
- package/dashboard/assets/cytoscape.esm-CGd-uY3x.js +0 -321
- package/dashboard/assets/dagre-GXQ25YYZ-Dqc8FS9x.js +0 -4
- package/dashboard/assets/dagre-PrKaheQc.js +0 -1
- package/dashboard/assets/eventmodeling-NTZA5JFV-D8ZNnPkV.js +0 -1
- package/dashboard/assets/flowDiagram-HODETNUW-pDb1AYm8.js +0 -1
- package/dashboard/assets/gitGraph-4MIJSDKK-mvNUo0ZA.js +0 -1
- package/dashboard/assets/info-A6RAGUB7-DChKqZMi.js +0 -1
- package/dashboard/assets/linear-Bl6JKbf4.js +0 -1
- package/dashboard/assets/mermaid-parser.core-Cc6sgCzs.js +0 -7
- package/dashboard/assets/operations-B7JAWOi6.js +0 -130
- package/dashboard/assets/operations-QjKT0Hwi.css +0 -1
- package/dashboard/assets/packet-AYTQ26CC-bQXLDhQC.js +0 -1
- package/dashboard/assets/pie-WAS4IAKB-DfzoABIi.js +0 -1
- package/dashboard/assets/radar-RG4KPBEZ-CZ2pyeUT.js +0 -1
- package/dashboard/assets/railroad-74A4TZTK-CP4Jazfd.js +0 -1
- package/dashboard/assets/railroad-abnf-HS5TGJTU-3MvEiHwD.js +0 -1
- package/dashboard/assets/railroad-ebnf-LZEXJU2U-BWto6cXE.js +0 -1
- package/dashboard/assets/railroad-peg-WCYAUIDC-DasEjbyf.js +0 -1
- package/dashboard/assets/sizeCapture-INFHLROL-B0uUizjq.js +0 -1
- package/dashboard/assets/src-CaNUT1AQ.js +0 -1
- package/dashboard/assets/stateDiagram-v2-MP3YSRHH-B3REMjpY.js +0 -1
- package/dashboard/assets/swimlanes-42K2YHIH-uJE05Tt_.js +0 -1
- package/dashboard/assets/swimlanesDiagram-VR7AAH4N-CIaVMZEy.js +0 -8
- package/dashboard/assets/treeView-Q6P3EWNA-ZOE2enu2.js +0 -1
- package/dashboard/assets/treemap-WGGIJYW6-yIZoPBF5.js +0 -1
- package/dashboard/assets/wardley-WFR3VGLG-D5V-jLbB.js +0 -1
|
@@ -1,100 +1,86 @@
|
|
|
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-ZZV56ACK.js";
|
|
4
7
|
import {
|
|
5
8
|
registerOrchestrateCommand
|
|
6
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-YYFODVZG.js";
|
|
7
10
|
import {
|
|
8
11
|
registerDbCommand
|
|
9
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-B5TIXHCO.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-G2EJ3R5I.js";
|
|
19
|
-
import "./chunk-UHUW45S3.js";
|
|
20
|
-
import "./chunk-ZPFBQ3SD.js";
|
|
21
|
-
import {
|
|
22
|
-
registerLensSynthCommand
|
|
23
|
-
} from "./chunk-JSTLXPJS.js";
|
|
24
|
-
import "./chunk-O7Q2G2KW.js";
|
|
18
|
+
} from "./chunk-3HMO42M2.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-BWUW6ZQR.js";
|
|
29
|
+
import "./chunk-DMDWIW3E.js";
|
|
30
|
+
import "./chunk-GOUGG7IQ.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-C6ZMPXN2.js";
|
|
37
|
+
import {
|
|
38
|
+
registerRoutingCommand
|
|
39
|
+
} from "./chunk-3DF55BWV.js";
|
|
41
40
|
import {
|
|
42
41
|
executeManagedOperation
|
|
43
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-JCRQV4FE.js";
|
|
43
|
+
import "./chunk-ZWAWZU6C.js";
|
|
44
|
+
import "./chunk-EQBC2ZWL.js";
|
|
44
45
|
import {
|
|
45
|
-
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import "./chunk-
|
|
46
|
+
getRuntimeAvailability
|
|
47
|
+
} from "./chunk-ITHDAIRY.js";
|
|
48
|
+
import "./chunk-7TIWL6E5.js";
|
|
48
49
|
import {
|
|
49
50
|
deployWorker,
|
|
51
|
+
repairWorker,
|
|
50
52
|
stopWorker,
|
|
51
53
|
validateWorkerOptions
|
|
52
|
-
} from "./chunk-
|
|
53
|
-
import {
|
|
54
|
-
performAutoUpdate
|
|
55
|
-
} from "./chunk-SGILXLR3.js";
|
|
56
|
-
import {
|
|
57
|
-
Command,
|
|
58
|
-
InvalidArgumentError,
|
|
59
|
-
Option
|
|
60
|
-
} from "./chunk-WUPN3D37.js";
|
|
54
|
+
} from "./chunk-SEWZ76MN.js";
|
|
61
55
|
import {
|
|
62
56
|
consolePresentationOutput,
|
|
57
|
+
performAutoUpdate,
|
|
63
58
|
processPresentationOutput,
|
|
64
59
|
writePresentationLine
|
|
65
|
-
} from "./chunk-
|
|
66
|
-
import "./chunk-FEOPHBMY.js";
|
|
60
|
+
} from "./chunk-NBLKIQCW.js";
|
|
67
61
|
import {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
Command,
|
|
63
|
+
InvalidArgumentError,
|
|
64
|
+
Option
|
|
65
|
+
} from "./chunk-S4DFH2FJ.js";
|
|
66
|
+
import "./chunk-NO543ZBU.js";
|
|
67
|
+
import "./chunk-RBTJYREN.js";
|
|
71
68
|
import {
|
|
72
69
|
source_default
|
|
73
70
|
} from "./chunk-HLFS6WV2.js";
|
|
74
71
|
import {
|
|
75
|
-
|
|
72
|
+
DEFAULT_SETTINGS,
|
|
76
73
|
SETTING_DEFS,
|
|
77
|
-
THEMES,
|
|
78
|
-
THEME_NAMES,
|
|
79
|
-
installedThemeEntries,
|
|
80
|
-
installedThemesDir,
|
|
81
|
-
isKnownTheme,
|
|
82
|
-
isSafeThemeId,
|
|
83
74
|
loadGlobalSettings,
|
|
84
75
|
loadLayeredSettings,
|
|
85
|
-
loadSettings,
|
|
86
76
|
normalizeSettings,
|
|
87
77
|
projectSettingsFilePath,
|
|
88
78
|
readProjectOverrides,
|
|
89
|
-
reloadInstalledThemes,
|
|
90
|
-
removeInstalledTheme,
|
|
91
79
|
sanitizeOverrides,
|
|
92
80
|
saveProjectOverrides,
|
|
93
81
|
saveSettings,
|
|
94
|
-
settingsFilePath
|
|
95
|
-
|
|
96
|
-
writeInstalledTheme
|
|
97
|
-
} from "./chunk-QEA2VHBD.js";
|
|
82
|
+
settingsFilePath
|
|
83
|
+
} from "./chunk-6TA3CWND.js";
|
|
98
84
|
import {
|
|
99
85
|
CraftMemoryStore,
|
|
100
86
|
DEFAULT_MAX_TOOL_ITERATIONS,
|
|
@@ -107,91 +93,48 @@ import {
|
|
|
107
93
|
H1NetworkError,
|
|
108
94
|
H1RateLimitError,
|
|
109
95
|
McpServer,
|
|
110
|
-
ObjectiveOracle,
|
|
111
96
|
ReadBuffer,
|
|
112
|
-
agentActionConfigurationChanges,
|
|
113
|
-
agentActionManifestSha256,
|
|
114
|
-
agenticScan,
|
|
115
|
-
appendLedgerEntry,
|
|
116
|
-
approveObservation,
|
|
117
97
|
atlasTechniquesForEvent,
|
|
118
98
|
automationVerdict,
|
|
119
|
-
captureObservation,
|
|
120
|
-
compareScorecards,
|
|
121
99
|
consolidateMemory,
|
|
122
|
-
corpusV1Path,
|
|
123
|
-
createAgenticScanAdapter,
|
|
124
|
-
createBenchIntegrationRegistry,
|
|
125
100
|
createConsoleRuntime,
|
|
126
|
-
createCoreBenchIntegration,
|
|
127
|
-
createVariantExecutionFactory,
|
|
128
101
|
defaultCraftCandidateReviewer,
|
|
129
|
-
digestBenchManifest,
|
|
130
102
|
enumerateTargetModelFromKext,
|
|
131
|
-
evaluateRegression,
|
|
132
|
-
formatTournamentSummary,
|
|
133
103
|
generateInputsForSelector,
|
|
134
104
|
generateSyzChoiceWeights,
|
|
135
105
|
getProgram,
|
|
136
106
|
getStructuredScopes,
|
|
137
|
-
|
|
138
|
-
lastGreen,
|
|
139
|
-
listObservations,
|
|
107
|
+
inspectLensRegistry,
|
|
140
108
|
listPrograms,
|
|
141
109
|
listProjectReviewChecks,
|
|
142
110
|
loadH1Credentials,
|
|
143
|
-
loadLedger,
|
|
144
|
-
loadManifest,
|
|
145
111
|
makeRng,
|
|
146
|
-
mcpAgentTarget,
|
|
147
|
-
objectiveOracleEvaluatorAttestation,
|
|
148
|
-
objectiveOracleEvaluatorCodeBytes,
|
|
149
|
-
objectiveOracleEvaluatorConfigJson,
|
|
150
|
-
pairwiseDeltas,
|
|
151
|
-
parseApprovedObservationShape,
|
|
152
|
-
parseEnsembleModels,
|
|
153
|
-
parseManifest,
|
|
154
|
-
parseObservationInput,
|
|
155
|
-
pickChampion,
|
|
156
112
|
planSingleShardRun,
|
|
157
113
|
preseedMemory,
|
|
158
|
-
projectResearchExecutionEvidence,
|
|
159
|
-
projectResearchImprovementResult,
|
|
160
114
|
radarCandidatesToSeedFindings,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
researchExecutionEvidenceRef,
|
|
164
|
-
runAgentActionAssurance,
|
|
165
|
-
runEnsembleCraft,
|
|
115
|
+
retireArchetype,
|
|
116
|
+
runLensSynthesisLoop,
|
|
166
117
|
runSecureProject,
|
|
167
|
-
runTournament,
|
|
168
|
-
saveLedger,
|
|
169
118
|
scan,
|
|
170
119
|
scanRepoCommitsWithJev,
|
|
171
120
|
selectorModelToLine,
|
|
172
121
|
serializeMessage,
|
|
173
|
-
snapshotBenchVariant,
|
|
174
|
-
subsetManifest,
|
|
175
122
|
summariseScopes,
|
|
176
123
|
syzChoiceWeightsFromPlan,
|
|
177
124
|
techniquesForEvent,
|
|
178
125
|
toScopeFile,
|
|
179
|
-
updateProjectReviewChecks
|
|
180
|
-
|
|
181
|
-
writeAgentActionEvidenceBundle
|
|
182
|
-
} from "./chunk-V5I5GAQH.js";
|
|
126
|
+
updateProjectReviewChecks
|
|
127
|
+
} from "./chunk-EEP6GBUO.js";
|
|
183
128
|
import {
|
|
184
129
|
formatSarif
|
|
185
|
-
} from "./chunk-
|
|
130
|
+
} from "./chunk-AL32F74R.js";
|
|
186
131
|
import {
|
|
187
132
|
adaptAndVerify
|
|
188
|
-
} from "./chunk-
|
|
133
|
+
} from "./chunk-FI5YL4R2.js";
|
|
189
134
|
import {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
} from "./chunk-TOAAYJVN.js";
|
|
194
|
-
import "./chunk-4TUR47H5.js";
|
|
135
|
+
enumerateJsChunkUrls
|
|
136
|
+
} from "./chunk-WK6VUCKK.js";
|
|
137
|
+
import "./chunk-D4IBEO2K.js";
|
|
195
138
|
import {
|
|
196
139
|
createLiveHttpSender
|
|
197
140
|
} from "./chunk-GVD6SJGH.js";
|
|
@@ -203,8 +146,7 @@ import {
|
|
|
203
146
|
import {
|
|
204
147
|
getEvalCategories,
|
|
205
148
|
runEval
|
|
206
|
-
} from "./chunk-
|
|
207
|
-
import "./chunk-IIBNQTOK.js";
|
|
149
|
+
} from "./chunk-PMAKX6KP.js";
|
|
208
150
|
import {
|
|
209
151
|
runNpmDynamicDiscovery
|
|
210
152
|
} from "./chunk-2WNCI664.js";
|
|
@@ -216,74 +158,122 @@ import {
|
|
|
216
158
|
DETECTOR_REGISTRY,
|
|
217
159
|
resolveDetectors
|
|
218
160
|
} from "./chunk-DQTNI3KY.js";
|
|
219
|
-
import "./chunk-
|
|
220
|
-
import "./chunk-RPTO5FY2.js";
|
|
161
|
+
import "./chunk-FI2H6HV2.js";
|
|
221
162
|
import {
|
|
222
163
|
prepare
|
|
223
|
-
} from "./chunk-
|
|
224
|
-
import "./chunk-
|
|
225
|
-
import "./chunk-
|
|
226
|
-
import "./chunk-H76JYUPE.js";
|
|
227
|
-
import "./chunk-CSPF47S3.js";
|
|
164
|
+
} from "./chunk-HJKJ4NQP.js";
|
|
165
|
+
import "./chunk-TFKY6D7O.js";
|
|
166
|
+
import "./chunk-76CLUI54.js";
|
|
228
167
|
import {
|
|
168
|
+
ObjectiveOracle,
|
|
229
169
|
ToolExecutor,
|
|
170
|
+
agentActionConfigurationChanges,
|
|
171
|
+
agentActionManifestSha256,
|
|
172
|
+
agenticScan,
|
|
230
173
|
aggregateScorecard,
|
|
174
|
+
appendLedgerEntry,
|
|
231
175
|
approveEvolutionCandidate,
|
|
176
|
+
approveObservation,
|
|
232
177
|
bucketInScope,
|
|
178
|
+
captureObservation,
|
|
233
179
|
classifyTakeover,
|
|
180
|
+
compareScorecards,
|
|
181
|
+
corpusV1Path,
|
|
182
|
+
createAgenticScanAdapter,
|
|
183
|
+
createBenchIntegrationRegistry,
|
|
184
|
+
createCoreBenchIntegration,
|
|
185
|
+
createVariantExecutionFactory,
|
|
234
186
|
describeEngagementPosture,
|
|
187
|
+
digestBenchManifest,
|
|
188
|
+
evaluateRegression,
|
|
235
189
|
executeEvolutionVersion,
|
|
236
190
|
extractAttributionFromScopeJson,
|
|
237
191
|
extractEngagementFromScopeJson,
|
|
238
192
|
fetchScoped,
|
|
193
|
+
formatTournamentSummary,
|
|
239
194
|
getToolsForRole,
|
|
195
|
+
harvestMissesFromLedgerEntry,
|
|
196
|
+
httpActionOracle,
|
|
197
|
+
lastGreen,
|
|
198
|
+
listObservations,
|
|
240
199
|
loadEvolutionCampaign,
|
|
241
200
|
loadEvolutionRegistry,
|
|
201
|
+
loadLedger,
|
|
202
|
+
loadManifest,
|
|
203
|
+
makeFinderLensProbe,
|
|
204
|
+
mcpAgentTarget,
|
|
205
|
+
mergeHarvestedMisses,
|
|
242
206
|
networkScopeRequiredRefusal,
|
|
207
|
+
objectiveOracleEvaluatorAttestation,
|
|
208
|
+
objectiveOracleEvaluatorCodeBytes,
|
|
209
|
+
objectiveOracleEvaluatorConfigJson,
|
|
210
|
+
pairwiseDeltas,
|
|
211
|
+
parseApprovedObservationShape,
|
|
212
|
+
parseEnsembleModels,
|
|
213
|
+
parseManifest,
|
|
214
|
+
parseObservationInput,
|
|
215
|
+
pickChampion,
|
|
243
216
|
probeS3Bucket,
|
|
217
|
+
projectResearchExecutionEvidence,
|
|
218
|
+
projectResearchImprovementResult,
|
|
244
219
|
reconcileCampaignDispatch,
|
|
220
|
+
releaseClaim,
|
|
221
|
+
renderScoreboard,
|
|
222
|
+
researchExecutionEvidenceRef,
|
|
245
223
|
resolveAttribution,
|
|
246
224
|
resolveEngagementProfile,
|
|
247
225
|
rollbackEvolutionVersion,
|
|
226
|
+
runAgentActionAssurance,
|
|
227
|
+
runEnsembleCraft,
|
|
248
228
|
runEvolution,
|
|
249
229
|
runJsRecon,
|
|
250
230
|
runRecon,
|
|
251
231
|
runSmolvmPocSteps,
|
|
232
|
+
runTournament,
|
|
233
|
+
saveLedger,
|
|
234
|
+
snapshotBenchVariant,
|
|
235
|
+
subsetManifest,
|
|
252
236
|
targetRequiresScope,
|
|
253
237
|
validateAwsCredentials,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
238
|
+
withVariantFeatureFlags,
|
|
239
|
+
workflowPolicyRuntime,
|
|
240
|
+
writeAgentActionEvidenceBundle
|
|
241
|
+
} from "./chunk-HFUOUT2B.js";
|
|
242
|
+
import "./chunk-ACYZMJHC.js";
|
|
257
243
|
import "./chunk-K2PWUPUI.js";
|
|
258
244
|
import {
|
|
245
|
+
RateLimiter,
|
|
259
246
|
buildIntelDossier,
|
|
260
247
|
lookupCve,
|
|
248
|
+
parseRateLimitFlag,
|
|
261
249
|
searchAdvisories,
|
|
262
250
|
searchSimilar,
|
|
263
251
|
searchTargetHistory
|
|
264
|
-
} from "./chunk-
|
|
265
|
-
import "./chunk-
|
|
252
|
+
} from "./chunk-OFPF26WL.js";
|
|
253
|
+
import "./chunk-PAE7ZAV6.js";
|
|
266
254
|
import "./chunk-UEX7PFSE.js";
|
|
267
|
-
import "./chunk-
|
|
255
|
+
import "./chunk-I4VIAQHM.js";
|
|
256
|
+
import "./chunk-2J3STRJT.js";
|
|
268
257
|
import {
|
|
269
258
|
budgetNativeRuntime
|
|
270
|
-
} from "./chunk-
|
|
271
|
-
import "./chunk-
|
|
259
|
+
} from "./chunk-HDJSHLRM.js";
|
|
260
|
+
import "./chunk-AZ7L3HFD.js";
|
|
261
|
+
import "./chunk-FOLTHXRH.js";
|
|
272
262
|
import {
|
|
273
263
|
runSourceFix
|
|
274
|
-
} from "./chunk-
|
|
264
|
+
} from "./chunk-ITEMDJAB.js";
|
|
275
265
|
import {
|
|
276
266
|
appendImprovementLedgerEntry,
|
|
277
267
|
evaluateImprovementPromotion,
|
|
278
268
|
loadEvolutionConfigFile,
|
|
279
269
|
verifyImprovementLedger
|
|
280
|
-
} from "./chunk-
|
|
270
|
+
} from "./chunk-DJGJECBV.js";
|
|
281
271
|
import {
|
|
282
272
|
runHttpConformanceCheck
|
|
283
|
-
} from "./chunk-
|
|
273
|
+
} from "./chunk-LWMEJYCP.js";
|
|
284
274
|
import {
|
|
285
275
|
createRuntime
|
|
286
|
-
} from "./chunk-
|
|
276
|
+
} from "./chunk-DHNYJ2ML.js";
|
|
287
277
|
import "./chunk-O6KPVYOI.js";
|
|
288
278
|
import {
|
|
289
279
|
buildAdGraph,
|
|
@@ -303,7 +293,7 @@ import {
|
|
|
303
293
|
resolveOsecDbPath,
|
|
304
294
|
resolveOsecRunStorage,
|
|
305
295
|
writeOsecRunReport
|
|
306
|
-
} from "./chunk-
|
|
296
|
+
} from "./chunk-YXTV2FRE.js";
|
|
307
297
|
import {
|
|
308
298
|
DISCLOSURE_STATUSES,
|
|
309
299
|
IncompleteEvidenceError,
|
|
@@ -322,39 +312,39 @@ import {
|
|
|
322
312
|
renderReproducibilityManifest,
|
|
323
313
|
renderVendorNotificationMarkdown,
|
|
324
314
|
transition
|
|
325
|
-
} from "./chunk-
|
|
315
|
+
} from "./chunk-S2WCYEK2.js";
|
|
326
316
|
import {
|
|
327
317
|
executePocSteps
|
|
328
|
-
} from "./chunk-
|
|
318
|
+
} from "./chunk-XPDJE537.js";
|
|
329
319
|
import {
|
|
330
320
|
findCveArtifacts,
|
|
331
321
|
normaliseCveId
|
|
332
|
-
} from "./chunk-
|
|
333
|
-
import "./chunk-
|
|
334
|
-
import "./chunk-
|
|
322
|
+
} from "./chunk-5H2PXZ7Q.js";
|
|
323
|
+
import "./chunk-ABKUI3QB.js";
|
|
324
|
+
import "./chunk-GXSECFUE.js";
|
|
335
325
|
import {
|
|
336
326
|
LlmApiRuntime,
|
|
337
327
|
features
|
|
338
|
-
} from "./chunk-
|
|
328
|
+
} from "./chunk-EIONVEFN.js";
|
|
339
329
|
import {
|
|
340
330
|
isAdmittedSmolvmWorkbench
|
|
341
|
-
} from "./chunk-
|
|
331
|
+
} from "./chunk-3T5R7P4T.js";
|
|
342
332
|
import {
|
|
343
333
|
eventBus
|
|
344
|
-
} from "./chunk-
|
|
334
|
+
} from "./chunk-MY44EZKD.js";
|
|
345
335
|
import "./chunk-RS4MAN3Q.js";
|
|
346
336
|
import {
|
|
347
337
|
EmptyPocError,
|
|
348
338
|
detectVersionRange,
|
|
349
339
|
renderAdvisoryMarkdown,
|
|
350
340
|
verifyAgainstRef
|
|
351
|
-
} from "./chunk-
|
|
341
|
+
} from "./chunk-RFK5F45W.js";
|
|
352
342
|
import {
|
|
353
343
|
ScopePolicy,
|
|
354
344
|
getScopeEnforcementState,
|
|
355
345
|
isScopeEnforcementEnabled,
|
|
356
346
|
loadScope
|
|
357
|
-
} from "./chunk-
|
|
347
|
+
} from "./chunk-27SXCYWH.js";
|
|
358
348
|
import "./chunk-5IBCBQEH.js";
|
|
359
349
|
import {
|
|
360
350
|
AgentActionScenarioSchema,
|
|
@@ -371,15 +361,131 @@ import {
|
|
|
371
361
|
meetsSeverityFloor,
|
|
372
362
|
parseAgentActionEvidenceManifest,
|
|
373
363
|
pocStepArraySchema,
|
|
374
|
-
reportSummarySchema
|
|
375
|
-
|
|
364
|
+
reportSummarySchema,
|
|
365
|
+
validateScanPlan
|
|
366
|
+
} from "./chunk-S3B6HFSM.js";
|
|
376
367
|
import {
|
|
377
368
|
external_exports
|
|
378
|
-
} from "./chunk-
|
|
369
|
+
} from "./chunk-5XOYTAOK.js";
|
|
370
|
+
import "./chunk-36J5ZLFE.js";
|
|
379
371
|
import "./chunk-VCSFCHAJ.js";
|
|
380
372
|
|
|
381
373
|
// packages/cli/src/commands/scan.ts
|
|
382
374
|
import { readFileSync, existsSync } from "node:fs";
|
|
375
|
+
|
|
376
|
+
// packages/cli/src/guided-scan.ts
|
|
377
|
+
import { createInterface } from "node:readline/promises";
|
|
378
|
+
|
|
379
|
+
// packages/cli/src/tui/scan-plan.ts
|
|
380
|
+
function recommendedScanGoal(kind) {
|
|
381
|
+
if (kind === "package") return "known-vulnerabilities";
|
|
382
|
+
if (kind === "web") return "misconfigurations";
|
|
383
|
+
return "unknown-vulnerabilities";
|
|
384
|
+
}
|
|
385
|
+
function recommendedScanDepth(goal) {
|
|
386
|
+
return goal === "unknown-vulnerabilities" ? "deep" : "default";
|
|
387
|
+
}
|
|
388
|
+
function recommendedTimeCapMs(kind, depth) {
|
|
389
|
+
if (kind === "web") {
|
|
390
|
+
return depth === "deep" ? 3e5 : depth === "default" ? 6e4 : 3e4;
|
|
391
|
+
}
|
|
392
|
+
return depth === "deep" ? 18e5 : depth === "default" ? 6e5 : 3e5;
|
|
393
|
+
}
|
|
394
|
+
function formatTimeCap(ms) {
|
|
395
|
+
if (ms < 6e4) return `${Math.round(ms / 1e3)}s`;
|
|
396
|
+
const minutes = ms / 6e4;
|
|
397
|
+
return Number.isInteger(minutes) ? `${minutes}m` : `${minutes.toFixed(1)}m`;
|
|
398
|
+
}
|
|
399
|
+
function formatGoal(goal) {
|
|
400
|
+
return goal === "known-vulnerabilities" ? "known vulnerabilities" : goal === "unknown-vulnerabilities" ? "unknown vulnerabilities" : "misconfigurations";
|
|
401
|
+
}
|
|
402
|
+
function scanDepthExplanation(goal) {
|
|
403
|
+
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.";
|
|
404
|
+
}
|
|
405
|
+
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.";
|
|
406
|
+
var SCAN_MODE_HELP = "Sequential is suggested for lower concurrency. Parallel overlaps runs and may finish sooner, but can consume the shared budget sooner.";
|
|
407
|
+
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.";
|
|
408
|
+
|
|
409
|
+
// packages/cli/src/guided-scan.ts
|
|
410
|
+
var SCAN_MODEL_ROLES = ["discovery", "attack", "verify", "report"];
|
|
411
|
+
function parseScanModelAssignments(values) {
|
|
412
|
+
const assignments = {};
|
|
413
|
+
for (const value of values) {
|
|
414
|
+
const separator = value.indexOf("=");
|
|
415
|
+
const role = value.slice(0, separator);
|
|
416
|
+
const model = value.slice(separator + 1).trim();
|
|
417
|
+
if (separator < 1 || !SCAN_MODEL_ROLES.includes(role) || !model || model === "auto" || /[\r\n\0]/.test(model)) {
|
|
418
|
+
throw new Error("--task-model requires discovery|attack|verify|report=MODEL (an explicit model ID).");
|
|
419
|
+
}
|
|
420
|
+
if (Object.hasOwn(assignments, role)) throw new Error(`Duplicate task model for ${role}.`);
|
|
421
|
+
assignments[role] = model;
|
|
422
|
+
}
|
|
423
|
+
return assignments;
|
|
424
|
+
}
|
|
425
|
+
function scanRoutingSummary(model, assignments = {}, singleModel = false) {
|
|
426
|
+
const fallback = model ?? "configured session model";
|
|
427
|
+
return SCAN_MODEL_ROLES.map((role) => `${role}: ${singleModel ? fallback : assignments[role] ?? fallback}`).join(" \xB7 ");
|
|
428
|
+
}
|
|
429
|
+
async function collectGuidedScanPlan(options, io) {
|
|
430
|
+
const choose = async (label, choices, recommended) => {
|
|
431
|
+
while (true) {
|
|
432
|
+
const answer = (await io.question(`${label} (${choices.join(" / ")}) [${recommended}]: `)).trim();
|
|
433
|
+
if (!answer) return recommended;
|
|
434
|
+
if (choices.includes(answer)) return answer;
|
|
435
|
+
io.write("Choose one of the listed values.\n");
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
const positive2 = async (label, fallback, integer = false, max = Infinity) => {
|
|
439
|
+
while (true) {
|
|
440
|
+
const raw = (await io.question(`${label} [${fallback}]: `)).trim();
|
|
441
|
+
const value = raw ? Number(raw) : fallback;
|
|
442
|
+
if (Number.isFinite(value) && value > 0 && value <= max && (!integer || Number.isSafeInteger(value))) return value;
|
|
443
|
+
io.write(`Enter a positive ${integer ? "integer" : "number"}${max < Infinity ? ` no greater than ${max}` : ""}.
|
|
444
|
+
`);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
io.write(`Scope: ${options.target}
|
|
448
|
+
Recommendations keep this scope unchanged.
|
|
449
|
+
`);
|
|
450
|
+
const goal = await choose("Goal", ["known-vulnerabilities", "unknown-vulnerabilities", "misconfigurations"], recommendedScanGoal("web"));
|
|
451
|
+
io.write(`${scanDepthExplanation(goal)} Unknown vulnerabilities are an objective, not a promised result.
|
|
452
|
+
`);
|
|
453
|
+
const depth = await choose("Depth", ["quick", "default", "deep"], options.depth ?? recommendedScanDepth(goal));
|
|
454
|
+
io.write(`${SCAN_RUNS_HELP}
|
|
455
|
+
`);
|
|
456
|
+
const runCount = await positive2("Separate runs", 1, true, 16);
|
|
457
|
+
io.write(`${SCAN_MODE_HELP}
|
|
458
|
+
`);
|
|
459
|
+
const executionMode = await choose("Execution", ["sequential", "parallel"], "sequential");
|
|
460
|
+
io.write("This planner supports up to 24 hours and $1,000 estimated for the whole plan.\n");
|
|
461
|
+
const timeCapMs = await positive2("Total wall-clock cap (minutes)", recommendedTimeCapMs("web", depth) / 6e4, false, 1440) * 6e4;
|
|
462
|
+
io.write(`${SCAN_COST_HELP}
|
|
463
|
+
`);
|
|
464
|
+
const costCapUsd = await positive2("Total estimated cost cap (USD)", Math.min(options.costCapUsd ?? 5, 1e3), false, 1e3);
|
|
465
|
+
const plan = { goal, depth, runCount, executionMode, timeCapMs, costCapUsd };
|
|
466
|
+
validateScanPlan(plan);
|
|
467
|
+
io.write(`
|
|
468
|
+
${options.target} \xB7 ${formatGoal(goal)} \xB7 ${depth} \xB7 ${runCount} separate run(s) \xB7 ${executionMode} \xB7 ${formatTimeCap(timeCapMs)} total \xB7 $${costCapUsd} total estimated
|
|
469
|
+
`);
|
|
470
|
+
const routing = options.singleModel ? void 0 : options.recommendRouting?.(plan);
|
|
471
|
+
if (routing) for (const role of SCAN_MODEL_ROLES) io.write(`${role}: ${routing.reasons[role]}
|
|
472
|
+
`);
|
|
473
|
+
io.write(`${scanRoutingSummary(options.model, routing?.assignments ?? options.agentModels, options.singleModel)}
|
|
474
|
+
Configured models are operator choices; no task-specific superiority is assumed. Override with --task-model ROLE=MODEL or --single-model.
|
|
475
|
+
`);
|
|
476
|
+
const confirmed = (await io.question("Start this plan? [y/N]: ")).trim().toLowerCase();
|
|
477
|
+
return confirmed === "y" || confirmed === "yes" ? plan : void 0;
|
|
478
|
+
}
|
|
479
|
+
async function guidedScanPlan(options) {
|
|
480
|
+
const readline = createInterface({ input: process.stdin, output: process.stderr });
|
|
481
|
+
try {
|
|
482
|
+
return await collectGuidedScanPlan(options, { question: (prompt) => readline.question(prompt), write: (text2) => process.stderr.write(text2) });
|
|
483
|
+
} finally {
|
|
484
|
+
readline.close();
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// packages/cli/src/commands/scan.ts
|
|
383
489
|
function parseAuthFlag(value) {
|
|
384
490
|
let raw;
|
|
385
491
|
if (!value.trimStart().startsWith("{") && existsSync(value)) {
|
|
@@ -431,16 +537,27 @@ function parseIdentitiesFile(path) {
|
|
|
431
537
|
}
|
|
432
538
|
}
|
|
433
539
|
var fixtureSchema = external_exports.array(external_exports.object({
|
|
434
|
-
url: external_exports.string().url().refine((url) =>
|
|
540
|
+
url: external_exports.string().url().max(8192).refine((url) => {
|
|
541
|
+
const parsed = new URL(url);
|
|
542
|
+
return /^https?:/.test(url) && !parsed.username && !parsed.password;
|
|
543
|
+
}),
|
|
435
544
|
ownerIdentity: external_exports.string().min(1),
|
|
436
545
|
comparisonIdentities: external_exports.array(external_exports.string().min(1)).min(1).max(16),
|
|
437
|
-
ownershipMarker: external_exports.string().min(16).max(500)
|
|
438
|
-
|
|
546
|
+
ownershipMarker: external_exports.string().min(16).max(500),
|
|
547
|
+
stateChange: external_exports.object({
|
|
548
|
+
disposable: external_exports.literal(true),
|
|
549
|
+
jsonPointer: external_exports.string().regex(/^(?:\/(?:[^~]|~[01])*)?$/),
|
|
550
|
+
stepUrls: external_exports.array(external_exports.string().url().max(8192).refine((url) => /^https?:/.test(url))).min(1).max(10)
|
|
551
|
+
}).strict().optional()
|
|
552
|
+
}).strict().refine((fixture) => !fixture.stateChange || fixture.stateChange.stepUrls.every((url) => {
|
|
553
|
+
const step = new URL(url), observation = new URL(fixture.url);
|
|
554
|
+
return step.origin === observation.origin && !step.username && !step.password;
|
|
555
|
+
}))).min(1).max(100);
|
|
439
556
|
function parseAccessControlFixturesFile(path) {
|
|
440
557
|
try {
|
|
441
558
|
return fixtureSchema.parse(JSON.parse(readFileSync(path, "utf8")));
|
|
442
559
|
} catch {
|
|
443
|
-
throw new Error("Invalid --access-control-fixtures file: expected
|
|
560
|
+
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
561
|
}
|
|
445
562
|
}
|
|
446
563
|
function parseStringArrayEnv(name, raw) {
|
|
@@ -505,14 +622,14 @@ var PRESET_TOKENS = /* @__PURE__ */ new Set([
|
|
|
505
622
|
"moat"
|
|
506
623
|
]);
|
|
507
624
|
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(
|
|
625
|
+
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
626
|
"--attribution-header <name=value>",
|
|
510
627
|
"Header to attach to in-scope requests (repeatable); never sent out-of-scope",
|
|
511
628
|
(value, prev = []) => [...prev, value]
|
|
512
629
|
).option(
|
|
513
630
|
"--attribution-ua <token>",
|
|
514
631
|
"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>", "
|
|
632
|
+
).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
633
|
"--rate-limit <spec>",
|
|
517
634
|
"Per-host requests/sec cap, e.g. '5' or 'host=5,*=3' (default 5)"
|
|
518
635
|
).option(
|
|
@@ -521,16 +638,16 @@ function registerScanCommand(program) {
|
|
|
521
638
|
).option(
|
|
522
639
|
"--no-waf-evasion",
|
|
523
640
|
"Disable adaptive WAF-evasion retries"
|
|
524
|
-
).option(
|
|
641
|
+
).option(
|
|
525
642
|
"--features <list>",
|
|
526
643
|
"Comma-separated feature flags to enable, e.g. 'fp-moat'"
|
|
527
644
|
).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
645
|
"--emit <target>",
|
|
529
646
|
"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) => {
|
|
647
|
+
).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
648
|
if (opts.replay) {
|
|
532
649
|
try {
|
|
533
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
650
|
+
const { osecDB: osecDB2 } = await import("./dist-OLGNKDB2.js");
|
|
534
651
|
const db = new osecDB2(opts.dbPath);
|
|
535
652
|
const scans = db.listScans(1);
|
|
536
653
|
if (scans.length === 0) {
|
|
@@ -682,7 +799,7 @@ function registerScanCommand(program) {
|
|
|
682
799
|
process.exit(2);
|
|
683
800
|
}
|
|
684
801
|
try {
|
|
685
|
-
const { loadScope: loadScope2 } = await import("./dist-
|
|
802
|
+
const { loadScope: loadScope2 } = await import("./dist-6RNAVFAY.js");
|
|
686
803
|
const policy = loadScope2(scopeFile);
|
|
687
804
|
const verdict = scopeEnforcement.enabled ? policy.match(String(opts.target)) : void 0;
|
|
688
805
|
if (verdict && !verdict.allowed) {
|
|
@@ -709,7 +826,7 @@ function registerScanCommand(program) {
|
|
|
709
826
|
loadScope: loadScope2,
|
|
710
827
|
resolveAttribution: resolveAttribution2,
|
|
711
828
|
extractAttributionFromScopeJson: extractAttributionFromScopeJson2
|
|
712
|
-
} = await import("./dist-
|
|
829
|
+
} = await import("./dist-6RNAVFAY.js");
|
|
713
830
|
const policy = scopeFile ? loadScope2(scopeFile) : void 0;
|
|
714
831
|
resolveAttribution2({
|
|
715
832
|
scopeFileBlock: policy ? extractAttributionFromScopeJson2(policy.raw) : void 0,
|
|
@@ -727,7 +844,7 @@ function registerScanCommand(program) {
|
|
|
727
844
|
loadScope: loadScope2,
|
|
728
845
|
resolveEngagementProfile: resolveEngagementProfile2,
|
|
729
846
|
extractEngagementFromScopeJson: extractEngagementFromScopeJson2
|
|
730
|
-
} = await import("./dist-
|
|
847
|
+
} = await import("./dist-6RNAVFAY.js");
|
|
731
848
|
const policy = scopeFile ? loadScope2(scopeFile) : void 0;
|
|
732
849
|
resolveEngagementProfile2({
|
|
733
850
|
scopeFileBlock: policy ? extractEngagementFromScopeJson2(policy.raw) : void 0,
|
|
@@ -756,13 +873,41 @@ function registerScanCommand(program) {
|
|
|
756
873
|
const rateLimit = opts.rateLimit;
|
|
757
874
|
if (rateLimit !== void 0 && rateLimit !== "") {
|
|
758
875
|
try {
|
|
759
|
-
const { parseRateLimitFlag: parseRateLimitFlag2 } = await import("./dist-
|
|
876
|
+
const { parseRateLimitFlag: parseRateLimitFlag2 } = await import("./dist-6RNAVFAY.js");
|
|
760
877
|
parseRateLimitFlag2(rateLimit);
|
|
761
878
|
} catch (err) {
|
|
762
879
|
console.error(source_default.red(err instanceof Error ? err.message : String(err)));
|
|
763
880
|
process.exit(2);
|
|
764
881
|
}
|
|
765
882
|
}
|
|
883
|
+
const manualModels = parseScanModelAssignments(opts.taskModel ?? []);
|
|
884
|
+
let agentModels = manualModels;
|
|
885
|
+
let recommendRouting;
|
|
886
|
+
if (opts.routingReport && !opts.singleModel) {
|
|
887
|
+
if (opts.runtime !== "api") throw new Error("Reviewed routing requires --runtime api; no unsupported runtime or provider substitution.");
|
|
888
|
+
if (!opts.routingReviewRef || !opts.routingModel?.length) throw new Error("--routing-report requires --routing-model approvals and --routing-review-ref confirming the workflow/provider review.");
|
|
889
|
+
const { readRoutingJson } = await import("./routing-ITJZBJIU.js");
|
|
890
|
+
const { recommendQualifiedRouting, LlmApiRuntime: LlmApiRuntime2 } = await import("./dist-6RNAVFAY.js");
|
|
891
|
+
const raw = readRoutingJson(String(opts.routingReport));
|
|
892
|
+
const current = new LlmApiRuntime2({ type: "api", timeout: parseInt(opts.timeout, 10), model: opts.model });
|
|
893
|
+
recommendRouting = (selectedPlan) => {
|
|
894
|
+
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 });
|
|
895
|
+
agentModels = { ...result.assignments, ...manualModels };
|
|
896
|
+
return { assignments: agentModels, reasons: Object.fromEntries(Object.entries(result.reasons).map(([role, reason]) => [role, manualModels[role] ? `Operator override: ${manualModels[role]}.` : reason])) };
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
const interactivePlanning = opts.guided !== false && opts.format === "terminal" && process.stdin.isTTY && process.stdout.isTTY && !opts.resume;
|
|
900
|
+
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;
|
|
901
|
+
if (interactivePlanning && !plan) return;
|
|
902
|
+
if (!interactivePlanning && recommendRouting) {
|
|
903
|
+
if (!opts.goal || !opts.planTimeCap || costCeilingUsd === void 0) throw new Error("Noninteractive reviewed routing requires --goal, --plan-time-cap and --cost-ceiling.");
|
|
904
|
+
plan = { goal: opts.goal, depth: opts.depth, runCount: 1, executionMode: "sequential", timeCapMs: Number(opts.planTimeCap), costCapUsd: costCeilingUsd };
|
|
905
|
+
const { validateScanPlan: validateScanPlan2 } = await import("./dist-DWN7U5OV.js");
|
|
906
|
+
validateScanPlan2(plan);
|
|
907
|
+
const routing = recommendRouting(plan);
|
|
908
|
+
for (const [role, model] of Object.entries(routing.assignments)) console.error(`${role}: ${model} \u2014 ${routing.reasons[role]}`);
|
|
909
|
+
}
|
|
910
|
+
const hasAssignments = Object.keys(agentModels).length > 0;
|
|
766
911
|
const branchFrom = opts.branchFrom;
|
|
767
912
|
await runUnified({
|
|
768
913
|
target: opts.target,
|
|
@@ -770,7 +915,10 @@ function registerScanCommand(program) {
|
|
|
770
915
|
resumeScanId: opts.resume,
|
|
771
916
|
branchFromEntry: branchFrom !== void 0 ? parseInt(branchFrom, 10) : void 0,
|
|
772
917
|
mode,
|
|
773
|
-
depth: opts.depth,
|
|
918
|
+
depth: plan?.depth ?? opts.depth,
|
|
919
|
+
plan,
|
|
920
|
+
...hasAssignments ? { agentModels } : {},
|
|
921
|
+
...opts.singleModel !== void 0 ? { singleModel: opts.singleModel } : {},
|
|
774
922
|
format: opts.format === "md" ? "markdown" : opts.format,
|
|
775
923
|
runtime: opts.runtime ?? "auto",
|
|
776
924
|
timeout: parseInt(opts.timeout, 10),
|
|
@@ -786,9 +934,8 @@ function registerScanCommand(program) {
|
|
|
786
934
|
exportTarget: opts.export,
|
|
787
935
|
race: opts.race,
|
|
788
936
|
egats: opts.egats,
|
|
789
|
-
costCeilingUsd,
|
|
937
|
+
costCeilingUsd: plan?.costCapUsd ?? costCeilingUsd,
|
|
790
938
|
rateLimit,
|
|
791
|
-
tui: opts.tui,
|
|
792
939
|
scopeFile,
|
|
793
940
|
allowScanners: opts.allowScanners,
|
|
794
941
|
attributionHeaders: opts.attributionHeader,
|
|
@@ -927,7 +1074,7 @@ function registerResumeCommand(program) {
|
|
|
927
1074
|
|
|
928
1075
|
// packages/cli/src/commands/replay.ts
|
|
929
1076
|
async function replayScan(opts) {
|
|
930
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
1077
|
+
const { osecDB: osecDB2 } = await import("./dist-OLGNKDB2.js");
|
|
931
1078
|
const db = new osecDB2(opts.dbPath);
|
|
932
1079
|
const requestedScan = opts.scan;
|
|
933
1080
|
let scanRecord;
|
|
@@ -992,14 +1139,8 @@ async function replayScan(opts) {
|
|
|
992
1139
|
});
|
|
993
1140
|
}
|
|
994
1141
|
function registerReplayCommand(program) {
|
|
995
|
-
program.command("replay").description("
|
|
1142
|
+
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
1143
|
try {
|
|
997
|
-
const { isBunRuntime, canUseOpenTui } = await import("./runtime-HFFRUOPL.js");
|
|
998
|
-
if (isBunRuntime() && canUseOpenTui()) {
|
|
999
|
-
const { showOpenTuiReplay } = await import("./run-5T4Z3Q2D.js");
|
|
1000
|
-
await showOpenTuiReplay({ dbPath: opts.dbPath, scanId: opts.scan });
|
|
1001
|
-
return;
|
|
1002
|
-
}
|
|
1003
1144
|
await replayScan(opts);
|
|
1004
1145
|
} catch (err) {
|
|
1005
1146
|
console.error(
|
|
@@ -1015,12 +1156,6 @@ import { existsSync as existsSync2 } from "node:fs";
|
|
|
1015
1156
|
function registerHistoryCommand(program) {
|
|
1016
1157
|
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", "10").action(async (opts) => {
|
|
1017
1158
|
const limit2 = Number.parseInt(opts.limit ?? "10", 10);
|
|
1018
|
-
const { isBunRuntime, canUseOpenTui } = await import("./runtime-HFFRUOPL.js");
|
|
1019
|
-
if (opts.dbPath && isBunRuntime() && canUseOpenTui()) {
|
|
1020
|
-
const { showOpenTuiHistory } = await import("./run-5T4Z3Q2D.js");
|
|
1021
|
-
await showOpenTuiHistory({ dbPath: opts.dbPath, limit: limit2 });
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
1159
|
const dbPaths = opts.dbPath ? [opts.dbPath] : listOsecRunDatabasePaths();
|
|
1025
1160
|
const legacyDbPath = resolveOsecDbPath();
|
|
1026
1161
|
if (!opts.dbPath && existsSync2(legacyDbPath) && !dbPaths.includes(legacyDbPath)) {
|
|
@@ -1223,46 +1358,12 @@ function registerFindingsCommand(program) {
|
|
|
1223
1358
|
{ defaultLimit: "50" }
|
|
1224
1359
|
).option("--all", "Show raw finding rows instead of grouped fingerprints", false).action(async (opts, command) => {
|
|
1225
1360
|
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-HFFRUOPL.js");
|
|
1229
|
-
if (selectedDbPath && isBunRuntime() && canUseOpenTui()) {
|
|
1230
|
-
const { showOpenTuiFindings } = await import("./run-5T4Z3Q2D.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
1361
|
await renderFindingsList(resolved);
|
|
1244
1362
|
});
|
|
1245
1363
|
withFindingsListOptions(
|
|
1246
1364
|
findingsCmd.command("list").description("List findings from the database")
|
|
1247
1365
|
).action(async (opts, command) => {
|
|
1248
1366
|
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-HFFRUOPL.js");
|
|
1252
|
-
if (selectedDbPath && isBunRuntime() && canUseOpenTui()) {
|
|
1253
|
-
const { showOpenTuiFindings } = await import("./run-5T4Z3Q2D.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
1367
|
await renderFindingsList(resolved);
|
|
1267
1368
|
});
|
|
1268
1369
|
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 +1409,7 @@ function registerFindingsCommand(program) {
|
|
|
1308
1409
|
console.log(` ${source_default.dim(finding.evidenceAnalysis)}`);
|
|
1309
1410
|
}
|
|
1310
1411
|
{
|
|
1311
|
-
const { summarizeTriageProvenance, formatTriageProvenance } = await import("./dist-
|
|
1412
|
+
const { summarizeTriageProvenance, formatTriageProvenance } = await import("./dist-6RNAVFAY.js");
|
|
1312
1413
|
const provenance = summarizeTriageProvenance({
|
|
1313
1414
|
...finding,
|
|
1314
1415
|
layerVerdicts: parseLayerVerdicts(finding.layerVerdicts)
|
|
@@ -1371,7 +1472,7 @@ function positiveAmount(value) {
|
|
|
1371
1472
|
return parsed;
|
|
1372
1473
|
}
|
|
1373
1474
|
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) => {
|
|
1475
|
+
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
1476
|
if (options.format !== "json") throw new InvalidArgumentError("--format must be json.");
|
|
1376
1477
|
if (!["api", "auto"].includes(options.runtime)) throw new InvalidArgumentError("--runtime must be api or auto.");
|
|
1377
1478
|
if (!options.testCommand.trim()) throw new InvalidArgumentError("--test-command cannot be blank.");
|
|
@@ -1392,6 +1493,7 @@ function registerSecureCommand(program) {
|
|
|
1392
1493
|
try {
|
|
1393
1494
|
const result = await runSecureProject({
|
|
1394
1495
|
repoRoot: repo,
|
|
1496
|
+
sourcePath: options.sourcePath,
|
|
1395
1497
|
stateDir,
|
|
1396
1498
|
testCommand: options.testCommand,
|
|
1397
1499
|
setupCommand: options.setupCommand,
|
|
@@ -1428,7 +1530,7 @@ import { existsSync as existsSync3 } from "node:fs";
|
|
|
1428
1530
|
var VALID_BUILD_SYSTEMS = /* @__PURE__ */ new Set(["autotools", "cmake", "meson", "auto"]);
|
|
1429
1531
|
var VALID_SANITIZERS = /* @__PURE__ */ new Set(["asan", "ubsan", "msan"]);
|
|
1430
1532
|
async function runHarnessTier2(args2) {
|
|
1431
|
-
const { buildTier2Harness, extractCorpus } = await import("./dist-
|
|
1533
|
+
const { buildTier2Harness, extractCorpus } = await import("./dist-6RNAVFAY.js");
|
|
1432
1534
|
const repoAbs = resolve2(args2.repo);
|
|
1433
1535
|
if (!existsSync3(repoAbs)) {
|
|
1434
1536
|
throw new Error(`Tier-2: repo path '${repoAbs}' does not exist.`);
|
|
@@ -1524,7 +1626,7 @@ async function runHarnessTier3(args2) {
|
|
|
1524
1626
|
buildTier2Harness,
|
|
1525
1627
|
extractCorpus,
|
|
1526
1628
|
runTier3Validation
|
|
1527
|
-
} = await import("./dist-
|
|
1629
|
+
} = await import("./dist-6RNAVFAY.js");
|
|
1528
1630
|
const repoAbs = resolve3(args2.repo);
|
|
1529
1631
|
if (!existsSync4(repoAbs)) {
|
|
1530
1632
|
throw new Error(`Tier-3: repo path '${repoAbs}' does not exist.`);
|
|
@@ -1642,7 +1744,7 @@ function normalizeReviewProfile(value, flag) {
|
|
|
1642
1744
|
);
|
|
1643
1745
|
}
|
|
1644
1746
|
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("--
|
|
1747
|
+
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
1748
|
"--profile <profile>",
|
|
1647
1749
|
"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
1750
|
"default"
|
|
@@ -1744,7 +1846,7 @@ function registerReviewCommand(program) {
|
|
|
1744
1846
|
let seedFindings;
|
|
1745
1847
|
const seedPath = opts.seedFindings;
|
|
1746
1848
|
if (seedPath) {
|
|
1747
|
-
const { readSeedFindings } = await import("./dist-
|
|
1849
|
+
const { readSeedFindings } = await import("./dist-6RNAVFAY.js");
|
|
1748
1850
|
seedFindings = readSeedFindings(seedPath);
|
|
1749
1851
|
console.log(
|
|
1750
1852
|
source_default.cyan(
|
|
@@ -1760,7 +1862,7 @@ function registerReviewCommand(program) {
|
|
|
1760
1862
|
);
|
|
1761
1863
|
}
|
|
1762
1864
|
if (fixCommit) {
|
|
1763
|
-
const { huntAppFixVariants, appFixVariantsToSeedFindings } = await import("./dist-
|
|
1865
|
+
const { huntAppFixVariants, appFixVariantsToSeedFindings } = await import("./dist-6RNAVFAY.js");
|
|
1764
1866
|
const result = huntAppFixVariants({
|
|
1765
1867
|
repoPath: repo,
|
|
1766
1868
|
fixCommit
|
|
@@ -1874,7 +1976,6 @@ function registerReviewCommand(program) {
|
|
|
1874
1976
|
conversation: opts.conversation,
|
|
1875
1977
|
priorFindings,
|
|
1876
1978
|
npmDynamicDiscovery: opts.npmDynamic,
|
|
1877
|
-
tui: opts.tui,
|
|
1878
1979
|
seedFindings,
|
|
1879
1980
|
seedOnly: opts.seedOnly,
|
|
1880
1981
|
emit,
|
|
@@ -2035,7 +2136,7 @@ function registerAuditCommand(program) {
|
|
|
2035
2136
|
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
2137
|
"--package-version <version>",
|
|
2037
2138
|
"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("--
|
|
2139
|
+
).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
2140
|
const ecosystem = (opts.ecosystem ?? "npm").trim().toLowerCase();
|
|
2040
2141
|
if (!SUPPORTED_AUDIT_ECOSYSTEMS.has(ecosystem)) {
|
|
2041
2142
|
throw new Error(`Unsupported ecosystem '${ecosystem}'. Valid: npm, pypi, cargo, oci.`);
|
|
@@ -2064,8 +2165,7 @@ function registerAuditCommand(program) {
|
|
|
2064
2165
|
model: opts.model,
|
|
2065
2166
|
// Read in priority: --package-version, --pkg-version, --ver.
|
|
2066
2167
|
packageVersion: opts.packageVersion ?? opts.pkgVersion ?? opts.ver,
|
|
2067
|
-
costCeilingUsd
|
|
2068
|
-
tui: opts.tui
|
|
2168
|
+
costCeilingUsd
|
|
2069
2169
|
});
|
|
2070
2170
|
});
|
|
2071
2171
|
}
|
|
@@ -2073,12 +2173,7 @@ function registerAuditCommand(program) {
|
|
|
2073
2173
|
// packages/cli/src/commands/doctor.ts
|
|
2074
2174
|
function registerDoctorCommand(program) {
|
|
2075
2175
|
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-5T4Z3Q2D.js");
|
|
2079
|
-
await showOpenTuiDoctor();
|
|
2080
|
-
return;
|
|
2081
|
-
}
|
|
2176
|
+
const { getRuntimeMetadata } = await import("./runtime-W6JNDQRO.js");
|
|
2082
2177
|
const { hasApiKey, availableRuntimes, apiRuntime } = await getRuntimeAvailability();
|
|
2083
2178
|
const runtime = getRuntimeMetadata();
|
|
2084
2179
|
const nodeMajor = Number.parseInt(process.versions.node.split(".")[0] ?? "0", 10);
|
|
@@ -2114,8 +2209,9 @@ function registerDoctorCommand(program) {
|
|
|
2114
2209
|
|
|
2115
2210
|
// packages/cli/src/commands/tui.ts
|
|
2116
2211
|
function registerTuiCommand(program) {
|
|
2117
|
-
program.command("tui").alias("watch").description("Retired terminal UI; use 0 web for interactive work").action(() => {
|
|
2118
|
-
console.
|
|
2212
|
+
program.command("tui", { hidden: true }).alias("watch").description("Retired terminal UI; use 0 web for interactive work").action(() => {
|
|
2213
|
+
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.");
|
|
2214
|
+
process.exitCode = 2;
|
|
2119
2215
|
});
|
|
2120
2216
|
}
|
|
2121
2217
|
|
|
@@ -2123,7 +2219,7 @@ function registerTuiCommand(program) {
|
|
|
2123
2219
|
import { randomUUID } from "node:crypto";
|
|
2124
2220
|
import { isAbsolute } from "node:path";
|
|
2125
2221
|
|
|
2126
|
-
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@
|
|
2222
|
+
// node_modules/.pnpm/@modelcontextprotocol+sdk@1.32.1_zod@4.6.6/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
2127
2223
|
import process2 from "node:process";
|
|
2128
2224
|
var StdioServerTransport = class {
|
|
2129
2225
|
constructor(_stdin = process2.stdin, _stdout = process2.stdout, options) {
|
|
@@ -2180,12 +2276,12 @@ var StdioServerTransport = class {
|
|
|
2180
2276
|
this.onclose?.();
|
|
2181
2277
|
}
|
|
2182
2278
|
send(message) {
|
|
2183
|
-
return new Promise((
|
|
2279
|
+
return new Promise((resolve29) => {
|
|
2184
2280
|
const json = serializeMessage(message);
|
|
2185
2281
|
if (this._stdout.write(json)) {
|
|
2186
|
-
|
|
2282
|
+
resolve29();
|
|
2187
2283
|
} else {
|
|
2188
|
-
this._stdout.once("drain",
|
|
2284
|
+
this._stdout.once("drain", resolve29);
|
|
2189
2285
|
}
|
|
2190
2286
|
});
|
|
2191
2287
|
}
|
|
@@ -2293,7 +2389,7 @@ function zodForParam(param) {
|
|
|
2293
2389
|
} else if (param.type === "boolean") {
|
|
2294
2390
|
schema = external_exports.boolean();
|
|
2295
2391
|
} else if (param.type === "object") {
|
|
2296
|
-
schema = external_exports.record(external_exports.unknown());
|
|
2392
|
+
schema = external_exports.record(external_exports.string(), external_exports.unknown());
|
|
2297
2393
|
} else {
|
|
2298
2394
|
schema = external_exports.string();
|
|
2299
2395
|
}
|
|
@@ -2325,9 +2421,9 @@ function toolResultToMcp(result) {
|
|
|
2325
2421
|
return toTextResult(text2, { success: true, output: result.output });
|
|
2326
2422
|
}
|
|
2327
2423
|
function withToolTimeout(task, timeoutMs) {
|
|
2328
|
-
return new Promise((
|
|
2424
|
+
return new Promise((resolve29) => {
|
|
2329
2425
|
const timer = setTimeout(() => {
|
|
2330
|
-
|
|
2426
|
+
resolve29({
|
|
2331
2427
|
success: false,
|
|
2332
2428
|
output: null,
|
|
2333
2429
|
error: `MCP tool timed out after ${timeoutMs}ms`
|
|
@@ -2336,11 +2432,11 @@ function withToolTimeout(task, timeoutMs) {
|
|
|
2336
2432
|
task.then(
|
|
2337
2433
|
(result) => {
|
|
2338
2434
|
clearTimeout(timer);
|
|
2339
|
-
|
|
2435
|
+
resolve29(result);
|
|
2340
2436
|
},
|
|
2341
2437
|
(error) => {
|
|
2342
2438
|
clearTimeout(timer);
|
|
2343
|
-
|
|
2439
|
+
resolve29({
|
|
2344
2440
|
success: false,
|
|
2345
2441
|
output: null,
|
|
2346
2442
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -2372,7 +2468,7 @@ function clampRateLimitToPosture(cfg, posture) {
|
|
|
2372
2468
|
}
|
|
2373
2469
|
var workflowInputsSchema = SecurityWorkflowBindingsSchema;
|
|
2374
2470
|
async function registerWorkflowTools(server, selected, opts) {
|
|
2375
|
-
const runtime = opts.backend || opts.engineUrl ? await (await import("./remote-workflow-runtime-
|
|
2471
|
+
const runtime = opts.backend || opts.engineUrl ? await (await import("./remote-workflow-runtime-6CEVRZXS.js")).createRemoteWorkflowRuntime({ backendId: opts.backend, configPath: opts.backendsConfig, sessionId: opts.session, engineUrl: opts.engineUrl, engineTokenEnv: opts.engineTokenEnv }) : await (await import("./workflow-runtime-PLB32XC3.js")).createCliWorkflowRuntime({
|
|
2376
2472
|
ownerId: `mcp:${randomUUID()}`,
|
|
2377
2473
|
workspace: opts.workspace,
|
|
2378
2474
|
target: opts.target,
|
|
@@ -2396,13 +2492,13 @@ async function registerWorkflowTools(server, selected, opts) {
|
|
|
2396
2492
|
{ 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
2493
|
{ 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
2494
|
{ 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) },
|
|
2495
|
+
{ 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
2496
|
{ 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
2497
|
{ name: "get_session", description: "Read an existing engine session.", schema: external_exports.object({ sessionId: id }).strict(), run: (args2) => sessionRuntime.getSession(args2.sessionId) },
|
|
2402
2498
|
{ 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
2499
|
{ 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
2500
|
{ 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) },
|
|
2501
|
+
{ 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
2502
|
{ name: "list_saved_sessions", description: "List retained session snapshots on the engine.", schema: external_exports.object({}).strict(), run: () => sessionRuntime.listSavedSessions() },
|
|
2407
2503
|
{ 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
2504
|
{ name: "list_templates", description: "List workflow templates and supported target types.", schema: external_exports.object({}).strict(), run: () => runtime.listTemplates() },
|
|
@@ -2410,7 +2506,7 @@ async function registerWorkflowTools(server, selected, opts) {
|
|
|
2410
2506
|
{ 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
2507
|
{ name: "list_workflows", description: "List saved workflow definitions.", schema: external_exports.object({}).strict(), run: () => runtime.listWorkflows() },
|
|
2412
2508
|
{ 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) },
|
|
2509
|
+
{ 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
2510
|
{ 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
2511
|
if (Boolean(args2.templateId) === Boolean(args2.workflowId)) throw new Error("Select exactly one templateId or workflowId.");
|
|
2416
2512
|
if (args2.workflowId && !args2.revision) throw new Error("Saved workflow runs require a pinned revision.");
|
|
@@ -2670,11 +2766,11 @@ function rowToFinding(row) {
|
|
|
2670
2766
|
};
|
|
2671
2767
|
}
|
|
2672
2768
|
async function openStore(dbPath) {
|
|
2673
|
-
const { MemoryStore } = await import("./dist-
|
|
2769
|
+
const { MemoryStore } = await import("./dist-6RNAVFAY.js");
|
|
2674
2770
|
return new MemoryStore(dbPath);
|
|
2675
2771
|
}
|
|
2676
2772
|
async function loadFinding2(dbPath, findingId) {
|
|
2677
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
2773
|
+
const { osecDB: osecDB2 } = await import("./dist-OLGNKDB2.js");
|
|
2678
2774
|
const db = new osecDB2(dbPath);
|
|
2679
2775
|
try {
|
|
2680
2776
|
const rows = db.listFindings({ limit: 5e3 });
|
|
@@ -2749,7 +2845,7 @@ async function runMemoryRemove(id, dbPath) {
|
|
|
2749
2845
|
async function runMarkFp(findingId, opts) {
|
|
2750
2846
|
const row = await loadFinding2(opts.dbPath, findingId);
|
|
2751
2847
|
const finding = rowToFinding(row);
|
|
2752
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
2848
|
+
const { osecDB: osecDB2 } = await import("./dist-OLGNKDB2.js");
|
|
2753
2849
|
const db = new osecDB2(opts.dbPath);
|
|
2754
2850
|
try {
|
|
2755
2851
|
db.updateFindingTriage(row.id, "suppressed", opts.reason);
|
|
@@ -6464,7 +6560,7 @@ function registerIngestCommand(program) {
|
|
|
6464
6560
|
reviewKernelCrashSubsystems,
|
|
6465
6561
|
verifyStandaloneKernelReproducer,
|
|
6466
6562
|
verifyKernelCrash
|
|
6467
|
-
} = await import("./dist-
|
|
6563
|
+
} = await import("./dist-6RNAVFAY.js");
|
|
6468
6564
|
let kernelBuild;
|
|
6469
6565
|
if (opts.kernelTree) {
|
|
6470
6566
|
kernelBuild = prepareKernelVmArtifacts({
|
|
@@ -6887,7 +6983,7 @@ function registerKernelCommand(program) {
|
|
|
6887
6983
|
checkAlreadyFixed,
|
|
6888
6984
|
rankKernelHypothesesWithJev,
|
|
6889
6985
|
verifyStaticKernelFinding
|
|
6890
|
-
} = await import("./dist-
|
|
6986
|
+
} = await import("./dist-6RNAVFAY.js");
|
|
6891
6987
|
const noveltyExcluded = opts.upstreamTree ? findings.flatMap((finding) => {
|
|
6892
6988
|
const path = finding.reviewAnnotation?.path ?? finding.evidence.request.match(/([^\s:]+\.[ch]):\d+/)?.[1];
|
|
6893
6989
|
if (!path) return [];
|
|
@@ -6934,7 +7030,7 @@ function registerKernelCommand(program) {
|
|
|
6934
7030
|
try {
|
|
6935
7031
|
const config = jevConfigFromEnvironment("kernel", process.env);
|
|
6936
7032
|
if (!config) throw new Error("Jev commit prepass requires ZERO_JEV_FEATURES=kernel and a configured provider");
|
|
6937
|
-
const { rankKernelCommitsWithJev } = await import("./dist-
|
|
7033
|
+
const { rankKernelCommitsWithJev } = await import("./dist-6RNAVFAY.js");
|
|
6938
7034
|
const result = await rankKernelCommitsWithJev({
|
|
6939
7035
|
tree: opts.tree,
|
|
6940
7036
|
evaluator: createJevEvaluator(config),
|
|
@@ -6958,7 +7054,7 @@ function registerKernelCommand(program) {
|
|
|
6958
7054
|
try {
|
|
6959
7055
|
const config = jevConfigFromEnvironment("kernel", process.env);
|
|
6960
7056
|
if (!config) throw new Error("Jev source prepass requires ZERO_JEV_FEATURES=kernel and a configured provider");
|
|
6961
|
-
const { runKernelSourceJevPrepass } = await import("./dist-
|
|
7057
|
+
const { runKernelSourceJevPrepass } = await import("./dist-6RNAVFAY.js");
|
|
6962
7058
|
const result = await runKernelSourceJevPrepass({
|
|
6963
7059
|
tree: opts.tree,
|
|
6964
7060
|
subtree: opts.subtree,
|
|
@@ -6992,7 +7088,7 @@ function registerKernelCommand(program) {
|
|
|
6992
7088
|
if (crashes.length === 0) throw new Error("Crash input must be a CrashRecord[] or an object with a crashes array");
|
|
6993
7089
|
const records = crashes.filter((c) => !!c && typeof c === "object" && "id" in c && "summary" in c && typeof c.id === "string" && typeof c.summary === "string");
|
|
6994
7090
|
if (records.length !== crashes.length) throw new Error("Every crash record requires string id and summary fields");
|
|
6995
|
-
const { rankCrashesWithJev, crashSummaryFromTriage } = await import("./dist-
|
|
7091
|
+
const { rankCrashesWithJev, crashSummaryFromTriage } = await import("./dist-6RNAVFAY.js");
|
|
6996
7092
|
const result = await rankCrashesWithJev(
|
|
6997
7093
|
records,
|
|
6998
7094
|
createJevEvaluator(config)
|
|
@@ -7020,7 +7116,7 @@ function registerKernelCommand(program) {
|
|
|
7020
7116
|
const details = parsePositiveInt(opts.details, "--details", 100);
|
|
7021
7117
|
const detailDelayMs = parsePositiveInt(opts.detailDelay, "--detail-delay", 5e3);
|
|
7022
7118
|
const subsystems = opts.subsystems.split(",").map((value) => value.trim()).filter(Boolean);
|
|
7023
|
-
const { defaultSyzbotFetcher, mineSyzbotQueue, toHuntCandidates } = await import("./dist-
|
|
7119
|
+
const { defaultSyzbotFetcher, mineSyzbotQueue, toHuntCandidates } = await import("./dist-6RNAVFAY.js");
|
|
7024
7120
|
const result = await mineSyzbotQueue({
|
|
7025
7121
|
fetch: defaultSyzbotFetcher,
|
|
7026
7122
|
fetchDetail: defaultSyzbotFetcher,
|
|
@@ -7078,7 +7174,7 @@ function registerKernelCommand(program) {
|
|
|
7078
7174
|
`Invalid output format '${opts.output}'. Valid: ${VALID_OUTPUT_FORMATS2.join(", ")}`
|
|
7079
7175
|
);
|
|
7080
7176
|
}
|
|
7081
|
-
const { runKernelVariantHunt } = await import("./dist-
|
|
7177
|
+
const { runKernelVariantHunt } = await import("./dist-6RNAVFAY.js");
|
|
7082
7178
|
const report = await runKernelVariantHunt({
|
|
7083
7179
|
tree: opts.tree,
|
|
7084
7180
|
advisory: opts.advisory,
|
|
@@ -7181,7 +7277,7 @@ function resolveOutputDir(opts, scanId) {
|
|
|
7181
7277
|
return join9(homedir2(), "0", "disclosures", `scan-${scanId.slice(0, 8)}`);
|
|
7182
7278
|
}
|
|
7183
7279
|
async function disclose(findingId, opts) {
|
|
7184
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
7280
|
+
const { osecDB: osecDB2 } = await import("./dist-OLGNKDB2.js");
|
|
7185
7281
|
const db = new osecDB2(opts.dbPath);
|
|
7186
7282
|
try {
|
|
7187
7283
|
let routeDroppedFinding2 = function(args2) {
|
|
@@ -7633,7 +7729,7 @@ async function runExploit(opts) {
|
|
|
7633
7729
|
classifyPrimitiveFromDmesg,
|
|
7634
7730
|
describeKernelPrimitive,
|
|
7635
7731
|
runWeaponization
|
|
7636
|
-
} = await import("./dist-
|
|
7732
|
+
} = await import("./dist-6RNAVFAY.js");
|
|
7637
7733
|
const rawFinding = readJson(opts.findingPath, "finding");
|
|
7638
7734
|
let finding;
|
|
7639
7735
|
try {
|
|
@@ -7696,7 +7792,7 @@ async function runExploit(opts) {
|
|
|
7696
7792
|
}
|
|
7697
7793
|
async function exploitAction(opts) {
|
|
7698
7794
|
if (opts.agent) {
|
|
7699
|
-
const { agentFromExploitOpts } = await import("./exploit-agent-
|
|
7795
|
+
const { agentFromExploitOpts } = await import("./exploit-agent-M3KUMZJH.js");
|
|
7700
7796
|
process.exitCode = await agentFromExploitOpts({
|
|
7701
7797
|
...opts.task ? { task: opts.task } : {},
|
|
7702
7798
|
...opts.flagPath ? { flagPath: opts.flagPath } : {},
|
|
@@ -7711,7 +7807,7 @@ async function exploitAction(opts) {
|
|
|
7711
7807
|
return;
|
|
7712
7808
|
}
|
|
7713
7809
|
if (opts.autoclimb) {
|
|
7714
|
-
const { autoclimbFromExploitOpts } = await import("./exploit-autoclimb-
|
|
7810
|
+
const { autoclimbFromExploitOpts } = await import("./exploit-autoclimb-QTTWC5WM.js");
|
|
7715
7811
|
process.exitCode = await autoclimbFromExploitOpts({
|
|
7716
7812
|
...opts.bugSpec ? { bugSpec: opts.bugSpec } : {},
|
|
7717
7813
|
...opts.bootScript ? { bootScript: opts.bootScript } : {},
|
|
@@ -7725,7 +7821,7 @@ async function exploitAction(opts) {
|
|
|
7725
7821
|
throw new Error("missing required flag: --finding <path>");
|
|
7726
7822
|
}
|
|
7727
7823
|
if (opts.climb) {
|
|
7728
|
-
const { runClimb } = await import("./exploit-climb-
|
|
7824
|
+
const { runClimb } = await import("./exploit-climb-E4KDELTN.js");
|
|
7729
7825
|
let loopBoots = 8;
|
|
7730
7826
|
if (opts.loopBoots !== void 0) {
|
|
7731
7827
|
loopBoots = parseInt(opts.loopBoots, 10);
|
|
@@ -7898,7 +7994,7 @@ async function runHunt(opts) {
|
|
|
7898
7994
|
makeLloreJudge,
|
|
7899
7995
|
makeHuntProveStage,
|
|
7900
7996
|
prepare: prepare2
|
|
7901
|
-
} = await import("./dist-
|
|
7997
|
+
} = await import("./dist-6RNAVFAY.js");
|
|
7902
7998
|
const log = opts.log ?? (() => {
|
|
7903
7999
|
});
|
|
7904
8000
|
const runtime = opts.runtime ?? "api";
|
|
@@ -8246,7 +8342,7 @@ function parseWitnessMode(raw) {
|
|
|
8246
8342
|
}
|
|
8247
8343
|
async function recencyAction(opts) {
|
|
8248
8344
|
if (!opts.tree) throw new Error("missing required flag: --tree <kernel source tree>");
|
|
8249
|
-
const { runRecencyHunt, renderRecencyReportMarkdown } = await import("./dist-
|
|
8345
|
+
const { runRecencyHunt, renderRecencyReportMarkdown } = await import("./dist-6RNAVFAY.js");
|
|
8250
8346
|
const tree = resolve14(opts.tree);
|
|
8251
8347
|
const runtime = opts.runtime ?? "api";
|
|
8252
8348
|
const modelDir = opts.modelDir ? resolve14(opts.modelDir) : join10(tree, ".recency-models");
|
|
@@ -8323,9 +8419,271 @@ function registerRecencyHuntCommand(program) {
|
|
|
8323
8419
|
});
|
|
8324
8420
|
}
|
|
8325
8421
|
|
|
8422
|
+
// packages/cli/src/commands/lens-synth.ts
|
|
8423
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
8424
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
8425
|
+
import { resolve as resolve15 } from "node:path";
|
|
8426
|
+
function isRecord(value) {
|
|
8427
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8428
|
+
}
|
|
8429
|
+
function parseFixtures(value, label) {
|
|
8430
|
+
if (value === void 0) return [];
|
|
8431
|
+
if (!Array.isArray(value)) throw new Error(`${label} must be an array`);
|
|
8432
|
+
return value.map((entry, i) => {
|
|
8433
|
+
if (!isRecord(entry)) throw new Error(`${label}[${i}] must be an object`);
|
|
8434
|
+
const id = entry.id;
|
|
8435
|
+
const path = entry.path;
|
|
8436
|
+
if (typeof id !== "string" || id.trim() === "") throw new Error(`${label}[${i}].id must be a non-empty string`);
|
|
8437
|
+
if (typeof path !== "string" || path.trim() === "") throw new Error(`${label}[${i}].path must be a non-empty string`);
|
|
8438
|
+
const fixture = { id, path };
|
|
8439
|
+
if (typeof entry.note === "string") fixture.note = entry.note;
|
|
8440
|
+
if (typeof entry.expectedCwe === "string") fixture.expectedCwe = entry.expectedCwe;
|
|
8441
|
+
if (typeof entry.expectedFile === "string") fixture.expectedFile = entry.expectedFile;
|
|
8442
|
+
if (typeof entry.expectedLine === "number" && Number.isFinite(entry.expectedLine)) {
|
|
8443
|
+
fixture.expectedLine = entry.expectedLine;
|
|
8444
|
+
}
|
|
8445
|
+
if (Array.isArray(entry.expectedRange) && entry.expectedRange.length === 2 && typeof entry.expectedRange[0] === "number" && typeof entry.expectedRange[1] === "number") {
|
|
8446
|
+
fixture.expectedRange = [entry.expectedRange[0], entry.expectedRange[1]];
|
|
8447
|
+
}
|
|
8448
|
+
if (typeof entry.contentDigest === "string") fixture.contentDigest = entry.contentDigest;
|
|
8449
|
+
if (typeof entry.cleanProvenance === "string") fixture.cleanProvenance = entry.cleanProvenance;
|
|
8450
|
+
return fixture;
|
|
8451
|
+
});
|
|
8452
|
+
}
|
|
8453
|
+
function parseMissInputFile(raw) {
|
|
8454
|
+
if (!isRecord(raw)) throw new Error("miss-input must be a JSON object");
|
|
8455
|
+
const missesRaw = isRecord(raw.misses) ? raw.misses : {};
|
|
8456
|
+
const corpusRaw = isRecord(raw.corpus) ? raw.corpus : {};
|
|
8457
|
+
const misses = {
|
|
8458
|
+
...Array.isArray(missesRaw.confirmedMisses) ? { confirmedMisses: missesRaw.confirmedMisses } : {},
|
|
8459
|
+
...Array.isArray(missesRaw.incompleteCoverage) ? { incompleteCoverage: missesRaw.incompleteCoverage } : {},
|
|
8460
|
+
...Array.isArray(missesRaw.curatedCandidates) ? { curatedCandidates: missesRaw.curatedCandidates } : {}
|
|
8461
|
+
};
|
|
8462
|
+
const heldOutFixtures = parseFixtures(corpusRaw.heldOut, "corpus.heldOut");
|
|
8463
|
+
const corpus = {
|
|
8464
|
+
positives: parseFixtures(corpusRaw.positives, "corpus.positives"),
|
|
8465
|
+
negativeControls: parseFixtures(corpusRaw.negativeControls, "corpus.negativeControls"),
|
|
8466
|
+
...heldOutFixtures.length > 0 ? { heldOut: heldOutFixtures } : {},
|
|
8467
|
+
...typeof corpusRaw.baselineDigest === "string" ? { baselineDigest: corpusRaw.baselineDigest } : {}
|
|
8468
|
+
};
|
|
8469
|
+
if (corpus.positives.length === 0) {
|
|
8470
|
+
throw new Error("corpus.positives must contain at least one fixture (the seeded miss) \u2014 the loop is fail-closed without it");
|
|
8471
|
+
}
|
|
8472
|
+
if (corpus.negativeControls.length === 0) {
|
|
8473
|
+
throw new Error("corpus.negativeControls must contain at least one fixture \u2014 the loop cannot measure FP regression without it");
|
|
8474
|
+
}
|
|
8475
|
+
if (!corpus.heldOut || corpus.heldOut.length === 0) {
|
|
8476
|
+
throw new Error("corpus.heldOut must contain at least one fixture \u2014 held-out positives are required to demonstrate generalisation beyond development misses");
|
|
8477
|
+
}
|
|
8478
|
+
return { misses, corpus };
|
|
8479
|
+
}
|
|
8480
|
+
async function harvestBenchMisses(fromBench, manifestPath) {
|
|
8481
|
+
const ledger = await loadLedger(resolve15(fromBench));
|
|
8482
|
+
const entry = lastGreen(ledger) ?? ledger.entries[ledger.entries.length - 1];
|
|
8483
|
+
if (!entry) throw new Error(`--from-bench: ledger ${fromBench} has no entries to harvest`);
|
|
8484
|
+
const manifest = await loadManifest(resolve15(manifestPath));
|
|
8485
|
+
const result = harvestMissesFromLedgerEntry(entry, manifest);
|
|
8486
|
+
return { misses: result.misses, result };
|
|
8487
|
+
}
|
|
8488
|
+
function trialCount(value) {
|
|
8489
|
+
const count = value ?? 2;
|
|
8490
|
+
if (!Number.isSafeInteger(count) || count < 2 || count > 10) throw new Error("--trials must be an integer between 2 and 10");
|
|
8491
|
+
return count;
|
|
8492
|
+
}
|
|
8493
|
+
async function runLensSynthesisInput(input, opts, deps = {}) {
|
|
8494
|
+
const trials = trialCount(opts.trials);
|
|
8495
|
+
const log = deps.log ?? (() => {
|
|
8496
|
+
});
|
|
8497
|
+
const probe = deps.probe ?? makeFinderLensProbe({ log });
|
|
8498
|
+
return runLensSynthesisLoop(input, {
|
|
8499
|
+
...deps.model ? { model: deps.model } : {},
|
|
8500
|
+
...opts.model ? { modelId: opts.model } : {},
|
|
8501
|
+
probe,
|
|
8502
|
+
...opts.registry ? { registryPath: resolve15(opts.registry) } : {},
|
|
8503
|
+
maxRegistrations: opts.maxRegister ?? 1,
|
|
8504
|
+
dryRun: !opts.promote,
|
|
8505
|
+
trials,
|
|
8506
|
+
...opts.signal ? { signal: opts.signal } : {},
|
|
8507
|
+
log
|
|
8508
|
+
});
|
|
8509
|
+
}
|
|
8510
|
+
async function runLensSynthCommand(opts, deps = {}) {
|
|
8511
|
+
const raw = JSON.parse(readFileSync13(resolve15(opts.missInput), "utf8"));
|
|
8512
|
+
let input = parseMissInputFile(raw);
|
|
8513
|
+
if (opts.fromBench) {
|
|
8514
|
+
if (!opts.manifest) throw new Error("--from-bench requires --manifest");
|
|
8515
|
+
const { misses } = await harvestBenchMisses(opts.fromBench, opts.manifest);
|
|
8516
|
+
input = { ...input, misses: mergeHarvestedMisses(input.misses, misses) };
|
|
8517
|
+
deps.log?.(`[lens-synth] harvested ${misses.length} bench miss(es) from ${opts.fromBench}`);
|
|
8518
|
+
}
|
|
8519
|
+
return runLensSynthesisInput(input, opts, deps);
|
|
8520
|
+
}
|
|
8521
|
+
async function watchLensSynthCommand(opts, deps = {}) {
|
|
8522
|
+
const inputPath = resolve15(opts.missInput);
|
|
8523
|
+
const log = deps.log ?? (() => {
|
|
8524
|
+
});
|
|
8525
|
+
const requestedInterval = opts.pollIntervalMs ?? 2e3;
|
|
8526
|
+
const pollIntervalMs = Number.isFinite(requestedInterval) ? Math.max(100, Math.floor(requestedInterval)) : 2e3;
|
|
8527
|
+
const sleep = deps.sleep ?? ((milliseconds) => new Promise((done) => setTimeout(done, milliseconds)));
|
|
8528
|
+
let previousRevision;
|
|
8529
|
+
while (!deps.signal?.aborted) {
|
|
8530
|
+
try {
|
|
8531
|
+
const bytes = readFileSync13(inputPath);
|
|
8532
|
+
const revision2 = createHash5("sha256").update(bytes).digest("hex");
|
|
8533
|
+
if (revision2 !== previousRevision) {
|
|
8534
|
+
previousRevision = revision2;
|
|
8535
|
+
const input = parseMissInputFile(JSON.parse(bytes.toString("utf8")));
|
|
8536
|
+
const result = await runLensSynthesisInput(input, opts, deps);
|
|
8537
|
+
deps.onResult?.(result);
|
|
8538
|
+
}
|
|
8539
|
+
} catch (cause) {
|
|
8540
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
8541
|
+
const revision2 = `error:${error.name}:${error.message}`;
|
|
8542
|
+
if (revision2 !== previousRevision) {
|
|
8543
|
+
previousRevision = revision2;
|
|
8544
|
+
if (deps.onError) deps.onError(error);
|
|
8545
|
+
else log(`[lens-synth] input revision rejected: ${error.message}`);
|
|
8546
|
+
}
|
|
8547
|
+
}
|
|
8548
|
+
if (deps.signal?.aborted) return;
|
|
8549
|
+
const signal = deps.signal;
|
|
8550
|
+
if (!signal) {
|
|
8551
|
+
await sleep(pollIntervalMs);
|
|
8552
|
+
continue;
|
|
8553
|
+
}
|
|
8554
|
+
if (signal.aborted) return;
|
|
8555
|
+
await new Promise((resume) => {
|
|
8556
|
+
const onAbort = () => {
|
|
8557
|
+
signal.removeEventListener("abort", onAbort);
|
|
8558
|
+
resume();
|
|
8559
|
+
};
|
|
8560
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
8561
|
+
void sleep(pollIntervalMs).then(() => {
|
|
8562
|
+
signal.removeEventListener("abort", onAbort);
|
|
8563
|
+
resume();
|
|
8564
|
+
});
|
|
8565
|
+
});
|
|
8566
|
+
}
|
|
8567
|
+
}
|
|
8568
|
+
function formatLensSynthResult(result, dryRun2) {
|
|
8569
|
+
const lines = [
|
|
8570
|
+
`captured ${result.candidatesCaptured} miss candidate(s) \u2192 ${result.clusters} cluster(s) \u2192 ${result.synthesized.length} synthesized`
|
|
8571
|
+
];
|
|
8572
|
+
for (const validation of result.validations) {
|
|
8573
|
+
lines.push(` validate ${validation.lensId}: ${validation.passed ? "CHAMPION" : "rejected"} \u2014 ${validation.reason}`);
|
|
8574
|
+
}
|
|
8575
|
+
if (dryRun2) {
|
|
8576
|
+
lines.push(`dry-run: ${result.validations.filter((validation) => validation.passed).length} champion(s) would register (nothing written)`);
|
|
8577
|
+
} else {
|
|
8578
|
+
lines.push(
|
|
8579
|
+
result.registered.length > 0 ? `REGISTERED ${result.registered.length} lens(es): ${result.registered.map((registered) => registered.uid).join(", ")}` : "registered 0 lenses"
|
|
8580
|
+
);
|
|
8581
|
+
}
|
|
8582
|
+
for (const rejected of result.rejected) lines.push(` rejected ${rejected.id}: ${rejected.reason}`);
|
|
8583
|
+
for (const warning of result.warnings) lines.push(` warning: ${warning}`);
|
|
8584
|
+
return lines.join("\n");
|
|
8585
|
+
}
|
|
8586
|
+
function formatLensRegistryStatus(status) {
|
|
8587
|
+
const lines = [
|
|
8588
|
+
`registry: ${status.path}`,
|
|
8589
|
+
`state: ${status.valid ? "valid" : "INVALID"}`,
|
|
8590
|
+
`exists: ${status.exists ? "yes" : "no"}`,
|
|
8591
|
+
`active lenses: ${status.activeLensCount}`,
|
|
8592
|
+
`ledger entries: ${status.ledgerEntries}`,
|
|
8593
|
+
`unbound archetypes: ${status.unboundArchetypes}`
|
|
8594
|
+
];
|
|
8595
|
+
if (status.error) lines.push(`error: ${status.error}`);
|
|
8596
|
+
return lines.join("\n");
|
|
8597
|
+
}
|
|
8598
|
+
function registerLensSynthCommand(program) {
|
|
8599
|
+
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) => {
|
|
8600
|
+
try {
|
|
8601
|
+
const registry = opts.registry ? resolve15(opts.registry) : void 0;
|
|
8602
|
+
if (opts.status && opts.rollback) throw new Error("--status and --rollback cannot be combined");
|
|
8603
|
+
if (opts.status) {
|
|
8604
|
+
const status = inspectLensRegistry(registry);
|
|
8605
|
+
process.stdout.write(opts.json ? `${JSON.stringify(status, null, 2)}
|
|
8606
|
+
` : `${formatLensRegistryStatus(status)}
|
|
8607
|
+
`);
|
|
8608
|
+
if (!status.valid) process.exitCode = 3;
|
|
8609
|
+
return;
|
|
8610
|
+
}
|
|
8611
|
+
if (opts.rollback) {
|
|
8612
|
+
const outcome = retireArchetype(String(opts.rollback), { ...registry ? { registryPath: registry } : {} });
|
|
8613
|
+
process.stdout.write(
|
|
8614
|
+
opts.json ? `${JSON.stringify(outcome, null, 2)}
|
|
8615
|
+
` : outcome.retired ? `RETIRED ${outcome.id} from ${outcome.registryPath}
|
|
8616
|
+
` : `not retired ${outcome.id}: ${outcome.reason ?? "unknown reason"}
|
|
8617
|
+
`
|
|
8618
|
+
);
|
|
8619
|
+
if (!outcome.retired) process.exitCode = 3;
|
|
8620
|
+
return;
|
|
8621
|
+
}
|
|
8622
|
+
if (!opts.missInput) throw new Error("--miss-input is required unless --status or --rollback is used");
|
|
8623
|
+
if (opts.maxRegister !== void 0 && (!Number.isInteger(opts.maxRegister) || opts.maxRegister < 0)) {
|
|
8624
|
+
throw new Error("--max-register must be a non-negative integer");
|
|
8625
|
+
}
|
|
8626
|
+
if (opts.fromBench && !opts.manifest) throw new Error("--from-bench requires --manifest");
|
|
8627
|
+
if (opts.fromBench && opts.watch) throw new Error("--from-bench cannot be combined with --watch");
|
|
8628
|
+
const pollIntervalMs = Number.parseInt(opts.pollInterval ?? "2000", 10);
|
|
8629
|
+
if (!Number.isInteger(pollIntervalMs) || pollIntervalMs < 100) {
|
|
8630
|
+
throw new Error("--poll-interval must be an integer of at least 100ms");
|
|
8631
|
+
}
|
|
8632
|
+
const request = {
|
|
8633
|
+
missInput: String(opts.missInput),
|
|
8634
|
+
...registry ? { registry } : {},
|
|
8635
|
+
...opts.maxRegister !== void 0 ? { maxRegister: opts.maxRegister } : {},
|
|
8636
|
+
...opts.model ? { model: String(opts.model) } : {},
|
|
8637
|
+
promote: Boolean(opts.promote),
|
|
8638
|
+
trials: trialCount(opts.trials),
|
|
8639
|
+
...opts.fromBench ? { fromBench: String(opts.fromBench) } : {},
|
|
8640
|
+
...opts.manifest ? { manifest: resolve15(String(opts.manifest)) } : {}
|
|
8641
|
+
};
|
|
8642
|
+
const printResult = (result) => {
|
|
8643
|
+
process.stdout.write(
|
|
8644
|
+
opts.json ? `${JSON.stringify(result, null, 2)}
|
|
8645
|
+
` : `${formatLensSynthResult(result, !opts.promote)}
|
|
8646
|
+
`
|
|
8647
|
+
);
|
|
8648
|
+
};
|
|
8649
|
+
const log = (message) => {
|
|
8650
|
+
process.stderr.write(`${message}
|
|
8651
|
+
`);
|
|
8652
|
+
};
|
|
8653
|
+
if (!opts.watch) {
|
|
8654
|
+
printResult(await runLensSynthCommand(request, { log }));
|
|
8655
|
+
return;
|
|
8656
|
+
}
|
|
8657
|
+
const controller = new AbortController();
|
|
8658
|
+
const stop = () => controller.abort();
|
|
8659
|
+
process.once("SIGINT", stop);
|
|
8660
|
+
process.once("SIGTERM", stop);
|
|
8661
|
+
try {
|
|
8662
|
+
await watchLensSynthCommand(
|
|
8663
|
+
{ ...request, pollIntervalMs },
|
|
8664
|
+
{
|
|
8665
|
+
log,
|
|
8666
|
+
signal: controller.signal,
|
|
8667
|
+
onResult: printResult,
|
|
8668
|
+
onError: (error) => process.stderr.write(`lens-synth watch: ${error.message}
|
|
8669
|
+
`)
|
|
8670
|
+
}
|
|
8671
|
+
);
|
|
8672
|
+
} finally {
|
|
8673
|
+
process.off("SIGINT", stop);
|
|
8674
|
+
process.off("SIGTERM", stop);
|
|
8675
|
+
}
|
|
8676
|
+
} catch (error) {
|
|
8677
|
+
process.stderr.write(`lens-synth: ${error instanceof Error ? error.message : String(error)}
|
|
8678
|
+
`);
|
|
8679
|
+
process.exitCode = 3;
|
|
8680
|
+
}
|
|
8681
|
+
});
|
|
8682
|
+
}
|
|
8683
|
+
|
|
8326
8684
|
// packages/cli/src/commands/memsafety.ts
|
|
8327
8685
|
import { existsSync as existsSync12, mkdirSync as mkdirSync8, realpathSync, writeFileSync as writeFileSync10 } from "node:fs";
|
|
8328
|
-
import { resolve as
|
|
8686
|
+
import { resolve as resolve16, join as join11, sep } from "node:path";
|
|
8329
8687
|
var VALID_LANGUAGES = /* @__PURE__ */ new Set(["c", "cpp", "rust"]);
|
|
8330
8688
|
var VALID_BUILD_SYSTEMS3 = /* @__PURE__ */ new Set([
|
|
8331
8689
|
"cargo",
|
|
@@ -8350,7 +8708,7 @@ function detectMemSafetyBuild(sourceRoot, exists2 = existsSync12) {
|
|
|
8350
8708
|
function resolveArtifactDir(value, sourceRoot) {
|
|
8351
8709
|
const raw = value?.trim();
|
|
8352
8710
|
if (!raw) return void 0;
|
|
8353
|
-
const artifactDir =
|
|
8711
|
+
const artifactDir = resolve16(raw);
|
|
8354
8712
|
const preparedRoot = realpathSync(sourceRoot);
|
|
8355
8713
|
mkdirSync8(artifactDir, { recursive: true, mode: 448 });
|
|
8356
8714
|
const canonicalArtifactDir = realpathSync(artifactDir);
|
|
@@ -8362,7 +8720,7 @@ function resolveArtifactDir(value, sourceRoot) {
|
|
|
8362
8720
|
return canonicalArtifactDir;
|
|
8363
8721
|
}
|
|
8364
8722
|
async function runMemSafety(opts) {
|
|
8365
|
-
const { prepare: prepare2, runMemSafetyScan } = await import("./dist-
|
|
8723
|
+
const { prepare: prepare2, runMemSafetyScan } = await import("./dist-6RNAVFAY.js");
|
|
8366
8724
|
const log = opts.log ?? (() => {
|
|
8367
8725
|
});
|
|
8368
8726
|
const prepared = await prepare2(
|
|
@@ -8373,11 +8731,11 @@ async function runMemSafety(opts) {
|
|
|
8373
8731
|
if (e.message) log(`[memsafety:source] ${e.message}`);
|
|
8374
8732
|
}
|
|
8375
8733
|
);
|
|
8376
|
-
const sourceRoot =
|
|
8734
|
+
const sourceRoot = resolve16(prepared.resolvedTarget);
|
|
8377
8735
|
try {
|
|
8378
8736
|
let scopeRoot = sourceRoot;
|
|
8379
8737
|
if (opts.subsystem && opts.subsystem.trim() !== "") {
|
|
8380
|
-
const scoped =
|
|
8738
|
+
const scoped = resolve16(join11(sourceRoot, opts.subsystem));
|
|
8381
8739
|
if (scoped !== sourceRoot && !scoped.startsWith(sourceRoot + sep)) {
|
|
8382
8740
|
throw new Error(`--subsystem '${opts.subsystem}' escapes the source tree`);
|
|
8383
8741
|
}
|
|
@@ -8502,7 +8860,7 @@ function parseArtifactOptions(opts) {
|
|
|
8502
8860
|
throw new Error("--artifact-max-bytes must be at least 65536");
|
|
8503
8861
|
}
|
|
8504
8862
|
return {
|
|
8505
|
-
artifactDir:
|
|
8863
|
+
artifactDir: resolve16(artifactDir),
|
|
8506
8864
|
artifactMaxBytes: maxBytes
|
|
8507
8865
|
};
|
|
8508
8866
|
}
|
|
@@ -8526,7 +8884,7 @@ async function memsafetyAction(target, opts) {
|
|
|
8526
8884
|
log: (m) => process.stderr.write(m + "\n")
|
|
8527
8885
|
});
|
|
8528
8886
|
const json = JSON.stringify(outcome.result, null, 2);
|
|
8529
|
-
if (opts.output) writeFileSync10(
|
|
8887
|
+
if (opts.output) writeFileSync10(resolve16(opts.output), json + "\n", "utf8");
|
|
8530
8888
|
else process.stdout.write(json + "\n");
|
|
8531
8889
|
process.exitCode = outcome.exitCode;
|
|
8532
8890
|
}
|
|
@@ -8546,9 +8904,9 @@ function registerMemsafetyCommand(program) {
|
|
|
8546
8904
|
const reason = err instanceof Error ? err.message : String(err);
|
|
8547
8905
|
const json = JSON.stringify({ mode: "memsafety", error: reason }, null, 2);
|
|
8548
8906
|
if (opts.output) {
|
|
8549
|
-
const { writeFileSync:
|
|
8907
|
+
const { writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
8550
8908
|
try {
|
|
8551
|
-
|
|
8909
|
+
writeFileSync18(resolve16(opts.output), json + "\n", "utf8");
|
|
8552
8910
|
} catch {
|
|
8553
8911
|
process.stderr.write(json + "\n");
|
|
8554
8912
|
}
|
|
@@ -8559,7 +8917,7 @@ function registerMemsafetyCommand(program) {
|
|
|
8559
8917
|
}
|
|
8560
8918
|
|
|
8561
8919
|
// packages/cli/src/commands/assumption-hunt.ts
|
|
8562
|
-
import { resolve as
|
|
8920
|
+
import { resolve as resolve17 } from "node:path";
|
|
8563
8921
|
function parseWitnessMode2(raw) {
|
|
8564
8922
|
if (raw === void 0) return void 0;
|
|
8565
8923
|
const m = raw.trim();
|
|
@@ -8569,16 +8927,16 @@ function parseWitnessMode2(raw) {
|
|
|
8569
8927
|
return m;
|
|
8570
8928
|
}
|
|
8571
8929
|
async function runAssumptionHuntCli(sourceRoot, opts) {
|
|
8572
|
-
const { runAssumptionHunt, makeSkepticVerifier } = await import("./dist-
|
|
8930
|
+
const { runAssumptionHunt, makeSkepticVerifier } = await import("./dist-6RNAVFAY.js");
|
|
8573
8931
|
const log = (m) => process.stderr.write(m + "\n");
|
|
8574
8932
|
const runtime = opts.runtime ?? "api";
|
|
8575
|
-
const root =
|
|
8933
|
+
const root = resolve17(sourceRoot);
|
|
8576
8934
|
const subsystem = opts.subsystem?.trim() || "subsystem";
|
|
8577
8935
|
const files = (opts.files ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
8578
8936
|
if (files.length === 0) {
|
|
8579
8937
|
throw new Error("--files is required: a comma-separated list of subsystem source files (repo-relative to <source-root>)");
|
|
8580
8938
|
}
|
|
8581
|
-
const modelPath = opts.modelPath ?
|
|
8939
|
+
const modelPath = opts.modelPath ? resolve17(opts.modelPath) : resolve17(root, `.0/assumption-models/${subsystem.replaceAll("/", "_")}.json`);
|
|
8582
8940
|
const models = opts.models ? opts.models.split(",").map((s) => s.trim()).filter(Boolean) : void 0;
|
|
8583
8941
|
const verify = opts.skipHunt || opts.noVerify ? void 0 : (
|
|
8584
8942
|
// `finderModels` decorrelates the refute pass from the finder fan-out
|
|
@@ -8604,7 +8962,7 @@ async function runAssumptionHuntCli(sourceRoot, opts) {
|
|
|
8604
8962
|
...models ? { finderModels: models } : {},
|
|
8605
8963
|
...opts.finderTargeting === false ? { finderTargeting: false } : {},
|
|
8606
8964
|
...opts.dualView === false ? { dualView: false } : {},
|
|
8607
|
-
...opts.excerptDir ? { excerptDir:
|
|
8965
|
+
...opts.excerptDir ? { excerptDir: resolve17(opts.excerptDir) } : {},
|
|
8608
8966
|
...opts.dynamicWitness ? {
|
|
8609
8967
|
dynamicWitness: {
|
|
8610
8968
|
runtime,
|
|
@@ -8687,8 +9045,8 @@ function registerAssumptionHuntCommand(program) {
|
|
|
8687
9045
|
const outcome = await runAssumptionHuntCli(sourceRoot, opts);
|
|
8688
9046
|
const json = JSON.stringify(outcome.result, null, 2);
|
|
8689
9047
|
if (opts.output) {
|
|
8690
|
-
const { writeFileSync:
|
|
8691
|
-
|
|
9048
|
+
const { writeFileSync: writeFileSync18 } = await import("node:fs");
|
|
9049
|
+
writeFileSync18(resolve17(opts.output), json + "\n", "utf8");
|
|
8692
9050
|
} else process.stdout.write(json + "\n");
|
|
8693
9051
|
process.exitCode = outcome.exitCode;
|
|
8694
9052
|
} catch (err) {
|
|
@@ -8700,8 +9058,8 @@ function registerAssumptionHuntCommand(program) {
|
|
|
8700
9058
|
}
|
|
8701
9059
|
|
|
8702
9060
|
// packages/cli/src/commands/specdrift.ts
|
|
8703
|
-
import { readFileSync as
|
|
8704
|
-
import { basename as basename4, resolve as
|
|
9061
|
+
import { readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "node:fs";
|
|
9062
|
+
import { basename as basename4, resolve as resolve18 } from "node:path";
|
|
8705
9063
|
function parsePositive4(flag, raw, dflt) {
|
|
8706
9064
|
if (raw === void 0) return dflt;
|
|
8707
9065
|
const n = parseInt(raw, 10);
|
|
@@ -8711,8 +9069,8 @@ function parsePositive4(flag, raw, dflt) {
|
|
|
8711
9069
|
async function runSpecdriftExtract(opts) {
|
|
8712
9070
|
if (!opts.spec) throw new Error("missing required flag: --spec <path>");
|
|
8713
9071
|
const maxInvariants = parsePositive4("--max-invariants", opts.maxInvariants, 40);
|
|
8714
|
-
const specPath =
|
|
8715
|
-
const specText =
|
|
9072
|
+
const specPath = resolve18(opts.spec);
|
|
9073
|
+
const specText = readFileSync14(specPath, "utf8");
|
|
8716
9074
|
return extractSpecInvariants({
|
|
8717
9075
|
specName: opts.specName ?? basename4(specPath),
|
|
8718
9076
|
specText,
|
|
@@ -8733,8 +9091,8 @@ async function runSpecdriftSourceWorkflow(opts, stage) {
|
|
|
8733
9091
|
const maxCandidatesPerInvariant = parsePositive4("--max-candidates-per-invariant", opts.maxCandidatesPerInvariant, 5);
|
|
8734
9092
|
const maxHypotheses = parsePositive4("--max-hypotheses", opts.maxHypotheses, 20);
|
|
8735
9093
|
const timeout = parsePositive4("--timeout", opts.timeout, 6e5);
|
|
8736
|
-
const specPath =
|
|
8737
|
-
const specText =
|
|
9094
|
+
const specPath = resolve18(opts.spec);
|
|
9095
|
+
const specText = readFileSync14(specPath, "utf8");
|
|
8738
9096
|
const prepared = await prepare(opts.source, "source-code", { timeout }, (e) => {
|
|
8739
9097
|
if (e.message) process.stderr.write(`[specdrift:source] ${e.message}
|
|
8740
9098
|
`);
|
|
@@ -8743,7 +9101,7 @@ async function runSpecdriftSourceWorkflow(opts, stage) {
|
|
|
8743
9101
|
const input = {
|
|
8744
9102
|
specName: opts.specName ?? basename4(specPath),
|
|
8745
9103
|
specText,
|
|
8746
|
-
sourceRoot:
|
|
9104
|
+
sourceRoot: resolve18(prepared.resolvedTarget),
|
|
8747
9105
|
maxInvariants,
|
|
8748
9106
|
maxFiles,
|
|
8749
9107
|
maxCandidatesPerInvariant
|
|
@@ -8757,14 +9115,14 @@ async function writeJsonResult(fn, output2, stage = "extract") {
|
|
|
8757
9115
|
try {
|
|
8758
9116
|
const result = await fn();
|
|
8759
9117
|
const json = JSON.stringify(result, null, 2);
|
|
8760
|
-
if (output2) writeFileSync11(
|
|
9118
|
+
if (output2) writeFileSync11(resolve18(output2), json + "\n", "utf8");
|
|
8761
9119
|
else process.stdout.write(json + "\n");
|
|
8762
9120
|
} catch (err) {
|
|
8763
9121
|
const reason = err instanceof Error ? err.message : String(err);
|
|
8764
9122
|
const json = JSON.stringify({ mode: "specdrift", stage, error: reason }, null, 2);
|
|
8765
9123
|
if (output2) {
|
|
8766
9124
|
try {
|
|
8767
|
-
writeFileSync11(
|
|
9125
|
+
writeFileSync11(resolve18(output2), json + "\n", "utf8");
|
|
8768
9126
|
} catch {
|
|
8769
9127
|
process.stderr.write(json + "\n");
|
|
8770
9128
|
}
|
|
@@ -8786,8 +9144,8 @@ function registerSpecdriftCommand(program) {
|
|
|
8786
9144
|
}
|
|
8787
9145
|
|
|
8788
9146
|
// packages/cli/src/commands/protocol-check.ts
|
|
8789
|
-
import { readFileSync as
|
|
8790
|
-
import { resolve as
|
|
9147
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
9148
|
+
import { resolve as resolve19 } from "node:path";
|
|
8791
9149
|
function resolveNativeRuntime(runtimeFlag) {
|
|
8792
9150
|
const choice = (runtimeFlag ?? "auto").toLowerCase();
|
|
8793
9151
|
const timeout = 6e4;
|
|
@@ -8806,9 +9164,9 @@ function resolveNativeRuntime(runtimeFlag) {
|
|
|
8806
9164
|
return rt;
|
|
8807
9165
|
}
|
|
8808
9166
|
function readExcerpt(path, label) {
|
|
8809
|
-
const abs =
|
|
9167
|
+
const abs = resolve19(path);
|
|
8810
9168
|
try {
|
|
8811
|
-
return
|
|
9169
|
+
return readFileSync15(abs, "utf8");
|
|
8812
9170
|
} catch (err) {
|
|
8813
9171
|
throw new Error(
|
|
8814
9172
|
`failed to read ${label} from ${abs}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -8932,8 +9290,8 @@ function registerProtocolCheckCommand(program) {
|
|
|
8932
9290
|
}
|
|
8933
9291
|
|
|
8934
9292
|
// packages/cli/src/commands/cve.ts
|
|
8935
|
-
import { readFileSync as
|
|
8936
|
-
import { resolve as
|
|
9293
|
+
import { readFileSync as readFileSync16 } from "node:fs";
|
|
9294
|
+
import { resolve as resolve20 } from "node:path";
|
|
8937
9295
|
var VALID_FORMATS2 = ["json", "table"];
|
|
8938
9296
|
var EXIT_OK = 0;
|
|
8939
9297
|
var EXIT_USER_ERROR = 1;
|
|
@@ -8965,10 +9323,10 @@ function parseAttempts(input, fallback = 5) {
|
|
|
8965
9323
|
return parsed;
|
|
8966
9324
|
}
|
|
8967
9325
|
function loadArtifactsFile(path) {
|
|
8968
|
-
const abs =
|
|
9326
|
+
const abs = resolve20(path);
|
|
8969
9327
|
let raw;
|
|
8970
9328
|
try {
|
|
8971
|
-
raw =
|
|
9329
|
+
raw = readFileSync16(abs, "utf-8");
|
|
8972
9330
|
} catch (err) {
|
|
8973
9331
|
throw new Error(`failed to read --artifacts ${abs}: ${err instanceof Error ? err.message : String(err)}`);
|
|
8974
9332
|
}
|
|
@@ -9944,7 +10302,7 @@ function resolveConsoleAutonomyMode(opts) {
|
|
|
9944
10302
|
function registerConsoleCommand(program) {
|
|
9945
10303
|
program.command("console").alias("chat").description(
|
|
9946
10304
|
"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>", "Safety cap on tool-call rounds per message", String(DEFAULT_MAX_TOOL_ITERATIONS)).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
|
|
10305
|
+
).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>", "Safety cap on tool-call rounds per message", String(DEFAULT_MAX_TOOL_ITERATIONS)).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
10306
|
if (opts.prompt !== void 0) opts.print = opts.prompt;
|
|
9949
10307
|
if (opts.print === void 0) {
|
|
9950
10308
|
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 +10380,7 @@ function registerConsoleCommand(program) {
|
|
|
10022
10380
|
let resumedModel;
|
|
10023
10381
|
let resumedTarget;
|
|
10024
10382
|
if (opts.continue || opts.resume !== void 0) {
|
|
10025
|
-
const { listSessions, loadSession } = await import("./session-store-
|
|
10383
|
+
const { listSessions, loadSession } = await import("./session-store-DBBI544Y.js");
|
|
10026
10384
|
const idArg = typeof opts.resume === "string" ? opts.resume.trim() : "";
|
|
10027
10385
|
if (idArg || opts.continue) {
|
|
10028
10386
|
let stored = idArg ? loadSession(idArg) : null;
|
|
@@ -10136,7 +10494,7 @@ async function runTurn(session, text2, output2) {
|
|
|
10136
10494
|
engine error: ${outcome.error ?? "unknown"}
|
|
10137
10495
|
`), "console.turn.error");
|
|
10138
10496
|
if (/ChatGPT.*model.*not supported/i.test(outcome.error ?? "")) {
|
|
10139
|
-
output2.stderr(source_default.dim("Choose an available account/provider model with --model; the
|
|
10497
|
+
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
10498
|
}
|
|
10141
10499
|
}
|
|
10142
10500
|
return outcome;
|
|
@@ -11013,7 +11371,7 @@ function loadScopeOrExit(path) {
|
|
|
11013
11371
|
}
|
|
11014
11372
|
|
|
11015
11373
|
// packages/cli/src/commands/xnu-fuzz.ts
|
|
11016
|
-
import { readFileSync as
|
|
11374
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync12 } from "node:fs";
|
|
11017
11375
|
function enumerateAction(opts) {
|
|
11018
11376
|
const bundle = opts.bundle ?? "com.apple.unknown";
|
|
11019
11377
|
const model = enumerateTargetModelFromKext(opts.kext, { kext: bundle, source: opts.kext });
|
|
@@ -11050,7 +11408,7 @@ function pickClient(model, name) {
|
|
|
11050
11408
|
return model.userClients[0];
|
|
11051
11409
|
}
|
|
11052
11410
|
function genAction(opts) {
|
|
11053
|
-
const model = JSON.parse(
|
|
11411
|
+
const model = JSON.parse(readFileSync17(opts.model, "utf8"));
|
|
11054
11412
|
const uc = pickClient(model, opts.class);
|
|
11055
11413
|
if (!uc) {
|
|
11056
11414
|
process.stderr.write("no user client in model\n");
|
|
@@ -11136,10 +11494,10 @@ function registerXnuFuzzCommand(program) {
|
|
|
11136
11494
|
}
|
|
11137
11495
|
|
|
11138
11496
|
// packages/cli/src/commands/research.ts
|
|
11139
|
-
import { readFileSync as
|
|
11140
|
-
import { resolve as
|
|
11497
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
11498
|
+
import { resolve as resolve21 } from "node:path";
|
|
11141
11499
|
async function managedResearch(adapter, target, options, engine) {
|
|
11142
|
-
const { executeManagedOperation: executeManagedOperation2 } = await import("./managed-operation-
|
|
11500
|
+
const { executeManagedOperation: executeManagedOperation2 } = await import("./managed-operation-642WPTLC.js");
|
|
11143
11501
|
const started = Date.now();
|
|
11144
11502
|
return executeManagedOperation2({
|
|
11145
11503
|
type: "research",
|
|
@@ -11191,7 +11549,7 @@ function print(value) {
|
|
|
11191
11549
|
function registerResearchCommand(program) {
|
|
11192
11550
|
const research = program.command("research").description("Run target-specific research engines");
|
|
11193
11551
|
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-
|
|
11552
|
+
const { UnifiedPipelineResearchAdapter, runResearch } = await import("./dist-6RNAVFAY.js");
|
|
11195
11553
|
const allowedTypes = /* @__PURE__ */ new Set(["url", "web-app", "source-code", "npm-package", "pypi-package", "cargo-package", "oci-image"]);
|
|
11196
11554
|
if (opts.targetType && !allowedTypes.has(opts.targetType)) throw new Error(`unsupported --target-type ${opts.targetType}`);
|
|
11197
11555
|
print(await managedResearch(
|
|
@@ -11210,12 +11568,12 @@ function registerResearchCommand(program) {
|
|
|
11210
11568
|
}
|
|
11211
11569
|
}
|
|
11212
11570
|
},
|
|
11213
|
-
{ artifactRoot:
|
|
11571
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11214
11572
|
runResearch
|
|
11215
11573
|
));
|
|
11216
11574
|
});
|
|
11217
11575
|
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-
|
|
11576
|
+
const { UserspaceCounterexampleResearchAdapter, runResearch } = await import("./dist-6RNAVFAY.js");
|
|
11219
11577
|
const SHAPES = { bytesAndLen: true, bytesPtr: true, bytesAndLenOut: true };
|
|
11220
11578
|
if (!SHAPES[opts.inputShape]) throw new Error(`unsupported --input-shape ${opts.inputShape}`);
|
|
11221
11579
|
const SYSTEMS = { auto: true, autotools: true, cmake: true, meson: true };
|
|
@@ -11225,9 +11583,9 @@ function registerResearchCommand(program) {
|
|
|
11225
11583
|
{
|
|
11226
11584
|
kind: "userspace.counterexample",
|
|
11227
11585
|
id: `counterexample:${opts.source}:${opts.fn}`,
|
|
11228
|
-
location:
|
|
11586
|
+
location: resolve21(opts.source),
|
|
11229
11587
|
config: {
|
|
11230
|
-
sourceRoot:
|
|
11588
|
+
sourceRoot: resolve21(opts.source),
|
|
11231
11589
|
buildSystem: opts.buildSystem,
|
|
11232
11590
|
suspectFunction: {
|
|
11233
11591
|
header: opts.header,
|
|
@@ -11235,43 +11593,43 @@ function registerResearchCommand(program) {
|
|
|
11235
11593
|
declaration: opts.declaration,
|
|
11236
11594
|
inputShape: opts.inputShape
|
|
11237
11595
|
},
|
|
11238
|
-
...opts.witness?.length ? { witnessInputs: opts.witness.map((path) =>
|
|
11596
|
+
...opts.witness?.length ? { witnessInputs: opts.witness.map((path) => resolve21(path)) } : {},
|
|
11239
11597
|
...opts.timeout ? { timeoutSec: Number.parseInt(opts.timeout, 10) } : {},
|
|
11240
11598
|
...opts.mitigationSource?.length ? { mitigation: { sourceFiles: opts.mitigationSource, ...opts.mitigationInclude?.length ? { includeDirs: opts.mitigationInclude } : {} } } : {}
|
|
11241
11599
|
}
|
|
11242
11600
|
},
|
|
11243
|
-
{ artifactRoot:
|
|
11601
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11244
11602
|
runResearch
|
|
11245
11603
|
));
|
|
11246
11604
|
});
|
|
11247
11605
|
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 =
|
|
11606
|
+
const { MobileStaticResearchAdapter, runResearch } = await import("./dist-6RNAVFAY.js");
|
|
11607
|
+
const targetPath = resolve21(opts.target);
|
|
11250
11608
|
print(await managedResearch(
|
|
11251
11609
|
new MobileStaticResearchAdapter(),
|
|
11252
11610
|
{ kind: "mobile.static-intake", id: `mobile:${targetPath}`, location: targetPath, config: {} },
|
|
11253
|
-
{ artifactRoot:
|
|
11611
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11254
11612
|
runResearch
|
|
11255
11613
|
));
|
|
11256
11614
|
});
|
|
11257
11615
|
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(
|
|
11616
|
+
const { LinuxBootMatrixImportAdapter, runResearch } = await import("./dist-6RNAVFAY.js");
|
|
11617
|
+
const matrix = resolve21(opts.matrix);
|
|
11618
|
+
const finding = JSON.parse(readFileSync18(resolve21(opts.finding), "utf8"));
|
|
11261
11619
|
const result = await managedResearch(
|
|
11262
11620
|
new LinuxBootMatrixImportAdapter(),
|
|
11263
11621
|
{ kind: "linux.kernel-boot-matrix-import", id: `linux-matrix:${finding.id}`, location: matrix, config: { finding } },
|
|
11264
|
-
{ artifactRoot:
|
|
11622
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11265
11623
|
runResearch
|
|
11266
11624
|
);
|
|
11267
11625
|
if (result.candidates.length === 0) throw new Error("external boot-matrix manifest failed validation");
|
|
11268
11626
|
print(result);
|
|
11269
11627
|
});
|
|
11270
11628
|
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(
|
|
11629
|
+
const { LinuxKernelResearchAdapter, runResearch } = await import("./dist-6RNAVFAY.js");
|
|
11630
|
+
const kernelTree = resolve21(opts.kernelTree);
|
|
11631
|
+
const reproducer = resolve21(opts.reproducer);
|
|
11632
|
+
const finding = JSON.parse(readFileSync18(resolve21(opts.finding), "utf8"));
|
|
11275
11633
|
const boots = Number.parseInt(opts.boots, 10);
|
|
11276
11634
|
const minHits = Number.parseInt(opts.minHits, 10);
|
|
11277
11635
|
if (!Number.isFinite(boots) || boots < 1 || !Number.isFinite(minHits) || minHits < 1 || minHits > boots) {
|
|
@@ -11287,7 +11645,7 @@ function registerResearchCommand(program) {
|
|
|
11287
11645
|
location: kernelTree,
|
|
11288
11646
|
config: { finding, verify }
|
|
11289
11647
|
},
|
|
11290
|
-
{ artifactRoot:
|
|
11648
|
+
{ artifactRoot: resolve21(opts.artifactRoot), log: (message) => process.stderr.write(message + "\n") },
|
|
11291
11649
|
runResearch
|
|
11292
11650
|
);
|
|
11293
11651
|
if (result.findings.length === 0) {
|
|
@@ -11314,6 +11672,9 @@ function registerWorkerCommand(program) {
|
|
|
11314
11672
|
});
|
|
11315
11673
|
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
11316
11674
|
});
|
|
11675
|
+
worker.command("repair <backend-id>").description("Reconnect a managed worker tunnel and start its retained engine when needed").action(async (backendId) => {
|
|
11676
|
+
process.stdout.write(JSON.stringify(await repairWorker(backendId)) + "\n");
|
|
11677
|
+
});
|
|
11317
11678
|
worker.command("stop <backend-id>").description("Stop a managed worker engine and its owned tunnel; retain remote files and registration").action(async (backendId) => {
|
|
11318
11679
|
process.stdout.write(JSON.stringify(await stopWorker(backendId)) + "\n");
|
|
11319
11680
|
});
|
|
@@ -11332,7 +11693,7 @@ function registerWorkerCommand(program) {
|
|
|
11332
11693
|
// packages/cli/src/commands/radar.ts
|
|
11333
11694
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
11334
11695
|
import { writeFileSync as writeFileSync13 } from "node:fs";
|
|
11335
|
-
import { resolve as
|
|
11696
|
+
import { resolve as resolve22 } from "node:path";
|
|
11336
11697
|
function parsePositive5(flag, raw, dflt) {
|
|
11337
11698
|
if (raw === void 0) return dflt;
|
|
11338
11699
|
const n = parseInt(raw, 10);
|
|
@@ -11341,7 +11702,7 @@ function parsePositive5(flag, raw, dflt) {
|
|
|
11341
11702
|
}
|
|
11342
11703
|
async function radarAction(opts) {
|
|
11343
11704
|
if (!opts.repo) throw new Error("missing required flag: --repo <path>");
|
|
11344
|
-
const repo =
|
|
11705
|
+
const repo = resolve22(opts.repo);
|
|
11345
11706
|
try {
|
|
11346
11707
|
execFileSync2("git", ["-C", repo, "rev-parse", "--is-inside-work-tree"], { stdio: "pipe" });
|
|
11347
11708
|
} catch {
|
|
@@ -11366,14 +11727,14 @@ async function radarAction(opts) {
|
|
|
11366
11727
|
});
|
|
11367
11728
|
const rankedJson = JSON.stringify(result, null, 2);
|
|
11368
11729
|
if (opts.out) {
|
|
11369
|
-
writeFileSync13(
|
|
11730
|
+
writeFileSync13(resolve22(opts.out), rankedJson + "\n", "utf8");
|
|
11370
11731
|
} else {
|
|
11371
11732
|
process.stdout.write(rankedJson + "\n");
|
|
11372
11733
|
}
|
|
11373
11734
|
if (opts.seedsOut) {
|
|
11374
|
-
const repo2 =
|
|
11735
|
+
const repo2 = resolve22(opts.repo);
|
|
11375
11736
|
const seeds = radarCandidatesToSeedFindings(result, repo2);
|
|
11376
|
-
writeFileSync13(
|
|
11737
|
+
writeFileSync13(resolve22(opts.seedsOut), JSON.stringify(seeds, null, 2) + "\n", "utf8");
|
|
11377
11738
|
}
|
|
11378
11739
|
process.exitCode = 0;
|
|
11379
11740
|
}
|
|
@@ -11430,7 +11791,7 @@ function registerTimelineCommand(program) {
|
|
|
11430
11791
|
process.exitCode = 2;
|
|
11431
11792
|
return;
|
|
11432
11793
|
}
|
|
11433
|
-
const { osecDB: osecDB2 } = await import("./dist-
|
|
11794
|
+
const { osecDB: osecDB2 } = await import("./dist-OLGNKDB2.js");
|
|
11434
11795
|
const db = new osecDB2(opts.dbPath);
|
|
11435
11796
|
let scan2;
|
|
11436
11797
|
let rows;
|
|
@@ -11717,12 +12078,12 @@ function strArray(value) {
|
|
|
11717
12078
|
}
|
|
11718
12079
|
|
|
11719
12080
|
// packages/cli/src/commands/agent-assure.ts
|
|
11720
|
-
import { createHash as
|
|
11721
|
-
import { readFileSync as
|
|
12081
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
12082
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
11722
12083
|
function readScenario(path) {
|
|
11723
12084
|
let raw;
|
|
11724
12085
|
try {
|
|
11725
|
-
raw = JSON.parse(
|
|
12086
|
+
raw = JSON.parse(readFileSync19(path, "utf8"));
|
|
11726
12087
|
} catch (error) {
|
|
11727
12088
|
const message = error instanceof Error ? error.message : String(error);
|
|
11728
12089
|
throw new Error(`agent-assure: failed to read scenario ${path}: ${message}`);
|
|
@@ -11733,7 +12094,7 @@ function readHeaders(path, field) {
|
|
|
11733
12094
|
if (!path) return {};
|
|
11734
12095
|
let raw;
|
|
11735
12096
|
try {
|
|
11736
|
-
raw = JSON.parse(
|
|
12097
|
+
raw = JSON.parse(readFileSync19(path, "utf8"));
|
|
11737
12098
|
} catch (error) {
|
|
11738
12099
|
const message = error instanceof Error ? error.message : String(error);
|
|
11739
12100
|
throw new Error(`agent-assure: failed to read ${field} file ${path}: ${message}`);
|
|
@@ -11782,7 +12143,7 @@ function assertInScope(scope, endpoint, label) {
|
|
|
11782
12143
|
}
|
|
11783
12144
|
}
|
|
11784
12145
|
function readBaseline(path) {
|
|
11785
|
-
const raw =
|
|
12146
|
+
const raw = readFileSync19(path, "utf8");
|
|
11786
12147
|
return {
|
|
11787
12148
|
manifest: parseAgentActionEvidenceManifest(JSON.parse(raw)),
|
|
11788
12149
|
sha256: agentActionManifestSha256(raw)
|
|
@@ -11800,11 +12161,11 @@ function registerAgentAssureCommand(program) {
|
|
|
11800
12161
|
assertInScope(scope, opts.mcpEndpoint, "MCP endpoint");
|
|
11801
12162
|
assertInScope(scope, opts.oracleEndpoint, "oracle endpoint");
|
|
11802
12163
|
const baseline = opts.baseline ? readBaseline(opts.baseline) : void 0;
|
|
11803
|
-
const scenarioPayloadSha256 =
|
|
12164
|
+
const scenarioPayloadSha256 = createHash6("sha256").update(scenario.payload).digest("hex");
|
|
11804
12165
|
if (baseline && (baseline.manifest.scenario.id !== scenario.id || baseline.manifest.scenario.payload_sha256 !== scenarioPayloadSha256)) {
|
|
11805
12166
|
throw new Error("agent-assure: --baseline must describe the same scenario id and payload");
|
|
11806
12167
|
}
|
|
11807
|
-
const scopeRaw = opts.scope ?
|
|
12168
|
+
const scopeRaw = opts.scope ? readFileSync19(opts.scope, "utf8") : "";
|
|
11808
12169
|
const timeoutMs = parsePositiveMilliseconds(opts.timeout, "--timeout");
|
|
11809
12170
|
const oracleTimeoutMs = parsePositiveMilliseconds(opts.oracleTimeout, "--oracle-timeout");
|
|
11810
12171
|
const run2 = await runAgentActionAssurance({
|
|
@@ -11824,7 +12185,7 @@ function registerAgentAssureCommand(program) {
|
|
|
11824
12185
|
}),
|
|
11825
12186
|
scenario,
|
|
11826
12187
|
targetConfig: {
|
|
11827
|
-
scopeSha256:
|
|
12188
|
+
scopeSha256: createHash6("sha256").update(scopeRaw).digest("hex"),
|
|
11828
12189
|
environment: opts.environment,
|
|
11829
12190
|
agentEndpoint: opts.agentEndpoint,
|
|
11830
12191
|
mcpEndpoint: opts.mcpEndpoint,
|
|
@@ -11868,7 +12229,7 @@ function registerAgentAssureCommand(program) {
|
|
|
11868
12229
|
// packages/cli/src/commands/binary.ts
|
|
11869
12230
|
import { spawn, spawnSync as spawnSync2 } from "node:child_process";
|
|
11870
12231
|
import { existsSync as existsSync13 } from "node:fs";
|
|
11871
|
-
import { dirname as dirname6, join as join14, resolve as
|
|
12232
|
+
import { dirname as dirname6, join as join14, resolve as resolve23 } from "node:path";
|
|
11872
12233
|
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
11873
12234
|
var BINARY_MODES = ["triage", "run", "scan"];
|
|
11874
12235
|
function locateOverseDir(startDir) {
|
|
@@ -11950,7 +12311,9 @@ function resolveBinaryRun(target, opts, passthrough, deps = { isUvAvailable, loc
|
|
|
11950
12311
|
ok: true,
|
|
11951
12312
|
exitCode: 0,
|
|
11952
12313
|
overseDir,
|
|
11953
|
-
|
|
12314
|
+
// The subprocess runs from the engine checkout, so anchor the input before
|
|
12315
|
+
// changing cwd. Relative targets belong to the caller's workspace.
|
|
12316
|
+
argv: buildOverseArgv(mode, resolve23(target), opts, passthrough)
|
|
11954
12317
|
};
|
|
11955
12318
|
}
|
|
11956
12319
|
function registerBinaryCommand(program) {
|
|
@@ -11966,9 +12329,11 @@ function registerBinaryCommand(program) {
|
|
|
11966
12329
|
return;
|
|
11967
12330
|
}
|
|
11968
12331
|
const overseDir = resolution.overseDir;
|
|
11969
|
-
const
|
|
11970
|
-
const
|
|
11971
|
-
|
|
12332
|
+
const local = localZeroverseRuntime(process.cwd());
|
|
12333
|
+
const argv = local ? ["-m", "zeroverse.cli", ...resolution.argv ?? []] : ["run", "--frozen", "0verse", ...resolution.argv ?? []];
|
|
12334
|
+
const child = spawn(local?.pythonPath ?? "uv", argv, {
|
|
12335
|
+
cwd: local?.cwd ?? resolve23(overseDir),
|
|
12336
|
+
...local ? { env: { ...process.env, ...local.env } } : {},
|
|
11972
12337
|
stdio: "inherit",
|
|
11973
12338
|
shell: false
|
|
11974
12339
|
});
|
|
@@ -11993,9 +12358,9 @@ import { constants as constants3, closeSync as closeSync3, fchmodSync, lstatSync
|
|
|
11993
12358
|
import { join as join16 } from "node:path";
|
|
11994
12359
|
|
|
11995
12360
|
// 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
|
|
12361
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
12362
|
+
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";
|
|
12363
|
+
import { dirname as dirname7, join as join15, resolve as resolve24 } from "node:path";
|
|
11999
12364
|
var HACKSTORE_REGISTRY_REPO = "github.com/0sec-labs/hackstore";
|
|
12000
12365
|
var HACKSTORE_SCHEMA_ID = "https://raw.githubusercontent.com/0sec-labs/hackstore/main/hackstore-manifest.schema.json";
|
|
12001
12366
|
var MANIFEST_FILE = "manifest.json";
|
|
@@ -12006,7 +12371,7 @@ var MAX_SOURCE_BYTES = 4 * 1024 * 1024;
|
|
|
12006
12371
|
var cachedCore;
|
|
12007
12372
|
async function defaultCorePort() {
|
|
12008
12373
|
if (cachedCore) return cachedCore;
|
|
12009
|
-
const mod = await import("./dist-
|
|
12374
|
+
const mod = await import("./dist-6RNAVFAY.js");
|
|
12010
12375
|
cachedCore = {
|
|
12011
12376
|
validatePluginManifest: mod.validatePluginManifest,
|
|
12012
12377
|
reservedToolNames: Object.values(mod.TOOL_DEFINITIONS).map((tool) => tool.name),
|
|
@@ -12015,7 +12380,7 @@ async function defaultCorePort() {
|
|
|
12015
12380
|
return cachedCore;
|
|
12016
12381
|
}
|
|
12017
12382
|
function resolveManifestPath2(pathArg) {
|
|
12018
|
-
const target =
|
|
12383
|
+
const target = resolve24(pathArg);
|
|
12019
12384
|
try {
|
|
12020
12385
|
const stat3 = lstatSync2(target);
|
|
12021
12386
|
if (stat3.isSymbolicLink()) return { ok: false, error: `refusing symbolic link: ${target}` };
|
|
@@ -12030,7 +12395,7 @@ function readAuthorFile(file, maxBytes) {
|
|
|
12030
12395
|
const stat3 = fstatSync2(fd);
|
|
12031
12396
|
if (!stat3.isFile()) throw new Error(`${file} is not a regular file`);
|
|
12032
12397
|
if (stat3.size > maxBytes) throw new Error(`${file} exceeds ${maxBytes} bytes`);
|
|
12033
|
-
return
|
|
12398
|
+
return readFileSync20(fd, "utf8");
|
|
12034
12399
|
} finally {
|
|
12035
12400
|
closeSync2(fd);
|
|
12036
12401
|
}
|
|
@@ -12220,7 +12585,7 @@ input.on("line", (line) => {
|
|
|
12220
12585
|
`;
|
|
12221
12586
|
}
|
|
12222
12587
|
function runInit(name, deps) {
|
|
12223
|
-
const base = deps.dir ?
|
|
12588
|
+
const base = deps.dir ? resolve24(deps.dir) : process.cwd();
|
|
12224
12589
|
if (!name.trim() || name.length > 2e3 || name === "." || name === ".." || /[/\\\0]/.test(name)) {
|
|
12225
12590
|
console.error(source_default.red("Extension name must be a single non-empty directory name (at most 2000 characters)."));
|
|
12226
12591
|
process.exitCode = EXIT_USER_ERROR3;
|
|
@@ -12288,7 +12653,7 @@ function runPrepareSubmission(pathArg, deps) {
|
|
|
12288
12653
|
process.exitCode = EXIT_USER_ERROR3;
|
|
12289
12654
|
return;
|
|
12290
12655
|
}
|
|
12291
|
-
const output2 =
|
|
12656
|
+
const output2 = resolve24(deps.out ?? `${extension.manifest.id}-submission`);
|
|
12292
12657
|
let created = false;
|
|
12293
12658
|
try {
|
|
12294
12659
|
const readme = readAuthorFile(join15(extension.dir, "README.md"), MAX_MANIFEST_BYTES);
|
|
@@ -12312,7 +12677,7 @@ function runPrepareSubmission(pathArg, deps) {
|
|
|
12312
12677
|
}
|
|
12313
12678
|
console.log(source_default.green(`Prepared ${extension.manifest.id}@${extension.manifest.version}: ${target}`));
|
|
12314
12679
|
for (const [name, content] of Object.entries(files)) {
|
|
12315
|
-
console.log(` SHA-256 ${name}: ${
|
|
12680
|
+
console.log(` SHA-256 ${name}: ${createHash7("sha256").update(content).digest("hex")}`);
|
|
12316
12681
|
}
|
|
12317
12682
|
console.log("Not published. No code was executed and nothing was uploaded.");
|
|
12318
12683
|
console.log(`Fork and clone https://${HACKSTORE_REGISTRY_REPO}, then copy this extensions directory into your fork.`);
|
|
@@ -12345,13 +12710,13 @@ function registerHackstoreCommand(program) {
|
|
|
12345
12710
|
var cachedCore2;
|
|
12346
12711
|
async function defaultCorePort2() {
|
|
12347
12712
|
if (cachedCore2) return cachedCore2;
|
|
12348
|
-
const mod = await import("./dist-
|
|
12713
|
+
const mod = await import("./dist-6RNAVFAY.js");
|
|
12349
12714
|
cachedCore2 = mod;
|
|
12350
12715
|
return mod;
|
|
12351
12716
|
}
|
|
12352
12717
|
var EXIT_OK4 = 0;
|
|
12353
12718
|
var EXIT_USER_ERROR4 = 1;
|
|
12354
|
-
function
|
|
12719
|
+
function resolve25(deps) {
|
|
12355
12720
|
return {
|
|
12356
12721
|
core: deps.core,
|
|
12357
12722
|
fetchImpl: deps.fetchImpl ?? fetch,
|
|
@@ -12384,7 +12749,7 @@ function installedViews(d) {
|
|
|
12384
12749
|
return out;
|
|
12385
12750
|
}
|
|
12386
12751
|
function runList(deps) {
|
|
12387
|
-
const d =
|
|
12752
|
+
const d = resolve25(deps);
|
|
12388
12753
|
const installed = installedViews(d);
|
|
12389
12754
|
const record2 = d.core.readEnablement(d.projectPath, d.homeDir);
|
|
12390
12755
|
const reconciled = d.core.reconcile(record2, installed);
|
|
@@ -12415,7 +12780,7 @@ function runList(deps) {
|
|
|
12415
12780
|
process.exitCode = EXIT_OK4;
|
|
12416
12781
|
}
|
|
12417
12782
|
async function runSearch(query, deps) {
|
|
12418
|
-
const d =
|
|
12783
|
+
const d = resolve25(deps);
|
|
12419
12784
|
if (d.registryUrl.trim().length === 0) {
|
|
12420
12785
|
d.out("The Hackstore is disabled (registry URL is empty), so there is nothing to search.");
|
|
12421
12786
|
d.out(" The default community Hackstore lives at github.com/0sec-labs/hackstore.");
|
|
@@ -12452,7 +12817,7 @@ async function runSearch(query, deps) {
|
|
|
12452
12817
|
process.exitCode = EXIT_OK4;
|
|
12453
12818
|
}
|
|
12454
12819
|
async function runInstall(id, deps) {
|
|
12455
|
-
const d =
|
|
12820
|
+
const d = resolve25(deps);
|
|
12456
12821
|
if (deps.local === true) {
|
|
12457
12822
|
const local = readLocalExtension(id, {
|
|
12458
12823
|
validatePluginManifest: d.core.validatePluginManifest,
|
|
@@ -12588,7 +12953,7 @@ function writePluginFiles(d, root, entry) {
|
|
|
12588
12953
|
}
|
|
12589
12954
|
}
|
|
12590
12955
|
function runEnable(id, deps) {
|
|
12591
|
-
const d =
|
|
12956
|
+
const d = resolve25(deps);
|
|
12592
12957
|
if (!d.core.isSafePluginId(id)) {
|
|
12593
12958
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12594
12959
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12641,7 +13006,7 @@ function runEnable(id, deps) {
|
|
|
12641
13006
|
process.exitCode = EXIT_OK4;
|
|
12642
13007
|
}
|
|
12643
13008
|
function runDisable(id, deps) {
|
|
12644
|
-
const d =
|
|
13009
|
+
const d = resolve25(deps);
|
|
12645
13010
|
if (!d.core.isSafePluginId(id)) {
|
|
12646
13011
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12647
13012
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12666,7 +13031,7 @@ function runDisable(id, deps) {
|
|
|
12666
13031
|
process.exitCode = EXIT_OK4;
|
|
12667
13032
|
}
|
|
12668
13033
|
function runInfo(id, deps) {
|
|
12669
|
-
const d =
|
|
13034
|
+
const d = resolve25(deps);
|
|
12670
13035
|
if (!d.core.isSafePluginId(id)) {
|
|
12671
13036
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12672
13037
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12738,7 +13103,7 @@ function parseRunArgs(pairs, jsonArgs) {
|
|
|
12738
13103
|
return { ok: true, args: args2 };
|
|
12739
13104
|
}
|
|
12740
13105
|
async function runRun(id, tool, pairs, deps) {
|
|
12741
|
-
const d =
|
|
13106
|
+
const d = resolve25(deps);
|
|
12742
13107
|
if (!d.core.isSafePluginId(id)) {
|
|
12743
13108
|
d.err(source_default.red(`"${id}" is not a valid plugin id.`));
|
|
12744
13109
|
process.exitCode = EXIT_USER_ERROR4;
|
|
@@ -12890,220 +13255,18 @@ function registerPluginCommand(program) {
|
|
|
12890
13255
|
}
|
|
12891
13256
|
|
|
12892
13257
|
// packages/cli/src/commands/theme.ts
|
|
12893
|
-
import { writeFileSync as writeFileSync16 } from "node:fs";
|
|
12894
|
-
var EXIT_OK5 = 0;
|
|
12895
13258
|
var EXIT_USER_ERROR5 = 1;
|
|
12896
|
-
var cachedCore3;
|
|
12897
|
-
async function defaultThemeCorePort() {
|
|
12898
|
-
if (cachedCore3) return cachedCore3;
|
|
12899
|
-
const mod = await import("./dist-AJU25UXA.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
13259
|
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);
|
|
13260
|
+
program.command("theme", { hidden: true }).argument("[legacy...]").allowUnknownOption(true).description("Retired terminal theme command; use browser Settings").action(() => {
|
|
13261
|
+
console.error("Terminal themes are no longer used. Run 0 web and open Settings \u2192 Appearance. Existing theme files have not been changed.");
|
|
13262
|
+
process.exitCode = EXIT_USER_ERROR5;
|
|
13100
13263
|
});
|
|
13101
13264
|
}
|
|
13102
13265
|
|
|
13103
13266
|
// packages/cli/src/commands/evolve.ts
|
|
13104
|
-
import { readFileSync as
|
|
13105
|
-
import { resolve as
|
|
13106
|
-
var
|
|
13267
|
+
import { readFileSync as readFileSync21, existsSync as existsSync15 } from "node:fs";
|
|
13268
|
+
import { resolve as resolve26 } from "node:path";
|
|
13269
|
+
var EXIT_OK5 = 0;
|
|
13107
13270
|
var EXIT_USER_ERROR6 = 1;
|
|
13108
13271
|
var EXIT_RUNTIME_ERROR = 2;
|
|
13109
13272
|
var EXIT_INTERRUPT = 3;
|
|
@@ -13237,7 +13400,7 @@ function registerEvolveCommand(program) {
|
|
|
13237
13400
|
else formatEvaluationResult(result, Boolean(opts.json), out);
|
|
13238
13401
|
if (result.iterations.length === 0) break;
|
|
13239
13402
|
}
|
|
13240
|
-
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT :
|
|
13403
|
+
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT : EXIT_OK5;
|
|
13241
13404
|
} catch (error) {
|
|
13242
13405
|
const message = error instanceof Error ? error.message : String(error);
|
|
13243
13406
|
if (opts.json) out(JSON.stringify({ error: message }));
|
|
@@ -13249,7 +13412,7 @@ function registerEvolveCommand(program) {
|
|
|
13249
13412
|
});
|
|
13250
13413
|
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
13414
|
try {
|
|
13252
|
-
const storePath = opts.store ?
|
|
13415
|
+
const storePath = opts.store ? resolve26(opts.store) : void 0;
|
|
13253
13416
|
if (!storePath) {
|
|
13254
13417
|
console.error(source_default.red("--store <path> is required. Point it to the evolution store directory containing registry.json."));
|
|
13255
13418
|
process.exitCode = EXIT_USER_ERROR6;
|
|
@@ -13278,7 +13441,7 @@ function registerEvolveCommand(program) {
|
|
|
13278
13441
|
if (campaign.status === "blocked" || campaign.status === "exhausted") console.log(` ${campaign.resumeReason}`);
|
|
13279
13442
|
}
|
|
13280
13443
|
}
|
|
13281
|
-
process.exitCode =
|
|
13444
|
+
process.exitCode = EXIT_OK5;
|
|
13282
13445
|
} catch (error) {
|
|
13283
13446
|
const message = error instanceof Error ? error.message : String(error);
|
|
13284
13447
|
if (opts.json) {
|
|
@@ -13291,9 +13454,9 @@ function registerEvolveCommand(program) {
|
|
|
13291
13454
|
});
|
|
13292
13455
|
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
13456
|
try {
|
|
13294
|
-
const ledger = reconcileCampaignDispatch(
|
|
13457
|
+
const ledger = reconcileCampaignDispatch(resolve26(opts.store), opts.dispatch, opts.costUsd, opts.receiptDigest);
|
|
13295
13458
|
console.log(opts.json ? JSON.stringify(ledger) : `Reconciled ${opts.dispatch}; campaign ${ledger.status}`);
|
|
13296
|
-
process.exitCode =
|
|
13459
|
+
process.exitCode = EXIT_OK5;
|
|
13297
13460
|
} catch (error) {
|
|
13298
13461
|
const message = error instanceof Error ? error.message : String(error);
|
|
13299
13462
|
if (opts.json) console.log(JSON.stringify({ error: message }));
|
|
@@ -13306,10 +13469,10 @@ function registerEvolveCommand(program) {
|
|
|
13306
13469
|
const interrupt = () => controller.abort();
|
|
13307
13470
|
process.once("SIGINT", interrupt);
|
|
13308
13471
|
try {
|
|
13309
|
-
const result = await approveEvolutionCandidate(
|
|
13472
|
+
const result = await approveEvolutionCandidate(resolve26(opts.store), opts.version, { signal: controller.signal });
|
|
13310
13473
|
if (opts.json) console.log(JSON.stringify(result));
|
|
13311
13474
|
else console.log(`Promoted ${result.versionId}; canary cost $${result.evaluationCostUsd.toFixed(4)}`);
|
|
13312
|
-
process.exitCode =
|
|
13475
|
+
process.exitCode = EXIT_OK5;
|
|
13313
13476
|
} catch (error) {
|
|
13314
13477
|
const message = error instanceof Error ? error.message : String(error);
|
|
13315
13478
|
if (opts.json) console.log(JSON.stringify({ error: message }));
|
|
@@ -13321,7 +13484,7 @@ function registerEvolveCommand(program) {
|
|
|
13321
13484
|
});
|
|
13322
13485
|
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
13486
|
try {
|
|
13324
|
-
const storePath =
|
|
13487
|
+
const storePath = resolve26(opts.store);
|
|
13325
13488
|
if (!existsSync15(storePath)) {
|
|
13326
13489
|
console.error(source_default.red(`store directory not found: ${storePath}`));
|
|
13327
13490
|
process.exitCode = EXIT_USER_ERROR6;
|
|
@@ -13337,7 +13500,7 @@ function registerEvolveCommand(program) {
|
|
|
13337
13500
|
await rollbackEvolutionVersion(storePath, opts.version, opts.reason);
|
|
13338
13501
|
console.log(source_default.green(`Retired ${opts.version.slice(0, 12)}\u2026; restored ${loadEvolutionRegistry(storePath).activeId}`));
|
|
13339
13502
|
console.log(` Reason: ${opts.reason}`);
|
|
13340
|
-
process.exitCode =
|
|
13503
|
+
process.exitCode = EXIT_OK5;
|
|
13341
13504
|
} catch (error) {
|
|
13342
13505
|
const message = error instanceof Error ? error.message : String(error);
|
|
13343
13506
|
console.error(source_default.red(`Rollback failed: ${message}`));
|
|
@@ -13372,7 +13535,7 @@ function registerEvolveCommand(program) {
|
|
|
13372
13535
|
if (exec.error) err(source_default.red(` ${exec.error}`));
|
|
13373
13536
|
}
|
|
13374
13537
|
formatExecResult(executionResult.versionId, executionResult, Boolean(opts.json), out);
|
|
13375
|
-
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT : hasError ? EXIT_RUNTIME_ERROR :
|
|
13538
|
+
process.exitCode = abortController.signal.aborted ? EXIT_INTERRUPT : hasError ? EXIT_RUNTIME_ERROR : EXIT_OK5;
|
|
13376
13539
|
} catch (error) {
|
|
13377
13540
|
const message = error instanceof Error ? error.message : String(error);
|
|
13378
13541
|
if (opts.json) {
|
|
@@ -13389,12 +13552,12 @@ function registerEvolveCommand(program) {
|
|
|
13389
13552
|
const feedback = evolve.command("feedback").description("Capture, approve, and inspect evolution feedback candidates");
|
|
13390
13553
|
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
13554
|
try {
|
|
13392
|
-
const input = parseObservationInput(JSON.parse(
|
|
13555
|
+
const input = parseObservationInput(JSON.parse(readFileSync21(resolve26(opts.input), "utf8")));
|
|
13393
13556
|
const result = captureObservation({ ...input, consent: opts.allowSourceAccess === true }, {
|
|
13394
|
-
...opts.store ? { storePath:
|
|
13557
|
+
...opts.store ? { storePath: resolve26(opts.store) } : {}
|
|
13395
13558
|
});
|
|
13396
13559
|
console.log(JSON.stringify(result, null, 2));
|
|
13397
|
-
process.exitCode =
|
|
13560
|
+
process.exitCode = EXIT_OK5;
|
|
13398
13561
|
} catch (error) {
|
|
13399
13562
|
console.error(source_default.red(`Feedback capture failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
13400
13563
|
process.exitCode = EXIT_RUNTIME_ERROR;
|
|
@@ -13402,14 +13565,14 @@ function registerEvolveCommand(program) {
|
|
|
13402
13565
|
});
|
|
13403
13566
|
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
13567
|
try {
|
|
13405
|
-
const shape = parseApprovedObservationShape(JSON.parse(
|
|
13568
|
+
const shape = parseApprovedObservationShape(JSON.parse(readFileSync21(resolve26(opts.fixtures), "utf8")));
|
|
13406
13569
|
const result = approveObservation(opts.id, shape, {
|
|
13407
|
-
...opts.store ? { storePath:
|
|
13570
|
+
...opts.store ? { storePath: resolve26(opts.store) } : {},
|
|
13408
13571
|
...opts.allowSourceAccess === true ? { allowModelSourceAccess: true } : {}
|
|
13409
13572
|
});
|
|
13410
13573
|
if (!result) throw new Error("observation was not found or is not pending");
|
|
13411
13574
|
console.log(JSON.stringify(result, null, 2));
|
|
13412
|
-
process.exitCode =
|
|
13575
|
+
process.exitCode = EXIT_OK5;
|
|
13413
13576
|
} catch (error) {
|
|
13414
13577
|
console.error(source_default.red(`Feedback approval failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
13415
13578
|
process.exitCode = EXIT_RUNTIME_ERROR;
|
|
@@ -13417,11 +13580,11 @@ function registerEvolveCommand(program) {
|
|
|
13417
13580
|
});
|
|
13418
13581
|
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
13582
|
try {
|
|
13420
|
-
if (!releaseClaim(opts.id, opts.claimToken, opts.store ? { storePath:
|
|
13583
|
+
if (!releaseClaim(opts.id, opts.claimToken, opts.store ? { storePath: resolve26(opts.store) } : {})) {
|
|
13421
13584
|
throw new Error("observation or processing claim no longer matches");
|
|
13422
13585
|
}
|
|
13423
13586
|
console.log(`Released feedback claim ${opts.id}`);
|
|
13424
|
-
process.exitCode =
|
|
13587
|
+
process.exitCode = EXIT_OK5;
|
|
13425
13588
|
} catch (error) {
|
|
13426
13589
|
console.error(`Feedback release failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
13427
13590
|
process.exitCode = EXIT_USER_ERROR6;
|
|
@@ -13429,11 +13592,11 @@ function registerEvolveCommand(program) {
|
|
|
13429
13592
|
});
|
|
13430
13593
|
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
13594
|
try {
|
|
13432
|
-
const observations = listObservations(void 0, { ...opts.store ? { storePath:
|
|
13595
|
+
const observations = listObservations(void 0, { ...opts.store ? { storePath: resolve26(opts.store) } : {} });
|
|
13433
13596
|
if (opts.json) console.log(JSON.stringify(observations, null, 2));
|
|
13434
13597
|
else if (observations.length === 0) console.log("No feedback observations.");
|
|
13435
13598
|
else for (const observation of observations) console.log(`${observation.id} ${observation.status} ${observation.classHint}`);
|
|
13436
|
-
process.exitCode =
|
|
13599
|
+
process.exitCode = EXIT_OK5;
|
|
13437
13600
|
} catch (error) {
|
|
13438
13601
|
console.error(source_default.red(`Feedback status failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
13439
13602
|
process.exitCode = EXIT_RUNTIME_ERROR;
|
|
@@ -13443,11 +13606,11 @@ function registerEvolveCommand(program) {
|
|
|
13443
13606
|
|
|
13444
13607
|
// packages/cli/src/commands/learning.ts
|
|
13445
13608
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
13446
|
-
import { isAbsolute as isAbsolute3, resolve as
|
|
13609
|
+
import { isAbsolute as isAbsolute3, resolve as resolve27 } from "node:path";
|
|
13447
13610
|
import { homedir as homedir3 } from "node:os";
|
|
13448
13611
|
async function defaultService() {
|
|
13449
|
-
const { LearningService, HuntMemoryStore } = await import("./dist-
|
|
13450
|
-
const { SecurityWorkflowStore: SecurityWorkflowStore2, learningProjectId } = await import("./dist-
|
|
13612
|
+
const { LearningService, HuntMemoryStore } = await import("./dist-6RNAVFAY.js");
|
|
13613
|
+
const { SecurityWorkflowStore: SecurityWorkflowStore2, learningProjectId } = await import("./dist-OLGNKDB2.js");
|
|
13451
13614
|
const workflows = new SecurityWorkflowStore2();
|
|
13452
13615
|
const store = workflows.learningStore();
|
|
13453
13616
|
const service = new LearningService(store, { workflows });
|
|
@@ -13461,7 +13624,7 @@ async function defaultService() {
|
|
|
13461
13624
|
if (isAbsolute3(source) || /^\.{1,2}\//.test(source) || source.startsWith("~/")) {
|
|
13462
13625
|
let root;
|
|
13463
13626
|
try {
|
|
13464
|
-
root = realpathSync3(source.startsWith("~/") ?
|
|
13627
|
+
root = realpathSync3(source.startsWith("~/") ? resolve27(homedir3(), source.slice(2)) : source);
|
|
13465
13628
|
} catch {
|
|
13466
13629
|
}
|
|
13467
13630
|
if (root) service.importCodebaseNotes(project(selected), root, new HuntMemoryStore());
|
|
@@ -13549,16 +13712,34 @@ function registerLearningCommand(program, deps = {}) {
|
|
|
13549
13712
|
}
|
|
13550
13713
|
|
|
13551
13714
|
// packages/cli/src/commands/config.ts
|
|
13552
|
-
import { readFileSync as
|
|
13553
|
-
var
|
|
13715
|
+
import { readFileSync as readFileSync22, writeFileSync as writeFileSync16 } from "node:fs";
|
|
13716
|
+
var EXIT_OK6 = 0;
|
|
13554
13717
|
var EXIT_USER_ERROR7 = 1;
|
|
13718
|
+
var CLI_CONFIG_KEYS = [
|
|
13719
|
+
"busyInputMode",
|
|
13720
|
+
"autoCompaction",
|
|
13721
|
+
"compactionThreshold",
|
|
13722
|
+
"allowSubagentPeerMessaging",
|
|
13723
|
+
"allowSubagentOperatorMessaging",
|
|
13724
|
+
"allowModelSelfExtension",
|
|
13725
|
+
"allowDevSourceUpdates",
|
|
13726
|
+
"executionProfile",
|
|
13727
|
+
"analyticsLevel",
|
|
13728
|
+
"diagnosticReporting",
|
|
13729
|
+
"updatePolicy"
|
|
13730
|
+
];
|
|
13731
|
+
var PUBLIC_CONFIG_KEYS = new Set(CLI_CONFIG_KEYS);
|
|
13732
|
+
var INTERNAL_CONFIG_KEYS = /* @__PURE__ */ new Set(["onboardingCompleted", "diagnosticReportingPrompted", "modelPreference"]);
|
|
13733
|
+
function publicConfig(settings) {
|
|
13734
|
+
return Object.fromEntries(CLI_CONFIG_KEYS.map((key) => [key, settings[key]]));
|
|
13735
|
+
}
|
|
13555
13736
|
var SECURITY_KEYS = SETTING_DEFS.filter(
|
|
13556
13737
|
(d) => d.group === "Security"
|
|
13557
13738
|
).map((d) => d.key);
|
|
13558
|
-
function
|
|
13739
|
+
function outOf(deps) {
|
|
13559
13740
|
return deps.out ?? ((l) => console.log(l));
|
|
13560
13741
|
}
|
|
13561
|
-
function
|
|
13742
|
+
function errOf(deps) {
|
|
13562
13743
|
return deps.err ?? ((l) => console.error(l));
|
|
13563
13744
|
}
|
|
13564
13745
|
function renderValue(value) {
|
|
@@ -13567,39 +13748,39 @@ function renderValue(value) {
|
|
|
13567
13748
|
return String(value);
|
|
13568
13749
|
}
|
|
13569
13750
|
function runConfigShow(deps = {}) {
|
|
13570
|
-
const out =
|
|
13751
|
+
const out = outOf(deps);
|
|
13571
13752
|
const { settings, sources } = loadLayeredSettings({
|
|
13572
13753
|
homeDir: deps.homeDir,
|
|
13573
13754
|
projectDir: deps.projectDir
|
|
13574
13755
|
});
|
|
13575
|
-
out(source_default.bold("Effective
|
|
13756
|
+
out(source_default.bold("Effective engine configuration"));
|
|
13576
13757
|
out(source_default.dim(` global: ${settingsFilePath(deps.homeDir)}`));
|
|
13577
13758
|
out(source_default.dim(` project: ${projectSettingsFilePath(deps.projectDir)}`));
|
|
13578
13759
|
out("");
|
|
13579
|
-
const keys =
|
|
13760
|
+
const keys = CLI_CONFIG_KEYS;
|
|
13580
13761
|
const width = Math.max(...keys.map((k) => k.length));
|
|
13581
13762
|
for (const key of keys) {
|
|
13582
13763
|
const layer = sources[key];
|
|
13583
13764
|
const tag = layer === "project" ? source_default.cyan("[project]") : layer === "global" ? source_default.green("[global]") : source_default.dim("[default]");
|
|
13584
13765
|
out(` ${key.padEnd(width)} ${renderValue(settings[key]).padEnd(11)} ${tag}`);
|
|
13585
13766
|
}
|
|
13586
|
-
process.exitCode =
|
|
13767
|
+
process.exitCode = EXIT_OK6;
|
|
13587
13768
|
}
|
|
13588
13769
|
function runConfigExport(file, deps = {}) {
|
|
13589
|
-
const out =
|
|
13590
|
-
const err =
|
|
13770
|
+
const out = outOf(deps);
|
|
13771
|
+
const err = errOf(deps);
|
|
13591
13772
|
const settings = deps.global ? loadGlobalSettings(deps.homeDir) : loadLayeredSettings({ homeDir: deps.homeDir, projectDir: deps.projectDir }).settings;
|
|
13592
|
-
const json = `${JSON.stringify(settings, null, 2)}
|
|
13773
|
+
const json = `${JSON.stringify(publicConfig(settings), null, 2)}
|
|
13593
13774
|
`;
|
|
13594
13775
|
if (!file) {
|
|
13595
13776
|
out(json.trimEnd());
|
|
13596
|
-
process.exitCode =
|
|
13777
|
+
process.exitCode = EXIT_OK6;
|
|
13597
13778
|
return;
|
|
13598
13779
|
}
|
|
13599
13780
|
try {
|
|
13600
|
-
|
|
13781
|
+
writeFileSync16(file, json, "utf8");
|
|
13601
13782
|
out(source_default.green(`Exported ${deps.global ? "global" : "effective"} config to ${file}.`));
|
|
13602
|
-
process.exitCode =
|
|
13783
|
+
process.exitCode = EXIT_OK6;
|
|
13603
13784
|
} catch (e) {
|
|
13604
13785
|
err(source_default.red(`Could not write ${file}: ${e instanceof Error ? e.message : String(e)}`));
|
|
13605
13786
|
process.exitCode = EXIT_USER_ERROR7;
|
|
@@ -13612,24 +13793,32 @@ function extractConfigBag(parsed) {
|
|
|
13612
13793
|
return parsed;
|
|
13613
13794
|
}
|
|
13614
13795
|
function runConfigImport(file, deps = {}) {
|
|
13615
|
-
const out =
|
|
13616
|
-
const err =
|
|
13796
|
+
const out = outOf(deps);
|
|
13797
|
+
const err = errOf(deps);
|
|
13617
13798
|
const scope = deps.scope ?? "global";
|
|
13618
13799
|
let parsed;
|
|
13619
13800
|
try {
|
|
13620
|
-
parsed = JSON.parse(
|
|
13801
|
+
parsed = JSON.parse(readFileSync22(file, "utf8"));
|
|
13621
13802
|
} catch (e) {
|
|
13622
13803
|
err(source_default.red(`Could not read ${file}: ${e instanceof Error ? e.message : String(e)}`));
|
|
13623
13804
|
process.exitCode = EXIT_USER_ERROR7;
|
|
13624
13805
|
return;
|
|
13625
13806
|
}
|
|
13626
13807
|
const bag = extractConfigBag(parsed);
|
|
13808
|
+
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)) : [];
|
|
13809
|
+
if (legacyKeys.length) {
|
|
13810
|
+
err(source_default.red(`Retired terminal settings cannot be imported: ${legacyKeys.join(", ")}. Nothing was written.`));
|
|
13811
|
+
err("Use 0 web \u2192 Settings for browser appearance. Remove retired keys to import engine settings.");
|
|
13812
|
+
process.exitCode = EXIT_USER_ERROR7;
|
|
13813
|
+
return;
|
|
13814
|
+
}
|
|
13627
13815
|
const patch = sanitizeOverrides(bag);
|
|
13628
13816
|
const profile = typeof bag === "object" && bag !== null ? bag["executionProfile"] : void 0;
|
|
13629
13817
|
const profileChoices = SETTING_DEFS.find((def) => def.key === "executionProfile")?.choices;
|
|
13630
13818
|
if (scope === "global" && typeof profile === "string" && profileChoices?.includes(profile)) {
|
|
13631
13819
|
patch.executionProfile = profile;
|
|
13632
13820
|
}
|
|
13821
|
+
for (const key of Object.keys(patch)) if (!PUBLIC_CONFIG_KEYS.has(key)) delete patch[key];
|
|
13633
13822
|
const patchKeys = Object.keys(patch);
|
|
13634
13823
|
const skipped = typeof bag === "object" && bag !== null && !Array.isArray(bag) ? Object.keys(bag).filter((k) => !patchKeys.includes(k)) : [];
|
|
13635
13824
|
if (patchKeys.length === 0) {
|
|
@@ -13670,10 +13859,10 @@ function runConfigImport(file, deps = {}) {
|
|
|
13670
13859
|
}
|
|
13671
13860
|
if (changes.length === 0) out(source_default.dim(" (all imported values already matched the current config)"));
|
|
13672
13861
|
if (skipped.length > 0) out(source_default.dim(` Skipped unknown/invalid keys: ${skipped.join(", ")}`));
|
|
13673
|
-
process.exitCode =
|
|
13862
|
+
process.exitCode = EXIT_OK6;
|
|
13674
13863
|
}
|
|
13675
13864
|
function registerConfigCommand(program) {
|
|
13676
|
-
const config = program.command("config").description("Inspect, export, and import
|
|
13865
|
+
const config = program.command("config").description("Inspect, export, and import engine configuration (global and project layers)");
|
|
13677
13866
|
config.command("show").description("Show the effective config with the source layer (default/global/project) per key").action(() => {
|
|
13678
13867
|
runConfigShow();
|
|
13679
13868
|
});
|
|
@@ -13731,16 +13920,16 @@ function registerReviewChecksCommand(program) {
|
|
|
13731
13920
|
import { open } from "node:fs/promises";
|
|
13732
13921
|
import { constants as constants4 } from "node:fs";
|
|
13733
13922
|
var defaults = {
|
|
13734
|
-
createRemoteRuntime: async (options) => (await import("./remote-workflow-runtime-
|
|
13923
|
+
createRemoteRuntime: async (options) => (await import("./remote-workflow-runtime-6CEVRZXS.js")).createRemoteWorkflowRuntime(options),
|
|
13735
13924
|
createRuntime: async (options) => {
|
|
13736
|
-
const { createCliWorkflowRuntime } = await import("./workflow-runtime-
|
|
13925
|
+
const { createCliWorkflowRuntime } = await import("./workflow-runtime-PLB32XC3.js");
|
|
13737
13926
|
return await createCliWorkflowRuntime(options);
|
|
13738
13927
|
},
|
|
13739
13928
|
out: (text2) => process.stdout.write(`${text2}
|
|
13740
13929
|
`),
|
|
13741
13930
|
err: (text2) => process.stderr.write(`${text2}
|
|
13742
13931
|
`),
|
|
13743
|
-
sleep: () => new Promise((
|
|
13932
|
+
sleep: () => new Promise((resolve29) => setTimeout(resolve29, 100))
|
|
13744
13933
|
};
|
|
13745
13934
|
function positive(value, name, integer = false) {
|
|
13746
13935
|
if (value === void 0) return void 0;
|
|
@@ -13941,9 +14130,9 @@ function registerWorkflowCommand(program, deps = defaults) {
|
|
|
13941
14130
|
}
|
|
13942
14131
|
|
|
13943
14132
|
// packages/cli/src/commands/team.ts
|
|
13944
|
-
import { constants as constants5, closeSync as closeSync4, fstatSync as fstatSync3, openSync as openSync4, readFileSync as
|
|
14133
|
+
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
14134
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
13946
|
-
import { resolve as
|
|
14135
|
+
import { resolve as resolve28 } from "node:path";
|
|
13947
14136
|
import { emitKeypressEvents } from "node:readline";
|
|
13948
14137
|
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
14138
|
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 +14142,7 @@ function readPrivateConfig(path) {
|
|
|
13953
14142
|
const stat3 = fstatSync3(fd);
|
|
13954
14143
|
if (!stat3.isFile() || (stat3.mode & 63) !== 0) throw new Error("Team configuration must be a private regular file (chmod 600)");
|
|
13955
14144
|
if (stat3.size > 1024 * 1024) throw new Error("Team configuration is too large");
|
|
13956
|
-
const cfg = configSchema.parse(JSON.parse(
|
|
14145
|
+
const cfg = configSchema.parse(JSON.parse(readFileSync23(fd, "utf8")));
|
|
13957
14146
|
if (new Set(cfg.users.map((user) => user.id)).size !== cfg.users.length) throw new Error("Team user IDs must be unique");
|
|
13958
14147
|
return cfg;
|
|
13959
14148
|
} finally {
|
|
@@ -14005,7 +14194,7 @@ async function readPassword() {
|
|
|
14005
14194
|
function writeNew(path, config) {
|
|
14006
14195
|
const fd = openSync4(path, "wx", 384);
|
|
14007
14196
|
try {
|
|
14008
|
-
|
|
14197
|
+
writeFileSync17(fd, `${JSON.stringify(config, null, 2)}
|
|
14009
14198
|
`, "utf8");
|
|
14010
14199
|
} catch (error) {
|
|
14011
14200
|
try {
|
|
@@ -14036,11 +14225,11 @@ function registerTeamCommand(program, dependencies = {}) {
|
|
|
14036
14225
|
const opts = init.opts();
|
|
14037
14226
|
const member = memberSchema.parse({ id: opts.owner, name: opts.displayName, role: "owner" });
|
|
14038
14227
|
const workspace = configSchema.shape.workspace.parse({ id: randomUUID3(), name: opts.name });
|
|
14039
|
-
const path =
|
|
14228
|
+
const path = resolve28(opts.config);
|
|
14040
14229
|
const fd = openSync4(path, "wx", 384);
|
|
14041
14230
|
try {
|
|
14042
14231
|
member.passwordHash = await hashTeamPassword(await password());
|
|
14043
|
-
|
|
14232
|
+
writeFileSync17(fd, `${JSON.stringify({ workspace, users: [member] }, null, 2)}
|
|
14044
14233
|
`, "utf8");
|
|
14045
14234
|
} catch (failure) {
|
|
14046
14235
|
try {
|
|
@@ -14057,7 +14246,7 @@ function registerTeamCommand(program, dependencies = {}) {
|
|
|
14057
14246
|
add.action(perform(async () => {
|
|
14058
14247
|
const opts = add.opts();
|
|
14059
14248
|
const member = memberSchema.parse({ id: opts.user, name: opts.displayName, role: opts.role });
|
|
14060
|
-
const path =
|
|
14249
|
+
const path = resolve28(opts.config);
|
|
14061
14250
|
const lock = `${path}.lock`;
|
|
14062
14251
|
const lockFD = openSync4(lock, "wx", 384);
|
|
14063
14252
|
const temporary = `${path}.${randomUUID3()}.tmp`;
|
|
@@ -14081,7 +14270,7 @@ function registerTeamCommand(program, dependencies = {}) {
|
|
|
14081
14270
|
}));
|
|
14082
14271
|
const list = team.command("list").description("List workspace accounts without credentials").requiredOption("--config <path>", "Team configuration");
|
|
14083
14272
|
list.action(perform(() => {
|
|
14084
|
-
const config = readPrivateConfig(
|
|
14273
|
+
const config = readPrivateConfig(resolve28(list.opts().config));
|
|
14085
14274
|
out(JSON.stringify({ workspace: config.workspace, users: config.users.map(({ id, name, role }) => ({ id, name, role })) }, null, 2));
|
|
14086
14275
|
}));
|
|
14087
14276
|
}
|
|
@@ -14133,6 +14322,7 @@ export {
|
|
|
14133
14322
|
registerResumeCommand,
|
|
14134
14323
|
registerReviewChecksCommand,
|
|
14135
14324
|
registerReviewCommand,
|
|
14325
|
+
registerRoutingCommand,
|
|
14136
14326
|
registerScanCommand,
|
|
14137
14327
|
registerSecureCommand,
|
|
14138
14328
|
registerSpecdriftCommand,
|