@qwen-code/qwen-code 0.23.1-preview.1 → 0.23.1
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/computer-use/SKILL.md +189 -116
- package/bundled/goal-draft/SKILL.md +23 -13
- package/bundled/qc-helper/docs/_meta.ts +1 -0
- package/bundled/qc-helper/docs/configuration/model-providers.md +47 -1
- package/bundled/qc-helper/docs/configuration/settings.md +57 -7
- package/bundled/qc-helper/docs/conversations-recovery.md +102 -0
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +26 -0
- package/bundled/qc-helper/docs/features/channels/overview.md +1 -1
- package/bundled/qc-helper/docs/features/commands.md +71 -6
- package/bundled/qc-helper/docs/features/computer-use.md +9 -7
- package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
- package/bundled/qc-helper/docs/features/goals.md +15 -3
- package/bundled/qc-helper/docs/features/skills.md +40 -0
- package/bundled/qc-helper/docs/qwen-serve.md +19 -1
- package/chunks/{MaxSizedBox-5ARLO5PR.js → MaxSizedBox-UDO6Y7RB.js} +35 -36
- package/chunks/{StandaloneSessionPicker-T6B322CB.js → StandaloneSessionPicker-D4CUOO4H.js} +55 -56
- package/chunks/{acp-startup-profiler-6ULXXQMS.js → acp-startup-profiler-KEU6VAYR.js} +2 -2
- package/chunks/{acpAgent-WTDEY5KD.js → acpAgent-KWLJFADK.js} +210 -131
- package/chunks/{agent-NXPUXEVZ.js → agent-GSUPGEOL.js} +24 -25
- package/chunks/{agent-headless-QQZTWOKO.js → agent-headless-HNYCQUJB.js} +24 -25
- package/chunks/{anthropicContentGenerator-6XDHXIII.js → anthropicContentGenerator-I7LQZH26.js} +30 -7
- package/chunks/{artifact-tool-DFVVJXL2.js → artifact-tool-P52OKKEF.js} +1 -1
- package/chunks/{askUserQuestion-GF7VQ44M.js → askUserQuestion-I5W5S3D6.js} +2 -2
- package/chunks/{bridge-OHY5OGOZ.js → bridge-B7CV6RVI.js} +40 -41
- package/chunks/{channel-management-service-ZDDG3G5S.js → channel-management-service-TRTLQTSV.js} +4 -4
- package/chunks/{channel-settings-store-7BJAS2SU.js → channel-settings-store-FW45IRUP.js} +46 -47
- package/chunks/{channel-worker-group-2ISMRENV.js → channel-worker-group-PIYPVCTF.js} +6 -6
- package/chunks/{channel-worker-manager-VSRPVPRH.js → channel-worker-manager-FQHEDTD2.js} +6 -6
- package/chunks/{channel-worker-supervisor-SRJBK72Z.js → channel-worker-supervisor-XJPZZ3VK.js} +3 -3
- package/chunks/{chunk-2WGJG2KW.js → chunk-25CBAK3H.js} +4 -4
- package/chunks/{chunk-XUSOYE2I.js → chunk-27LTEY6D.js} +1 -1
- package/chunks/{chunk-WTW36TJ3.js → chunk-2EKVPSIJ.js} +1 -1
- package/chunks/{chunk-NAKALAL4.js → chunk-2TMJRF46.js} +116 -15
- package/chunks/{chunk-E4L5BM2B.js → chunk-2YS3NU4A.js} +4 -4
- package/chunks/chunk-2Z3T52OC.js +82 -0
- package/chunks/{chunk-ER273QE6.js → chunk-2ZFO5JD7.js} +21 -4
- package/chunks/{chunk-WXC6OAWD.js → chunk-3BTHHXXE.js} +1 -1
- package/chunks/{chunk-GXZHYPHZ.js → chunk-3LPJ776W.js} +5 -2
- package/chunks/{chunk-XY3USGFE.js → chunk-3VDLQUR2.js} +1 -1
- package/chunks/{chunk-LK7S2D6V.js → chunk-3VWPPK5Q.js} +58 -4
- package/chunks/{chunk-IKLFS6SC.js → chunk-3YQMUBTS.js} +3 -3
- package/chunks/{chunk-P4RUUG64.js → chunk-45ROPFQY.js} +1 -1
- package/chunks/{chunk-W4LL5RZO.js → chunk-4ALNJDHL.js} +52 -13
- package/chunks/{chunk-D6PIMKY3.js → chunk-4VY3ITHR.js} +4 -4
- package/chunks/{chunk-H3UDNQLO.js → chunk-5CVY5Q2P.js} +3 -3
- package/chunks/{chunk-6UIACMGH.js → chunk-5DQ4YTIZ.js} +1 -1
- package/chunks/{chunk-P6LATTDG.js → chunk-5IL2BZHW.js} +3 -3
- package/chunks/{chunk-537SQ2AI.js → chunk-5WC2ECUK.js} +104 -16
- package/chunks/{chunk-HFTB354P.js → chunk-5Z4FCEPY.js} +60 -6
- package/chunks/{chunk-3K65MUKD.js → chunk-65I7S4Z3.js} +2 -1
- package/chunks/{chunk-AQ5NAGWI.js → chunk-66JBCTJF.js} +8 -7
- package/chunks/{chunk-54TF2ZIQ.js → chunk-6JXHO7LG.js} +3 -3
- package/chunks/{chunk-YCDL2SAS.js → chunk-6QILGINT.js} +2 -2
- package/chunks/{chunk-P5LDR7FI.js → chunk-6QV7Z74P.js} +3 -3
- package/chunks/{chunk-4HC4DYKN.js → chunk-6RZX2HIH.js} +1 -1
- package/chunks/{chunk-O45WBTNS.js → chunk-6SADVYQQ.js} +3 -3
- package/chunks/{chunk-KE3Q4JMY.js → chunk-6TPVIESH.js} +5 -7
- package/chunks/{chunk-2LD5U7Q3.js → chunk-6YEOCHSE.js} +29 -1
- package/chunks/{chunk-QWZOOIR3.js → chunk-75LBC7SV.js} +69 -12
- package/chunks/{chunk-7BZS4ZDV.js → chunk-7SL55L5H.js} +25 -18
- package/chunks/{chunk-O2GG7H4C.js → chunk-ARYNBBBM.js} +3 -3
- package/chunks/{chunk-CZACBHAW.js → chunk-B3EL44K3.js} +5 -5
- package/chunks/{chunk-VY6UVU7G.js → chunk-CABDNUJ4.js} +2 -2
- package/chunks/{chunk-RVNS7NWN.js → chunk-CALNF3Z3.js} +1 -1
- package/chunks/{chunk-MWHY26G3.js → chunk-CHVU543W.js} +1 -1
- package/chunks/{chunk-GZWW2QWR.js → chunk-CIKL2DQP.js} +2 -2
- package/chunks/{chunk-R355CUNQ.js → chunk-CLKE4IY3.js} +1 -77
- package/chunks/{chunk-MUZCSTOO.js → chunk-CRZBDVP2.js} +5 -4
- package/chunks/{chunk-SFMCYMVF.js → chunk-D6AQNMUA.js} +4 -4
- package/chunks/{chunk-D4CU6DKR.js → chunk-DO5SMV52.js} +10 -8
- package/chunks/{chunk-ZAZ3NFL6.js → chunk-DXQ6Z7AH.js} +315 -63
- package/chunks/{chunk-IXSGOSEG.js → chunk-DZ6D4B3K.js} +28 -25
- package/chunks/{chunk-GMNLYQOS.js → chunk-E6TI726I.js} +1 -1
- package/chunks/{chunk-JBTZUFR4.js → chunk-E7XSUYCZ.js} +6 -6
- package/chunks/{chunk-AHBLRVD5.js → chunk-EEKU6COG.js} +4 -4
- package/chunks/{chunk-47BZVBTE.js → chunk-EHTKOO6W.js} +4 -4
- package/chunks/{chunk-HJ34U5J4.js → chunk-ENZDGHGJ.js} +4 -4
- package/chunks/{chunk-IFD3BTEA.js → chunk-EOET4H7C.js} +3 -3
- package/chunks/{chunk-ZTAVGFKA.js → chunk-ERXNTINK.js} +1 -1
- package/chunks/{chunk-F47DITLZ.js → chunk-FAWTMDX7.js} +14 -0
- package/chunks/{chunk-KPXRFTT7.js → chunk-FETY36NQ.js} +1 -1
- package/chunks/{chunk-5JLQWQK6.js → chunk-FV4DM2M4.js} +2 -2
- package/chunks/{chunk-4F2QRVW6.js → chunk-FW4E4QPG.js} +1 -1
- package/chunks/{chunk-KJJPJYHI.js → chunk-FWRRUITH.js} +8 -8
- package/chunks/{chunk-4VUVBN3Y.js → chunk-G6UUOCUT.js} +87 -0
- package/chunks/{chunk-4JAGXZR3.js → chunk-GM44O6F7.js} +1 -1
- package/chunks/{chunk-4MCY33Y2.js → chunk-GNY7B3CA.js} +1 -1
- package/chunks/{chunk-VEFRT7NX.js → chunk-H3Q3RSKZ.js} +1 -1
- package/chunks/{chunk-43NOB5NM.js → chunk-HIXUUCGY.js} +188 -13
- package/chunks/{chunk-EJNYBDYC.js → chunk-HNLMYDQE.js} +1 -1
- package/chunks/{chunk-JOPC3FND.js → chunk-HUX2DOTF.js} +5 -5
- package/chunks/{chunk-GCFZ2LAX.js → chunk-HZ2HUXX7.js} +2 -2
- package/chunks/{chunk-CWNC7M73.js → chunk-IKG2YVRZ.js} +2 -2
- package/chunks/{chunk-L4R7BCVV.js → chunk-J3TJH52D.js} +1 -1
- package/chunks/{chunk-QMFOYPGV.js → chunk-J3VZF2AL.js} +2 -2
- package/chunks/{chunk-ZJ2LM2SI.js → chunk-JGDRB4FP.js} +104 -33
- package/chunks/{chunk-LMJQSPWB.js → chunk-KA5HR3G2.js} +1 -1
- package/chunks/{chunk-G34YLYCS.js → chunk-L7V52QEZ.js} +10 -10
- package/chunks/{chunk-GVVCLL2P.js → chunk-LNCNUMJ5.js} +451 -396
- package/chunks/{chunk-RDKXZ2LS.js → chunk-LYT2OU7D.js} +1 -1
- package/chunks/{chunk-SAZS4IWW.js → chunk-LZGFVUWZ.js} +3 -3
- package/chunks/{chunk-32YDNYXP.js → chunk-M73KHGNR.js} +13 -66
- package/chunks/{chunk-ADJD4LZF.js → chunk-MA5OUNN6.js} +1 -1
- package/chunks/{chunk-2RYWGYB3.js → chunk-MFYH2VXV.js} +3 -3
- package/chunks/{chunk-RPBMP6BN.js → chunk-MWIO7MF6.js} +3 -0
- package/chunks/{chunk-OECNP26L.js → chunk-N6S3NUYJ.js} +1 -1
- package/chunks/{chunk-5MTARK4Y.js → chunk-N7YQEKGX.js} +6 -6
- package/chunks/{chunk-XOVVCGZX.js → chunk-NB3NDQQK.js} +1 -1
- package/chunks/chunk-NOO4QFXM.js +171 -0
- package/chunks/{chunk-NGX4NUNP.js → chunk-O2FEO2CB.js} +131 -6
- package/chunks/{chunk-XHGGYCTA.js → chunk-O2JBJQCF.js} +1 -1
- package/chunks/{chunk-LPBQODMR.js → chunk-OESZTXTG.js} +4 -4
- package/chunks/{chunk-UKADFFL2.js → chunk-OFVAS4AR.js} +1 -1
- package/chunks/{chunk-TDP7UULF.js → chunk-OPMKGOLD.js} +1 -1
- package/chunks/{chunk-LDS57224.js → chunk-OWCFKIFQ.js} +1 -1
- package/chunks/{chunk-I72PHOKL.js → chunk-PDUMGZ2P.js} +1524 -1382
- package/chunks/{chunk-JRYL3T2O.js → chunk-PQSCGZT2.js} +1 -1
- package/chunks/{chunk-WEXA2DNG.js → chunk-PSPAM24S.js} +14 -0
- package/chunks/{chunk-UKKYOIVT.js → chunk-QAZ2MGYT.js} +2 -2
- package/chunks/{chunk-J3O5I5ZD.js → chunk-QK4K76T6.js} +3 -3
- package/chunks/{chunk-NUQFUXOG.js → chunk-QTNCGZHQ.js} +2 -0
- package/chunks/{chunk-5YY5MZT6.js → chunk-QZOXVQPK.js} +1 -1
- package/chunks/{chunk-QJVZLILI.js → chunk-R7OO56VZ.js} +1 -1
- package/chunks/{chunk-IQN2CCIE.js → chunk-RNYENHN5.js} +398 -55
- package/chunks/{chunk-64MQTIX7.js → chunk-RPFJJ33Z.js} +2 -2
- package/chunks/{chunk-4VZCORNT.js → chunk-RXT4QBDX.js} +1 -1
- package/chunks/{chunk-SN5FV4FY.js → chunk-S6QVI3MV.js} +3 -3
- package/chunks/{chunk-NXWYCSPL.js → chunk-SOA4HKRJ.js} +1 -1
- package/chunks/{chunk-JLWFGYXU.js → chunk-T2IHCZLS.js} +2 -2
- package/chunks/{chunk-DNPHKA72.js → chunk-TGC4264Q.js} +6 -6
- package/chunks/{chunk-PZV2FASB.js → chunk-TRWQQBVH.js} +1 -1
- package/chunks/{chunk-Y3ZKI4RQ.js → chunk-TWAMIEQ2.js} +85 -22
- package/chunks/{chunk-KK2GZGBK.js → chunk-TWWS7XUW.js} +14 -11
- package/chunks/{chunk-4IQKBLTQ.js → chunk-UHUT4IDM.js} +18 -9
- package/chunks/{chunk-BKNY7PDI.js → chunk-USN6VNTO.js} +1 -1
- package/chunks/{chunk-TMWB67LS.js → chunk-UXDVUFKU.js} +3 -3
- package/chunks/{chunk-HY3DXYZK.js → chunk-UYDQYDW2.js} +1 -1
- package/chunks/{chunk-3K456UJF.js → chunk-VF6D6EGV.js} +12 -4
- package/chunks/{chunk-PZUOHCWI.js → chunk-WAASYFPK.js} +2 -2
- package/chunks/{chunk-OHOO527W.js → chunk-WG7BL3FY.js} +52 -2
- package/chunks/{chunk-JPEAQJNS.js → chunk-WJDXKQIO.js} +1 -1
- package/chunks/{chunk-MNEYUNOE.js → chunk-WNISCNTA.js} +40 -2
- package/chunks/{chunk-Z6WZPXQH.js → chunk-WQMUGQ6G.js} +2 -2
- package/chunks/{chunk-N7VURC4O.js → chunk-WXFCI3O5.js} +2 -2
- package/chunks/{chunk-VU7O7CGQ.js → chunk-XDNFODER.js} +1 -1
- package/chunks/{chunk-N7EYO2E7.js → chunk-XQ4RDO5B.js} +1 -1
- package/chunks/{chunk-VDXYYVCD.js → chunk-XVTCSVBK.js} +579 -57
- package/chunks/{chunk-PTFFWTTO.js → chunk-XZ3Z43XL.js} +3 -3
- package/chunks/{chunk-QSC5YOEC.js → chunk-YAC7H4K3.js} +2 -2
- package/chunks/{chunk-43JNQAHO.js → chunk-YCEKI7QX.js} +51 -10
- package/chunks/{chunk-7IKXTGZT.js → chunk-YI2YCNSP.js} +1 -1
- package/chunks/{chunk-VUSSAGKI.js → chunk-YZTGGCEE.js} +10 -2
- package/chunks/{chunk-WR3SH3EY.js → chunk-ZNO5BUAD.js} +149 -66
- package/chunks/{chunk-URSCX7S7.js → chunk-ZPL2TZNA.js} +353 -11
- package/chunks/{chunk-UEZOXZNI.js → chunk-ZU2T5JIS.js} +804 -371
- package/chunks/{config-utils-QXDOTXEQ.js → config-utils-KTDSQ4MU.js} +39 -40
- package/chunks/{contextCommand-RN4KARWC.js → contextCommand-UQ3KRYGK.js} +37 -38
- package/chunks/{core-runtime-NAZCOKHB.js → core-runtime-JR34JAFH.js} +35 -36
- package/chunks/{create-sub-session-BCSM4WKB.js → create-sub-session-RGPJOI4S.js} +45 -40
- package/chunks/{create-sub-session-BQ3SE4TX.js → create-sub-session-TGIX63YU.js} +2 -2
- package/chunks/{cron-create-D6HQ7I7I.js → cron-create-GTPVMJCF.js} +1 -1
- package/chunks/{cron-delete-KK3D2SQV.js → cron-delete-ZBK27Z4K.js} +1 -1
- package/chunks/{cron-list-VBF3IZMF.js → cron-list-KTFKFDKC.js} +1 -1
- package/chunks/{daemon-LCUELM6E.js → daemon-UI6SQSBV.js} +1 -1
- package/chunks/{daemon-git-worktree-guard-3K5CAU36.js → daemon-git-worktree-guard-H3OA26KQ.js} +35 -36
- package/chunks/{daemon-status-provider-4X3ZZQTZ.js → daemon-status-provider-6WZLKSZU.js} +45 -46
- package/chunks/{daemon-trust-policy-R45CFUJA.js → daemon-trust-policy-3EDP2BYD.js} +42 -43
- package/chunks/{daemon-trust-policy-monitor-DSSFCO3K.js → daemon-trust-policy-monitor-CRHZPK52.js} +42 -43
- package/chunks/{deferred-core-runtime-UO2M6WYI.js → deferred-core-runtime-LO5NTQQ4.js} +35 -36
- package/chunks/{discovery-TUM3ZQ6U.js → discovery-XP4RMDUM.js} +4 -2
- package/chunks/{display-image-EVVTBVYE.js → display-image-CTNHJRZC.js} +4 -4
- package/chunks/{dist-SIHF5MU2.js → dist-24TCWK5H.js} +1 -1
- package/chunks/{dist-AFH3BMZZ.js → dist-5I4HLUTO.js} +1 -1
- package/chunks/{dist-3T5MDUHP.js → dist-FDISN4AK.js} +1 -1
- package/chunks/{dist-SB2XRXZA.js → dist-M4CBX53H.js} +1 -1
- package/chunks/{dist-UVHW2U56.js → dist-NQ2636VT.js} +1 -1
- package/chunks/{dist-PH5RSTEA.js → dist-OR2ZQTXZ.js} +1 -1
- package/chunks/{dist-MK5PPBRF.js → dist-STAGIFNB.js} +1099 -67
- package/chunks/{dist-R5Y34V6T.js → dist-WZTUKIDR.js} +2 -2
- package/chunks/{dist-QUU7TVE3.js → dist-XJ25G6OH.js} +1 -1
- package/chunks/{edit-VNBCTRWP.js → edit-LB7Z7XK5.js} +24 -25
- package/chunks/{en-JMR535HP.js → en-YJNRUQG4.js} +1 -1
- package/chunks/{enter-worktree-CEVK7MQ2.js → enter-worktree-YFTKHXHZ.js} +4 -4
- package/chunks/{enterPlanMode-4KMZMUIA.js → enterPlanMode-P6TVUFIY.js} +24 -25
- package/chunks/{environment-S2HYQDON.js → environment-QATJNNKI.js} +38 -39
- package/chunks/{errors-DAAN5TL7.js → errors-3XJ37PS2.js} +37 -38
- package/chunks/{exit-worktree-D3YE6MUN.js → exit-worktree-NF2XEMES.js} +5 -5
- package/chunks/{exitPlanMode-HR36HG3D.js → exitPlanMode-A3OKL5UO.js} +24 -25
- package/chunks/{fast-path-4IWSW3UV.js → fast-path-DBIT5YQQ.js} +3 -3
- package/chunks/{fast-path-settings-ISEJPRYE.js → fast-path-settings-SATXY3PD.js} +3 -3
- package/chunks/{glob-IZYB2XH2.js → glob-73EDTXUE.js} +24 -25
- package/chunks/{goal-tools-VGUPKQDJ.js → goal-tools-DFI6YMSD.js} +24 -25
- package/chunks/{grep-OUVLNXG7.js → grep-BLHF2S5D.js} +2 -2
- package/chunks/{handleAutoUpdate-D56FMDTW.js → handleAutoUpdate-2FUNJO3B.js} +38 -39
- package/chunks/{i18n-BKE5WO6T.js → i18n-FDIA6KFI.js} +38 -37
- package/chunks/{image-gen-SHVQ3XID.js → image-gen-XP4NNIYG.js} +5 -5
- package/chunks/{initializer-MS4SGEHF.js → initializer-4MJTJOTW.js} +42 -43
- package/chunks/{installationInfo-542MGC4S.js → installationInfo-232RA2OK.js} +35 -36
- package/chunks/{list-H6XTKUWL.js → list-WN6WSGEB.js} +45 -46
- package/chunks/{list-agents-ULYBGJXC.js → list-agents-I5TRH3J7.js} +2 -2
- package/chunks/{llm-3NUC4EJY.js → llm-UDFWQWZA.js} +77 -78
- package/chunks/{llm-content-generator-R4NL3OQN.js → llm-content-generator-VLMZ2A7A.js} +23 -8
- package/chunks/{loadedSettingsAdapter-3XLKYDVT.js → loadedSettingsAdapter-OBQEIXM7.js} +42 -43
- package/chunks/{loggingContentGenerator-ZYSWVNEO.js → loggingContentGenerator-RGVUMUVX.js} +26 -27
- package/chunks/{loop-wakeup-B27BEYRL.js → loop-wakeup-HL6XOWI4.js} +2 -2
- package/chunks/{ls-3IIMMVKF.js → ls-YV7RKLKY.js} +1 -1
- package/chunks/{lsp-VJAT7XKS.js → lsp-NO3AMRZT.js} +1 -1
- package/chunks/{managed-npm-update-L2I53ZAI.js → managed-npm-update-QBAJYCFU.js} +35 -36
- package/chunks/{mcp-4PIXQASW.js → mcp-OTIZZCPY.js} +42 -43
- package/chunks/{monitor-O2YQTOZZ.js → monitor-BV5XF6LL.js} +24 -25
- package/chunks/{nonInteractiveCli-LV7CDBA2.js → nonInteractiveCli-W6MUKDVJ.js} +79 -77
- package/chunks/{notebook-edit-4RE2ALH4.js → notebook-edit-HGBEKGTE.js} +24 -25
- package/chunks/{openaiContentGenerator-7ND7K5CP.js → openaiContentGenerator-NSU3ERBH.js} +15 -15
- package/chunks/{pidfile-UFTLQ7NP.js → pidfile-LE3TU4GE.js} +35 -36
- package/chunks/{processUtils-3XBB4FYV.js → processUtils-YFBGJK67.js} +2 -2
- package/chunks/{prompt-terminal-ledger-2QASOGMM.js → prompt-terminal-ledger-4W4W7DSO.js} +36 -37
- package/chunks/{qwenContentGenerator-AELTUTH6.js → qwenContentGenerator-HTA57WFC.js} +28 -29
- package/chunks/{qwenOAuth2-BS5D2LYV.js → qwenOAuth2-KX6LVYQ3.js} +4 -4
- package/chunks/{read-file-PDWHZPHX.js → read-file-KHPQ2MB6.js} +4 -4
- package/chunks/{read-mcp-resource-YXJZ75UB.js → read-mcp-resource-D3N75DGF.js} +1 -1
- package/chunks/{record-artifact-WJDOV6XU.js → record-artifact-Q5CRGJTP.js} +2 -2
- package/chunks/{report-findings-Q4UACKWR.js → report-findings-TJ34R7QK.js} +3 -3
- package/chunks/{request-shutdown-2YZ3E3GH.js → request-shutdown-LRKMTBAD.js} +6 -6
- package/chunks/{resumeHistoryUtils-QRXZEEBA.js → resumeHistoryUtils-K7RV3QBN.js} +39 -40
- package/chunks/{ripGrep-KSOOLE6H.js → ripGrep-NBBVCMG4.js} +7 -7
- package/chunks/{run-qwen-serve-RTAREPT6.js → run-qwen-serve-A3JBOZCM.js} +58 -60
- package/chunks/{runtime-ESFSCJRZ.js → runtime-7YOU2KJ3.js} +47 -48
- package/chunks/{scheduled-tasks-6ZHRNBH6.js → scheduled-tasks-52LXK7LN.js} +42 -43
- package/chunks/{scheduler-DQI6KV7T.js → scheduler-J44M72VM.js} +37 -38
- package/chunks/{send-message-PQCVSVMN.js → send-message-AWKUDJBH.js} +8 -8
- package/chunks/{serve-FY7ZEW52.js → serve-TRC6XJUB.js} +42 -43
- package/chunks/{server-KNDY6K5F.js → server-YPNTJLX2.js} +1314 -841
- package/chunks/{session-MCEPXAZP.js → session-FMMIBFYX.js} +98 -84
- package/chunks/{session-attachments-root-OLNAE6GF.js → session-attachments-root-LDJMNK7K.js} +35 -36
- package/chunks/{session-pr-refresh-HKJHQQQK.js → session-pr-refresh-NLR4EK2J.js} +41 -42
- package/chunks/{settings-VXO4WBMK.js → settings-A46L577J.js} +41 -42
- package/chunks/{shell-U263OTES.js → shell-Q5LSQPPY.js} +24 -25
- package/chunks/{skill-SDODGBKL.js → skill-75KPJRCM.js} +10 -57
- package/chunks/{skill-settings-YEIA22QJ.js → skill-settings-775YT4YR.js} +41 -42
- package/chunks/{spawnChannel-4WJZVFPP.js → spawnChannel-XY73I5CU.js} +37 -38
- package/chunks/{standalone-update-ZWVQUO64.js → standalone-update-L46XXNQ2.js} +37 -38
- package/chunks/{start-opentui-ui-BFYCJQRZ.js → start-opentui-ui-WLV43247.js} +2007 -1003
- package/chunks/{startInteractiveUI-JYAFCMHL.js → startInteractiveUI-F5DKMLOV.js} +1231 -1528
- package/chunks/{syntheticOutput-AUAJBNXR.js → syntheticOutput-D2P5V6RG.js} +2 -2
- package/chunks/{task-create-LD5ISM3E.js → task-create-PMAFST2T.js} +7 -7
- package/chunks/{task-list-YISJ4RJA.js → task-list-R2HSY2NC.js} +1 -1
- package/chunks/{task-stop-65ZOVATJ.js → task-stop-BFSKRTGV.js} +1 -1
- package/chunks/{task-update-AAN4ZVEY.js → task-update-JYC57USF.js} +7 -7
- package/chunks/{team-create-KU7MABNO.js → team-create-2PATB77U.js} +24 -25
- package/chunks/{team-delete-XFRRTJTT.js → team-delete-CBHVBTPB.js} +1 -1
- package/chunks/{team-plan-approval-DPB377A3.js → team-plan-approval-QTANEWOS.js} +24 -25
- package/chunks/{terminal-image-renderer-WGWRENOF.js → terminal-image-renderer-OGULCFNF.js} +37 -38
- package/chunks/{theme-manager-GBUFULSO.js → theme-manager-CNO3QERP.js} +35 -36
- package/chunks/{todoWrite-G7NT4IFP.js → todoWrite-5ERKFWAK.js} +3 -5
- package/chunks/{tool-search-6YUXHBPT.js → tool-search-VXWEOZE7.js} +9 -9
- package/chunks/{total-session-admission-54R2JQ5L.js → total-session-admission-4KAADZPB.js} +41 -42
- package/chunks/{trustedFolders-KAJIDJTH.js → trustedFolders-PPJSOPOT.js} +36 -37
- package/chunks/{update-relaunch-XM4IWBFD.js → update-relaunch-4PT4MW7B.js} +5 -5
- package/chunks/{updateCheck-W6UZFURI.js → updateCheck-WAVFLWNG.js} +37 -38
- package/chunks/{useAutoAcceptIndicator-LAWYHY3U.js → useAutoAcceptIndicator-XNED4NRB.js} +44 -45
- package/chunks/{validateNonInterActiveAuth-7WCKHRN2.js → validateNonInterActiveAuth-J676DUQ2.js} +74 -74
- package/chunks/{version-3ZU43RJ6.js → version-J6SRRQB2.js} +1 -1
- package/chunks/{web-fetch-QHI2SQL4.js → web-fetch-FMZZYX44.js} +7 -7
- package/chunks/{web-search-3KZZKWNY.js → web-search-3G2KXCX5.js} +19 -8
- package/chunks/{workflow-HRW7Y2X4.js → workflow-PPZZICQ7.js} +26 -27
- package/chunks/{workspace-providers-status-KTGCWCPC.js → workspace-providers-status-IIYTAQST.js} +46 -47
- package/chunks/{workspace-registration-store-LHLPPWNE.js → workspace-registration-store-VHCDXAV7.js} +1 -1
- package/chunks/{workspace-registry-X34MLN52.js → workspace-registry-I7VQIPS2.js} +41 -42
- package/chunks/{workspace-runtime-coordinator-U4PW4P7K.js → workspace-runtime-coordinator-DBGNY32G.js} +41 -42
- package/chunks/{workspace-service-KD7BCGYL.js → workspace-service-QSKB2T54.js} +47 -48
- package/chunks/{workspace-skills-status-YJGO6Y3T.js → workspace-skills-status-T7GPT65J.js} +43 -44
- package/chunks/{workspace-trust-reconciler-EUYHISCH.js → workspace-trust-reconciler-2PKRDAU4.js} +48 -49
- package/chunks/{write-file-EBSB34NJ.js → write-file-L76CGFTQ.js} +26 -27
- package/chunks/{zh-TW-W2GNP2IU.js → zh-TW-N2TBF2F2.js} +1 -1
- package/chunks/{zh-DVFYHRK5.js → zh-VBFCRQBL.js} +1 -1
- package/chunks/{zoom-image-UJ5VKWKP.js → zoom-image-TDJJY2VZ.js} +4 -4
- package/cli.js +13 -13
- package/export-transcript-document.js +126 -122
- package/locales/en.js +2 -2
- package/locales/zh-TW.js +2 -2
- package/locales/zh.js +2 -2
- package/package.json +3 -3
- package/web-shell/assets/{abnfDiagram-VCTEODGH-Dur--luQ.js → abnfDiagram-VCTEODGH-DHc6plZn.js} +1 -1
- package/web-shell/assets/{arc-tYLobxFi.js → arc-BQ9m8TDV.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-IG6aXD03.js → architectureDiagram-5GKGNRK7-D5ap3oVB.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-C6eBSkfA.js → blockDiagram-NRAW4CY4-BIbnyNph.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-BrX3HJqB.js → c4Diagram-UCG6FXSJ-BRsdx_iG.js} +1 -1
- package/web-shell/assets/channel-uMMdTrYk.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-B3fcJ8ee.js → chunk-2Q5K7J3B-3lf1fNlx.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-CeC90yKM.js → chunk-5VM5RSS4-DP8VNRc4.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-CW44RVki.js → chunk-F27PBJKO-DrohDmZ6.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-D1PAMukD.js → chunk-G27WJ6UU-UZ2QhSx6.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-Dt3Y2Fvx.js → chunk-JWPE2WC7-BIMHVcZK.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-CZHw2lLI.js → chunk-LCL6LL3I-izRxdSDd.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-ysNAdTGx.js → chunk-POPQ4Y6H-CXADD4PP.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-BdNXW6YQ.js → chunk-SVP7TREG-B96d8Y_1.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-DgqQ9UA8.js → chunk-XXDRQBXY-CF2sVQpv.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DcY-26Ig.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DcY-26Ig.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-BILImXzJ.js → cose-bilkent-JH36ORCC-CT6tXVAS.js} +1 -1
- package/web-shell/assets/csv-CX7rUNeC.svg +1 -0
- package/web-shell/assets/{cynefin-OW5HDTMX-DR88Pund.js → cynefin-OW5HDTMX-X1NS4vtV.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-BYFbfkA6.js → cynefinDiagram-5FMLGOSQ-DNsKNOT4.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-rfpyc6sX.js → dagre-3AP2YEHR-9-AHKqsb.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-BJxLmEwH.js → diagram-S7CK7UJ4-Bjgms7j6.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-H34xm7k3.js → diagram-UQ7AKVKN-h6bCprbE.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-HYxhwNLx.js → diagram-VSXAHHWV-4SbQXVLt.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-BJazso8F.js → diagram-VX7I27RA-B5gPCzzB.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-Clje1aNy.js → diagram-Z3DM3KII-DFJXIA3A.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-M93YBkFh.js → ebnfDiagram-PWID7BFC-FwyaU7VY.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-DY8XzSHU.js → erDiagram-SSCWMZ5O-8vJQh2te.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-CE6Aylcq.js → flowDiagram-A5DVABFB-BzA_1gMN.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-DI-5LL22.js → ganttDiagram-EL5Y4UJY-Co-ABbVX.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-C7BZWElk.js → gitGraphDiagram-WWUBYQGX-DW_FcyrX.js} +1 -1
- package/web-shell/assets/{index-DclFHns9.js → index-BbMXfhNG.js} +1 -1
- package/web-shell/assets/{index-CVyqwW7y.js → index-Bu-rZoJ-.js} +483 -475
- package/web-shell/assets/index-CsPwZ1ut.css +36 -0
- package/web-shell/assets/{infoDiagram-RXCK75RN-CGUSy4Pc.js → infoDiagram-RXCK75RN-BEgfhUFN.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-B5BVks9q.js → ishikawaDiagram-5VMMS53U-DCsMxQmc.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-CFh6Tf7h.js → journeyDiagram-EYS64GPL-DyIEYoHz.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-B7TlxP7c.js → kanban-definition-3QL26DDD-CkxjqCNr.js} +1 -1
- package/web-shell/assets/{layout-Br_pZq2Q.js → layout-BEWc0Al9.js} +1 -1
- package/web-shell/assets/{linear-BVlP6fte.js → linear-CNuNxirL.js} +1 -1
- package/web-shell/assets/{mermaid.core-TrcYWoiF.js → mermaid.core-DZBre674.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-BJ4LzqjZ.js → mindmap-definition-FBJOCRG2-CpafFz_F.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-1b_MxlOl.js → pegDiagram-XKGWAZYB-DfZqk_dq.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-B8zl0YhY.js → pieDiagram-E7YTZNPT-S0UWXlgC.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-CIZO8ukl.js → quadrantDiagram-AXDQQJYC-dd37_Ohj.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-CepHSbCj.js → railroadDiagram-O6MQD6OU-CH8NJZ7u.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-BCgxkcSW.js → requirementDiagram-EFPCY7ZU-CFdqWYih.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-CE5CcoMM.js → sankeyDiagram-P5KCCOFB-CsddcEGD.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DvgHi-d5.js → sequenceDiagram-WJ2MYXX4-BZ270mGw.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-T-fAsCPX.js → sizeCapture-X5ZJPWSS-CGaS4DBV.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-DYHaul-5.js → stateDiagram-HBIQ2CUA-COpIzMu6.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-D6qEVAji.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-Dbz3Qiej.js → swimlanes-XN3QIQJK-CMF889m3.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-mem5Jj4m.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-9NVRts3N.js → timeline-definition-24CTP7MA-BelnxYz5.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-C7cb7vnH.js → vennDiagram-4TSXK5OY-CU-NRqIB.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-CG-8Ddjm.js → wardleyDiagram-VM6X3IG4-CDNKqWh-.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-iGeYAcP4.js → xychartDiagram-S5SC5T6Z-CLqguL5D.js} +1 -1
- package/web-shell/index.html +6 -3
- package/chunks/chunk-3UMWOKJC.js +0 -78
- package/chunks/chunk-FKJM6JKY.js +0 -98
- package/chunks/chunk-IQAFKVXS.js +0 -22
- package/web-shell/assets/channel-uEkvKckd.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-DuPsnhWS.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-DuPsnhWS.js +0 -1
- package/web-shell/assets/index-FO7JXPnH.css +0 -36
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-BcYho9a4.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-D6HsOIgX.js +0 -8
|
@@ -181,6 +181,7 @@ These settings are read from operator scopes only (User, System, and SystemDefau
|
|
|
181
181
|
| `model.maxSessionTurns` | integer | Maximum number of user/model/tool turns to keep in a session. -1 means unlimited. | `-1` |
|
|
182
182
|
| `model.maxWallTimeSeconds` | number | Wall-clock budget for headless / unattended runs, in seconds. `-1` means unlimited. Overridable per-invocation via `--max-wall-time`, which requires a positive duration (`90`, `30s`, `5m`, `1h`, `1.5h`); the minimum is 1 second — sub-second values (`500ms`, `0.5`) are rejected as typos. Omit the flag to fall back to this setting. Aborts with exit code 55 when exceeded. | `-1` |
|
|
183
183
|
| `model.goalTokenBudget` | integer | Autonomous spend window armed on each new Goal, in tokens as counted by the Goal meter (`totalTokenCount` summed over the model calls the Goal makes in its own turns). A Goal that spends its window gets one wind-down turn to hand off, then stops until you resume it, which arms another window. Unset uses the built-in default of 30,000,000; `-1` means unlimited. Zero, values above 300,000,000 (10x the default, a typo guard), other negative, fractional, or non-number values are rejected at startup. | `30000000` |
|
|
184
|
+
| `model.goalCheckpointTimeoutSeconds` | integer | Ceiling on one Goal evidence-checkpoint call, in seconds. A long Goal periodically compresses its evidence into checkpoint claims with a side model call; a call that does not finish in time is abandoned as an inconclusive check — the checkpoint stall streak is preserved rather than incremented — and a later turn retries it. Unset uses the built-in default of 180. Must be an integer between 1 and 900; other values are rejected at startup. The call is streamed, so the per-request transport timeout (`model.generationConfig.timeout`, default 120 s) bounds only connect and first response, and values above 900 are rejected because past the default stream lifetime guard that guard, not this setting, ends the call. The 900 ceiling is fixed: raising `QWEN_STREAM_MAX_LIFETIME_MS` does not lift it. | `180` |
|
|
184
185
|
| `model.maxToolCalls` | number | Cumulative tool-call budget for a run (counts every executed tool, success or failure; `structured_output` under `--json-schema` is exempt). `-1` means unlimited; `0` means "no tool calls allowed". Capped at 1,000,000 to catch typos. Overridable via `--max-tool-calls`. Aborts with exit code 55 when exceeded. | `-1` |
|
|
185
186
|
| `model.maxSubagentDepth` | number | Maximum sub-agent nesting depth (1-based levels: a top-level sub-agent is level 1). `1` keeps sub-agents available but disables nesting — the pre-nesting behavior. Values clamp to the range 1–100; non-finite values fall back to the default. Teammates, forks, and workflow-spawned agents never nest regardless of this setting. Overridable via `--max-subagent-depth`. | `5` |
|
|
186
187
|
| `model.generationConfig` | object | Advanced overrides passed to the underlying content generator. Supports request controls such as `timeout`, `maxRetries`, `retryInitialDelayMs`, `retryMaxDelayMs`, `enableCacheControl`, `splitToolMedia` (default `true`; splits tool-returned media — including images read by the built-in read_file — into a follow-up user message instead of the spec-violating `role: "tool"` message, so strict OpenAI-compatible servers like doubao / new-api / LM Studio can see it; set `false` to restore the legacy embed-in-tool behavior), `toolResultContentFormat` (default `"parts"`; set `"string"` only for legacy OpenAI-compatible runtimes whose tool templates ignore text content parts), `contextWindowSize` (override model's context window size), `modalities` (override auto-detected input modalities), `customHeaders` (custom HTTP headers for API requests), and `extra_body` (additional body parameters for OpenAI-compatible API requests only), along with fine-tuning knobs under `samplingParams` (for example `temperature`, `top_p`, `max_tokens`). Leave unset to rely on provider defaults. | `undefined` |
|
|
@@ -407,13 +408,13 @@ See [Memory](../features/memory) for details on how auto-memory works and how to
|
|
|
407
408
|
|
|
408
409
|
#### agents
|
|
409
410
|
|
|
410
|
-
| Setting | Type | Description
|
|
411
|
-
| ------------------------------ | ---------------- |
|
|
412
|
-
| `agents.builtin.exploreModel` | string | Model selector for the built-in Explore subagent. Use `inherit` for the main session model, `fast` for `fastModel`, a model ID, or an `authType:model-id` selector. A custom same-name Explore agent keeps its own model configuration. Requires restart.
|
|
413
|
-
| `agents.modelGrades` | object | Maps semantic grade names exposed to the Agent tool to model selectors. Requires restart.
|
|
414
|
-
| `agents.allowedGrades` | array of strings | Optional whitelist of configured model grades the Agent tool may use. Requires restart.
|
|
415
|
-
| `agents.crossSessionMessaging` | boolean | Experimental. Let Qwen Code sessions on this machine send each other messages over a per-session local socket. Turning it on opens this session to peer messages, makes it discoverable to others, and lets its model address them from `send_message`. Requires restart. A workspace may set this to `false` only; a workspace `true` is ignored, with a warning only when it would loosen the operator-set or default value.
|
|
416
|
-
| `agents.crossSessionInbound` | enum | What happens to
|
|
411
|
+
| Setting | Type | Description | Default |
|
|
412
|
+
| ------------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
|
|
413
|
+
| `agents.builtin.exploreModel` | string | Model selector for the built-in Explore subagent. Use `inherit` for the main session model, `fast` for `fastModel`, a model ID, or an `authType:model-id` selector. A custom same-name Explore agent keeps its own model configuration. Requires restart. | `inherit` |
|
|
414
|
+
| `agents.modelGrades` | object | Maps semantic grade names exposed to the Agent tool to model selectors. Requires restart. | `undefined` |
|
|
415
|
+
| `agents.allowedGrades` | array of strings | Optional whitelist of configured model grades the Agent tool may use. Requires restart. | `undefined` |
|
|
416
|
+
| `agents.crossSessionMessaging` | boolean | Experimental. Let Qwen Code sessions on this machine send each other messages over a per-session local socket. Turning it on opens this session to peer messages, makes it discoverable to others, and lets its model address them from `send_message`. Requires restart. A workspace may set this to `false` only; a workspace `true` is ignored, with a warning only when it would loosen the operator-set or default value. | `false` |
|
|
417
|
+
| `agents.crossSessionInbound` | enum | What happens to inbound cross-session messages: `accept` delivers them, `hold` parks them for `/peers` review without letting the model act, and `refuse` opts this session out. Unset means [user-minted controllers](../features/commands.md#trusted-controllers) and this session's own child processes auto-deliver, while other sessions use [review-class parity](../features/commands.md#6-messaging-another-running-session); other messages are held for review. A workspace may only tighten this (`hold` or `refuse`, when stricter than the operator-set value or the unset default); an effective unrecognized value holds every message. | `undefined` |
|
|
417
418
|
|
|
418
419
|
#### permissions
|
|
419
420
|
|
|
@@ -661,6 +662,38 @@ Configures logging and metrics collection for Qwen Code. For more information, s
|
|
|
661
662
|
| `telemetry.sensitiveSpanAttributeMaxLength` | number | Maximum JavaScript string length for each sensitive native OTel span attribute content payload. Must be between `1` and `104857600` (100 MiB). Set lower if your collector or backend rejects large attributes. | `1048576` |
|
|
662
663
|
| `telemetry.outfile` | string | Path to write telemetry to a file. When set, overrides OTLP export. | |
|
|
663
664
|
|
|
665
|
+
#### outboundCorrelation
|
|
666
|
+
|
|
667
|
+
⚠️ **Security-relevant.** Controls what client-side correlation data Qwen Code writes into outbound LLM API requests — a separate consent decision from `telemetry.*`, which governs data flowing into your OWN observability backend. All values default to off.
|
|
668
|
+
|
|
669
|
+
| Setting | Type | Description | Default |
|
|
670
|
+
| ---------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
|
671
|
+
| `outboundCorrelation.propagateTraceContext` | boolean | Inject W3C `traceparent` on outbound `fetch` requests and as a `TRACEPARENT` env var in shell child processes. Requires `telemetry.enabled: true`. | `false` |
|
|
672
|
+
| `outboundCorrelation.allowDynamicHeaderValues` | boolean | Allow `customHeaders` values to contain runtime placeholders such as `${session_id}`, expanded per request. When off, such a value is dropped rather than sent. | `false` |
|
|
673
|
+
|
|
674
|
+
```json
|
|
675
|
+
{
|
|
676
|
+
"outboundCorrelation": {
|
|
677
|
+
"allowDynamicHeaderValues": true
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
`allowDynamicHeaderValues` is only the consent switch. _Which_ hosts receive the
|
|
683
|
+
value and _what_ the header is called are decided where the header lives —
|
|
684
|
+
`modelProviders[].generationConfig.customHeaders`, see
|
|
685
|
+
[Dynamic values in `customHeaders`](model-providers.md#dynamic-values-in-customheaders).
|
|
686
|
+
That scoping is why there is no host allowlist here: you already chose the
|
|
687
|
+
endpoint when you wrote the provider's `baseUrl`, and providers that should not
|
|
688
|
+
send the header simply do not carry it.
|
|
689
|
+
|
|
690
|
+
If a provider entry has a placeholder while this is off, the header is dropped
|
|
691
|
+
and a warning naming both is printed at startup — so a gateway rejecting your
|
|
692
|
+
requests should never be a silent mystery.
|
|
693
|
+
|
|
694
|
+
**Privacy note:** an expanded value is a stable per-conversation identifier.
|
|
695
|
+
Only put one on a provider you already send your prompt content to.
|
|
696
|
+
|
|
664
697
|
### Example `settings.json`
|
|
665
698
|
|
|
666
699
|
Here is an example of a `settings.json` file with the nested structure, new as of v0.3.0:
|
|
@@ -791,6 +824,23 @@ When both user-level `.env` files define the same variable, the Qwen-specific
|
|
|
791
824
|
file wins: `<QWEN_HOME>/.env` (or `~/.qwen/.env` when `QWEN_HOME` is unset) is
|
|
792
825
|
loaded before `~/.env`, and existing environment values are not overwritten.
|
|
793
826
|
|
|
827
|
+
### Standalone update download source
|
|
828
|
+
|
|
829
|
+
Set `QWEN_UPDATE_BASE_URL` to use a custom HTTPS release root for standalone updates:
|
|
830
|
+
|
|
831
|
+
```bash
|
|
832
|
+
export QWEN_UPDATE_BASE_URL="https://downloads.example.com/qwen-code"
|
|
833
|
+
qwen update
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
For version `0.23.0`, the updater downloads the platform archive, `SHA256SUMS`, and `SHA256SUMS.sig` from `<base-url>/v0.23.0/`. Host these files using the same names and directory layout as an official release. Existing checksum and signature checks still apply, including `QWEN_REQUIRE_SIGNATURE=1` when a signature is required.
|
|
837
|
+
|
|
838
|
+
The URL must use HTTPS and cannot contain credentials, a query string, or a fragment. Surrounding whitespace and trailing slashes are removed. An empty or whitespace-only value preserves the built-in download sources and their fallback order. When a custom root is set, a failed download does not fall back to the built-in sources.
|
|
839
|
+
|
|
840
|
+
Configure this variable in the launching shell or a user-level `.env` file. It is rejected from project `.env` and `.qwen/.env` files and from the top-level `settings.json` `env` section at every scope. A user-level `.env` value is loaded at startup; restart Qwen Code after changing it.
|
|
841
|
+
|
|
842
|
+
This setting applies to `qwen update`, `/update`, and automatic standalone updates. It does not change npm registry version discovery. It is separate from the installer's `QWEN_INSTALL_BASE_URL`, which points directly to a version-specific directory.
|
|
843
|
+
|
|
794
844
|
## Command-Line Arguments
|
|
795
845
|
|
|
796
846
|
Arguments passed directly when running the CLI can override other configurations for that specific session.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Conversations writer locks and recovery
|
|
2
|
+
|
|
3
|
+
Updated daemons can share Conversations and use different sessions at the same
|
|
4
|
+
time. A loaded session still has one writer. Live activation belongs only to
|
|
5
|
+
the exact publisher of the stable Live locator; losing Live publication does
|
|
6
|
+
not disable standalone conversations.
|
|
7
|
+
|
|
8
|
+
## A conversation will not open
|
|
9
|
+
|
|
10
|
+
`session_writer_conflict` means the writer fence prevented access. It can mean
|
|
11
|
+
another process has the conversation open, or that a residual lock cannot be
|
|
12
|
+
safely reclaimed. It is not proof that another writer is currently alive.
|
|
13
|
+
`session_writer_unavailable` means ownership could not be verified; retrying
|
|
14
|
+
does not authorize bypassing it. Archive and delete can return HTTP 200 with a
|
|
15
|
+
writer error for an individual session. Check every result item.
|
|
16
|
+
|
|
17
|
+
Close the conversation in the owning Qwen process normally, then use **Try
|
|
18
|
+
again** in the affected conversation. You can continue using other sessions.
|
|
19
|
+
Do not create a replacement conversation merely to make the error disappear.
|
|
20
|
+
|
|
21
|
+
After an ungraceful shutdown, a Linux reboot or a container restart into a new
|
|
22
|
+
PID namespace can leave an unsealed active writer record fenced indefinitely.
|
|
23
|
+
There may be no surviving owner to close. Follow
|
|
24
|
+
[Operator recovery for a residual lock](#operator-recovery-for-a-residual-lock)
|
|
25
|
+
instead of repeatedly retrying; this release does not reclaim across those
|
|
26
|
+
identity boundaries automatically.
|
|
27
|
+
|
|
28
|
+
If it persists, enable local debug logging (`QWEN_DEBUG_LOG_FILE=1`) when
|
|
29
|
+
starting the affected daemon and inspect the daemon and ACP child's diagnostics.
|
|
30
|
+
Lease-acquisition diagnostics include the session ID, error kind, and exact
|
|
31
|
+
`lockPath` resolved from that writer's runtime storage. Do not guess a lock path
|
|
32
|
+
from the primary workspace or a default home directory. Public HTTP/ACP errors
|
|
33
|
+
intentionally omit paths and ownership records. Keep diagnostic files private;
|
|
34
|
+
do not publish owner tokens or unredacted lock contents.
|
|
35
|
+
|
|
36
|
+
## Which state can recover automatically?
|
|
37
|
+
|
|
38
|
+
These rules apply to session writer leases. Legacy global owner records use
|
|
39
|
+
the more limited compatibility check described below.
|
|
40
|
+
|
|
41
|
+
- Normal close releases the lease. A certified sealed handoff is accepted only
|
|
42
|
+
when its transcript proof is still valid.
|
|
43
|
+
- A dead active writer is reclaimable only when the existing identity checks
|
|
44
|
+
establish that its process belongs to the same verified liveness domain.
|
|
45
|
+
- Live or stalled writers remain fenced. Killing a daemon is insufficient if
|
|
46
|
+
its ACP writer child survives.
|
|
47
|
+
- Foreign or missing boot/process-namespace identity is not proof of death.
|
|
48
|
+
An absent PID in your namespace does not prove a foreign writer exited.
|
|
49
|
+
- Malformed records, uncertain transcript identity, and residual transition
|
|
50
|
+
claims fail closed. Elapsed time alone never authorizes takeover.
|
|
51
|
+
|
|
52
|
+
## Operator recovery for a residual lock
|
|
53
|
+
|
|
54
|
+
1. Identify the exact affected session and storage from local diagnostics.
|
|
55
|
+
Preserve the failure log and a private backup of its transcript and lock
|
|
56
|
+
artifacts. Record which binaries and hosts may access this storage.
|
|
57
|
+
2. Stop or otherwise fence **every possible writer**, including detached ACP
|
|
58
|
+
children, other daemons, containers, namespaces, and machines sharing the
|
|
59
|
+
filesystem. Verify the fence from the relevant host/namespace. If you cannot
|
|
60
|
+
establish this, stop here and ask an operator who can.
|
|
61
|
+
3. Inspect the exact record and any associated claim/retired artifacts with a
|
|
62
|
+
maintainer. Determine whether the last transcript and handoff proof are
|
|
63
|
+
authoritative. Do not edit ownership identity fields to manufacture a match.
|
|
64
|
+
4. Only after writers are fenced and evidence is backed up, move individually
|
|
65
|
+
verified residual artifacts to private recovery storage under operator
|
|
66
|
+
supervision. Never recursively delete a lock directory or remove all locks.
|
|
67
|
+
5. Start one updated daemon, restore the original session, and verify its last
|
|
68
|
+
recorded turn before appending. Retain the backups until continuity is
|
|
69
|
+
confirmed. Bring other updated daemons back only after that check.
|
|
70
|
+
|
|
71
|
+
There is no force-unlock API or automatic cross-boot/TTL takeover in this
|
|
72
|
+
release. When safe ownership cannot be established, retain the fence.
|
|
73
|
+
|
|
74
|
+
## Coordinated upgrade and rollback
|
|
75
|
+
|
|
76
|
+
The backend cutover and Web Shell local-error/retry changes must ship in the
|
|
77
|
+
same release. This is **not a mixed-version rolling upgrade**: older daemons
|
|
78
|
+
can create a global owner after an updated daemon has already started.
|
|
79
|
+
|
|
80
|
+
Before upgrading, drain all old sessions and scheduled work, stop all old
|
|
81
|
+
daemons and their ACP children, preserve runtime data, and only then start the
|
|
82
|
+
updated binaries. An updated daemon encountering a live legacy owner returns
|
|
83
|
+
`503 conversation_runtime_in_use`; after that owner exits, retry without
|
|
84
|
+
restarting. Only an exactly revalidated stale legacy record is retired.
|
|
85
|
+
Malformed or unsafe legacy state requires operator investigation.
|
|
86
|
+
|
|
87
|
+
The legacy `conversations/runtime-owner.json` record carries a PID and nonce,
|
|
88
|
+
but no hostname, boot ID, or PID-namespace identity. Its compatibility check
|
|
89
|
+
can only test whether that PID exists in the updated daemon's own host and
|
|
90
|
+
PID namespace. It cannot detect an old writer that is alive elsewhere on shared
|
|
91
|
+
storage. This is another reason to fence every possible writer before starting
|
|
92
|
+
an updated daemon; the check does not make mixed-host or mixed-namespace
|
|
93
|
+
upgrades safe.
|
|
94
|
+
|
|
95
|
+
Before rollback, drain and fence every updated daemon and writer too. Inventory
|
|
96
|
+
active, sealed, claim, retired, and extended-schema records. Confirm the target
|
|
97
|
+
binary understands each retained schema and handoff state; never feed an
|
|
98
|
+
unsupported schema to an older writer or delete its protective record to make
|
|
99
|
+
rollback proceed. If compatibility cannot be established, keep writers stopped
|
|
100
|
+
and use maintainer-guided recovery or the coherent pre-upgrade backup. Never
|
|
101
|
+
restore an old transcript over later authoritative turns without explicitly
|
|
102
|
+
accounting for those turns.
|
|
@@ -105,6 +105,32 @@ you edit other fields.
|
|
|
105
105
|
|
|
106
106
|
Set `"useConnectionManager": false` to disable Qwen Code's connection manager and fall back to the SDK's keepalive and automatic reconnect behavior.
|
|
107
107
|
|
|
108
|
+
### Background Agent Responses
|
|
109
|
+
|
|
110
|
+
Background Agent output is sent as soon as each response segment is available.
|
|
111
|
+
Every message is labeled with the Agent name so concurrent work remains
|
|
112
|
+
attributable.
|
|
113
|
+
|
|
114
|
+
To buffer each Agent's notification turn and send it as one labeled message,
|
|
115
|
+
enable aggregation for the DingTalk channel in `settings.json`:
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"channels": {
|
|
120
|
+
"my-dingtalk": {
|
|
121
|
+
"type": "dingtalk",
|
|
122
|
+
"clientId": "$DINGTALK_CLIENT_ID",
|
|
123
|
+
"clientSecret": "$DINGTALK_CLIENT_SECRET",
|
|
124
|
+
"aggregateBackgroundAgentResponses": true
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Aggregation is disabled by default. A partial labeled message is sent if the
|
|
131
|
+
Agent turn is interrupted, fails before producing a final response, or does
|
|
132
|
+
not finish within ten minutes.
|
|
133
|
+
|
|
108
134
|
## Running
|
|
109
135
|
|
|
110
136
|
```bash
|
|
@@ -118,7 +118,7 @@ The catalog is private to the exact channel, chat, and sender. Task names use 1
|
|
|
118
118
|
|
|
119
119
|
Named results identify their originating task: direct chats use `[task]`, while group chats use `[sender · task]`. Named text permission prompts also show the exact request ID and the corresponding `/approve <id>`, `/approve-always <id>`, and `/deny <id>` commands. The label is presentation-only and is not stored in the model transcript.
|
|
120
120
|
|
|
121
|
-
One task remains selected to receive the next normal message, but other named tasks may keep running concurrently. `/session new <name>` shares the configured workspace, while `/session new <name> --worktree` creates an isolated checkout for that task under the daemon workspace's `.qwen/worktrees/` directory. The daemon verifies the persisted worktree owner before reopening the task after a restart; a missing, changed, or foreign ownership record fails closed instead of silently moving the task into the shared workspace. Creating or selecting another task does not cancel or retarget earlier work, and late results retain their originating task label. A busy task cannot be closed, but its active prompt can be cancelled with `/session cancel [<name>]` through the existing Channel cancellation behavior. Independently queued turns are not cancelled, but in `collect` dispatch mode any follow-ups buffered behind the cancelled prompt are discarded by that existing behavior. Media preparation is not targeted. Bare permission commands apply only to the selected task, while an explicit request ID can answer an owned inactive task. `/clear`, `/new`, and `/reset`
|
|
121
|
+
One task remains selected to receive the next normal message, but other named tasks may keep running concurrently. `/session new <name>` shares the configured workspace, while `/session new <name> --worktree` creates an isolated checkout for that task under the daemon workspace's `.qwen/worktrees/` directory. The daemon verifies the persisted worktree owner before reopening the task after a restart; a missing, changed, or foreign ownership record fails closed instead of silently moving the task into the shared workspace. Creating or selecting another task does not cancel or retarget earlier work, and late results retain their originating task label. A busy task cannot be closed, but its active prompt can be cancelled with `/session cancel [<name>]` through the existing Channel cancellation behavior. Independently queued turns are not cancelled, but in `collect` dispatch mode any follow-ups buffered behind the cancelled prompt are discarded by that existing behavior. Media preparation is not targeted. Bare permission commands apply only to the selected task, while an explicit request ID can answer an owned inactive task. `/clear`, `/new`, and `/reset` also work on a selected worktree task: the task gets a fresh conversation while its worktree and files are kept. A busy worktree task refuses the reset until its prompt finishes, and a task whose worktree record was damaged reports the failure without touching files. Channel memory remains scoped to the chat rather than to a named task.
|
|
122
122
|
|
|
123
123
|
This mode is unavailable in standalone `qwen channel start`, with webhooks, with non-zero channel or group `groupHistoryLimit`, or with Channel loops. If an enabled loop already exists for that channel, the daemon worker refuses to start until the loop is disabled.
|
|
124
124
|
|
|
@@ -100,7 +100,7 @@ Commands for managing AI tools and models.
|
|
|
100
100
|
| → `auto-edit` | Auto-approve edits (trusted environment) | `/approval-mode auto-edit` |
|
|
101
101
|
| → `auto` | Classifier-evaluated approval (autonomous) | `/approval-mode auto` |
|
|
102
102
|
| → `yolo` | Auto-approve everything (quick prototyping) | `/approval-mode yolo` |
|
|
103
|
-
| `/peers` | Review
|
|
103
|
+
| `/peers` | Review held peer messages; manage trusted controllers | `/peers`, `/peers accept <id>`, `/peers deny all`, `/peers controllers`, `/peers revoke <id>` |
|
|
104
104
|
| `/model` | Switch model used in current session | `/model`, `/model <model-id>` (switch immediately) |
|
|
105
105
|
| `/model --fast` | Set a lighter model for prompt suggestions | `/model --fast qwen3-coder-flash` |
|
|
106
106
|
| `/model --voice` | Set the model used for voice transcription | `/model --voice <model-id>` |
|
|
@@ -711,10 +711,11 @@ These commands are run from the shell as `qwen <subcommand>` before starting an
|
|
|
711
711
|
|
|
712
712
|
### Session Management
|
|
713
713
|
|
|
714
|
-
| Command
|
|
715
|
-
|
|
|
716
|
-
| `qwen sessions list`
|
|
717
|
-
| `qwen sessions ps`
|
|
714
|
+
| Command | Description | Usage Examples |
|
|
715
|
+
| --------------------------- | ------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
716
|
+
| `qwen sessions list` | List recent conversation sessions | `qwen sessions list`, `qwen sessions list --json --limit 50` |
|
|
717
|
+
| `qwen sessions ps` | List interactive sessions running right now | `qwen sessions ps`, `qwen sessions ps --json` |
|
|
718
|
+
| `qwen sessions controllers` | Manage trusted controller tokens | `qwen sessions controllers add --label <name>`, `qwen sessions controllers list` |
|
|
718
719
|
|
|
719
720
|
#### `qwen sessions list`
|
|
720
721
|
|
|
@@ -780,7 +781,7 @@ object with fields:
|
|
|
780
781
|
|
|
781
782
|
```
|
|
782
783
|
schemaVersion, pid, procStart, pidNs, sessionId, cwd, name, startedAt,
|
|
783
|
-
qwenVersion
|
|
784
|
+
qwenVersion, ipcPath (when peer messaging is available)
|
|
784
785
|
```
|
|
785
786
|
|
|
786
787
|
Nothing else is written to stdout — an empty listing prints nothing at
|
|
@@ -914,3 +915,67 @@ anything else. The model sees it as
|
|
|
914
915
|
`<cross_session_message from="own process" origin="own-process">` with a
|
|
915
916
|
notice that it came from a script or hook the session ran, not from the
|
|
916
917
|
user.
|
|
918
|
+
|
|
919
|
+
### Trusted controllers
|
|
920
|
+
|
|
921
|
+
The rule above holds a message from any sender that does not say which
|
|
922
|
+
review class it is in, and a program that is not a Qwen Code session has
|
|
923
|
+
none to say. That is the right default for a stranger, but not for a
|
|
924
|
+
program you chose: a voice front-end, a dictation bridge, an automation
|
|
925
|
+
daemon relaying your own instructions would have every message parked,
|
|
926
|
+
and approving each one by hand defeats the point.
|
|
927
|
+
|
|
928
|
+
You grant such a program delivery by minting it a token:
|
|
929
|
+
|
|
930
|
+
```bash
|
|
931
|
+
qwen sessions controllers add --label voice-bridge
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
The token is printed once and is not stored anywhere: the file under
|
|
935
|
+
your Qwen home keeps only its SHA-256 hash, so nothing that later reads
|
|
936
|
+
that file can present the token. Put it in the controller's own
|
|
937
|
+
configuration when the command prints it.
|
|
938
|
+
|
|
939
|
+
A controller presents the token the way any other sender does — as the
|
|
940
|
+
first line of the connection — and takes the socket path from the
|
|
941
|
+
session registry (`qwen sessions ps --json` prints one record per live
|
|
942
|
+
session, `ipcPath` being the address):
|
|
943
|
+
|
|
944
|
+
```bash
|
|
945
|
+
{ printf '%s\n' \
|
|
946
|
+
'{"msgV":1,"type":"auth","token":"'"$QWEN_CONTROLLER_TOKEN"'"}' \
|
|
947
|
+
'{"msgV":1,"msgId":"'"$(uuidgen)"'","type":"user","priority":"next","message":{"role":"user","content":"open the failing test"}}'; \
|
|
948
|
+
} | socat - UNIX-CONNECT:"$SESSION_IPC_PATH"
|
|
949
|
+
```
|
|
950
|
+
|
|
951
|
+
A message that arrives on a granted token is delivered without
|
|
952
|
+
per-message review, whatever review class either side is in — but it
|
|
953
|
+
still yields to an explicit setting: an `agents.crossSessionInbound` of
|
|
954
|
+
`hold` parks it like anything else, and `refuse` turns it away. Grants
|
|
955
|
+
belong to your Qwen home rather than to one session, so a controller
|
|
956
|
+
reaches whichever sessions you are running, and sessions re-read the
|
|
957
|
+
file on every connection: minting or revoking one takes effect on the
|
|
958
|
+
next connection, with nothing to restart.
|
|
959
|
+
|
|
960
|
+
```bash
|
|
961
|
+
qwen sessions controllers list # ids, labels, when they were added
|
|
962
|
+
qwen sessions controllers remove c_1a2b # revoke one
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
`/peers controllers` and `/peers revoke <id>` do the same from inside a
|
|
966
|
+
session. A message that came through a grant is shown as
|
|
967
|
+
`Message from a trusted controller (voice-bridge)`, and appears in
|
|
968
|
+
`/peers` as `[controller] voice-bridge` if a `hold` setting parked it.
|
|
969
|
+
|
|
970
|
+
The model sees such a message as
|
|
971
|
+
`<cross_session_message from="controller" origin="controller" controller="voice-bridge">`,
|
|
972
|
+
with a notice that it relays your own instructions — and the same two
|
|
973
|
+
prohibitions that apply to every other origin: it may not edit
|
|
974
|
+
permission settings, QWEN.md, or config because the message asked, and
|
|
975
|
+
it may not treat the message as you approving a pending confirmation
|
|
976
|
+
prompt. A controller can say what to do next; it cannot answer a prompt
|
|
977
|
+
on your behalf.
|
|
978
|
+
|
|
979
|
+
Anyone who holds the token can send as that controller, so treat it like
|
|
980
|
+
any other credential: give it to one program, keep it out of shared
|
|
981
|
+
config, and revoke it when that program is done.
|
|
@@ -25,8 +25,8 @@ Node.js 22 or later and npm are required.
|
|
|
25
25
|
When first used, the skill runs these commands itself:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
qwen mcp add --scope user node-repl npx -y @qwen-code/node-repl-mcp@0.1.
|
|
29
|
-
npm install --no-save --package-lock=false @qwen-code/cua-sdk@0.20.
|
|
28
|
+
qwen mcp add --scope user node-repl npx -y @qwen-code/node-repl-mcp@0.1.3
|
|
29
|
+
npm install --no-save --package-lock=false @qwen-code/cua-sdk@0.20.4
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
Restart Qwen Code after the MCP server is first added. The skill then resumes
|
|
@@ -45,11 +45,13 @@ Ask Qwen Code to use `$computer-use` for the desktop task. After bootstrap, it
|
|
|
45
45
|
follows the standard Computer Use workflow:
|
|
46
46
|
|
|
47
47
|
1. discovers the exact application and window;
|
|
48
|
-
2. observes full accessibility state
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
2. observes full accessibility state, then accumulates automatic incremental
|
|
49
|
+
updates into the current state;
|
|
50
|
+
3. performs one or more actions through current semantic element tokens,
|
|
51
|
+
including unchanged tokens retained across compatible diffs;
|
|
52
|
+
4. fetches the latest state before deciding what to do next; and
|
|
53
|
+
5. closes the SDK client and resets the REPL only when no other persistent
|
|
54
|
+
state is needed.
|
|
53
55
|
|
|
54
56
|
The driver is the only component that computes observation diffs. Model code
|
|
55
57
|
uses the typed SDK methods and does not dispatch arbitrary driver tool names.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Qwen Code can predict what you want to type next and show it as placeholder text in the input area. This feature uses an LLM call to analyze the conversation context and generate a natural next step suggestion.
|
|
4
4
|
|
|
5
|
-
This feature works end-to-end in both the CLI and Web Shell. Generation is automatic and server-side: after each completed turn the daemon emits the suggestion on the session stream (on by default; set `ui.enableFollowupSuggestions` to `false` to opt out), and Web Shell's composer already wires the `useDaemonFollowupSuggestion` hook, so suggestions render and accept with no additional host wiring.
|
|
5
|
+
This feature works end-to-end in both the CLI and Web Shell. Generation is automatic and server-side: after each cleanly completed turn (the daemon's `end_turn` stop reason — a `cancelled`, `refusal`, `max_tokens`, or `max_turn_requests` turn gets none) the daemon emits the suggestion on the session stream (on by default; set `ui.enableFollowupSuggestions` to `false` to opt out), and Web Shell's composer already wires the `useDaemonFollowupSuggestion` hook, so suggestions render and accept with no additional host wiring.
|
|
6
6
|
|
|
7
7
|
## How It Works
|
|
8
8
|
|
|
@@ -36,7 +36,7 @@ Suggestions are generated when all of the following conditions are met:
|
|
|
36
36
|
- The approval mode is not set to `plan`
|
|
37
37
|
- The feature is enabled (on by default — set `ui.enableFollowupSuggestions` to `false` to turn it off)
|
|
38
38
|
|
|
39
|
-
Suggestions will not appear in non-interactive mode (e.g., headless/SDK mode).
|
|
39
|
+
Suggestions will not appear in the CLI's non-interactive mode (e.g., headless/SDK mode). In the daemon, generation is server-side and runs after every turn that meets the conditions above, so a headless or SDK client that cannot render the suggestion should set `ui.enableFollowupSuggestions` to `false` to avoid the per-turn LLM cost.
|
|
40
40
|
|
|
41
41
|
Suggestions are automatically dismissed when:
|
|
42
42
|
|
|
@@ -16,13 +16,17 @@ A Goal keeps Qwen Code working across turns until a stated condition is met. Set
|
|
|
16
16
|
|
|
17
17
|
Creating, editing, or resuming a Goal requires a trusted workspace (`/trust`). Headless usage is covered in [Headless Mode](./headless.md#run-a-persistent-goal).
|
|
18
18
|
|
|
19
|
+
Once a Goal has billed a turn, the footer pill and every status card show what it has spent against the window it is allowed, as `1.2k/30.0m`. The figure counts the model calls the Goal makes in its own turns; subagents and the verifier's own checks are not included. The window is set by [`model.goalTokenBudget`](../configuration/settings.md); resuming a Goal that has spent its window grants another one on top of what it has already spent, so the figure reads `30.0m/60.0m` rather than starting over. A Goal with no budget shows only what it has spent. A Goal that has not billed a turn yet shows no figures at all.
|
|
20
|
+
|
|
21
|
+
A long Goal periodically compresses the evidence it has recorded into checkpoint claims with a side model call, so later turns and the verifier still have it to cite. That call is bounded by [`model.goalCheckpointTimeoutSeconds`](../configuration/settings.md), 180 seconds by default; a checkpoint that does not finish in time is abandoned as an inconclusive check — the checkpoint stall streak is preserved rather than incremented — and a later turn retries it. The call is streamed, so the per-request transport timeout bounds only connect and first response, and the ceiling itself stops at the stream guards' 15-minute lifetime cap because past that the guard, not the setting, ends the call. That 15-minute limit on the setting is fixed, and raising the stream guard's own cap does not lift it.
|
|
22
|
+
|
|
19
23
|
## Interrupting a Goal
|
|
20
24
|
|
|
21
25
|
Cancelling a Goal turn pauses the Goal. Press Esc while the model is answering or while its tools are still running, and the turn stops, the Goal moves to `paused`, and the card and `/goal` both say why it stopped. Nothing continues until you run `/goal resume`.
|
|
22
26
|
|
|
23
27
|
Typing a message while a Goal is active does not pause it. Your message runs as the next Goal turn, so use it to steer the work; use `/goal pause` or `/goal clear` to stop it.
|
|
24
28
|
|
|
25
|
-
Every pause states its reason: that you interrupted it, that you ran `/goal pause`, that the session token limit blocked the next model request, or that the
|
|
29
|
+
Every pause states its reason: that you interrupted it, that you ran `/goal pause`, that the session token limit blocked the next model request, that the turn failed, or that three turns in a row recorded nothing the verifier could judge and no proposal — Goal bookkeeping reads (`get_goal`, `update_goal`) do not count as progress. A Goal stopped by a limit keeps the reason for that limit instead.
|
|
26
30
|
|
|
27
31
|
## How a Goal is judged
|
|
28
32
|
|
|
@@ -50,6 +54,8 @@ Put these into the objective, in this order:
|
|
|
50
54
|
|
|
51
55
|
Keep it to one objective. `/goal set` and `/goal edit` accept any length, but stay roughly under 1,200 characters: the objective is re-sent on every Goal turn. An objective the model proposes through `propose_goal` is capped at 1,500 characters. Both commands collapse newlines to spaces, so number the items rather than relying on line breaks.
|
|
52
56
|
|
|
57
|
+
`Budget` is an instruction to the model about when to stop and report a blocker. Writing a turn count or time limit in the objective does not configure a runtime timer or change the Goal's token budget.
|
|
58
|
+
|
|
53
59
|
| Weak | Why it fails | Stronger |
|
|
54
60
|
| -------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
55
61
|
| make checkout faster | No threshold, no check. | `Outcome: checkout p95 is below 250 ms. Done when: 1) npm run bench:checkout exits 0 and prints p95 < 250 (paste the line); 2) npm test exits 0. Must not: change the benchmark or skip tests. Budget: stop as blocked after 20 turns.` |
|
|
@@ -59,9 +65,15 @@ Keep it to one objective. `/goal set` and `/goal edit` accept any length, but st
|
|
|
59
65
|
|
|
60
66
|
## Let `/goal-draft` write it
|
|
61
67
|
|
|
62
|
-
`/goal-draft <what you want done>` is a bundled skill that does the above for you. It
|
|
68
|
+
`/goal-draft <what you want done>` is a bundled skill that does the above for you. It reads only enough of the workspace to establish the scope and real verification commands, without running tests, building, installing dependencies, or starting services. It asks at most one round of questions when essential choices are unclear, then writes a compact objective, usually with 3–5 completion checks (fewer when enough). Explicit requirements are preserved; it does not add checks just to reach a count.
|
|
69
|
+
|
|
70
|
+
For an audit, completion means covering the agreed scenarios and reporting evidence, including reproduction steps for confirmed defects. Finding no defects is a valid result. The draft should not invent a minimum number of scenarios, evidence files, exploration rounds, or defects.
|
|
71
|
+
|
|
72
|
+
If a success criterion, command, input path, or essential decision cannot be established, the skill returns a draft marked "Needs clarification" with `<TODO: …>` items. It does not offer that draft for approval or print a runnable `/goal set` or `/goal edit` command. Nonessential defaults are marked `[ASSUMPTION]`; they do not stand in for missing success criteria.
|
|
73
|
+
|
|
74
|
+
Once the objective is ready, an interactive terminal session can show the `propose_goal` approval dialog described below. Web Shell and other ACP clients, headless runs, sessions with the tool disabled, and sessions with an active Goal receive a command to run manually instead. The hand-off says that the draft has not been applied. The skill never starts the work itself, and nothing is set without your approval.
|
|
63
75
|
|
|
64
|
-
Pass an existing objective to tighten it: `/goal-draft all tests pass and the lint is clean`.
|
|
76
|
+
Pass an existing objective to tighten it: `/goal-draft all tests pass and the lint is clean`. For an active Goal, an explicit request to tighten it produces `/goal edit`; a replacement uses `/goal set`. If the intended operation is unclear, the skill includes that choice in its single round of questions.
|
|
65
77
|
|
|
66
78
|
### Approve a Goal the model proposes
|
|
67
79
|
|
|
@@ -190,6 +190,46 @@ disable-model-invocation: true
|
|
|
190
190
|
|
|
191
191
|
You can combine both fields, but then the Skill is not reachable through the normal user or model invocation paths.
|
|
192
192
|
|
|
193
|
+
### Optional: enforce a rule deterministically (`hooks:`)
|
|
194
|
+
|
|
195
|
+
Everything in a `SKILL.md` body is an instruction to the model: it is prompt text, so following it depends on the model. When a rule must hold no matter what the model decides — refuse to run unless a required value was injected, never touch a protected path — declare a [hook](hooks.md) in the frontmatter instead. Hooks run as code, so they do not depend on the model's cooperation:
|
|
196
|
+
|
|
197
|
+
```yaml
|
|
198
|
+
---
|
|
199
|
+
name: gated-skill
|
|
200
|
+
description: Calls the downstream CLI using a runtime-injected session ID
|
|
201
|
+
hooks:
|
|
202
|
+
PreToolUse:
|
|
203
|
+
- matcher: run_shell_command
|
|
204
|
+
hooks:
|
|
205
|
+
- type: command
|
|
206
|
+
command: '"$QWEN_SKILL_ROOT/scripts/gate-session-id.sh"'
|
|
207
|
+
---
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`$QWEN_SKILL_ROOT` is set to the Skill's own directory, so hook commands can reference files shipped alongside `SKILL.md`. The command string is handed to a shell, so **keep the inner quotes**: unquoted, a project path containing a space splits into two words and the gate never runs. **Make the script executable** (`chmod +x`) too. Both mistakes fail open in the same way: the tool call proceeds, and nothing appears in the transcript or the log to say the gate did not run. A `PreToolUse` hook blocks the tool call when it exits with code `2` (stderr is fed back to the model as the reason), or when it prints `hookSpecificOutput.permissionDecision: "deny"`:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
#!/usr/bin/env bash
|
|
214
|
+
if [ -z "${DOWNSTREAM_SESSION_ID:-}" ]; then
|
|
215
|
+
echo "Required input DOWNSTREAM_SESSION_ID is not available. Cannot proceed." >&2
|
|
216
|
+
exit 2
|
|
217
|
+
fi
|
|
218
|
+
exit 0
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Notes:
|
|
222
|
+
|
|
223
|
+
- Hooks are registered when the Skill is invoked and last for the rest of the session. This is true on both invocation paths — whether the model calls the Skill or you type `/<skill-name>`.
|
|
224
|
+
- Session hooks live only in memory, so resuming a session with `--continue` / `--resume` does **not** restore them, on either invocation path. The Skill's instructions can come back with the replayed conversation while the hooks meant to enforce them are gone — re-run the Skill after resuming to re-arm its gate.
|
|
225
|
+
- Registration is idempotent: re-invoking a Skill does not stack duplicate hooks.
|
|
226
|
+
- Always give a tool event an explicit `matcher:`. An omitted one is stored as the empty pattern, which is compiled to `^$` and matches no tool name — the hook registers and then never fires, with nothing to say so. Use `*` if you mean every tool.
|
|
227
|
+
- The `command:` runs through the platform shell: `bash` on macOS and Linux, and on Windows Git Bash when it is detected (`MSYSTEM`/`TERM`), otherwise `cmd.exe` or PowerShell. The example above is POSIX shell — under `cmd.exe` `$QWEN_SKILL_ROOT` is not expanded and a `.sh` script is not executable, so the gate fails open there. A hook may set `shell: bash` to force bash, but that resolves to whatever `bash` is on `PATH`, so on Windows outside Git Bash write the gate for the shell you actually have.
|
|
228
|
+
- Sessions that disable hooks register none of them — `disableAllHooks`, safe mode, and an ACP client's `skipHooks`. The Skill's body and its `allowedTools` still apply in those sessions, but its gate does not, so a rule you rely on a hook to enforce is not enforced there. Bare mode goes further: no Skills are discovered at all, so there is no body and no `allowedTools` either.
|
|
229
|
+
- A **project** Skill's hooks run repo-supplied commands, so they are registered only in a trusted folder, and trust is re-read every time a hook fires and every time a permission is decided. With an IDE companion connected that value is live: revoking trust silences an already-registered gate — and suspends the Skill's `allowedTools` — at the next tool call, without a restart. Without an IDE connection the value is fixed when the CLI starts, so a change made through the CLI's own trust dialog takes effect on restart. Granting trust never retro-registers: invoke the Skill again.
|
|
230
|
+
- `hooks:` is read for project, user, and bundled Skills. Extension-provided Skills do not support it; use the extension's own manifest-level hooks instead.
|
|
231
|
+
- See [Hooks](hooks.md) for the full event list, matcher syntax, and output format.
|
|
232
|
+
|
|
193
233
|
## Add supporting files
|
|
194
234
|
|
|
195
235
|
Create additional files alongside `SKILL.md`:
|
|
@@ -66,6 +66,12 @@ qwen serve
|
|
|
66
66
|
|
|
67
67
|
The default bind is `127.0.0.1:4170`. Bearer auth is **off** and the primary listener is trusted, so any local process that can reach the port can use the full operator API, including executing code as the daemon user. Route-specific workspace trust, session ownership, `X-Qwen-Client-Id`, permission, feature, validation, and resource checks still apply. The daemon registers the current working directory as its primary workspace; use an absolute `--workspace /path/to/dir` to override it, and repeat the flag to register additional isolated runtimes.
|
|
68
68
|
|
|
69
|
+
For an API-only daemon, disable the Web Shell without narrowing the daemon's REST or SSE API:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
qwen serve --no-web
|
|
73
|
+
```
|
|
74
|
+
|
|
69
75
|
**Open the Web Shell UI.** Browse to `http://127.0.0.1:4170/` (or start the daemon with `qwen serve --open` to launch it automatically) for the full browser terminal — chat, diffs, commit history, tool calls, and permission prompts. The UI is served at the daemon root on the same origin as the API. The rest of this guide uses raw HTTP so you can script against the API directly.
|
|
70
76
|
|
|
71
77
|
For an authenticated single-user launch without manually creating a token, opt in explicitly:
|
|
@@ -99,6 +105,18 @@ curl http://127.0.0.1:4170/daemon/status
|
|
|
99
105
|
The `workspaceCwd` field surfaces the primary compatibility workspace so clients can intentionally omit `cwd` on `POST /session`. Current clients should select a trusted entry from `workspaces[]` and send that entry's `cwd` when targeting a runtime explicitly.
|
|
100
106
|
The `limits.maxPendingPromptsPerSession` field advertises the active per-session prompt admission cap; `null` means the cap is disabled. `limits.maxTotalSessions` advertises the optional daemon-wide fresh-session cap; `null` means unlimited.
|
|
101
107
|
|
|
108
|
+
### Adjust session live-state polling
|
|
109
|
+
|
|
110
|
+
Web Shell refreshes workspace session live-state every **5 seconds** by default. To use a different interval, set the daemon environment variable before starting it:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
QWEN_SESSION_LIVE_STATE_POLL_INTERVAL_MS=10000 qwen serve --web
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The value is an integer in milliseconds, from `1000` to `2147483647`. Missing or invalid values fall back to `5000`. The interval applies to all workspaces served by that daemon; restart the daemon and reload any open Web Shell pages after changing it. Local session actions and returning to a visible tab can still refresh immediately. This only changes live-state polling, not full session-catalog polling.
|
|
117
|
+
|
|
118
|
+
The daemon publishes the effective interval as `sessionLiveStatePollIntervalMs` in `/capabilities`. Web Shell uses that value and falls back to five seconds when connecting to an older daemon that omits it. SDK consumers can read the value when choosing their own polling schedule.
|
|
119
|
+
|
|
102
120
|
### Run channels from the daemon
|
|
103
121
|
|
|
104
122
|
```bash
|
|
@@ -217,7 +235,7 @@ idle daemon returns `initialized: false` with an empty snapshot. Once a
|
|
|
217
235
|
session is alive they switch to `initialized: true` and surface the real
|
|
218
236
|
state.
|
|
219
237
|
|
|
220
|
-
To update workspace Skill settings by name, call `POST /workspace/skills/:name/enable` with `{ "enabled": true | false }` after checking the `workspace_skill_settings_toggle` capability. To change several names, check `workspace_skill_settings_batch_toggle` and call `POST /workspace/skills/enable` with `{ "skillNames": ["review", "deploy"], "enabled": false }`; it processes every structurally valid name together, persists all resulting declaration changes in at most one locked settings write, and refreshes active ACP sessions once when anything changed. These routes write workspace `skills.disabled` and `skills.enabled` without consulting the loaded Skill catalog, so names may be disabled before installation or while their Extension is inactive. Enabling removes a matching workspace disable and records an explicit `skills.enabled` opt-in, even before installation, so this entry can override an Extension's internal Skill disablement. Repeating the same declaration is a no-op (`changed: false`). Their paths and request bodies are unchanged; the settings-specific capabilities replace the retired catalog-validated Skill toggle tags. The batch `errors` array remains for wire compatibility and is empty for structurally valid names. A hard `skills.disabled` entry inherited from a higher scope remains authoritative for effective availability, but does not block the workspace from recording or removing its own declaration. Skill status cells expose `disabledReason` (`hard`, `default`, or `inactive_extension`) and an optional `lockedScope`. Untrusted workspace writes are still rejected. A `deferred` response means no child was live at the liveness check or a changed request lost its child/session during the required refresh; when `changed` is true, the persisted declaration applies when a child starts. Whether a declaration actually changed is reported by `changed` (on each result for a batch request). `skills.disabled` disables both manual and model use, unlike `disable-model-invocation: true`, which keeps direct `/skill-name` invocation available. For V2 Extension batches, check `extension_batch_activation_v2`: `PUT /extensions/activation` changes global defaults, while `PUT /workspaces/:workspace/extensions/activation` changes exact overrides for the selected workspace and accepts `"inherit"` to clear them. Both accept names in `extensionNames`; `enabled` and `disabled` may be declared before installation, while `inherit` for an unknown name is a no-op. Each request returns one operation to poll.
|
|
238
|
+
To update workspace Skill settings by name, call `POST /workspace/skills/:name/enable` with `{ "enabled": true | false }` after checking the `workspace_skill_settings_toggle` capability. To change several names, check `workspace_skill_settings_batch_toggle` and call `POST /workspace/skills/enable` with `{ "skillNames": ["review", "deploy"], "enabled": false }`; it processes every structurally valid name together, persists all resulting declaration changes in at most one locked settings write, and refreshes active ACP sessions once when anything changed. These routes write workspace `skills.disabled` and `skills.enabled` without consulting the loaded Skill catalog, so names may be disabled before installation or while their Extension is inactive. Enabling removes a matching workspace disable and records an explicit `skills.enabled` opt-in, even before installation, so this entry can override an Extension's internal Skill disablement. Repeating the same declaration is a no-op (`changed: false`). Their paths and request bodies are unchanged; the settings-specific capabilities replace the retired catalog-validated Skill toggle tags. The batch `errors` array remains for wire compatibility and is empty for structurally valid names. A hard `skills.disabled` entry inherited from a higher scope remains authoritative for effective availability, but does not block the workspace from recording or removing its own declaration. Skill status cells expose `disabledReason` (`hard`, `default`, or `inactive_extension`) and an optional `lockedScope`. Untrusted workspace writes are still rejected. A `deferred` response means no child was live at the liveness check or a changed request lost its child/session during the required refresh; when `changed` is true, the persisted declaration applies when a child starts. Whether a declaration actually changed is reported by `changed` (on each result for a batch request). `skills.disabled` disables both manual and model use, unlike `disable-model-invocation: true`, which keeps direct `/skill-name` invocation available. For V2 Extension batches, check `extension_batch_activation_v2`: `PUT /extensions/activation` changes global defaults, while `PUT /workspaces/:workspace/extensions/activation` changes exact overrides for the selected workspace and accepts `"inherit"` to clear them. Both accept names in `extensionNames`; `enabled` and `disabled` may be declared before installation, while `inherit` for an unknown name is a no-op. Each request returns one operation to poll. When `extension_activation_explicit_refresh` is advertised, that operation finishes after the activation policy is committed and does not directly refresh active sessions. To apply it immediately, submit the independent primary or workspace-qualified Extension refresh after activation succeeds. Without that explicit refresh, other workspaces can continue using the previous activation for up to the next 30-second generation-reconciler pass; failed reconciliation is retried by later passes.
|
|
221
239
|
|
|
222
240
|
`GET /workspace/env` and `GET /workspace/preflight` always answer with
|
|
223
241
|
`initialized: true` regardless of ACP state. `env` never consults ACP
|