@qwen-code/qwen-code 0.21.5 → 0.21.6-preview.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/bundled/qc-helper/docs/configuration/model-providers.md +8 -8
- package/bundled/qc-helper/docs/configuration/settings.md +15 -15
- package/bundled/qc-helper/docs/features/code-review.md +2 -0
- package/bundled/qc-helper/docs/features/headless.md +31 -0
- package/bundled/qc-helper/docs/qwen-serve.md +75 -0
- package/bundled/review/SKILL.md +59 -52
- package/chunks/{MaxSizedBox-2MWU5JYB.js → MaxSizedBox-A3UYJS6B.js} +8 -7
- package/chunks/{StandaloneSessionPicker-B6MI5NTB.js → StandaloneSessionPicker-NGLY26I4.js} +21 -20
- package/chunks/{acpAgent-MRPYN6FH.js → acpAgent-V54T2EEL.js} +215 -63
- package/chunks/{agent-NAOXNW4I.js → agent-2P53VL2L.js} +8 -7
- package/chunks/{agent-headless-L4PPVFKW.js → agent-headless-6X4GCFRD.js} +8 -7
- package/chunks/{bridge-LHXGYNCO.js → bridge-TCFMLKHR.js} +12 -10
- package/chunks/{channel-settings-store-QB54TLYE.js → channel-settings-store-B4HNMNQV.js} +13 -12
- package/chunks/{channel-worker-group-NDG4WOOZ.js → channel-worker-group-SVGPDH2C.js} +3 -2
- package/chunks/{channel-worker-manager-ZCW6UW34.js → channel-worker-manager-72ZK2GTS.js} +3 -2
- package/chunks/{channel-worker-supervisor-ATGFTZRN.js → channel-worker-supervisor-NUEDVHX4.js} +2 -1
- package/chunks/{chunk-UWSXFI6E.js → chunk-2U7GPHA6.js} +6 -2
- package/chunks/{chunk-CIUUYB23.js → chunk-3DTM3RPU.js} +1 -1
- package/chunks/{chunk-7MFQLOHZ.js → chunk-3PRJYMXC.js} +1 -1
- package/chunks/{chunk-K6VEL5KP.js → chunk-3ZRS2XNY.js} +1 -1
- package/chunks/{chunk-GBY3ODW7.js → chunk-4E5PO6R7.js} +3 -3
- package/chunks/{chunk-KH2BIJ4H.js → chunk-4T6QMNX2.js} +89 -6
- package/chunks/{chunk-K64OI7S7.js → chunk-546CDN6D.js} +1 -1
- package/chunks/{chunk-J7I2BZHS.js → chunk-5CDI4UOY.js} +23 -6
- package/chunks/{chunk-7W5KOBYU.js → chunk-6D6V55ZQ.js} +1 -1
- package/chunks/{chunk-WU5NBSLD.js → chunk-6KEN3RIC.js} +3 -3
- package/chunks/{chunk-FEUXV3DC.js → chunk-6KZP75GT.js} +1 -1
- package/chunks/{chunk-B3EBIZUY.js → chunk-72DZPDH4.js} +1 -1
- package/chunks/{chunk-TCOJPG2P.js → chunk-7FUVSN4D.js} +1 -1
- package/chunks/{chunk-EXHQZBVJ.js → chunk-AFZTZLFB.js} +2 -2
- package/chunks/{chunk-AEWOKOJY.js → chunk-AU3XNTMV.js} +1 -1
- package/chunks/{chunk-C6ARWPCG.js → chunk-AVDEBBMI.js} +2 -2
- package/chunks/chunk-BKHCW2BI.js +41 -0
- package/chunks/{chunk-ZLGPHA34.js → chunk-BU4BRCPX.js} +4 -4
- package/chunks/{chunk-3GOCVBYR.js → chunk-C4GRKMUL.js} +4 -4
- package/chunks/{chunk-VOA2UPZM.js → chunk-CDHNGCJI.js} +3 -3
- package/chunks/{chunk-3H5RFLTS.js → chunk-CJBRIJ7W.js} +1 -1
- package/chunks/{chunk-D7QAZ5DF.js → chunk-CXYBX4AL.js} +1 -1
- package/chunks/{chunk-GEP54CHX.js → chunk-DBIEZC7T.js} +3 -3
- package/chunks/{chunk-BWLUCN35.js → chunk-DG563ZCS.js} +2 -2
- package/chunks/{chunk-YLL3SC5S.js → chunk-DOA7MCDY.js} +167 -99
- package/chunks/{chunk-OIGB253L.js → chunk-DOICUTPO.js} +7 -7
- package/chunks/{chunk-VJPF6GF2.js → chunk-EHMN6SEG.js} +2 -2
- package/chunks/{chunk-YO4JI7B4.js → chunk-EKWNNQQD.js} +4 -4
- package/chunks/{chunk-B2RBYP7Z.js → chunk-FDV3CXTD.js} +2 -2
- package/chunks/{chunk-LMNM37OE.js → chunk-HKNSU4WX.js} +1 -1
- package/chunks/{chunk-4LLUH3A7.js → chunk-HU5TUALO.js} +95 -8
- package/chunks/{chunk-G2UXFO2B.js → chunk-IISDPZ5X.js} +1 -1
- package/chunks/{chunk-LYPXNRBX.js → chunk-IKXE3AAC.js} +1 -1
- package/chunks/{chunk-TJ56V3AR.js → chunk-MFBUJMQ3.js} +3 -3
- package/chunks/{chunk-SQTA6PAY.js → chunk-MVLM6PJK.js} +1 -1
- package/chunks/{chunk-4NEBUDWS.js → chunk-N47ZM2KI.js} +9 -9
- package/chunks/{chunk-5HWAJ4BK.js → chunk-NAYPZ72V.js} +1 -1
- package/chunks/{chunk-IZ2CMEYO.js → chunk-NKST54XA.js} +1 -1
- package/chunks/{chunk-IK3RYLAD.js → chunk-NYZAL2W2.js} +3 -3
- package/chunks/{chunk-ZPGMDT4S.js → chunk-O656RSMC.js} +19 -92
- package/chunks/{chunk-XD2PNH3K.js → chunk-P7LKADIT.js} +5 -5
- package/chunks/{chunk-JDNWIXHJ.js → chunk-PQTK2FVO.js} +3 -3
- package/chunks/{chunk-LSYVASZS.js → chunk-QG2ACINA.js} +1 -1
- package/chunks/{chunk-IWYXZAGT.js → chunk-QWUYFMAR.js} +24 -24
- package/chunks/{chunk-YMUZQ3MQ.js → chunk-RTWF7FF7.js} +3 -3
- package/chunks/{chunk-5XNO4AW7.js → chunk-SPUDIAHX.js} +11 -11
- package/chunks/{chunk-7M2RLFNX.js → chunk-SQ3ZJOYL.js} +11 -11
- package/chunks/{chunk-SJMCYCUQ.js → chunk-T4XY5CT4.js} +4 -4
- package/chunks/{chunk-2JBETW4S.js → chunk-TVFC3XF5.js} +5 -5
- package/chunks/{chunk-NLQIEY6W.js → chunk-VDLXPEI5.js} +3 -3
- package/chunks/{chunk-Q2V4AOQL.js → chunk-WAOLM6SQ.js} +1 -1
- package/chunks/{chunk-N3RERU5N.js → chunk-WIPQR44Y.js} +3 -3
- package/chunks/{chunk-PDDYAXL2.js → chunk-WIRAPZ62.js} +7 -0
- package/chunks/chunk-WOJZWRAZ.js +123 -0
- package/chunks/{chunk-SVIEVA3L.js → chunk-WPKIU4PA.js} +28 -3
- package/chunks/{chunk-K2ETEWG6.js → chunk-WVRJKSIG.js} +1 -1
- package/chunks/{chunk-WTM5QONI.js → chunk-WXS647W5.js} +2 -2
- package/chunks/{chunk-4O6HLCOF.js → chunk-X6DV3WKN.js} +1 -1
- package/chunks/{chunk-OGAARVN7.js → chunk-XKTCA6BW.js} +3 -3
- package/chunks/{chunk-FHPKHXHT.js → chunk-XNZBXQCG.js} +4 -0
- package/chunks/{chunk-GP4IMBX5.js → chunk-XOZ2R6XI.js} +529 -259
- package/chunks/{chunk-IWGMDSC3.js → chunk-XSGQKR37.js} +4 -4
- package/chunks/{chunk-ZLJQIGCH.js → chunk-XZCMQUOF.js} +8 -0
- package/chunks/{chunk-P3SLTSNY.js → chunk-Y5HIDFKZ.js} +4 -4
- package/chunks/{chunk-RM3F46UT.js → chunk-YUVTZ4UH.js} +6 -6
- package/chunks/{chunk-3P4GP4S2.js → chunk-Z5S6KH2B.js} +1 -1
- package/chunks/{chunk-4NNR24EP.js → chunk-ZH7G3A4U.js} +3 -3
- package/chunks/{chunk-CAX76R46.js → chunk-ZQL73PPE.js} +1 -1
- package/chunks/{computer-use-XDOGP2KA.js → computer-use-GTOP2CVH.js} +8 -7
- package/chunks/{config-utils-E3ZQTHGM.js → config-utils-LIRO7NSU.js} +2 -2
- package/chunks/{contextCommand-N3LQDCYJ.js → contextCommand-K6T6RRF3.js} +10 -9
- package/chunks/{core-runtime-STAFP45W.js → core-runtime-D2626QQU.js} +8 -7
- package/chunks/{create-sub-session-2B3JENWD.js → create-sub-session-MWUWNBM6.js} +8 -7
- package/chunks/{daemon-status-provider-PPAH3ATF.js → daemon-status-provider-2EHRZZVF.js} +16 -14
- package/chunks/{daemon-trust-policy-X6XL3MB4.js → daemon-trust-policy-B3EPDJDR.js} +13 -12
- package/chunks/{daemon-trust-policy-monitor-M5LBL2HD.js → daemon-trust-policy-monitor-MFM5X26G.js} +13 -12
- package/chunks/{deferred-core-runtime-O54YPTBU.js → deferred-core-runtime-KXN7HLN7.js} +8 -7
- package/chunks/{earlyInputCapture-CBIT2RGT.js → earlyInputCapture-WUNYYFOS.js} +8 -7
- package/chunks/{edit-KW2TOC6A.js → edit-DMFCBP2D.js} +8 -7
- package/chunks/{enter-worktree-YL34NEU5.js → enter-worktree-5SVBCXFC.js} +8 -7
- package/chunks/{enterPlanMode-JFJTDASQ.js → enterPlanMode-QUIZFQ4M.js} +8 -7
- package/chunks/{environment-IATU5GXG.js → environment-U6QP23VJ.js} +10 -9
- package/chunks/{errors-SAVRDE7Q.js → errors-GZWFA6ON.js} +10 -9
- package/chunks/{exit-worktree-5M43QPBB.js → exit-worktree-FUB44KAF.js} +8 -7
- package/chunks/{exitPlanMode-W4EICZ4N.js → exitPlanMode-XSHHYR73.js} +8 -7
- package/chunks/external-tool-guard-provider-5HTGOPGU.js +273 -0
- package/chunks/{fast-path-YQJPIKMP.js → fast-path-JHQJSIMZ.js} +5 -5
- package/chunks/{gemini-FUF5SSPR.js → gemini-O44ETOKT.js} +61 -46
- package/chunks/{geminiContentGenerator-LLLZBOUG.js → geminiContentGenerator-TTM4TZJM.js} +1 -1
- package/chunks/{glob-LJFFMN4D.js → glob-YECOWTRW.js} +8 -7
- package/chunks/{grep-Q64EAM73.js → grep-BZO4LOTA.js} +8 -7
- package/chunks/{handleAutoUpdate-QBMPRTSQ.js → handleAutoUpdate-TOO52D6H.js} +12 -11
- package/chunks/{i18n-LDUW5DMN.js → i18n-ARJYXZQ5.js} +9 -8
- package/chunks/{image-gen-G7RLG3KR.js → image-gen-J6Q2YBEU.js} +1 -1
- package/chunks/{initializer-74A7DMMD.js → initializer-CEZ4RPQV.js} +13 -12
- package/chunks/{installationInfo-OFDYLDFD.js → installationInfo-AEGIIQAT.js} +9 -8
- package/chunks/{list-JA2EWRHJ.js → list-7XLPV5GC.js} +16 -15
- package/chunks/{loadedSettingsAdapter-2GNJOQ3L.js → loadedSettingsAdapter-YK5SBHOT.js} +13 -12
- package/chunks/{loggingContentGenerator-B6B5EGB3.js → loggingContentGenerator-I7QDXS43.js} +4 -3
- package/chunks/{managed-npm-update-4YZHLUER.js → managed-npm-update-YSL7PA7G.js} +9 -8
- package/chunks/{mcp-LLK5YJVH.js → mcp-RKFQZXP6.js} +13 -12
- package/chunks/{monitor-NYJPAWVP.js → monitor-QHHJIKGL.js} +8 -7
- package/chunks/{nonInteractiveCli-HZBBBDJD.js → nonInteractiveCli-XEBIE7MG.js} +41 -39
- package/chunks/{notebook-edit-LLM6UXFX.js → notebook-edit-SG7X2EQA.js} +8 -7
- package/chunks/{openaiContentGenerator-2AEXDN55.js → openaiContentGenerator-63CVR33K.js} +5 -4
- package/chunks/{pidfile-3JUWX7G2.js → pidfile-I3CXJGQD.js} +8 -7
- package/chunks/{processUtils-JLLRVZHT.js → processUtils-LJ3DSANX.js} +2 -2
- package/chunks/{qwenContentGenerator-2FESCF27.js → qwenContentGenerator-JINBVCH6.js} +9 -8
- package/chunks/{qwenOAuth2-2KKPYA5J.js → qwenOAuth2-SY2O3NRR.js} +1 -1
- package/chunks/{read-file-5GVXLY74.js → read-file-PGTXF25I.js} +3 -2
- package/chunks/{record-artifact-L3BAHQFN.js → record-artifact-E6AWQU2Z.js} +1 -1
- package/chunks/{resumeHistoryUtils-Z4OFBXPM.js → resumeHistoryUtils-FB2NFVZ2.js} +11 -10
- package/chunks/{ripGrep-TKOJTIAB.js → ripGrep-IY3KGPM6.js} +8 -7
- package/chunks/{run-qwen-serve-K5W6MM6M.js → run-qwen-serve-UYEMGPKA.js} +72 -36
- package/chunks/{runtime-IADXMRCY.js → runtime-CG3BKRFE.js} +16 -15
- package/chunks/{scheduler-T7AV37LD.js → scheduler-VFUVGDE5.js} +8 -7
- package/chunks/{serve-ROEGMS3I.js → serve-ZCCQ2G2L.js} +14 -12
- package/chunks/{server-NGXMRODI.js → server-WS7LWXPP.js} +161 -54
- package/chunks/{session-RCDLDJA4.js → session-IQLCT32T.js} +42 -40
- package/chunks/{settings-E6H3AURD.js → settings-NX4EUIE6.js} +12 -11
- package/chunks/{shell-RHGGJ6BE.js → shell-THDYM4CS.js} +8 -7
- package/chunks/{skill-GQ7PBS25.js → skill-OXXZBNQB.js} +3 -2
- package/chunks/{skill-settings-E2F7OCBL.js → skill-settings-T3JZ33T2.js} +12 -11
- package/chunks/{spawnChannel-Q2IQBHME.js → spawnChannel-COLJMSA7.js} +11 -9
- package/chunks/{standalone-update-NYYZEHLD.js → standalone-update-ICW7H5IF.js} +10 -9
- package/chunks/{startInteractiveUI-IX6I3Y2Z.js → startInteractiveUI-6BDRXSMF.js} +60 -58
- package/chunks/{team-create-UTRVUEDA.js → team-create-BCSMDK4Z.js} +8 -7
- package/chunks/{team-plan-approval-YZNB4U5U.js → team-plan-approval-B5YRLJFV.js} +8 -7
- package/chunks/{terminal-image-renderer-QRSCS2BE.js → terminal-image-renderer-PW6Z6VFY.js} +8 -7
- package/chunks/{theme-manager-EKZBY34I.js → theme-manager-CMVKD2JH.js} +8 -7
- package/chunks/{tool-search-N2R7LVMC.js → tool-search-SQTUSG6P.js} +3 -2
- package/chunks/{total-session-admission-HBIYARPO.js → total-session-admission-XAXOSE46.js} +12 -10
- package/chunks/{trustedFolders-ZQLYRCSY.js → trustedFolders-Z2UAEG2V.js} +9 -8
- package/chunks/{update-relaunch-PJWXMPCR.js → update-relaunch-JBLI6LJF.js} +5 -5
- package/chunks/{updateCheck-ZXRCGY66.js → updateCheck-FDAVGOFT.js} +11 -10
- package/chunks/{useAutoAcceptIndicator-ZYQW5SGJ.js → useAutoAcceptIndicator-PDZFIYRM.js} +14 -13
- package/chunks/{validateNonInterActiveAuth-M7J7OTRH.js → validateNonInterActiveAuth-Q4763ONQ.js} +38 -36
- package/chunks/{version-2AOHMPK3.js → version-C7MPCGWD.js} +1 -1
- package/chunks/{web-fetch-DS34CJ3R.js → web-fetch-L7RAPOJB.js} +3 -2
- package/chunks/{web-search-ITFPD7V4.js → web-search-IDOYUOWX.js} +4 -3
- package/chunks/{workflow-LZQ4PGNS.js → workflow-HXURUJB5.js} +9 -8
- package/chunks/{workspace-providers-status-ZPTLKOBM.js → workspace-providers-status-JZ3GPWNU.js} +16 -15
- package/chunks/{workspace-registration-store-OTFKSGG7.js → workspace-registration-store-SM2PWB6L.js} +1 -1
- package/chunks/{workspace-registry-YZ3OXPHP.js → workspace-registry-6W4ES7BJ.js} +12 -10
- package/chunks/{workspace-service-OCZXOOSQ.js → workspace-service-V47ZFJRX.js} +17 -16
- package/chunks/{workspace-skills-status-K2ALGUCD.js → workspace-skills-status-6ZQ45XKA.js} +14 -13
- package/chunks/{workspace-trust-reconciler-KMRZISJP.js → workspace-trust-reconciler-6V25LMCN.js} +17 -15
- package/chunks/{write-file-AWBI4GJS.js → write-file-H2QOF25K.js} +8 -7
- package/chunks/{zoom-image-NHKN6F77.js → zoom-image-JTUSS43N.js} +3 -2
- package/cli-entry.js +14 -0
- package/cli.js +16 -12
- package/package.json +3 -3
- package/web-shell/assets/{arc-Dpg66jw7.js → arc-DtI1rZcQ.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-BJ4FIBxN.js → architectureDiagram-3BPJPVTR-BPZwSVct.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-VXmYdtYT.js → blockDiagram-GPEHLZMM-BIQ03j4C.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-BNLDb8FE.js → c4Diagram-AAUBKEIU-CB0RyFGm.js} +1 -1
- package/web-shell/assets/channel-vfbVFuM1.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-DR5yHxr0.js → chunk-2J33WTMH-B3WoS-4H.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-Czkq8UZU.js → chunk-4BX2VUAB-C98xYZ1X.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-DugUgM6s.js → chunk-55IACEB6-CbTIWRwQ.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-Dw6quA1K.js → chunk-727SXJPM-DWGnKTPu.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-BoVYOTTz.js → chunk-AQP2D5EJ-4__QyCEX.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4--Amcse-j.js → chunk-FMBD7UC4-DFtG1YCW.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-ajaEYAC8.js → chunk-ND2GUHAM-rvAhW51N.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-CUNDZ7im.js → chunk-QZHKN3VN-DfiU9pwZ.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-Cvr8atq3.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Cvr8atq3.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-BnfkD-m1.js → cose-bilkent-S5V4N54A-Cc4EIdxu.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-BuUdFk7Z.js → dagre-BM42HDAG-CZNj4dGW.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-B2ZXxoab.js → diagram-2AECGRRQ-D5tiqQCr.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BsgOICzM.js → diagram-5GNKFQAL-pwzw0jVO.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-DTTjG6U-.js → diagram-KO2AKTUF-4CWiM00x.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-temLf1x7.js → diagram-LMA3HP47-Dd7rc7Qf.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-CRFjScs2.js → diagram-OG6HWLK6-_vzV52ml.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-D4oaY-rQ.js → erDiagram-TEJ5UH35-CqbE2bx_.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-BqG8B49b.js → flowDiagram-I6XJVG4X-CaxNr7w4.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-DffQBdd5.js → ganttDiagram-6RSMTGT7-AGjrtfUA.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CMDPfseF.js → gitGraphDiagram-PVQCEYII-ADG2zSkc.js} +1 -1
- package/web-shell/assets/{index-qTQR_smP.js → index-BOryKCqt.js} +1 -1
- package/web-shell/assets/{index-CaucmEO_.css → index-Cb1LjsCv.css} +1 -1
- package/web-shell/assets/{index-2F4RsNzd.js → index-CvJDaIy8.js} +311 -311
- package/web-shell/assets/{infoDiagram-5YYISTIA-Cn3T83MA.js → infoDiagram-5YYISTIA-CE3B_IoZ.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-ijFs7e25.js → ishikawaDiagram-YF4QCWOH-CN-Frhoi.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CINTv8VB.js → journeyDiagram-JHISSGLW-CGgezS93.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-CMGRZCxx.js → kanban-definition-UN3LZRKU-BqWijky5.js} +1 -1
- package/web-shell/assets/{linear-Co-2_37d.js → linear-D8sfpZf6.js} +1 -1
- package/web-shell/assets/{mermaid.core-DijbyaN5.js → mermaid.core-3PA4QrzM.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-k_sDYDPZ.js → mindmap-definition-RKZ34NQL-D9QxwiCY.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-CG-oz8V3.js → pieDiagram-4H26LBE5-Bioaf6uE.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-Baq7HIG2.js → quadrantDiagram-W4KKPZXB-DBb2AS73.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-CDM3ZvBt.js → requirementDiagram-4Y6WPE33-DXOvZ3KB.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-C2dJbWKN.js → sankeyDiagram-5OEKKPKP-D9qg09Dm.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-Cf1_h59p.js → sequenceDiagram-3UESZ5HK-DSAUIfpw.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-CI5clUEc.js → stateDiagram-AJRCARHV-BPZkzfQ3.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DInOqnhZ.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-B2O8cAZX.js → timeline-definition-PNZ67QCA-UDaQp9sP.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-BLsJ_h9s.js → vennDiagram-CIIHVFJN-2ouhAnHO.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-BlPU4FTA.js → wardley-L42UT6IY-Cq_WEvTK.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-D_U-RdU4.js → wardleyDiagram-YWT4CUSO-Dt24aXOM.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-BynXGSTl.js → xychartDiagram-2RQKCTM6-A5Xk2WCH.js} +1 -1
- package/web-shell/index.html +2 -2
- package/bundled/review/DESIGN.md +0 -724
- package/web-shell/assets/channel-Bd9wOnaA.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-XhCT8FE3.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-XhCT8FE3.js +0 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BDc8asKD.js +0 -1
- package/chunks/{channel-management-service-UHX56NBO.js → channel-management-service-5XPPTWUQ.js} +3 -3
- package/chunks/{chunk-LEZFUYPM.js → chunk-7GYP5COR.js} +3 -3
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
import {
|
|
4
4
|
serveCommand
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-WPKIU4PA.js";
|
|
6
6
|
import {
|
|
7
7
|
listCommand
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-BU4BRCPX.js";
|
|
9
9
|
import {
|
|
10
10
|
getErrorMessage as getErrorMessage2
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-EHMN6SEG.js";
|
|
12
12
|
import {
|
|
13
13
|
ObservedChannelContactStore
|
|
14
14
|
} from "./chunk-DYA25Y7U.js";
|
|
@@ -46,22 +46,22 @@ import {
|
|
|
46
46
|
registerToolCallDispatch,
|
|
47
47
|
selectFirstModel,
|
|
48
48
|
sessionsPath
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-CDHNGCJI.js";
|
|
50
50
|
import {
|
|
51
51
|
getExtensionManager,
|
|
52
52
|
requestChoicePluginNonInteractive,
|
|
53
53
|
requestConsentNonInteractive,
|
|
54
54
|
requestConsentOrFail,
|
|
55
55
|
resolveExtensionCommandScope
|
|
56
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-C4GRKMUL.js";
|
|
57
57
|
import {
|
|
58
58
|
collectProviderModelsForProtocol,
|
|
59
59
|
getAuthTypeFromEnv,
|
|
60
60
|
resolveCliGenerationConfig
|
|
61
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-6KEN3RIC.js";
|
|
62
62
|
import {
|
|
63
63
|
parseChannelConfig
|
|
64
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-7GYP5COR.js";
|
|
65
65
|
import {
|
|
66
66
|
findCliEntryPath
|
|
67
67
|
} from "./chunk-V6WHFGST.js";
|
|
@@ -96,6 +96,9 @@ import {
|
|
|
96
96
|
import {
|
|
97
97
|
normalizeServeChannelSelection
|
|
98
98
|
} from "./chunk-ALMR3E6Q.js";
|
|
99
|
+
import {
|
|
100
|
+
EXTERNAL_TOOL_GUARD_TOKEN_ENV
|
|
101
|
+
} from "./chunk-BKHCW2BI.js";
|
|
99
102
|
import {
|
|
100
103
|
redactLogCredentials
|
|
101
104
|
} from "./chunk-M5GB774H.js";
|
|
@@ -128,29 +131,29 @@ import {
|
|
|
128
131
|
assembleMcpServers,
|
|
129
132
|
getPendingGatedMcpServers,
|
|
130
133
|
mcpCommand
|
|
131
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-T4XY5CT4.js";
|
|
132
135
|
import {
|
|
133
136
|
loadSettings
|
|
134
|
-
} from "./chunk-
|
|
137
|
+
} from "./chunk-YUVTZ4UH.js";
|
|
135
138
|
import {
|
|
136
139
|
detectSystemLanguage,
|
|
137
140
|
getCurrentLanguage,
|
|
138
141
|
initializeI18n,
|
|
139
142
|
resolveLanguageSetting,
|
|
140
143
|
t
|
|
141
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-546CDN6D.js";
|
|
142
145
|
import {
|
|
143
146
|
loadEnvironment
|
|
144
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-IKXE3AAC.js";
|
|
145
148
|
import {
|
|
146
149
|
getCliVersion
|
|
147
|
-
} from "./chunk-
|
|
150
|
+
} from "./chunk-NKST54XA.js";
|
|
148
151
|
import {
|
|
149
152
|
getPackageJson
|
|
150
153
|
} from "./chunk-VJNBRRZG.js";
|
|
151
154
|
import {
|
|
152
155
|
isWorkspaceTrusted
|
|
153
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-72DZPDH4.js";
|
|
154
157
|
import {
|
|
155
158
|
require_strip_json_comments
|
|
156
159
|
} from "./chunk-ALGGS7UH.js";
|
|
@@ -191,7 +194,7 @@ import {
|
|
|
191
194
|
unquoteCStylePath,
|
|
192
195
|
updateChannelMemoryEntry,
|
|
193
196
|
updateSetting
|
|
194
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-DOA7MCDY.js";
|
|
195
198
|
import {
|
|
196
199
|
nextFireTime,
|
|
197
200
|
parseCron
|
|
@@ -206,14 +209,14 @@ import {
|
|
|
206
209
|
import {
|
|
207
210
|
getAllGeminiMdFilenames,
|
|
208
211
|
setGeminiMdFilename
|
|
209
|
-
} from "./chunk-
|
|
212
|
+
} from "./chunk-O656RSMC.js";
|
|
210
213
|
import {
|
|
211
214
|
SchemaValidator,
|
|
212
215
|
ToolNames
|
|
213
216
|
} from "./chunk-D7D7RXIJ.js";
|
|
214
217
|
import {
|
|
215
218
|
DEFAULT_QWEN_EMBEDDING_MODEL
|
|
216
|
-
} from "./chunk-
|
|
219
|
+
} from "./chunk-P7LKADIT.js";
|
|
217
220
|
import {
|
|
218
221
|
isTlsVerificationDisabled
|
|
219
222
|
} from "./chunk-BFHXDAR7.js";
|
|
@@ -3585,6 +3588,7 @@ function scrubDaemonWorkerEnv() {
|
|
|
3585
3588
|
delete process.env[QWEN_DAEMON_URL_ENV];
|
|
3586
3589
|
delete process.env[QWEN_DAEMON_WORKSPACE_ENV];
|
|
3587
3590
|
delete process.env[QWEN_SERVER_TOKEN_ENV];
|
|
3591
|
+
delete process.env[EXTERNAL_TOOL_GUARD_TOKEN_ENV];
|
|
3588
3592
|
}
|
|
3589
3593
|
__name(scrubDaemonWorkerEnv, "scrubDaemonWorkerEnv");
|
|
3590
3594
|
function readDaemonWorkerEnv() {
|
|
@@ -4547,12 +4551,12 @@ var parseArgsCommand = {
|
|
|
4547
4551
|
|
|
4548
4552
|
// packages/cli/src/commands/review/compose-review.ts
|
|
4549
4553
|
init_esbuild_shims();
|
|
4550
|
-
import { mkdirSync as
|
|
4551
|
-
import { dirname as dirname4, join as
|
|
4554
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
4555
|
+
import { dirname as dirname4, join as join9 } from "node:path";
|
|
4552
4556
|
|
|
4553
4557
|
// packages/cli/src/commands/review/lib/coverage.ts
|
|
4554
4558
|
init_esbuild_shims();
|
|
4555
|
-
import { readFileSync as
|
|
4559
|
+
import { readFileSync as readFileSync8, statSync as statSync3 } from "node:fs";
|
|
4556
4560
|
|
|
4557
4561
|
// packages/cli/src/commands/review/lib/transcripts.ts
|
|
4558
4562
|
init_esbuild_shims();
|
|
@@ -6186,6 +6190,150 @@ If you find no new gap in your scope, say so **and name what you re-examined** \
|
|
|
6186
6190
|
}
|
|
6187
6191
|
};
|
|
6188
6192
|
|
|
6193
|
+
// packages/cli/src/commands/review/lib/deadline.ts
|
|
6194
|
+
init_esbuild_shims();
|
|
6195
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync7, statSync as statSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
6196
|
+
import { join as join8 } from "node:path";
|
|
6197
|
+
var DEADLINE_ENV = "QWEN_REVIEW_DEADLINE_EPOCH";
|
|
6198
|
+
var RESERVE_ENV = "QWEN_REVIEW_DEADLINE_RESERVE_SECONDS";
|
|
6199
|
+
var DEFAULT_RESERVE_SECONDS = 3600;
|
|
6200
|
+
var DEFAULT_ROUND_SECONDS = 1800;
|
|
6201
|
+
var MIN_OBSERVED_ROUND_SECONDS = 600;
|
|
6202
|
+
var STAMPS_FILE = "budget-rounds.json";
|
|
6203
|
+
var STOP_FILE = "budget-stop.json";
|
|
6204
|
+
var RUN_EPOCH_SLACK_MS = 2e3;
|
|
6205
|
+
function runEpochMs(planPath) {
|
|
6206
|
+
try {
|
|
6207
|
+
return statSync2(planPath).mtimeMs - RUN_EPOCH_SLACK_MS;
|
|
6208
|
+
} catch {
|
|
6209
|
+
return Number.NEGATIVE_INFINITY;
|
|
6210
|
+
}
|
|
6211
|
+
}
|
|
6212
|
+
__name(runEpochMs, "runEpochMs");
|
|
6213
|
+
function readRoundStamps(planPath) {
|
|
6214
|
+
try {
|
|
6215
|
+
const raw = readFileSync7(
|
|
6216
|
+
join8(promptRecordDir(planPath), STAMPS_FILE),
|
|
6217
|
+
"utf8"
|
|
6218
|
+
);
|
|
6219
|
+
const parsed = JSON.parse(raw);
|
|
6220
|
+
if (!Array.isArray(parsed)) return [];
|
|
6221
|
+
const epoch = runEpochMs(planPath);
|
|
6222
|
+
return parsed.filter(
|
|
6223
|
+
(e) => typeof e === "object" && e !== null && typeof e.atMs === "number" && e.atMs >= epoch
|
|
6224
|
+
);
|
|
6225
|
+
} catch {
|
|
6226
|
+
return [];
|
|
6227
|
+
}
|
|
6228
|
+
}
|
|
6229
|
+
__name(readRoundStamps, "readRoundStamps");
|
|
6230
|
+
function stampRound(planPath, round, nowMs = Date.now()) {
|
|
6231
|
+
try {
|
|
6232
|
+
const stamps = readRoundStamps(planPath);
|
|
6233
|
+
if (round !== void 0 && stamps.some((s) => s.round === round)) return;
|
|
6234
|
+
stamps.push({ round: round ?? null, atMs: nowMs });
|
|
6235
|
+
const dir = promptRecordDir(planPath);
|
|
6236
|
+
mkdirSync5(dir, { recursive: true });
|
|
6237
|
+
writeFileSync5(join8(dir, STAMPS_FILE), JSON.stringify(stamps));
|
|
6238
|
+
} catch {
|
|
6239
|
+
}
|
|
6240
|
+
}
|
|
6241
|
+
__name(stampRound, "stampRound");
|
|
6242
|
+
function expectedRoundSeconds(planPath, round, nowMs = Date.now()) {
|
|
6243
|
+
const stamps = readRoundStamps(planPath);
|
|
6244
|
+
for (let i = stamps.length - 1; i >= 0; i--) {
|
|
6245
|
+
const s = stamps[i];
|
|
6246
|
+
if (round !== void 0 && s.round === round) continue;
|
|
6247
|
+
const observed = Math.round((nowMs - s.atMs) / 1e3);
|
|
6248
|
+
return Math.max(MIN_OBSERVED_ROUND_SECONDS, observed);
|
|
6249
|
+
}
|
|
6250
|
+
return DEFAULT_ROUND_SECONDS;
|
|
6251
|
+
}
|
|
6252
|
+
__name(expectedRoundSeconds, "expectedRoundSeconds");
|
|
6253
|
+
function reverseAuditBudgetExhausted(env, roundCostSeconds, nowMs = Date.now()) {
|
|
6254
|
+
const raw = env[DEADLINE_ENV];
|
|
6255
|
+
if (raw === void 0 || raw.trim() === "") return null;
|
|
6256
|
+
const deadline = Number(raw);
|
|
6257
|
+
if (!Number.isFinite(deadline) || deadline <= 0) return null;
|
|
6258
|
+
let reserve = DEFAULT_RESERVE_SECONDS;
|
|
6259
|
+
const reserveRaw = env[RESERVE_ENV];
|
|
6260
|
+
if (reserveRaw !== void 0 && reserveRaw.trim() !== "") {
|
|
6261
|
+
const r = Number(reserveRaw);
|
|
6262
|
+
if (Number.isFinite(r) && r >= 0) reserve = r;
|
|
6263
|
+
}
|
|
6264
|
+
const remainingSeconds = Math.floor(deadline - nowMs / 1e3);
|
|
6265
|
+
if (remainingSeconds >= reserve + roundCostSeconds) return null;
|
|
6266
|
+
return {
|
|
6267
|
+
remainingSeconds,
|
|
6268
|
+
reserveSeconds: reserve,
|
|
6269
|
+
expectedRoundSeconds: roundCostSeconds
|
|
6270
|
+
};
|
|
6271
|
+
}
|
|
6272
|
+
__name(reverseAuditBudgetExhausted, "reverseAuditBudgetExhausted");
|
|
6273
|
+
var BUDGET_STOP_PHRASE = "review time budget";
|
|
6274
|
+
function budgetStopDisclosure(round) {
|
|
6275
|
+
const which = round !== void 0 ? `round ${round}` : "the next round";
|
|
6276
|
+
const whichZh = round !== void 0 ? `\u7B2C ${round} \u8F6E` : "\u4E0B\u4E00\u8F6E";
|
|
6277
|
+
return {
|
|
6278
|
+
subject: "reverse audit",
|
|
6279
|
+
reason: `stopped before ${which} by the ${BUDGET_STOP_PHRASE}`,
|
|
6280
|
+
subjectZh: "\u53CD\u5411\u5BA1\u8BA1",
|
|
6281
|
+
reasonZh: `\u8BC4\u5BA1\u65F6\u95F4\u9884\u7B97\u4E0D\u8DB3\uFF0C\u672A\u80FD\u5F00\u59CB${whichZh}`
|
|
6282
|
+
};
|
|
6283
|
+
}
|
|
6284
|
+
__name(budgetStopDisclosure, "budgetStopDisclosure");
|
|
6285
|
+
function budgetStopEntry(round) {
|
|
6286
|
+
const d = budgetStopDisclosure(round);
|
|
6287
|
+
return `${d.subject} \u2014 ${d.reason}`;
|
|
6288
|
+
}
|
|
6289
|
+
__name(budgetStopEntry, "budgetStopEntry");
|
|
6290
|
+
function budgetStopEntryZh(round) {
|
|
6291
|
+
const d = budgetStopDisclosure(round);
|
|
6292
|
+
return `${d.subjectZh}\u2014\u2014${d.reasonZh}`;
|
|
6293
|
+
}
|
|
6294
|
+
__name(budgetStopEntryZh, "budgetStopEntryZh");
|
|
6295
|
+
function writeBudgetStop(planPath, spent, round, nowMs = Date.now()) {
|
|
6296
|
+
try {
|
|
6297
|
+
const dir = promptRecordDir(planPath);
|
|
6298
|
+
mkdirSync5(dir, { recursive: true });
|
|
6299
|
+
const stop = {
|
|
6300
|
+
entry: budgetStopEntry(round),
|
|
6301
|
+
entryZh: budgetStopEntryZh(round),
|
|
6302
|
+
round: round ?? null,
|
|
6303
|
+
remainingSeconds: spent.remainingSeconds,
|
|
6304
|
+
reserveSeconds: spent.reserveSeconds,
|
|
6305
|
+
atMs: nowMs
|
|
6306
|
+
};
|
|
6307
|
+
writeFileSync5(join8(dir, STOP_FILE), JSON.stringify(stop, null, 2));
|
|
6308
|
+
} catch {
|
|
6309
|
+
}
|
|
6310
|
+
}
|
|
6311
|
+
__name(writeBudgetStop, "writeBudgetStop");
|
|
6312
|
+
function readBudgetStop(planPath) {
|
|
6313
|
+
try {
|
|
6314
|
+
const raw = readFileSync7(
|
|
6315
|
+
join8(promptRecordDir(planPath), STOP_FILE),
|
|
6316
|
+
"utf8"
|
|
6317
|
+
);
|
|
6318
|
+
const parsed = JSON.parse(raw);
|
|
6319
|
+
if (typeof parsed !== "object" || parsed === null || typeof parsed.entry !== "string" || typeof parsed.atMs !== "number" || parsed.atMs < runEpochMs(planPath)) {
|
|
6320
|
+
return null;
|
|
6321
|
+
}
|
|
6322
|
+
return parsed;
|
|
6323
|
+
} catch {
|
|
6324
|
+
return null;
|
|
6325
|
+
}
|
|
6326
|
+
}
|
|
6327
|
+
__name(readBudgetStop, "readBudgetStop");
|
|
6328
|
+
function reverseAuditBudgetMessage(spent, round) {
|
|
6329
|
+
const minutesLeft = Math.max(0, Math.floor(spent.remainingSeconds / 60));
|
|
6330
|
+
const reserveMinutes = Math.round(spent.reserveSeconds / 60);
|
|
6331
|
+
const roundMinutes = Math.round(spent.expectedRoundSeconds / 60);
|
|
6332
|
+
const which = round !== void 0 ? `round ${round}` : "the next round";
|
|
6333
|
+
return `BUDGET: ${minutesLeft} minute(s) remain before this review's deadline \u2014 not enough for the ~${roundMinutes}-minute round being asked for plus the ${reserveMinutes}-minute reserve kept for its verification, compose-review and submission \u2014 so no further reverse-audit round will be built. This is the loop's termination rule, not an error: do not rebuild ${which} and do not relaunch auditors. A budget-stop marker has been recorded and compose-review will disclose it and cap the verdict itself; also add exactly this entry to unreviewedDimensions so the terminal report says it too \u2014 \`${budgetStopEntry(round)}\` \u2014 and proceed to Step 6 with the findings already confirmed. Spend what time remains only on verifying findings already in hand, composing, and submitting. A review that stops here still reports everything it proved; a review that runs past its deadline is killed holding all of it.`;
|
|
6334
|
+
}
|
|
6335
|
+
__name(reverseAuditBudgetMessage, "reverseAuditBudgetMessage");
|
|
6336
|
+
|
|
6189
6337
|
// packages/cli/src/commands/review/lib/shell-quote.ts
|
|
6190
6338
|
init_esbuild_shims();
|
|
6191
6339
|
function shellQuotePath(p) {
|
|
@@ -6195,7 +6343,7 @@ __name(shellQuotePath, "shellQuotePath");
|
|
|
6195
6343
|
|
|
6196
6344
|
// packages/cli/src/commands/review/lib/coverage.ts
|
|
6197
6345
|
function readPlan(path3) {
|
|
6198
|
-
const plan = JSON.parse(
|
|
6346
|
+
const plan = JSON.parse(readFileSync8(path3, "utf8"));
|
|
6199
6347
|
if (typeof plan?.diffPathAbsolute !== "string" || !plan.diffPathAbsolute) {
|
|
6200
6348
|
throw new Error(`coverage: ${path3} has no diffPathAbsolute`);
|
|
6201
6349
|
}
|
|
@@ -6206,7 +6354,7 @@ function readPlan(path3) {
|
|
|
6206
6354
|
if (problem) {
|
|
6207
6355
|
throw new Error(`coverage: ${path3} has ${problem}`);
|
|
6208
6356
|
}
|
|
6209
|
-
return { plan, mtimeMs:
|
|
6357
|
+
return { plan, mtimeMs: statSync3(path3).mtimeMs };
|
|
6210
6358
|
}
|
|
6211
6359
|
__name(readPlan, "readPlan");
|
|
6212
6360
|
var CHUNK_RE = /\bchunk\s+(\d+)\s+of\s+\d+\b/i;
|
|
@@ -6552,7 +6700,13 @@ function coverageFromTranscripts(planPath, env = process.env) {
|
|
|
6552
6700
|
};
|
|
6553
6701
|
}
|
|
6554
6702
|
__name(coverageFromTranscripts, "coverageFromTranscripts");
|
|
6555
|
-
var rebuildFix = /* @__PURE__ */ __name((role, noun) => `build the prompt with \`"\${QWEN_CODE_CLI:-qwen}" review agent-prompt --plan <plan> --role ${role} --findings <file> [--rules <rules file>]
|
|
6703
|
+
var rebuildFix = /* @__PURE__ */ __name((role, noun) => `build the prompt with \`"\${QWEN_CODE_CLI:-qwen}" review agent-prompt --plan <plan> --role ${role} --findings <file> [--rules <rules file>] ` + // --round is MANDATORY for a reverse-audit build (`agent-prompt` refuses a
|
|
6704
|
+
// round-less call — the label keys the record and the budget gate's
|
|
6705
|
+
// accounting), so the paste-and-run repair must not bracket it as optional:
|
|
6706
|
+
// an orchestrator honouring the bracket convention would have its first
|
|
6707
|
+
// repair attempt rejected. Verify genuinely takes it or not (only a repeat
|
|
6708
|
+
// verification round passes one), so its brackets stay.
|
|
6709
|
+
(role === "reverse-audit" ? `--round <k>\` ` : `[--round <k>]\` `) + (role === "reverse-audit" ? `(an early round with nothing confirmed passes an empty file; ` : `(pass the shard's findings, never an empty file \u2014 a verifier that sees no findings verifies nothing; `) + `pass --rules whenever the review loaded any, or the rebuilt brief silently drops the project rules) and launch an agent with EXACTLY what it prints \u2014 no hand-added ${noun} number` + // --round bakes in a ROUND number. Verify's noun is "shard", and a
|
|
6556
6710
|
// parenthetical claiming --round bakes it in would send the reader to the
|
|
6557
6711
|
// wrong flag — shards are already told apart by their findings digest.
|
|
6558
6712
|
(role === "reverse-audit" ? ` (--round bakes it in)` : ``) + `, no summary of your own, no rewording`, "rebuildFix");
|
|
@@ -6667,7 +6821,9 @@ function verificationGaps(planPath, opts, env = process.env) {
|
|
|
6667
6821
|
(k) => k === "reverse-audit" || k.startsWith("reverse-audit--")
|
|
6668
6822
|
);
|
|
6669
6823
|
const reverse = bestDelivery(reverseKeys);
|
|
6670
|
-
const
|
|
6824
|
+
const budgetStopped = readBudgetStop(planPath) !== null;
|
|
6825
|
+
const reverseByDesign = budgetStopped && reverse === "not-built";
|
|
6826
|
+
const reverseGap = !balancedMedium && !reverseByDesign && reverse !== "ok";
|
|
6671
6827
|
if (reverseGap) {
|
|
6672
6828
|
remediation.push(
|
|
6673
6829
|
`reverse audit: ${REVERSE_AUDIT_GAP[reverse].fix.replace(
|
|
@@ -6970,6 +7126,24 @@ function unmarkedComments(comments) {
|
|
|
6970
7126
|
}
|
|
6971
7127
|
__name(unmarkedComments, "unmarkedComments");
|
|
6972
7128
|
|
|
7129
|
+
// packages/cli/src/commands/review/lib/review-footer.ts
|
|
7130
|
+
init_esbuild_shims();
|
|
7131
|
+
var FOOTER_MARKER = "via Qwen Code /review";
|
|
7132
|
+
function reviewFooter(modelId, cliVersion) {
|
|
7133
|
+
return `_\u2014 ${modelId} ${FOOTER_MARKER} (v${cliVersion})_`;
|
|
7134
|
+
}
|
|
7135
|
+
__name(reviewFooter, "reviewFooter");
|
|
7136
|
+
var REVIEW_FOOTER_RE = /\s*(?:_— (?:(?! via Qwen Code \/review)[^\n])* via Qwen Code \/review(?: \(v[^\n)]*\))?_?\s*)+$/;
|
|
7137
|
+
function isFooterSafeModelId(modelId) {
|
|
7138
|
+
return !/[\n\r]/.test(modelId) && !modelId.includes(FOOTER_MARKER);
|
|
7139
|
+
}
|
|
7140
|
+
__name(isFooterSafeModelId, "isFooterSafeModelId");
|
|
7141
|
+
var FOOTER_VERSION_RE = /^[A-Za-z0-9._+-]+$/;
|
|
7142
|
+
function footerVersion(stamp) {
|
|
7143
|
+
return stamp !== void 0 && FOOTER_VERSION_RE.test(stamp) ? stamp : void 0;
|
|
7144
|
+
}
|
|
7145
|
+
__name(footerVersion, "footerVersion");
|
|
7146
|
+
|
|
6973
7147
|
// packages/cli/src/commands/review/compose-review.ts
|
|
6974
7148
|
var LOW_SIGNAL_SRC_DIFF_LINES = 100;
|
|
6975
7149
|
function withMarker(line) {
|
|
@@ -6996,6 +7170,10 @@ function toStringList(value, field) {
|
|
|
6996
7170
|
return [...value];
|
|
6997
7171
|
}
|
|
6998
7172
|
__name(toStringList, "toStringList");
|
|
7173
|
+
function stripReviewFooter(entry) {
|
|
7174
|
+
return entry.replace(REVIEW_FOOTER_RE, "");
|
|
7175
|
+
}
|
|
7176
|
+
__name(stripReviewFooter, "stripReviewFooter");
|
|
6999
7177
|
function toBool(value, field) {
|
|
7000
7178
|
if (value === void 0 || value === null) return false;
|
|
7001
7179
|
if (typeof value !== "boolean") {
|
|
@@ -7017,15 +7195,15 @@ __name(composeReview, "composeReview");
|
|
|
7017
7195
|
function ledgerMarkerFor(input) {
|
|
7018
7196
|
try {
|
|
7019
7197
|
if (!input.planPath) return null;
|
|
7020
|
-
const plan = JSON.parse(
|
|
7198
|
+
const plan = JSON.parse(readFileSync9(input.planPath, "utf8"));
|
|
7021
7199
|
const pr = plan?.prNumber;
|
|
7022
7200
|
const isPr = typeof pr === "number" && Number.isInteger(pr) && pr > 0 || typeof pr === "string" && /^\d+$/.test(pr);
|
|
7023
7201
|
if (!isPr) return null;
|
|
7024
7202
|
let prevRound = 0;
|
|
7025
7203
|
try {
|
|
7026
7204
|
const prev = JSON.parse(
|
|
7027
|
-
|
|
7028
|
-
|
|
7205
|
+
readFileSync9(
|
|
7206
|
+
join9(
|
|
7029
7207
|
dirname4(input.planPath),
|
|
7030
7208
|
`qwen-review-pr-${pr}-prev-ledger.json`
|
|
7031
7209
|
),
|
|
@@ -7040,7 +7218,7 @@ function ledgerMarkerFor(input) {
|
|
|
7040
7218
|
buildLedger(
|
|
7041
7219
|
prevRound + 1,
|
|
7042
7220
|
input.draftedComments ?? [],
|
|
7043
|
-
toStringList(input.bodyCriticals, "bodyCriticals")
|
|
7221
|
+
toStringList(input.bodyCriticals, "bodyCriticals").map(stripReviewFooter).filter((entry) => entry.trim() !== "")
|
|
7044
7222
|
)
|
|
7045
7223
|
);
|
|
7046
7224
|
} catch {
|
|
@@ -7054,7 +7232,7 @@ function composeReviewBody(input, cliVersion) {
|
|
|
7054
7232
|
input.suggestionsInline,
|
|
7055
7233
|
"suggestionsInline"
|
|
7056
7234
|
);
|
|
7057
|
-
const bodyCriticals = toStringList(input.bodyCriticals, "bodyCriticals");
|
|
7235
|
+
const bodyCriticals = toStringList(input.bodyCriticals, "bodyCriticals").map(stripReviewFooter).filter((entry) => entry.trim() !== "");
|
|
7058
7236
|
const suggestionsDiscarded = toCount(
|
|
7059
7237
|
input.suggestionsDiscarded,
|
|
7060
7238
|
"suggestionsDiscarded"
|
|
@@ -7062,7 +7240,7 @@ function composeReviewBody(input, cliVersion) {
|
|
|
7062
7240
|
const cannotTell = toStringList(
|
|
7063
7241
|
input.cannotTellCriticals,
|
|
7064
7242
|
"cannotTellCriticals"
|
|
7065
|
-
);
|
|
7243
|
+
).map(stripReviewFooter).filter((entry) => entry.trim() !== "");
|
|
7066
7244
|
const uncoverable = toStringList(
|
|
7067
7245
|
input.uncoverableChunks,
|
|
7068
7246
|
"uncoverableChunks"
|
|
@@ -7072,6 +7250,19 @@ function composeReviewBody(input, cliVersion) {
|
|
|
7072
7250
|
"unreviewedDimensions"
|
|
7073
7251
|
);
|
|
7074
7252
|
const coverageEntries = [];
|
|
7253
|
+
let budgetEntry;
|
|
7254
|
+
if (input.planPath) {
|
|
7255
|
+
const stop = readBudgetStop(input.planPath);
|
|
7256
|
+
if (stop !== null) {
|
|
7257
|
+
for (let i = unreviewed.length - 1; i >= 0; i--) {
|
|
7258
|
+
if (unreviewed[i].includes(BUDGET_STOP_PHRASE)) {
|
|
7259
|
+
unreviewed.splice(i, 1);
|
|
7260
|
+
}
|
|
7261
|
+
}
|
|
7262
|
+
budgetEntry = budgetStopDisclosure(stop.round ?? void 0);
|
|
7263
|
+
coverageEntries.push(budgetEntry);
|
|
7264
|
+
}
|
|
7265
|
+
}
|
|
7075
7266
|
const remediation = [];
|
|
7076
7267
|
const planRef = input.planPath ? shellQuotePath(input.planPath) : "<plan>";
|
|
7077
7268
|
const missingReceipts = [];
|
|
@@ -7231,6 +7422,11 @@ function composeReviewBody(input, cliVersion) {
|
|
|
7231
7422
|
"compose-review: modelId is required (the public footer names the reviewing model)"
|
|
7232
7423
|
);
|
|
7233
7424
|
}
|
|
7425
|
+
if (!isFooterSafeModelId(modelId)) {
|
|
7426
|
+
throw new TypeError(
|
|
7427
|
+
"compose-review: modelId is interpolated into the public footer verbatim \u2014 it must be a single line that does not contain the footer marker"
|
|
7428
|
+
);
|
|
7429
|
+
}
|
|
7234
7430
|
const c = criticalsInline + bodyCriticals.length;
|
|
7235
7431
|
const s = suggestionsInline + suggestionsDiscarded;
|
|
7236
7432
|
const baseEvent = c >= 1 ? "REQUEST_CHANGES" : s >= 1 ? "COMMENT" : "APPROVE";
|
|
@@ -7264,7 +7460,7 @@ function composeReviewBody(input, cliVersion) {
|
|
|
7264
7460
|
if (event2 === "APPROVE" && input.planPath) {
|
|
7265
7461
|
try {
|
|
7266
7462
|
const plan = JSON.parse(
|
|
7267
|
-
|
|
7463
|
+
readFileSync9(input.planPath, "utf8")
|
|
7268
7464
|
);
|
|
7269
7465
|
const src = Number(plan.srcDiffLines ?? 0);
|
|
7270
7466
|
if (src > LOW_SIGNAL_SRC_DIFF_LINES) {
|
|
@@ -7273,7 +7469,7 @@ function composeReviewBody(input, cliVersion) {
|
|
|
7273
7469
|
} catch {
|
|
7274
7470
|
}
|
|
7275
7471
|
}
|
|
7276
|
-
const footer =
|
|
7472
|
+
const footer = reviewFooter(modelId, cliVersion);
|
|
7277
7473
|
const bilingual = bilingualFromPlan(input.planPath, input.prBodyFetcher);
|
|
7278
7474
|
const render = /* @__PURE__ */ __name((parts, sep5) => {
|
|
7279
7475
|
const en = parts.map((p) => p.en).join(sep5);
|
|
@@ -7332,7 +7528,7 @@ ${footer}`;
|
|
|
7332
7528
|
if (seenCaller.has(d)) continue;
|
|
7333
7529
|
seenCaller.add(d);
|
|
7334
7530
|
const echoesCoverage = covEntries.some(
|
|
7335
|
-
(e) => d === e.subject || d.startsWith(`${e.subject} \u2014 `)
|
|
7531
|
+
(e) => d === e.subject || e !== budgetEntry && d.startsWith(`${e.subject} \u2014 `)
|
|
7336
7532
|
);
|
|
7337
7533
|
if (!echoesCoverage) callerLeft.push(d);
|
|
7338
7534
|
}
|
|
@@ -7556,7 +7752,7 @@ function scriptLintGate(planPath) {
|
|
|
7556
7752
|
const disclosed = [];
|
|
7557
7753
|
let plan;
|
|
7558
7754
|
try {
|
|
7559
|
-
plan = JSON.parse(
|
|
7755
|
+
plan = JSON.parse(readFileSync9(planPath, "utf8"));
|
|
7560
7756
|
} catch {
|
|
7561
7757
|
unreviewed.push(
|
|
7562
7758
|
"the executable-script lint \u2014 could not read the plan to check the gate"
|
|
@@ -7567,13 +7763,13 @@ function scriptLintGate(planPath) {
|
|
|
7567
7763
|
return { criticals, unreviewed, disclosed };
|
|
7568
7764
|
}
|
|
7569
7765
|
const owed = hasExecutableScript(plan);
|
|
7570
|
-
const reportPath =
|
|
7766
|
+
const reportPath = join9(
|
|
7571
7767
|
dirname4(planPath),
|
|
7572
7768
|
scriptLintReportName(plan.prNumber)
|
|
7573
7769
|
);
|
|
7574
7770
|
let report;
|
|
7575
7771
|
try {
|
|
7576
|
-
report = JSON.parse(
|
|
7772
|
+
report = JSON.parse(readFileSync9(reportPath, "utf8"));
|
|
7577
7773
|
} catch {
|
|
7578
7774
|
if (owed) {
|
|
7579
7775
|
unreviewed.push(
|
|
@@ -7629,7 +7825,7 @@ function testPlanGate(planPath) {
|
|
|
7629
7825
|
const notes = [];
|
|
7630
7826
|
let plan;
|
|
7631
7827
|
try {
|
|
7632
|
-
plan = JSON.parse(
|
|
7828
|
+
plan = JSON.parse(readFileSync9(planPath, "utf8"));
|
|
7633
7829
|
} catch {
|
|
7634
7830
|
return { notes };
|
|
7635
7831
|
}
|
|
@@ -7639,8 +7835,8 @@ function testPlanGate(planPath) {
|
|
|
7639
7835
|
let report;
|
|
7640
7836
|
try {
|
|
7641
7837
|
report = JSON.parse(
|
|
7642
|
-
|
|
7643
|
-
|
|
7838
|
+
readFileSync9(
|
|
7839
|
+
join9(dirname4(planPath), `qwen-review-pr-${pr}-test-plan.json`),
|
|
7644
7840
|
"utf8"
|
|
7645
7841
|
)
|
|
7646
7842
|
);
|
|
@@ -7673,7 +7869,7 @@ function bilingualFromPlan(planPath, fetchPrBody2 = fetchPrBodyViaGh) {
|
|
|
7673
7869
|
if (!planPath) return false;
|
|
7674
7870
|
let plan;
|
|
7675
7871
|
try {
|
|
7676
|
-
plan = JSON.parse(
|
|
7872
|
+
plan = JSON.parse(readFileSync9(planPath, "utf8"));
|
|
7677
7873
|
} catch {
|
|
7678
7874
|
return false;
|
|
7679
7875
|
}
|
|
@@ -7693,7 +7889,7 @@ __name(bilingualFromPlan, "bilingualFromPlan");
|
|
|
7693
7889
|
function readDraftedComments(path3) {
|
|
7694
7890
|
let raw;
|
|
7695
7891
|
try {
|
|
7696
|
-
raw =
|
|
7892
|
+
raw = readFileSync9(path3, "utf8");
|
|
7697
7893
|
} catch (err) {
|
|
7698
7894
|
throw new Error(
|
|
7699
7895
|
`compose-review: cannot read the comments file ${path3}: ${err.message}. Pass the drafted inline comments \u2014 the same array the review payload will carry \u2014 or a file containing [] when nothing anchors inline.`
|
|
@@ -7747,7 +7943,7 @@ var composeReviewCommand = {
|
|
|
7747
7943
|
"compose-review: --comments is required \u2014 the inline counts are counted from the drafted comments file, never typed. Pass a file containing [] when nothing anchors inline."
|
|
7748
7944
|
);
|
|
7749
7945
|
}
|
|
7750
|
-
const raw =
|
|
7946
|
+
const raw = readFileSync9(input ?? 0, "utf8");
|
|
7751
7947
|
const parsed = JSON.parse(raw);
|
|
7752
7948
|
delete parsed.env;
|
|
7753
7949
|
delete parsed.prBodyFetcher;
|
|
@@ -7764,7 +7960,9 @@ var composeReviewCommand = {
|
|
|
7764
7960
|
...countInlineFindings(drafted),
|
|
7765
7961
|
draftedComments: drafted
|
|
7766
7962
|
},
|
|
7767
|
-
|
|
7963
|
+
// Same pin as `submit`: the startup stamp, not a version resolved at
|
|
7964
|
+
// compose time — a shared runner can rewrite the install mid-session.
|
|
7965
|
+
footerVersion(process.env["QWEN_CODE_STARTUP_VERSION"]) ?? await getCliVersion()
|
|
7768
7966
|
);
|
|
7769
7967
|
const json = JSON.stringify(
|
|
7770
7968
|
{ ...result, verdictLine: verdictLine(result) },
|
|
@@ -7772,8 +7970,8 @@ var composeReviewCommand = {
|
|
|
7772
7970
|
2
|
|
7773
7971
|
);
|
|
7774
7972
|
if (out) {
|
|
7775
|
-
|
|
7776
|
-
|
|
7973
|
+
mkdirSync6(dirname4(out), { recursive: true });
|
|
7974
|
+
writeFileSync6(out, json, "utf8");
|
|
7777
7975
|
}
|
|
7778
7976
|
writeStdoutLine(json);
|
|
7779
7977
|
for (const fix of result.remediation) {
|
|
@@ -7874,7 +8072,7 @@ __name(verdictLine, "verdictLine");
|
|
|
7874
8072
|
|
|
7875
8073
|
// packages/cli/src/commands/review/findings.ts
|
|
7876
8074
|
init_esbuild_shims();
|
|
7877
|
-
import { existsSync as existsSync3, readFileSync as
|
|
8075
|
+
import { existsSync as existsSync3, readFileSync as readFileSync10, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "node:fs";
|
|
7878
8076
|
import { dirname as dirname5, resolve as resolve5 } from "node:path";
|
|
7879
8077
|
var SEVERITIES = ["Critical", "Suggestion", "Nice to have"];
|
|
7880
8078
|
var CONFIDENCES = ["high", "low"];
|
|
@@ -8248,7 +8446,7 @@ __name(renderFindings, "renderFindings");
|
|
|
8248
8446
|
function readJson(path3, what) {
|
|
8249
8447
|
let text;
|
|
8250
8448
|
try {
|
|
8251
|
-
text =
|
|
8449
|
+
text = readFileSync10(resolve5(path3), "utf8");
|
|
8252
8450
|
} catch (err) {
|
|
8253
8451
|
throw new Error(
|
|
8254
8452
|
`Could not read the ${what} file at ${JSON.stringify(path3)}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -8319,8 +8517,8 @@ var findingsCommand = {
|
|
|
8319
8517
|
}
|
|
8320
8518
|
const report = buildReport(findings);
|
|
8321
8519
|
const target = resolve5(out);
|
|
8322
|
-
|
|
8323
|
-
|
|
8520
|
+
mkdirSync7(dirname5(target), { recursive: true });
|
|
8521
|
+
writeFileSync7(target, `${JSON.stringify(report, null, 2)}
|
|
8324
8522
|
`, "utf8");
|
|
8325
8523
|
const { bySeverity, byConfidence } = report.counts;
|
|
8326
8524
|
writeStderrLine(
|
|
@@ -8351,7 +8549,7 @@ var findingsCommand = {
|
|
|
8351
8549
|
// packages/cli/src/commands/review/fetch-pr.ts
|
|
8352
8550
|
init_esbuild_shims();
|
|
8353
8551
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
8354
|
-
import { mkdirSync as
|
|
8552
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync8 } from "node:fs";
|
|
8355
8553
|
import { dirname as dirname6, resolve as resolve6 } from "node:path";
|
|
8356
8554
|
|
|
8357
8555
|
// packages/cli/src/commands/review/lib/git.ts
|
|
@@ -8459,11 +8657,11 @@ var LITERAL_PATHSPECS = "--literal-pathspecs";
|
|
|
8459
8657
|
|
|
8460
8658
|
// packages/cli/src/commands/review/lib/effort.ts
|
|
8461
8659
|
init_esbuild_shims();
|
|
8462
|
-
import { readFileSync as
|
|
8660
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
8463
8661
|
function resolveEffort(explicit) {
|
|
8464
8662
|
if (explicit && EFFORT_LEVELS.has(explicit)) return explicit;
|
|
8465
8663
|
try {
|
|
8466
|
-
const parsed = JSON.parse(
|
|
8664
|
+
const parsed = JSON.parse(readFileSync11(PARSE_ARGS_REPORT, "utf8"));
|
|
8467
8665
|
if (typeof parsed.effort === "string" && EFFORT_LEVELS.has(parsed.effort)) {
|
|
8468
8666
|
return parsed.effort;
|
|
8469
8667
|
}
|
|
@@ -8484,7 +8682,7 @@ __name(planEffortField, "planEffortField");
|
|
|
8484
8682
|
|
|
8485
8683
|
// packages/cli/src/commands/review/lib/report.ts
|
|
8486
8684
|
init_esbuild_shims();
|
|
8487
|
-
import { statSync as
|
|
8685
|
+
import { statSync as statSync4 } from "node:fs";
|
|
8488
8686
|
|
|
8489
8687
|
// packages/cli/src/commands/review/lib/heavy.ts
|
|
8490
8688
|
init_esbuild_shims();
|
|
@@ -8587,7 +8785,7 @@ __name(buildPlanReport, "buildPlanReport");
|
|
|
8587
8785
|
function warnOnReportSize(path3, cap) {
|
|
8588
8786
|
let size = 0;
|
|
8589
8787
|
try {
|
|
8590
|
-
size =
|
|
8788
|
+
size = statSync4(path3).size;
|
|
8591
8789
|
} catch {
|
|
8592
8790
|
return;
|
|
8593
8791
|
}
|
|
@@ -8710,7 +8908,7 @@ async function runFetchPr(args) {
|
|
|
8710
8908
|
);
|
|
8711
8909
|
}
|
|
8712
8910
|
try {
|
|
8713
|
-
|
|
8911
|
+
mkdirSync8(dirname6(wt), { recursive: true });
|
|
8714
8912
|
git("worktree", "add", wt, ref);
|
|
8715
8913
|
} catch (err) {
|
|
8716
8914
|
tryRemove(
|
|
@@ -8720,7 +8918,7 @@ async function runFetchPr(args) {
|
|
|
8720
8918
|
`Failed to create worktree at ${wt}: ${err.message}`
|
|
8721
8919
|
);
|
|
8722
8920
|
}
|
|
8723
|
-
|
|
8921
|
+
mkdirSync8(REVIEW_TMP_DIR, { recursive: true });
|
|
8724
8922
|
const { sha: mergeBaseSha, baseFetchFailed } = resolveMergeBase(
|
|
8725
8923
|
remote,
|
|
8726
8924
|
meta.baseRefName,
|
|
@@ -8744,7 +8942,7 @@ async function runFetchPr(args) {
|
|
|
8744
8942
|
...PINNED_DIFF_FLAGS,
|
|
8745
8943
|
`${mergeBaseSha}..${fetchedSha}`
|
|
8746
8944
|
);
|
|
8747
|
-
|
|
8945
|
+
writeFileSync8(diffRel, buf);
|
|
8748
8946
|
diffText = buf.toString("utf8");
|
|
8749
8947
|
diffPath = diffRel;
|
|
8750
8948
|
diffPathAbsolute = resolve6(diffRel);
|
|
@@ -8771,7 +8969,7 @@ async function runFetchPr(args) {
|
|
|
8771
8969
|
let auditSince = fetchedAt;
|
|
8772
8970
|
let prevRaw = null;
|
|
8773
8971
|
try {
|
|
8774
|
-
prevRaw =
|
|
8972
|
+
prevRaw = readFileSync12(out, "utf8");
|
|
8775
8973
|
} catch (err) {
|
|
8776
8974
|
const code = err.code;
|
|
8777
8975
|
if (code !== "ENOENT") {
|
|
@@ -8854,7 +9052,7 @@ async function runFetchPr(args) {
|
|
|
8854
9052
|
...buildPlanReport(plan, (path3) => fileLineCount(fetchedSha, path3)),
|
|
8855
9053
|
...planEffortField(args.effort)
|
|
8856
9054
|
};
|
|
8857
|
-
|
|
9055
|
+
writeFileSync8(out, stringifyPlanReport(result), "utf8");
|
|
8858
9056
|
writeStdoutLine(`Wrote fetch-pr report to ${out}`);
|
|
8859
9057
|
if (diffPath) writeStdoutLine(`Wrote review diff to ${diffPath}`);
|
|
8860
9058
|
writeStderrLine(
|
|
@@ -8938,13 +9136,13 @@ var fetchPrCommand = {
|
|
|
8938
9136
|
|
|
8939
9137
|
// packages/cli/src/commands/review/capture-local.ts
|
|
8940
9138
|
init_esbuild_shims();
|
|
8941
|
-
import { mkdirSync as
|
|
9139
|
+
import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "node:fs";
|
|
8942
9140
|
import { dirname as dirname7, resolve as resolve8 } from "node:path";
|
|
8943
9141
|
|
|
8944
9142
|
// packages/cli/src/commands/review/lib/local-diff.ts
|
|
8945
9143
|
init_esbuild_shims();
|
|
8946
|
-
import { lstatSync as lstatSync2, statSync as
|
|
8947
|
-
import { join as
|
|
9144
|
+
import { lstatSync as lstatSync2, statSync as statSync5, realpathSync as realpathSync2 } from "node:fs";
|
|
9145
|
+
import { join as join10, relative as relative2, resolve as resolve7, isAbsolute as isAbsolute2, sep as sep2 } from "node:path";
|
|
8948
9146
|
var MAX_UNTRACKED_BYTES = 1e6;
|
|
8949
9147
|
var MAX_UNTRACKED_FILES = 500;
|
|
8950
9148
|
var MAX_UNTRACKED_TOTAL_BYTES = 1e7;
|
|
@@ -8965,7 +9163,7 @@ function describeUndiffable(abs, st) {
|
|
|
8965
9163
|
}
|
|
8966
9164
|
if (st.isSymbolicLink()) {
|
|
8967
9165
|
try {
|
|
8968
|
-
return
|
|
9166
|
+
return statSync5(abs).isDirectory() ? "is a symlink to a directory \u2014 git cannot diff it as a file" : null;
|
|
8969
9167
|
} catch {
|
|
8970
9168
|
return null;
|
|
8971
9169
|
}
|
|
@@ -9070,7 +9268,7 @@ function captureLocalDiff(opts) {
|
|
|
9070
9268
|
for (const path3 of candidates) {
|
|
9071
9269
|
let bytes;
|
|
9072
9270
|
try {
|
|
9073
|
-
const abs =
|
|
9271
|
+
const abs = join10(repoRoot, path3);
|
|
9074
9272
|
const st = lstatSync2(abs);
|
|
9075
9273
|
const kind = describeUndiffable(abs, st);
|
|
9076
9274
|
if (kind) {
|
|
@@ -9162,10 +9360,10 @@ function runCaptureLocal(args) {
|
|
|
9162
9360
|
includeUntracked: args.untracked
|
|
9163
9361
|
});
|
|
9164
9362
|
const diffText = capture.diff.toString("utf8");
|
|
9165
|
-
|
|
9166
|
-
|
|
9363
|
+
mkdirSync9(REVIEW_TMP_DIR, { recursive: true });
|
|
9364
|
+
mkdirSync9(dirname7(resolve8(out)), { recursive: true });
|
|
9167
9365
|
const diffPath = tmpFile(target, "diff.txt");
|
|
9168
|
-
|
|
9366
|
+
writeFileSync9(diffPath, capture.diff);
|
|
9169
9367
|
const plan = buildDiffPlan(diffText);
|
|
9170
9368
|
const result = {
|
|
9171
9369
|
diffPath,
|
|
@@ -9178,7 +9376,7 @@ function runCaptureLocal(args) {
|
|
|
9178
9376
|
skippedFiles: capture.skipped,
|
|
9179
9377
|
...planEffortField(args.effort)
|
|
9180
9378
|
};
|
|
9181
|
-
|
|
9379
|
+
writeFileSync9(out, stringifyPlanReport(result), "utf8");
|
|
9182
9380
|
writeStdoutLine(`Wrote diff to ${diffPath} and plan to ${out}`);
|
|
9183
9381
|
if (capture.unbornHead) {
|
|
9184
9382
|
writeStderrLine(
|
|
@@ -9236,13 +9434,13 @@ var captureLocalCommand = {
|
|
|
9236
9434
|
|
|
9237
9435
|
// packages/cli/src/commands/review/plan-diff.ts
|
|
9238
9436
|
init_esbuild_shims();
|
|
9239
|
-
import { readFileSync as
|
|
9437
|
+
import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10 } from "node:fs";
|
|
9240
9438
|
import { resolve as resolve9 } from "node:path";
|
|
9241
9439
|
function runPlanDiff(args) {
|
|
9242
9440
|
const { diff_path: diffPath, out } = args;
|
|
9243
9441
|
let diffText;
|
|
9244
9442
|
try {
|
|
9245
|
-
diffText =
|
|
9443
|
+
diffText = readFileSync13(diffPath, "utf8");
|
|
9246
9444
|
} catch (err) {
|
|
9247
9445
|
throw new Error(
|
|
9248
9446
|
`Cannot read diff file ${diffPath}: ${err.message}`
|
|
@@ -9269,8 +9467,8 @@ function runPlanDiff(args) {
|
|
|
9269
9467
|
...buildPlanReport(plan, null),
|
|
9270
9468
|
...planEffortField(args.effort)
|
|
9271
9469
|
};
|
|
9272
|
-
|
|
9273
|
-
|
|
9470
|
+
mkdirSync10(REVIEW_TMP_DIR, { recursive: true });
|
|
9471
|
+
writeFileSync10(out, stringifyPlanReport(result), "utf8");
|
|
9274
9472
|
writeStdoutLine(`Wrote diff plan to ${out}`);
|
|
9275
9473
|
if (plan.diffLines === 0) {
|
|
9276
9474
|
writeStderrLine(
|
|
@@ -9316,8 +9514,8 @@ var planDiffCommand = {
|
|
|
9316
9514
|
|
|
9317
9515
|
// packages/cli/src/commands/review/pr-context.ts
|
|
9318
9516
|
init_esbuild_shims();
|
|
9319
|
-
import { mkdirSync as
|
|
9320
|
-
import { dirname as dirname8, join as
|
|
9517
|
+
import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "node:fs";
|
|
9518
|
+
import { dirname as dirname8, join as join11 } from "node:path";
|
|
9321
9519
|
var SUMMARY_MARKER = "<!-- qwen-review-suggestion-summary -->";
|
|
9322
9520
|
function isLegacySuggestionSummary(body) {
|
|
9323
9521
|
return (body ?? "").includes(SUMMARY_MARKER);
|
|
@@ -9795,9 +9993,9 @@ async function runPrContext(args) {
|
|
|
9795
9993
|
}
|
|
9796
9994
|
if (prevLedger) {
|
|
9797
9995
|
try {
|
|
9798
|
-
|
|
9799
|
-
|
|
9800
|
-
|
|
9996
|
+
mkdirSync11(dirname8(out), { recursive: true });
|
|
9997
|
+
writeFileSync11(
|
|
9998
|
+
join11(dirname8(out), `qwen-review-pr-${prNumber}-prev-ledger.json`),
|
|
9801
9999
|
JSON.stringify(prevLedger, null, 2)
|
|
9802
10000
|
);
|
|
9803
10001
|
} catch {
|
|
@@ -9812,8 +10010,8 @@ async function runPrContext(args) {
|
|
|
9812
10010
|
reviews,
|
|
9813
10011
|
prevLedger
|
|
9814
10012
|
);
|
|
9815
|
-
|
|
9816
|
-
|
|
10013
|
+
mkdirSync11(dirname8(out), { recursive: true });
|
|
10014
|
+
writeFileSync11(out, md, "utf8");
|
|
9817
10015
|
const meaningfulReviewCount = reviews.filter(
|
|
9818
10016
|
(r) => isReviewWorthShowing(stripLedgerMarker(r.body ?? ""))
|
|
9819
10017
|
).length;
|
|
@@ -9867,7 +10065,7 @@ var prContextCommand = {
|
|
|
9867
10065
|
|
|
9868
10066
|
// packages/cli/src/commands/review/comment-status.ts
|
|
9869
10067
|
init_esbuild_shims();
|
|
9870
|
-
import { mkdirSync as
|
|
10068
|
+
import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync12 } from "node:fs";
|
|
9871
10069
|
import { dirname as dirname9 } from "node:path";
|
|
9872
10070
|
var TOUCHED_BY_CAP = 10;
|
|
9873
10071
|
function buildThreadStatuses(comments, prAuthor, probe) {
|
|
@@ -10073,9 +10271,9 @@ async function runCommentStatus(args) {
|
|
|
10073
10271
|
summary,
|
|
10074
10272
|
threads
|
|
10075
10273
|
};
|
|
10076
|
-
|
|
10274
|
+
mkdirSync12(dirname9(out), { recursive: true });
|
|
10077
10275
|
const json = JSON.stringify(report, null, 2) + "\n";
|
|
10078
|
-
|
|
10276
|
+
writeFileSync12(out, json, "utf8");
|
|
10079
10277
|
writeStdoutLine(
|
|
10080
10278
|
`Wrote comment-status report to ${out} (${comments.length} inline comments in ${summary.threads} threads: ${summary.outdated} outdated, ${summary.blockers} blocker(s), ${summary.changedSinceComment} on files changed since their comment, ${summary.withReplies} with replies, ${summary.authorReplied} answered by the PR author)`
|
|
10081
10279
|
);
|
|
@@ -10103,8 +10301,8 @@ async function runCommentStatus(args) {
|
|
|
10103
10301
|
writeStdoutLine(
|
|
10104
10302
|
`warning: comment-status failed: ${msg}. It is an index, not the evidence \u2014 re-derive thread statuses per-comment if needed.`
|
|
10105
10303
|
);
|
|
10106
|
-
|
|
10107
|
-
|
|
10304
|
+
mkdirSync12(dirname9(out), { recursive: true });
|
|
10305
|
+
writeFileSync12(
|
|
10108
10306
|
out,
|
|
10109
10307
|
JSON.stringify(
|
|
10110
10308
|
{
|
|
@@ -10166,7 +10364,7 @@ var commentStatusCommand = {
|
|
|
10166
10364
|
|
|
10167
10365
|
// packages/cli/src/commands/review/load-rules.ts
|
|
10168
10366
|
init_esbuild_shims();
|
|
10169
|
-
import { mkdirSync as
|
|
10367
|
+
import { mkdirSync as mkdirSync13, writeFileSync as writeFileSync13 } from "node:fs";
|
|
10170
10368
|
import { dirname as dirname10 } from "node:path";
|
|
10171
10369
|
function showFile(baseRef, path3) {
|
|
10172
10370
|
return gitOpt("show", `${baseRef}:${path3}`);
|
|
@@ -10247,8 +10445,8 @@ __name(loadCombined, "loadCombined");
|
|
|
10247
10445
|
async function runLoadRules(args) {
|
|
10248
10446
|
const { base_ref: baseRef, out } = args;
|
|
10249
10447
|
const { combined, loaded } = loadCombined(baseRef);
|
|
10250
|
-
|
|
10251
|
-
|
|
10448
|
+
mkdirSync13(dirname10(out), { recursive: true });
|
|
10449
|
+
writeFileSync13(out, combined, "utf8");
|
|
10252
10450
|
if (loaded.length === 0) {
|
|
10253
10451
|
writeStdoutLine(
|
|
10254
10452
|
`No review rules found on ${baseRef}; wrote empty file to ${out}`
|
|
@@ -10279,7 +10477,7 @@ var loadRulesCommand = {
|
|
|
10279
10477
|
|
|
10280
10478
|
// packages/cli/src/commands/review/presubmit.ts
|
|
10281
10479
|
init_esbuild_shims();
|
|
10282
|
-
import { writeFileSync as
|
|
10480
|
+
import { writeFileSync as writeFileSync14, readFileSync as readFileSync14 } from "node:fs";
|
|
10283
10481
|
function verdictStamp(run4) {
|
|
10284
10482
|
return run4.completed_at ?? run4.started_at ?? "";
|
|
10285
10483
|
}
|
|
@@ -10315,7 +10513,7 @@ __name(isCurrentActionsRunCheck, "isCurrentActionsRunCheck");
|
|
|
10315
10513
|
function parseFindingsFile(path3) {
|
|
10316
10514
|
let parsed;
|
|
10317
10515
|
try {
|
|
10318
|
-
parsed = JSON.parse(
|
|
10516
|
+
parsed = JSON.parse(readFileSync14(path3, "utf8"));
|
|
10319
10517
|
} catch {
|
|
10320
10518
|
return null;
|
|
10321
10519
|
}
|
|
@@ -10618,7 +10816,7 @@ async function runPresubmit(args) {
|
|
|
10618
10816
|
findingsFileInvalid,
|
|
10619
10817
|
headDrift
|
|
10620
10818
|
};
|
|
10621
|
-
|
|
10819
|
+
writeFileSync14(outPath, JSON.stringify(result, null, 2) + "\n", "utf8");
|
|
10622
10820
|
writeStdoutLine(`Wrote presubmit report to ${outPath}`);
|
|
10623
10821
|
}
|
|
10624
10822
|
__name(runPresubmit, "runPresubmit");
|
|
@@ -10657,17 +10855,17 @@ var presubmitCommand = {
|
|
|
10657
10855
|
// packages/cli/src/commands/review/publish-assets.ts
|
|
10658
10856
|
init_esbuild_shims();
|
|
10659
10857
|
import { createHash as createHash2 } from "node:crypto";
|
|
10660
|
-
import { readFileSync as
|
|
10858
|
+
import { readFileSync as readFileSync16, statSync as statSync6, writeFileSync as writeFileSync15, mkdirSync as mkdirSync15 } from "node:fs";
|
|
10661
10859
|
import { basename as basename5, dirname as dirname11, resolve as resolve10 } from "node:path";
|
|
10662
10860
|
|
|
10663
10861
|
// packages/cli/src/commands/review/lib/authorization.ts
|
|
10664
10862
|
init_esbuild_shims();
|
|
10665
|
-
import { readFileSync as
|
|
10863
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
10666
10864
|
|
|
10667
10865
|
// packages/cli/src/services/skill-args-file.ts
|
|
10668
10866
|
init_esbuild_shims();
|
|
10669
10867
|
import {
|
|
10670
|
-
mkdirSync as
|
|
10868
|
+
mkdirSync as mkdirSync14,
|
|
10671
10869
|
openSync as openSync2,
|
|
10672
10870
|
writeSync,
|
|
10673
10871
|
closeSync as closeSync2,
|
|
@@ -10676,9 +10874,9 @@ import {
|
|
|
10676
10874
|
existsSync as existsSync5,
|
|
10677
10875
|
constants
|
|
10678
10876
|
} from "node:fs";
|
|
10679
|
-
import { join as
|
|
10877
|
+
import { join as join12 } from "node:path";
|
|
10680
10878
|
var debugLogger3 = createDebugLogger("SKILL_ARGS_FILE");
|
|
10681
|
-
var SKILL_ARGS_DIR =
|
|
10879
|
+
var SKILL_ARGS_DIR = join12(".qwen", "tmp");
|
|
10682
10880
|
function safe(s) {
|
|
10683
10881
|
return s.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
10684
10882
|
}
|
|
@@ -10688,11 +10886,11 @@ function currentSessionId() {
|
|
|
10688
10886
|
}
|
|
10689
10887
|
__name(currentSessionId, "currentSessionId");
|
|
10690
10888
|
function skillArgsDir(sessionId = currentSessionId()) {
|
|
10691
|
-
return sessionId ?
|
|
10889
|
+
return sessionId ? join12(SKILL_ARGS_DIR, `s-${safe(sessionId)}`) : SKILL_ARGS_DIR;
|
|
10692
10890
|
}
|
|
10693
10891
|
__name(skillArgsDir, "skillArgsDir");
|
|
10694
10892
|
function skillArgsPath(skillName, sessionId = currentSessionId()) {
|
|
10695
|
-
return
|
|
10893
|
+
return join12(
|
|
10696
10894
|
skillArgsDir(sessionId),
|
|
10697
10895
|
`qwen-skill-args-${safe(skillName)}.txt`
|
|
10698
10896
|
);
|
|
@@ -10702,7 +10900,7 @@ function writeSkillArgs(skillName, args) {
|
|
|
10702
10900
|
const path3 = skillArgsPath(skillName);
|
|
10703
10901
|
try {
|
|
10704
10902
|
const dir = skillArgsDir();
|
|
10705
|
-
|
|
10903
|
+
mkdirSync14(dir, { recursive: true });
|
|
10706
10904
|
if (lstatSync3(dir).isSymbolicLink()) {
|
|
10707
10905
|
debugLogger3.warn(
|
|
10708
10906
|
`Skill args directory ${dir} is a symlink; refusing to write through it.`
|
|
@@ -10785,7 +10983,7 @@ function reviewWriteAuthorization(req) {
|
|
|
10785
10983
|
const path3 = currentSessionId() === "" && req.skillArgs ? req.skillArgs : sessionScoped;
|
|
10786
10984
|
let raw;
|
|
10787
10985
|
try {
|
|
10788
|
-
raw =
|
|
10986
|
+
raw = readFileSync15(path3, "utf8");
|
|
10789
10987
|
} catch {
|
|
10790
10988
|
return {
|
|
10791
10989
|
ok: false,
|
|
@@ -11051,7 +11249,7 @@ function runPublishAssets(args) {
|
|
|
11051
11249
|
const fileList = [...args.files ?? []];
|
|
11052
11250
|
if (args.findings) {
|
|
11053
11251
|
try {
|
|
11054
|
-
const artifact = JSON.parse(
|
|
11252
|
+
const artifact = JSON.parse(readFileSync16(resolve10(args.findings), "utf8"));
|
|
11055
11253
|
findings = validateFindings(
|
|
11056
11254
|
Array.isArray(artifact) ? artifact : artifact.findings
|
|
11057
11255
|
);
|
|
@@ -11081,7 +11279,7 @@ function runPublishAssets(args) {
|
|
|
11081
11279
|
for (const file of unique) {
|
|
11082
11280
|
const abs = resolve10(file);
|
|
11083
11281
|
try {
|
|
11084
|
-
const st =
|
|
11282
|
+
const st = statSync6(abs);
|
|
11085
11283
|
if (!st.isFile()) throw new Error("not a regular file");
|
|
11086
11284
|
stats.push({ file, abs, basename: basename5(abs), bytes: st.size });
|
|
11087
11285
|
} catch (err) {
|
|
@@ -11100,7 +11298,7 @@ function runPublishAssets(args) {
|
|
|
11100
11298
|
for (const st of stats) {
|
|
11101
11299
|
let content;
|
|
11102
11300
|
try {
|
|
11103
|
-
content =
|
|
11301
|
+
content = readFileSync16(st.abs);
|
|
11104
11302
|
} catch (err) {
|
|
11105
11303
|
refuse(
|
|
11106
11304
|
`cannot read ${JSON.stringify(st.file)}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -11147,8 +11345,8 @@ function runPublishAssets(args) {
|
|
|
11147
11345
|
published
|
|
11148
11346
|
};
|
|
11149
11347
|
const outPath = resolve10(args.out);
|
|
11150
|
-
|
|
11151
|
-
|
|
11348
|
+
mkdirSync15(dirname11(outPath), { recursive: true });
|
|
11349
|
+
writeFileSync15(outPath, `${JSON.stringify(manifest, null, 2)}
|
|
11152
11350
|
`, "utf8");
|
|
11153
11351
|
if (findings && !args.findingsOut) {
|
|
11154
11352
|
writeStderrLine(
|
|
@@ -11163,8 +11361,8 @@ function runPublishAssets(args) {
|
|
|
11163
11361
|
});
|
|
11164
11362
|
const report = buildReport(updated);
|
|
11165
11363
|
const fOut = resolve10(args.findingsOut);
|
|
11166
|
-
|
|
11167
|
-
|
|
11364
|
+
mkdirSync15(dirname11(fOut), { recursive: true });
|
|
11365
|
+
writeFileSync15(fOut, `${JSON.stringify(report, null, 2)}
|
|
11168
11366
|
`, "utf8");
|
|
11169
11367
|
}
|
|
11170
11368
|
writeStderrLine(
|
|
@@ -11226,7 +11424,7 @@ var publishAssetsCommand = {
|
|
|
11226
11424
|
|
|
11227
11425
|
// packages/cli/src/commands/review/resolve-anchors.ts
|
|
11228
11426
|
init_esbuild_shims();
|
|
11229
|
-
import { readFileSync as
|
|
11427
|
+
import { readFileSync as readFileSync17, writeFileSync as writeFileSync16, mkdirSync as mkdirSync16 } from "node:fs";
|
|
11230
11428
|
import { dirname as dirname12, resolve as resolve11 } from "node:path";
|
|
11231
11429
|
|
|
11232
11430
|
// packages/cli/src/commands/review/lib/anchors.ts
|
|
@@ -11451,7 +11649,7 @@ __name(validateRequests, "validateRequests");
|
|
|
11451
11649
|
function runResolveAnchors(args) {
|
|
11452
11650
|
let diffText;
|
|
11453
11651
|
try {
|
|
11454
|
-
diffText =
|
|
11652
|
+
diffText = readFileSync17(args.diff, "utf8");
|
|
11455
11653
|
} catch (err) {
|
|
11456
11654
|
throw new Error(
|
|
11457
11655
|
`Cannot read diff file ${args.diff}: ${err.message}`
|
|
@@ -11459,7 +11657,7 @@ function runResolveAnchors(args) {
|
|
|
11459
11657
|
}
|
|
11460
11658
|
let rawText;
|
|
11461
11659
|
try {
|
|
11462
|
-
rawText =
|
|
11660
|
+
rawText = readFileSync17(args.input, "utf8");
|
|
11463
11661
|
} catch (err) {
|
|
11464
11662
|
throw new Error(
|
|
11465
11663
|
`Cannot read findings file ${args.input}: ${err.message}`
|
|
@@ -11490,8 +11688,8 @@ function runResolveAnchors(args) {
|
|
|
11490
11688
|
loose: resolved.filter((r) => r.tier?.startsWith("loose")).length
|
|
11491
11689
|
}
|
|
11492
11690
|
};
|
|
11493
|
-
|
|
11494
|
-
|
|
11691
|
+
mkdirSync16(dirname12(resolve11(args.out)), { recursive: true });
|
|
11692
|
+
writeFileSync16(args.out, JSON.stringify(report, null, 2), "utf8");
|
|
11495
11693
|
writeStdoutLine(`Wrote resolved anchors to ${args.out}`);
|
|
11496
11694
|
const s = report.stats;
|
|
11497
11695
|
writeStderrLine(
|
|
@@ -11538,7 +11736,7 @@ var resolveAnchorsCommand = {
|
|
|
11538
11736
|
|
|
11539
11737
|
// packages/cli/src/commands/review/check-coverage.ts
|
|
11540
11738
|
init_esbuild_shims();
|
|
11541
|
-
import { writeFileSync as
|
|
11739
|
+
import { writeFileSync as writeFileSync17, mkdirSync as mkdirSync17 } from "node:fs";
|
|
11542
11740
|
import { dirname as dirname13, resolve as resolve12 } from "node:path";
|
|
11543
11741
|
function runCheckCoverage(args) {
|
|
11544
11742
|
let report;
|
|
@@ -11555,8 +11753,8 @@ This is an environment problem, not a finding about the agents. Coverage cannot
|
|
|
11555
11753
|
}
|
|
11556
11754
|
throw err;
|
|
11557
11755
|
}
|
|
11558
|
-
|
|
11559
|
-
|
|
11756
|
+
mkdirSync17(dirname13(resolve12(args.out)), { recursive: true });
|
|
11757
|
+
writeFileSync17(args.out, JSON.stringify(report, null, 2));
|
|
11560
11758
|
writeStdoutLine(`Wrote coverage report to ${args.out}`);
|
|
11561
11759
|
const totalChunks = report.coveredChunks.length + report.missingChunks.length + report.uncoverableChunks.length;
|
|
11562
11760
|
const worked = report.agents - report.blindAgents.length - report.idleAgents.length;
|
|
@@ -11655,8 +11853,8 @@ var checkCoverageCommand = {
|
|
|
11655
11853
|
// packages/cli/src/commands/review/agent-prompt.ts
|
|
11656
11854
|
init_esbuild_shims();
|
|
11657
11855
|
import { createHash as createHash3 } from "node:crypto";
|
|
11658
|
-
import { readFileSync as
|
|
11659
|
-
import { dirname as dirname14, join as
|
|
11856
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
11857
|
+
import { dirname as dirname14, join as join13, resolve as resolve13 } from "node:path";
|
|
11660
11858
|
|
|
11661
11859
|
// packages/cli/src/commands/review/lib/path-rules.ts
|
|
11662
11860
|
init_esbuild_shims();
|
|
@@ -12108,7 +12306,7 @@ function buildRoleBrief(report, role, opts = {}) {
|
|
|
12108
12306
|
"agent-prompt: --role 0 needs a plan with `prNumber` and `ownerRepo` (the report `fetch-pr` writes). Issue fidelity has nothing to check against without a pull request."
|
|
12109
12307
|
);
|
|
12110
12308
|
}
|
|
12111
|
-
const ctx = opts.planPath ?
|
|
12309
|
+
const ctx = opts.planPath ? join13(dirname14(resolve13(opts.planPath)), `qwen-review-pr-${pr}-context.md`) : null;
|
|
12112
12310
|
parts.push(
|
|
12113
12311
|
"",
|
|
12114
12312
|
`**This PR:** #${pr} of \`${repo}\`. Use exactly that number and repo \u2014 a bare \`gh pr view\` falls back to the current branch's PR and would judge this diff against an unrelated issue.`
|
|
@@ -12367,7 +12565,7 @@ The \`description\` parameter of each Agent call is the task name the user watch
|
|
|
12367
12565
|
);
|
|
12368
12566
|
}
|
|
12369
12567
|
__name(runRoster, "runRoster");
|
|
12370
|
-
function
|
|
12568
|
+
function requireAuditableChunks(report) {
|
|
12371
12569
|
if (!Array.isArray(report.chunks) || report.chunks.length === 0) {
|
|
12372
12570
|
throw new Error("agent-prompt: the plan has no `chunks[]`.");
|
|
12373
12571
|
}
|
|
@@ -12378,6 +12576,11 @@ function runAllChunks(report, planPath, role, findingsContent, rules, round) {
|
|
|
12378
12576
|
`agent-prompt: the plan has ${problem} \u2014 a round built from what remains would look complete while a territory goes unaudited. Re-run the Step 1 capture; do not hand-edit the plan.`
|
|
12379
12577
|
);
|
|
12380
12578
|
}
|
|
12579
|
+
return chunks;
|
|
12580
|
+
}
|
|
12581
|
+
__name(requireAuditableChunks, "requireAuditableChunks");
|
|
12582
|
+
function runAllChunks(report, planPath, role, findingsContent, rules, round) {
|
|
12583
|
+
const chunks = requireAuditableChunks(report);
|
|
12381
12584
|
const digest = findingsDigest(findingsContent, rules);
|
|
12382
12585
|
const roundPart = round !== void 0 ? `--round-${round}` : "";
|
|
12383
12586
|
const blocks = chunks.map((c, i) => {
|
|
@@ -12483,6 +12686,11 @@ function runAgentPrompt(args) {
|
|
|
12483
12686
|
);
|
|
12484
12687
|
}
|
|
12485
12688
|
}
|
|
12689
|
+
if (role === "reverse-audit" && !hasRound) {
|
|
12690
|
+
bad(
|
|
12691
|
+
"--role reverse-audit builds one round of the Step 5 loop and requires --round <k>: the label keys the record and the budget gate's per-round accounting."
|
|
12692
|
+
);
|
|
12693
|
+
}
|
|
12486
12694
|
} else if (hasFindings) {
|
|
12487
12695
|
const findingRoles = Object.keys(BRIEFS).filter(
|
|
12488
12696
|
(r) => BRIEFS[r].acceptsFindings
|
|
@@ -12513,7 +12721,7 @@ function runAgentPrompt(args) {
|
|
|
12513
12721
|
}
|
|
12514
12722
|
let report;
|
|
12515
12723
|
try {
|
|
12516
|
-
report = JSON.parse(
|
|
12724
|
+
report = JSON.parse(readFileSync18(args.plan, "utf8"));
|
|
12517
12725
|
} catch (err) {
|
|
12518
12726
|
throw new Error(
|
|
12519
12727
|
`agent-prompt: cannot read the plan ${args.plan}: ${err.message}`
|
|
@@ -12522,7 +12730,7 @@ function runAgentPrompt(args) {
|
|
|
12522
12730
|
let rules;
|
|
12523
12731
|
if (args.rules) {
|
|
12524
12732
|
try {
|
|
12525
|
-
rules =
|
|
12733
|
+
rules = readFileSync18(args.rules, "utf8");
|
|
12526
12734
|
} catch (err) {
|
|
12527
12735
|
throw new Error(
|
|
12528
12736
|
`agent-prompt: cannot read the rules ${args.rules}: ${err.message}. Omit --rules if this review has none; passing a path that does not resolve would silently review without the project rules it was told to enforce.`
|
|
@@ -12537,7 +12745,7 @@ function runAgentPrompt(args) {
|
|
|
12537
12745
|
if (hasFindings && args.role) {
|
|
12538
12746
|
const role = args.role;
|
|
12539
12747
|
try {
|
|
12540
|
-
findingsContent =
|
|
12748
|
+
findingsContent = readFileSync18(args.findings, "utf8");
|
|
12541
12749
|
} catch (err) {
|
|
12542
12750
|
throw new Error(
|
|
12543
12751
|
`agent-prompt: cannot read the findings ${args.findings}: ${err.message}. Pass a path that resolves \u2014 --findings is required for this role, so omitting it only fails one guard earlier. An early reverse-audit round with nothing confirmed passes an empty file (create it first).`
|
|
@@ -12549,6 +12757,21 @@ function runAgentPrompt(args) {
|
|
|
12549
12757
|
);
|
|
12550
12758
|
}
|
|
12551
12759
|
}
|
|
12760
|
+
if (args.allChunks && args.role && findingsContent !== void 0) {
|
|
12761
|
+
requireAuditableChunks(report);
|
|
12762
|
+
}
|
|
12763
|
+
if (args.role === "reverse-audit") {
|
|
12764
|
+
const spent = reverseAuditBudgetExhausted(
|
|
12765
|
+
process.env,
|
|
12766
|
+
expectedRoundSeconds(args.plan, args.round)
|
|
12767
|
+
);
|
|
12768
|
+
if (spent !== null) {
|
|
12769
|
+
writeBudgetStop(args.plan, spent, args.round);
|
|
12770
|
+
writeStderrLine(reverseAuditBudgetMessage(spent, args.round));
|
|
12771
|
+
process.exitCode = 4;
|
|
12772
|
+
return;
|
|
12773
|
+
}
|
|
12774
|
+
}
|
|
12552
12775
|
if (args.allChunks && args.role && findingsContent !== void 0) {
|
|
12553
12776
|
runAllChunks(
|
|
12554
12777
|
report,
|
|
@@ -12558,6 +12781,9 @@ function runAgentPrompt(args) {
|
|
|
12558
12781
|
rules,
|
|
12559
12782
|
args.round
|
|
12560
12783
|
);
|
|
12784
|
+
if (args.role === "reverse-audit") {
|
|
12785
|
+
stampRound(args.plan, args.round);
|
|
12786
|
+
}
|
|
12561
12787
|
return;
|
|
12562
12788
|
}
|
|
12563
12789
|
let prompt;
|
|
@@ -12588,11 +12814,14 @@ function runAgentPrompt(args) {
|
|
|
12588
12814
|
const printed = findingsContent !== void 0 && args.role ? foldFindings(args.role, findingsContent, prompt) : prompt;
|
|
12589
12815
|
recordPrompt(args.plan, key, printed);
|
|
12590
12816
|
writeStdoutLine(printed);
|
|
12817
|
+
if (args.role === "reverse-audit") {
|
|
12818
|
+
stampRound(args.plan, args.round);
|
|
12819
|
+
}
|
|
12591
12820
|
}
|
|
12592
12821
|
__name(runAgentPrompt, "runAgentPrompt");
|
|
12593
12822
|
var agentPromptCommand = {
|
|
12594
12823
|
command: "agent-prompt",
|
|
12595
|
-
describe: "Build a review agent's launch prompt from the plan (the diff path, its line ranges and the agent's own brief are welded in, not left to the caller to remember)",
|
|
12824
|
+
describe: "Build a review agent's launch prompt from the plan (the diff path, its line ranges and the agent's own brief are welded in, not left to the caller to remember). Exit codes: 0 built; 4 the review time budget refused another reverse-audit round (a termination rule, not an error \u2014 see the BUDGET line on stderr); anything else is a bad call or a broken plan.",
|
|
12596
12825
|
builder: /* @__PURE__ */ __name((yargs) => yargs.option("plan", {
|
|
12597
12826
|
type: "string",
|
|
12598
12827
|
demandOption: true,
|
|
@@ -12647,17 +12876,17 @@ init_esbuild_shims();
|
|
|
12647
12876
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
12648
12877
|
import {
|
|
12649
12878
|
existsSync as existsSync7,
|
|
12650
|
-
readFileSync as
|
|
12879
|
+
readFileSync as readFileSync20,
|
|
12651
12880
|
rmSync as rmSync5,
|
|
12652
12881
|
statfsSync,
|
|
12653
|
-
writeFileSync as
|
|
12882
|
+
writeFileSync as writeFileSync18
|
|
12654
12883
|
} from "node:fs";
|
|
12655
|
-
import { join as
|
|
12884
|
+
import { join as join15, resolve as resolve14 } from "node:path";
|
|
12656
12885
|
|
|
12657
12886
|
// packages/cli/src/commands/review/lib/workspaces.ts
|
|
12658
12887
|
init_esbuild_shims();
|
|
12659
|
-
import { existsSync as existsSync6, readFileSync as
|
|
12660
|
-
import { join as
|
|
12888
|
+
import { existsSync as existsSync6, readFileSync as readFileSync19, readdirSync as readdirSync4 } from "node:fs";
|
|
12889
|
+
import { join as join14 } from "node:path";
|
|
12661
12890
|
function isWorkspaceMember(filePath, workspaceGlobs) {
|
|
12662
12891
|
return workspaceDirFor(filePath, workspaceGlobs) !== null;
|
|
12663
12892
|
}
|
|
@@ -12695,7 +12924,7 @@ __name(hasUnmodeledWorkspaceGlob, "hasUnmodeledWorkspaceGlob");
|
|
|
12695
12924
|
function readWorkspaceGlobs(root) {
|
|
12696
12925
|
try {
|
|
12697
12926
|
const pkg = JSON.parse(
|
|
12698
|
-
|
|
12927
|
+
readFileSync19(join14(root, "package.json"), "utf8")
|
|
12699
12928
|
);
|
|
12700
12929
|
const ws = pkg.workspaces;
|
|
12701
12930
|
const globs = Array.isArray(ws) ? ws : Array.isArray(ws?.packages) ? ws.packages : [];
|
|
@@ -12708,7 +12937,7 @@ __name(readWorkspaceGlobs, "readWorkspaceGlobs");
|
|
|
12708
12937
|
function readRootPackage(root) {
|
|
12709
12938
|
let pkg;
|
|
12710
12939
|
try {
|
|
12711
|
-
pkg = JSON.parse(
|
|
12940
|
+
pkg = JSON.parse(readFileSync19(join14(root, "package.json"), "utf8"));
|
|
12712
12941
|
} catch {
|
|
12713
12942
|
return null;
|
|
12714
12943
|
}
|
|
@@ -12732,7 +12961,7 @@ function readWorkspacePackages(root) {
|
|
|
12732
12961
|
const base = g.slice(0, -2);
|
|
12733
12962
|
let entries;
|
|
12734
12963
|
try {
|
|
12735
|
-
entries = readdirSync4(
|
|
12964
|
+
entries = readdirSync4(join14(root, base), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
12736
12965
|
} catch {
|
|
12737
12966
|
continue;
|
|
12738
12967
|
}
|
|
@@ -12744,11 +12973,11 @@ function readWorkspacePackages(root) {
|
|
|
12744
12973
|
const pkgs = [];
|
|
12745
12974
|
for (const dir of dirs) {
|
|
12746
12975
|
if (workspaceDirFor(`${dir}/package.json`, globs) !== dir) continue;
|
|
12747
|
-
const manifest =
|
|
12976
|
+
const manifest = join14(root, dir, "package.json");
|
|
12748
12977
|
if (!existsSync6(manifest)) continue;
|
|
12749
12978
|
let pkg;
|
|
12750
12979
|
try {
|
|
12751
|
-
pkg = JSON.parse(
|
|
12980
|
+
pkg = JSON.parse(readFileSync19(manifest, "utf8"));
|
|
12752
12981
|
} catch {
|
|
12753
12982
|
continue;
|
|
12754
12983
|
}
|
|
@@ -12921,7 +13150,7 @@ __name(unresolvedWorkspaceDeps, "unresolvedWorkspaceDeps");
|
|
|
12921
13150
|
function changedFilesFrom(planPath) {
|
|
12922
13151
|
let parsed;
|
|
12923
13152
|
try {
|
|
12924
|
-
parsed = JSON.parse(
|
|
13153
|
+
parsed = JSON.parse(readFileSync20(planPath, "utf8"));
|
|
12925
13154
|
} catch (err) {
|
|
12926
13155
|
throw new Error(
|
|
12927
13156
|
`build-test: cannot read the plan ${planPath}: ${err.message}`
|
|
@@ -13004,15 +13233,15 @@ function runBuildTest(args) {
|
|
|
13004
13233
|
timedOut: [],
|
|
13005
13234
|
note: ""
|
|
13006
13235
|
};
|
|
13007
|
-
const npmLock = existsSync7(
|
|
13008
|
-
const installComplete = /* @__PURE__ */ __name(() => existsSync7(
|
|
13009
|
-
if (args.install && !npmLock && !existsSync7(
|
|
13236
|
+
const npmLock = existsSync7(join15(root, "package-lock.json"));
|
|
13237
|
+
const installComplete = /* @__PURE__ */ __name(() => existsSync7(join15(root, "node_modules", ".package-lock.json")), "installComplete");
|
|
13238
|
+
if (args.install && !npmLock && !existsSync7(join15(root, "node_modules"))) {
|
|
13010
13239
|
const altLock = [
|
|
13011
13240
|
["yarn.lock", "yarn install --frozen-lockfile"],
|
|
13012
13241
|
["pnpm-lock.yaml", "pnpm install --frozen-lockfile"],
|
|
13013
13242
|
["bun.lockb", "bun install --frozen-lockfile"],
|
|
13014
13243
|
["bun.lock", "bun install --frozen-lockfile"]
|
|
13015
|
-
].find(([f]) => existsSync7(
|
|
13244
|
+
].find(([f]) => existsSync7(join15(root, f)));
|
|
13016
13245
|
return unsupportedReport(
|
|
13017
13246
|
altLock ? `This is a ${altLock[0]} repo with no installed \`node_modules\`, so \`npm ci\` cannot install it. Run \`${altLock[1]}\` first, then fall back to the build/test precedence in your brief, each command with a deadline it can meet.` : "There is no lockfile and no `node_modules` here, so nothing can be installed deterministically. Install dependencies first, then fall back to the build/test precedence in your brief."
|
|
13018
13247
|
);
|
|
@@ -13030,7 +13259,7 @@ function runBuildTest(args) {
|
|
|
13030
13259
|
if (install.timedOut) results.timedOut.push(install.command);
|
|
13031
13260
|
if (install.timedOut) {
|
|
13032
13261
|
try {
|
|
13033
|
-
rmSync5(
|
|
13262
|
+
rmSync5(join15(root, "node_modules"), {
|
|
13034
13263
|
recursive: true,
|
|
13035
13264
|
force: true,
|
|
13036
13265
|
maxRetries: 3
|
|
@@ -13153,7 +13382,7 @@ var buildTestCommand = {
|
|
|
13153
13382
|
try {
|
|
13154
13383
|
const report = runBuildTest(args);
|
|
13155
13384
|
if (args.out) {
|
|
13156
|
-
|
|
13385
|
+
writeFileSync18(args.out, JSON.stringify(report, null, 2));
|
|
13157
13386
|
}
|
|
13158
13387
|
writeStdoutLine(JSON.stringify(report, null, 2));
|
|
13159
13388
|
} catch (err) {
|
|
@@ -13168,13 +13397,13 @@ init_esbuild_shims();
|
|
|
13168
13397
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
13169
13398
|
import {
|
|
13170
13399
|
existsSync as existsSync8,
|
|
13171
|
-
mkdirSync as
|
|
13172
|
-
readFileSync as
|
|
13400
|
+
mkdirSync as mkdirSync18,
|
|
13401
|
+
readFileSync as readFileSync21,
|
|
13173
13402
|
rmSync as rmSync7,
|
|
13174
|
-
statSync as
|
|
13175
|
-
writeFileSync as
|
|
13403
|
+
statSync as statSync7,
|
|
13404
|
+
writeFileSync as writeFileSync19
|
|
13176
13405
|
} from "node:fs";
|
|
13177
|
-
import { dirname as dirname15, join as
|
|
13406
|
+
import { dirname as dirname15, join as join16, resolve as resolve15 } from "node:path";
|
|
13178
13407
|
|
|
13179
13408
|
// packages/cli/src/commands/review/lib/worktree.ts
|
|
13180
13409
|
init_esbuild_shims();
|
|
@@ -13221,7 +13450,7 @@ function runBaseTree(args) {
|
|
|
13221
13450
|
}), "unavailable");
|
|
13222
13451
|
let plan;
|
|
13223
13452
|
try {
|
|
13224
|
-
plan = JSON.parse(
|
|
13453
|
+
plan = JSON.parse(readFileSync21(args.plan, "utf8"));
|
|
13225
13454
|
} catch (err) {
|
|
13226
13455
|
return unavailable(
|
|
13227
13456
|
`cannot read the plan ${args.plan}: ${err.message}`
|
|
@@ -13243,10 +13472,10 @@ function runBaseTree(args) {
|
|
|
13243
13472
|
return unavailable(`the review worktree ${worktree} does not exist`);
|
|
13244
13473
|
}
|
|
13245
13474
|
const tree = baseWorktreePath(worktree);
|
|
13246
|
-
const marker = /* @__PURE__ */ __name(() =>
|
|
13247
|
-
const failedMarker = /* @__PURE__ */ __name(() =>
|
|
13475
|
+
const marker = /* @__PURE__ */ __name(() => join16(tree, ".qwen-review-base-ok"), "marker");
|
|
13476
|
+
const failedMarker = /* @__PURE__ */ __name(() => join16(tree, ".qwen-review-base-failed"), "failedMarker");
|
|
13248
13477
|
try {
|
|
13249
|
-
if (existsSync8(tree) &&
|
|
13478
|
+
if (existsSync8(tree) && readFileSync21(marker(), "utf8").trim() === baseSha && gitOut(tree, "rev-parse", "HEAD") === baseSha) {
|
|
13250
13479
|
return {
|
|
13251
13480
|
available: true,
|
|
13252
13481
|
path: tree,
|
|
@@ -13258,7 +13487,7 @@ function runBaseTree(args) {
|
|
|
13258
13487
|
} catch {
|
|
13259
13488
|
}
|
|
13260
13489
|
try {
|
|
13261
|
-
if (existsSync8(tree) &&
|
|
13490
|
+
if (existsSync8(tree) && readFileSync21(failedMarker(), "utf8").trim() === baseSha) {
|
|
13262
13491
|
return {
|
|
13263
13492
|
available: false,
|
|
13264
13493
|
path: tree,
|
|
@@ -13271,14 +13500,14 @@ function runBaseTree(args) {
|
|
|
13271
13500
|
}
|
|
13272
13501
|
const lock = `${tree}.lock`;
|
|
13273
13502
|
try {
|
|
13274
|
-
const age = Date.now() -
|
|
13503
|
+
const age = Date.now() - statSync7(lock).mtimeMs;
|
|
13275
13504
|
if (age > 30 * 60 * 1e3) {
|
|
13276
13505
|
rmSync7(lock, { recursive: true, force: true });
|
|
13277
13506
|
}
|
|
13278
13507
|
} catch {
|
|
13279
13508
|
}
|
|
13280
13509
|
try {
|
|
13281
|
-
|
|
13510
|
+
mkdirSync18(lock);
|
|
13282
13511
|
} catch (err) {
|
|
13283
13512
|
if (err.code !== "EEXIST") {
|
|
13284
13513
|
return unavailable(
|
|
@@ -13316,7 +13545,7 @@ function runBaseTree(args) {
|
|
|
13316
13545
|
});
|
|
13317
13546
|
if (!build.ok || build.toolchain !== "npm" || build.build.length === 0) {
|
|
13318
13547
|
try {
|
|
13319
|
-
|
|
13548
|
+
writeFileSync19(failedMarker(), `${baseSha2}
|
|
13320
13549
|
`);
|
|
13321
13550
|
} catch {
|
|
13322
13551
|
}
|
|
@@ -13329,7 +13558,7 @@ function runBaseTree(args) {
|
|
|
13329
13558
|
};
|
|
13330
13559
|
}
|
|
13331
13560
|
try {
|
|
13332
|
-
|
|
13561
|
+
writeFileSync19(marker(), `${baseSha2}
|
|
13333
13562
|
`);
|
|
13334
13563
|
} catch {
|
|
13335
13564
|
}
|
|
@@ -13369,8 +13598,8 @@ var baseTreeCommand = {
|
|
|
13369
13598
|
try {
|
|
13370
13599
|
const report = runBaseTree(args);
|
|
13371
13600
|
if (args.out) {
|
|
13372
|
-
|
|
13373
|
-
|
|
13601
|
+
mkdirSync18(dirname15(resolve15(args.out)), { recursive: true });
|
|
13602
|
+
writeFileSync19(resolve15(args.out), JSON.stringify(report, null, 2));
|
|
13374
13603
|
}
|
|
13375
13604
|
writeStdoutLine(JSON.stringify(report, null, 2));
|
|
13376
13605
|
writeStderrLine(`base-tree: ${report.note}`);
|
|
@@ -13384,7 +13613,7 @@ var baseTreeCommand = {
|
|
|
13384
13613
|
// packages/cli/src/commands/review/test-delta.ts
|
|
13385
13614
|
init_esbuild_shims();
|
|
13386
13615
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
13387
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
13616
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync19, readFileSync as readFileSync22, writeFileSync as writeFileSync20 } from "node:fs";
|
|
13388
13617
|
import { dirname as dirname16, resolve as resolve16 } from "node:path";
|
|
13389
13618
|
var ANSI_SGR_RE2 = /\x1b\[[0-9;]*m/g;
|
|
13390
13619
|
var RERUNNABLE_COMMAND_RE = /^npm test(?: --workspace="[\w@./-]+")?$/;
|
|
@@ -13458,7 +13687,7 @@ function runTestDelta(args) {
|
|
|
13458
13687
|
}), "empty");
|
|
13459
13688
|
let report;
|
|
13460
13689
|
try {
|
|
13461
|
-
report = JSON.parse(
|
|
13690
|
+
report = JSON.parse(readFileSync22(args.report, "utf8"));
|
|
13462
13691
|
} catch (err) {
|
|
13463
13692
|
return empty(
|
|
13464
13693
|
`cannot read the build-test report ${args.report}: ${err.message}`
|
|
@@ -13600,8 +13829,8 @@ var testDeltaCommand = {
|
|
|
13600
13829
|
const args = argv;
|
|
13601
13830
|
const report = runTestDelta(args);
|
|
13602
13831
|
if (args.out) {
|
|
13603
|
-
|
|
13604
|
-
|
|
13832
|
+
mkdirSync19(dirname16(resolve16(args.out)), { recursive: true });
|
|
13833
|
+
writeFileSync20(resolve16(args.out), JSON.stringify(report, null, 2));
|
|
13605
13834
|
}
|
|
13606
13835
|
writeStdoutLine(JSON.stringify(report, null, 2));
|
|
13607
13836
|
writeStderrLine(`test-delta: ${report.note}`);
|
|
@@ -13612,14 +13841,14 @@ var testDeltaCommand = {
|
|
|
13612
13841
|
init_esbuild_shims();
|
|
13613
13842
|
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
13614
13843
|
import {
|
|
13615
|
-
mkdirSync as
|
|
13616
|
-
writeFileSync as
|
|
13617
|
-
readFileSync as
|
|
13844
|
+
mkdirSync as mkdirSync20,
|
|
13845
|
+
writeFileSync as writeFileSync21,
|
|
13846
|
+
readFileSync as readFileSync23,
|
|
13618
13847
|
existsSync as existsSync10,
|
|
13619
13848
|
rmSync as rmSync8,
|
|
13620
|
-
statSync as
|
|
13849
|
+
statSync as statSync8
|
|
13621
13850
|
} from "node:fs";
|
|
13622
|
-
import { dirname as dirname17, join as
|
|
13851
|
+
import { dirname as dirname17, join as join17, resolve as resolve17 } from "node:path";
|
|
13623
13852
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
13624
13853
|
var SERVER_NAME_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
13625
13854
|
function shellQuote(v) {
|
|
@@ -13631,7 +13860,7 @@ var LOG_MAX_BYTES = 8 * 1024 * 1024;
|
|
|
13631
13860
|
var POLL_MS = 250;
|
|
13632
13861
|
function logBytes(p) {
|
|
13633
13862
|
try {
|
|
13634
|
-
return
|
|
13863
|
+
return statSync8(p).size;
|
|
13635
13864
|
} catch {
|
|
13636
13865
|
return 0;
|
|
13637
13866
|
}
|
|
@@ -13737,13 +13966,13 @@ function runDrive(args) {
|
|
|
13737
13966
|
waitMs(POLL_MS);
|
|
13738
13967
|
}
|
|
13739
13968
|
}
|
|
13740
|
-
const dir =
|
|
13741
|
-
|
|
13742
|
-
const scriptPath =
|
|
13743
|
-
const logPath = args.logPath ??
|
|
13744
|
-
const sentinelPath =
|
|
13969
|
+
const dir = join17(tmpdir2(), `qwen-review-drive-${server}`);
|
|
13970
|
+
mkdirSync20(dir, { recursive: true });
|
|
13971
|
+
const scriptPath = join17(dir, "drive.sh");
|
|
13972
|
+
const logPath = args.logPath ?? join17(dir, "drive.log");
|
|
13973
|
+
const sentinelPath = join17(dir, "drive.rc");
|
|
13745
13974
|
rmSync8(sentinelPath, { force: true });
|
|
13746
|
-
|
|
13975
|
+
writeFileSync21(scriptPath, wrapScript(args.script, sentinelPath), "utf8");
|
|
13747
13976
|
const droveFrom = Date.now();
|
|
13748
13977
|
let output = "";
|
|
13749
13978
|
let exitCode = null;
|
|
@@ -13773,8 +14002,8 @@ function runDrive(args) {
|
|
|
13773
14002
|
}
|
|
13774
14003
|
const deadline = droveFrom + args.timeout * 1e3;
|
|
13775
14004
|
for (; ; ) {
|
|
13776
|
-
output = existsSync10(logPath) ?
|
|
13777
|
-
exitCode = existsSync10(sentinelPath) ? sentinelExitCode(
|
|
14005
|
+
output = existsSync10(logPath) ? readFileSync23(logPath, "utf8") : "";
|
|
14006
|
+
exitCode = existsSync10(sentinelPath) ? sentinelExitCode(readFileSync23(sentinelPath, "utf8")) : null;
|
|
13778
14007
|
if (exitCode !== null) {
|
|
13779
14008
|
outcome = "completed";
|
|
13780
14009
|
break;
|
|
@@ -13841,8 +14070,8 @@ var driveCommand = {
|
|
|
13841
14070
|
const args = argv;
|
|
13842
14071
|
const report = runDrive(args);
|
|
13843
14072
|
if (args.out) {
|
|
13844
|
-
|
|
13845
|
-
|
|
14073
|
+
mkdirSync20(dirname17(resolve17(args.out)), { recursive: true });
|
|
14074
|
+
writeFileSync21(resolve17(args.out), JSON.stringify(report, null, 2));
|
|
13846
14075
|
}
|
|
13847
14076
|
writeStdoutLine(JSON.stringify(report, null, 2));
|
|
13848
14077
|
writeStderrLine(`drive: ${report.note}`);
|
|
@@ -13859,7 +14088,7 @@ init_esbuild_shims();
|
|
|
13859
14088
|
import {
|
|
13860
14089
|
createServer
|
|
13861
14090
|
} from "node:http";
|
|
13862
|
-
import { appendFileSync, mkdirSync as
|
|
14091
|
+
import { appendFileSync, mkdirSync as mkdirSync21, writeFileSync as writeFileSync22 } from "node:fs";
|
|
13863
14092
|
import { dirname as dirname18, resolve as resolve18 } from "node:path";
|
|
13864
14093
|
import { pathToFileURL } from "node:url";
|
|
13865
14094
|
function messagesText(body) {
|
|
@@ -14116,8 +14345,8 @@ async function startMockProvider(args, respondOverride) {
|
|
|
14116
14345
|
respond = fn;
|
|
14117
14346
|
}
|
|
14118
14347
|
const logPath = resolve18(args.log);
|
|
14119
|
-
|
|
14120
|
-
|
|
14348
|
+
mkdirSync21(dirname18(logPath), { recursive: true });
|
|
14349
|
+
writeFileSync22(logPath, "");
|
|
14121
14350
|
let n = 0;
|
|
14122
14351
|
const record = /* @__PURE__ */ __name((entry) => appendFileSync(logPath, `${JSON.stringify(entry)}
|
|
14123
14352
|
`), "record");
|
|
@@ -14279,8 +14508,8 @@ var mockProviderCommand = {
|
|
|
14279
14508
|
const args = argv;
|
|
14280
14509
|
const { report, close } = await startMockProvider(args);
|
|
14281
14510
|
if (args.out) {
|
|
14282
|
-
|
|
14283
|
-
|
|
14511
|
+
mkdirSync21(dirname18(resolve18(args.out)), { recursive: true });
|
|
14512
|
+
writeFileSync22(resolve18(args.out), JSON.stringify(report, null, 2));
|
|
14284
14513
|
}
|
|
14285
14514
|
writeStdoutLine(JSON.stringify(report, null, 2));
|
|
14286
14515
|
writeStderrLine(`mock-provider: ${report.note}`);
|
|
@@ -14298,7 +14527,7 @@ var mockProviderCommand = {
|
|
|
14298
14527
|
// packages/cli/src/commands/review/extract-step.ts
|
|
14299
14528
|
init_esbuild_shims();
|
|
14300
14529
|
var import_yaml = __toESM(require_dist(), 1);
|
|
14301
|
-
import { mkdirSync as
|
|
14530
|
+
import { mkdirSync as mkdirSync22, readFileSync as readFileSync24, writeFileSync as writeFileSync23, chmodSync } from "node:fs";
|
|
14302
14531
|
import { dirname as dirname19, resolve as resolve19 } from "node:path";
|
|
14303
14532
|
function expressionsOf(...texts) {
|
|
14304
14533
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -14546,7 +14775,7 @@ function runExtractStep(args) {
|
|
|
14546
14775
|
const wfPath = resolve19(args.workflow);
|
|
14547
14776
|
let text;
|
|
14548
14777
|
try {
|
|
14549
|
-
text =
|
|
14778
|
+
text = readFileSync24(wfPath, "utf8");
|
|
14550
14779
|
} catch (err) {
|
|
14551
14780
|
throw new Error(
|
|
14552
14781
|
`extract-step: cannot read ${args.workflow}: ${err.message}`
|
|
@@ -14613,7 +14842,7 @@ function runExtractStep(args) {
|
|
|
14613
14842
|
const script = step.run;
|
|
14614
14843
|
const stepLabel = String(step.name ?? step.id ?? index);
|
|
14615
14844
|
const outPath = resolve19(args.out);
|
|
14616
|
-
|
|
14845
|
+
mkdirSync22(dirname19(outPath), { recursive: true });
|
|
14617
14846
|
const header = [
|
|
14618
14847
|
`#!/usr/bin/env ${shellCommand}`,
|
|
14619
14848
|
...commentLines(
|
|
@@ -14637,7 +14866,7 @@ function runExtractStep(args) {
|
|
|
14637
14866
|
),
|
|
14638
14867
|
""
|
|
14639
14868
|
].join("\n");
|
|
14640
|
-
|
|
14869
|
+
writeFileSync23(outPath, header + script + (script.endsWith("\n") ? "" : "\n"));
|
|
14641
14870
|
chmodSync(outPath, 493);
|
|
14642
14871
|
return {
|
|
14643
14872
|
workflow: args.workflow,
|
|
@@ -14698,7 +14927,7 @@ var extractStepCommand = {
|
|
|
14698
14927
|
|
|
14699
14928
|
// packages/cli/src/commands/review/submit.ts
|
|
14700
14929
|
init_esbuild_shims();
|
|
14701
|
-
import { mkdirSync as
|
|
14930
|
+
import { mkdirSync as mkdirSync23, readFileSync as readFileSync25 } from "node:fs";
|
|
14702
14931
|
|
|
14703
14932
|
// packages/cli/src/commands/review/lib/receipt.ts
|
|
14704
14933
|
init_esbuild_shims();
|
|
@@ -14720,7 +14949,7 @@ __name(parseReceiptIds, "parseReceiptIds");
|
|
|
14720
14949
|
var EVENTS = /* @__PURE__ */ new Set(["APPROVE", "REQUEST_CHANGES", "COMMENT"]);
|
|
14721
14950
|
function readReceiptIds(receiptPath) {
|
|
14722
14951
|
try {
|
|
14723
|
-
return parseReceiptIds(
|
|
14952
|
+
return parseReceiptIds(readFileSync25(receiptPath, "utf8"));
|
|
14724
14953
|
} catch {
|
|
14725
14954
|
return [];
|
|
14726
14955
|
}
|
|
@@ -14730,6 +14959,24 @@ function isDiffLine(n) {
|
|
|
14730
14959
|
return typeof n === "number" && Number.isSafeInteger(n) && n > 0;
|
|
14731
14960
|
}
|
|
14732
14961
|
__name(isDiffLine, "isDiffLine");
|
|
14962
|
+
function normalizeInlineComments(comments, modelId, cliVersion) {
|
|
14963
|
+
if (typeof modelId !== "string" || modelId.trim() === "") return comments;
|
|
14964
|
+
const footer = reviewFooter(modelId, cliVersion);
|
|
14965
|
+
return comments.map(
|
|
14966
|
+
(comment) => (
|
|
14967
|
+
// An empty body stays empty: this runs BEFORE the consistency check, and
|
|
14968
|
+
// a footer pasted onto '' would hide the emptiness from the refusal that
|
|
14969
|
+
// names it ('has no body — an empty comment').
|
|
14970
|
+
typeof comment.body === "string" && comment.body.trim() !== "" ? {
|
|
14971
|
+
...comment,
|
|
14972
|
+
body: `${comment.body.replace(REVIEW_FOOTER_RE, "")}
|
|
14973
|
+
|
|
14974
|
+
${footer}`
|
|
14975
|
+
} : comment
|
|
14976
|
+
)
|
|
14977
|
+
);
|
|
14978
|
+
}
|
|
14979
|
+
__name(normalizeInlineComments, "normalizeInlineComments");
|
|
14733
14980
|
function authorization(args) {
|
|
14734
14981
|
return reviewWriteAuthorization({
|
|
14735
14982
|
userAuthorized: args.userAuthorized,
|
|
@@ -14775,6 +15022,18 @@ __name(compose, "compose");
|
|
|
14775
15022
|
function structuralProblems(payload) {
|
|
14776
15023
|
const problems = [];
|
|
14777
15024
|
if (!payload.commit_id) problems.push("`commit_id` is missing");
|
|
15025
|
+
if (payload.comments !== void 0 && !Array.isArray(payload.comments)) {
|
|
15026
|
+
problems.push(
|
|
15027
|
+
"`comments` is not an array \u2014 it is the list of findings this post carries; any other shape is not a list of findings."
|
|
15028
|
+
);
|
|
15029
|
+
}
|
|
15030
|
+
if (Array.isArray(payload.comments) && payload.comments.some(
|
|
15031
|
+
(c) => c === null || typeof c !== "object"
|
|
15032
|
+
)) {
|
|
15033
|
+
problems.push(
|
|
15034
|
+
"`comments` entries must each be an object \u2014 a finding is a path, a line and a body; any other shape is not a finding."
|
|
15035
|
+
);
|
|
15036
|
+
}
|
|
14778
15037
|
if (payload.event !== void 0 || payload.body !== void 0) {
|
|
14779
15038
|
problems.push(
|
|
14780
15039
|
"the payload carries `event`/`body`. Those are computed here, from `state` and from the comments you attached \u2014 they are not inputs. Remove them. (A run that skipped `compose-review` and typed its own Approve is exactly what this refuses.)"
|
|
@@ -14855,7 +15114,7 @@ function runSubmit(args, cliVersion = "unknown") {
|
|
|
14855
15114
|
}
|
|
14856
15115
|
let payload;
|
|
14857
15116
|
try {
|
|
14858
|
-
payload = JSON.parse(
|
|
15117
|
+
payload = JSON.parse(readFileSync25(args.review, "utf8"));
|
|
14859
15118
|
} catch (err) {
|
|
14860
15119
|
throw new Error(
|
|
14861
15120
|
`Cannot read review JSON ${args.review}: ${err.message}`
|
|
@@ -14880,6 +15139,14 @@ Posting is a public, irreversible write, and this run has no authorisation for o
|
|
|
14880
15139
|
` + structural.map((p) => ` - ${p}`).join("\n")
|
|
14881
15140
|
);
|
|
14882
15141
|
}
|
|
15142
|
+
payload = {
|
|
15143
|
+
...payload,
|
|
15144
|
+
comments: normalizeInlineComments(
|
|
15145
|
+
payload.comments ?? [],
|
|
15146
|
+
payload.state?.modelId,
|
|
15147
|
+
cliVersion
|
|
15148
|
+
)
|
|
15149
|
+
};
|
|
14883
15150
|
let event2;
|
|
14884
15151
|
let body;
|
|
14885
15152
|
let cappedBy;
|
|
@@ -14931,7 +15198,7 @@ Posting is a public, irreversible write, and this run has no authorisation for o
|
|
|
14931
15198
|
const receiptPath = tmpFile(`pr-${args.pr}`, "submit-receipt.json");
|
|
14932
15199
|
const priorIds = readReceiptIds(receiptPath);
|
|
14933
15200
|
const reviewIds = [.../* @__PURE__ */ new Set([...priorIds, reviewId])];
|
|
14934
|
-
|
|
15201
|
+
mkdirSync23(REVIEW_TMP_DIR, { recursive: true });
|
|
14935
15202
|
atomicWriteFileSync(
|
|
14936
15203
|
receiptPath,
|
|
14937
15204
|
`${JSON.stringify({ reviewIds, event: event2, postedAt: (/* @__PURE__ */ new Date()).toISOString() })}
|
|
@@ -14988,7 +15255,8 @@ var submitCommand = {
|
|
|
14988
15255
|
describe: "Check authorisation and payload consistency, then stop."
|
|
14989
15256
|
}), "builder"),
|
|
14990
15257
|
handler: /* @__PURE__ */ __name(async (argv) => {
|
|
14991
|
-
|
|
15258
|
+
const cliVersion = footerVersion(process.env["QWEN_CODE_STARTUP_VERSION"]) ?? await getCliVersion();
|
|
15259
|
+
runSubmit(argv, cliVersion);
|
|
14992
15260
|
}, "handler")
|
|
14993
15261
|
};
|
|
14994
15262
|
|
|
@@ -14996,18 +15264,18 @@ var submitCommand = {
|
|
|
14996
15264
|
init_esbuild_shims();
|
|
14997
15265
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
14998
15266
|
import {
|
|
14999
|
-
mkdirSync as
|
|
15267
|
+
mkdirSync as mkdirSync24,
|
|
15000
15268
|
readdirSync as readdirSync5,
|
|
15001
|
-
writeFileSync as
|
|
15002
|
-
readFileSync as
|
|
15269
|
+
writeFileSync as writeFileSync24,
|
|
15270
|
+
readFileSync as readFileSync26,
|
|
15003
15271
|
rmSync as rmSync9,
|
|
15004
15272
|
lstatSync as lstatSync4,
|
|
15005
15273
|
existsSync as existsSync11,
|
|
15006
|
-
statSync as
|
|
15274
|
+
statSync as statSync9,
|
|
15007
15275
|
symlinkSync
|
|
15008
15276
|
} from "node:fs";
|
|
15009
15277
|
import { createRequire } from "node:module";
|
|
15010
|
-
import { dirname as dirname20, join as
|
|
15278
|
+
import { dirname as dirname20, join as join18, isAbsolute as isAbsolute3, sep as sep3 } from "node:path";
|
|
15011
15279
|
var FIXTURE_DIR_RE = /(^|\/)(__fixtures__|__mocks__|__snapshots__|fixtures)\//;
|
|
15012
15280
|
function planTestEfficacy(files, workspaceGlobs) {
|
|
15013
15281
|
const tests = files.filter((f) => f.kind === "test").map((f) => f.path);
|
|
@@ -15530,23 +15798,24 @@ function gitOut2(cwd, ...args) {
|
|
|
15530
15798
|
return (r.stdout ?? "").trim();
|
|
15531
15799
|
}
|
|
15532
15800
|
__name(gitOut2, "gitOut");
|
|
15533
|
-
function findVitestBin(worktree
|
|
15534
|
-
|
|
15801
|
+
function findVitestBin(worktree, resolveModule = createRequire(
|
|
15802
|
+
join18(worktree, "noop.js")
|
|
15803
|
+
).resolve) {
|
|
15535
15804
|
let pkgPath;
|
|
15536
15805
|
try {
|
|
15537
|
-
pkgPath =
|
|
15806
|
+
pkgPath = resolveModule("vitest/package.json");
|
|
15538
15807
|
} catch (error) {
|
|
15539
15808
|
if (error.code === "MODULE_NOT_FOUND") {
|
|
15540
15809
|
throw new Error(`vitest not found searching up from ${worktree}`);
|
|
15541
15810
|
}
|
|
15542
15811
|
throw error;
|
|
15543
15812
|
}
|
|
15544
|
-
const pkg = JSON.parse(
|
|
15813
|
+
const pkg = JSON.parse(readFileSync26(pkgPath, "utf8"));
|
|
15545
15814
|
const bin = pkg.bin?.vitest;
|
|
15546
15815
|
if (!bin) {
|
|
15547
15816
|
throw new Error(`vitest package at ${pkgPath} declares no "vitest" bin`);
|
|
15548
15817
|
}
|
|
15549
|
-
return
|
|
15818
|
+
return join18(dirname20(pkgPath), bin);
|
|
15550
15819
|
}
|
|
15551
15820
|
__name(findVitestBin, "findVitestBin");
|
|
15552
15821
|
function gitCapture(cwd, ...args) {
|
|
@@ -15572,7 +15841,7 @@ function safeRmWithin(worktree, relPath) {
|
|
|
15572
15841
|
const parts = relPath.split(/[/\\]+/).filter((s) => s && s !== ".");
|
|
15573
15842
|
let cur = worktree;
|
|
15574
15843
|
for (let i = 0; i < parts.length; i++) {
|
|
15575
|
-
cur =
|
|
15844
|
+
cur = join18(cur, parts[i]);
|
|
15576
15845
|
let st;
|
|
15577
15846
|
try {
|
|
15578
15847
|
st = lstatSync4(cur);
|
|
@@ -15597,15 +15866,15 @@ __name(probeCleanupFailureDetail, "probeCleanupFailureDetail");
|
|
|
15597
15866
|
function exposeDependencies(probeTree, dependencyRoot) {
|
|
15598
15867
|
const done = { linked: 0, failed: 0 };
|
|
15599
15868
|
if (probeTree === dependencyRoot) return done;
|
|
15600
|
-
const source =
|
|
15601
|
-
const target =
|
|
15869
|
+
const source = join18(dependencyRoot, "node_modules");
|
|
15870
|
+
const target = join18(probeTree, "node_modules");
|
|
15602
15871
|
if (!existsSync11(source) || existsSync11(target)) return done;
|
|
15603
|
-
|
|
15872
|
+
mkdirSync24(target);
|
|
15604
15873
|
const linkType = process.platform === "win32" ? "junction" : "dir";
|
|
15605
15874
|
for (const entry of readdirSync5(source, { withFileTypes: true })) {
|
|
15606
15875
|
if (entry.name === ".vite" || entry.name === ".vite-temp") continue;
|
|
15607
|
-
const sourceEntry =
|
|
15608
|
-
const targetEntry =
|
|
15876
|
+
const sourceEntry = join18(source, entry.name);
|
|
15877
|
+
const targetEntry = join18(target, entry.name);
|
|
15609
15878
|
let sourceStats;
|
|
15610
15879
|
try {
|
|
15611
15880
|
sourceStats = lstatSync4(sourceEntry);
|
|
@@ -15615,7 +15884,7 @@ function exposeDependencies(probeTree, dependencyRoot) {
|
|
|
15615
15884
|
}
|
|
15616
15885
|
if (sourceStats.isSymbolicLink()) {
|
|
15617
15886
|
try {
|
|
15618
|
-
if (!
|
|
15887
|
+
if (!statSync9(sourceEntry).isDirectory()) continue;
|
|
15619
15888
|
} catch {
|
|
15620
15889
|
continue;
|
|
15621
15890
|
}
|
|
@@ -15625,7 +15894,7 @@ function exposeDependencies(probeTree, dependencyRoot) {
|
|
|
15625
15894
|
if (entry.name.startsWith("@")) {
|
|
15626
15895
|
let pkgs;
|
|
15627
15896
|
try {
|
|
15628
|
-
|
|
15897
|
+
mkdirSync24(targetEntry);
|
|
15629
15898
|
pkgs = readdirSync5(sourceEntry);
|
|
15630
15899
|
} catch {
|
|
15631
15900
|
done.failed++;
|
|
@@ -15633,7 +15902,7 @@ function exposeDependencies(probeTree, dependencyRoot) {
|
|
|
15633
15902
|
}
|
|
15634
15903
|
for (const pkg of pkgs) {
|
|
15635
15904
|
try {
|
|
15636
|
-
symlinkSync(
|
|
15905
|
+
symlinkSync(join18(sourceEntry, pkg), join18(targetEntry, pkg), linkType);
|
|
15637
15906
|
done.linked++;
|
|
15638
15907
|
} catch {
|
|
15639
15908
|
done.failed++;
|
|
@@ -15779,10 +16048,10 @@ function newSideLength(header) {
|
|
|
15779
16048
|
__name(newSideLength, "newSideLength");
|
|
15780
16049
|
function runOneHunkProbe(probeTree, hunk, probes, deadlineAt, now = Date.now) {
|
|
15781
16050
|
const { patch: _patch, ...meta } = hunk;
|
|
15782
|
-
const abs =
|
|
16051
|
+
const abs = join18(probeTree, hunk.file);
|
|
15783
16052
|
let original;
|
|
15784
16053
|
try {
|
|
15785
|
-
original =
|
|
16054
|
+
original = readFileSync26(abs, "utf8");
|
|
15786
16055
|
} catch (e) {
|
|
15787
16056
|
return {
|
|
15788
16057
|
...meta,
|
|
@@ -15808,21 +16077,21 @@ function runOneHunkProbe(probeTree, hunk, probes, deadlineAt, now = Date.now) {
|
|
|
15808
16077
|
const detail = verdict === "killed" ? "the suite went red with this hunk reverted \u2014 a test covers this change" : verdict === "survived" ? "every affected test still PASSED with this hunk reverted \u2014 no test in this diff fails when the change is undone" : "the tree with this hunk reverted produced no clean verdict (likely a compile or import error) \u2014 not evidence either way";
|
|
15809
16078
|
return { ...meta, verdict, detail };
|
|
15810
16079
|
} finally {
|
|
15811
|
-
|
|
15812
|
-
|
|
16080
|
+
mkdirSync24(dirname20(abs), { recursive: true });
|
|
16081
|
+
writeFileSync24(abs, original, "utf8");
|
|
15813
16082
|
}
|
|
15814
16083
|
}
|
|
15815
16084
|
__name(runOneHunkProbe, "runOneHunkProbe");
|
|
15816
16085
|
function runControlMutant(probeTree, probeFile, deadlineAt, now = Date.now) {
|
|
15817
|
-
const abs =
|
|
16086
|
+
const abs = join18(probeTree, probeFile);
|
|
15818
16087
|
let original;
|
|
15819
16088
|
try {
|
|
15820
|
-
original =
|
|
16089
|
+
original = readFileSync26(abs, "utf8");
|
|
15821
16090
|
} catch {
|
|
15822
16091
|
return null;
|
|
15823
16092
|
}
|
|
15824
16093
|
try {
|
|
15825
|
-
|
|
16094
|
+
writeFileSync24(
|
|
15826
16095
|
abs,
|
|
15827
16096
|
`${original}
|
|
15828
16097
|
;import { it as __qcIt, expect as __qcExpect } from 'vitest';
|
|
@@ -15835,13 +16104,13 @@ __qcIt('QWEN-REVIEW-POSITIVE-CONTROL', () => {
|
|
|
15835
16104
|
const { perFile } = runProbeSuite(probeTree, [probeFile], deadlineAt, now);
|
|
15836
16105
|
return perFile.some((r) => r.verdict === "gated");
|
|
15837
16106
|
} finally {
|
|
15838
|
-
|
|
16107
|
+
writeFileSync24(abs, original, "utf8");
|
|
15839
16108
|
}
|
|
15840
16109
|
}
|
|
15841
16110
|
__name(runControlMutant, "runControlMutant");
|
|
15842
16111
|
function runOneMutant(probeTree, mutant, probes, deadlineAt, now = Date.now, dependencyRoot = probeTree) {
|
|
15843
|
-
const abs =
|
|
15844
|
-
const original =
|
|
16112
|
+
const abs = join18(probeTree, mutant.file);
|
|
16113
|
+
const original = readFileSync26(abs, "utf8");
|
|
15845
16114
|
const lines2 = original.split("\n");
|
|
15846
16115
|
if ((lines2[mutant.line - 1] ?? "").trim() !== mutant.statement) {
|
|
15847
16116
|
return {
|
|
@@ -15857,7 +16126,7 @@ function runOneMutant(probeTree, mutant, probes, deadlineAt, now = Date.now, dep
|
|
|
15857
16126
|
lines2.splice(mutant.line - 1, 1);
|
|
15858
16127
|
}
|
|
15859
16128
|
try {
|
|
15860
|
-
|
|
16129
|
+
writeFileSync24(abs, lines2.join("\n"), "utf8");
|
|
15861
16130
|
const { perFile } = runProbeSuite(
|
|
15862
16131
|
probeTree,
|
|
15863
16132
|
probes,
|
|
@@ -15869,7 +16138,7 @@ function runOneMutant(probeTree, mutant, probes, deadlineAt, now = Date.now, dep
|
|
|
15869
16138
|
const detail = verdict === "killed" ? `the suite went red with this statement ${what} \u2014 a test catches it` : verdict === "survived" ? `every affected test still PASSED with this statement ${what} \u2014 no test fails ${mutant.mutated === void 0 ? "when it is removed" : "when it changes"}` : "the mutated tree produced no clean verdict (likely a compile or import error) \u2014 not evidence either way";
|
|
15870
16139
|
return { ...mutant, verdict, detail };
|
|
15871
16140
|
} finally {
|
|
15872
|
-
|
|
16141
|
+
writeFileSync24(abs, original, "utf8");
|
|
15873
16142
|
}
|
|
15874
16143
|
}
|
|
15875
16144
|
__name(runOneMutant, "runOneMutant");
|
|
@@ -15908,9 +16177,9 @@ async function runTestEfficacy(args) {
|
|
|
15908
16177
|
const now = args.now ?? Date.now;
|
|
15909
16178
|
const startedAt = now();
|
|
15910
16179
|
const { report, worktree, base, out } = args;
|
|
15911
|
-
const plan = JSON.parse(
|
|
16180
|
+
const plan = JSON.parse(readFileSync26(report, "utf8"));
|
|
15912
16181
|
const rootPkg = JSON.parse(
|
|
15913
|
-
|
|
16182
|
+
readFileSync26(`${worktree}/package.json`, "utf8")
|
|
15914
16183
|
);
|
|
15915
16184
|
const globs = rootPkg.workspaces ?? [];
|
|
15916
16185
|
const { unreachable, probes, revert } = planTestEfficacy(
|
|
@@ -15918,8 +16187,8 @@ async function runTestEfficacy(args) {
|
|
|
15918
16187
|
globs
|
|
15919
16188
|
);
|
|
15920
16189
|
for (const p of revert) {
|
|
15921
|
-
const norm =
|
|
15922
|
-
const root =
|
|
16190
|
+
const norm = join18(worktree, p);
|
|
16191
|
+
const root = join18(worktree, ".");
|
|
15923
16192
|
if (isAbsolute3(p) || norm !== root && !norm.startsWith(root + sep3)) {
|
|
15924
16193
|
throw new Error(
|
|
15925
16194
|
`refusing to run: revert path escapes the worktree: ${JSON.stringify(p)}`
|
|
@@ -16290,8 +16559,8 @@ async function runTestEfficacy(args) {
|
|
|
16290
16559
|
findings,
|
|
16291
16560
|
cleanupFailure
|
|
16292
16561
|
};
|
|
16293
|
-
|
|
16294
|
-
|
|
16562
|
+
mkdirSync24(dirname20(out), { recursive: true });
|
|
16563
|
+
writeFileSync24(out, JSON.stringify(result, null, 2), "utf8");
|
|
16295
16564
|
writeStdoutLine(
|
|
16296
16565
|
`Wrote test-efficacy report to ${out} (${unreachable.length} unreachable, ${results.length} probed, ${mutantResults.length} mutant(s), ${hunkResults.length} hunk probe(s), ${findings.length} finding(s))`
|
|
16297
16566
|
);
|
|
@@ -16368,8 +16637,8 @@ var testEfficacyCommand = {
|
|
|
16368
16637
|
|
|
16369
16638
|
// packages/cli/src/commands/review/test-plan.ts
|
|
16370
16639
|
init_esbuild_shims();
|
|
16371
|
-
import { existsSync as existsSync12, mkdirSync as
|
|
16372
|
-
import { dirname as dirname21, join as
|
|
16640
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync25, readFileSync as readFileSync27, writeFileSync as writeFileSync25 } from "node:fs";
|
|
16641
|
+
import { dirname as dirname21, join as join19, normalize, resolve as resolve20 } from "node:path";
|
|
16373
16642
|
var PLAN_NAME_RE = /(test\s*plan|\btesting\b|how\s+(?:has\s+this|to)\s+(?:been\s+)?test(?:ed)?|测试计划|测试方案|测试步骤)/i;
|
|
16374
16643
|
var HEADING_LINE_RE = /^(#{1,6})(?:[ \t](.*))?$/;
|
|
16375
16644
|
var BOLD_LINE_RE = /^\*\*([^*\n]+)\*\*:?\s*$/;
|
|
@@ -16572,7 +16841,7 @@ function rulePath(text, worktree, changed) {
|
|
|
16572
16841
|
};
|
|
16573
16842
|
}
|
|
16574
16843
|
const ignored = isGitIgnored(worktree, path3);
|
|
16575
|
-
if (existsSync12(
|
|
16844
|
+
if (existsSync12(join19(worktree, path3))) {
|
|
16576
16845
|
return {
|
|
16577
16846
|
kind: "path",
|
|
16578
16847
|
text,
|
|
@@ -16643,7 +16912,7 @@ function ruleCommand(text, worktree, buildTest) {
|
|
|
16643
16912
|
let rootScripts = [];
|
|
16644
16913
|
try {
|
|
16645
16914
|
const rootPkg = JSON.parse(
|
|
16646
|
-
|
|
16915
|
+
readFileSync27(join19(worktree, "package.json"), "utf8")
|
|
16647
16916
|
);
|
|
16648
16917
|
rootScripts = Object.keys(rootPkg.scripts ?? {});
|
|
16649
16918
|
} catch {
|
|
@@ -16721,7 +16990,7 @@ __name(fetchPrBody, "fetchPrBody");
|
|
|
16721
16990
|
function runTestPlan(args, fetchBody = fetchPrBody) {
|
|
16722
16991
|
let plan;
|
|
16723
16992
|
try {
|
|
16724
|
-
plan = JSON.parse(
|
|
16993
|
+
plan = JSON.parse(readFileSync27(args.plan, "utf8"));
|
|
16725
16994
|
} catch (err) {
|
|
16726
16995
|
throw new Error(
|
|
16727
16996
|
`test-plan: cannot read the plan ${args.plan}: ${err.message}`
|
|
@@ -16756,7 +17025,7 @@ function runTestPlan(args, fetchBody = fetchPrBody) {
|
|
|
16756
17025
|
if (args.buildTest) {
|
|
16757
17026
|
try {
|
|
16758
17027
|
buildTest = JSON.parse(
|
|
16759
|
-
|
|
17028
|
+
readFileSync27(args.buildTest, "utf8")
|
|
16760
17029
|
);
|
|
16761
17030
|
} catch {
|
|
16762
17031
|
buildTest = null;
|
|
@@ -16813,8 +17082,8 @@ var testPlanCommand = {
|
|
|
16813
17082
|
try {
|
|
16814
17083
|
const report = runTestPlan(args);
|
|
16815
17084
|
if (args.out) {
|
|
16816
|
-
|
|
16817
|
-
|
|
17085
|
+
mkdirSync25(dirname21(resolve20(args.out)), { recursive: true });
|
|
17086
|
+
writeFileSync25(resolve20(args.out), JSON.stringify(report, null, 2));
|
|
16818
17087
|
}
|
|
16819
17088
|
writeStdoutLine(JSON.stringify(report, null, 2));
|
|
16820
17089
|
writeStderrLine(`test-plan: ${report.note}`);
|
|
@@ -16828,8 +17097,8 @@ var testPlanCommand = {
|
|
|
16828
17097
|
// packages/cli/src/commands/review/cleanup.ts
|
|
16829
17098
|
init_esbuild_shims();
|
|
16830
17099
|
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
16831
|
-
import { existsSync as existsSync13, readFileSync as
|
|
16832
|
-
import { join as
|
|
17100
|
+
import { existsSync as existsSync13, readFileSync as readFileSync28, readdirSync as readdirSync6, rmSync as rmSync10 } from "node:fs";
|
|
17101
|
+
import { join as join20 } from "node:path";
|
|
16833
17102
|
var AUTOMATION_MARKER = "<!-- qwen-";
|
|
16834
17103
|
function isAutomationComment(body) {
|
|
16835
17104
|
return (body ?? "").trimStart().startsWith(AUTOMATION_MARKER);
|
|
@@ -16860,7 +17129,7 @@ var OWNER_REPO_RE = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
|
|
|
16860
17129
|
function readAuditWindow(target, expectedPrNumber) {
|
|
16861
17130
|
let raw;
|
|
16862
17131
|
try {
|
|
16863
|
-
raw =
|
|
17132
|
+
raw = readFileSync28(tmpFile(target, "fetch.json"), "utf8");
|
|
16864
17133
|
} catch (err) {
|
|
16865
17134
|
const code = err.code;
|
|
16866
17135
|
return code === "ENOENT" ? { skip: "no fetch report" } : {
|
|
@@ -16907,7 +17176,7 @@ function readSubmitReceipt(target) {
|
|
|
16907
17176
|
try {
|
|
16908
17177
|
return new Set(
|
|
16909
17178
|
parseReceiptIds(
|
|
16910
|
-
|
|
17179
|
+
readFileSync28(tmpFile(target, "submit-receipt.json"), "utf8")
|
|
16911
17180
|
)
|
|
16912
17181
|
);
|
|
16913
17182
|
} catch {
|
|
@@ -17042,7 +17311,7 @@ function runCleanup(target) {
|
|
|
17042
17311
|
}
|
|
17043
17312
|
for (const file of tmpEntries) {
|
|
17044
17313
|
if (!file.startsWith(prefix)) continue;
|
|
17045
|
-
const full =
|
|
17314
|
+
const full = join20(REVIEW_TMP_DIR, file);
|
|
17046
17315
|
try {
|
|
17047
17316
|
rmSync10(full, { recursive: true, force: true });
|
|
17048
17317
|
writeStdoutLine(`Removed temp file: ${full}`);
|
|
@@ -17076,8 +17345,8 @@ var cleanupCommand = {
|
|
|
17076
17345
|
// packages/cli/src/commands/review/run.ts
|
|
17077
17346
|
init_esbuild_shims();
|
|
17078
17347
|
import { spawn, execFileSync as execFileSync6 } from "node:child_process";
|
|
17079
|
-
import { readdirSync as readdirSync7, readFileSync as
|
|
17080
|
-
import { dirname as dirname22, join as
|
|
17348
|
+
import { readdirSync as readdirSync7, readFileSync as readFileSync29, realpathSync as realpathSync3, statSync as statSync10 } from "node:fs";
|
|
17349
|
+
import { dirname as dirname22, join as join21, resolve as resolve21 } from "node:path";
|
|
17081
17350
|
var COMPOSED_PATTERN = /^qwen-review-.*composed\.json$/;
|
|
17082
17351
|
var COMPOSED_POLL_MS = 250;
|
|
17083
17352
|
var SIGNAL_EXIT_CODES = {
|
|
@@ -17111,10 +17380,10 @@ function newestArtifactSince(dir, pattern, startMs) {
|
|
|
17111
17380
|
}
|
|
17112
17381
|
for (const name of names) {
|
|
17113
17382
|
if (!pattern.test(name)) continue;
|
|
17114
|
-
const path3 =
|
|
17383
|
+
const path3 = join21(dir, name);
|
|
17115
17384
|
let mtime;
|
|
17116
17385
|
try {
|
|
17117
|
-
mtime =
|
|
17386
|
+
mtime = statSync10(path3).mtimeMs;
|
|
17118
17387
|
} catch {
|
|
17119
17388
|
continue;
|
|
17120
17389
|
}
|
|
@@ -17132,7 +17401,7 @@ function exitCodeFor(completed, event2, failOn) {
|
|
|
17132
17401
|
__name(exitCodeFor, "exitCodeFor");
|
|
17133
17402
|
function readComposed(path3) {
|
|
17134
17403
|
try {
|
|
17135
|
-
const parsed = JSON.parse(
|
|
17404
|
+
const parsed = JSON.parse(readFileSync29(path3, "utf8"));
|
|
17136
17405
|
return typeof parsed.event === "string" ? parsed : null;
|
|
17137
17406
|
} catch {
|
|
17138
17407
|
return null;
|
|
@@ -17368,14 +17637,14 @@ init_esbuild_shims();
|
|
|
17368
17637
|
import {
|
|
17369
17638
|
existsSync as existsSync14,
|
|
17370
17639
|
lstatSync as lstatSync5,
|
|
17371
|
-
mkdirSync as
|
|
17372
|
-
readFileSync as
|
|
17373
|
-
statSync as
|
|
17640
|
+
mkdirSync as mkdirSync26,
|
|
17641
|
+
readFileSync as readFileSync30,
|
|
17642
|
+
statSync as statSync11
|
|
17374
17643
|
} from "node:fs";
|
|
17375
17644
|
import {
|
|
17376
17645
|
dirname as dirname23,
|
|
17377
17646
|
isAbsolute as isAbsolute4,
|
|
17378
|
-
join as
|
|
17647
|
+
join as join22,
|
|
17379
17648
|
relative as relative3,
|
|
17380
17649
|
resolve as resolve22,
|
|
17381
17650
|
sep as sep4,
|
|
@@ -17405,7 +17674,7 @@ function rejectSymlinkPath(root, path3, label2) {
|
|
|
17405
17674
|
const rel = relative3(root, path3);
|
|
17406
17675
|
let current = root;
|
|
17407
17676
|
for (const segment of rel.split(sep4)) {
|
|
17408
|
-
current =
|
|
17677
|
+
current = join22(current, segment);
|
|
17409
17678
|
if (existsSync14(current) && lstatSync5(current).isSymbolicLink()) {
|
|
17410
17679
|
throw new Error(`${label2} must not traverse a symbolic link.`);
|
|
17411
17680
|
}
|
|
@@ -17415,14 +17684,14 @@ __name(rejectSymlinkPath, "rejectSymlinkPath");
|
|
|
17415
17684
|
function sameFile(left, right) {
|
|
17416
17685
|
if (left === right) return true;
|
|
17417
17686
|
if (!existsSync14(left) || !existsSync14(right)) return false;
|
|
17418
|
-
const leftStat =
|
|
17419
|
-
const rightStat =
|
|
17687
|
+
const leftStat = statSync11(left);
|
|
17688
|
+
const rightStat = statSync11(right);
|
|
17420
17689
|
return leftStat.dev === rightStat.dev && leftStat.ino === rightStat.ino;
|
|
17421
17690
|
}
|
|
17422
17691
|
__name(sameFile, "sameFile");
|
|
17423
17692
|
function readText(path3, label2) {
|
|
17424
17693
|
try {
|
|
17425
|
-
return
|
|
17694
|
+
return readFileSync30(path3, "utf8");
|
|
17426
17695
|
} catch (error) {
|
|
17427
17696
|
throw new Error(
|
|
17428
17697
|
`Could not read the ${label2} file at ${JSON.stringify(path3)}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -17589,7 +17858,7 @@ function saveReviewArtifact(args) {
|
|
|
17589
17858
|
const verdict = validateVerdict(readJson2(composedPath, "composed verdict"));
|
|
17590
17859
|
let reportIsFile;
|
|
17591
17860
|
try {
|
|
17592
|
-
reportIsFile =
|
|
17861
|
+
reportIsFile = statSync11(reportPath).isFile();
|
|
17593
17862
|
} catch {
|
|
17594
17863
|
}
|
|
17595
17864
|
if (reportIsFile === false) {
|
|
@@ -17609,7 +17878,7 @@ function saveReviewArtifact(args) {
|
|
|
17609
17878
|
outcomesRecorded: findings.outcomesRecorded,
|
|
17610
17879
|
markdownReportPath
|
|
17611
17880
|
};
|
|
17612
|
-
|
|
17881
|
+
mkdirSync26(dirname23(outputPath), { recursive: true });
|
|
17613
17882
|
atomicWriteFileSync(
|
|
17614
17883
|
toNamespacedPath(outputPath),
|
|
17615
17884
|
`${JSON.stringify(document, null, 2)}
|
|
@@ -17864,10 +18133,10 @@ var updateCommand3 = {
|
|
|
17864
18133
|
stdioHelpers,
|
|
17865
18134
|
{ updateEventEmitter }
|
|
17866
18135
|
] = await Promise.all([
|
|
17867
|
-
import("./settings-
|
|
17868
|
-
import("./updateCheck-
|
|
17869
|
-
import("./installationInfo-
|
|
17870
|
-
import("./standalone-update-
|
|
18136
|
+
import("./settings-NX4EUIE6.js"),
|
|
18137
|
+
import("./updateCheck-FDAVGOFT.js"),
|
|
18138
|
+
import("./installationInfo-AEGIIQAT.js"),
|
|
18139
|
+
import("./standalone-update-ICW7H5IF.js"),
|
|
17871
18140
|
import("./stdioHelpers-HGIYTWAY.js"),
|
|
17872
18141
|
import("./updateEventEmitter-5MKC7BLQ.js")
|
|
17873
18142
|
]);
|
|
@@ -18713,7 +18982,7 @@ var SessionIdConflictError = class extends Error {
|
|
|
18713
18982
|
this.sessionId = sessionId;
|
|
18714
18983
|
}
|
|
18715
18984
|
};
|
|
18716
|
-
async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtensions, hooksConfig, disabledSkillNamesProvider, sessionMcpServers, settingsWatcher, throwOnSessionIdConflict = false) {
|
|
18985
|
+
async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtensions, hooksConfig, disabledSkillNamesProvider, sessionMcpServers, settingsWatcher, throwOnSessionIdConflict = false, hostPolicy) {
|
|
18717
18986
|
const debugMode = isDebugMode(argv);
|
|
18718
18987
|
if (debugMode && process.env["QWEN_DEBUG_LOG_FILE"] === void 0) {
|
|
18719
18988
|
process.env["QWEN_DEBUG_LOG_FILE"] = "1";
|
|
@@ -19034,7 +19303,7 @@ async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtens
|
|
|
19034
19303
|
disabledSlashCommands: disabledSlashCommands.length > 0 ? disabledSlashCommands : void 0,
|
|
19035
19304
|
disabledSkillNamesProvider: bareMode || safeMode ? void 0 : disabledSkillNamesProvider,
|
|
19036
19305
|
terminalImageRenderSupportProvider: interactive ? async () => {
|
|
19037
|
-
const { getTerminalImageRenderSupport } = await import("./terminal-image-renderer-
|
|
19306
|
+
const { getTerminalImageRenderSupport } = await import("./terminal-image-renderer-PW6Z6VFY.js");
|
|
19038
19307
|
return getTerminalImageRenderSupport();
|
|
19039
19308
|
} : void 0,
|
|
19040
19309
|
disabledSkillLevels: bareMode || safeMode || !Array.isArray(settings.skills?.disabledLevels) ? void 0 : settings.skills.disabledLevels.filter(isSkillLevel),
|
|
@@ -19051,6 +19320,7 @@ async function loadCliConfig(settings, argv, cwd = process.cwd(), overrideExtens
|
|
|
19051
19320
|
deny: mergedDeny.length > 0 ? mergedDeny : void 0,
|
|
19052
19321
|
autoMode: bareMode || safeMode ? void 0 : settings.permissions?.autoMode
|
|
19053
19322
|
},
|
|
19323
|
+
toolInvocationGuard: hostPolicy?.toolInvocationGuard,
|
|
19054
19324
|
// Permission rule persistence callback (writes to settings files).
|
|
19055
19325
|
onPersistPermissionRule: /* @__PURE__ */ __name(async (scope, ruleType, rule) => {
|
|
19056
19326
|
const currentSettings = loadSettings(cwd);
|