@qwen-code/qwen-code 0.21.10 → 0.21.11-nightly.20260814.45c2e73080
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/coordinate/SKILL.md +52 -0
- package/bundled/qc-helper/docs/configuration/model-providers.md +10 -8
- package/bundled/qc-helper/docs/configuration/settings.md +10 -0
- package/bundled/qc-helper/docs/extension/_meta.ts +1 -0
- package/bundled/qc-helper/docs/extension/agent-plugins.md +50 -0
- package/bundled/qc-helper/docs/extension/extension-releasing.md +3 -3
- package/bundled/qc-helper/docs/extension/introduction.md +17 -3
- package/bundled/qc-helper/docs/features/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/arena.md +4 -3
- package/bundled/qc-helper/docs/features/code-review.md +1 -1
- package/bundled/qc-helper/docs/features/commands.md +7 -6
- package/bundled/qc-helper/docs/features/dual-output.md +5 -0
- package/bundled/qc-helper/docs/features/headless.md +8 -0
- package/bundled/qc-helper/docs/features/multi-agent-coordination.md +30 -0
- package/bundled/qc-helper/docs/qwen-serve.md +40 -40
- package/bundled/review/SKILL.md +45 -23
- package/chunks/{MaxSizedBox-FKXYULMW.js → MaxSizedBox-P4Z76535.js} +45 -44
- package/chunks/{StandaloneSessionPicker-OQS3M7AY.js → StandaloneSessionPicker-TRWDBCJG.js} +65 -64
- package/chunks/{acp-startup-profiler-VNTFWYAC.js → acp-startup-profiler-TVI2OVUN.js} +2 -2
- package/chunks/{acpAgent-AGS6HLQQ.js → acpAgent-MSZHQSZ7.js} +1645 -579
- package/chunks/{agent-4NCVO27U.js → agent-TMTEYQGK.js} +42 -41
- package/chunks/agent-headless-54WWND2M.js +87 -0
- package/chunks/{anthropicContentGenerator-D3Y4RFT4.js → anthropicContentGenerator-7ZK7U65G.js} +8 -8
- package/chunks/{artifact-tool-N652YE4L.js → artifact-tool-7HVSSXYZ.js} +2 -2
- package/chunks/{askUserQuestion-ONW74PKJ.js → askUserQuestion-IQCA2SOX.js} +2 -2
- package/chunks/{bridge-FHINXZMN.js → bridge-CI2NKV64.js} +49 -48
- package/chunks/{ca-ZLKAB4K3.js → ca-4CQ6MYNQ.js} +2 -1
- package/chunks/{channel-management-service-PHELKOW2.js → channel-management-service-LNEYNMDX.js} +6 -6
- package/chunks/channel-settings-store-QU4WFXHO.js +102 -0
- package/chunks/{channel-worker-group-WQP4RCDO.js → channel-worker-group-Q5WQVOMZ.js} +8 -7
- package/chunks/{channel-worker-manager-MRDFAKIM.js → channel-worker-manager-Z3JLH72P.js} +8 -7
- package/chunks/{channel-worker-supervisor-IVSDIMI4.js → channel-worker-supervisor-CG5HHT7K.js} +6 -5
- package/chunks/{chunk-A7XMDZRI.js → chunk-2AG524A4.js} +5 -5
- package/chunks/{chunk-GM463R2B.js → chunk-2ASWIM4A.js} +1 -1
- package/chunks/{chunk-DP3IHZGG.js → chunk-2AUM35J5.js} +59 -7
- package/chunks/{chunk-TZEZYNYD.js → chunk-2N6CV4PW.js} +1 -1
- package/chunks/{chunk-BSI645OU.js → chunk-3LHSUFPE.js} +3 -3
- package/chunks/{chunk-DCZEPFB4.js → chunk-3XLWKV4S.js} +3 -3
- package/chunks/{chunk-YWPSGJFI.js → chunk-4IBNVBGJ.js} +2 -2
- package/chunks/{chunk-ZRBMO3C7.js → chunk-4IWFPTAH.js} +1 -1
- package/chunks/{chunk-B2GJNDTV.js → chunk-4JS2QK7P.js} +1 -1
- package/chunks/{chunk-5MZCSWI4.js → chunk-4NV6L4GZ.js} +1184 -1450
- package/chunks/{chunk-Y3OVRWRY.js → chunk-4QC6SUVN.js} +1 -1
- package/chunks/{chunk-AOHJKPKL.js → chunk-5KZNWF2M.js} +1 -1
- package/chunks/{chunk-UMD7WQTR.js → chunk-5XNR53C7.js} +10 -8
- package/chunks/{chunk-IIJEYBNH.js → chunk-66PLFJQ7.js} +197 -60
- package/chunks/{chunk-SEZ556DZ.js → chunk-67F2BEYW.js} +1 -1
- package/chunks/{chunk-7GTMV7UE.js → chunk-6KXHEN6M.js} +8700 -2449
- package/chunks/{chunk-FVKHVJZQ.js → chunk-6OJDN5ZT.js} +1 -1
- package/chunks/{chunk-CKASRHZI.js → chunk-6SU6OW5Z.js} +1 -1
- package/chunks/{chunk-NEOXOWYH.js → chunk-6YUEAYJ5.js} +7 -7
- package/chunks/{chunk-QGNOFE5E.js → chunk-766PXUQ3.js} +1 -1
- package/chunks/{chunk-UVX4Y6IN.js → chunk-7JL5YBSA.js} +1 -1
- package/chunks/{chunk-2PLNY5TN.js → chunk-7MAHENBD.js} +4 -4
- package/chunks/{chunk-L2AFWWJE.js → chunk-7UNST76G.js} +105 -24
- package/chunks/{chunk-HUWENAHO.js → chunk-7WUMS2UA.js} +1 -1
- package/chunks/{chunk-MVUQRLOH.js → chunk-A4BAHMJF.js} +3 -3
- package/chunks/{chunk-7MH4J33A.js → chunk-A6GQUQ7I.js} +2 -2
- package/chunks/{chunk-GNPNYXJB.js → chunk-AAZWJAPQ.js} +2 -2
- package/chunks/{chunk-DX3RGJMS.js → chunk-ADJDLEVO.js} +72 -13
- package/chunks/{chunk-IWTMYQ32.js → chunk-AN3LCBS7.js} +9 -8
- package/chunks/{chunk-LHEC5V6G.js → chunk-AXEL55JW.js} +2 -2
- package/chunks/{chunk-QUI267ZP.js → chunk-B66LYK4B.js} +492 -63
- package/chunks/{chunk-VNNWAZSI.js → chunk-BCGJZGFI.js} +3 -3
- package/chunks/{chunk-F6WDTQ3M.js → chunk-BRYHERQ6.js} +5 -5
- package/chunks/{chunk-6ZRFAKXK.js → chunk-C2DR57L6.js} +1 -1
- package/chunks/{chunk-26CXSA6V.js → chunk-CAOT4DYN.js} +2 -2
- package/chunks/{chunk-H6XPXXMH.js → chunk-CQ35AJ4Z.js} +252 -254
- package/chunks/{chunk-F24A2JBM.js → chunk-CUXI3S6E.js} +914 -175
- package/chunks/{chunk-AEL7KN2O.js → chunk-DANYMI4U.js} +2 -2
- package/chunks/{chunk-AAE6SR4Q.js → chunk-DX7V233D.js} +1 -1
- package/chunks/{chunk-PJRW65JO.js → chunk-E74YSVIN.js} +1 -1
- package/chunks/{chunk-OWMAZHIX.js → chunk-EGB2PIYM.js} +1 -1
- package/chunks/{chunk-TRRF5BSP.js → chunk-F4BUGC4Y.js} +1 -1
- package/chunks/{chunk-4MKXUHXY.js → chunk-FGQY4VOZ.js} +5 -5
- package/chunks/{chunk-ZBVS26BY.js → chunk-FPGTNKCP.js} +7 -5
- package/chunks/{chunk-SR7RZ4MS.js → chunk-FTGU6G45.js} +2 -2
- package/chunks/{chunk-IBUGFUXC.js → chunk-G2ZEKO4T.js} +12 -12
- package/chunks/{chunk-NDU63YLI.js → chunk-GN2SCYBA.js} +4 -4
- package/chunks/{chunk-NV3F44FL.js → chunk-GNRFC5UM.js} +2 -2
- package/chunks/{chunk-KKBPOU75.js → chunk-H6BFLALJ.js} +1 -1
- package/chunks/chunk-HHJLM3WQ.js +41 -0
- package/chunks/{chunk-LLCWZQCU.js → chunk-HM7TLULV.js} +3 -3
- package/chunks/{chunk-ECWR5LQR.js → chunk-I76FLAP7.js} +3 -3
- package/chunks/{chunk-Q3AL4JQ3.js → chunk-IAE7LYSB.js} +2 -2
- package/chunks/{chunk-DREZZAZM.js → chunk-IDNVCWXZ.js} +13 -5
- package/chunks/{chunk-YF5MALI4.js → chunk-IPMHLZPY.js} +20 -16
- package/chunks/{chunk-UDXSXLER.js → chunk-IW6RQPQB.js} +14 -4
- package/chunks/{chunk-UBX6NL47.js → chunk-JLT5HCGQ.js} +47 -3
- package/chunks/{chunk-COBO5EBO.js → chunk-JRTJEGSP.js} +1 -1
- package/chunks/{chunk-PBRVUF5B.js → chunk-JW5UEE3V.js} +1 -1
- package/chunks/{chunk-W4RQUHY3.js → chunk-K5IDV3PC.js} +184 -22
- package/chunks/{chunk-O3EU6GMH.js → chunk-KACBT7N7.js} +27 -4
- package/chunks/{chunk-MFDYOYZZ.js → chunk-KCGEAL2C.js} +25 -2
- package/chunks/{chunk-EI3HZX6C.js → chunk-KK3FEHPJ.js} +1 -1
- package/chunks/{chunk-OJUQF2PL.js → chunk-KRRRRU3X.js} +5 -5
- package/chunks/{chunk-J6SZID63.js → chunk-KTWUFHS4.js} +2 -2
- package/chunks/{chunk-E2FPSSKP.js → chunk-KZKEVWJW.js} +57 -13
- package/chunks/{chunk-ZJ4W6SUY.js → chunk-L6PE52MF.js} +3 -3
- package/chunks/{chunk-YGT2AUJ7.js → chunk-LAKFZU36.js} +39 -19
- package/chunks/{chunk-47PEPJO7.js → chunk-LKN5SEHD.js} +3 -3
- package/chunks/{chunk-OQTXYMKW.js → chunk-LSMCI42W.js} +3 -3
- package/chunks/{chunk-ABVRJU3D.js → chunk-LY2SB7GC.js} +7 -7
- package/chunks/{chunk-D27I6YJT.js → chunk-M53FFYQJ.js} +27 -18
- package/chunks/{chunk-YTFDX4PR.js → chunk-M6NDLY2T.js} +1 -1
- package/chunks/{chunk-3P2LV43B.js → chunk-MMEDZKWK.js} +3 -3
- package/chunks/{chunk-VFMASYQA.js → chunk-MS7GNABG.js} +3 -0
- package/chunks/{chunk-6LP743KE.js → chunk-MUTFMB5B.js} +78 -112
- package/chunks/{chunk-URK542T4.js → chunk-NF5J2WFA.js} +15 -2
- package/chunks/{chunk-VSFKIRRW.js → chunk-NH6U7L42.js} +4 -4
- package/chunks/{chunk-DA4HRSBW.js → chunk-NHZF4VCD.js} +1 -1
- package/chunks/{chunk-QG3FFJYU.js → chunk-NJE5NH5B.js} +1 -1
- package/chunks/{chunk-2UUMVNYT.js → chunk-NM33GGOM.js} +3 -3
- package/chunks/{chunk-FOGU3LJX.js → chunk-NW7SPXVG.js} +1 -1
- package/chunks/{chunk-EUNWC2VS.js → chunk-O6SLWH4X.js} +2 -2
- package/chunks/{chunk-EBZ6BJTF.js → chunk-OEVVUUYW.js} +1 -1
- package/chunks/chunk-OMVHZ7E6.js +1280 -0
- package/chunks/{chunk-KZ22NXBY.js → chunk-OT72MGHE.js} +4 -4
- package/chunks/{chunk-DZUO626D.js → chunk-OUCCIS3E.js} +3 -3
- package/chunks/{chunk-OONWZLFK.js → chunk-OYLYERMH.js} +4 -4
- package/chunks/{chunk-P3BJLFSZ.js → chunk-OYQM5XZ4.js} +3 -3
- package/chunks/{chunk-NRLFZWCT.js → chunk-PNU3TILU.js} +3 -3
- package/chunks/{chunk-M6HMMKVG.js → chunk-PSTHNTHF.js} +1 -1
- package/chunks/{chunk-4PYCZH2V.js → chunk-QEWAHAW2.js} +3 -3
- package/chunks/{chunk-QJMOAMXT.js → chunk-RG2S3GYC.js} +8 -8
- package/chunks/{chunk-CTJLZLB5.js → chunk-RQS2BGPI.js} +1 -1
- package/chunks/{chunk-Y4R47ZUH.js → chunk-RTBUTKAX.js} +7 -7
- package/chunks/{chunk-NV65ZUVM.js → chunk-RZZV6GQN.js} +1 -1
- package/chunks/{chunk-UEOKWYGY.js → chunk-SESSAEWC.js} +11 -11
- package/chunks/{chunk-CPG6P4GG.js → chunk-SKRHR6N2.js} +1 -1
- package/chunks/{chunk-WAUGQKUU.js → chunk-SNHBRO4C.js} +9 -5
- package/chunks/{chunk-KID7K6H2.js → chunk-SNPOURNX.js} +6 -6
- package/chunks/{chunk-VWKER4ZH.js → chunk-SQCTJ435.js} +3 -3
- package/chunks/{chunk-Z4JX4NSH.js → chunk-SXJ7JYQA.js} +23 -23
- package/chunks/{chunk-XVHYA33G.js → chunk-TD7JVTIA.js} +4 -4
- package/chunks/{chunk-IRZ2ZH72.js → chunk-TEFHXP7C.js} +4 -4
- package/chunks/{chunk-2FRY5CRX.js → chunk-TNETSI2A.js} +3 -3
- package/chunks/{chunk-IA7TGCN2.js → chunk-TROB4PZY.js} +4 -4
- package/chunks/{chunk-4TRQPFDP.js → chunk-U3O2EO5Y.js} +26 -20
- package/chunks/{chunk-VKJ4KTPJ.js → chunk-U7ROFHSH.js} +1 -1
- package/chunks/{chunk-Q3JQ7OSU.js → chunk-UBC6PMV7.js} +1 -1
- package/chunks/{chunk-W5UC37EE.js → chunk-UFHPAMAV.js} +6 -0
- package/chunks/{chunk-EQL65XGA.js → chunk-UHF5VBKO.js} +47 -21
- package/chunks/{chunk-S6HYI3MF.js → chunk-UQPLUR4A.js} +2 -2
- package/chunks/{chunk-HGCQ5SE7.js → chunk-UXEO7E3V.js} +21 -0
- package/chunks/{chunk-WCG5O7IP.js → chunk-V3NMFQD2.js} +2 -2
- package/chunks/{chunk-EKPKKXY2.js → chunk-V4SJMQVJ.js} +1 -1
- package/chunks/{chunk-ONSZH6VM.js → chunk-VFJVRSRK.js} +2 -2
- package/chunks/{chunk-MZSJ43WV.js → chunk-W5ZFJYUG.js} +13 -0
- package/chunks/{chunk-XCGIMOLN.js → chunk-WCCLLK7X.js} +14 -1
- package/chunks/{chunk-4WL6SY4F.js → chunk-WDSTNDEW.js} +1 -1
- package/chunks/{chunk-KONVMRK7.js → chunk-WFTBYUOR.js} +1 -1
- package/chunks/{chunk-EI3NWELG.js → chunk-WH32GXQS.js} +6233 -4342
- package/chunks/{chunk-MIKXJYZB.js → chunk-WS5TWVT6.js} +305 -291
- package/chunks/{chunk-VJNBRRZG.js → chunk-WZMH7II3.js} +1 -1
- package/chunks/{chunk-67EWJE77.js → chunk-XY7DGTIC.js} +1 -1
- package/chunks/{chunk-HV76SFIA.js → chunk-YI5G32RU.js} +3 -3
- package/chunks/{chunk-OIVKILPI.js → chunk-YMB77M76.js} +18 -0
- package/chunks/{chunk-AQAJJMRR.js → chunk-YPITLFHS.js} +1 -1
- package/chunks/{chunk-WOJZWRAZ.js → chunk-YRLW2MSX.js} +1 -1
- package/chunks/{chunk-ZZCWJWTF.js → chunk-YY23TR4M.js} +31 -11
- package/chunks/{chunk-URKIBIFC.js → chunk-YYI3Z3AO.js} +3 -3
- package/chunks/chunk-Z7B6SRPM.js +32 -0
- package/chunks/{chunk-6Q5ABMTU.js → chunk-ZGONVQ3D.js} +23 -19
- package/chunks/{chunk-GWVUR3QZ.js → chunk-ZM6LZON7.js} +3 -3
- package/chunks/{chunk-XCWO3SMQ.js → chunk-ZPZANKVP.js} +3 -3
- package/chunks/{chunk-OCSFNUU4.js → chunk-ZRD3BUEX.js} +8 -8
- package/chunks/{chunk-PYQADEFD.js → chunk-ZRT36RSF.js} +1 -1
- package/chunks/{chunk-JT7XS4YW.js → chunk-ZZ7RUTJ4.js} +1 -1
- package/chunks/{computer-use-WQFK33Z3.js → computer-use-7BMFU557.js} +42 -41
- package/chunks/{config-utils-ULCSRMWD.js → config-utils-I732W437.js} +6 -6
- package/chunks/{contextCommand-7EOZND7C.js → contextCommand-VJ6UOMM4.js} +44 -43
- package/chunks/{core-runtime-FGMQRM6E.js → core-runtime-PMRKP77C.js} +42 -41
- package/chunks/{create-sub-session-QIDZUOPU.js → create-sub-session-23ULO5PO.js} +2 -2
- package/chunks/{create-sub-session-QM2K5HLZ.js → create-sub-session-5A3MSW22.js} +42 -41
- package/chunks/{cron-create-VONA5JYY.js → cron-create-5WUTNKNF.js} +4 -4
- package/chunks/{cron-delete-5JXSP2MI.js → cron-delete-JEQ27YPS.js} +4 -4
- package/chunks/{cron-list-KE4F2CIR.js → cron-list-IXGCA7UR.js} +4 -4
- package/chunks/{daemon-GWD7BT6E.js → daemon-PXIC4ZDK.js} +186 -7
- package/chunks/daemon-status-provider-33BLPRUA.js +103 -0
- package/chunks/daemon-trust-policy-ZUV26YGP.js +99 -0
- package/chunks/{daemon-trust-policy-monitor-6UKEABN5.js → daemon-trust-policy-monitor-35WRTIMA.js} +49 -48
- package/chunks/{de-LIW4XVLN.js → de-UBEBKG6V.js} +2 -1
- package/chunks/{deferred-core-runtime-67GJXHXS.js → deferred-core-runtime-ZSLQKM7J.js} +42 -41
- package/chunks/{display-image-NQRSIBXM.js → display-image-CAD7RAUM.js} +4 -4
- package/chunks/{dist-6BMOAE3Z.js → dist-362MN6CP.js} +4 -4
- package/chunks/{dist-3NTTUAHT.js → dist-5VDE7U3A.js} +3 -3
- package/chunks/{dist-Z3CS4OVP.js → dist-6RK4U6VU.js} +11 -5
- package/chunks/{dist-B2CGTW6T.js → dist-CCUH2Z4C.js} +3 -3
- package/chunks/{dist-J47AXBZC.js → dist-EZHCZSW6.js} +3 -3
- package/chunks/{dist-EZE3V3Q7.js → dist-JIORWIDV.js} +3 -3
- package/chunks/{dist-EWW3J4HQ.js → dist-M3XMEIP2.js} +3 -3
- package/chunks/{dist-OTUO3AS2.js → dist-NN5ARGTQ.js} +13 -5
- package/chunks/{earlyInputCapture-IWMYR6OB.js → earlyInputCapture-UNMCTGJR.js} +43 -42
- package/chunks/{edit-ZFGROCAF.js → edit-TXVTSXHY.js} +42 -41
- package/chunks/{en-SY5GTIGX.js → en-X6YV7GME.js} +2 -1
- package/chunks/{enter-worktree-TZZZCDM5.js → enter-worktree-7Q3X4PW7.js} +42 -41
- package/chunks/{enterPlanMode-U77BI3R6.js → enterPlanMode-AZBU3ZB6.js} +42 -41
- package/chunks/{environment-HC37DS2I.js → environment-TGFFQISF.js} +45 -44
- package/chunks/{errors-6AG54JPD.js → errors-GVPFT7BA.js} +44 -43
- package/chunks/{exit-worktree-UYYWFPNK.js → exit-worktree-7INKYMWE.js} +42 -41
- package/chunks/exitPlanMode-5CE7CLAE.js +85 -0
- package/chunks/{fast-path-F5FSZ3O7.js → fast-path-7B6F74IR.js} +5 -5
- package/chunks/{fast-path-settings-RPAVBD7P.js → fast-path-settings-LNOFM2YP.js} +2 -2
- package/chunks/{fr-RQFO7U4P.js → fr-VENTC2BS.js} +2 -1
- package/chunks/{gemini-NKQHYM36.js → gemini-4RUYPDKT.js} +92 -91
- package/chunks/{geminiContentGenerator-HCWZOUX3.js → geminiContentGenerator-NLL52POY.js} +6 -6
- package/chunks/{glob-3PDXKBAO.js → glob-DHU3INUK.js} +42 -41
- package/chunks/{goal-tools-SWNB6GP4.js → goal-tools-LQFO4BRY.js} +4 -4
- package/chunks/{grep-5HZKZYVD.js → grep-523W6G52.js} +42 -41
- package/chunks/handleAutoUpdate-PKUQ3OQQ.js +94 -0
- package/chunks/{i18n-Q27KKNDL.js → i18n-HYL2UBJW.js} +43 -42
- package/chunks/{image-gen-2Z2RJ6W7.js → image-gen-NLIDBAKE.js} +10 -10
- package/chunks/initializer-DGH7RAJ7.js +100 -0
- package/chunks/{installationInfo-XXB75T7O.js → installationInfo-FZ4XWV7O.js} +43 -42
- package/chunks/{ja-KOZKHJHZ.js → ja-QHT4EQTO.js} +2 -1
- package/chunks/{keychain-token-storage-TVAMTNP7.js → keychain-token-storage-GU75J2T2.js} +2 -2
- package/chunks/list-RH5HGWRJ.js +103 -0
- package/chunks/{list-agents-Z4WABFDZ.js → list-agents-5PNMK2AM.js} +2 -2
- package/chunks/loadedSettingsAdapter-XMX2JDOU.js +97 -0
- package/chunks/{loggingContentGenerator-6NTFBM7Q.js → loggingContentGenerator-T3J4HZ7U.js} +139 -98
- package/chunks/{loop-wakeup-UZ5RL5Y2.js → loop-wakeup-OV65FEGR.js} +5 -5
- package/chunks/{ls-TVHDGIES.js → ls-7CETV7WV.js} +4 -4
- package/chunks/{lsp-CVN6OQPI.js → lsp-IWTJWFLT.js} +2 -2
- package/chunks/{managed-npm-update-SPHYQUWZ.js → managed-npm-update-E5ZGIGWV.js} +45 -44
- package/chunks/mcp-6LC572CW.js +97 -0
- package/chunks/{monitor-ZBBPAA54.js → monitor-HQUS4RTV.js} +42 -41
- package/chunks/nonInteractiveCli-X7HKTS5Z.js +163 -0
- package/chunks/{notebook-edit-5W3FW7Z2.js → notebook-edit-QPI3LTFM.js} +42 -41
- package/chunks/{openaiContentGenerator-TQANPEVZ.js → openaiContentGenerator-GGS72DVB.js} +29 -29
- package/chunks/{pidfile-EQOBLH4E.js → pidfile-HD3EB6GL.js} +43 -42
- package/chunks/{processUtils-7XQG7EHS.js → processUtils-2WNEPSW4.js} +2 -2
- package/chunks/{pt-U6AOCTMF.js → pt-VL3I5RNY.js} +2 -1
- package/chunks/{qwenContentGenerator-BKCPHHXU.js → qwenContentGenerator-WJYPELF3.js} +48 -48
- package/chunks/{qwenOAuth2-BJ6PQKE6.js → qwenOAuth2-RSMEBZU4.js} +9 -9
- package/chunks/read-file-URU5ALY3.js +32 -0
- package/chunks/{read-mcp-resource-PZ4ZF6YL.js → read-mcp-resource-THCSZHXO.js} +2 -2
- package/chunks/{read-package-up-TCM6I7S2.js → read-package-up-K6RKTL5D.js} +1 -1
- package/chunks/{record-artifact-P4HFMS7X.js → record-artifact-76YYQA5F.js} +3 -3
- package/chunks/{resumeHistoryUtils-6N6XGJJW.js → resumeHistoryUtils-XMC3CR2U.js} +49 -48
- package/chunks/ripGrep-6NYCUBVW.js +85 -0
- package/chunks/{ru-CMX4UMYP.js → ru-4RCKL4PY.js} +2 -1
- package/chunks/{run-qwen-serve-BCKBCAMX.js → run-qwen-serve-H4IXCJDQ.js} +165 -65
- package/chunks/{runtime-E2437YKL.js → runtime-EJHNZR7H.js} +55 -54
- package/chunks/{scheduler-K3D5Z655.js → scheduler-VVORKEEZ.js} +44 -43
- package/chunks/{sdk-exporters-http-XVTZQRCE.js → sdk-exporters-http-JYKTSCMG.js} +11 -7
- package/chunks/{sdk-impl-7W7AKCS4.js → sdk-impl-ROR54N3H.js} +13 -10
- package/chunks/{send-message-CAMSLG2L.js → send-message-P5SLP57G.js} +6 -6
- package/chunks/serve-3ULKH2KQ.js +107 -0
- package/chunks/{server-UD6INW7J.js → server-J52IQLRJ.js} +949 -303
- package/chunks/{session-GR4ZEVW4.js → session-MNWSMCC2.js} +118 -98
- package/chunks/{settings-5O24D3OJ.js → settings-WFCKUQZO.js} +48 -47
- package/chunks/{shell-UTLWLG5G.js → shell-H5DZN76B.js} +42 -41
- package/chunks/{skill-QQAZL4VO.js → skill-STSDBOIL.js} +19 -19
- package/chunks/{skill-settings-P3YHJVBZ.js → skill-settings-LTJAR2LV.js} +48 -47
- package/chunks/spawnChannel-XL27KTLE.js +98 -0
- package/chunks/{standalone-update-QP742MGP.js → standalone-update-3FUDL2R6.js} +44 -43
- package/chunks/{startInteractiveUI-YCS6AEPN.js → startInteractiveUI-5BFJCCWU.js} +596 -335
- package/chunks/{syntheticOutput-PEBJQYJV.js → syntheticOutput-SEW4NA47.js} +3 -3
- package/chunks/{task-create-5NWCQSJF.js → task-create-247EAVF7.js} +10 -10
- package/chunks/{task-list-53265TRZ.js → task-list-ZJN4QHLK.js} +5 -5
- package/chunks/{task-stop-FPCOIRYX.js → task-stop-MAYQJ42I.js} +2 -2
- package/chunks/{task-update-5HN577LS.js → task-update-CG4FALQF.js} +10 -10
- package/chunks/{team-create-WFH7OCDQ.js → team-create-FC2EYGE7.js} +44 -43
- package/chunks/{team-delete-MMQB4OSC.js → team-delete-3XVRPQBP.js} +5 -5
- package/chunks/{team-plan-approval-EGTT53MV.js → team-plan-approval-X673CRIZ.js} +42 -41
- package/chunks/{terminal-image-renderer-BWRESAQ7.js → terminal-image-renderer-MRNJ77H7.js} +44 -43
- package/chunks/theme-manager-6UMSB7DJ.js +89 -0
- package/chunks/{todoWrite-JGV6VLOX.js → todoWrite-IE2YTCK7.js} +4 -4
- package/chunks/{tool-search-TI5PTIBF.js → tool-search-7Z3PPA5O.js} +19 -19
- package/chunks/total-session-admission-NU4KV76R.js +99 -0
- package/chunks/{trustedFolders-4KYHA4IG.js → trustedFolders-SCUSHKHS.js} +43 -42
- package/chunks/{update-relaunch-WB6LGIF2.js → update-relaunch-M6BNKY4W.js} +5 -5
- package/chunks/{updateCheck-LOS5GYFC.js → updateCheck-QMZZ53S6.js} +48 -47
- package/chunks/{useAutoAcceptIndicator-MHAPY52L.js → useAutoAcceptIndicator-GAFG5PFE.js} +52 -51
- package/chunks/{validateNonInterActiveAuth-QV22HNQU.js → validateNonInterActiveAuth-V44BOAD2.js} +87 -86
- package/chunks/{version-DALWZHKQ.js → version-A4J2RQXD.js} +2 -2
- package/chunks/{web-fetch-JMJVMYFE.js → web-fetch-43TWEBWB.js} +19 -19
- package/chunks/{web-search-DNDUIPU5.js → web-search-CS3Q6JBI.js} +11 -11
- package/chunks/{workflow-JGNN64PM.js → workflow-ETQXJUPR.js} +115 -49
- package/chunks/workspace-providers-status-Y4FPKLHN.js +100 -0
- package/chunks/{workspace-registration-store-LRJG7QA4.js → workspace-registration-store-JASCK5RS.js} +1 -1
- package/chunks/{workspace-registry-KVXIFM36.js → workspace-registry-MU3VIM2D.js} +49 -48
- package/chunks/{workspace-service-PO4AAKKT.js → workspace-service-MHVHRNDX.js} +54 -53
- package/chunks/workspace-skills-status-QVQMNHGO.js +100 -0
- package/chunks/{workspace-trust-reconciler-DOZPCVHG.js → workspace-trust-reconciler-ABXDCISO.js} +56 -55
- package/chunks/write-file-YL7EPQRJ.js +87 -0
- package/chunks/{zh-AGL2FVBI.js → zh-LMSTK4WD.js} +2 -1
- package/chunks/{zh-TW-KI66MHQY.js → zh-TW-SQ4HTSCW.js} +2 -1
- package/chunks/{zoom-image-CNC77ZMA.js → zoom-image-ZQV6O2KE.js} +15 -15
- package/cli.js +13 -13
- package/locales/ca.js +1 -0
- package/locales/de.js +1 -0
- package/locales/en.js +1 -0
- package/locales/fr.js +1 -0
- package/locales/ja.js +1 -0
- package/locales/pt.js +1 -0
- package/locales/ru.js +1 -0
- package/locales/zh-TW.js +1 -0
- package/locales/zh.js +1 -0
- package/package.json +4 -4
- package/web-shell/assets/{arc-CDk0d60K.js → arc-BDKBUdHd.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-h-W3I2lP.js → architectureDiagram-3BPJPVTR-DgMi5iOf.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-D1pvSmZg.js → blockDiagram-GPEHLZMM-DOyxD2BK.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-ByAm5ZNf.js → c4Diagram-AAUBKEIU-CmXzCE_n.js} +1 -1
- package/web-shell/assets/channel-BCff03Ag.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-VrGPPOGV.js → chunk-2J33WTMH-Dr13N7PT.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-B7hTowgG.js → chunk-4BX2VUAB-CIFcKNCP.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-j1Fq8DpE.js → chunk-55IACEB6-B8jmrVPK.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-UjABYpF2.js → chunk-727SXJPM-CQc0wjze.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-D4uBItrs.js → chunk-AQP2D5EJ-CGdZxT9s.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-DeFbKlb8.js → chunk-FMBD7UC4-4iCBhCLJ.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-rQJ8TIgT.js → chunk-ND2GUHAM-B0mMzZcM.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-DAGcRxvq.js → chunk-QZHKN3VN-6CURQrGl.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-DnwxH0ri.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-DnwxH0ri.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-MaE7MJSt.js → cose-bilkent-S5V4N54A-L6Fo1GN1.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-DzijYGSb.js → dagre-BM42HDAG-BTsGDeLA.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-WdbG7WnX.js → diagram-2AECGRRQ-B4AXYZGR.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-NYutsBnw.js → diagram-5GNKFQAL-C2yM5aNc.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-Dqg0eBY0.js → diagram-KO2AKTUF-CrGLZmRK.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-C7vRP2Lb.js → diagram-LMA3HP47-rycHl4fv.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-B2sEPpPt.js → diagram-OG6HWLK6-MQj80AQu.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-a4zIbzm8.js → erDiagram-TEJ5UH35-DCgH-D0D.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-BK9y89ya.js → flowDiagram-I6XJVG4X-B0gnwCnt.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-wUQTSNvV.js → ganttDiagram-6RSMTGT7-CB0OxXVE.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Dnzt4SAi.js → gitGraphDiagram-PVQCEYII-xLxucse9.js} +1 -1
- package/web-shell/assets/{index-BA3wUcKL.js → index-BFFbq0E-.js} +1 -1
- package/web-shell/assets/index-D7XXR9S-.js +1789 -0
- package/web-shell/assets/index-Dk5RwPL9.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-DcaoToij.js → infoDiagram-5YYISTIA-7FCqN4qa.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-DzduqhP2.js → ishikawaDiagram-YF4QCWOH-BGyKlnik.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-BvviZR_O.js → journeyDiagram-JHISSGLW-CmgSXMLF.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-Efm2JxY3.js → kanban-definition-UN3LZRKU-CjT2mF6A.js} +1 -1
- package/web-shell/assets/{linear-DtY3IbOs.js → linear-CiTDGfCW.js} +1 -1
- package/web-shell/assets/{mermaid.core-PzpFqoMe.js → mermaid.core-_QnqxPRF.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-BLlTkHS0.js → mindmap-definition-RKZ34NQL-B1On14ZB.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-D-mKF-jE.js → pieDiagram-4H26LBE5-x1Pf1OG2.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-DYCzslGm.js → quadrantDiagram-W4KKPZXB-ZawmK1Q9.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-Dfpxlk7R.js → requirementDiagram-4Y6WPE33-krIMX0c8.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-D5cRaaxh.js → sankeyDiagram-5OEKKPKP-aMJyxtx_.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-s04DReiS.js → sequenceDiagram-3UESZ5HK-C530-Kqz.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-01UNFgnb.js → stateDiagram-AJRCARHV-DObd9dT_.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Bttf9Ae9.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-DX8_wZBC.js → timeline-definition-PNZ67QCA-D9LnwQ1O.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-BK0FlBme.js → vennDiagram-CIIHVFJN-B_MT_v6Y.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-DkPc9UlD.js → wardley-L42UT6IY-DHKPz5Hu.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DNKkpDAo.js → wardleyDiagram-YWT4CUSO-BoyKaItA.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-CiPwg8QG.js → xychartDiagram-2RQKCTM6--xBJT7Kg.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/agent-headless-HYEHZFH6.js +0 -86
- package/chunks/channel-settings-store-OXYG5S5X.js +0 -101
- package/chunks/chunk-I5VM3SKY.js +0 -451
- package/chunks/chunk-PDPFQ2FO.js +0 -156
- package/chunks/daemon-status-provider-L3J6GKCT.js +0 -102
- package/chunks/daemon-trust-policy-4PHPY23S.js +0 -98
- package/chunks/exitPlanMode-RWJR2KGB.js +0 -84
- package/chunks/handleAutoUpdate-NHFSGYTF.js +0 -93
- package/chunks/initializer-Y5DJLT43.js +0 -99
- package/chunks/list-YHNQ32CS.js +0 -102
- package/chunks/loadedSettingsAdapter-GHUQK7H4.js +0 -96
- package/chunks/mcp-EA3KO6FS.js +0 -96
- package/chunks/nonInteractiveCli-NNOR56HU.js +0 -162
- package/chunks/read-file-KKTXGIZD.js +0 -32
- package/chunks/ripGrep-SJVAAYDV.js +0 -84
- package/chunks/serve-IH4XR5IL.js +0 -106
- package/chunks/spawnChannel-UAQMH6Y6.js +0 -94
- package/chunks/theme-manager-ZNDGAHJN.js +0 -88
- package/chunks/total-session-admission-66UDSOHO.js +0 -98
- package/chunks/workspace-providers-status-K22B3Z6B.js +0 -99
- package/chunks/workspace-skills-status-DDYCBVSH.js +0 -99
- package/chunks/write-file-TT6MWIKC.js +0 -86
- package/web-shell/assets/channel-DPFUV4oi.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CLm0hVvw.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CLm0hVvw.js +0 -1
- package/web-shell/assets/index-BjC3yjjL.css +0 -5
- package/web-shell/assets/index-QzFq6w7o.js +0 -1775
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DXb5olqv.js +0 -1
|
@@ -2,38 +2,31 @@
|
|
|
2
2
|
"use strict";
|
|
3
3
|
import {
|
|
4
4
|
formatHistoryGapNotice
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-4IWFPTAH.js";
|
|
6
6
|
import {
|
|
7
7
|
sanitizeTerminalText
|
|
8
8
|
} from "./chunk-4NFY2S7N.js";
|
|
9
|
-
import {
|
|
10
|
-
isGoalStatusKind,
|
|
11
|
-
isTerminalGoalStatusKind
|
|
12
|
-
} from "./chunk-EKTCKZV5.js";
|
|
13
9
|
import {
|
|
14
10
|
loadUndici
|
|
15
11
|
} from "./chunk-3Z43GZUQ.js";
|
|
16
12
|
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
setGoalTerminalObserver,
|
|
20
|
-
setLastGoalTerminal,
|
|
21
|
-
unregisterGoalHook
|
|
22
|
-
} from "./chunk-EI3NWELG.js";
|
|
13
|
+
projectGoalStateToLegacy
|
|
14
|
+
} from "./chunk-WH32GXQS.js";
|
|
23
15
|
import {
|
|
16
|
+
parseGoalSnapshotV2,
|
|
17
|
+
parseGoalStateCause,
|
|
24
18
|
projectUserTranscriptForDisplay
|
|
25
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-B66LYK4B.js";
|
|
26
20
|
import {
|
|
27
|
-
apiActivityTracker,
|
|
28
21
|
formatVisionBridgeNoticeDisplay,
|
|
29
22
|
isVisionBridgeNoticeDisplay
|
|
30
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-LAKFZU36.js";
|
|
31
24
|
import {
|
|
32
25
|
ToolNames
|
|
33
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-ZRT36RSF.js";
|
|
34
27
|
import {
|
|
35
28
|
createDebugLogger
|
|
36
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-YMB77M76.js";
|
|
37
30
|
import {
|
|
38
31
|
writeStderrLine,
|
|
39
32
|
writeStderrLineSafe
|
|
@@ -45,788 +38,147 @@ import {
|
|
|
45
38
|
__name
|
|
46
39
|
} from "./chunk-J2S4EL5Y.js";
|
|
47
40
|
|
|
48
|
-
// packages/cli/src/
|
|
41
|
+
// packages/cli/src/acp-integration/session/history-replayer.ts
|
|
49
42
|
init_esbuild_shims();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
43
|
+
|
|
44
|
+
// packages/acp-bridge/src/transcript-replay.ts
|
|
45
|
+
init_esbuild_shims();
|
|
46
|
+
|
|
47
|
+
// packages/core/dist/src/goals/goal-wire.js
|
|
48
|
+
init_esbuild_shims();
|
|
49
|
+
|
|
50
|
+
// packages/core/dist/src/goals/goal-protocol.js
|
|
51
|
+
init_esbuild_shims();
|
|
52
|
+
var GOAL_STATE_VERSION = 2;
|
|
53
|
+
var GOAL_CHECKPOINT_CLAIM_LIMIT = 32;
|
|
54
|
+
var GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS = 2e3;
|
|
55
|
+
var GOAL_CHECKPOINT_CLAIM_MAX_BYTES = 16e3;
|
|
56
|
+
var GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT = 32;
|
|
57
|
+
function isGoalEvidenceProofKind(value) {
|
|
58
|
+
return value === "user_input" || value === "delivered_output" || value === "external_fact";
|
|
64
59
|
}
|
|
65
|
-
__name(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
60
|
+
__name(isGoalEvidenceProofKind, "isGoalEvidenceProofKind");
|
|
61
|
+
|
|
62
|
+
// packages/core/dist/src/goals/goal-reducer.js
|
|
63
|
+
init_esbuild_shims();
|
|
64
|
+
var MAX_BLOCKED_AUDIT_COUNT = 3;
|
|
65
|
+
function parseGoalStateRecordPayloadV2(value) {
|
|
66
|
+
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
67
|
+
"v",
|
|
68
|
+
"cause",
|
|
69
|
+
"snapshot",
|
|
70
|
+
"checkpointPending",
|
|
71
|
+
"blockedAudit"
|
|
72
|
+
]) || value["v"] !== GOAL_STATE_VERSION || !isGoalStateCause(value["cause"]) || !isCheckpointPending(value["checkpointPending"]) || !isBlockedAudit(value["blockedAudit"])) {
|
|
73
|
+
return void 0;
|
|
76
74
|
}
|
|
77
|
-
|
|
75
|
+
const parsedSnapshot = parseGoalSnapshotV22(value["snapshot"]);
|
|
76
|
+
if (parsedSnapshot?.activity !== "idle")
|
|
77
|
+
return void 0;
|
|
78
|
+
const checkpointPending = value["checkpointPending"];
|
|
79
|
+
if (checkpointPending && (parsedSnapshot.goal?.status !== "active" || checkpointPending.permit.goalId !== parsedSnapshot.goal.goalId || checkpointPending.permit.revision !== parsedSnapshot.goal.revision || checkpointPending.recordUuid === parsedSnapshot.goal.evidenceCursor.recordId || value["cause"] !== "turn_finished" && value["cause"] !== "verifier_reject")) {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
v: GOAL_STATE_VERSION,
|
|
84
|
+
cause: value["cause"],
|
|
85
|
+
snapshot: parsedSnapshot,
|
|
86
|
+
...checkpointPending ? { checkpointPending: structuredClone(checkpointPending) } : {},
|
|
87
|
+
...value["blockedAudit"] ? { blockedAudit: structuredClone(value["blockedAudit"]) } : {}
|
|
88
|
+
};
|
|
78
89
|
}
|
|
79
|
-
__name(
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (!isTerminalGoalStatusKind(goal.kind)) continue;
|
|
90
|
+
__name(parseGoalStateRecordPayloadV2, "parseGoalStateRecordPayloadV2");
|
|
91
|
+
function parseGoalSnapshotV22(value) {
|
|
92
|
+
if (!isRecord(value) || !hasOnlyKeys(value, ["v", "goal", "activity"]) || value["v"] !== GOAL_STATE_VERSION || !isGoalActivity(value["activity"])) {
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
if (value["goal"] === null) {
|
|
86
96
|
return {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
durationMs: goal.durationMs ?? 0,
|
|
91
|
-
lastReason: goal.lastReason
|
|
97
|
+
v: GOAL_STATE_VERSION,
|
|
98
|
+
goal: null,
|
|
99
|
+
activity: value["activity"]
|
|
92
100
|
};
|
|
93
101
|
}
|
|
94
|
-
|
|
102
|
+
const goal = parseGoalRecord(value["goal"]);
|
|
103
|
+
return goal ? { v: GOAL_STATE_VERSION, goal, activity: value["activity"] } : void 0;
|
|
95
104
|
}
|
|
96
|
-
__name(
|
|
97
|
-
function
|
|
98
|
-
return
|
|
105
|
+
__name(parseGoalSnapshotV22, "parseGoalSnapshotV2");
|
|
106
|
+
function parseGoalStateCause2(value) {
|
|
107
|
+
return isGoalStateCause(value) ? value : void 0;
|
|
99
108
|
}
|
|
100
|
-
__name(
|
|
101
|
-
function
|
|
102
|
-
return
|
|
103
|
-
}
|
|
104
|
-
__name(isTranscriptItemRecord, "isTranscriptItemRecord");
|
|
105
|
-
function parseGoalStatusItem(item) {
|
|
106
|
-
if (!isTranscriptItemRecord(item)) return null;
|
|
107
|
-
if (item["type"] !== "goal_status" /* GOAL_STATUS */) return null;
|
|
108
|
-
const kind = item["kind"];
|
|
109
|
-
const condition = item["condition"];
|
|
110
|
-
if (!isGoalStatusKind(kind) || typeof condition !== "string") return null;
|
|
111
|
-
const iterations = finiteNumber(item["iterations"]);
|
|
112
|
-
const setAt = finiteNumber(item["setAt"]);
|
|
113
|
-
const durationMs = finiteNumber(item["durationMs"]);
|
|
114
|
-
const lastReason = typeof item["lastReason"] === "string" ? item["lastReason"] : void 0;
|
|
115
|
-
return {
|
|
116
|
-
type: "goal_status" /* GOAL_STATUS */,
|
|
117
|
-
kind,
|
|
118
|
-
condition,
|
|
119
|
-
...iterations !== void 0 ? { iterations } : {},
|
|
120
|
-
...setAt !== void 0 ? { setAt } : {},
|
|
121
|
-
...durationMs !== void 0 ? { durationMs } : {},
|
|
122
|
-
...lastReason !== void 0 ? { lastReason } : {}
|
|
123
|
-
};
|
|
109
|
+
__name(parseGoalStateCause2, "parseGoalStateCause");
|
|
110
|
+
function copyCursor(cursor) {
|
|
111
|
+
return { recordId: cursor.recordId };
|
|
124
112
|
}
|
|
125
|
-
__name(
|
|
126
|
-
function
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
113
|
+
__name(copyCursor, "copyCursor");
|
|
114
|
+
function parseGoalRecord(value) {
|
|
115
|
+
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
116
|
+
"goalId",
|
|
117
|
+
"revision",
|
|
118
|
+
"objective",
|
|
119
|
+
"status",
|
|
120
|
+
"evidenceCursor",
|
|
121
|
+
"turnCount",
|
|
122
|
+
"activeTimeMs",
|
|
123
|
+
"createdAt",
|
|
124
|
+
"updatedAt",
|
|
125
|
+
"evidenceCheckpoint",
|
|
126
|
+
"lastReason"
|
|
127
|
+
]) || typeof value["goalId"] !== "string" || !value["goalId"] || !isNonNegativeInteger(value["revision"]) || value["revision"] === 0 || typeof value["objective"] !== "string" || !value["objective"].trim() || !isGoalStatus(value["status"]) || !isTranscriptCursor(value["evidenceCursor"]) || !isNonNegativeInteger(value["turnCount"]) || !isNonNegativeNumber(value["activeTimeMs"]) || !isFiniteNumber(value["createdAt"]) || !isFiniteNumber(value["updatedAt"]) || !isGoalEvidenceCheckpoint(value["evidenceCheckpoint"]) || value["lastReason"] !== void 0 && typeof value["lastReason"] !== "string") {
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
if (value["evidenceCheckpoint"] && value["evidenceCursor"].recordId !== value["evidenceCheckpoint"].checkpointId) {
|
|
131
|
+
return void 0;
|
|
140
132
|
}
|
|
141
|
-
return items;
|
|
142
|
-
}
|
|
143
|
-
__name(collectGoalStatusItemsFromRecords, "collectGoalStatusItemsFromRecords");
|
|
144
|
-
function goalTerminalEventToHistoryItem(event) {
|
|
145
133
|
return {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
134
|
+
goalId: value["goalId"],
|
|
135
|
+
revision: value["revision"],
|
|
136
|
+
objective: value["objective"],
|
|
137
|
+
status: value["status"],
|
|
138
|
+
evidenceCursor: copyCursor(value["evidenceCursor"]),
|
|
139
|
+
turnCount: value["turnCount"],
|
|
140
|
+
activeTimeMs: value["activeTimeMs"],
|
|
141
|
+
createdAt: value["createdAt"],
|
|
142
|
+
updatedAt: value["updatedAt"],
|
|
143
|
+
...value["evidenceCheckpoint"] === void 0 ? {} : {
|
|
144
|
+
evidenceCheckpoint: structuredClone(value["evidenceCheckpoint"])
|
|
145
|
+
},
|
|
146
|
+
...value["lastReason"] === void 0 ? {} : { lastReason: value["lastReason"] }
|
|
152
147
|
};
|
|
153
148
|
}
|
|
154
|
-
__name(
|
|
155
|
-
function
|
|
156
|
-
|
|
157
|
-
const recording = config.getChatRecordingService?.();
|
|
158
|
-
if (!recording) {
|
|
159
|
-
writeStderrLineSafe(
|
|
160
|
-
`qwen: no chat recording service; goal_status (kind=${item.kind}) will not survive a resume.`
|
|
161
|
-
);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
recording.recordSlashCommand({
|
|
165
|
-
phase: "result",
|
|
166
|
-
rawCommand,
|
|
167
|
-
outputHistoryItems: [{ ...item }]
|
|
168
|
-
});
|
|
169
|
-
} catch (error) {
|
|
170
|
-
writeStderrLineSafe(
|
|
171
|
-
`qwen: failed to record goal_status (kind=${item.kind}): ${error}`
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
__name(recordGoalStatusItem, "recordGoalStatusItem");
|
|
176
|
-
function installGoalTerminalObserver(args) {
|
|
177
|
-
const { sessionId, config, addItem } = args;
|
|
178
|
-
setGoalTerminalObserver(sessionId, (event) => {
|
|
179
|
-
const item = goalTerminalEventToHistoryItem(event);
|
|
180
|
-
addItem(item, Date.now());
|
|
181
|
-
recordGoalStatusItem(config, item);
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
__name(installGoalTerminalObserver, "installGoalTerminalObserver");
|
|
185
|
-
function goalRestoreBlockedBy(config) {
|
|
186
|
-
if (!config.isTrustedFolder()) return "untrusted-folder";
|
|
187
|
-
if (config.getDisableAllHooks()) return "hooks-disabled";
|
|
188
|
-
if (!config.getHookSystem()) return "no-hook-system";
|
|
189
|
-
return null;
|
|
149
|
+
__name(parseGoalRecord, "parseGoalRecord");
|
|
150
|
+
function isTranscriptCursor(value) {
|
|
151
|
+
return isRecord(value) && hasOnlyKeys(value, ["recordId"]) && (typeof value["recordId"] === "string" || value["recordId"] === null);
|
|
190
152
|
}
|
|
191
|
-
__name(
|
|
192
|
-
function
|
|
193
|
-
|
|
194
|
-
return null;
|
|
153
|
+
__name(isTranscriptCursor, "isTranscriptCursor");
|
|
154
|
+
function isGoalStatus(value) {
|
|
155
|
+
return value === "active" || value === "paused" || value === "blocked" || value === "usage_limited" || value === "complete";
|
|
195
156
|
}
|
|
196
|
-
__name(
|
|
197
|
-
function
|
|
198
|
-
|
|
199
|
-
const lastTerminal = findLastTerminalGoal(history);
|
|
200
|
-
setLastGoalTerminal(sessionId, lastTerminal ?? void 0);
|
|
201
|
-
const restorable = findGoalToRestore(history);
|
|
202
|
-
if (restorable === null) {
|
|
203
|
-
unregisterGoalHook(config, sessionId);
|
|
204
|
-
return { restored: false };
|
|
205
|
-
}
|
|
206
|
-
const blockedBy = goalRestoreBlockedBy(config);
|
|
207
|
-
if (blockedBy) {
|
|
208
|
-
unregisterGoalHook(config, sessionId);
|
|
209
|
-
return { restored: false, blockedBy };
|
|
210
|
-
}
|
|
211
|
-
if (goalConditionBlockedBy(restorable.condition)) {
|
|
212
|
-
writeStderrLineSafe(
|
|
213
|
-
`qwen: refusing to restore a goal for session ${sessionId}: the condition is empty.`
|
|
214
|
-
);
|
|
215
|
-
unregisterGoalHook(config, sessionId);
|
|
216
|
-
return { restored: false, blockedBy: "condition-invalid" };
|
|
217
|
-
}
|
|
218
|
-
registerGoalHook({
|
|
219
|
-
config,
|
|
220
|
-
sessionId,
|
|
221
|
-
condition: restorable.condition,
|
|
222
|
-
tokensAtStart: 0,
|
|
223
|
-
// Resume the iteration count so MAX_GOAL_ITERATIONS is a cross-resume cap,
|
|
224
|
-
// not a per-resume one.
|
|
225
|
-
initialIterations: restorable.iterations,
|
|
226
|
-
// Likewise the start time: without it every reload restarts the clock, and
|
|
227
|
-
// `GET /goals` reports a long-running goal as freshly started.
|
|
228
|
-
...restorable.setAt !== void 0 ? { initialSetAt: restorable.setAt } : {}
|
|
229
|
-
});
|
|
230
|
-
if (addItem) {
|
|
231
|
-
installGoalTerminalObserver({ sessionId, config, addItem });
|
|
232
|
-
}
|
|
233
|
-
return { restored: true, condition: restorable.condition };
|
|
157
|
+
__name(isGoalStatus, "isGoalStatus");
|
|
158
|
+
function isGoalActivity(value) {
|
|
159
|
+
return value === "idle" || value === "running" || value === "verifying";
|
|
234
160
|
}
|
|
235
|
-
__name(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
init_esbuild_shims();
|
|
239
|
-
import { promises as fsp } from "node:fs";
|
|
240
|
-
import * as path from "node:path";
|
|
241
|
-
|
|
242
|
-
// packages/cli/src/utils/gitUtils.ts
|
|
243
|
-
init_esbuild_shims();
|
|
244
|
-
import * as childProcess from "node:child_process";
|
|
245
|
-
var debugLogger = createDebugLogger("GIT");
|
|
246
|
-
async function runGit(args, opts = {}) {
|
|
247
|
-
return await new Promise((resolve2, reject) => {
|
|
248
|
-
childProcess.execFile(
|
|
249
|
-
"git",
|
|
250
|
-
args,
|
|
251
|
-
{
|
|
252
|
-
encoding: "utf-8",
|
|
253
|
-
...opts.cwd ? { cwd: opts.cwd } : {}
|
|
254
|
-
},
|
|
255
|
-
(err, stdout) => {
|
|
256
|
-
if (err) {
|
|
257
|
-
reject(err);
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
|
-
resolve2(String(stdout ?? "").trim());
|
|
261
|
-
}
|
|
262
|
-
);
|
|
263
|
-
});
|
|
161
|
+
__name(isGoalActivity, "isGoalActivity");
|
|
162
|
+
function isGoalStateCause(value) {
|
|
163
|
+
return value === "create" || value === "replace" || value === "edit" || value === "pause" || value === "resume" || value === "turn_finished" || value === "checkpoint" || value === "verifier_accept" || value === "verifier_reject" || value === "complete" || value === "blocked" || value === "usage_limited" || value === "clear" || value === "migrated";
|
|
264
164
|
}
|
|
265
|
-
__name(
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
const remotes = await runGit(["remote", "-v"], opts);
|
|
269
|
-
return remotes.split("\n").some((line) => {
|
|
270
|
-
const remoteUrl = line.trim().split(/\s+/)[1];
|
|
271
|
-
return remoteUrl ? isGitHubRemoteUrl(remoteUrl) : false;
|
|
272
|
-
});
|
|
273
|
-
} catch (_error) {
|
|
274
|
-
debugLogger.debug(`Failed to get git remote:`, _error);
|
|
275
|
-
return false;
|
|
276
|
-
}
|
|
277
|
-
}, "isGitHubRepositoryAsync");
|
|
278
|
-
function isGitHubRemoteUrl(remoteUrl) {
|
|
279
|
-
if (remoteUrl.startsWith("git@github.com:")) {
|
|
165
|
+
__name(isGoalStateCause, "isGoalStateCause");
|
|
166
|
+
function isGoalEvidenceCheckpoint(value) {
|
|
167
|
+
if (value === void 0)
|
|
280
168
|
return true;
|
|
281
|
-
|
|
282
|
-
if (remoteUrl.startsWith("git@")) {
|
|
283
|
-
return false;
|
|
284
|
-
}
|
|
285
|
-
try {
|
|
286
|
-
return new URL(remoteUrl).hostname === "github.com";
|
|
287
|
-
} catch {
|
|
169
|
+
if (!isRecord(value) || !hasOnlyKeys(value, ["checkpointId", "createdAt", "claims"]) || typeof value["checkpointId"] !== "string" || value["checkpointId"].length === 0 || !isFiniteNumber(value["createdAt"]) || !Array.isArray(value["claims"]) || value["claims"].length === 0 || value["claims"].length > GOAL_CHECKPOINT_CLAIM_LIMIT) {
|
|
288
170
|
return false;
|
|
289
171
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
if (!gitRepoRoot) {
|
|
295
|
-
throw new Error(`Git repo returned empty value`);
|
|
296
|
-
}
|
|
297
|
-
return gitRepoRoot;
|
|
298
|
-
}, "getGitRepoRootAsync");
|
|
299
|
-
var getLatestGitHubRelease = /* @__PURE__ */ __name(async (proxy) => {
|
|
300
|
-
try {
|
|
301
|
-
const controller = new AbortController();
|
|
302
|
-
const endpoint = `https://api.github.com/repos/QwenLM/qwen-code-action/releases/latest`;
|
|
303
|
-
const dispatcher = proxy ? new (await loadUndici()).ProxyAgent(proxy) : void 0;
|
|
304
|
-
const response = await fetch(endpoint, {
|
|
305
|
-
method: "GET",
|
|
306
|
-
headers: {
|
|
307
|
-
Accept: "application/vnd.github+json",
|
|
308
|
-
"Content-Type": "application/json",
|
|
309
|
-
"X-GitHub-Api-Version": "2022-11-28"
|
|
310
|
-
},
|
|
311
|
-
dispatcher,
|
|
312
|
-
signal: AbortSignal.any([AbortSignal.timeout(3e4), controller.signal])
|
|
313
|
-
});
|
|
314
|
-
if (!response.ok) {
|
|
315
|
-
throw new Error(
|
|
316
|
-
`Invalid response code: ${response.status} - ${response.statusText}`
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
const releaseTag = (await response.json()).tag_name;
|
|
320
|
-
if (!releaseTag) {
|
|
321
|
-
throw new Error(`Response did not include tag_name field`);
|
|
172
|
+
let checkpointBytes = 0;
|
|
173
|
+
for (const [index, claim] of value["claims"].entries()) {
|
|
174
|
+
if (!isRecord(claim) || !hasOnlyKeys(claim, ["id", "proofKind", "claim", "sourceRefs"]) || claim["id"] !== `${value["checkpointId"]}:${index + 1}` || !isGoalEvidenceProofKind(claim["proofKind"]) || typeof claim["claim"] !== "string" || claim["claim"].trim().length === 0 || [...claim["claim"]].length > GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS || !Array.isArray(claim["sourceRefs"]) || claim["sourceRefs"].length === 0 || claim["sourceRefs"].length > GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT || new Set(claim["sourceRefs"]).size !== claim["sourceRefs"].length || claim["sourceRefs"].some((reference) => typeof reference !== "string" || reference.length === 0)) {
|
|
175
|
+
return false;
|
|
322
176
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
`Failed to determine latest qwen-code-action release:`,
|
|
327
|
-
_error
|
|
328
|
-
);
|
|
329
|
-
throw new Error(
|
|
330
|
-
`Unable to determine the latest qwen-code-action release on GitHub.`
|
|
331
|
-
);
|
|
177
|
+
checkpointBytes += new TextEncoder().encode(claim["claim"]).byteLength;
|
|
178
|
+
if (checkpointBytes > GOAL_CHECKPOINT_CLAIM_MAX_BYTES)
|
|
179
|
+
return false;
|
|
332
180
|
}
|
|
333
|
-
|
|
334
|
-
async function getGitHubRepoInfoAsync(opts = {}) {
|
|
335
|
-
return parseGitHubRepoInfo(
|
|
336
|
-
await runGit(["remote", "get-url", "origin"], opts)
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
__name(getGitHubRepoInfoAsync, "getGitHubRepoInfoAsync");
|
|
340
|
-
function parseGitHubRepoInfo(remoteUrl) {
|
|
341
|
-
let urlToParse = remoteUrl;
|
|
342
|
-
if (remoteUrl.startsWith("git@github.com:")) {
|
|
343
|
-
urlToParse = remoteUrl.replace("git@github.com:", "");
|
|
344
|
-
} else if (remoteUrl.startsWith("git@")) {
|
|
345
|
-
throw new Error(
|
|
346
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
let parsedUrl;
|
|
350
|
-
try {
|
|
351
|
-
parsedUrl = new URL(urlToParse, "https://github.com");
|
|
352
|
-
} catch {
|
|
353
|
-
throw new Error(
|
|
354
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
if (parsedUrl.hostname !== "github.com") {
|
|
358
|
-
throw new Error(
|
|
359
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
const parts = parsedUrl.pathname.split("/").filter((part) => part !== "");
|
|
363
|
-
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
364
|
-
throw new Error(
|
|
365
|
-
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
366
|
-
);
|
|
367
|
-
}
|
|
368
|
-
return { owner: parts[0], repo: parts[1].replace(/\.git$/, "") };
|
|
369
|
-
}
|
|
370
|
-
__name(parseGitHubRepoInfo, "parseGitHubRepoInfo");
|
|
371
|
-
|
|
372
|
-
// packages/cli/src/services/setup-github.ts
|
|
373
|
-
var debugLogger2 = createDebugLogger("SETUP_GITHUB");
|
|
374
|
-
var GITHUB_WORKFLOW_PATHS = [
|
|
375
|
-
"qwen-dispatch/qwen-dispatch.yml",
|
|
376
|
-
"qwen-assistant/qwen-invoke.yml",
|
|
377
|
-
"issue-triage/qwen-triage.yml",
|
|
378
|
-
"issue-triage/qwen-scheduled-triage.yml",
|
|
379
|
-
"pr-review/qwen-review.yml"
|
|
380
|
-
];
|
|
381
|
-
var GITIGNORE_ENTRIES = [".qwen/", "gha-creds-*.json"];
|
|
382
|
-
var MAX_WORKFLOW_DOWNLOAD_BYTES = 5 * 1024 * 1024;
|
|
383
|
-
var SetupGithubError = class extends Error {
|
|
384
|
-
static {
|
|
385
|
-
__name(this, "SetupGithubError");
|
|
386
|
-
}
|
|
387
|
-
code;
|
|
388
|
-
status;
|
|
389
|
-
partial;
|
|
390
|
-
partialResult;
|
|
391
|
-
constructor(code, message, status, partialResult) {
|
|
392
|
-
super(message);
|
|
393
|
-
this.name = "SetupGithubError";
|
|
394
|
-
this.code = code;
|
|
395
|
-
this.status = status;
|
|
396
|
-
this.partial = partialResult !== void 0;
|
|
397
|
-
this.partialResult = partialResult;
|
|
398
|
-
}
|
|
399
|
-
};
|
|
400
|
-
function isWorkspaceGenerationClosed(error) {
|
|
401
|
-
return Boolean(
|
|
402
|
-
error && typeof error === "object" && "code" in error && error.code === "workspace_generation_closed"
|
|
403
|
-
);
|
|
404
|
-
}
|
|
405
|
-
__name(isWorkspaceGenerationClosed, "isWorkspaceGenerationClosed");
|
|
406
|
-
var nodeFileOps = {
|
|
407
|
-
assertCanWrite() {
|
|
408
|
-
},
|
|
409
|
-
async ensureWorkflowDirectory(gitRepoRoot) {
|
|
410
|
-
await fsp.mkdir(path.join(gitRepoRoot, ".github", "workflows"), {
|
|
411
|
-
recursive: true
|
|
412
|
-
});
|
|
413
|
-
},
|
|
414
|
-
async writeTextFile(gitRepoRoot, relativePath, content) {
|
|
415
|
-
const target = path.join(gitRepoRoot, relativePath);
|
|
416
|
-
await fsp.writeFile(target, content, { mode: 420 });
|
|
417
|
-
return { sizeBytes: Buffer.byteLength(content, "utf8") };
|
|
418
|
-
},
|
|
419
|
-
async readTextFile(gitRepoRoot, relativePath) {
|
|
420
|
-
try {
|
|
421
|
-
return await fsp.readFile(path.join(gitRepoRoot, relativePath), "utf8");
|
|
422
|
-
} catch (error) {
|
|
423
|
-
if (error.code === "ENOENT") {
|
|
424
|
-
return void 0;
|
|
425
|
-
}
|
|
426
|
-
throw error;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
async function setupGithub(options = {}) {
|
|
431
|
-
const cwd = options.cwd ?? process.cwd();
|
|
432
|
-
const fileOps = options.fileOps ?? nodeFileOps;
|
|
433
|
-
if (!await isGitHubRepositoryAsync({ cwd })) {
|
|
434
|
-
throw new SetupGithubError(
|
|
435
|
-
"github_repository_not_found",
|
|
436
|
-
"Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
|
|
437
|
-
400
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
let gitRepoRoot;
|
|
441
|
-
try {
|
|
442
|
-
gitRepoRoot = await getGitRepoRootAsync({ cwd });
|
|
443
|
-
} catch (error) {
|
|
444
|
-
debugLogger2.debug("Failed to get git repo root:", error);
|
|
445
|
-
throw new SetupGithubError(
|
|
446
|
-
"github_repository_not_found",
|
|
447
|
-
"Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
|
|
448
|
-
400
|
|
449
|
-
);
|
|
450
|
-
}
|
|
451
|
-
if (options.workspaceRoot) {
|
|
452
|
-
const [gitRootReal, workspaceReal] = await Promise.all([
|
|
453
|
-
realpathOrResolve(gitRepoRoot),
|
|
454
|
-
realpathOrResolve(options.workspaceRoot)
|
|
455
|
-
]);
|
|
456
|
-
if (gitRootReal !== workspaceReal) {
|
|
457
|
-
throw new SetupGithubError(
|
|
458
|
-
"github_git_root_mismatch",
|
|
459
|
-
"The Git repository root must match the daemon workspace root.",
|
|
460
|
-
400
|
|
461
|
-
);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
fileOps.assertCanWrite?.();
|
|
465
|
-
let releaseTag;
|
|
466
|
-
try {
|
|
467
|
-
releaseTag = await getLatestGitHubRelease(options.proxy);
|
|
468
|
-
} catch (error) {
|
|
469
|
-
writeStderrLine(
|
|
470
|
-
`qwen setup-github: failed to determine latest qwen-code-action release: ${error instanceof Error ? error.message : String(error)}`
|
|
471
|
-
);
|
|
472
|
-
debugLogger2.debug(
|
|
473
|
-
"Failed to determine latest qwen-code-action release:",
|
|
474
|
-
error
|
|
475
|
-
);
|
|
476
|
-
throw new SetupGithubError(
|
|
477
|
-
"github_release_lookup_failed",
|
|
478
|
-
"Unable to determine the latest qwen-code-action release on GitHub.",
|
|
479
|
-
502
|
|
480
|
-
);
|
|
481
|
-
}
|
|
482
|
-
const readmeUrl = `https://github.com/QwenLM/qwen-code-action/blob/${releaseTag}/README.md#quick-start`;
|
|
483
|
-
const secretsUrl = await resolveSecretsUrl(cwd);
|
|
484
|
-
const downloads = await downloadWorkflows({
|
|
485
|
-
releaseTag,
|
|
486
|
-
proxy: options.proxy,
|
|
487
|
-
abortSignal: options.abortSignal,
|
|
488
|
-
fetchImpl: options.fetchImpl ?? fetch
|
|
489
|
-
});
|
|
490
|
-
const result = {
|
|
491
|
-
kind: "github_setup",
|
|
492
|
-
workspaceCwd: options.workspaceRoot ?? gitRepoRoot,
|
|
493
|
-
gitRepoRoot,
|
|
494
|
-
releaseTag,
|
|
495
|
-
readmeUrl,
|
|
496
|
-
...secretsUrl ? { secretsUrl } : {},
|
|
497
|
-
workflows: [],
|
|
498
|
-
gitignore: { path: ".gitignore", status: "skipped" },
|
|
499
|
-
warnings: []
|
|
500
|
-
};
|
|
501
|
-
result.gitignore = await updateGitignore(gitRepoRoot, fileOps);
|
|
502
|
-
if (result.gitignore.status === "failed") {
|
|
503
|
-
result.warnings.push("Failed to update .gitignore.");
|
|
504
|
-
}
|
|
505
|
-
try {
|
|
506
|
-
await fileOps.ensureWorkflowDirectory(gitRepoRoot);
|
|
507
|
-
for (const workflow of downloads) {
|
|
508
|
-
const relativePath = path.posix.join(
|
|
509
|
-
".github",
|
|
510
|
-
"workflows",
|
|
511
|
-
path.posix.basename(workflow.sourcePath)
|
|
512
|
-
);
|
|
513
|
-
try {
|
|
514
|
-
const write = await fileOps.writeTextFile(
|
|
515
|
-
gitRepoRoot,
|
|
516
|
-
relativePath,
|
|
517
|
-
workflow.content
|
|
518
|
-
);
|
|
519
|
-
result.workflows.push({
|
|
520
|
-
sourcePath: workflow.sourcePath,
|
|
521
|
-
path: relativePath,
|
|
522
|
-
status: "written",
|
|
523
|
-
sizeBytes: write.sizeBytes
|
|
524
|
-
});
|
|
525
|
-
} catch (error) {
|
|
526
|
-
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
527
|
-
result.partial = true;
|
|
528
|
-
result.workflows.push({
|
|
529
|
-
sourcePath: workflow.sourcePath,
|
|
530
|
-
path: relativePath,
|
|
531
|
-
status: "failed",
|
|
532
|
-
error: error instanceof Error ? error.message : String(error)
|
|
533
|
-
});
|
|
534
|
-
throw new SetupGithubError(
|
|
535
|
-
"github_workflow_write_failed",
|
|
536
|
-
`Unable to write ${relativePath}.`,
|
|
537
|
-
500,
|
|
538
|
-
result
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
}
|
|
542
|
-
} catch (error) {
|
|
543
|
-
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
544
|
-
if (error instanceof SetupGithubError) throw error;
|
|
545
|
-
throw new SetupGithubError(
|
|
546
|
-
"github_workflow_write_failed",
|
|
547
|
-
"Unable to create .github/workflows.",
|
|
548
|
-
500,
|
|
549
|
-
result
|
|
550
|
-
);
|
|
551
|
-
}
|
|
552
|
-
return result;
|
|
553
|
-
}
|
|
554
|
-
__name(setupGithub, "setupGithub");
|
|
555
|
-
async function updateGitignore(gitRepoRoot, fileOps = nodeFileOps) {
|
|
556
|
-
try {
|
|
557
|
-
const existingContent = await fileOps.readTextFile(
|
|
558
|
-
gitRepoRoot,
|
|
559
|
-
".gitignore"
|
|
560
|
-
);
|
|
561
|
-
if (existingContent === void 0) {
|
|
562
|
-
const content = GITIGNORE_ENTRIES.join("\n") + "\n";
|
|
563
|
-
await fileOps.writeTextFile(gitRepoRoot, ".gitignore", content);
|
|
564
|
-
return {
|
|
565
|
-
path: ".gitignore",
|
|
566
|
-
status: "created",
|
|
567
|
-
added: [...GITIGNORE_ENTRIES]
|
|
568
|
-
};
|
|
569
|
-
}
|
|
570
|
-
const missingEntries = GITIGNORE_ENTRIES.filter(
|
|
571
|
-
(entry) => !existingContent.split(/\r?\n/).some((line) => line.split("#")[0].trim() === entry)
|
|
572
|
-
);
|
|
573
|
-
if (missingEntries.length === 0) {
|
|
574
|
-
return { path: ".gitignore", status: "unchanged" };
|
|
575
|
-
}
|
|
576
|
-
const nextContent = existingContent + "\n" + missingEntries.join("\n") + "\n";
|
|
577
|
-
await fileOps.writeTextFile(gitRepoRoot, ".gitignore", nextContent);
|
|
578
|
-
return {
|
|
579
|
-
path: ".gitignore",
|
|
580
|
-
status: "updated",
|
|
581
|
-
added: missingEntries
|
|
582
|
-
};
|
|
583
|
-
} catch (error) {
|
|
584
|
-
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
585
|
-
debugLogger2.debug("Failed to update .gitignore:", error);
|
|
586
|
-
return {
|
|
587
|
-
path: ".gitignore",
|
|
588
|
-
status: "failed",
|
|
589
|
-
error: error instanceof Error ? error.message : String(error)
|
|
590
|
-
};
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
__name(updateGitignore, "updateGitignore");
|
|
594
|
-
async function downloadWorkflows(options) {
|
|
595
|
-
const internalAbort = new AbortController();
|
|
596
|
-
try {
|
|
597
|
-
const dispatcher = options.proxy ? new (await loadUndici()).ProxyAgent(options.proxy) : void 0;
|
|
598
|
-
return await Promise.all(
|
|
599
|
-
GITHUB_WORKFLOW_PATHS.map(async (workflow) => {
|
|
600
|
-
const endpoint = `https://raw.githubusercontent.com/QwenLM/qwen-code-action/refs/tags/${options.releaseTag}/examples/workflows/${workflow}`;
|
|
601
|
-
const response = await options.fetchImpl(endpoint, {
|
|
602
|
-
method: "GET",
|
|
603
|
-
dispatcher,
|
|
604
|
-
signal: AbortSignal.any([
|
|
605
|
-
AbortSignal.timeout(3e4),
|
|
606
|
-
internalAbort.signal,
|
|
607
|
-
...options.abortSignal ? [options.abortSignal] : []
|
|
608
|
-
])
|
|
609
|
-
});
|
|
610
|
-
if (!response.ok) {
|
|
611
|
-
throw new Error(
|
|
612
|
-
`Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`
|
|
613
|
-
);
|
|
614
|
-
}
|
|
615
|
-
return {
|
|
616
|
-
sourcePath: workflow,
|
|
617
|
-
content: await readResponseTextWithLimit(response, workflow)
|
|
618
|
-
};
|
|
619
|
-
})
|
|
620
|
-
);
|
|
621
|
-
} catch (error) {
|
|
622
|
-
internalAbort.abort();
|
|
623
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
624
|
-
debugLogger2.debug("Failed to download qwen-code-action workflows:", error);
|
|
625
|
-
throw new SetupGithubError(
|
|
626
|
-
"github_workflow_download_failed",
|
|
627
|
-
`Unable to download qwen-code-action workflows from GitHub. ${message}`,
|
|
628
|
-
502
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
__name(downloadWorkflows, "downloadWorkflows");
|
|
633
|
-
async function readResponseTextWithLimit(response, sourcePath) {
|
|
634
|
-
const contentLength = response.headers.get("content-length");
|
|
635
|
-
if (contentLength !== null) {
|
|
636
|
-
const parsedLength = Number(contentLength);
|
|
637
|
-
if (Number.isFinite(parsedLength) && parsedLength > MAX_WORKFLOW_DOWNLOAD_BYTES) {
|
|
638
|
-
throw new Error(
|
|
639
|
-
`${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
|
|
640
|
-
);
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
if (!response.body) return "";
|
|
644
|
-
const reader = response.body.getReader();
|
|
645
|
-
const chunks = [];
|
|
646
|
-
let totalBytes = 0;
|
|
647
|
-
try {
|
|
648
|
-
while (true) {
|
|
649
|
-
const { done, value } = await reader.read();
|
|
650
|
-
if (done) break;
|
|
651
|
-
if (!value) continue;
|
|
652
|
-
totalBytes += value.byteLength;
|
|
653
|
-
if (totalBytes > MAX_WORKFLOW_DOWNLOAD_BYTES) {
|
|
654
|
-
await reader.cancel().catch(() => {
|
|
655
|
-
});
|
|
656
|
-
throw new Error(
|
|
657
|
-
`${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
|
|
658
|
-
);
|
|
659
|
-
}
|
|
660
|
-
chunks.push(value);
|
|
661
|
-
}
|
|
662
|
-
} finally {
|
|
663
|
-
reader.releaseLock();
|
|
664
|
-
}
|
|
665
|
-
const body = new Uint8Array(totalBytes);
|
|
666
|
-
let offset = 0;
|
|
667
|
-
for (const chunk of chunks) {
|
|
668
|
-
body.set(chunk, offset);
|
|
669
|
-
offset += chunk.byteLength;
|
|
670
|
-
}
|
|
671
|
-
return new TextDecoder().decode(body);
|
|
672
|
-
}
|
|
673
|
-
__name(readResponseTextWithLimit, "readResponseTextWithLimit");
|
|
674
|
-
async function resolveSecretsUrl(cwd) {
|
|
675
|
-
try {
|
|
676
|
-
const repoInfo = await getGitHubRepoInfoAsync({ cwd });
|
|
677
|
-
return `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`;
|
|
678
|
-
} catch {
|
|
679
|
-
return void 0;
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
__name(resolveSecretsUrl, "resolveSecretsUrl");
|
|
683
|
-
async function realpathOrResolve(input) {
|
|
684
|
-
try {
|
|
685
|
-
return await fsp.realpath(input);
|
|
686
|
-
} catch {
|
|
687
|
-
return path.resolve(input);
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
__name(realpathOrResolve, "realpathOrResolve");
|
|
691
|
-
|
|
692
|
-
// packages/acp-bridge/src/transcript-replay.ts
|
|
693
|
-
init_esbuild_shims();
|
|
694
|
-
|
|
695
|
-
// packages/core/dist/src/goals/goal-wire.js
|
|
696
|
-
init_esbuild_shims();
|
|
697
|
-
|
|
698
|
-
// packages/core/dist/src/goals/goal-protocol.js
|
|
699
|
-
init_esbuild_shims();
|
|
700
|
-
var GOAL_STATE_VERSION = 2;
|
|
701
|
-
var GOAL_CHECKPOINT_CLAIM_LIMIT = 32;
|
|
702
|
-
var GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS = 2e3;
|
|
703
|
-
var GOAL_CHECKPOINT_CLAIM_MAX_BYTES = 16e3;
|
|
704
|
-
var GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT = 32;
|
|
705
|
-
function isGoalEvidenceProofKind(value) {
|
|
706
|
-
return value === "user_input" || value === "delivered_output" || value === "external_fact";
|
|
707
|
-
}
|
|
708
|
-
__name(isGoalEvidenceProofKind, "isGoalEvidenceProofKind");
|
|
709
|
-
|
|
710
|
-
// packages/core/dist/src/goals/goal-reducer.js
|
|
711
|
-
init_esbuild_shims();
|
|
712
|
-
var MAX_BLOCKED_AUDIT_COUNT = 3;
|
|
713
|
-
function parseGoalStateRecordPayloadV2(value) {
|
|
714
|
-
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
715
|
-
"v",
|
|
716
|
-
"cause",
|
|
717
|
-
"snapshot",
|
|
718
|
-
"checkpointPending",
|
|
719
|
-
"blockedAudit"
|
|
720
|
-
]) || value["v"] !== GOAL_STATE_VERSION || !isGoalStateCause(value["cause"]) || !isCheckpointPending(value["checkpointPending"]) || !isBlockedAudit(value["blockedAudit"])) {
|
|
721
|
-
return void 0;
|
|
722
|
-
}
|
|
723
|
-
const parsedSnapshot = parseGoalSnapshotV2(value["snapshot"]);
|
|
724
|
-
if (parsedSnapshot?.activity !== "idle")
|
|
725
|
-
return void 0;
|
|
726
|
-
const checkpointPending = value["checkpointPending"];
|
|
727
|
-
if (checkpointPending && (parsedSnapshot.goal?.status !== "active" || checkpointPending.permit.goalId !== parsedSnapshot.goal.goalId || checkpointPending.permit.revision !== parsedSnapshot.goal.revision || checkpointPending.recordUuid === parsedSnapshot.goal.evidenceCursor.recordId || value["cause"] !== "turn_finished" && value["cause"] !== "verifier_reject")) {
|
|
728
|
-
return void 0;
|
|
729
|
-
}
|
|
730
|
-
return {
|
|
731
|
-
v: GOAL_STATE_VERSION,
|
|
732
|
-
cause: value["cause"],
|
|
733
|
-
snapshot: parsedSnapshot,
|
|
734
|
-
...checkpointPending ? { checkpointPending: structuredClone(checkpointPending) } : {},
|
|
735
|
-
...value["blockedAudit"] ? { blockedAudit: structuredClone(value["blockedAudit"]) } : {}
|
|
736
|
-
};
|
|
737
|
-
}
|
|
738
|
-
__name(parseGoalStateRecordPayloadV2, "parseGoalStateRecordPayloadV2");
|
|
739
|
-
function parseGoalSnapshotV2(value) {
|
|
740
|
-
if (!isRecord(value) || !hasOnlyKeys(value, ["v", "goal", "activity"]) || value["v"] !== GOAL_STATE_VERSION || !isGoalActivity(value["activity"])) {
|
|
741
|
-
return void 0;
|
|
742
|
-
}
|
|
743
|
-
if (value["goal"] === null) {
|
|
744
|
-
return {
|
|
745
|
-
v: GOAL_STATE_VERSION,
|
|
746
|
-
goal: null,
|
|
747
|
-
activity: value["activity"]
|
|
748
|
-
};
|
|
749
|
-
}
|
|
750
|
-
const goal = parseGoalRecord(value["goal"]);
|
|
751
|
-
return goal ? { v: GOAL_STATE_VERSION, goal, activity: value["activity"] } : void 0;
|
|
752
|
-
}
|
|
753
|
-
__name(parseGoalSnapshotV2, "parseGoalSnapshotV2");
|
|
754
|
-
function parseGoalStateCause(value) {
|
|
755
|
-
return isGoalStateCause(value) ? value : void 0;
|
|
756
|
-
}
|
|
757
|
-
__name(parseGoalStateCause, "parseGoalStateCause");
|
|
758
|
-
function copyCursor(cursor) {
|
|
759
|
-
return { recordId: cursor.recordId };
|
|
760
|
-
}
|
|
761
|
-
__name(copyCursor, "copyCursor");
|
|
762
|
-
function parseGoalRecord(value) {
|
|
763
|
-
if (!isRecord(value) || !hasOnlyKeys(value, [
|
|
764
|
-
"goalId",
|
|
765
|
-
"revision",
|
|
766
|
-
"objective",
|
|
767
|
-
"status",
|
|
768
|
-
"evidenceCursor",
|
|
769
|
-
"turnCount",
|
|
770
|
-
"activeTimeMs",
|
|
771
|
-
"createdAt",
|
|
772
|
-
"updatedAt",
|
|
773
|
-
"evidenceCheckpoint",
|
|
774
|
-
"lastReason"
|
|
775
|
-
]) || typeof value["goalId"] !== "string" || !value["goalId"] || !isNonNegativeInteger(value["revision"]) || value["revision"] === 0 || typeof value["objective"] !== "string" || !value["objective"].trim() || !isGoalStatus(value["status"]) || !isTranscriptCursor(value["evidenceCursor"]) || !isNonNegativeInteger(value["turnCount"]) || !isNonNegativeNumber(value["activeTimeMs"]) || !isFiniteNumber(value["createdAt"]) || !isFiniteNumber(value["updatedAt"]) || !isGoalEvidenceCheckpoint(value["evidenceCheckpoint"]) || value["lastReason"] !== void 0 && typeof value["lastReason"] !== "string") {
|
|
776
|
-
return void 0;
|
|
777
|
-
}
|
|
778
|
-
if (value["evidenceCheckpoint"] && value["evidenceCursor"].recordId !== value["evidenceCheckpoint"].checkpointId) {
|
|
779
|
-
return void 0;
|
|
780
|
-
}
|
|
781
|
-
return {
|
|
782
|
-
goalId: value["goalId"],
|
|
783
|
-
revision: value["revision"],
|
|
784
|
-
objective: value["objective"],
|
|
785
|
-
status: value["status"],
|
|
786
|
-
evidenceCursor: copyCursor(value["evidenceCursor"]),
|
|
787
|
-
turnCount: value["turnCount"],
|
|
788
|
-
activeTimeMs: value["activeTimeMs"],
|
|
789
|
-
createdAt: value["createdAt"],
|
|
790
|
-
updatedAt: value["updatedAt"],
|
|
791
|
-
...value["evidenceCheckpoint"] === void 0 ? {} : {
|
|
792
|
-
evidenceCheckpoint: structuredClone(value["evidenceCheckpoint"])
|
|
793
|
-
},
|
|
794
|
-
...value["lastReason"] === void 0 ? {} : { lastReason: value["lastReason"] }
|
|
795
|
-
};
|
|
796
|
-
}
|
|
797
|
-
__name(parseGoalRecord, "parseGoalRecord");
|
|
798
|
-
function isTranscriptCursor(value) {
|
|
799
|
-
return isRecord(value) && hasOnlyKeys(value, ["recordId"]) && (typeof value["recordId"] === "string" || value["recordId"] === null);
|
|
800
|
-
}
|
|
801
|
-
__name(isTranscriptCursor, "isTranscriptCursor");
|
|
802
|
-
function isGoalStatus(value) {
|
|
803
|
-
return value === "active" || value === "paused" || value === "blocked" || value === "usage_limited" || value === "complete";
|
|
804
|
-
}
|
|
805
|
-
__name(isGoalStatus, "isGoalStatus");
|
|
806
|
-
function isGoalActivity(value) {
|
|
807
|
-
return value === "idle" || value === "running" || value === "verifying";
|
|
808
|
-
}
|
|
809
|
-
__name(isGoalActivity, "isGoalActivity");
|
|
810
|
-
function isGoalStateCause(value) {
|
|
811
|
-
return value === "create" || value === "replace" || value === "edit" || value === "pause" || value === "resume" || value === "turn_finished" || value === "checkpoint" || value === "verifier_accept" || value === "verifier_reject" || value === "complete" || value === "blocked" || value === "usage_limited" || value === "clear" || value === "migrated";
|
|
812
|
-
}
|
|
813
|
-
__name(isGoalStateCause, "isGoalStateCause");
|
|
814
|
-
function isGoalEvidenceCheckpoint(value) {
|
|
815
|
-
if (value === void 0)
|
|
816
|
-
return true;
|
|
817
|
-
if (!isRecord(value) || !hasOnlyKeys(value, ["checkpointId", "createdAt", "claims"]) || typeof value["checkpointId"] !== "string" || value["checkpointId"].length === 0 || !isFiniteNumber(value["createdAt"]) || !Array.isArray(value["claims"]) || value["claims"].length === 0 || value["claims"].length > GOAL_CHECKPOINT_CLAIM_LIMIT) {
|
|
818
|
-
return false;
|
|
819
|
-
}
|
|
820
|
-
let checkpointBytes = 0;
|
|
821
|
-
for (const [index, claim] of value["claims"].entries()) {
|
|
822
|
-
if (!isRecord(claim) || !hasOnlyKeys(claim, ["id", "proofKind", "claim", "sourceRefs"]) || claim["id"] !== `${value["checkpointId"]}:${index + 1}` || !isGoalEvidenceProofKind(claim["proofKind"]) || typeof claim["claim"] !== "string" || claim["claim"].trim().length === 0 || [...claim["claim"]].length > GOAL_CHECKPOINT_CLAIM_MAX_CHARACTERS || !Array.isArray(claim["sourceRefs"]) || claim["sourceRefs"].length === 0 || claim["sourceRefs"].length > GOAL_CHECKPOINT_SOURCE_REFERENCE_LIMIT || new Set(claim["sourceRefs"]).size !== claim["sourceRefs"].length || claim["sourceRefs"].some((reference) => typeof reference !== "string" || reference.length === 0)) {
|
|
823
|
-
return false;
|
|
824
|
-
}
|
|
825
|
-
checkpointBytes += new TextEncoder().encode(claim["claim"]).byteLength;
|
|
826
|
-
if (checkpointBytes > GOAL_CHECKPOINT_CLAIM_MAX_BYTES)
|
|
827
|
-
return false;
|
|
828
|
-
}
|
|
829
|
-
return true;
|
|
181
|
+
return true;
|
|
830
182
|
}
|
|
831
183
|
__name(isGoalEvidenceCheckpoint, "isGoalEvidenceCheckpoint");
|
|
832
184
|
function isCheckpointPending(value) {
|
|
@@ -864,7 +216,7 @@ __name(isFiniteNumber, "isFiniteNumber");
|
|
|
864
216
|
|
|
865
217
|
// packages/core/dist/src/goals/goal-legacy-projection.js
|
|
866
218
|
init_esbuild_shims();
|
|
867
|
-
function
|
|
219
|
+
function projectGoalStateToLegacy2(payload, previousGoal = null) {
|
|
868
220
|
const snapshotGoal = payload.snapshot.goal;
|
|
869
221
|
const displayGoal = snapshotGoal ?? previousGoal;
|
|
870
222
|
const kind = legacyStatusKind(payload);
|
|
@@ -895,7 +247,7 @@ function projectGoalStateToLegacy(payload, previousGoal = null) {
|
|
|
895
247
|
} : null
|
|
896
248
|
};
|
|
897
249
|
}
|
|
898
|
-
__name(
|
|
250
|
+
__name(projectGoalStateToLegacy2, "projectGoalStateToLegacy");
|
|
899
251
|
function isGoalCheckpointBookkeepingTransition(previous, next) {
|
|
900
252
|
const previousGoal = previous?.goal;
|
|
901
253
|
const nextGoal = next.goal;
|
|
@@ -920,12 +272,16 @@ function legacyStatusKind(payload) {
|
|
|
920
272
|
case "replace":
|
|
921
273
|
case "edit":
|
|
922
274
|
case "resume":
|
|
923
|
-
case "migrated":
|
|
924
275
|
return "set";
|
|
925
276
|
case "complete":
|
|
926
277
|
return "achieved";
|
|
927
278
|
case "clear":
|
|
928
279
|
return "cleared";
|
|
280
|
+
// A migrated goal is always persisted `paused` (`createMigratedGoalState`),
|
|
281
|
+
// and nothing drives a paused goal. Projecting it as `set` would re-assert
|
|
282
|
+
// "active" to every client that derives the live goal from the newest card,
|
|
283
|
+
// leaving a phantom running goal behind a resumed pre-v2 transcript.
|
|
284
|
+
case "migrated":
|
|
929
285
|
case "pause":
|
|
930
286
|
return "paused";
|
|
931
287
|
case "blocked":
|
|
@@ -954,6 +310,12 @@ var TRANSCRIPT_GOAL_STATUS_KINDS = /* @__PURE__ */ new Set([
|
|
|
954
310
|
"cleared",
|
|
955
311
|
"failed",
|
|
956
312
|
"aborted",
|
|
313
|
+
// A paused goal is not running, and dropping the card here is not neutral:
|
|
314
|
+
// the replay stream is what feeds the goal renderer, so the older `set` card
|
|
315
|
+
// stays newest and every surface keeps claiming autonomous work is under way.
|
|
316
|
+
// Kept in step with `GOAL_STATUS_KINDS`, which the daemon-side reader
|
|
317
|
+
// (`parseGoalStatusItem`) validates the same on-disk cards against.
|
|
318
|
+
"paused",
|
|
957
319
|
"checking"
|
|
958
320
|
]);
|
|
959
321
|
function isObjectRecord(value) {
|
|
@@ -1023,12 +385,12 @@ function createTranscriptImageUpdate(options) {
|
|
|
1023
385
|
__name(createTranscriptImageUpdate, "createTranscriptImageUpdate");
|
|
1024
386
|
function createTranscriptUsageUpdate(usageMetadata, options = {}) {
|
|
1025
387
|
const usage = {
|
|
1026
|
-
inputTokens:
|
|
1027
|
-
outputTokens:
|
|
1028
|
-
totalTokens:
|
|
1029
|
-
...
|
|
1030
|
-
...
|
|
1031
|
-
cachedReadTokens:
|
|
388
|
+
inputTokens: finiteNumber(usageMetadata.promptTokenCount) ?? 0,
|
|
389
|
+
outputTokens: finiteNumber(usageMetadata.candidatesTokenCount) ?? 0,
|
|
390
|
+
totalTokens: finiteNumber(usageMetadata.totalTokenCount) ?? 0,
|
|
391
|
+
...finiteNumber(usageMetadata.thoughtsTokenCount) !== void 0 ? { thoughtTokens: finiteNumber(usageMetadata.thoughtsTokenCount) } : {},
|
|
392
|
+
...finiteNumber(usageMetadata.cachedContentTokenCount) !== void 0 ? {
|
|
393
|
+
cachedReadTokens: finiteNumber(usageMetadata.cachedContentTokenCount)
|
|
1032
394
|
} : {}
|
|
1033
395
|
};
|
|
1034
396
|
const meta = buildUpdateMeta({
|
|
@@ -1480,7 +842,7 @@ var DefaultTranscriptReplayMachine = class {
|
|
|
1480
842
|
previous: this.goalState,
|
|
1481
843
|
next: payload2.snapshot
|
|
1482
844
|
});
|
|
1483
|
-
const projection =
|
|
845
|
+
const projection = projectGoalStateToLegacy2(
|
|
1484
846
|
payload2,
|
|
1485
847
|
this.goalState?.goal ?? null
|
|
1486
848
|
);
|
|
@@ -1541,9 +903,9 @@ var DefaultTranscriptReplayMachine = class {
|
|
|
1541
903
|
}
|
|
1542
904
|
}
|
|
1543
905
|
addUsage(metadata) {
|
|
1544
|
-
this.usage.promptTokens +=
|
|
1545
|
-
this.usage.candidateTokens +=
|
|
1546
|
-
this.usage.cachedTokens +=
|
|
906
|
+
this.usage.promptTokens += finiteNumber(metadata["promptTokenCount"]) ?? 0;
|
|
907
|
+
this.usage.candidateTokens += finiteNumber(metadata["candidatesTokenCount"]) ?? 0;
|
|
908
|
+
this.usage.cachedTokens += finiteNumber(metadata["cachedContentTokenCount"]) ?? 0;
|
|
1547
909
|
}
|
|
1548
910
|
correlateResultCallId(toolName, recordId) {
|
|
1549
911
|
const candidates = [...this.pendingToolCalls.values()].filter(
|
|
@@ -1638,9 +1000,9 @@ function parseTranscriptGoalStatus(value) {
|
|
|
1638
1000
|
if (typeof kind !== "string" || !TRANSCRIPT_GOAL_STATUS_KINDS.has(kind) || typeof condition !== "string") {
|
|
1639
1001
|
return void 0;
|
|
1640
1002
|
}
|
|
1641
|
-
const iterations =
|
|
1642
|
-
const setAt =
|
|
1643
|
-
const durationMs =
|
|
1003
|
+
const iterations = finiteNumber(value["iterations"]);
|
|
1004
|
+
const setAt = finiteNumber(value["setAt"]);
|
|
1005
|
+
const durationMs = finiteNumber(value["durationMs"]);
|
|
1644
1006
|
const lastReason = typeof value["lastReason"] === "string" ? value["lastReason"] : void 0;
|
|
1645
1007
|
return {
|
|
1646
1008
|
kind,
|
|
@@ -1705,7 +1067,7 @@ function parseInitialState(value, onDiagnostic) {
|
|
|
1705
1067
|
);
|
|
1706
1068
|
const rawUsage = value.cumulativeUsage;
|
|
1707
1069
|
const usage = isObjectRecord(rawUsage) ? rawUsage : {};
|
|
1708
|
-
const validUsage =
|
|
1070
|
+
const validUsage = finiteNumber(usage["promptTokens"]) !== void 0 && finiteNumber(usage["cachedTokens"]) !== void 0 && finiteNumber(usage["candidateTokens"]) !== void 0 && finiteNumber(usage["apiTimeMs"]) !== void 0;
|
|
1709
1071
|
if (!validUsage) {
|
|
1710
1072
|
onDiagnostic?.({
|
|
1711
1073
|
code: "invalid_replay_state",
|
|
@@ -1715,7 +1077,7 @@ function parseInitialState(value, onDiagnostic) {
|
|
|
1715
1077
|
});
|
|
1716
1078
|
}
|
|
1717
1079
|
const rawGoalState = value["goalState"];
|
|
1718
|
-
const goalState = rawGoalState === void 0 ? void 0 :
|
|
1080
|
+
const goalState = rawGoalState === void 0 ? void 0 : parseGoalSnapshotV22(rawGoalState);
|
|
1719
1081
|
if (rawGoalState !== void 0 && !goalState) {
|
|
1720
1082
|
onDiagnostic?.({
|
|
1721
1083
|
code: "invalid_replay_state",
|
|
@@ -1725,7 +1087,7 @@ function parseInitialState(value, onDiagnostic) {
|
|
|
1725
1087
|
});
|
|
1726
1088
|
}
|
|
1727
1089
|
const rawGoalCause = value["goalCause"];
|
|
1728
|
-
const goalCause = rawGoalCause === void 0 ? void 0 :
|
|
1090
|
+
const goalCause = rawGoalCause === void 0 ? void 0 : parseGoalStateCause2(rawGoalCause);
|
|
1729
1091
|
if (rawGoalCause !== void 0 && !goalCause) {
|
|
1730
1092
|
onDiagnostic?.({
|
|
1731
1093
|
code: "invalid_replay_state",
|
|
@@ -1918,18 +1280,18 @@ function usageFromTaskExecution(display) {
|
|
|
1918
1280
|
const summary = isObjectRecord(display["executionSummary"]) ? display["executionSummary"] : void 0;
|
|
1919
1281
|
if (!summary) return {};
|
|
1920
1282
|
return {
|
|
1921
|
-
...
|
|
1922
|
-
...
|
|
1923
|
-
...
|
|
1924
|
-
...
|
|
1925
|
-
...
|
|
1283
|
+
...finiteNumber(summary["inputTokens"]) !== void 0 ? { promptTokenCount: summary["inputTokens"] } : {},
|
|
1284
|
+
...finiteNumber(summary["outputTokens"]) !== void 0 ? { candidatesTokenCount: summary["outputTokens"] } : {},
|
|
1285
|
+
...finiteNumber(summary["thoughtTokens"]) !== void 0 ? { thoughtsTokenCount: summary["thoughtTokens"] } : {},
|
|
1286
|
+
...finiteNumber(summary["cachedTokens"]) !== void 0 ? { cachedContentTokenCount: summary["cachedTokens"] } : {},
|
|
1287
|
+
...finiteNumber(summary["totalTokens"]) !== void 0 ? { totalTokenCount: summary["totalTokens"] } : {}
|
|
1926
1288
|
};
|
|
1927
1289
|
}
|
|
1928
1290
|
__name(usageFromTaskExecution, "usageFromTaskExecution");
|
|
1929
|
-
function
|
|
1291
|
+
function finiteNumber(value) {
|
|
1930
1292
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1931
1293
|
}
|
|
1932
|
-
__name(
|
|
1294
|
+
__name(finiteNumber, "finiteNumber");
|
|
1933
1295
|
function extractErrorMessage(value) {
|
|
1934
1296
|
if (value instanceof Error) return value.message;
|
|
1935
1297
|
if (!isObjectRecord(value)) return void 0;
|
|
@@ -1941,15 +1303,8 @@ function dedupeStrings(values) {
|
|
|
1941
1303
|
}
|
|
1942
1304
|
__name(dedupeStrings, "dedupeStrings");
|
|
1943
1305
|
|
|
1944
|
-
// packages/cli/src/acp-integration/session/emitters/
|
|
1945
|
-
init_esbuild_shims();
|
|
1946
|
-
|
|
1947
|
-
// packages/cli/src/acp-integration/session/types.ts
|
|
1306
|
+
// packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
|
|
1948
1307
|
init_esbuild_shims();
|
|
1949
|
-
function hasFullSessionContext(context) {
|
|
1950
|
-
return "config" in context;
|
|
1951
|
-
}
|
|
1952
|
-
__name(hasFullSessionContext, "hasFullSessionContext");
|
|
1953
1308
|
|
|
1954
1309
|
// packages/cli/src/acp-integration/session/emitters/base-emitter.ts
|
|
1955
1310
|
init_esbuild_shims();
|
|
@@ -1993,724 +1348,985 @@ var BaseEmitter = class {
|
|
|
1993
1348
|
}
|
|
1994
1349
|
};
|
|
1995
1350
|
|
|
1996
|
-
// packages/cli/src/acp-integration/session/emitters/
|
|
1997
|
-
|
|
1351
|
+
// packages/cli/src/acp-integration/session/emitters/PlanEmitter.ts
|
|
1352
|
+
init_esbuild_shims();
|
|
1353
|
+
var PlanEmitter = class extends BaseEmitter {
|
|
1354
|
+
static {
|
|
1355
|
+
__name(this, "PlanEmitter");
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Emits a plan update with the given todo items.
|
|
1359
|
+
*
|
|
1360
|
+
* @param plan - Plan identity and todo items to send as plan entries
|
|
1361
|
+
*/
|
|
1362
|
+
async emitPlan(plan, sourceCallId) {
|
|
1363
|
+
const cumulative = this.ctx.cumulativeUsage;
|
|
1364
|
+
await this.sendUpdate(
|
|
1365
|
+
createTranscriptPlanUpdate(plan.todos, cumulative, {
|
|
1366
|
+
planToolCallId: sourceCallId,
|
|
1367
|
+
todoPlanId: plan.planId
|
|
1368
|
+
})
|
|
1369
|
+
);
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* Extracts todos from tool result display or args.
|
|
1373
|
+
* Tries multiple sources in priority order:
|
|
1374
|
+
* 1. Result display object with type 'todo_list'
|
|
1375
|
+
* 2. Result display as JSON string
|
|
1376
|
+
* 3. Args with 'todos' array when no result display is available
|
|
1377
|
+
*
|
|
1378
|
+
* @param resultDisplay - The tool result display (object, string, or undefined)
|
|
1379
|
+
* @param args - The tool call arguments (fallback source)
|
|
1380
|
+
* @returns Plan snapshot if found, null otherwise
|
|
1381
|
+
*/
|
|
1382
|
+
extractPlan(resultDisplay, args) {
|
|
1383
|
+
const plan = extractTranscriptTodoPlan(resultDisplay, args);
|
|
1384
|
+
if (!plan) return null;
|
|
1385
|
+
return {
|
|
1386
|
+
...plan.planId ? { planId: plan.planId } : {},
|
|
1387
|
+
todos: plan.todos.map((todo, index) => ({
|
|
1388
|
+
id: todo.id ?? String(index),
|
|
1389
|
+
content: todo.content,
|
|
1390
|
+
status: todo.status,
|
|
1391
|
+
...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
|
|
1392
|
+
}))
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1396
|
+
|
|
1397
|
+
// packages/cli/src/acp-integration/session/types.ts
|
|
1398
|
+
init_esbuild_shims();
|
|
1399
|
+
function hasFullSessionContext(context) {
|
|
1400
|
+
return "config" in context;
|
|
1401
|
+
}
|
|
1402
|
+
__name(hasFullSessionContext, "hasFullSessionContext");
|
|
1403
|
+
|
|
1404
|
+
// packages/cli/src/acp-integration/session/emitters/tool-call-emitter.ts
|
|
1405
|
+
var KIND_MAP = {
|
|
1406
|
+
["read" /* Read */]: "read",
|
|
1407
|
+
["edit" /* Edit */]: "edit",
|
|
1408
|
+
["delete" /* Delete */]: "delete",
|
|
1409
|
+
["move" /* Move */]: "move",
|
|
1410
|
+
["search" /* Search */]: "search",
|
|
1411
|
+
["execute" /* Execute */]: "execute",
|
|
1412
|
+
["think" /* Think */]: "think",
|
|
1413
|
+
["fetch" /* Fetch */]: "fetch",
|
|
1414
|
+
// ACP defines no 'agent' ToolKind (verified through @agentclientprotocol/sdk
|
|
1415
|
+
// 0.25.1). The daemon's ClientSideConnection Zod-validates every session/update
|
|
1416
|
+
// and session/request_permission from the `qwen --acp` child before fanning out
|
|
1417
|
+
// to SSE clients, so emitting 'agent' is rejected at that hop and the frame is
|
|
1418
|
+
// dropped. Map the internal Kind.Agent to 'other' on the wire to stay
|
|
1419
|
+
// protocol-valid; dedicated agent UI is delivered out-of-band (via _meta.toolName)
|
|
1420
|
+
// in a follow-up rather than via a kind the protocol can't carry.
|
|
1421
|
+
["agent" /* Agent */]: "other",
|
|
1422
|
+
["other" /* Other */]: "other"
|
|
1423
|
+
};
|
|
1424
|
+
var ToolCallEmitter = class _ToolCallEmitter extends BaseEmitter {
|
|
1998
1425
|
static {
|
|
1999
|
-
__name(this, "
|
|
1426
|
+
__name(this, "ToolCallEmitter");
|
|
1427
|
+
}
|
|
1428
|
+
planEmitter;
|
|
1429
|
+
preparedCallIds = /* @__PURE__ */ new Set();
|
|
1430
|
+
constructor(ctx) {
|
|
1431
|
+
super(ctx);
|
|
1432
|
+
this.planEmitter = new PlanEmitter(ctx);
|
|
2000
1433
|
}
|
|
2001
1434
|
/**
|
|
2002
|
-
* Emits a
|
|
2003
|
-
* This informs the client that Stop hooks have been executed multiple times.
|
|
1435
|
+
* Emits a tool call start event.
|
|
2004
1436
|
*
|
|
2005
|
-
* @param
|
|
2006
|
-
* @
|
|
2007
|
-
* @param stopHookCount - Number of Stop hooks that were executed
|
|
1437
|
+
* @param params - Tool call start parameters
|
|
1438
|
+
* @returns true if event was emitted, false if skipped (e.g., TodoWriteTool)
|
|
2008
1439
|
*/
|
|
2009
|
-
async
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
1440
|
+
async emitStart(params) {
|
|
1441
|
+
if (this.isTodoWriteTool(params.toolName)) {
|
|
1442
|
+
return false;
|
|
1443
|
+
}
|
|
1444
|
+
if (params.phase === "preparing" && this.preparedCallIds.has(params.callId)) {
|
|
1445
|
+
return false;
|
|
1446
|
+
}
|
|
1447
|
+
const { title, locations, kind } = this.resolveToolMetadata(
|
|
1448
|
+
params.toolName,
|
|
1449
|
+
params.args
|
|
1450
|
+
);
|
|
1451
|
+
const provenance = _ToolCallEmitter.resolveToolProvenance(
|
|
1452
|
+
params.toolName,
|
|
1453
|
+
params.subagentMeta
|
|
1454
|
+
);
|
|
1455
|
+
const updatesPreparedCall = params.phase !== "preparing" && this.preparedCallIds.delete(params.callId);
|
|
1456
|
+
await this.sendUpdate(
|
|
1457
|
+
createTranscriptToolCallStartUpdate({
|
|
1458
|
+
toolName: params.toolName,
|
|
1459
|
+
callId: params.callId,
|
|
1460
|
+
status: params.status || "pending",
|
|
1461
|
+
args: params.args,
|
|
1462
|
+
metadata: { title, locations, kind },
|
|
1463
|
+
timestamp: params.timestamp,
|
|
1464
|
+
asUpdate: updatesPreparedCall,
|
|
1465
|
+
extra: {
|
|
1466
|
+
...params.phase ? { phase: params.phase } : {},
|
|
1467
|
+
...params.subagentMeta,
|
|
1468
|
+
provenance: provenance.provenance,
|
|
1469
|
+
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
2027
1470
|
}
|
|
2028
|
-
}
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
content: { type: "text", text: "" },
|
|
2035
|
-
_meta: {
|
|
2036
|
-
goalTerminal: event
|
|
2037
|
-
}
|
|
2038
|
-
});
|
|
1471
|
+
})
|
|
1472
|
+
);
|
|
1473
|
+
if (params.phase === "preparing") {
|
|
1474
|
+
this.preparedCallIds.add(params.callId);
|
|
1475
|
+
}
|
|
1476
|
+
return true;
|
|
2039
1477
|
}
|
|
2040
|
-
|
|
1478
|
+
/**
|
|
1479
|
+
* Emits a terminal frame when a prepared tool call is discarded before
|
|
1480
|
+
* execution. TodoWrite remains represented exclusively by plan updates.
|
|
1481
|
+
*
|
|
1482
|
+
* @param callId - ID of the prepared tool call
|
|
1483
|
+
* @param toolName - Name of the prepared tool
|
|
1484
|
+
*/
|
|
1485
|
+
async emitPreparationDiscarded(callId, toolName) {
|
|
1486
|
+
if (this.isTodoWriteTool(toolName)) return;
|
|
1487
|
+
this.preparedCallIds.delete(callId);
|
|
1488
|
+
const provenance = _ToolCallEmitter.resolveToolProvenance(toolName);
|
|
2041
1489
|
await this.sendUpdate({
|
|
2042
|
-
sessionUpdate: "
|
|
2043
|
-
|
|
1490
|
+
sessionUpdate: "tool_call_update",
|
|
1491
|
+
toolCallId: callId,
|
|
1492
|
+
status: "failed",
|
|
1493
|
+
content: [],
|
|
2044
1494
|
_meta: {
|
|
2045
|
-
|
|
1495
|
+
toolName,
|
|
1496
|
+
phase: "preparing",
|
|
1497
|
+
preparationDiscarded: true,
|
|
1498
|
+
provenance: provenance.provenance,
|
|
1499
|
+
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
2046
1500
|
}
|
|
2047
1501
|
});
|
|
2048
1502
|
}
|
|
2049
1503
|
/**
|
|
2050
|
-
* Emits a
|
|
1504
|
+
* Emits a tool call result event.
|
|
1505
|
+
* Handles TodoWriteTool specially by routing to plan updates.
|
|
2051
1506
|
*
|
|
2052
|
-
* @param
|
|
2053
|
-
* @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
|
|
1507
|
+
* @param params - Tool call result parameters
|
|
2054
1508
|
*/
|
|
2055
|
-
async
|
|
1509
|
+
async emitResult(params) {
|
|
1510
|
+
if (this.isTodoWriteTool(params.toolName)) {
|
|
1511
|
+
if (params.subagentMeta) return;
|
|
1512
|
+
if (!params.success) return;
|
|
1513
|
+
const plan = this.planEmitter.extractPlan(
|
|
1514
|
+
params.resultDisplay,
|
|
1515
|
+
params.args
|
|
1516
|
+
);
|
|
1517
|
+
if (plan && (plan.todos.length > 0 || params.args && Array.isArray(params.args["todos"]))) {
|
|
1518
|
+
await this.planEmitter.emitPlan(plan, params.callId);
|
|
1519
|
+
}
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
this.preparedCallIds.delete(params.callId);
|
|
1523
|
+
const provenance = _ToolCallEmitter.resolveToolProvenance(
|
|
1524
|
+
params.toolName,
|
|
1525
|
+
params.subagentMeta
|
|
1526
|
+
);
|
|
2056
1527
|
await this.sendUpdate(
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
1528
|
+
createTranscriptToolCallResultUpdate({
|
|
1529
|
+
toolName: params.toolName,
|
|
1530
|
+
callId: params.callId,
|
|
1531
|
+
success: params.success,
|
|
1532
|
+
message: params.message,
|
|
1533
|
+
resultDisplay: params.resultDisplay,
|
|
1534
|
+
errorMessage: params.error?.message,
|
|
1535
|
+
artifacts: params.artifacts,
|
|
1536
|
+
contentPrefix: buildToolResultContentPrefix(params.resultDisplay),
|
|
1537
|
+
timestamp: params.timestamp,
|
|
1538
|
+
extra: {
|
|
1539
|
+
...params.subagentMeta,
|
|
1540
|
+
provenance: provenance.provenance,
|
|
1541
|
+
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
1542
|
+
}
|
|
2062
1543
|
})
|
|
2063
1544
|
);
|
|
2064
1545
|
}
|
|
2065
1546
|
/**
|
|
2066
|
-
* Emits
|
|
1547
|
+
* Emits a tool call error event.
|
|
1548
|
+
* Use this for explicit error handling when not using emitResult.
|
|
2067
1549
|
*
|
|
2068
|
-
* @param
|
|
2069
|
-
* @param
|
|
1550
|
+
* @param callId - The tool call ID
|
|
1551
|
+
* @param toolName - The tool name
|
|
1552
|
+
* @param error - The error that occurred
|
|
1553
|
+
* @param subagentMeta - Optional subagent metadata
|
|
2070
1554
|
*/
|
|
2071
|
-
async
|
|
1555
|
+
async emitError(callId, toolName, error, subagentMeta) {
|
|
1556
|
+
this.preparedCallIds.delete(callId);
|
|
1557
|
+
const provenance = _ToolCallEmitter.resolveToolProvenance(
|
|
1558
|
+
toolName,
|
|
1559
|
+
subagentMeta
|
|
1560
|
+
);
|
|
2072
1561
|
await this.sendUpdate(
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
1562
|
+
createTranscriptToolCallResultUpdate({
|
|
1563
|
+
toolName,
|
|
1564
|
+
callId,
|
|
1565
|
+
success: false,
|
|
1566
|
+
errorMessage: error.message,
|
|
1567
|
+
extra: {
|
|
1568
|
+
...subagentMeta,
|
|
1569
|
+
provenance: provenance.provenance,
|
|
1570
|
+
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
1571
|
+
}
|
|
2079
1572
|
})
|
|
2080
1573
|
);
|
|
2081
1574
|
}
|
|
2082
1575
|
/**
|
|
2083
|
-
*
|
|
1576
|
+
* Resolve a tool's provenance for UI dispatch on tool_call events.
|
|
1577
|
+
* The SDK reads `_meta.
|
|
1578
|
+
* provenance` + `_meta.serverId` to render builtin / MCP-server-badge /
|
|
1579
|
+
* subagent-block differently. Without this stamping, the SDK falls
|
|
1580
|
+
* back to string-matching the toolName which can't reliably
|
|
1581
|
+
* distinguish builtin from subagent.
|
|
1582
|
+
*
|
|
1583
|
+
* Resolution rules:
|
|
1584
|
+
* - `subagentMeta` present → `'subagent'` (a Task tool / Codex
|
|
1585
|
+
* subagent / etc. wrapping its own tool calls)
|
|
1586
|
+
* - toolName matches `mcp__<server>__<tool>` → `'mcp'` with
|
|
1587
|
+
* `serverId: <server>`. Naming convention from
|
|
1588
|
+
* `packages/core/src/tools/mcp-tool.ts` in the
|
|
1589
|
+
* `@qwen-code/qwen-code-core` package — mirrors the SDK's same
|
|
1590
|
+
* heuristic fallback so SDK consumers stay consistent with
|
|
1591
|
+
* daemon classification.
|
|
1592
|
+
* - everything else → `'builtin'`
|
|
1593
|
+
*
|
|
1594
|
+
* Static + pure so it can be unit-tested without an emitter
|
|
1595
|
+
* instance. Exported via `ToolCallEmitter.resolveToolProvenance`.
|
|
1596
|
+
*/
|
|
1597
|
+
static resolveToolProvenance(toolName, subagentMeta) {
|
|
1598
|
+
if (subagentMeta !== void 0) {
|
|
1599
|
+
return { provenance: "subagent" };
|
|
1600
|
+
}
|
|
1601
|
+
if (toolName.startsWith("mcp__")) {
|
|
1602
|
+
const parts = toolName.split("__");
|
|
1603
|
+
if (parts.length >= 3 && parts[1] && parts[1].length > 0) {
|
|
1604
|
+
return { provenance: "mcp", serverId: parts[1] };
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
return { provenance: "builtin" };
|
|
1608
|
+
}
|
|
1609
|
+
// ==================== Public Utilities ====================
|
|
1610
|
+
/**
|
|
1611
|
+
* Checks if a tool name is the TodoWriteTool.
|
|
1612
|
+
* Exposed for external use in components that need to check this.
|
|
1613
|
+
*/
|
|
1614
|
+
isTodoWriteTool(toolName) {
|
|
1615
|
+
return toolName === ToolNames.TODO_WRITE;
|
|
1616
|
+
}
|
|
1617
|
+
/**
|
|
1618
|
+
* Checks if a tool name is the ExitPlanModeTool.
|
|
1619
|
+
*/
|
|
1620
|
+
isExitPlanModeTool(toolName) {
|
|
1621
|
+
return toolName === ToolNames.EXIT_PLAN_MODE;
|
|
1622
|
+
}
|
|
1623
|
+
/**
|
|
1624
|
+
* Checks if a tool name is the EnterPlanModeTool.
|
|
1625
|
+
*/
|
|
1626
|
+
isEnterPlanModeTool(toolName) {
|
|
1627
|
+
return toolName === ToolNames.ENTER_PLAN_MODE;
|
|
1628
|
+
}
|
|
1629
|
+
/**
|
|
1630
|
+
* Resolves tool metadata from the registry.
|
|
1631
|
+
* Falls back to defaults if tool not found or build fails.
|
|
2084
1632
|
*
|
|
2085
|
-
* @param
|
|
2086
|
-
* @param
|
|
1633
|
+
* @param toolName - Name of the tool
|
|
1634
|
+
* @param args - Tool call arguments (used to build invocation)
|
|
2087
1635
|
*/
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
}
|
|
2096
|
-
|
|
1636
|
+
resolveToolMetadata(toolName, args) {
|
|
1637
|
+
if (!hasFullSessionContext(this.ctx)) {
|
|
1638
|
+
const description = typeof args?.["description"] === "string" ? args["description"].trim() : "";
|
|
1639
|
+
return {
|
|
1640
|
+
title: description ? `${toolName}: ${description}` : toolName,
|
|
1641
|
+
locations: [],
|
|
1642
|
+
kind: "other"
|
|
1643
|
+
};
|
|
1644
|
+
}
|
|
1645
|
+
const toolRegistry = this.ctx.config.getToolRegistry();
|
|
1646
|
+
const tool = toolRegistry.getTool(toolName);
|
|
1647
|
+
let title = tool?.displayName ?? toolName;
|
|
1648
|
+
let locations = [];
|
|
1649
|
+
let kind = "other";
|
|
1650
|
+
if (tool && args) {
|
|
1651
|
+
try {
|
|
1652
|
+
const invocation = tool.build(args);
|
|
1653
|
+
title = `${title}: ${invocation.getDescription()}`;
|
|
1654
|
+
locations = invocation.toolLocations().map((loc) => ({
|
|
1655
|
+
path: loc.path,
|
|
1656
|
+
line: loc.line ?? null
|
|
1657
|
+
}));
|
|
1658
|
+
kind = this.mapToolKind(tool.kind, toolName);
|
|
1659
|
+
} catch {
|
|
1660
|
+
if (typeof args["description"] === "string") {
|
|
1661
|
+
title = `${title}: ${args["description"]}`;
|
|
1662
|
+
}
|
|
1663
|
+
if (tool.kind) {
|
|
1664
|
+
kind = this.mapToolKind(tool.kind, toolName);
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
}
|
|
1668
|
+
return { title, locations, kind };
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Maps core Tool Kind enum to ACP ToolKind string literals.
|
|
1672
|
+
*
|
|
1673
|
+
* @param kind - The core Kind enum value
|
|
1674
|
+
* @param toolName - Optional tool name to handle special cases like exit_plan_mode
|
|
1675
|
+
*/
|
|
1676
|
+
mapToolKind(kind, toolName) {
|
|
1677
|
+
if (toolName && (this.isExitPlanModeTool(toolName) || this.isEnterPlanModeTool(toolName))) {
|
|
1678
|
+
return "switch_mode";
|
|
1679
|
+
}
|
|
1680
|
+
return KIND_MAP[kind] ?? "other";
|
|
1681
|
+
}
|
|
1682
|
+
};
|
|
1683
|
+
function buildToolResultContentPrefix(resultDisplay) {
|
|
1684
|
+
if (!isVisionBridgeNoticeDisplay(resultDisplay)) return [];
|
|
1685
|
+
return [
|
|
1686
|
+
{
|
|
1687
|
+
type: "content",
|
|
1688
|
+
content: {
|
|
1689
|
+
type: "text",
|
|
1690
|
+
text: sanitizeTerminalText(
|
|
1691
|
+
formatVisionBridgeNoticeDisplay(resultDisplay)
|
|
1692
|
+
)
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
];
|
|
1696
|
+
}
|
|
1697
|
+
__name(buildToolResultContentPrefix, "buildToolResultContentPrefix");
|
|
1698
|
+
|
|
1699
|
+
// packages/cli/src/acp-integration/session/history-replayer.ts
|
|
1700
|
+
var HistoryReplayer = class {
|
|
1701
|
+
constructor(ctx) {
|
|
1702
|
+
this.ctx = ctx;
|
|
1703
|
+
this.toolCallEmitter = new ToolCallEmitter(ctx);
|
|
1704
|
+
this.machine = this.createMachine();
|
|
2097
1705
|
}
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
1706
|
+
static {
|
|
1707
|
+
__name(this, "HistoryReplayer");
|
|
1708
|
+
}
|
|
1709
|
+
toolCallEmitter;
|
|
1710
|
+
machine;
|
|
1711
|
+
async replay(records, gaps, options = {}) {
|
|
1712
|
+
try {
|
|
1713
|
+
if (options.goalBootstrap) {
|
|
1714
|
+
const update = {
|
|
1715
|
+
sessionUpdate: "agent_message_chunk",
|
|
1716
|
+
content: { type: "text", text: "" },
|
|
1717
|
+
_meta: {
|
|
1718
|
+
...options.goalBootstrap.goalState ? { goalState: options.goalBootstrap.goalState } : {},
|
|
1719
|
+
goalStatus: options.goalBootstrap.goalStatus
|
|
1720
|
+
}
|
|
1721
|
+
};
|
|
1722
|
+
await this.sendUpdate(update);
|
|
2106
1723
|
}
|
|
1724
|
+
await this.replayPage(records, {
|
|
1725
|
+
finalizeDangling: true,
|
|
1726
|
+
gaps,
|
|
1727
|
+
...options.initialGoalState ? { goalState: options.initialGoalState } : {},
|
|
1728
|
+
...options.initialGoalCause ? { goalCause: options.initialGoalCause } : {}
|
|
1729
|
+
});
|
|
1730
|
+
} finally {
|
|
1731
|
+
this.setActiveRecordId(null);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
static v2GoalBootstrap(rawGoalState, rawGoalCause) {
|
|
1735
|
+
const goalState = parseGoalSnapshotV2(rawGoalState);
|
|
1736
|
+
const goalCause = parseGoalStateCause(rawGoalCause);
|
|
1737
|
+
if (!goalState?.goal || goalState.goal.status !== "active" || !goalCause) {
|
|
1738
|
+
return void 0;
|
|
1739
|
+
}
|
|
1740
|
+
const projection = projectGoalStateToLegacy({
|
|
1741
|
+
v: 2,
|
|
1742
|
+
cause: goalCause,
|
|
1743
|
+
snapshot: goalState
|
|
2107
1744
|
});
|
|
1745
|
+
const { type: _type, kind, ...goalStatus } = projection.goalStatus;
|
|
1746
|
+
if (kind !== "set" && kind !== "checking") {
|
|
1747
|
+
return void 0;
|
|
1748
|
+
}
|
|
1749
|
+
return { goalStatus: { ...goalStatus, kind }, goalState };
|
|
2108
1750
|
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
cumulative.cachedTokens = addFinite(
|
|
2125
|
-
cumulative.cachedTokens,
|
|
2126
|
-
usageMetadata.cachedContentTokenCount
|
|
2127
|
-
);
|
|
2128
|
-
cumulative.apiTimeMs = addFinite(cumulative.apiTimeMs, durationMs);
|
|
2129
|
-
}
|
|
2130
|
-
let activityMeta = {};
|
|
2131
|
-
if (typeof durationMs === "number") {
|
|
2132
|
-
const activity = apiActivityTracker.drain();
|
|
2133
|
-
activityMeta = {
|
|
2134
|
-
...activity.errors > 0 ? { apiErrors: activity.errors } : {},
|
|
2135
|
-
...activity.retries > 0 ? { apiRetries: activity.retries } : {}
|
|
2136
|
-
};
|
|
1751
|
+
async replayPage(records, options = {}) {
|
|
1752
|
+
this.machine = this.createMachine(options);
|
|
1753
|
+
let replayError;
|
|
1754
|
+
try {
|
|
1755
|
+
for (const record of records) {
|
|
1756
|
+
for (const emission of this.machine.project(record)) {
|
|
1757
|
+
this.setActiveRecordId(
|
|
1758
|
+
emission.sourceRecordId,
|
|
1759
|
+
emission.sourceTimestamp
|
|
1760
|
+
);
|
|
1761
|
+
await this.sendUpdate(emission.update);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
} catch (error) {
|
|
1765
|
+
replayError = error;
|
|
2137
1766
|
}
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
1767
|
+
let danglingError;
|
|
1768
|
+
if (options.finalizeDangling === true) {
|
|
1769
|
+
for (const emission of this.machine.finalize()) {
|
|
1770
|
+
this.setActiveRecordId(
|
|
1771
|
+
emission.sourceRecordId,
|
|
1772
|
+
emission.sourceTimestamp
|
|
1773
|
+
);
|
|
1774
|
+
try {
|
|
1775
|
+
await this.sendUpdate(emission.update);
|
|
1776
|
+
} catch (error) {
|
|
1777
|
+
danglingError ??= error;
|
|
2145
1778
|
}
|
|
2146
|
-
}
|
|
2147
|
-
);
|
|
2148
|
-
if (!Number.isFinite(durationMs) || subagentMeta || !hasFullSessionContext(this.ctx)) {
|
|
2149
|
-
return;
|
|
1779
|
+
}
|
|
2150
1780
|
}
|
|
2151
|
-
const
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
1781
|
+
const replay = this.machine.snapshot();
|
|
1782
|
+
this.copyCumulativeUsage(replay);
|
|
1783
|
+
const state = {
|
|
1784
|
+
pendingToolCalls: options.finalizeDangling === true ? [] : replay.pendingToolCalls.map(toLegacyPendingToolCall),
|
|
1785
|
+
replay
|
|
1786
|
+
};
|
|
1787
|
+
this.setActiveRecordId(null);
|
|
1788
|
+
if (replayError && danglingError) {
|
|
1789
|
+
throw new AggregateError(
|
|
1790
|
+
[replayError, danglingError],
|
|
1791
|
+
"Replay and dangling-cleanup both failed"
|
|
1792
|
+
);
|
|
2155
1793
|
}
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
size
|
|
2160
|
-
});
|
|
1794
|
+
if (replayError) throw replayError;
|
|
1795
|
+
if (danglingError) throw danglingError;
|
|
1796
|
+
return state;
|
|
2161
1797
|
}
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
* This is the unified method that handles all message types.
|
|
2165
|
-
*
|
|
2166
|
-
* @param text - The message text content
|
|
2167
|
-
* @param role - Whether this is a user or assistant message
|
|
2168
|
-
* @param isThought - Whether this is an assistant thought (only applies to assistant role)
|
|
2169
|
-
* @param timestamp - Optional server-side timestamp (ISO string or ms) for message ordering
|
|
2170
|
-
*/
|
|
2171
|
-
async emitMessage(text, role, isThought = false, timestamp, subagentMeta) {
|
|
2172
|
-
if (role === "user") {
|
|
2173
|
-
return this.emitUserMessage(text, timestamp);
|
|
2174
|
-
}
|
|
2175
|
-
return isThought ? this.emitAgentThought(text, timestamp, subagentMeta) : this.emitAgentMessage(text, timestamp, subagentMeta);
|
|
1798
|
+
getPendingToolCalls() {
|
|
1799
|
+
return this.machine.snapshot().pendingToolCalls.map(toLegacyPendingToolCall);
|
|
2176
1800
|
}
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
// packages/cli/src/acp-integration/session/emitters/PlanEmitter.ts
|
|
2180
|
-
init_esbuild_shims();
|
|
2181
|
-
var PlanEmitter = class extends BaseEmitter {
|
|
2182
|
-
static {
|
|
2183
|
-
__name(this, "PlanEmitter");
|
|
1801
|
+
getReplayState() {
|
|
1802
|
+
return this.machine.snapshot();
|
|
2184
1803
|
}
|
|
2185
|
-
|
|
2186
|
-
* Emits a plan update with the given todo items.
|
|
2187
|
-
*
|
|
2188
|
-
* @param plan - Plan identity and todo items to send as plan entries
|
|
2189
|
-
*/
|
|
2190
|
-
async emitPlan(plan, sourceCallId) {
|
|
1804
|
+
createMachine(options = {}) {
|
|
2191
1805
|
const cumulative = this.ctx.cumulativeUsage;
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
1806
|
+
const initialState = {
|
|
1807
|
+
v: 1,
|
|
1808
|
+
pendingToolCalls: (options.pendingToolCalls ?? []).map(
|
|
1809
|
+
toPendingTranscriptToolCall
|
|
1810
|
+
),
|
|
1811
|
+
cumulativeUsage: cumulative ? { ...cumulative } : {
|
|
1812
|
+
promptTokens: 0,
|
|
1813
|
+
cachedTokens: 0,
|
|
1814
|
+
candidateTokens: 0,
|
|
1815
|
+
apiTimeMs: 0
|
|
1816
|
+
},
|
|
1817
|
+
...options.goalState ? { goalState: options.goalState } : {},
|
|
1818
|
+
...options.goalCause ? { goalCause: options.goalCause } : {}
|
|
1819
|
+
};
|
|
1820
|
+
return createTranscriptReplayMachine({
|
|
1821
|
+
initialState,
|
|
1822
|
+
gaps: options.gaps,
|
|
1823
|
+
presentation: this.presentationAdapter(),
|
|
1824
|
+
onDiagnostic: /* @__PURE__ */ __name((diagnostic) => {
|
|
1825
|
+
if (diagnostic.code === "malformed_part" && diagnostic.path === "systemPayload.outputHistoryItems.goalStatus.condition") {
|
|
1826
|
+
writeStderrLineSafe(`qwen: ${diagnostic.message}`);
|
|
1827
|
+
}
|
|
1828
|
+
}, "onDiagnostic")
|
|
1829
|
+
});
|
|
2198
1830
|
}
|
|
2199
|
-
|
|
2200
|
-
* Extracts todos from tool result display or args.
|
|
2201
|
-
* Tries multiple sources in priority order:
|
|
2202
|
-
* 1. Result display object with type 'todo_list'
|
|
2203
|
-
* 2. Result display as JSON string
|
|
2204
|
-
* 3. Args with 'todos' array when no result display is available
|
|
2205
|
-
*
|
|
2206
|
-
* @param resultDisplay - The tool result display (object, string, or undefined)
|
|
2207
|
-
* @param args - The tool call arguments (fallback source)
|
|
2208
|
-
* @returns Plan snapshot if found, null otherwise
|
|
2209
|
-
*/
|
|
2210
|
-
extractPlan(resultDisplay, args) {
|
|
2211
|
-
const plan = extractTranscriptTodoPlan(resultDisplay, args);
|
|
2212
|
-
if (!plan) return null;
|
|
1831
|
+
presentationAdapter() {
|
|
2213
1832
|
return {
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
content: todo.content,
|
|
2218
|
-
status: todo.status,
|
|
2219
|
-
...todo.blockedBy ? { blockedBy: [...todo.blockedBy] } : {}
|
|
2220
|
-
}))
|
|
1833
|
+
resolveToolMetadata: /* @__PURE__ */ __name((toolName, args) => this.toolCallEmitter.resolveToolMetadata(toolName, { ...args }), "resolveToolMetadata"),
|
|
1834
|
+
formatHistoryGap: /* @__PURE__ */ __name((gap) => formatHistoryGapNotice(gap), "formatHistoryGap"),
|
|
1835
|
+
buildToolResultContentPrefix
|
|
2221
1836
|
};
|
|
2222
1837
|
}
|
|
1838
|
+
async sendUpdate(update) {
|
|
1839
|
+
if (this.ctx.messageRewriter) {
|
|
1840
|
+
await this.ctx.messageRewriter.interceptUpdate(update);
|
|
1841
|
+
return;
|
|
1842
|
+
}
|
|
1843
|
+
await this.ctx.sendUpdate(update);
|
|
1844
|
+
}
|
|
1845
|
+
copyCumulativeUsage(state) {
|
|
1846
|
+
const cumulative = this.ctx.cumulativeUsage;
|
|
1847
|
+
if (!cumulative) return;
|
|
1848
|
+
cumulative.promptTokens = state.cumulativeUsage.promptTokens;
|
|
1849
|
+
cumulative.cachedTokens = state.cumulativeUsage.cachedTokens;
|
|
1850
|
+
cumulative.candidateTokens = state.cumulativeUsage.candidateTokens;
|
|
1851
|
+
cumulative.apiTimeMs = state.cumulativeUsage.apiTimeMs;
|
|
1852
|
+
}
|
|
1853
|
+
setActiveRecordId(recordId, timestamp) {
|
|
1854
|
+
this.ctx.setActiveRecordId?.(recordId, timestamp);
|
|
1855
|
+
}
|
|
2223
1856
|
};
|
|
1857
|
+
function toPendingTranscriptToolCall(pending) {
|
|
1858
|
+
return {
|
|
1859
|
+
callId: pending.callId,
|
|
1860
|
+
toolName: pending.toolName,
|
|
1861
|
+
sourceRecordId: pending.recordId,
|
|
1862
|
+
...pending.timestamp ? { sourceTimestamp: pending.timestamp } : {}
|
|
1863
|
+
};
|
|
1864
|
+
}
|
|
1865
|
+
__name(toPendingTranscriptToolCall, "toPendingTranscriptToolCall");
|
|
1866
|
+
function toLegacyPendingToolCall(pending) {
|
|
1867
|
+
return {
|
|
1868
|
+
callId: pending.callId,
|
|
1869
|
+
toolName: pending.toolName,
|
|
1870
|
+
recordId: pending.sourceRecordId,
|
|
1871
|
+
...pending.sourceTimestamp ? { timestamp: pending.sourceTimestamp } : {}
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
__name(toLegacyPendingToolCall, "toLegacyPendingToolCall");
|
|
2224
1875
|
|
|
2225
|
-
// packages/cli/src/
|
|
1876
|
+
// packages/cli/src/services/setup-github.ts
|
|
2226
1877
|
init_esbuild_shims();
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
static {
|
|
2248
|
-
__name(this, "ToolCallEmitter");
|
|
2249
|
-
}
|
|
2250
|
-
planEmitter;
|
|
2251
|
-
preparedCallIds = /* @__PURE__ */ new Set();
|
|
2252
|
-
constructor(ctx) {
|
|
2253
|
-
super(ctx);
|
|
2254
|
-
this.planEmitter = new PlanEmitter(ctx);
|
|
2255
|
-
}
|
|
2256
|
-
/**
|
|
2257
|
-
* Emits a tool call start event.
|
|
2258
|
-
*
|
|
2259
|
-
* @param params - Tool call start parameters
|
|
2260
|
-
* @returns true if event was emitted, false if skipped (e.g., TodoWriteTool)
|
|
2261
|
-
*/
|
|
2262
|
-
async emitStart(params) {
|
|
2263
|
-
if (this.isTodoWriteTool(params.toolName)) {
|
|
2264
|
-
return false;
|
|
2265
|
-
}
|
|
2266
|
-
if (params.phase === "preparing" && this.preparedCallIds.has(params.callId)) {
|
|
2267
|
-
return false;
|
|
2268
|
-
}
|
|
2269
|
-
const { title, locations, kind } = this.resolveToolMetadata(
|
|
2270
|
-
params.toolName,
|
|
2271
|
-
params.args
|
|
2272
|
-
);
|
|
2273
|
-
const provenance = _ToolCallEmitter.resolveToolProvenance(
|
|
2274
|
-
params.toolName,
|
|
2275
|
-
params.subagentMeta
|
|
2276
|
-
);
|
|
2277
|
-
const updatesPreparedCall = params.phase !== "preparing" && this.preparedCallIds.delete(params.callId);
|
|
2278
|
-
await this.sendUpdate(
|
|
2279
|
-
createTranscriptToolCallStartUpdate({
|
|
2280
|
-
toolName: params.toolName,
|
|
2281
|
-
callId: params.callId,
|
|
2282
|
-
status: params.status || "pending",
|
|
2283
|
-
args: params.args,
|
|
2284
|
-
metadata: { title, locations, kind },
|
|
2285
|
-
timestamp: params.timestamp,
|
|
2286
|
-
asUpdate: updatesPreparedCall,
|
|
2287
|
-
extra: {
|
|
2288
|
-
...params.phase ? { phase: params.phase } : {},
|
|
2289
|
-
...params.subagentMeta,
|
|
2290
|
-
provenance: provenance.provenance,
|
|
2291
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
1878
|
+
import { promises as fsp } from "node:fs";
|
|
1879
|
+
import * as path from "node:path";
|
|
1880
|
+
|
|
1881
|
+
// packages/cli/src/utils/gitUtils.ts
|
|
1882
|
+
init_esbuild_shims();
|
|
1883
|
+
import * as childProcess from "node:child_process";
|
|
1884
|
+
var debugLogger = createDebugLogger("GIT");
|
|
1885
|
+
async function runGit(args, opts = {}) {
|
|
1886
|
+
return await new Promise((resolve2, reject) => {
|
|
1887
|
+
childProcess.execFile(
|
|
1888
|
+
"git",
|
|
1889
|
+
args,
|
|
1890
|
+
{
|
|
1891
|
+
encoding: "utf-8",
|
|
1892
|
+
...opts.cwd ? { cwd: opts.cwd } : {}
|
|
1893
|
+
},
|
|
1894
|
+
(err, stdout) => {
|
|
1895
|
+
if (err) {
|
|
1896
|
+
reject(err);
|
|
1897
|
+
return;
|
|
2292
1898
|
}
|
|
2293
|
-
|
|
1899
|
+
resolve2(String(stdout ?? "").trim());
|
|
1900
|
+
}
|
|
2294
1901
|
);
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
__name(runGit, "runGit");
|
|
1905
|
+
var isGitHubRepositoryAsync = /* @__PURE__ */ __name(async (opts = {}) => {
|
|
1906
|
+
try {
|
|
1907
|
+
const remotes = await runGit(["remote", "-v"], opts);
|
|
1908
|
+
return remotes.split("\n").some((line) => {
|
|
1909
|
+
const remoteUrl = line.trim().split(/\s+/)[1];
|
|
1910
|
+
return remoteUrl ? isGitHubRemoteUrl(remoteUrl) : false;
|
|
1911
|
+
});
|
|
1912
|
+
} catch (_error) {
|
|
1913
|
+
debugLogger.debug(`Failed to get git remote:`, _error);
|
|
1914
|
+
return false;
|
|
1915
|
+
}
|
|
1916
|
+
}, "isGitHubRepositoryAsync");
|
|
1917
|
+
function isGitHubRemoteUrl(remoteUrl) {
|
|
1918
|
+
if (remoteUrl.startsWith("git@github.com:")) {
|
|
2298
1919
|
return true;
|
|
2299
1920
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
* execution. TodoWrite remains represented exclusively by plan updates.
|
|
2303
|
-
*
|
|
2304
|
-
* @param callId - ID of the prepared tool call
|
|
2305
|
-
* @param toolName - Name of the prepared tool
|
|
2306
|
-
*/
|
|
2307
|
-
async emitPreparationDiscarded(callId, toolName) {
|
|
2308
|
-
if (this.isTodoWriteTool(toolName)) return;
|
|
2309
|
-
this.preparedCallIds.delete(callId);
|
|
2310
|
-
const provenance = _ToolCallEmitter.resolveToolProvenance(toolName);
|
|
2311
|
-
await this.sendUpdate({
|
|
2312
|
-
sessionUpdate: "tool_call_update",
|
|
2313
|
-
toolCallId: callId,
|
|
2314
|
-
status: "failed",
|
|
2315
|
-
content: [],
|
|
2316
|
-
_meta: {
|
|
2317
|
-
toolName,
|
|
2318
|
-
phase: "preparing",
|
|
2319
|
-
preparationDiscarded: true,
|
|
2320
|
-
provenance: provenance.provenance,
|
|
2321
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
2322
|
-
}
|
|
2323
|
-
});
|
|
1921
|
+
if (remoteUrl.startsWith("git@")) {
|
|
1922
|
+
return false;
|
|
2324
1923
|
}
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
1924
|
+
try {
|
|
1925
|
+
return new URL(remoteUrl).hostname === "github.com";
|
|
1926
|
+
} catch {
|
|
1927
|
+
return false;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
__name(isGitHubRemoteUrl, "isGitHubRemoteUrl");
|
|
1931
|
+
var getGitRepoRootAsync = /* @__PURE__ */ __name(async (opts = {}) => {
|
|
1932
|
+
const gitRepoRoot = await runGit(["rev-parse", "--show-toplevel"], opts);
|
|
1933
|
+
if (!gitRepoRoot) {
|
|
1934
|
+
throw new Error(`Git repo returned empty value`);
|
|
1935
|
+
}
|
|
1936
|
+
return gitRepoRoot;
|
|
1937
|
+
}, "getGitRepoRootAsync");
|
|
1938
|
+
var getLatestGitHubRelease = /* @__PURE__ */ __name(async (proxy) => {
|
|
1939
|
+
try {
|
|
1940
|
+
const controller = new AbortController();
|
|
1941
|
+
const endpoint = `https://api.github.com/repos/QwenLM/qwen-code-action/releases/latest`;
|
|
1942
|
+
const dispatcher = proxy ? new (await loadUndici()).ProxyAgent(proxy) : void 0;
|
|
1943
|
+
const response = await fetch(endpoint, {
|
|
1944
|
+
method: "GET",
|
|
1945
|
+
headers: {
|
|
1946
|
+
Accept: "application/vnd.github+json",
|
|
1947
|
+
"Content-Type": "application/json",
|
|
1948
|
+
"X-GitHub-Api-Version": "2022-11-28"
|
|
1949
|
+
},
|
|
1950
|
+
dispatcher,
|
|
1951
|
+
signal: AbortSignal.any([AbortSignal.timeout(3e4), controller.signal])
|
|
1952
|
+
});
|
|
1953
|
+
if (!response.ok) {
|
|
1954
|
+
throw new Error(
|
|
1955
|
+
`Invalid response code: ${response.status} - ${response.statusText}`
|
|
2338
1956
|
);
|
|
2339
|
-
if (plan && (plan.todos.length > 0 || params.args && Array.isArray(params.args["todos"]))) {
|
|
2340
|
-
await this.planEmitter.emitPlan(plan, params.callId);
|
|
2341
|
-
}
|
|
2342
|
-
return;
|
|
2343
1957
|
}
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
1958
|
+
const releaseTag = (await response.json()).tag_name;
|
|
1959
|
+
if (!releaseTag) {
|
|
1960
|
+
throw new Error(`Response did not include tag_name field`);
|
|
1961
|
+
}
|
|
1962
|
+
return releaseTag;
|
|
1963
|
+
} catch (_error) {
|
|
1964
|
+
debugLogger.debug(
|
|
1965
|
+
`Failed to determine latest qwen-code-action release:`,
|
|
1966
|
+
_error
|
|
2348
1967
|
);
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
toolName: params.toolName,
|
|
2352
|
-
callId: params.callId,
|
|
2353
|
-
success: params.success,
|
|
2354
|
-
message: params.message,
|
|
2355
|
-
resultDisplay: params.resultDisplay,
|
|
2356
|
-
errorMessage: params.error?.message,
|
|
2357
|
-
artifacts: params.artifacts,
|
|
2358
|
-
contentPrefix: buildToolResultContentPrefix(params.resultDisplay),
|
|
2359
|
-
timestamp: params.timestamp,
|
|
2360
|
-
extra: {
|
|
2361
|
-
...params.subagentMeta,
|
|
2362
|
-
provenance: provenance.provenance,
|
|
2363
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
2364
|
-
}
|
|
2365
|
-
})
|
|
1968
|
+
throw new Error(
|
|
1969
|
+
`Unable to determine the latest qwen-code-action release on GitHub.`
|
|
2366
1970
|
);
|
|
2367
1971
|
}
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
);
|
|
2383
|
-
await this.sendUpdate(
|
|
2384
|
-
createTranscriptToolCallResultUpdate({
|
|
2385
|
-
toolName,
|
|
2386
|
-
callId,
|
|
2387
|
-
success: false,
|
|
2388
|
-
errorMessage: error.message,
|
|
2389
|
-
extra: {
|
|
2390
|
-
...subagentMeta,
|
|
2391
|
-
provenance: provenance.provenance,
|
|
2392
|
-
...provenance.serverId ? { serverId: provenance.serverId } : {}
|
|
2393
|
-
}
|
|
2394
|
-
})
|
|
1972
|
+
}, "getLatestGitHubRelease");
|
|
1973
|
+
async function getGitHubRepoInfoAsync(opts = {}) {
|
|
1974
|
+
return parseGitHubRepoInfo(
|
|
1975
|
+
await runGit(["remote", "get-url", "origin"], opts)
|
|
1976
|
+
);
|
|
1977
|
+
}
|
|
1978
|
+
__name(getGitHubRepoInfoAsync, "getGitHubRepoInfoAsync");
|
|
1979
|
+
function parseGitHubRepoInfo(remoteUrl) {
|
|
1980
|
+
let urlToParse = remoteUrl;
|
|
1981
|
+
if (remoteUrl.startsWith("git@github.com:")) {
|
|
1982
|
+
urlToParse = remoteUrl.replace("git@github.com:", "");
|
|
1983
|
+
} else if (remoteUrl.startsWith("git@")) {
|
|
1984
|
+
throw new Error(
|
|
1985
|
+
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
2395
1986
|
);
|
|
2396
1987
|
}
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
*
|
|
2405
|
-
* Resolution rules:
|
|
2406
|
-
* - `subagentMeta` present → `'subagent'` (a Task tool / Codex
|
|
2407
|
-
* subagent / etc. wrapping its own tool calls)
|
|
2408
|
-
* - toolName matches `mcp__<server>__<tool>` → `'mcp'` with
|
|
2409
|
-
* `serverId: <server>`. Naming convention from
|
|
2410
|
-
* `packages/core/src/tools/mcp-tool.ts` in the
|
|
2411
|
-
* `@qwen-code/qwen-code-core` package — mirrors the SDK's same
|
|
2412
|
-
* heuristic fallback so SDK consumers stay consistent with
|
|
2413
|
-
* daemon classification.
|
|
2414
|
-
* - everything else → `'builtin'`
|
|
2415
|
-
*
|
|
2416
|
-
* Static + pure so it can be unit-tested without an emitter
|
|
2417
|
-
* instance. Exported via `ToolCallEmitter.resolveToolProvenance`.
|
|
2418
|
-
*/
|
|
2419
|
-
static resolveToolProvenance(toolName, subagentMeta) {
|
|
2420
|
-
if (subagentMeta !== void 0) {
|
|
2421
|
-
return { provenance: "subagent" };
|
|
2422
|
-
}
|
|
2423
|
-
if (toolName.startsWith("mcp__")) {
|
|
2424
|
-
const parts = toolName.split("__");
|
|
2425
|
-
if (parts.length >= 3 && parts[1] && parts[1].length > 0) {
|
|
2426
|
-
return { provenance: "mcp", serverId: parts[1] };
|
|
2427
|
-
}
|
|
2428
|
-
}
|
|
2429
|
-
return { provenance: "builtin" };
|
|
2430
|
-
}
|
|
2431
|
-
// ==================== Public Utilities ====================
|
|
2432
|
-
/**
|
|
2433
|
-
* Checks if a tool name is the TodoWriteTool.
|
|
2434
|
-
* Exposed for external use in components that need to check this.
|
|
2435
|
-
*/
|
|
2436
|
-
isTodoWriteTool(toolName) {
|
|
2437
|
-
return toolName === ToolNames.TODO_WRITE;
|
|
1988
|
+
let parsedUrl;
|
|
1989
|
+
try {
|
|
1990
|
+
parsedUrl = new URL(urlToParse, "https://github.com");
|
|
1991
|
+
} catch {
|
|
1992
|
+
throw new Error(
|
|
1993
|
+
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
1994
|
+
);
|
|
2438
1995
|
}
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
return toolName === ToolNames.EXIT_PLAN_MODE;
|
|
1996
|
+
if (parsedUrl.hostname !== "github.com") {
|
|
1997
|
+
throw new Error(
|
|
1998
|
+
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
1999
|
+
);
|
|
2444
2000
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2001
|
+
const parts = parsedUrl.pathname.split("/").filter((part) => part !== "");
|
|
2002
|
+
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
2003
|
+
throw new Error(
|
|
2004
|
+
`Owner & repo could not be extracted from remote URL: ${remoteUrl}`
|
|
2005
|
+
);
|
|
2450
2006
|
}
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
let title = tool?.displayName ?? toolName;
|
|
2470
|
-
let locations = [];
|
|
2471
|
-
let kind = "other";
|
|
2472
|
-
if (tool && args) {
|
|
2473
|
-
try {
|
|
2474
|
-
const invocation = tool.build(args);
|
|
2475
|
-
title = `${title}: ${invocation.getDescription()}`;
|
|
2476
|
-
locations = invocation.toolLocations().map((loc) => ({
|
|
2477
|
-
path: loc.path,
|
|
2478
|
-
line: loc.line ?? null
|
|
2479
|
-
}));
|
|
2480
|
-
kind = this.mapToolKind(tool.kind, toolName);
|
|
2481
|
-
} catch {
|
|
2482
|
-
if (typeof args["description"] === "string") {
|
|
2483
|
-
title = `${title}: ${args["description"]}`;
|
|
2484
|
-
}
|
|
2485
|
-
if (tool.kind) {
|
|
2486
|
-
kind = this.mapToolKind(tool.kind, toolName);
|
|
2487
|
-
}
|
|
2488
|
-
}
|
|
2489
|
-
}
|
|
2490
|
-
return { title, locations, kind };
|
|
2007
|
+
return { owner: parts[0], repo: parts[1].replace(/\.git$/, "") };
|
|
2008
|
+
}
|
|
2009
|
+
__name(parseGitHubRepoInfo, "parseGitHubRepoInfo");
|
|
2010
|
+
|
|
2011
|
+
// packages/cli/src/services/setup-github.ts
|
|
2012
|
+
var debugLogger2 = createDebugLogger("SETUP_GITHUB");
|
|
2013
|
+
var GITHUB_WORKFLOW_PATHS = [
|
|
2014
|
+
"qwen-dispatch/qwen-dispatch.yml",
|
|
2015
|
+
"qwen-assistant/qwen-invoke.yml",
|
|
2016
|
+
"issue-triage/qwen-triage.yml",
|
|
2017
|
+
"issue-triage/qwen-scheduled-triage.yml",
|
|
2018
|
+
"pr-review/qwen-review.yml"
|
|
2019
|
+
];
|
|
2020
|
+
var GITIGNORE_ENTRIES = [".qwen/", "gha-creds-*.json"];
|
|
2021
|
+
var MAX_WORKFLOW_DOWNLOAD_BYTES = 5 * 1024 * 1024;
|
|
2022
|
+
var SetupGithubError = class extends Error {
|
|
2023
|
+
static {
|
|
2024
|
+
__name(this, "SetupGithubError");
|
|
2491
2025
|
}
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2026
|
+
code;
|
|
2027
|
+
status;
|
|
2028
|
+
partial;
|
|
2029
|
+
partialResult;
|
|
2030
|
+
constructor(code, message, status, partialResult) {
|
|
2031
|
+
super(message);
|
|
2032
|
+
this.name = "SetupGithubError";
|
|
2033
|
+
this.code = code;
|
|
2034
|
+
this.status = status;
|
|
2035
|
+
this.partial = partialResult !== void 0;
|
|
2036
|
+
this.partialResult = partialResult;
|
|
2503
2037
|
}
|
|
2504
2038
|
};
|
|
2505
|
-
function
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2039
|
+
function isWorkspaceGenerationClosed(error) {
|
|
2040
|
+
return Boolean(
|
|
2041
|
+
error && typeof error === "object" && "code" in error && error.code === "workspace_generation_closed"
|
|
2042
|
+
);
|
|
2043
|
+
}
|
|
2044
|
+
__name(isWorkspaceGenerationClosed, "isWorkspaceGenerationClosed");
|
|
2045
|
+
var nodeFileOps = {
|
|
2046
|
+
assertCanWrite() {
|
|
2047
|
+
},
|
|
2048
|
+
async ensureWorkflowDirectory(gitRepoRoot) {
|
|
2049
|
+
await fsp.mkdir(path.join(gitRepoRoot, ".github", "workflows"), {
|
|
2050
|
+
recursive: true
|
|
2051
|
+
});
|
|
2052
|
+
},
|
|
2053
|
+
async writeTextFile(gitRepoRoot, relativePath, content) {
|
|
2054
|
+
const target = path.join(gitRepoRoot, relativePath);
|
|
2055
|
+
await fsp.writeFile(target, content, { mode: 420 });
|
|
2056
|
+
return { sizeBytes: Buffer.byteLength(content, "utf8") };
|
|
2057
|
+
},
|
|
2058
|
+
async readTextFile(gitRepoRoot, relativePath) {
|
|
2059
|
+
try {
|
|
2060
|
+
return await fsp.readFile(path.join(gitRepoRoot, relativePath), "utf8");
|
|
2061
|
+
} catch (error) {
|
|
2062
|
+
if (error.code === "ENOENT") {
|
|
2063
|
+
return void 0;
|
|
2515
2064
|
}
|
|
2065
|
+
throw error;
|
|
2516
2066
|
}
|
|
2517
|
-
|
|
2518
|
-
}
|
|
2519
|
-
__name(buildToolResultContentPrefix, "buildToolResultContentPrefix");
|
|
2520
|
-
|
|
2521
|
-
// packages/cli/src/acp-integration/session/history-replayer.ts
|
|
2522
|
-
init_esbuild_shims();
|
|
2523
|
-
var GOAL_NOT_RESTORED_REASON = {
|
|
2524
|
-
"untrusted-folder": "Goal not restored: this folder is not trusted, so its Stop hook cannot run.",
|
|
2525
|
-
"hooks-disabled": "Goal not restored: hooks are disabled for this session.",
|
|
2526
|
-
"no-hook-system": "Goal not restored: the hook system is unavailable."
|
|
2067
|
+
}
|
|
2527
2068
|
};
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2069
|
+
async function setupGithub(options = {}) {
|
|
2070
|
+
const cwd = options.cwd ?? process.cwd();
|
|
2071
|
+
const fileOps = options.fileOps ?? nodeFileOps;
|
|
2072
|
+
if (!await isGitHubRepositoryAsync({ cwd })) {
|
|
2073
|
+
throw new SetupGithubError(
|
|
2074
|
+
"github_repository_not_found",
|
|
2075
|
+
"Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
|
|
2076
|
+
400
|
|
2077
|
+
);
|
|
2535
2078
|
}
|
|
2536
|
-
|
|
2537
|
-
|
|
2079
|
+
let gitRepoRoot;
|
|
2080
|
+
try {
|
|
2081
|
+
gitRepoRoot = await getGitRepoRootAsync({ cwd });
|
|
2082
|
+
} catch (error) {
|
|
2083
|
+
debugLogger2.debug("Failed to get git repo root:", error);
|
|
2084
|
+
throw new SetupGithubError(
|
|
2085
|
+
"github_repository_not_found",
|
|
2086
|
+
"Unable to determine the GitHub repository. /setup-github must be run from a git repository.",
|
|
2087
|
+
400
|
|
2088
|
+
);
|
|
2538
2089
|
}
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
} finally {
|
|
2551
|
-
this.setActiveRecordId(null);
|
|
2090
|
+
if (options.workspaceRoot) {
|
|
2091
|
+
const [gitRootReal, workspaceReal] = await Promise.all([
|
|
2092
|
+
realpathOrResolve(gitRepoRoot),
|
|
2093
|
+
realpathOrResolve(options.workspaceRoot)
|
|
2094
|
+
]);
|
|
2095
|
+
if (gitRootReal !== workspaceReal) {
|
|
2096
|
+
throw new SetupGithubError(
|
|
2097
|
+
"github_git_root_mismatch",
|
|
2098
|
+
"The Git repository root must match the daemon workspace root.",
|
|
2099
|
+
400
|
|
2100
|
+
);
|
|
2552
2101
|
}
|
|
2553
2102
|
}
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2103
|
+
fileOps.assertCanWrite?.();
|
|
2104
|
+
let releaseTag;
|
|
2105
|
+
try {
|
|
2106
|
+
releaseTag = await getLatestGitHubRelease(options.proxy);
|
|
2107
|
+
} catch (error) {
|
|
2108
|
+
writeStderrLine(
|
|
2109
|
+
`qwen setup-github: failed to determine latest qwen-code-action release: ${error instanceof Error ? error.message : String(error)}`
|
|
2110
|
+
);
|
|
2111
|
+
debugLogger2.debug(
|
|
2112
|
+
"Failed to determine latest qwen-code-action release:",
|
|
2113
|
+
error
|
|
2114
|
+
);
|
|
2115
|
+
throw new SetupGithubError(
|
|
2116
|
+
"github_release_lookup_failed",
|
|
2117
|
+
"Unable to determine the latest qwen-code-action release on GitHub.",
|
|
2118
|
+
502
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
const readmeUrl = `https://github.com/QwenLM/qwen-code-action/blob/${releaseTag}/README.md#quick-start`;
|
|
2122
|
+
const secretsUrl = await resolveSecretsUrl(cwd);
|
|
2123
|
+
const downloads = await downloadWorkflows({
|
|
2124
|
+
releaseTag,
|
|
2125
|
+
proxy: options.proxy,
|
|
2126
|
+
abortSignal: options.abortSignal,
|
|
2127
|
+
fetchImpl: options.fetchImpl ?? fetch
|
|
2128
|
+
});
|
|
2129
|
+
const result = {
|
|
2130
|
+
kind: "github_setup",
|
|
2131
|
+
workspaceCwd: options.workspaceRoot ?? gitRepoRoot,
|
|
2132
|
+
gitRepoRoot,
|
|
2133
|
+
releaseTag,
|
|
2134
|
+
readmeUrl,
|
|
2135
|
+
...secretsUrl ? { secretsUrl } : {},
|
|
2136
|
+
workflows: [],
|
|
2137
|
+
gitignore: { path: ".gitignore", status: "skipped" },
|
|
2138
|
+
warnings: []
|
|
2139
|
+
};
|
|
2140
|
+
result.gitignore = await updateGitignore(gitRepoRoot, fileOps);
|
|
2141
|
+
if (result.gitignore.status === "failed") {
|
|
2142
|
+
result.warnings.push("Failed to update .gitignore.");
|
|
2143
|
+
}
|
|
2144
|
+
try {
|
|
2145
|
+
await fileOps.ensureWorkflowDirectory(gitRepoRoot);
|
|
2146
|
+
for (const workflow of downloads) {
|
|
2147
|
+
const relativePath = path.posix.join(
|
|
2148
|
+
".github",
|
|
2149
|
+
"workflows",
|
|
2150
|
+
path.posix.basename(workflow.sourcePath)
|
|
2151
|
+
);
|
|
2152
|
+
try {
|
|
2153
|
+
const write = await fileOps.writeTextFile(
|
|
2154
|
+
gitRepoRoot,
|
|
2155
|
+
relativePath,
|
|
2156
|
+
workflow.content
|
|
2157
|
+
);
|
|
2158
|
+
result.workflows.push({
|
|
2159
|
+
sourcePath: workflow.sourcePath,
|
|
2160
|
+
path: relativePath,
|
|
2161
|
+
status: "written",
|
|
2162
|
+
sizeBytes: write.sizeBytes
|
|
2163
|
+
});
|
|
2164
|
+
} catch (error) {
|
|
2165
|
+
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
2166
|
+
result.partial = true;
|
|
2167
|
+
result.workflows.push({
|
|
2168
|
+
sourcePath: workflow.sourcePath,
|
|
2169
|
+
path: relativePath,
|
|
2170
|
+
status: "failed",
|
|
2171
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2172
|
+
});
|
|
2173
|
+
throw new SetupGithubError(
|
|
2174
|
+
"github_workflow_write_failed",
|
|
2175
|
+
`Unable to write ${relativePath}.`,
|
|
2176
|
+
500,
|
|
2177
|
+
result
|
|
2576
2178
|
);
|
|
2577
|
-
try {
|
|
2578
|
-
await this.sendUpdate(emission.update);
|
|
2579
|
-
} catch (error) {
|
|
2580
|
-
danglingError ??= error;
|
|
2581
|
-
}
|
|
2582
2179
|
}
|
|
2583
2180
|
}
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
[replayError, danglingError],
|
|
2594
|
-
"Replay and dangling-cleanup both failed"
|
|
2595
|
-
);
|
|
2596
|
-
}
|
|
2597
|
-
if (replayError) throw replayError;
|
|
2598
|
-
if (danglingError) throw danglingError;
|
|
2599
|
-
return state;
|
|
2600
|
-
}
|
|
2601
|
-
getPendingToolCalls() {
|
|
2602
|
-
return this.machine.snapshot().pendingToolCalls.map(toLegacyPendingToolCall);
|
|
2603
|
-
}
|
|
2604
|
-
getReplayState() {
|
|
2605
|
-
return this.machine.snapshot();
|
|
2181
|
+
} catch (error) {
|
|
2182
|
+
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
2183
|
+
if (error instanceof SetupGithubError) throw error;
|
|
2184
|
+
throw new SetupGithubError(
|
|
2185
|
+
"github_workflow_write_failed",
|
|
2186
|
+
"Unable to create .github/workflows.",
|
|
2187
|
+
500,
|
|
2188
|
+
result
|
|
2189
|
+
);
|
|
2606
2190
|
}
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2191
|
+
return result;
|
|
2192
|
+
}
|
|
2193
|
+
__name(setupGithub, "setupGithub");
|
|
2194
|
+
async function updateGitignore(gitRepoRoot, fileOps = nodeFileOps) {
|
|
2195
|
+
try {
|
|
2196
|
+
const existingContent = await fileOps.readTextFile(
|
|
2197
|
+
gitRepoRoot,
|
|
2198
|
+
".gitignore"
|
|
2199
|
+
);
|
|
2200
|
+
if (existingContent === void 0) {
|
|
2201
|
+
const content = GITIGNORE_ENTRIES.join("\n") + "\n";
|
|
2202
|
+
await fileOps.writeTextFile(gitRepoRoot, ".gitignore", content);
|
|
2203
|
+
return {
|
|
2204
|
+
path: ".gitignore",
|
|
2205
|
+
status: "created",
|
|
2206
|
+
added: [...GITIGNORE_ENTRIES]
|
|
2207
|
+
};
|
|
2208
|
+
}
|
|
2209
|
+
const missingEntries = GITIGNORE_ENTRIES.filter(
|
|
2210
|
+
(entry) => !existingContent.split(/\r?\n/).some((line) => line.split("#")[0].trim() === entry)
|
|
2211
|
+
);
|
|
2212
|
+
if (missingEntries.length === 0) {
|
|
2213
|
+
return { path: ".gitignore", status: "unchanged" };
|
|
2214
|
+
}
|
|
2215
|
+
const nextContent = existingContent + "\n" + missingEntries.join("\n") + "\n";
|
|
2216
|
+
await fileOps.writeTextFile(gitRepoRoot, ".gitignore", nextContent);
|
|
2217
|
+
return {
|
|
2218
|
+
path: ".gitignore",
|
|
2219
|
+
status: "updated",
|
|
2220
|
+
added: missingEntries
|
|
2622
2221
|
};
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
presentation: this.presentationAdapter(),
|
|
2627
|
-
onDiagnostic: /* @__PURE__ */ __name((diagnostic) => {
|
|
2628
|
-
if (diagnostic.code === "malformed_part" && diagnostic.path === "systemPayload.outputHistoryItems.goalStatus.condition") {
|
|
2629
|
-
writeStderrLineSafe(`qwen: ${diagnostic.message}`);
|
|
2630
|
-
}
|
|
2631
|
-
}, "onDiagnostic")
|
|
2632
|
-
});
|
|
2633
|
-
}
|
|
2634
|
-
presentationAdapter() {
|
|
2222
|
+
} catch (error) {
|
|
2223
|
+
if (isWorkspaceGenerationClosed(error)) throw error;
|
|
2224
|
+
debugLogger2.debug("Failed to update .gitignore:", error);
|
|
2635
2225
|
return {
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2226
|
+
path: ".gitignore",
|
|
2227
|
+
status: "failed",
|
|
2228
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2639
2229
|
};
|
|
2640
2230
|
}
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2231
|
+
}
|
|
2232
|
+
__name(updateGitignore, "updateGitignore");
|
|
2233
|
+
async function downloadWorkflows(options) {
|
|
2234
|
+
const internalAbort = new AbortController();
|
|
2235
|
+
try {
|
|
2236
|
+
const dispatcher = options.proxy ? new (await loadUndici()).ProxyAgent(options.proxy) : void 0;
|
|
2237
|
+
return await Promise.all(
|
|
2238
|
+
GITHUB_WORKFLOW_PATHS.map(async (workflow) => {
|
|
2239
|
+
const endpoint = `https://raw.githubusercontent.com/QwenLM/qwen-code-action/refs/tags/${options.releaseTag}/examples/workflows/${workflow}`;
|
|
2240
|
+
const response = await options.fetchImpl(endpoint, {
|
|
2241
|
+
method: "GET",
|
|
2242
|
+
dispatcher,
|
|
2243
|
+
signal: AbortSignal.any([
|
|
2244
|
+
AbortSignal.timeout(3e4),
|
|
2245
|
+
internalAbort.signal,
|
|
2246
|
+
...options.abortSignal ? [options.abortSignal] : []
|
|
2247
|
+
])
|
|
2248
|
+
});
|
|
2249
|
+
if (!response.ok) {
|
|
2250
|
+
throw new Error(
|
|
2251
|
+
`Invalid response code downloading ${endpoint}: ${response.status} - ${response.statusText}`
|
|
2252
|
+
);
|
|
2253
|
+
}
|
|
2254
|
+
return {
|
|
2255
|
+
sourcePath: workflow,
|
|
2256
|
+
content: await readResponseTextWithLimit(response, workflow)
|
|
2257
|
+
};
|
|
2258
|
+
})
|
|
2259
|
+
);
|
|
2260
|
+
} catch (error) {
|
|
2261
|
+
internalAbort.abort();
|
|
2262
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2263
|
+
debugLogger2.debug("Failed to download qwen-code-action workflows:", error);
|
|
2264
|
+
throw new SetupGithubError(
|
|
2265
|
+
"github_workflow_download_failed",
|
|
2266
|
+
`Unable to download qwen-code-action workflows from GitHub. ${message}`,
|
|
2267
|
+
502
|
|
2268
|
+
);
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
__name(downloadWorkflows, "downloadWorkflows");
|
|
2272
|
+
async function readResponseTextWithLimit(response, sourcePath) {
|
|
2273
|
+
const contentLength = response.headers.get("content-length");
|
|
2274
|
+
if (contentLength !== null) {
|
|
2275
|
+
const parsedLength = Number(contentLength);
|
|
2276
|
+
if (Number.isFinite(parsedLength) && parsedLength > MAX_WORKFLOW_DOWNLOAD_BYTES) {
|
|
2277
|
+
throw new Error(
|
|
2278
|
+
`${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
|
|
2279
|
+
);
|
|
2645
2280
|
}
|
|
2646
|
-
await this.ctx.sendUpdate(update);
|
|
2647
2281
|
}
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2282
|
+
if (!response.body) return "";
|
|
2283
|
+
const reader = response.body.getReader();
|
|
2284
|
+
const chunks = [];
|
|
2285
|
+
let totalBytes = 0;
|
|
2286
|
+
try {
|
|
2287
|
+
while (true) {
|
|
2288
|
+
const { done, value } = await reader.read();
|
|
2289
|
+
if (done) break;
|
|
2290
|
+
if (!value) continue;
|
|
2291
|
+
totalBytes += value.byteLength;
|
|
2292
|
+
if (totalBytes > MAX_WORKFLOW_DOWNLOAD_BYTES) {
|
|
2293
|
+
await reader.cancel().catch(() => {
|
|
2294
|
+
});
|
|
2295
|
+
throw new Error(
|
|
2296
|
+
`${sourcePath} exceeds download limit of ${MAX_WORKFLOW_DOWNLOAD_BYTES} bytes`
|
|
2297
|
+
);
|
|
2298
|
+
}
|
|
2299
|
+
chunks.push(value);
|
|
2300
|
+
}
|
|
2301
|
+
} finally {
|
|
2302
|
+
reader.releaseLock();
|
|
2655
2303
|
}
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
* seen, so replaying a `set` card that no Stop hook will drive leaves the UI
|
|
2662
|
-
* claiming a goal is running when the loop is dead. The gates are pure
|
|
2663
|
-
* functions of `config`, so the answer is known here, before restore runs.
|
|
2664
|
-
*
|
|
2665
|
-
* This card is emitted, not recorded: the transcript keeps its `set` card, so
|
|
2666
|
-
* a later resume in a trusted folder (or with hooks re-enabled) restores the
|
|
2667
|
-
* goal instead of finding it destroyed. Emitting from inside replay is also
|
|
2668
|
-
* what puts the card *after* the `set` card — `loadSession` batches replay
|
|
2669
|
-
* updates into its response, and a notification sent afterwards would reach
|
|
2670
|
-
* the client first.
|
|
2671
|
-
*
|
|
2672
|
-
* Gated on `supersedeUnrestorableGoal`: only a resume registers a hook, and
|
|
2673
|
-
* only a resume has a `config` that answers trust and hook-policy questions.
|
|
2674
|
-
*/
|
|
2675
|
-
async supersedeUnrestorableGoal(records) {
|
|
2676
|
-
if (!this.options.supersedeUnrestorableGoal) return;
|
|
2677
|
-
const active = findGoalToRestore(
|
|
2678
|
-
collectGoalStatusItemsFromRecords(records)
|
|
2679
|
-
);
|
|
2680
|
-
if (!active || goalConditionBlockedBy(active.condition)) return;
|
|
2681
|
-
if (!hasFullSessionContext(this.ctx)) return;
|
|
2682
|
-
const blockedBy = goalRestoreBlockedBy(this.ctx.config);
|
|
2683
|
-
if (!blockedBy) return;
|
|
2684
|
-
await this.messageEmitter.emitGoalStatus({
|
|
2685
|
-
kind: "cleared",
|
|
2686
|
-
condition: active.condition,
|
|
2687
|
-
iterations: active.iterations,
|
|
2688
|
-
...active.setAt !== void 0 ? { setAt: active.setAt } : {},
|
|
2689
|
-
lastReason: GOAL_NOT_RESTORED_REASON[blockedBy]
|
|
2690
|
-
});
|
|
2304
|
+
const body = new Uint8Array(totalBytes);
|
|
2305
|
+
let offset = 0;
|
|
2306
|
+
for (const chunk of chunks) {
|
|
2307
|
+
body.set(chunk, offset);
|
|
2308
|
+
offset += chunk.byteLength;
|
|
2691
2309
|
}
|
|
2692
|
-
|
|
2693
|
-
|
|
2310
|
+
return new TextDecoder().decode(body);
|
|
2311
|
+
}
|
|
2312
|
+
__name(readResponseTextWithLimit, "readResponseTextWithLimit");
|
|
2313
|
+
async function resolveSecretsUrl(cwd) {
|
|
2314
|
+
try {
|
|
2315
|
+
const repoInfo = await getGitHubRepoInfoAsync({ cwd });
|
|
2316
|
+
return `https://github.com/${repoInfo.owner}/${repoInfo.repo}/settings/secrets/actions`;
|
|
2317
|
+
} catch {
|
|
2318
|
+
return void 0;
|
|
2694
2319
|
}
|
|
2695
|
-
};
|
|
2696
|
-
function toPendingTranscriptToolCall(pending) {
|
|
2697
|
-
return {
|
|
2698
|
-
callId: pending.callId,
|
|
2699
|
-
toolName: pending.toolName,
|
|
2700
|
-
sourceRecordId: pending.recordId,
|
|
2701
|
-
...pending.timestamp ? { sourceTimestamp: pending.timestamp } : {}
|
|
2702
|
-
};
|
|
2703
2320
|
}
|
|
2704
|
-
__name(
|
|
2705
|
-
function
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
};
|
|
2321
|
+
__name(resolveSecretsUrl, "resolveSecretsUrl");
|
|
2322
|
+
async function realpathOrResolve(input) {
|
|
2323
|
+
try {
|
|
2324
|
+
return await fsp.realpath(input);
|
|
2325
|
+
} catch {
|
|
2326
|
+
return path.resolve(input);
|
|
2327
|
+
}
|
|
2712
2328
|
}
|
|
2713
|
-
__name(
|
|
2329
|
+
__name(realpathOrResolve, "realpathOrResolve");
|
|
2714
2330
|
|
|
2715
2331
|
// packages/cli/src/ui/utils/export/collect.ts
|
|
2716
2332
|
init_esbuild_shims();
|
|
@@ -2931,7 +2547,7 @@ async function extractMetadata(conversation, config) {
|
|
|
2931
2547
|
const gitBranch = firstRecord?.gitBranch;
|
|
2932
2548
|
let gitRepo;
|
|
2933
2549
|
if (cwd) {
|
|
2934
|
-
const { getGitRepoName } = await import("./deferred-core-runtime-
|
|
2550
|
+
const { getGitRepoName } = await import("./deferred-core-runtime-ZSLQKM7J.js");
|
|
2935
2551
|
gitRepo = getGitRepoName(cwd);
|
|
2936
2552
|
}
|
|
2937
2553
|
let model;
|
|
@@ -3782,19 +3398,132 @@ __name(generateExportFilename, "generateExportFilename");
|
|
|
3782
3398
|
// packages/cli/src/ui/utils/export/index.ts
|
|
3783
3399
|
init_esbuild_shims();
|
|
3784
3400
|
|
|
3401
|
+
// packages/cli/src/utils/json-string-byte-projection.ts
|
|
3402
|
+
init_esbuild_shims();
|
|
3403
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
3404
|
+
var JSON_STRING_DELIMITER_BYTES = 2;
|
|
3405
|
+
function jsonPayloadBytesAt(value, index) {
|
|
3406
|
+
const code = value.charCodeAt(index);
|
|
3407
|
+
if (code === 34 || code === 92) return 2;
|
|
3408
|
+
if (code <= 31) {
|
|
3409
|
+
return code === 8 || code === 9 || code === 10 || code === 12 || code === 13 ? 2 : 6;
|
|
3410
|
+
}
|
|
3411
|
+
if (code <= 127) return 1;
|
|
3412
|
+
if (code <= 2047) return 2;
|
|
3413
|
+
if (code >= 55296 && code <= 56319) {
|
|
3414
|
+
const next = value.charCodeAt(index + 1);
|
|
3415
|
+
return next >= 56320 && next <= 57343 ? 4 : 6;
|
|
3416
|
+
}
|
|
3417
|
+
if (code >= 56320 && code <= 57343) return 6;
|
|
3418
|
+
return 3;
|
|
3419
|
+
}
|
|
3420
|
+
__name(jsonPayloadBytesAt, "jsonPayloadBytesAt");
|
|
3421
|
+
function jsonPayloadWidthAt(value, index) {
|
|
3422
|
+
const code = value.charCodeAt(index);
|
|
3423
|
+
if (code < 55296 || code > 56319) return 1;
|
|
3424
|
+
const next = value.charCodeAt(index + 1);
|
|
3425
|
+
return next >= 56320 && next <= 57343 ? 2 : 1;
|
|
3426
|
+
}
|
|
3427
|
+
__name(jsonPayloadWidthAt, "jsonPayloadWidthAt");
|
|
3428
|
+
function jsonStringPayloadByteLength(value, stopAfterBytes = Number.POSITIVE_INFINITY) {
|
|
3429
|
+
let bytes = 0;
|
|
3430
|
+
for (let index = 0; index < value.length; ) {
|
|
3431
|
+
bytes += jsonPayloadBytesAt(value, index);
|
|
3432
|
+
if (bytes > stopAfterBytes) return bytes;
|
|
3433
|
+
index += jsonPayloadWidthAt(value, index);
|
|
3434
|
+
}
|
|
3435
|
+
return bytes;
|
|
3436
|
+
}
|
|
3437
|
+
__name(jsonStringPayloadByteLength, "jsonStringPayloadByteLength");
|
|
3438
|
+
function jsonStringJsonByteLength(value) {
|
|
3439
|
+
return JSON_STRING_DELIMITER_BYTES + jsonStringPayloadByteLength(value);
|
|
3440
|
+
}
|
|
3441
|
+
__name(jsonStringJsonByteLength, "jsonStringJsonByteLength");
|
|
3442
|
+
function jsonPayloadWidthBefore(value, end) {
|
|
3443
|
+
const last = value.charCodeAt(end - 1);
|
|
3444
|
+
if (last >= 56320 && last <= 57343 && end >= 2) {
|
|
3445
|
+
const previous = value.charCodeAt(end - 2);
|
|
3446
|
+
if (previous >= 55296 && previous <= 56319) return 2;
|
|
3447
|
+
}
|
|
3448
|
+
return 1;
|
|
3449
|
+
}
|
|
3450
|
+
__name(jsonPayloadWidthBefore, "jsonPayloadWidthBefore");
|
|
3451
|
+
function selectPrefix(value, budget) {
|
|
3452
|
+
let end = 0;
|
|
3453
|
+
let bytes = 0;
|
|
3454
|
+
while (end < value.length) {
|
|
3455
|
+
const partBytes = jsonPayloadBytesAt(value, end);
|
|
3456
|
+
if (bytes + partBytes > budget) break;
|
|
3457
|
+
bytes += partBytes;
|
|
3458
|
+
end += jsonPayloadWidthAt(value, end);
|
|
3459
|
+
}
|
|
3460
|
+
return end;
|
|
3461
|
+
}
|
|
3462
|
+
__name(selectPrefix, "selectPrefix");
|
|
3463
|
+
function selectSuffix(value, budget) {
|
|
3464
|
+
let start = value.length;
|
|
3465
|
+
let bytes = 0;
|
|
3466
|
+
while (start > 0) {
|
|
3467
|
+
const partWidth = jsonPayloadWidthBefore(value, start);
|
|
3468
|
+
const partBytes = jsonPayloadBytesAt(value, start - partWidth);
|
|
3469
|
+
if (bytes + partBytes > budget) break;
|
|
3470
|
+
bytes += partBytes;
|
|
3471
|
+
start -= partWidth;
|
|
3472
|
+
}
|
|
3473
|
+
return start;
|
|
3474
|
+
}
|
|
3475
|
+
__name(selectSuffix, "selectSuffix");
|
|
3476
|
+
function copyString(value) {
|
|
3477
|
+
return value.split("").join("");
|
|
3478
|
+
}
|
|
3479
|
+
__name(copyString, "copyString");
|
|
3480
|
+
function truncateJsonStringPayload(value, originalPayloadBytes, payloadBudget, marker) {
|
|
3481
|
+
if (originalPayloadBytes <= payloadBudget) return value;
|
|
3482
|
+
const markerPayloadBytes = jsonStringPayloadByteLength(marker);
|
|
3483
|
+
if (payloadBudget < markerPayloadBytes) {
|
|
3484
|
+
return copyString(value.slice(0, selectPrefix(value, payloadBudget)));
|
|
3485
|
+
}
|
|
3486
|
+
const sourceBudget = payloadBudget - markerPayloadBytes;
|
|
3487
|
+
const headBudget = Math.floor(sourceBudget * 0.2);
|
|
3488
|
+
const tailBudget = sourceBudget - headBudget;
|
|
3489
|
+
const headEnd = selectPrefix(value, headBudget);
|
|
3490
|
+
const tailStart = selectSuffix(value, tailBudget);
|
|
3491
|
+
return copyString(value.slice(0, headEnd)) + marker + copyString(value.slice(tailStart));
|
|
3492
|
+
}
|
|
3493
|
+
__name(truncateJsonStringPayload, "truncateJsonStringPayload");
|
|
3494
|
+
function projectJsonStringToByteBudget(value, jsonByteBudget, marker) {
|
|
3495
|
+
const payloadBudget = Math.max(
|
|
3496
|
+
0,
|
|
3497
|
+
jsonByteBudget - JSON_STRING_DELIMITER_BYTES
|
|
3498
|
+
);
|
|
3499
|
+
const payloadBytes = jsonStringPayloadByteLength(value, payloadBudget);
|
|
3500
|
+
if (payloadBytes <= payloadBudget) return value;
|
|
3501
|
+
const projected = truncateJsonStringPayload(
|
|
3502
|
+
value,
|
|
3503
|
+
payloadBytes,
|
|
3504
|
+
payloadBudget,
|
|
3505
|
+
marker
|
|
3506
|
+
);
|
|
3507
|
+
if (Buffer2.byteLength(JSON.stringify(projected), "utf8") <= jsonByteBudget) {
|
|
3508
|
+
return projected;
|
|
3509
|
+
}
|
|
3510
|
+
const fallback = copyString(
|
|
3511
|
+
marker.slice(0, selectPrefix(marker, payloadBudget))
|
|
3512
|
+
);
|
|
3513
|
+
return Buffer2.byteLength(JSON.stringify(fallback), "utf8") <= jsonByteBudget ? fallback : "";
|
|
3514
|
+
}
|
|
3515
|
+
__name(projectJsonStringToByteBudget, "projectJsonStringToByteBudget");
|
|
3516
|
+
|
|
3785
3517
|
export {
|
|
3786
3518
|
GITHUB_WORKFLOW_PATHS,
|
|
3787
3519
|
SetupGithubError,
|
|
3788
3520
|
setupGithub,
|
|
3789
3521
|
createTranscriptMessageUpdate,
|
|
3790
|
-
|
|
3522
|
+
createTranscriptUsageUpdate,
|
|
3523
|
+
BaseEmitter,
|
|
3791
3524
|
PlanEmitter,
|
|
3525
|
+
hasFullSessionContext,
|
|
3792
3526
|
ToolCallEmitter,
|
|
3793
|
-
collectGoalStatusItemsFromRecords,
|
|
3794
|
-
goalTerminalEventToHistoryItem,
|
|
3795
|
-
recordGoalStatusItem,
|
|
3796
|
-
installGoalTerminalObserver,
|
|
3797
|
-
restoreGoalFromHistory,
|
|
3798
3527
|
HistoryReplayer,
|
|
3799
3528
|
collectSessionData,
|
|
3800
3529
|
normalizeSessionData,
|
|
@@ -3804,7 +3533,12 @@ export {
|
|
|
3804
3533
|
toHtml,
|
|
3805
3534
|
toJson,
|
|
3806
3535
|
toJsonl,
|
|
3807
|
-
generateExportFilename
|
|
3536
|
+
generateExportFilename,
|
|
3537
|
+
JSON_STRING_DELIMITER_BYTES,
|
|
3538
|
+
jsonStringPayloadByteLength,
|
|
3539
|
+
jsonStringJsonByteLength,
|
|
3540
|
+
truncateJsonStringPayload,
|
|
3541
|
+
projectJsonStringToByteBudget
|
|
3808
3542
|
};
|
|
3809
3543
|
/**
|
|
3810
3544
|
* @license
|
|
@@ -3813,17 +3547,17 @@ export {
|
|
|
3813
3547
|
*/
|
|
3814
3548
|
/**
|
|
3815
3549
|
* @license
|
|
3816
|
-
* Copyright 2025
|
|
3550
|
+
* Copyright 2025 Qwen Team
|
|
3817
3551
|
* SPDX-License-Identifier: Apache-2.0
|
|
3818
3552
|
*/
|
|
3819
3553
|
/**
|
|
3820
3554
|
* @license
|
|
3821
|
-
* Copyright 2025 Qwen
|
|
3555
|
+
* Copyright 2025 Qwen
|
|
3822
3556
|
* SPDX-License-Identifier: Apache-2.0
|
|
3823
3557
|
*/
|
|
3824
3558
|
/**
|
|
3825
3559
|
* @license
|
|
3826
|
-
* Copyright 2025
|
|
3560
|
+
* Copyright 2025 Google LLC
|
|
3827
3561
|
* SPDX-License-Identifier: Apache-2.0
|
|
3828
3562
|
*/
|
|
3829
3563
|
/**
|