@qwen-code/qwen-code 0.19.8 → 0.19.9-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (451) hide show
  1. package/bundled/qc-helper/SKILL.md +1 -0
  2. package/bundled/qc-helper/docs/configuration/auth.md +40 -55
  3. package/bundled/qc-helper/docs/configuration/model-providers.md +224 -218
  4. package/bundled/qc-helper/docs/configuration/settings.md +68 -51
  5. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  6. package/bundled/qc-helper/docs/features/channels/dingtalk.md +12 -2
  7. package/bundled/qc-helper/docs/features/channels/overview.md +82 -7
  8. package/bundled/qc-helper/docs/features/channels/wecom.md +6 -0
  9. package/bundled/qc-helper/docs/features/code-review.md +109 -41
  10. package/bundled/qc-helper/docs/features/commands.md +45 -44
  11. package/bundled/qc-helper/docs/features/computer-use.md +77 -0
  12. package/bundled/qc-helper/docs/features/hooks.md +29 -0
  13. package/bundled/qc-helper/docs/features/sub-agents.md +21 -0
  14. package/bundled/qc-helper/docs/features/tool-use-summaries.md +19 -23
  15. package/bundled/qc-helper/docs/integration-vscode.md +2 -2
  16. package/bundled/qc-helper/docs/qwen-serve.md +66 -23
  17. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +2 -2
  18. package/bundled/review/DESIGN.md +303 -46
  19. package/bundled/review/SKILL.md +670 -165
  20. package/chunks/MaxSizedBox-BEVSAWZ6.js +70 -0
  21. package/chunks/{StandaloneSessionPicker-EYRGH6PJ.js → StandaloneSessionPicker-2DA2MDDE.js} +81 -79
  22. package/chunks/{acpAgent-GRFTTRHW.js → acpAgent-G3WJU3PS.js} +1318 -465
  23. package/chunks/agent-DD3WSHXE.js +68 -0
  24. package/chunks/agent-headless-MHI7U2CU.js +62 -0
  25. package/chunks/{anthropicContentGenerator-CPF22MA7.js → anthropicContentGenerator-56U3YCP2.js} +187 -31
  26. package/chunks/{artifact-tool-D233YJFH.js → artifact-tool-MIZLXBLF.js} +5 -5
  27. package/chunks/{askUserQuestion-MKL5ZTMC.js → askUserQuestion-XMJVPNWM.js} +6 -6
  28. package/chunks/bridge-HKEWPNB5.js +78 -0
  29. package/chunks/{ca-MKD32FQL.js → ca-C2JTT2N5.js} +68 -6
  30. package/chunks/channel-worker-group-K7QKH6IG.js +13 -0
  31. package/chunks/channel-worker-manager-YSFB4HUU.js +418 -0
  32. package/chunks/channel-worker-supervisor-QCKIOYZD.js +20 -0
  33. package/chunks/chunk-2FMQQXMM.js +38 -0
  34. package/chunks/{chunk-CSOTA7KX.js → chunk-2FO5GFKZ.js} +2 -2
  35. package/chunks/{chunk-QQDPRDVW.js → chunk-2HRYPZT5.js} +1 -1
  36. package/chunks/{chunk-UXEW557D.js → chunk-2J4ZWME4.js} +3 -3
  37. package/chunks/{chunk-P3XEEI3X.js → chunk-2TQXXQMI.js} +36 -7
  38. package/chunks/{chunk-GSHQYYIV.js → chunk-2UW5RFRP.js} +6 -26
  39. package/chunks/{chunk-6IAWPIQ6.js → chunk-2W3OOD4W.js} +5 -3
  40. package/chunks/{chunk-2PSWA5ID.js → chunk-2X56YUSZ.js} +1 -1
  41. package/chunks/{chunk-NQKLOAVJ.js → chunk-2Z5UX4KI.js} +2 -2
  42. package/chunks/chunk-3MX7D6QN.js +516 -0
  43. package/chunks/{chunk-EEN2TKST.js → chunk-43RXPU5Q.js} +2 -2
  44. package/chunks/{chunk-55ZMG67I.js → chunk-4LD5APFL.js} +4 -4
  45. package/chunks/{chunk-WF4FAXDL.js → chunk-4QZ3XHWE.js} +62 -62
  46. package/chunks/chunk-4QZADKJS.js +34 -0
  47. package/chunks/{chunk-UIDXQNMV.js → chunk-4WGODMVR.js} +1 -1
  48. package/chunks/{chunk-E6US47KI.js → chunk-4WKAA4KS.js} +1 -1
  49. package/chunks/{chunk-TI3BWD4D.js → chunk-54UZQ57N.js} +39 -19
  50. package/chunks/{chunk-3GONHQOA.js → chunk-57OAHC2Y.js} +1 -1
  51. package/chunks/{chunk-JZSY4WP3.js → chunk-5DTTYNB7.js} +1 -1
  52. package/chunks/chunk-5HBA2Z7V.js +28 -0
  53. package/chunks/{chunk-SKAZWEV5.js → chunk-5M6IDOMF.js} +35 -98
  54. package/chunks/{chunk-A4BMJM77.js → chunk-5O2XNYP6.js} +1 -0
  55. package/chunks/{chunk-FQNC62B2.js → chunk-5VHASII5.js} +11 -11
  56. package/chunks/{chunk-GO6LNQXT.js → chunk-6AM5D4ME.js} +1 -1
  57. package/chunks/{chunk-BJBWRCSK.js → chunk-6H67XLET.js} +1 -1
  58. package/chunks/{chunk-O7FIRWJV.js → chunk-6JPDCEDB.js} +3 -3
  59. package/chunks/{chunk-3UP777ZS.js → chunk-6RLROE6G.js} +1 -1
  60. package/chunks/{chunk-GN3F6PIU.js → chunk-6WPJRYLZ.js} +5 -5
  61. package/chunks/{chunk-ZERZSAZL.js → chunk-75DOP5OR.js} +2 -2
  62. package/chunks/chunk-7DKX4A5Z.js +91 -0
  63. package/chunks/{chunk-M7S4GK5Z.js → chunk-7IDCQ35Q.js} +147 -30
  64. package/chunks/{chunk-22MNNNXE.js → chunk-7NFB7LBQ.js} +11 -3
  65. package/chunks/{chunk-ZL5HN75Q.js → chunk-7R4DPSRA.js} +37 -3
  66. package/chunks/{chunk-VZ7HY3YU.js → chunk-7STBROEV.js} +3 -3
  67. package/chunks/{chunk-SAIILPQ3.js → chunk-7X7TEQNX.js} +5 -3
  68. package/chunks/{chunk-RMLZAUWH.js → chunk-A3U2TQUL.js} +10 -12
  69. package/chunks/{chunk-IRJWHZWU.js → chunk-A4UCTEB5.js} +2 -2
  70. package/chunks/{chunk-BOBRZZKD.js → chunk-A7W4GQRW.js} +5 -5
  71. package/chunks/{chunk-O33TBKDC.js → chunk-AAUZBE5Y.js} +155 -19
  72. package/chunks/{chunk-SQ2UATK7.js → chunk-ADLYZJYZ.js} +11 -11
  73. package/chunks/{chunk-QYUE6W3T.js → chunk-ALGGS7UH.js} +2 -39
  74. package/chunks/{chunk-WMPVYQ4P.js → chunk-ARKANCNX.js} +3 -2
  75. package/chunks/{chunk-IBY3Q3HG.js → chunk-AU4R7ACM.js} +967 -181
  76. package/chunks/{channel-worker-supervisor-NZQUOEFJ.js → chunk-B7MFJBKE.js} +190 -34
  77. package/chunks/{chunk-HW4N45EE.js → chunk-B7NUUEXC.js} +38 -11
  78. package/chunks/{chunk-3B26UVCX.js → chunk-BLPMRN4B.js} +39 -10
  79. package/chunks/{chunk-ZN5T4BHI.js → chunk-BPZALHVR.js} +2 -2
  80. package/chunks/{chunk-BVYU3ZTI.js → chunk-BXT6PQ73.js} +1020 -942
  81. package/chunks/{chunk-OFEVLU4C.js → chunk-CARU2RR2.js} +1 -1
  82. package/chunks/{chunk-HDOH3QYE.js → chunk-CEGKYZDB.js} +2 -2
  83. package/chunks/{chunk-GLE2YUPU.js → chunk-COH43MRJ.js} +1 -1
  84. package/chunks/{chunk-E5A7LHNN.js → chunk-CPBF7KYF.js} +1 -1
  85. package/chunks/{chunk-UWCTAVOD.js → chunk-CR3C7WXL.js} +1 -1
  86. package/chunks/{chunk-IWKSG2AR.js → chunk-CXAOG665.js} +1 -1
  87. package/chunks/{chunk-64WXLC72.js → chunk-DJ2GSRLV.js} +1 -1
  88. package/chunks/{chunk-QN5NZ3UQ.js → chunk-DMTGGOSA.js} +2 -2
  89. package/chunks/{chunk-27BHARDE.js → chunk-DMVA55W5.js} +2124 -30
  90. package/chunks/{chunk-JPALE3PA.js → chunk-DQCCLVQK.js} +6 -6
  91. package/chunks/{chunk-X2XNQQJI.js → chunk-E2UVIFI2.js} +186 -399
  92. package/chunks/{chunk-KHDZHZMH.js → chunk-E5Z2AVNV.js} +1 -1
  93. package/chunks/{chunk-E7EMCSUG.js → chunk-EAHMOXLL.js} +64 -42
  94. package/chunks/{chunk-VGGOPZUL.js → chunk-EJ3KGYWL.js} +36 -8
  95. package/chunks/{chunk-DIWVZ3VM.js → chunk-ERTHKDKN.js} +5 -5
  96. package/chunks/{chunk-UX6OTBVD.js → chunk-EX5OULP3.js} +2 -2
  97. package/chunks/{chunk-5MBO76SL.js → chunk-F333XEAU.js} +3 -3
  98. package/chunks/{chunk-OACJLMLD.js → chunk-FBU7WRZI.js} +18 -2
  99. package/chunks/{chunk-5IFG2VC4.js → chunk-FCMNKVXT.js} +1 -1
  100. package/chunks/chunk-FEOBU3FA.js +253 -0
  101. package/chunks/{chunk-LAXNEOBG.js → chunk-FI2WSOWX.js} +19 -3
  102. package/chunks/{chunk-E7KNELIZ.js → chunk-FSA7ERJ2.js} +2 -2
  103. package/chunks/{chunk-44NROQYV.js → chunk-GDQQRV43.js} +4 -4
  104. package/chunks/{chunk-ZE6E424U.js → chunk-GN5HJJBO.js} +2 -2
  105. package/chunks/{chunk-O2YT7VB4.js → chunk-GOXKNSDZ.js} +2 -65
  106. package/chunks/{chunk-V35MD7KN.js → chunk-GRC5HGPI.js} +1 -1
  107. package/chunks/{chunk-ON3JA3RU.js → chunk-GTENQOEJ.js} +7 -9
  108. package/chunks/{chunk-S6RLAIUR.js → chunk-GYTKQYDB.js} +1 -1
  109. package/chunks/{chunk-A2X3KLC3.js → chunk-GZXCZHCT.js} +3 -3
  110. package/chunks/{chunk-K5PGHDBN.js → chunk-H6XPXXMH.js} +1 -1
  111. package/chunks/{chunk-PMFULMLX.js → chunk-HCJTURZD.js} +2262 -384
  112. package/chunks/chunk-HGG2RRXD.js +445 -0
  113. package/chunks/{chunk-II73RK2S.js → chunk-HGT6JR3U.js} +20 -1
  114. package/chunks/{chunk-DICGXFAI.js → chunk-HJCVNZLQ.js} +11 -9
  115. package/chunks/{chunk-3GNOQZDC.js → chunk-HJUDVNCO.js} +17663 -14877
  116. package/chunks/{chunk-AYNCLGTW.js → chunk-HRUGYOJN.js} +8 -51
  117. package/chunks/{chunk-KYMBIKIW.js → chunk-HTHUX2T5.js} +1 -1
  118. package/chunks/{chunk-LQ7TMOCE.js → chunk-HTO4JFDZ.js} +1 -1
  119. package/chunks/{chunk-BUZ6HGL4.js → chunk-HWTL6MPR.js} +357 -59
  120. package/chunks/chunk-IDS7MSUP.js +74 -0
  121. package/chunks/{chunk-4CGOWHKM.js → chunk-J4MOFEOK.js} +2 -2
  122. package/chunks/chunk-JCD4FM7K.js +296 -0
  123. package/chunks/{chunk-22IFUCVR.js → chunk-JESCGQM3.js} +1 -1
  124. package/chunks/{chunk-JZHIQJOE.js → chunk-JGO6RFI2.js} +6 -6
  125. package/chunks/{chunk-X3YGAX7V.js → chunk-JGUT3LWZ.js} +9 -2
  126. package/chunks/{chunk-JRQ7EVGE.js → chunk-JW7OOJC6.js} +2 -2
  127. package/chunks/{chunk-OQXDAMKY.js → chunk-KF5MMGG4.js} +8 -8
  128. package/chunks/{chunk-42XGFRJS.js → chunk-KKRTYONM.js} +8 -6
  129. package/chunks/{chunk-GGQQA4JW.js → chunk-KSO42X3Z.js} +15 -2
  130. package/chunks/{chunk-MRO43B25.js → chunk-KW7NOTN6.js} +1 -1
  131. package/chunks/{chunk-54YZOP7P.js → chunk-L573Z2QZ.js} +11894 -5190
  132. package/chunks/{chunk-TLWA7TPR.js → chunk-L5U3ELZX.js} +2 -2
  133. package/chunks/{chunk-YHKAK72D.js → chunk-LHEOLOXU.js} +251 -63
  134. package/chunks/{chunk-H6EMK6QK.js → chunk-LQIDP6K5.js} +11913 -5207
  135. package/chunks/{chunk-I6WGFJJ3.js → chunk-LSEJG6AM.js} +73 -19
  136. package/chunks/{chunk-MZ7BABX3.js → chunk-LXLTBIDP.js} +44 -7
  137. package/chunks/{chunk-HLKG6CZN.js → chunk-M5GB774H.js} +1 -1
  138. package/chunks/{chunk-JCH35JB3.js → chunk-MKK4XGLF.js} +2 -2
  139. package/chunks/{chunk-YKZIAK7C.js → chunk-MO7O5722.js} +424 -40
  140. package/chunks/chunk-MR3PXB6E.js +48 -0
  141. package/chunks/{chunk-A5JOJ77H.js → chunk-MRYWYBQ4.js} +38 -15
  142. package/chunks/{chunk-332PWN27.js → chunk-NHDKSOEY.js} +1 -1
  143. package/chunks/{chunk-TSPB77TG.js → chunk-NRAFASYX.js} +1016 -2967
  144. package/chunks/{chunk-BMFMJINR.js → chunk-OA4JVLSA.js} +28 -2
  145. package/chunks/{chunk-P7M4GA57.js → chunk-OCPBI7J5.js} +1 -1
  146. package/chunks/chunk-OJAMDVF5.js +66 -0
  147. package/chunks/{chunk-IJRL2S3D.js → chunk-OKAIGAYW.js} +6 -6
  148. package/chunks/{chunk-FBET5XZ2.js → chunk-PEJWA3QQ.js} +29 -10
  149. package/chunks/{chunk-L4AMBVQG.js → chunk-PMKW35AT.js} +54 -22
  150. package/chunks/{chunk-AGHU5VRK.js → chunk-PZL23GTM.js} +1 -1
  151. package/chunks/{chunk-PC4ZXHU2.js → chunk-Q6TUALBE.js} +3 -3
  152. package/chunks/{chunk-FXGLL2HL.js → chunk-Q7YDKOGY.js} +1 -1
  153. package/chunks/{chunk-XOHNA2S6.js → chunk-QAW7PIHT.js} +3 -3
  154. package/chunks/{chunk-XYR5RUA5.js → chunk-QE2WJ7FS.js} +10 -3
  155. package/chunks/{chunk-LGFAYIKX.js → chunk-QHTIBUWB.js} +1 -1
  156. package/chunks/{chunk-P3MYAZBY.js → chunk-QMGX2KO2.js} +1 -1
  157. package/chunks/{chunk-Z3I3QJK3.js → chunk-QRUIS3DN.js} +1 -1
  158. package/chunks/{chunk-ITOGNELQ.js → chunk-QSWDGAIC.js} +2 -2
  159. package/chunks/{chunk-PUVCVELY.js → chunk-QUJOI7SR.js} +70 -8
  160. package/chunks/{chunk-GHOTR7HL.js → chunk-QUPXZXLV.js} +1 -1
  161. package/chunks/{chunk-6VK6FIMQ.js → chunk-R5D5JOAM.js} +415 -379
  162. package/chunks/{chunk-CD6USWHZ.js → chunk-R5XLNDE2.js} +2 -2
  163. package/chunks/{chunk-W7EEOR7D.js → chunk-RCEEXIOO.js} +8 -6
  164. package/chunks/{chunk-TLRYABYP.js → chunk-RKUWKYED.js} +1 -1
  165. package/chunks/{chunk-RNBYOUGV.js → chunk-RXFQM6FQ.js} +1 -1
  166. package/chunks/{chunk-QXPI7FEC.js → chunk-S3TWXGKA.js} +4 -4
  167. package/chunks/{chunk-2EM7ECZD.js → chunk-SMSFWUFY.js} +309 -80
  168. package/chunks/{chunk-FV7425LN.js → chunk-SPJQO2CE.js} +18 -5
  169. package/chunks/{chunk-MLZQVCF3.js → chunk-SZRN75WQ.js} +1 -1
  170. package/chunks/{chunk-7RYW5LQV.js → chunk-T2NCM2ET.js} +2 -2
  171. package/chunks/{chunk-Z2Z3GUXZ.js → chunk-TB6UDU4T.js} +1 -1
  172. package/chunks/{chunk-EXPMGZZV.js → chunk-TEGEBB2I.js} +1 -1
  173. package/chunks/{chunk-MX2YXRER.js → chunk-TJTKSVIV.js} +1 -1
  174. package/chunks/{chunk-CCGOFQV3.js → chunk-TQBODCFD.js} +8 -7
  175. package/chunks/chunk-TV6K2FB4.js +224 -0
  176. package/chunks/{chunk-H6BD2ELD.js → chunk-TYAMGABM.js} +2 -2
  177. package/chunks/{chunk-QYNNN7BK.js → chunk-TYLOFD2U.js} +2 -2
  178. package/chunks/{chunk-VRDMOSQS.js → chunk-UDXSXLER.js} +2 -2
  179. package/chunks/{chunk-DHOLNQLC.js → chunk-UFDX27PL.js} +60 -40
  180. package/chunks/{chunk-WHJQ3JUS.js → chunk-UGN6CTNZ.js} +10 -10
  181. package/chunks/{chunk-CHB5SLZZ.js → chunk-UNLRKDMW.js} +4 -4
  182. package/chunks/{chunk-CJCKDMWO.js → chunk-URK542T4.js} +1 -1
  183. package/chunks/{chunk-AHNXYU4O.js → chunk-V6WHFGST.js} +1 -1
  184. package/chunks/{chunk-ZTQ26VBE.js → chunk-VDDGDZMA.js} +1 -1
  185. package/chunks/{chunk-BOBOCR5H.js → chunk-VEETSXYX.js} +4 -4
  186. package/chunks/{chunk-OMX7CUOE.js → chunk-VGC4I5JJ.js} +1 -1
  187. package/chunks/{chunk-43W4YSO6.js → chunk-VJNBRRZG.js} +2 -2
  188. package/chunks/{chunk-WQTHLB5T.js → chunk-VKS7EIOA.js} +7 -7
  189. package/chunks/{chunk-J7RCB6N5.js → chunk-VVDNGM6X.js} +2 -2
  190. package/chunks/{chunk-ER3BKOLB.js → chunk-W7FJ3N32.js} +1 -1
  191. package/chunks/{chunk-3HX5LZ6R.js → chunk-WBL3FJEU.js} +2 -2
  192. package/chunks/{chunk-7LTB54MK.js → chunk-WIEO4CWB.js} +2 -2
  193. package/chunks/chunk-WMC6HH7Y.js +493 -0
  194. package/chunks/{chunk-FEJ2FZ3U.js → chunk-WTNZ6DXB.js} +2 -2
  195. package/chunks/{chunk-L46XKEGM.js → chunk-X6ODDESK.js} +5 -8
  196. package/chunks/chunk-XDPYM5DE.js +71 -0
  197. package/chunks/{chunk-3RW4AZJV.js → chunk-XFSFZCM5.js} +1 -1
  198. package/chunks/{chunk-2MPVVENX.js → chunk-XU457J4V.js} +2 -2
  199. package/chunks/{chunk-SIUQ3YYX.js → chunk-XVNQMZ2I.js} +1 -1
  200. package/chunks/{chunk-SYCJMSIJ.js → chunk-XWRJCPHC.js} +1 -1
  201. package/chunks/{chunk-SUAKHHK7.js → chunk-Y66VOBRP.js} +3 -3
  202. package/chunks/chunk-YAF2MQZ6.js +19 -0
  203. package/chunks/chunk-YHN5SUIJ.js +219 -0
  204. package/chunks/{chunk-BR4QREVK.js → chunk-YQ3U5MUC.js} +1 -1
  205. package/chunks/{chunk-Y6Z2O3WR.js → chunk-YUZI3WAC.js} +1 -1
  206. package/chunks/{chunk-YDOXPLYL.js → chunk-ZA74ZTQU.js} +4564 -1326
  207. package/chunks/{chunk-DCZWC4PF.js → chunk-ZGE3222J.js} +5 -5
  208. package/chunks/chunk-ZP4ZZJJG.js +448 -0
  209. package/chunks/{chunk-AHNJGLFV.js → chunk-ZPAHLFZU.js} +3 -3
  210. package/chunks/cli-entry-path-4VJ3Y6T2.js +10 -0
  211. package/chunks/{computer-use-WMY3UOBX.js → computer-use-SHA6C3ES.js} +50 -50
  212. package/chunks/config-utils-XSHOMMK4.js +24 -0
  213. package/chunks/contextCommand-HOAF5LUC.js +68 -0
  214. package/chunks/create-sub-session-EAB2U5XW.js +207 -0
  215. package/chunks/create-sub-session-WJOWBFEP.js +375 -0
  216. package/chunks/{cron-create-JSXEIPVS.js → cron-create-GMVKSXZT.js} +9 -9
  217. package/chunks/{cron-delete-OIFVEPGU.js → cron-delete-VDZKUAVK.js} +7 -7
  218. package/chunks/{cron-list-D4ZX4IOE.js → cron-list-UG7C7RAR.js} +14 -10
  219. package/chunks/{daemon-WPAENEBW.js → daemon-MI5HF26N.js} +1074 -61
  220. package/chunks/daemon-status-provider-KFL3LRTP.js +76 -0
  221. package/chunks/{de-ZFPPQVSF.js → de-2VCDRDGU.js} +68 -6
  222. package/chunks/{devtools-FM6GJPYG.js → devtools-4QFYJT6U.js} +3 -3
  223. package/chunks/{dist-O2IRTRPP.js → dist-IEXZC5ZR.js} +10 -10
  224. package/chunks/{dist-SCFLLYMK.js → dist-PQK4GCKA.js} +12 -11
  225. package/chunks/{dist-63IS3ZMI.js → dist-PZV5RKM6.js} +4 -4
  226. package/chunks/{dist-E6UANPIM.js → dist-U75JK3PF.js} +1011 -197
  227. package/chunks/{dist-H2AEJCZ5.js → dist-VXO7QBON.js} +5 -5
  228. package/chunks/{dist-Z34QPAQW.js → dist-WH4TZSH3.js} +529 -79
  229. package/chunks/{dist-BEXOZXLQ.js → dist-X2ABIW5R.js} +36 -15
  230. package/chunks/earlyInputCapture-PKAQJMIP.js +69 -0
  231. package/chunks/{edit-OTYWAXGP.js → edit-6TXLYHJ2.js} +51 -51
  232. package/chunks/{en-N4EPZAQI.js → en-NJCA3TAA.js} +78 -6
  233. package/chunks/{enter-worktree-HNYBDVCX.js → enter-worktree-ZTILGPJX.js} +50 -50
  234. package/chunks/{enterPlanMode-CJCNGT63.js → enterPlanMode-62HRAMCH.js} +66 -51
  235. package/chunks/environment-OYA3ZVEL.js +89 -0
  236. package/chunks/errors-BFXOUUUR.js +75 -0
  237. package/chunks/{exit-worktree-DUUKOE3X.js → exit-worktree-HHJ5M6MV.js} +50 -50
  238. package/chunks/{exitPlanMode-AMMSXOAJ.js → exitPlanMode-M3SWHCL7.js} +51 -51
  239. package/chunks/{fast-path-OV6NIP3K.js → fast-path-3VMPLM74.js} +8 -8
  240. package/chunks/{fast-path-settings-7RIFI3PK.js → fast-path-settings-DAOVFADC.js} +8 -6
  241. package/chunks/{fileFromPath-IBEHA3CO.js → fileFromPath-UDALK7FM.js} +3 -3
  242. package/chunks/{fr-5WWMY53B.js → fr-5F3E7WKD.js} +68 -6
  243. package/chunks/{gemini-NQ3WWBKB.js → gemini-ZCGVYOJL.js} +181 -110
  244. package/chunks/{geminiContentGenerator-CDUNEJQE.js → geminiContentGenerator-XBYBAIDQ.js} +9 -9
  245. package/chunks/{getMachineId-bsd-4CASPIU4.js → getMachineId-bsd-EXV7SWPA.js} +3 -3
  246. package/chunks/{getMachineId-darwin-HPQPEMZR.js → getMachineId-darwin-IUOMFXU3.js} +3 -3
  247. package/chunks/{getMachineId-linux-AUARKYHL.js → getMachineId-linux-K7XJYFHL.js} +2 -2
  248. package/chunks/{getMachineId-unsupported-S32ZDA2T.js → getMachineId-unsupported-EA5FDRJ6.js} +2 -2
  249. package/chunks/{getMachineId-win-4EFLHYIJ.js → getMachineId-win-KBA6RAI5.js} +3 -3
  250. package/chunks/{glob-ROV3YS4R.js → glob-UOEYQNHN.js} +97 -75
  251. package/chunks/{grep-NRITKDCD.js → grep-OQM3CH7W.js} +50 -50
  252. package/chunks/handleAutoUpdate-ORBYVJHZ.js +69 -0
  253. package/chunks/i18n-NBP574CO.js +84 -0
  254. package/chunks/initializer-CWD7TCCD.js +73 -0
  255. package/chunks/installationInfo-CHPDUPWC.js +65 -0
  256. package/chunks/{ja-CUHZOLEJ.js → ja-66J6B53L.js} +69 -7
  257. package/chunks/{keychain-token-storage-UJV5XP4Z.js → keychain-token-storage-AU22CQI6.js} +4 -4
  258. package/chunks/{kittyProtocolDetector-OJRCJLIU.js → kittyProtocolDetector-HCNNKJTI.js} +2 -2
  259. package/chunks/list-ZTTO362W.js +76 -0
  260. package/chunks/loadedSettingsAdapter-V4ZTRKUO.js +70 -0
  261. package/chunks/{loop-wakeup-OHWEMFP5.js → loop-wakeup-C4EXLYVA.js} +10 -10
  262. package/chunks/{lowlight-FYAAUU5J.js → lowlight-J2OZNPCA.js} +1 -1
  263. package/chunks/{ls-7MFU2QYW.js → ls-2OUTG3IZ.js} +6 -6
  264. package/chunks/{lsp-XHDTPTGV.js → lsp-4VMNXZW6.js} +4 -4
  265. package/chunks/mcp-UH5PSGIK.js +70 -0
  266. package/chunks/{monitor-FL2ZO33W.js → monitor-F4NYEU5J.js} +50 -50
  267. package/chunks/{multipart-parser-AJ4WASWR.js → multipart-parser-AWZKXSQN.js} +3 -3
  268. package/chunks/nonInteractiveCli-7IHPXVNH.js +129 -0
  269. package/chunks/{notebook-edit-6PULTHL5.js → notebook-edit-HPDXNGQH.js} +51 -51
  270. package/chunks/openaiContentGenerator-OBDNNOE2.js +56 -0
  271. package/chunks/pidfile-AUMGYIOK.js +73 -0
  272. package/chunks/{pt-OLYN42DS.js → pt-TFZO5Y6T.js} +68 -6
  273. package/chunks/{qwenContentGenerator-NX2E7PB7.js → qwenContentGenerator-LH2U2YRG.js} +52 -52
  274. package/chunks/{qwenOAuth2-ZV7YLMND.js → qwenOAuth2-LEYOU7RU.js} +9 -9
  275. package/chunks/read-file-HUUFBLEO.js +30 -0
  276. package/chunks/{read-mcp-resource-CNQHBSJM.js → read-mcp-resource-JUFHCKSC.js} +5 -5
  277. package/chunks/{read-package-up-ER5OJUGP.js → read-package-up-TCM6I7S2.js} +2 -2
  278. package/chunks/{record-artifact-SQ2OKRJW.js → record-artifact-DWSMBXYY.js} +4 -4
  279. package/chunks/ripGrep-C7X33LU6.js +60 -0
  280. package/chunks/{ru-LDM3GWVQ.js → ru-4L4LFHIT.js} +68 -6
  281. package/chunks/{run-qwen-serve-JK2DL7PI.js → run-qwen-serve-DGW5AFDJ.js} +1465 -283
  282. package/chunks/runtime-NYUSLBEZ.js +99 -0
  283. package/chunks/{scheduler-O4IGVZKK.js → scheduler-5VKDXULT.js} +51 -51
  284. package/chunks/{send-message-76GT3JMC.js → send-message-JZ752NWD.js} +7 -7
  285. package/chunks/serve-UTAHSFXH.js +76 -0
  286. package/chunks/{server-SGNPKX2O.js → server-VUHSYSUV.js} +9088 -1817
  287. package/chunks/{session-5BNM25EZ.js → session-QSGSSNFB.js} +340 -135
  288. package/chunks/settings-X24RYEED.js +120 -0
  289. package/chunks/shell-4MSI2R4O.js +70 -0
  290. package/chunks/{skill-I22QK5XS.js → skill-JR3GTNVZ.js} +24 -24
  291. package/chunks/spawnChannel-RFAAO44J.js +70 -0
  292. package/chunks/{src-7XL4G4DC.js → src-VLI3TKEY.js} +4 -4
  293. package/chunks/{src-BBQSM46M.js → src-YDBNMIIM.js} +183 -53
  294. package/chunks/standalone-update-4CY4HKGC.js +79 -0
  295. package/chunks/{startInteractiveUI-JII36UGN.js → startInteractiveUI-FOD7MMVB.js} +2368 -1923
  296. package/chunks/stdioHelpers-UMY72QRP.js +14 -0
  297. package/chunks/{syntheticOutput-F7LSDCAR.js → syntheticOutput-LELY6HAI.js} +5 -5
  298. package/chunks/task-create-QY3BIMNM.js +23 -0
  299. package/chunks/{task-list-TGGJX7EA.js → task-list-D2U47WBJ.js} +11 -10
  300. package/chunks/{task-stop-W7NGTMYQ.js → task-stop-N6E5IYLH.js} +4 -4
  301. package/chunks/{task-update-XYWMHJGJ.js → task-update-HJCQILLB.js} +13 -12
  302. package/chunks/{team-create-A7NUU5AQ.js → team-create-ZLQSU2E3.js} +50 -50
  303. package/chunks/{team-delete-UHQQ2QQX.js → team-delete-RCWYDRF4.js} +11 -10
  304. package/chunks/{team-plan-approval-TOQRJ2KI.js → team-plan-approval-YUAYBYLS.js} +50 -50
  305. package/chunks/theme-manager-SKNEBMOG.js +64 -0
  306. package/chunks/{todoWrite-C4ZAMSR3.js → todoWrite-FKCGATPJ.js} +6 -6
  307. package/chunks/{tool-search-SZ4EFS2T.js → tool-search-V5J3TGWY.js} +24 -24
  308. package/chunks/total-session-admission-2WIH72I3.js +72 -0
  309. package/chunks/tree-sitter-YJVE2ZUK.js +2980 -0
  310. package/chunks/trustedFolders-JF265CRI.js +80 -0
  311. package/chunks/types-ML3TRJQ5.js +16 -0
  312. package/chunks/updateCheck-AMXNPBP6.js +69 -0
  313. package/chunks/updateEventEmitter-5MKC7BLQ.js +10 -0
  314. package/chunks/validateNonInterActiveAuth-6YHQO7PD.js +194 -0
  315. package/chunks/{version-NO2XSNNP.js → version-UEJJK7PE.js} +3 -3
  316. package/chunks/{web-fetch-UYGMOHW4.js → web-fetch-QGODBB6S.js} +8 -8
  317. package/chunks/{workflow-WO2H6NRI.js → workflow-5YFA5V4M.js} +51 -51
  318. package/chunks/workspace-providers-status-LMBLBNR7.js +73 -0
  319. package/chunks/workspace-registration-store-VV2S4MSV.js +27 -0
  320. package/chunks/workspace-registry-BVMPYRLN.js +76 -0
  321. package/chunks/workspace-service-PUYIZ3J4.js +86 -0
  322. package/chunks/workspace-skills-status-CJ7J2KPP.js +72 -0
  323. package/chunks/{write-file-PX2Z7IBE.js → write-file-OV77M6X7.js} +51 -51
  324. package/chunks/{yargs-B64EYTCF.js → yargs-6H2AUULL.js} +2 -2
  325. package/chunks/{zh-J4F6QWQV.js → zh-FSAH32JB.js} +79 -7
  326. package/chunks/{zh-TW-XVDWOLSW.js → zh-TW-D2YIE2LO.js} +79 -7
  327. package/cli.js +18 -17
  328. package/locales/ca.js +91 -7
  329. package/locales/de.js +90 -7
  330. package/locales/en.js +109 -7
  331. package/locales/fr.js +91 -7
  332. package/locales/ja.js +93 -7
  333. package/locales/pt.js +90 -7
  334. package/locales/ru.js +90 -7
  335. package/locales/zh-TW.js +106 -7
  336. package/locales/zh.js +106 -7
  337. package/package.json +3 -6
  338. package/web-shell/assets/{arc-BWyoJpY2.js → arc-CObt_TK9.js} +1 -1
  339. package/web-shell/assets/{architectureDiagram-3BPJPVTR-BT0mGrz2.js → architectureDiagram-3BPJPVTR-B7aiJ6CK.js} +1 -1
  340. package/web-shell/assets/{blockDiagram-GPEHLZMM-BLgUWvyf.js → blockDiagram-GPEHLZMM-BSK2CrID.js} +1 -1
  341. package/web-shell/assets/{c4Diagram-AAUBKEIU-DYx9M7oU.js → c4Diagram-AAUBKEIU-Bhx2p7T_.js} +1 -1
  342. package/web-shell/assets/channel-BBaLq8MV.js +1 -0
  343. package/web-shell/assets/{chunk-2J33WTMH-CfMHWbuZ.js → chunk-2J33WTMH-c3Hzv0Ni.js} +1 -1
  344. package/web-shell/assets/{chunk-4BX2VUAB-B1URoqEV.js → chunk-4BX2VUAB-DNXaK7ZF.js} +1 -1
  345. package/web-shell/assets/{chunk-55IACEB6-DAIaM4QF.js → chunk-55IACEB6-BXjvDj_i.js} +1 -1
  346. package/web-shell/assets/{chunk-727SXJPM-B2X34knw.js → chunk-727SXJPM-B6CaKFp-.js} +1 -1
  347. package/web-shell/assets/{chunk-AQP2D5EJ-Cif-zLTQ.js → chunk-AQP2D5EJ-tij6Mz9B.js} +1 -1
  348. package/web-shell/assets/{chunk-FMBD7UC4-H18WCXdY.js → chunk-FMBD7UC4-DdlsGk2h.js} +1 -1
  349. package/web-shell/assets/{chunk-ND2GUHAM-YFtetHi0.js → chunk-ND2GUHAM-CdgGZSHE.js} +1 -1
  350. package/web-shell/assets/{chunk-QZHKN3VN-By2hiH3r.js → chunk-QZHKN3VN-D8oJn1C0.js} +1 -1
  351. package/web-shell/assets/classDiagram-4FO5ZUOK-B2ZK6sWE.js +1 -0
  352. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-B2ZK6sWE.js +1 -0
  353. package/web-shell/assets/{cose-bilkent-S5V4N54A-VrcnnLZu.js → cose-bilkent-S5V4N54A-BUVmNp1Y.js} +1 -1
  354. package/web-shell/assets/{dagre-BM42HDAG-CGo-IaVV.js → dagre-BM42HDAG-CO4q310O.js} +1 -1
  355. package/web-shell/assets/{diagram-2AECGRRQ-Dl4QjzIB.js → diagram-2AECGRRQ-C6gFvWkg.js} +1 -1
  356. package/web-shell/assets/{diagram-5GNKFQAL-qMLmsO0u.js → diagram-5GNKFQAL-NG2I_c0h.js} +1 -1
  357. package/web-shell/assets/{diagram-KO2AKTUF-CHlmuxPI.js → diagram-KO2AKTUF-DFKMS6I9.js} +1 -1
  358. package/web-shell/assets/{diagram-LMA3HP47-BUwU3GwT.js → diagram-LMA3HP47-BiElfsfP.js} +1 -1
  359. package/web-shell/assets/{diagram-OG6HWLK6-HEhwPDUM.js → diagram-OG6HWLK6-zLWDYUqu.js} +1 -1
  360. package/web-shell/assets/{erDiagram-TEJ5UH35-1n0llBmM.js → erDiagram-TEJ5UH35-DoVaazhK.js} +1 -1
  361. package/web-shell/assets/{flowDiagram-I6XJVG4X-BN74uMnt.js → flowDiagram-I6XJVG4X-0RLz-mXg.js} +1 -1
  362. package/web-shell/assets/{ganttDiagram-6RSMTGT7-BoOq78i3.js → ganttDiagram-6RSMTGT7-C-eX1A39.js} +3 -3
  363. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CN8b00c8.js → gitGraphDiagram-PVQCEYII-BauQu1Bu.js} +1 -1
  364. package/web-shell/assets/index-3uAT3ehO.css +5 -0
  365. package/web-shell/assets/index-CVHa2QH7.js +3 -0
  366. package/web-shell/assets/index-D1KigWat.js +1128 -0
  367. package/web-shell/assets/{infoDiagram-5YYISTIA-CCurnIna.js → infoDiagram-5YYISTIA-C800cFvZ.js} +1 -1
  368. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-AwuRqdUP.js → ishikawaDiagram-YF4QCWOH-CFK1Jk6e.js} +1 -1
  369. package/web-shell/assets/{journeyDiagram-JHISSGLW-B7IICk-E.js → journeyDiagram-JHISSGLW-Cjx0WAC4.js} +1 -1
  370. package/web-shell/assets/{kanban-definition-UN3LZRKU-BYF0OKhx.js → kanban-definition-UN3LZRKU-DWMDHbiv.js} +1 -1
  371. package/web-shell/assets/{linear-GWWguGfD.js → linear-vpW4FrZs.js} +1 -1
  372. package/web-shell/assets/{mermaid.core-JqtkxvCl.js → mermaid.core-DsHRUnDd.js} +5 -5
  373. package/web-shell/assets/{mindmap-definition-RKZ34NQL-B0MmHsZ6.js → mindmap-definition-RKZ34NQL-D3Eb1cAK.js} +1 -1
  374. package/web-shell/assets/{pieDiagram-4H26LBE5-DhImUZLQ.js → pieDiagram-4H26LBE5-Cr2-6sWt.js} +1 -1
  375. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-DGeSC3DT.js → quadrantDiagram-W4KKPZXB-Yd7yUgVp.js} +1 -1
  376. package/web-shell/assets/{requirementDiagram-4Y6WPE33-DkspY6Re.js → requirementDiagram-4Y6WPE33-BE6SprL8.js} +1 -1
  377. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-CaOofS2x.js → sankeyDiagram-5OEKKPKP-DzkuMK8d.js} +1 -1
  378. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DFQ_kFnN.js → sequenceDiagram-3UESZ5HK-wD9A3Dhi.js} +1 -1
  379. package/web-shell/assets/{stateDiagram-AJRCARHV-D3snw0Tz.js → stateDiagram-AJRCARHV-BOp5q1Nm.js} +1 -1
  380. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BDsWUmPG.js +1 -0
  381. package/web-shell/assets/{timeline-definition-PNZ67QCA-l4zH8nLM.js → timeline-definition-PNZ67QCA-Btc08sUA.js} +1 -1
  382. package/web-shell/assets/{vennDiagram-CIIHVFJN-BnRlA98M.js → vennDiagram-CIIHVFJN-Bv6upsOA.js} +1 -1
  383. package/web-shell/assets/{wardley-L42UT6IY-BS0xUdmd.js → wardley-L42UT6IY-D-XamnCK.js} +1 -1
  384. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DKGBUWyQ.js → wardleyDiagram-YWT4CUSO-BbP_5Wfp.js} +1 -1
  385. package/web-shell/assets/{xychartDiagram-2RQKCTM6-DVb2HuOB.js → xychartDiagram-2RQKCTM6-CO5Hh28b.js} +1 -1
  386. package/web-shell/index.html +16 -4
  387. package/chunks/MaxSizedBox-5DT2SD7B.js +0 -71
  388. package/chunks/agent-H2DGKS77.js +0 -68
  389. package/chunks/agent-headless-KFMFIT6J.js +0 -62
  390. package/chunks/bridge-NA3ZQQKJ.js +0 -78
  391. package/chunks/chunk-5P5XGNYH.js +0 -93
  392. package/chunks/chunk-6SHO7WFF.js +0 -79
  393. package/chunks/chunk-IFEWJXFS.js +0 -37
  394. package/chunks/chunk-XNXVCNAT.js +0 -88
  395. package/chunks/contextCommand-LXFZRP4L.js +0 -68
  396. package/chunks/daemon-status-provider-GJRXY5EN.js +0 -76
  397. package/chunks/earlyInputCapture-KNOYZ4MJ.js +0 -69
  398. package/chunks/environment-ATFTYMLZ.js +0 -88
  399. package/chunks/errors-A54HAADA.js +0 -75
  400. package/chunks/handleAutoUpdate-CEZJAARW.js +0 -65
  401. package/chunks/initializer-BRFJKRRX.js +0 -71
  402. package/chunks/list-KVHF7O4X.js +0 -73
  403. package/chunks/loadedSettingsAdapter-LL5PSFKX.js +0 -68
  404. package/chunks/mcp-3GCXRTOQ.js +0 -68
  405. package/chunks/nonInteractiveCli-PTQI3DV6.js +0 -119
  406. package/chunks/openaiContentGenerator-YE42PKCY.js +0 -56
  407. package/chunks/pidfile-NZYSCFRK.js +0 -73
  408. package/chunks/read-file-33XGP5HF.js +0 -30
  409. package/chunks/ripGrep-QWZLGTAN.js +0 -60
  410. package/chunks/serve-JTMIGANH.js +0 -74
  411. package/chunks/settings-3MI4XXP6.js +0 -118
  412. package/chunks/shell-YJKBE67T.js +0 -68
  413. package/chunks/spawnChannel-UNV6W4DU.js +0 -70
  414. package/chunks/task-create-WCHTB435.js +0 -22
  415. package/chunks/theme-manager-WZ4RRMMB.js +0 -64
  416. package/chunks/total-session-admission-ULXJWXFV.js +0 -72
  417. package/chunks/trustedFolders-LAZZPZ3D.js +0 -79
  418. package/chunks/types-QX5C3CHJ.js +0 -12
  419. package/chunks/updateCheck-KONLM73X.js +0 -65
  420. package/chunks/validateNonInterActiveAuth-MPKSRCXD.js +0 -184
  421. package/chunks/workspace-providers-status-3W7E7DFW.js +0 -71
  422. package/chunks/workspace-registry-SXJZNN3O.js +0 -74
  423. package/chunks/workspace-service-CZRQZ4Q4.js +0 -80
  424. package/chunks/workspace-skills-status-K7WFREPD.js +0 -70
  425. package/node_modules/@qwen-code/audio-capture/dist/index.d.ts +0 -35
  426. package/node_modules/@qwen-code/audio-capture/dist/index.js +0 -48
  427. package/node_modules/@qwen-code/audio-capture/dist/index.js.map +0 -1
  428. package/node_modules/@qwen-code/audio-capture/dist/platform.d.ts +0 -7
  429. package/node_modules/@qwen-code/audio-capture/dist/platform.js +0 -18
  430. package/node_modules/@qwen-code/audio-capture/dist/platform.js.map +0 -1
  431. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/LICENSE +0 -21
  432. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/README.md +0 -58
  433. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/SECURITY.md +0 -5
  434. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/bin.js +0 -84
  435. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/build-test.js +0 -19
  436. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/index.js +0 -6
  437. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/node-gyp-build.js +0 -207
  438. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/optional.js +0 -7
  439. package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/package.json +0 -43
  440. package/node_modules/@qwen-code/audio-capture/package.json +0 -30
  441. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
  442. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
  443. package/node_modules/@qwen-code/audio-capture/prebuilds/linux-arm64/@qwen-code+audio-capture.node +0 -0
  444. package/node_modules/@qwen-code/audio-capture/prebuilds/linux-x64/@qwen-code+audio-capture.node +0 -0
  445. package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
  446. package/web-shell/assets/channel-wmPUGHtg.js +0 -1
  447. package/web-shell/assets/classDiagram-4FO5ZUOK-BA2ljEjW.js +0 -1
  448. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BA2ljEjW.js +0 -1
  449. package/web-shell/assets/index-CNwoO1Cn.js +0 -783
  450. package/web-shell/assets/index-CWQ0z6kZ.css +0 -5
  451. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BbSm_9d0.js +0 -1
@@ -1,6 +1,6 @@
1
1
  # Tool-Use Summaries
2
2
 
3
- Qwen Code can generate a short, git-commit-subject-style label after each tool batch completes, summarizing what the batch accomplished. The label appears inline in the transcript and replaces the generic `Tool × N` header in compact mode.
3
+ Qwen Code can generate a short, git-commit-subject-style label after each tool batch completes, summarizing what the batch accomplished. The label appears inline: for a completed tool group in the main view it replaces the generic `Tool × N` header; when the group is force-expanded (in the `Ctrl+O` full-detail transcript, or for error / user-initiated batches) it appears as a dim `● <label>` line below the group.
4
4
 
5
5
  This is a UX aid for parallel tool calls: when the model fans out into several `Read` + `Grep` + `Bash` calls at once, the summary tells you the intent at a glance instead of forcing you to scan the tool list.
6
6
 
@@ -8,33 +8,32 @@ The feature is enabled by default and runs silently in the background. It requir
8
8
 
9
9
  ## What You See
10
10
 
11
- ### Full mode (default)
11
+ ### Main view (completed group)
12
12
 
13
- The summary appears as a dim badge line directly below the tool group:
13
+ In the main transcript, a completed collapsible batch folds into a single labeled row — the summary replaces the generic `Tool × N` header:
14
14
 
15
15
  ```
16
16
  ╭──────────────────────────────────────────────╮
17
- │ ✓ ReadFile a.txt
18
- │ ✓ ReadFile b.txt │
19
- │ ✓ ReadFile c.txt │
20
- │ ✓ ReadFile d.txt │
17
+ │✓ Read 4 text files
21
18
  ╰──────────────────────────────────────────────╯
22
-
23
- ● Read 4 text files
24
19
  ```
25
20
 
26
- ### Compact mode (`Ctrl+O` or `ui.compactMode: true`)
21
+ The full per-tool output is a keystroke away: press `Ctrl+O` to open the full-detail transcript.
22
+
23
+ ### Full-detail transcript (`Ctrl+O`) and force-expanded groups
27
24
 
28
- The label replaces the generic `Tool × N` header in the compact one-liner:
25
+ When a group is force-expanded in the `Ctrl+O` transcript, or for error / user-initiated batches in the main view — each tool renders individually and the summary appears as a dim badge line below the group:
29
26
 
30
27
  ```
31
28
  ╭──────────────────────────────────────────────╮
32
- │✓ Read txt files · 4 tools
33
- Press Ctrl+O to show full tool output
29
+ │ ✓ ReadFile a.txt
30
+ ✓ ReadFile b.txt
31
+ │ ✓ ReadFile c.txt │
32
+ │ ✓ ReadFile d.txt │
34
33
  ╰──────────────────────────────────────────────╯
35
- ```
36
34
 
37
- The individual tool calls are still a keystroke away (`Ctrl+O` to toggle to full mode).
35
+ Read 4 text files
36
+ ```
38
37
 
39
38
  ## How It Works
40
39
 
@@ -123,7 +122,7 @@ These settings can be configured in `settings.json`:
123
122
 
124
123
  Three points that tend to trip up a first read of this feature:
125
124
 
126
- 1. **One generation per batch, shared by both display modes.** The fast-model call happens exactly once in `handleCompletedTools` when a tool batch finalizes. Toggling `Ctrl+O` afterwards does **not** trigger a new call — both modes read from the same `tool_use_summary` history entry that was captured the first time. You can flip compact mode on and off freely without extra cost.
125
+ 1. **One generation per batch, shared by both display modes.** The fast-model call happens exactly once in `handleCompletedTools` when a tool batch finalizes. Opening the `Ctrl+O` transcript afterwards does **not** trigger a new call — both the main view and the full-detail transcript read from the same `tool_use_summary` history entry that was captured the first time.
127
126
  2. **No backfill on toggle or on session resume.** A `tool_group` that completed before the feature was enabled (or before you flipped the setting on, or in a resumed session — `ChatRecordingService` does not persist summary entries) will never get a label. There is no "sweep existing history" pass. If you turn this setting on mid-session, only _future_ batches will show a label; older groups keep the default rendering with no indicator that a label is missing.
128
127
  3. **Main-agent batches only.** The trigger lives in the main session's turn loop (`useGeminiStream`), so:
129
128
  - ✅ Shell, MCP, file operations, and the `Task` / subagent tool _call itself_ (as it appears in the main batch) are summarized.
@@ -131,23 +130,20 @@ Three points that tend to trip up a first read of this feature:
131
130
 
132
131
  An outer batch that _contains_ a `Task` tool will still be labeled, but the fast model sees only the subagent tool call and its aggregated output — not the individual tool calls inside the subagent. Expect labels like `Ran research-agent` or `Delegated file search` rather than `Searched 14 files`. This is intentional — summarizing subagent internals would multiply the fast-model cost and surface noise that never shows up in the primary UI.
133
132
 
134
- ## Recommended pairing: enable compact mode
133
+ ## Display behavior
135
134
 
136
- For batches of 3+ parallel tool calls, pairing this feature with `ui.compactMode: true` produces the cleanest transcript. The compact view folds the whole batch into a single labeled row (`✓ Read txt files · 4 tools`) instead of showing every tool line plus the trailing summary. Details remain one keystroke away via `Ctrl+O`.
135
+ The main view already folds a completed collapsible batch into a single labeled row (`✓ Read 4 text files`) the summary does the work of the old per-tool list. For full per-tool detail, press `Ctrl+O` to open the full-detail transcript, where each tool renders individually with the summary as a trailing `● <label>` line below the group.
137
136
 
138
137
  ```json
139
138
  {
140
139
  "fastModel": "qwen3-coder-flash",
141
- "ui": {
142
- "compactMode": true
143
- },
144
140
  "experimental": {
145
141
  "emitToolUseSummaries": true
146
142
  }
147
143
  }
148
144
  ```
149
145
 
150
- In full mode (the default), the summary renders as a trailing `● <label>` line below the tool group — useful for large or heterogeneous batches, but for small same-type batches (e.g. `Read × 3`) the label can read as a restatement of the visible tool lines. If that matches your usual workflow, either turn compact mode on as above, or turn the summary off entirely via `experimental.emitToolUseSummaries: false`.
146
+ For small same-type batches (e.g. `Read × 3`) the expanded `● <label>` line can read as a restatement of the visible tool lines; if that matches your usual workflow you can turn the summary off entirely via `experimental.emitToolUseSummaries: false`.
151
147
 
152
148
  ## Monitoring
153
149
 
@@ -174,5 +170,5 @@ If you do not want the extra cost, turn the feature off via `experimental.emitTo
174
170
 
175
171
  ## Related
176
172
 
177
- - [Compact Mode](../configuration/settings#ui) — toggle with `Ctrl+O`; the summary replaces the generic tool-group header when compact mode is on.
173
+ - [Full-detail transcript](../configuration/settings#ui) — press `Ctrl+O` to open the frozen full-detail transcript; the summary replaces the generic tool-group header for completed groups in the main view.
178
174
  - [Followup Suggestions](./followup-suggestions) — another fast-model-driven UX enhancement that shares the same `fastModel` setting.
@@ -18,7 +18,7 @@
18
18
 
19
19
  ### Requirements
20
20
 
21
- - VS Code 1.85.0 or higher
21
+ - VS Code 1.96.0 or higher
22
22
 
23
23
  ### Installation
24
24
 
@@ -28,7 +28,7 @@ Download and install the extension from the [Visual Studio Code Extension Market
28
28
 
29
29
  ### Extension not installing
30
30
 
31
- - Ensure you have VS Code 1.85.0 or higher
31
+ - Ensure you have VS Code 1.96.0 or higher
32
32
  - Check that VS Code has permission to install extensions
33
33
  - Try installing directly from the Marketplace website
34
34
 
@@ -13,10 +13,11 @@ Run Qwen Code as a local HTTP daemon so multiple clients (IDE plugins, web UIs,
13
13
  - **Built-in Web Shell UI** — `qwen serve` serves the browser-based Web Shell at its root (`http://127.0.0.1:4170/`) out of the box; run `qwen serve --open` to launch it in your browser automatically. It is served on the same origin as the API, so no second port or reverse proxy is needed. Pass `--no-web` for an API-only daemon.
14
14
  - **One agent process, many clients** — under the default `sessionScope: 'single'`, every client connecting to the daemon shares one ACP session. Live cross-client collaboration on the same conversation, the same file diffs, the same permission prompts.
15
15
  - **Reconnect-safe streaming** — SSE with `Last-Event-ID` reconnect lets a client drop and pick up exactly where it left off (within the ring's replay window).
16
+ - **Paged persisted transcripts** — `GET /session/:id/transcript` returns the complete active on-disk transcript as replay pages without attaching a client or changing the live SSE replay window.
16
17
  - **First-responder permissions** — when the agent asks for permission to run a tool, every connected client sees the request; whichever client answers first wins.
17
- - **One daemon, one workspace** — each `qwen serve` process binds to exactly one workspace at boot (per [#3803](https://github.com/QwenLM/qwen-code/issues/3803) §02). Multi-workspace deployments run one daemon per workspace on separate ports (or behind an orchestrator).
18
- - **Experimental daemon-managed channels** — `qwen serve --channel <name>` starts a channel worker owned by the daemon lifecycle. The worker is a separate process, connects back to the daemon through the SDK, and reports its state in `GET /daemon/status`.
19
- - **Remote runtime control** ([#4175](https://github.com/QwenLM/qwen-code/issues/4175) PR 17) — change a session's approval mode (`POST /session/:id/approval-mode`), toggle a tool per workspace (`POST /workspace/tools/:name/enable`), scaffold an empty `QWEN.md` (`POST /workspace/init`, mechanical only — does NOT call the model; for AI-fill, follow up with `POST /session/:id/prompt`), restart a single MCP server with a budget pre-check (`POST /workspace/mcp/:server/restart`), or add/remove MCP servers at runtime without a daemon restart (`POST /workspace/mcp/servers`, `DELETE /workspace/mcp/servers/:name`). All strict-gated — configure `--token` first.
18
+ - **One daemon, one or more workspaces** — repeat `--workspace` to register isolated workspace runtimes under one listener. The first workspace is primary and remains the default for requests that omit `cwd`.
19
+ - **Experimental daemon-managed channels** — start with `qwen serve --channel <name>`, or start without a channel and select one later with `qwen channel set`. Workers are separate processes owned by the daemon lifecycle. Their selection can be queried, replaced, reloaded, and stopped without restarting the daemon.
20
+ - **Remote runtime control** — change a session's approval mode (`POST /session/:id/approval-mode`), toggle a tool (`POST /workspace/tools/:name/enable`) or loaded skill (`POST /workspace/skills/:name/enable`) per workspace, scaffold an empty `QWEN.md` (`POST /workspace/init`, mechanical only — does NOT call the model; for AI-fill, follow up with `POST /session/:id/prompt`), restart a single MCP server with a budget pre-check (`POST /workspace/mcp/:server/restart`), or add/remove MCP servers at runtime without a daemon restart (`POST /workspace/mcp/servers`, `DELETE /workspace/mcp/servers/:name`). All strict-gated — configure `--token` first.
20
21
  - **Session recap** ([#4175](https://github.com/QwenLM/qwen-code/issues/4175) follow-up) — fetch a one-sentence "where did I leave off" summary of an active session (`POST /session/:id/recap`). Wraps core's `generateSessionRecap` as a side-query against the fast model; pollutes neither the main chat history nor the SSE stream. Non-strict gate (same posture as `/prompt`); SDK helper `client.recapSession(sessionId)`.
21
22
  - **Known limit — token-cost amplification:** the route is a pure-cost endpoint (each call is an LLM side-query, no state benefit) and the daemon has no per-route rate limit in v1. On a no-token loopback default a buggy or malicious local client can spam it to burn tokens. Configure `--token` (and optionally `--require-auth`) on shared dev hosts before exposing the daemon.
22
23
  - **Concurrent recap safety:** two simultaneous `/recap` calls on the same session run two independent side-queries. `generateSessionRecap` reads a snapshot of the chat history via `GeminiClient.getChat().getHistory()` and feeds it to a separate `BaseLlmClient.generateText` call (via `runSideQuery`); it never appends to or mutates the session's `GeminiChat`. Safe to call from multiple clients without coordination.
@@ -37,7 +38,7 @@ The first npm release of `qwen serve` (v0.16-alpha) is intentionally narrow —
37
38
  - ✅ Local launch via `systemd` / `launchd` / `nohup &` / `tmux` — see [Local launch templates](./qwen-serve-deploy-local.md)
38
39
  - ✅ Bring-your-own bearer token via `QWEN_SERVER_TOKEN` env var ([Authentication](#authentication) for setup)
39
40
  - ❌ **Containerized deployment** — Docker / Compose / Kubernetes / nginx reverse-proxy with TLS termination NOT in v0.16-alpha. Defers to v0.16.x once an enterprise pilot is committed (would otherwise rot from no-one-validating).
40
- - ❌ **Multi-daemon coordination on one host** — `1 daemon = 1 workspace × N sessions` is enforced. Cross-host federation, instance-path token keying, and stale-token cleanup defer to v0.16.x.
41
+ - ❌ **Multi-daemon coordination on one host** — one daemon can host several explicitly registered workspaces, but daemons do not coordinate with each other. Cross-host federation, instance-path token keying, and stale-token cleanup defer to v0.16.x.
41
42
  - ❌ **Auto-generated daemon tokens** — alpha is BYO-token (one `openssl rand -hex 32` away). Auto-gen + token-store infrastructure defers to v0.16.x.
42
43
 
43
44
  **Hardening — minimum viable for local single-user:**
@@ -94,11 +95,29 @@ qwen serve --channel telegram --channel feishu
94
95
 
95
96
  # Start all configured channels
96
97
  qwen serve --channel all
98
+
99
+ # Or start a token-protected daemon with no channel worker
100
+ QWEN_SERVER_TOKEN=secret qwen serve
101
+
102
+ # Enable or replace its runtime selection later
103
+ qwen channel set telegram --token secret
104
+ qwen channel set telegram feishu --token secret
105
+ qwen channel set all --token secret
106
+
107
+ # Inspect or stop daemon-managed channels
108
+ qwen channel status --daemon-url http://127.0.0.1:4170 --token secret
109
+ qwen channel stop --daemon-url http://127.0.0.1:4170 --token secret
97
110
  ```
98
111
 
99
- This mode is experimental and daemon-managed. It does not replace the standalone `qwen channel start` command: standalone channels still use the ACP-backed `AcpBridge` service. With `qwen serve --channel`, the daemon launches one channel worker process after the HTTP runtime is ready. If the worker exits after startup, the daemon keeps running and `GET /daemon/status` reports a `channel_worker_exited` warning. Automatic worker restart is deferred.
112
+ This mode is experimental and daemon-managed. It does not replace the standalone `qwen channel start` command: without `--daemon-url`, existing `qwen channel start`, `stop`, and `status` behavior remains standalone. With `qwen serve --channel`, the daemon reserves the channel-service lease before listening and fails startup if the initial worker cannot become ready. Without `--channel`, it loads no channel runtime and reserves no channel-service lease until the first runtime PUT. If a ready worker later crashes, the daemon keeps running, relaunches it under a bounded restart policy, and reports its state (including `channel_worker_exited` warnings) in `GET /daemon/status`.
113
+
114
+ Runtime control is exposed as `GET`, `PUT`, and `DELETE /workspace/channel`; SDK helpers are `getChannelWorkerControl()`, `setChannelWorkerSelection()`, and `stopChannelWorker()`. PUT/DELETE/reload use the strict mutation gate, so the daemon must have a bearer token configured. Runtime selections are deliberately ephemeral: PUT does not edit settings or the boot options, and a restart returns to the `qwen serve --channel` selection (or disabled when that flag is omitted). Named selections are trimmed and deduplicated in first-occurrence order; order is preserved because the first channel can affect shared model selection.
100
115
 
101
- The daemon is bound to one workspace, so every selected channel's `cwd` must resolve to the daemon workspace. `--channel all` cannot be combined with named channels.
116
+ The daemon reads each channel's settings (tokens, `proxy`, per-channel `model`) when its worker starts. To re-read settings without changing the committed selection, call `POST /workspace/channel/reload` (SDK `client.reloadChannelWorker()`, or `qwen channel reload`). Reload re-resolves workspace ownership and restarts selected workers through the same rollback-safe reconcile path. The `channel_control` capability is present whenever runtime control is wired; `channel_reload` is present only while the manager is enabled. Persisted threads are restored from disk.
117
+
118
+ Each selected channel's `cwd` must resolve to a registered workspace, and channels are grouped by that owning workspace: a single-workspace daemon runs one worker (unchanged from before); a multi-workspace daemon (`--workspace` repeated) runs one worker per workspace that owns a selected channel, each bound to that workspace's cwd, `QWEN_DAEMON_WORKSPACE`, and env overlay. To host a channel in a non-primary workspace, define it in that workspace's own `.qwen/settings.json` (no `cwd` needed) or set an explicit `cwd` equal to the workspace path; a channel defined only in user/system scope with no `cwd` is ambiguous across workspaces and causes a boot error. `--channel all` stays primary-only (it hosts the primary workspace's channels) and cannot be combined with named channels.
119
+
120
+ Replacing a selection preflights configuration, ownership, and trust before stopping anything. It keeps workspace workers whose ordered selection is unchanged. If a changed worker cannot start, the daemon stops new workers and restores the old selection. If the daemon cannot confirm that an old child exited even after SIGKILL, it keeps the PID lease and refuses to create a duplicate worker. A worker is still considered ready when at least one requested adapter connects; PUT then returns `partial: true`, and `/daemon/status` reports `channel_worker_partial_connect` for the missing adapters.
102
121
 
103
122
  The daemon also exposes read-only runtime snapshots for client UIs and
104
123
  operators: `GET /daemon/status`, `GET /workspace/mcp`,
@@ -106,7 +125,8 @@ operators: `GET /daemon/status`, `GET /workspace/mcp`,
106
125
  `GET /workspace/preflight`,
107
126
  `GET /session/:id/status`, `GET /session/:id/context`,
108
127
  `GET /session/:id/supported-commands`, and
109
- `GET /session/:id/tasks`, and `GET /session/:id/lsp`.
128
+ `GET /session/:id/tasks`, `GET /session/:id/lsp`, and
129
+ `GET /session/:id/transcript`.
110
130
 
111
131
  `GET /session/:id/status` returns the live bridge summary for a single session:
112
132
  `sessionId`, `workspaceCwd`, `createdAt`, optional `displayName`, `clientCount`,
@@ -146,6 +166,8 @@ idle daemon returns `initialized: false` with an empty snapshot. Once a
146
166
  session is alive they switch to `initialized: true` and surface the real
147
167
  state.
148
168
 
169
+ To mirror the CLI `/skills` panel remotely, call `POST /workspace/skills/:name/enable` with `{ "enabled": true | false }` after checking the `workspace_skill_toggle` capability. The route writes only workspace `skills.disabled`, rejects unknown, hidden, inactive-extension, higher-scope-locked, and untrusted targets, and immediately refreshes active ACP sessions. A `deferred` response means the setting was saved while no ACP child was running; it will apply when the child starts. `skills.disabled` disables both manual and model use, unlike `disable-model-invocation: true`, which keeps direct `/skill-name` invocation available.
170
+
149
171
  `GET /workspace/env` and `GET /workspace/preflight` always answer with
150
172
  `initialized: true` regardless of ACP state. `env` never consults ACP
151
173
  (daemon-process info only); `preflight` answers daemon-level cells from
@@ -191,7 +213,7 @@ curl -X POST http://127.0.0.1:4170/session \
191
213
  # → {"sessionId":"<uuid>","workspaceCwd":"…","attached":false}
192
214
  ```
193
215
 
194
- `cwd` may be omitted — the route falls back to the daemon's bound workspace. Posting a `cwd` that doesn't match the bound workspace returns `400 workspace_mismatch` (the daemon is bound to exactly one workspace; start a separate daemon for a different one).
216
+ `cwd` may be omitted — the route falls back to the daemon's primary workspace. Posting a `cwd` that does not canonicalize to any registered workspace returns `400 workspace_mismatch`.
195
217
 
196
218
  A second client posting to `/session` (any matching `cwd` or none) gets `"attached": true` — they're now sharing the agent.
197
219
 
@@ -303,16 +325,16 @@ Notes:
303
325
  | `--tls-cert <path>` | — | Path to a PEM certificate file. Serve over **HTTPS** instead of HTTP. Must be paired with `--tls-key` (boot fails if only one is given). Unlocks secure-context browser APIs — voice input (`getUserMedia`), WebRTC — over a LAN IP, which browsers otherwise block on plain `http://`. TLS termination only; no auto-generation / ACME. See [HTTPS / TLS](#https--tls-for-mobile--cross-device-access) below. |
304
326
  | `--tls-key <path>` | — | Path to a PEM private key file. Must be paired with `--tls-cert`. |
305
327
  | `--max-sessions <n>` | `20` | Cap on concurrent live sessions. New `POST /session` requests that would spawn a fresh child return `503` (with `Retry-After: 5`) when the cap is hit; attaches to existing sessions are NOT counted. Set to `0` to disable. Sized for single-user / small-team usage; raise it if your deployment has the RAM/FD headroom (~30–50 MB per session). |
306
- | `--max-total-sessions <n>` | unlimited | Optional non-negative integer daemon-wide cap on fresh session creation across the runtime. It applies to new child sessions, session restore, and branch/fork-created sessions; attaching to an existing live session does not consume a slot. Set to `0` or omit the flag for unlimited. This is a guardrail for future multi-workspace sessions and does not enable multi-workspace serving by itself. |
328
+ | `--max-total-sessions <n>` | derived | Optional non-negative integer daemon-wide cap on fresh session creation across all registered workspace runtimes. It applies to new child sessions, session restore, and branch/fork-created sessions; attaching to an existing live session does not consume a slot. Set to `0` for unlimited. When omitted in multi-workspace mode, the daemon derives a cap from the per-workspace limit and workspace count. |
307
329
  | `--max-pending-prompts-per-session <n>` | `5` | Per-session cap on prompts accepted by `POST /session/:id/prompt` but not yet settled, including queued prompts and the active prompt. The bridge rejects overflow synchronously with `503`, `Retry-After: 5`, and `code: "prompt_queue_full"` before returning a `promptId`. Set to `0` to disable. `branchSession` serializes on the same FIFO but does not count against this prompt cap. |
308
- | `--workspace <path>` | `process.cwd()` | Absolute workspace path this daemon binds to (per [#3803](https://github.com/QwenLM/qwen-code/issues/3803) §02 1 daemon = 1 workspace). `POST /session` requests with a mismatched `cwd` return `400 workspace_mismatch`. For multi-workspace deployments, run one `qwen serve` per workspace on separate ports. |
309
- | `--channel <name\|all>` | — | Experimental daemon-managed channel worker. Repeat the flag to select multiple configured channels, or pass `all` to start every configured channel. `all` cannot be combined with named channels. Selected channel `cwd` values must resolve to the daemon workspace. The worker is owned by `qwen serve`; stop the daemon to stop serve-managed channels. |
330
+ | `--workspace <path>` | `process.cwd()` | Workspace path registered by this daemon. Repeat the flag to host multiple workspaces in one process; the first is primary and remains the default when a request omits `cwd`. Relative paths resolve from the process working directory. Session requests whose canonical `cwd` is not registered return `400 workspace_mismatch`. |
331
+ | `--channel <name\|all>` | — | Experimental daemon-managed channel worker. Repeat the flag to select multiple configured channels, or pass `all` to start every configured channel. `all` cannot be combined with named channels. Selected channel `cwd` values must resolve to a registered workspace; a multi-workspace daemon runs one worker per owning workspace. The worker is owned by `qwen serve`; stop the daemon to stop serve-managed channels. |
310
332
  | `--max-connections <n>` | `256` | Listener-level TCP connection cap (`server.maxConnections`). Bounds raw socket count irrespective of session count — slow / phantom SSE clients get rejected at accept time once full. Raise alongside `--max-sessions` if your deployment expects many SSE subscribers per session. |
311
333
  | `--event-ring-size <n>` | `8000` | Per-session SSE replay ring depth (#3803 §02 target). Sets the backlog available to `GET /session/:id/events` with `Last-Event-ID: N`. Larger = more reconnect headroom at the cost of a few hundred KB extra RAM per session. SDK clients can additionally request a larger per-subscriber backlog cap on a specific subscription via `?maxQueued=N` (range `[16, 2048]`, default 256). Daemons also emit a non-terminal `slow_client_warning` SSE frame at 75% queue fill so clients can drain / reconnect before getting evicted. Pre-flight `caps.features.slow_client_warning`. |
312
- | `--compacted-replay-max-bytes <n>` | `4194304` | Per-live-session byte cap for the retained replay events in the bounded snapshot returned by `POST /session/:id/load`. The cap applies to `compactedReplay`; the current in-flight `liveJournal` remains uncapped. Values must be positive safe integers; invalid values fail at boot, and the hard ceiling is 256 MiB. When older retained replay is dropped, the snapshot begins with `history_truncated`. This does not limit the on-disk transcript. |
334
+ | `--compacted-replay-max-bytes <n>` | `4194304` | Per-live-session byte cap for the retained replay events in the bounded snapshot returned by `POST /session/:id/load`. The cap applies to `compactedReplay`; the current in-flight `liveJournal` remains uncapped. Values must be positive safe integers; invalid values fail at boot, and the hard ceiling is 256 MiB. When older retained replay is dropped, the snapshot begins with `history_truncated`. This does not limit the on-disk transcript. |
313
335
  | `--mcp-client-budget <n>` | — | Positive integer cap on live MCP clients **per ACP session** (issue [#4175](https://github.com/QwenLM/qwen-code/issues/4175) PR 14 v1; PR 23 graduates this to per-workspace via the shared MCP pool). Combine with `--mcp-budget-mode`. When unset, no accounting-driven enforcement (but `GET /workspace/mcp` still reports `clientCount`). Distinct from claude-code's `MCP_SERVER_CONNECTION_BATCH_SIZE` which gates startup concurrency, not the total client count. Pre-flight `caps.features.mcp_guardrails`. |
314
336
  | `--mcp-budget-mode <m>` | `warn` / `off` | How `--mcp-client-budget` is enforced. `warn` (default when budget set): no refusal, snapshot's `budgets[0].status` flips to `warning` at ≥75% of budget. `enforce`: connects past the cap are refused, per-server cell shows `disabledReason: 'budget'`, deterministic by `mcpServers` declaration order. `off` (default when budget unset): pure observability. Boot rejects `enforce` without a budget. |
315
- | `--http-bridge` | `true` | Stage 1 mode: one `qwen --acp` child per daemon (bound to one workspace at boot, per [#3803](https://github.com/QwenLM/qwen-code/issues/3803) §02); N sessions multiplex onto that child via ACP `newSession()`. Stage 2 native in-process becomes available later. |
337
+ | `--http-bridge` | `true` | Stage 1 mode: one `qwen --acp` child per registered workspace runtime; sessions targeting that workspace multiplex onto its child via ACP `newSession()`. Stage 2 native in-process becomes available later. |
316
338
  | `--allow-origin <pat>` | — | T2.4 ([#4514](https://github.com/QwenLM/qwen-code/issues/4514)). Cross-origin allowlist for browser webui clients. Repeatable. Each value is `*` (any origin — boot refuses if no bearer token is configured; `--require-auth` on loopback is recommended so `/health` and `/demo` are also bearer-gated, since both are pre-auth on loopback by default) or a canonical URL origin (`<scheme>://<host>[:<port>]`, no trailing slash / path / userinfo / query). **Subdomain wildcards (`https://*.example.com`) are intentionally unsupported** — list each subdomain explicitly, or use `*` with a configured token (and `--require-auth` for full hardening). Matched origins receive CORS response headers (`Access-Control-Allow-Origin`, `Vary: Origin`, methods, headers, max-age, and exposed `Retry-After`); unmatched origins still get a 403 with the same envelope as today's wall. `Origin: null` (sandboxed iframes, file:// docs) is always rejected, even under `*`. Pre-flight via `caps.features.allow_origin`. Loopback self-origin hits are unaffected. |
317
339
  | `--web` / `--no-web` | `true` | Serve the built Web Shell SPA at the daemon root (`GET /`, `/assets/*`, and SPA deep-link fallback). The static shell is registered **before** the bearer-auth gate — a browser can't attach a token to a `<script>` subresource or an address-bar navigation, the shell carries no secrets, and every API route stays token-gated regardless. On non-loopback binds a one-line stderr warning notes the UI is reachable without auth. Use `--no-web` for an API-only daemon. No effect when the build omits the Web Shell assets (the daemon logs a breadcrumb and runs API-only). |
318
340
  | `--open` | `false` | After the listener is up, open the Web Shell in your default browser at the daemon URL (with `#token=` appended as a URL fragment when a token is configured — a fragment is never sent to the server, keeping the token out of access logs and Referer headers). No-op with `--no-web`, or in headless / CI / SSH environments where no browser is available. |
@@ -366,6 +388,7 @@ Notes:
366
388
  - **`LOOPBACK_BINDS` includes IPv6** — `::1` and `[::1]` count as loopback for the no-token rule.
367
389
  - **Host header allowlist** — on **loopback** binds the daemon checks `Host:` matches `localhost:port` / `127.0.0.1:port` / `[::1]:port` / `host.docker.internal:port` (case-insensitive per RFC 7230 §5.4) to defend against DNS rebinding. **Non-loopback binds (`--hostname 0.0.0.0`) intentionally bypass the Host allowlist** — the operator has chosen the surface area, so the bearer-token gate is the sole authentication layer; reverse proxies / SNI / client cert pinning are the operator's responsibility, not the daemon's. If you need Host-based isolation on a non-loopback bind, terminate TLS + check Host at a front proxy.
368
390
  - **CORS denies any browser Origin by default** — returns `403` JSON. Pass **`--allow-origin <pattern>`** (repeatable, T2.4 #4514) to opt specific browser origins through. Each value is either the literal `*` (any origin — boot refuses if no bearer token is configured; `--require-auth` on loopback is recommended for full hardening since `/health` and `/demo` remain pre-auth on loopback by default) or a canonical URL origin (`<scheme>://<host>[:<port>]`, no trailing slash / path / userinfo). Matched origins receive proper CORS response headers (`Access-Control-Allow-Origin: <echoed>`, `Vary: Origin`, plus standard methods / headers / max-age and exposed `Retry-After`); unmatched origins still get a 403 with the same envelope as the default wall. `caps.features.allow_origin` is advertised conditionally so SDK / webui clients can pre-flight whether the daemon honors cross-origin hits before issuing them. Example: `qwen serve --allow-origin http://localhost:3000 --allow-origin http://localhost:5173`. Loopback self-origin hits (e.g. the `/demo` page) are unaffected — a separate Origin-strip shim handles them regardless of `--allow-origin`. **Browser webuis without `--allow-origin` configured** still fall back to the same Stage 1 options as before: package as a native shell (Electron/Tauri) so no `Origin` header is sent, or front the daemon with a same-origin reverse proxy.
391
+ - **Chrome extension browser automation is separate from framing.** `qwen serve --allow-origin chrome-extension://<id>` lets the extension frame the Web Shell and connect to the daemon. Console/network/screenshot/click tools require an external CDP MCP adapter command: `QWEN_CDP_MCP_COMMAND=/path/to/cdp-mcp-adapter qwen serve --allow-origin chrome-extension://<id>`. The main CLI package does not bundle a browser automation adapter; clients can check `caps.features.includes('browser_automation_mcp')` before presenting those tools as available.
369
392
  - **Spawned `qwen --acp` child inherits the daemon's environment** with one explicit scrub: `QWEN_SERVER_TOKEN` is removed before the child starts (the daemon's own bearer; the agent doesn't need it). Everything else — `OPENAI_API_KEY` / `ANTHROPIC_API_KEY` / `QWEN_*` / `DASHSCOPE_API_KEY` / your custom `modelProviders[].envKey` / etc. — passes through, because the agent legitimately needs those to authenticate to the LLM. **This is intentional, not a sandbox.** The agent runs as the same UID with shell-tool access, so anything in `~/.bashrc` / `~/.aws/credentials` / `~/.npmrc` is reachable by prompt injection regardless. The env passthrough is not the security boundary; the user-as-trust-root is. Don't run `qwen serve` under an identity that has env-resident credentials you wouldn't trust the agent with.
370
393
  - **Per-subscriber bounded SSE queues** — a slow client that overflows its queue gets a `client_evicted` terminal frame and is closed; one stuck consumer can't pin the daemon.
371
394
  - **Per-session prompt admission cap** — defaults to 5 accepted-but-unsettled prompts per session. A buggy client cannot enqueue unbounded prompt promises or temporary SSE waits for one session.
@@ -410,9 +433,11 @@ Both flags accept a positive integer in milliseconds; `0`, `NaN`, non-integer, o
410
433
 
411
434
  ## Multi-session & multi-workspace deployment
412
435
 
413
- Per [#3803](https://github.com/QwenLM/qwen-code/issues/3803) §02, each `qwen serve` process binds to **one workspace** at boot. Within that workspace it multiplexes N sessions onto a single `qwen --acp` child via the agent's native session map sessions share the child's process / OAuth state / file-read cache / hierarchy-memory parse.
436
+ Pass `--workspace` more than once to register several non-overlapping workspaces in one `qwen serve` process. The first path is primary. Each registered workspace owns an isolated runtime boundary, while the daemon-wide listener, authentication policy, and total-session limit are shared. Trusted workspaces start their own `qwen --acp` child on demand. Requests may select a registered workspace by canonical `cwd`; requests that omit `cwd` use the primary workspace. Use one daemon per user or security principal; workspace trust is an execution gate, not an ACL.
437
+
438
+ An untrusted secondary workspace is visible in Web Shell as `untrusted` and `read-only`. It can be expanded to inspect the persisted session catalog, but it cannot yet be selected or opened in Web Shell, resumed, used to create sessions, or fully exported. The REST API exposes its persisted session-group catalog and, when `workspace_persisted_transcript` is advertised, its active persisted transcript through the bounded workspace-qualified pager. These reads do not include live runtime state or start an ACP child. Full workspace-qualified export requires a trusted workspace and the separate `workspace_session_export` capability. Trust the workspace and restart the daemon before using execution, mutation, or export features. An untrusted primary remains disabled in Web Shell.
414
439
 
415
- To host **multiple workspaces** (one user, several repos; or several users on the same host), run **multiple daemon processes** one per workspace, each on its own port, supervised by systemd / docker-compose / k8s / a `qwen-coordinator` reference orchestrator. The trade-off is intentional: one workspace per child means `loadSettings(cwd)` / OAuth / MCP server scope stay aligned with the bound directory and don't drift across requests.
440
+ Use separate daemon processes when you need a smaller fault or security boundary, independent bearer tokens, quotas, audit boundaries, operating-system isolation, or independent resource supervision. Multi-workspace mode is intended for one operator hosting several repos; it is not a multi-tenant isolation boundary. A single daemon token authorizes every route the daemon exposes, including the allowed read-only catalog for all registered workspaces.
416
441
 
417
442
  > **Subscribe BEFORE posting `modelServiceId` on attach.** When a client `POST /session` with a `modelServiceId` and the workspace already has a session running a different model, the daemon issues an internal `setSessionModel` call — failures are NOT propagated as an HTTP error (the session stays operational on its current model). The visible failure signal is a `model_switch_failed` event on the session's SSE stream. If you call `POST /session` and only THEN open `GET /session/:id/events`, you'll miss the failure event and silently keep talking to the wrong model. Open the SSE stream first, or pass `Last-Event-ID: 0` on subscribe to replay the ring's oldest available event.
418
443
 
@@ -420,14 +445,18 @@ To handle multiple **users** (each with their own quota, audit log, sandbox) or
420
445
 
421
446
  ## Loading and resuming a persisted session
422
447
 
423
- The daemon exposes ACP's `session/load` and resume flow over HTTP via two routes:
448
+ The daemon exposes ACP's `session/load` and resume flow over HTTP, plus a separate read-only transcript pager:
424
449
 
425
- | Route | Use when |
426
- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
427
- | `POST /session/:id/load` | The client has **no** useful local history rendered (cold reconnect, picker-then-open). For a live session, the daemon returns and injects the current bounded replay snapshot window; if older replay was dropped, the snapshot begins with `history_truncated`. Capability tag: `session_load`. |
428
- | `POST /session/:id/resume` | The client already has the turns on screen and only needs the daemon-side handle back. Model context is restored on the agent side without UI replay — the SSE stream stays clean. Capability tag: `session_resume` (`unstable_session_resume` remains a deprecated alias for older clients). |
450
+ | Route | Use when |
451
+ | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
452
+ | `POST /session/:id/load` | The client has **no** useful local history rendered (cold reconnect, picker-then-open). For a live session, the daemon returns and injects the current bounded replay snapshot window; if older replay was dropped, the snapshot begins with `history_truncated`. Capability tag: `session_load`. |
453
+ | `POST /session/:id/resume` | The client already has the turns on screen and only needs the daemon-side handle back. Model context is restored on the agent side without UI replay — the SSE stream stays clean. Capability tag: `session_resume` (`unstable_session_resume` remains a deprecated alias for older clients). |
454
+ | `GET /session/:id/transcript` | The client needs the complete active persisted transcript. It returns id-less replay frames in cursor pages and does not call `/load`, attach a client, seed the live EventBus, create a live session, or change the live replay window. Capability tag: `session_transcript`. |
455
+ | `GET /workspaces/:workspace/session/:id/transcript` | The client needs an active persisted transcript from a selected workspace without starting ACP or loading workspace settings. Registered untrusted secondary workspaces may use this read-only path. Capability tag: `workspace_persisted_transcript`. |
456
+ | `GET /workspaces/:workspace/session/:id/export` | The client needs a complete `html`, `md`, `json`, or `jsonl` attachment from a selected trusted workspace. It reads active persisted storage without starting ACP or falling back to primary. Capability tag: `workspace_session_export`. |
429
457
 
430
- The TypeScript SDK exposes both as static factories on `DaemonSessionClient`:
458
+ For load and resume, the TypeScript SDK exposes static factories on
459
+ `DaemonSessionClient`:
431
460
 
432
461
  ```ts
433
462
  import { DaemonClient, DaemonSessionClient } from '@qwen-code/sdk';
@@ -446,9 +475,23 @@ for await (const event of session.events()) {
446
475
  }
447
476
  ```
448
477
 
449
- Pre-flight `caps.features.session_load` / `caps.features.session_resume` before calling — older daemons return `404`. `unstable_session_resume` is still advertised as a deprecated compatibility alias. Concurrent same-action requests for the same id coalesce; cross-action races (a `load` racing a `resume`) get `409 restore_in_progress` with `Retry-After: 5`. See the [protocol reference](../developers/qwen-serve-protocol.md) for the full error envelope.
478
+ Pre-flight `caps.features.session_load`, `caps.features.session_resume`, or `caps.features.session_transcript` before calling the matching route — older daemons return `404`. `unstable_session_resume` is still advertised as a deprecated compatibility alias. Concurrent same-action requests for the same id coalesce; cross-action races (a `load` racing a `resume`) get `409 restore_in_progress` with `Retry-After: 5`. See the [protocol reference](../developers/qwen-serve-protocol.md) for the full error envelope.
479
+
480
+ For full persisted replay, page with `DaemonClient.getSessionTranscriptPage(sessionId, { cursor, limit })` or the raw REST route:
481
+
482
+ ```bash
483
+ curl "http://127.0.0.1:4170/session/$SESSION_ID/transcript?limit=100"
484
+ ```
485
+
486
+ For a registered workspace, use `client.workspaceById(workspaceId).getSessionTranscriptPage(sessionId, { cursor, limit })` or `/workspaces/:workspace/session/:id/transcript`. The workspace-qualified method always uses native REST even when the SDK client has a replaceable ACP transport. Its cursors are daemon-lifetime-only and must be restarted from page one after a daemon restart.
487
+
488
+ For a full attachment from a trusted registered workspace, pre-flight `workspace_session_export` and call `client.workspaceById(workspaceId).exportSession(sessionId, { format: 'html' })` or the raw `/workspaces/:workspace/session/:id/export` route. Do not infer support from `session_export` or `workspace_qualified_rest_core`: older daemons can advertise both while retaining primary-only export. The current Web Shell export action remains primary-only; use the SDK or REST route for another workspace.
489
+
490
+ `limit` counts active chat records, not emitted replay frames; one record can produce several `session_update` events. The first response freezes the JSONL snapshot size and returns `nextCursor` while `hasMore` is true. Later pages ignore appends after page 1, but return `409` if the file is deleted, truncated, replaced, archived, or otherwise conflicts with the frozen cursor. Very large snapshots return `413 transcript_too_large` before indexing so the daemon does not scan unbounded transcript files on the request path.
491
+
492
+ For repeated paging through the legacy singular route, set `--channel-idle-timeout-ms` to a positive value. With the default `0`, an idle workspace's ACP child — and the in-process transcript index cache it holds — is reaped after every page, so each page re-spawns the child and rebuilds the index by re-scanning the whole frozen prefix (`O(snapshotSize)` per page). A positive timeout keeps the child alive across the cursor walk so it reuses its cached transcript index and replay config. The workspace-qualified persisted route never starts an ACP child and is unaffected by this timeout.
450
493
 
451
- Note: live-session history replay is bounded twice: by the SSE ring for `Last-Event-ID` reconnects and by `--compacted-replay-max-bytes` for the snapshot returned by `POST /session/:id/load`. Long histories with chatty turns can exceed either bound. The daemon surfaces snapshot truncation with `history_truncated`; full transcript access is intentionally not a one-shot array response in this API. For very long sessions, prefer `resume` and rely on the client's local persisted UI until a paginated or streaming transcript endpoint is available.
494
+ Note: live-session history replay is bounded twice: by the SSE ring for `Last-Event-ID` reconnects and by `--compacted-replay-max-bytes` for the snapshot returned by `POST /session/:id/load`. Long histories with chatty turns can exceed either bound. The daemon surfaces snapshot truncation with `history_truncated`; use `/transcript` when you need the complete active persisted history.
452
495
 
453
496
  ## Durability model
454
497
 
@@ -10,8 +10,8 @@ This document lists the available keyboard shortcuts in Qwen Code.
10
10
  | `Ctrl+C` | Cancel the ongoing request and clear the input. Press twice to exit the application. |
11
11
  | `Ctrl+D` | Exit the application if the input is empty. Press twice to confirm. |
12
12
  | `Ctrl+L` | Clear the screen. |
13
- | `Ctrl+O` | Toggle compact mode (hide/show tool output and thinking). |
14
- | `Ctrl+S` | Allows long responses to print fully, disabling truncation. Use your terminal's scrollback to view the entire output. |
13
+ | `Ctrl+O` | Open/close the full-detail transcript view (a scrollable, frozen snapshot showing every tool's complete output and full thinking). Press again, or `Esc`/`q`, to close. |
14
+ | `Ctrl+S` | Stashes non-empty input for the current project and restores it on the next launch. With empty input, allows long responses to print fully, disabling truncation. Use your terminal's scrollback to view the entire output. |
15
15
  | `Ctrl+T` | Toggle the display of tool descriptions. |
16
16
  | `Ctrl+B` | While a foreground shell command is running: promote it to a background task. The child keeps running, the agent's turn unblocks, and the shell appears in `/tasks` + the Background tasks dialog. No-op when no shell is executing — Ctrl+B then falls through to its prompt-area binding (cursor-left). |
17
17
  | `Alt/Option+M` | Toggle Markdown output between rich rendered previews and raw/source mode. On macOS, the terminal must send Option as Meta. |