@qwen-code/qwen-code 0.21.7 → 0.21.8

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 (314) hide show
  1. package/README.md +2 -0
  2. package/bundled/qc-helper/docs/configuration/settings.md +43 -30
  3. package/bundled/qc-helper/docs/features/channels/dingtalk.md +40 -2
  4. package/bundled/qc-helper/docs/features/channels/feishu.md +13 -2
  5. package/bundled/qc-helper/docs/features/channels/github.md +13 -11
  6. package/bundled/qc-helper/docs/features/channels/gitlab.md +13 -11
  7. package/bundled/qc-helper/docs/features/channels/overview.md +49 -31
  8. package/bundled/qc-helper/docs/features/channels/plugins.md +2 -2
  9. package/bundled/qc-helper/docs/features/channels/qqbot.md +4 -2
  10. package/bundled/qc-helper/docs/features/channels/telegram.md +4 -2
  11. package/bundled/qc-helper/docs/features/channels/wecom.md +1 -1
  12. package/bundled/qc-helper/docs/features/code-review.md +4 -0
  13. package/bundled/qc-helper/docs/features/commands.md +1 -1
  14. package/bundled/qc-helper/docs/features/hooks.md +52 -0
  15. package/bundled/qc-helper/docs/integration-jetbrains.md +1 -0
  16. package/bundled/qc-helper/docs/qwen-serve.md +4 -1
  17. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +50 -36
  18. package/bundled/review/SKILL.md +28 -5
  19. package/chunks/{MaxSizedBox-ANWZBPTS.js → MaxSizedBox-7PM6BGJ5.js} +26 -22
  20. package/chunks/{StandaloneSessionPicker-XKS3VU3A.js → StandaloneSessionPicker-3UQHM7GV.js} +44 -40
  21. package/chunks/{acp-startup-profiler-ORIQ2CCQ.js → acp-startup-profiler-B5BYAMYQ.js} +2 -2
  22. package/chunks/{acpAgent-KUAZ3GCZ.js → acpAgent-5UWLFV6V.js} +534 -262
  23. package/chunks/{agent-T6PTGX5R.js → agent-624T2BLO.js} +26 -22
  24. package/chunks/{agent-headless-PR7YCB7S.js → agent-headless-2EE5J2KX.js} +26 -22
  25. package/chunks/{artifact-tool-U4VOZIK5.js → artifact-tool-N652YE4L.js} +1 -1
  26. package/chunks/{askUserQuestion-XOBQLPFA.js → askUserQuestion-ONW74PKJ.js} +1 -1
  27. package/chunks/{bridge-NU6YEEHK.js → bridge-JENKGFFP.js} +29 -25
  28. package/chunks/{ca-NYKNH222.js → ca-ZLKAB4K3.js} +6 -0
  29. package/chunks/{channel-management-service-FSQ7SHYI.js → channel-management-service-DDWUPHMU.js} +19 -10
  30. package/chunks/{channel-settings-store-35VQVUVV.js → channel-settings-store-SA6JZSPH.js} +34 -30
  31. package/chunks/{channel-worker-group-JWQK224X.js → channel-worker-group-E67EN3RV.js} +5 -5
  32. package/chunks/{channel-worker-manager-77E3OXRQ.js → channel-worker-manager-SW4C45CF.js} +5 -5
  33. package/chunks/{channel-worker-supervisor-62YWUGP2.js → channel-worker-supervisor-5SRD24FG.js} +3 -3
  34. package/chunks/{chunk-CJXIIILK.js → chunk-2FRY5CRX.js} +1 -1
  35. package/chunks/{chunk-ZJ3VGYHK.js → chunk-2ILAOM2I.js} +34 -17
  36. package/chunks/{chunk-6XJMFJ4D.js → chunk-2M4K4KYS.js} +177 -120
  37. package/chunks/{chunk-CNIID3TV.js → chunk-2UUMVNYT.js} +1 -1
  38. package/chunks/{chunk-22NBYCPD.js → chunk-3P2LV43B.js} +1 -1
  39. package/chunks/{chunk-2U3WZGZG.js → chunk-3PY4LPJF.js} +19 -131
  40. package/chunks/{chunk-SPMY6CX6.js → chunk-3SE7J4DR.js} +3 -3
  41. package/chunks/{chunk-6UWFTUQL.js → chunk-3WNQOYHQ.js} +66 -22
  42. package/chunks/{chunk-KXSDEOFU.js → chunk-4ALIARFY.js} +1 -1
  43. package/chunks/{chunk-D3UEZIQH.js → chunk-4DU3NCHG.js} +48 -55
  44. package/chunks/{chunk-BGG4MBYD.js → chunk-4PYCZH2V.js} +4 -187
  45. package/chunks/{chunk-H2UQ2M5Z.js → chunk-4WU6NY7F.js} +96 -22
  46. package/chunks/{chunk-TLV2IMHR.js → chunk-5ZGR6RKJ.js} +3 -3
  47. package/chunks/{chunk-3K7FH2KQ.js → chunk-67N6HB5H.js} +1310 -171
  48. package/chunks/{chunk-EORNAQDT.js → chunk-6TR7CFXH.js} +1 -1
  49. package/chunks/{chunk-NG2R4N5O.js → chunk-6ZRFAKXK.js} +1 -1
  50. package/chunks/{chunk-P2AJ7FTI.js → chunk-757GB46F.js} +1 -1
  51. package/chunks/{chunk-72LNFGUY.js → chunk-77QVBFCU.js} +3 -3
  52. package/chunks/{chunk-OH2VKQXH.js → chunk-7DVT4LVV.js} +37 -30
  53. package/chunks/{chunk-KKJJB5X6.js → chunk-7VUERJHS.js} +1503 -815
  54. package/chunks/{chunk-VOARQPTA.js → chunk-B52AWKBB.js} +65 -21
  55. package/chunks/{chunk-Y4EWSQF7.js → chunk-BF224XHL.js} +2 -2
  56. package/chunks/{chunk-PJOBIWUG.js → chunk-BF52U4XJ.js} +1 -1
  57. package/chunks/{chunk-55LYDVPU.js → chunk-C5VWPTGT.js} +1 -1
  58. package/chunks/{chunk-W7U4ESW2.js → chunk-CG3WBKJK.js} +1 -1
  59. package/chunks/chunk-COBO5EBO.js +135 -0
  60. package/chunks/chunk-CPG6P4GG.js +82 -0
  61. package/chunks/{chunk-DIEFUBV6.js → chunk-DIWZNWZT.js} +205 -35
  62. package/chunks/{chunk-AE77C5ZU.js → chunk-DQSDACD2.js} +1 -1
  63. package/chunks/{chunk-P3LEG54R.js → chunk-DX5W5AON.js} +2 -2
  64. package/chunks/{chunk-EUQTXRKZ.js → chunk-E4ZBKMSF.js} +5 -5
  65. package/chunks/{chunk-FPM27XN4.js → chunk-EIVICVHM.js} +4 -4
  66. package/chunks/{chunk-YHEEE624.js → chunk-EN2TKTFH.js} +1 -1
  67. package/chunks/chunk-F6WFNA7U.js +22 -0
  68. package/chunks/{chunk-FZBZSYKU.js → chunk-FN6YXJOP.js} +1 -1
  69. package/chunks/{chunk-KR4ZSC7K.js → chunk-FWBXMANW.js} +3 -3
  70. package/chunks/{chunk-LA7YLSR6.js → chunk-FYAXKJK7.js} +327 -67
  71. package/chunks/{chunk-CSZEXZBE.js → chunk-GBDINRIL.js} +3 -3
  72. package/chunks/{chunk-SCI7K3GM.js → chunk-GOEVOFQI.js} +19 -10
  73. package/chunks/{chunk-LEMXGVEP.js → chunk-GQCEQPYQ.js} +3 -3
  74. package/chunks/{chunk-Y7E5LNLO.js → chunk-GXSNGY5M.js} +1027 -876
  75. package/chunks/{chunk-6XU3PH66.js → chunk-HA3SAB64.js} +22 -69
  76. package/chunks/{chunk-Y4NGLFGJ.js → chunk-HUWENAHO.js} +1 -1
  77. package/chunks/{chunk-3ULCB3NE.js → chunk-HV76SFIA.js} +1 -1
  78. package/chunks/{chunk-CB2464BK.js → chunk-HWX5HPUG.js} +14 -4
  79. package/chunks/{chunk-LZC3B5N2.js → chunk-IA7TGCN2.js} +2 -2
  80. package/chunks/{chunk-RERATVSK.js → chunk-IBYULW65.js} +6 -6
  81. package/chunks/{chunk-HYRDKNUY.js → chunk-IUQ52YJK.js} +1 -1
  82. package/chunks/{chunk-TDXGKHDN.js → chunk-IYES5WOT.js} +2 -2
  83. package/chunks/{chunk-RGSBTHSU.js → chunk-KAQCJO6Y.js} +131 -4
  84. package/chunks/{chunk-VWOVHOTT.js → chunk-KJZ26VBX.js} +1 -1
  85. package/chunks/{chunk-6GONZVLS.js → chunk-KKDVZLGL.js} +1 -1
  86. package/chunks/{chunk-MKVZE4ZJ.js → chunk-KTJFU7RT.js} +3 -2
  87. package/chunks/{chunk-R574ATRM.js → chunk-M2PNLYGY.js} +41 -0
  88. package/chunks/{chunk-6EOI4HOK.js → chunk-M3STHEMM.js} +12 -17
  89. package/chunks/chunk-NGYI5EF5.js +244 -0
  90. package/chunks/{chunk-ALGGS7UH.js → chunk-NPQ5ZKRP.js} +82 -1
  91. package/chunks/{chunk-HQB2KUAN.js → chunk-NPUXXRJI.js} +1 -1
  92. package/chunks/{chunk-QETYKPMG.js → chunk-NVRDQFCX.js} +1 -1
  93. package/chunks/{chunk-PQBHU2IA.js → chunk-OHKJVAKG.js} +10 -10
  94. package/chunks/{chunk-CYR3HI5X.js → chunk-OQTXYMKW.js} +2 -2
  95. package/chunks/{chunk-DBOFL3LQ.js → chunk-PG62DFWD.js} +10 -10
  96. package/chunks/{chunk-2VSTGY6M.js → chunk-PJRW65JO.js} +1 -1
  97. package/chunks/{chunk-33ACCIIY.js → chunk-PLFATELK.js} +1 -1
  98. package/chunks/{chunk-IC4Z6LX6.js → chunk-PYQADEFD.js} +5 -0
  99. package/chunks/{chunk-MAJS7AT4.js → chunk-QGHSP65Z.js} +2 -2
  100. package/chunks/{chunk-OHJLEW5J.js → chunk-QQWD7LZV.js} +4 -4
  101. package/chunks/{chunk-ZXU5UHMI.js → chunk-QXVSWG66.js} +2 -2
  102. package/chunks/{chunk-E33LOKRA.js → chunk-RPWVIXDB.js} +18 -1
  103. package/chunks/{chunk-TYKC75AX.js → chunk-S3Y3GBFD.js} +1 -1
  104. package/chunks/{chunk-7UFKAV7Y.js → chunk-S6HYI3MF.js} +2 -2
  105. package/chunks/chunk-SAH4BD2J.js +92 -0
  106. package/chunks/{chunk-OMKQH5C5.js → chunk-SNRT2TJJ.js} +6 -23
  107. package/chunks/chunk-SR7RZ4MS.js +202 -0
  108. package/chunks/{chunk-CXE7E23H.js → chunk-TE3ZAJE7.js} +45 -17
  109. package/chunks/{chunk-S7CV4KO6.js → chunk-TKSZJ5BV.js} +3 -3
  110. package/chunks/{chunk-3NB7TSE2.js → chunk-U5SLIG7E.js} +1 -1
  111. package/chunks/chunk-UA5H3DS2.js +203 -0
  112. package/chunks/{chunk-24ER7UV4.js → chunk-UFALT4LK.js} +1 -1
  113. package/chunks/{chunk-YJQCUTT2.js → chunk-VWMUDKLC.js} +3 -3
  114. package/chunks/{chunk-RMH5OWLD.js → chunk-VXZ5HAOV.js} +1 -1
  115. package/chunks/{chunk-BVWVWGLE.js → chunk-WAUGQKUU.js} +4 -64
  116. package/chunks/{chunk-SHZYHGQH.js → chunk-WG6542MA.js} +1 -1
  117. package/chunks/{chunk-5KH532V7.js → chunk-WV5J6Q6N.js} +1 -1
  118. package/chunks/{chunk-RNVQB725.js → chunk-XHD7CRP2.js} +2 -2
  119. package/chunks/{chunk-W4B7UBUS.js → chunk-XZKQT2B2.js} +5 -5
  120. package/chunks/{chunk-6HVUFDS2.js → chunk-Y4TETC74.js} +22 -13
  121. package/chunks/{chunk-RZHU3ILK.js → chunk-YEF7XEO2.js} +4 -4
  122. package/chunks/{chunk-RUL4S3K3.js → chunk-YHJFF7KH.js} +146 -45
  123. package/chunks/{chunk-23RZCH76.js → chunk-YOM7DEGB.js} +3 -3
  124. package/chunks/{chunk-OFI7IGST.js → chunk-ZCLLJARV.js} +9 -9
  125. package/chunks/{chunk-GSS34377.js → chunk-ZHA242R4.js} +2 -2
  126. package/chunks/{chunk-TRLYP7OF.js → chunk-ZPLALRXZ.js} +17 -9
  127. package/chunks/{chunk-WUC6ZFXO.js → chunk-ZWBUH5UP.js} +1 -1
  128. package/chunks/{computer-use-KEAPATUY.js → computer-use-ESQYJ3JY.js} +26 -22
  129. package/chunks/{config-utils-K7SCOWHD.js → config-utils-XQHBJP7G.js} +4 -4
  130. package/chunks/{contextCommand-ZJA6A5K5.js → contextCommand-CX3YF4ZE.js} +28 -24
  131. package/chunks/{core-runtime-QMJPWHCI.js → core-runtime-DIAU7JMG.js} +30 -26
  132. package/chunks/{create-sub-session-DJE6XICH.js → create-sub-session-HDPD6HOA.js} +26 -22
  133. package/chunks/{create-sub-session-E4PBYXV5.js → create-sub-session-QIDZUOPU.js} +1 -1
  134. package/chunks/{cron-create-GRBWYMIJ.js → cron-create-VONA5JYY.js} +1 -1
  135. package/chunks/{cron-delete-4CMKBR2M.js → cron-delete-5JXSP2MI.js} +1 -1
  136. package/chunks/{cron-list-W7K4ASOA.js → cron-list-KE4F2CIR.js} +1 -1
  137. package/chunks/{daemon-SCTQMM7Z.js → daemon-VZBGJUNL.js} +30 -0
  138. package/chunks/{daemon-status-provider-FSWDPE2G.js → daemon-status-provider-H6O4UQ4F.js} +33 -29
  139. package/chunks/{daemon-trust-policy-P5L5VFAY.js → daemon-trust-policy-BNUXG6MT.js} +33 -29
  140. package/chunks/{daemon-trust-policy-monitor-73JYN6ET.js → daemon-trust-policy-monitor-E4EQ7GF4.js} +33 -29
  141. package/chunks/{de-VL76CPLV.js → de-LIW4XVLN.js} +5 -0
  142. package/chunks/{deferred-core-runtime-BWRCCFTE.js → deferred-core-runtime-CBMSHPAU.js} +26 -22
  143. package/chunks/{display-image-O2XFPQTC.js → display-image-NQRSIBXM.js} +2 -2
  144. package/chunks/{dist-DPPHJAVL.js → dist-EEEQGCZA.js} +918 -142
  145. package/chunks/{dist-K4WWQBHS.js → dist-HIACTZEK.js} +55 -15
  146. package/chunks/{dist-3BMEUGTG.js → dist-IRL7WA5Z.js} +1 -1
  147. package/chunks/{dist-HVBMEYWK.js → dist-KVISB2O2.js} +1 -1
  148. package/chunks/{dist-KS4O2NKE.js → dist-MBF3I5MX.js} +14 -8
  149. package/chunks/{dist-SFQ34F4M.js → dist-MKX5OSFF.js} +5 -4
  150. package/chunks/{dist-7JGAAQSC.js → dist-RCH3I7SS.js} +2 -2
  151. package/chunks/{dist-C5U4LJKW.js → dist-TUSWNE2I.js} +5 -4
  152. package/chunks/{earlyInputCapture-L5ST23A6.js → earlyInputCapture-UIOP7OIN.js} +26 -22
  153. package/chunks/{edit-LHHRFNFK.js → edit-ITMZYFKA.js} +26 -22
  154. package/chunks/{en-IRJ2WN5T.js → en-SY5GTIGX.js} +6 -0
  155. package/chunks/{enter-worktree-6NXCRZPF.js → enter-worktree-S4PL5UV6.js} +26 -22
  156. package/chunks/{enterPlanMode-ZVQT4U7D.js → enterPlanMode-YV52NNJT.js} +26 -22
  157. package/chunks/{environment-GJ2HWJOS.js → environment-NGOWPRZV.js} +30 -26
  158. package/chunks/{errors-6RLH3XXC.js → errors-BU26DTDX.js} +28 -24
  159. package/chunks/{exit-worktree-I2YLUHHY.js → exit-worktree-XRM6LH5F.js} +26 -22
  160. package/chunks/{exitPlanMode-7CCWKO7I.js → exitPlanMode-ZLI5F7KR.js} +26 -22
  161. package/chunks/{fast-path-DVFD4HQD.js → fast-path-UJWORIED.js} +23 -3
  162. package/chunks/{fast-path-settings-WQJU2LAT.js → fast-path-settings-37WQD5B2.js} +6 -3
  163. package/chunks/{fr-GK3HQYVB.js → fr-RQFO7U4P.js} +5 -0
  164. package/chunks/{gemini-7FWGOYD4.js → gemini-ZSKNDUMU.js} +77 -65
  165. package/chunks/{geminiContentGenerator-V2WVLIXU.js → geminiContentGenerator-YGEXOEKD.js} +1 -1
  166. package/chunks/{glob-3N6GGI75.js → glob-7KZG44BR.js} +26 -22
  167. package/chunks/{goal-tools-APOW6UXL.js → goal-tools-PXWN5VK3.js} +4 -2
  168. package/chunks/{grep-V43ILZVX.js → grep-6ZFC7RJ5.js} +26 -22
  169. package/chunks/{handleAutoUpdate-A5WFVWIA.js → handleAutoUpdate-KSEL3TQS.js} +30 -26
  170. package/chunks/{i18n-PLVQ4FBZ.js → i18n-ZIUXBW5V.js} +27 -23
  171. package/chunks/{image-gen-7C6IK6DC.js → image-gen-AUIZJJNK.js} +7 -5
  172. package/chunks/{initializer-CVAIKZYL.js → initializer-7AHY3N6Q.js} +33 -29
  173. package/chunks/{installationInfo-J6QDHNTK.js → installationInfo-VGBXMYLY.js} +27 -23
  174. package/chunks/{ja-3FA46IKD.js → ja-KOZKHJHZ.js} +5 -0
  175. package/chunks/{list-ZZ4OUUWV.js → list-PSFKQHLB.js} +36 -32
  176. package/chunks/{list-agents-KFFIIS2G.js → list-agents-Z4WABFDZ.js} +1 -1
  177. package/chunks/{loadedSettingsAdapter-QRYRJSWL.js → loadedSettingsAdapter-FTMRCTOF.js} +33 -29
  178. package/chunks/{loggingContentGenerator-OJCO75HM.js → loggingContentGenerator-MZAN52UV.js} +7 -5
  179. package/chunks/{loop-wakeup-TLMJPMMP.js → loop-wakeup-UZ5RL5Y2.js} +2 -2
  180. package/chunks/{ls-UVVE2XGE.js → ls-TVHDGIES.js} +1 -1
  181. package/chunks/{lsp-QMEA2VLB.js → lsp-CVN6OQPI.js} +1 -1
  182. package/chunks/{managed-npm-update-PCOSCP2N.js → managed-npm-update-O4NHK45X.js} +27 -23
  183. package/chunks/{mcp-M3WKKWKY.js → mcp-6CFP2AYQ.js} +33 -29
  184. package/chunks/{monitor-GN24FH6C.js → monitor-DAKD6OU4.js} +26 -22
  185. package/chunks/{nonInteractiveCli-KPTU3VSQ.js → nonInteractiveCli-RC7VIUZL.js} +66 -60
  186. package/chunks/{notebook-edit-4YM65BBO.js → notebook-edit-474DPMRL.js} +34 -22
  187. package/chunks/{openaiContentGenerator-EDQT6GTV.js → openaiContentGenerator-2NFY2MWO.js} +19 -9
  188. package/chunks/{pidfile-JOIIRN2C.js → pidfile-KBFVDNQP.js} +26 -22
  189. package/chunks/{process-registry-2CHQBXH5.js → process-registry-PMJOA5CO.js} +15 -0
  190. package/chunks/{processUtils-5SV4MX3Q.js → processUtils-6GRYH4Y3.js} +2 -2
  191. package/chunks/{pt-3AOBKPIJ.js → pt-U6AOCTMF.js} +5 -0
  192. package/chunks/{qwenContentGenerator-ODRJSUGR.js → qwenContentGenerator-KAHU6IZY.js} +33 -28
  193. package/chunks/{qwenOAuth2-NESCMZ47.js → qwenOAuth2-RRQTCP4W.js} +7 -5
  194. package/chunks/{read-file-HPSODLPK.js → read-file-3M6WXDXP.js} +6 -4
  195. package/chunks/{read-mcp-resource-2TNSJTC3.js → read-mcp-resource-PZ4ZF6YL.js} +1 -1
  196. package/chunks/{record-artifact-RAON52FC.js → record-artifact-P4HFMS7X.js} +2 -2
  197. package/chunks/{resumeHistoryUtils-TXCOFFMQ.js → resumeHistoryUtils-D6TAY3HX.js} +30 -26
  198. package/chunks/{ripGrep-ZKQGTQAO.js → ripGrep-PLPENT3E.js} +26 -22
  199. package/chunks/{ru-VJRAMC4W.js → ru-CMX4UMYP.js} +5 -0
  200. package/chunks/{run-qwen-serve-ZPKPKECF.js → run-qwen-serve-ZAFIJKJC.js} +168 -54
  201. package/chunks/{runtime-2FLNNM36.js → runtime-ZED7CYOZ.js} +38 -34
  202. package/chunks/{scheduler-365PJHNR.js → scheduler-MD3AL2W5.js} +26 -22
  203. package/chunks/{send-message-ZM7MRUGP.js → send-message-CAMSLG2L.js} +4 -3
  204. package/chunks/{serve-QD2RNLKJ.js → serve-E3VUDRZN.js} +33 -29
  205. package/chunks/{server-XLJVLTYM.js → server-OWMEMAKR.js} +450 -231
  206. package/chunks/{session-3VTUHH4Q.js → session-HZ57QK7K.js} +158 -97
  207. package/chunks/{settings-KULVPCQC.js → settings-V7BR3RKP.js} +32 -28
  208. package/chunks/{shell-3SWW22MH.js → shell-23OMNMW6.js} +26 -22
  209. package/chunks/{skill-KDHWYS7W.js → skill-6HBDYZRS.js} +7 -5
  210. package/chunks/{skill-settings-NMY4JEJC.js → skill-settings-HWJLTU7M.js} +32 -28
  211. package/chunks/{spawnChannel-ZKS4Q5OU.js → spawnChannel-N6KKUW5B.js} +27 -23
  212. package/chunks/{standalone-update-7CXPGAQ4.js → standalone-update-QGIKHATD.js} +28 -24
  213. package/chunks/{startInteractiveUI-2QQLEKM6.js → startInteractiveUI-GX2CRL42.js} +365 -155
  214. package/chunks/{syntheticOutput-ZLCUTKO2.js → syntheticOutput-PEBJQYJV.js} +2 -2
  215. package/chunks/{task-create-CQP5UEA3.js → task-create-5NWCQSJF.js} +5 -4
  216. package/chunks/{task-list-XLEZOJXP.js → task-list-53265TRZ.js} +1 -1
  217. package/chunks/{task-stop-7ZQM5CFF.js → task-stop-FPCOIRYX.js} +1 -1
  218. package/chunks/{task-update-JA75U2SN.js → task-update-5HN577LS.js} +5 -4
  219. package/chunks/{team-create-2WTNGAOX.js → team-create-CFFKU7KL.js} +26 -22
  220. package/chunks/{team-delete-MHY3UZGY.js → team-delete-MMQB4OSC.js} +1 -1
  221. package/chunks/{team-plan-approval-LZTYLEG4.js → team-plan-approval-6EFOKR6A.js} +26 -22
  222. package/chunks/{terminal-image-renderer-R5HHAFJN.js → terminal-image-renderer-TLDNACQY.js} +28 -24
  223. package/chunks/{theme-manager-PAUCSJFF.js → theme-manager-5LJ3H7VO.js} +26 -22
  224. package/chunks/{todoWrite-UPVOHYGD.js → todoWrite-JGV6VLOX.js} +1 -1
  225. package/chunks/{tool-search-2BFCGLI6.js → tool-search-UJV3A24H.js} +9 -6
  226. package/chunks/{total-session-admission-MK4SINFK.js → total-session-admission-D63QYXGO.js} +29 -25
  227. package/chunks/{trustedFolders-TJ5S26N7.js → trustedFolders-KZCOB53W.js} +30 -24
  228. package/chunks/{update-relaunch-N7AYLARF.js → update-relaunch-IFILM3SA.js} +5 -5
  229. package/chunks/{updateCheck-QRZ3DVT5.js → updateCheck-YZ2CRCFC.js} +29 -25
  230. package/chunks/{useAutoAcceptIndicator-DBJ7Y5AF.js → useAutoAcceptIndicator-AXEVNA3Q.js} +35 -31
  231. package/chunks/{validateNonInterActiveAuth-6ZQWUDS3.js → validateNonInterActiveAuth-3WTOJFWA.js} +61 -57
  232. package/chunks/{version-AJQGQWXC.js → version-GXK7OHZY.js} +1 -1
  233. package/chunks/{web-fetch-QWJYRXFL.js → web-fetch-ILB4GAVR.js} +12 -8
  234. package/chunks/{web-search-2AOXJGHU.js → web-search-HKRPGPZZ.js} +8 -6
  235. package/chunks/{workflow-ERH3SJG2.js → workflow-FXIPRQQA.js} +750 -147
  236. package/chunks/{workspace-providers-status-HZ474RA4.js → workspace-providers-status-NYHC7HSR.js} +35 -31
  237. package/chunks/{workspace-registration-store-6EUP4JXG.js → workspace-registration-store-AKEB7OMW.js} +1 -1
  238. package/chunks/{workspace-registry-R4APRRNC.js → workspace-registry-CDAS5TVZ.js} +29 -25
  239. package/chunks/{workspace-service-HFIFDMU7.js → workspace-service-PAMUKMAV.js} +36 -32
  240. package/chunks/{workspace-skills-status-HAHEIHGK.js → workspace-skills-status-YQSHCCMS.js} +33 -29
  241. package/chunks/{workspace-trust-reconciler-65GTAGDK.js → workspace-trust-reconciler-RPTXOIY2.js} +36 -32
  242. package/chunks/{write-file-B34CDELV.js → write-file-CGS57TS4.js} +26 -22
  243. package/chunks/{zh-ARWDLDLR.js → zh-AGL2FVBI.js} +6 -0
  244. package/chunks/{zh-TW-Y4RGI3P7.js → zh-TW-KI66MHQY.js} +6 -0
  245. package/chunks/{zoom-image-HPRBZHSS.js → zoom-image-E7D72GYV.js} +6 -4
  246. package/cli.js +13 -13
  247. package/locales/ca.js +10 -0
  248. package/locales/de.js +9 -0
  249. package/locales/en.js +10 -0
  250. package/locales/fr.js +9 -0
  251. package/locales/ja.js +9 -0
  252. package/locales/pt.js +9 -0
  253. package/locales/ru.js +9 -0
  254. package/locales/zh-TW.js +10 -0
  255. package/locales/zh.js +10 -0
  256. package/package.json +3 -3
  257. package/web-shell/assets/{arc-Ip-FFDJ0.js → arc-DybZaz32.js} +1 -1
  258. package/web-shell/assets/{architectureDiagram-3BPJPVTR-CChqgwIb.js → architectureDiagram-3BPJPVTR-jN3qBd19.js} +1 -1
  259. package/web-shell/assets/{blockDiagram-GPEHLZMM-BHN-Tfss.js → blockDiagram-GPEHLZMM-Ct5DZPrj.js} +1 -1
  260. package/web-shell/assets/{c4Diagram-AAUBKEIU-BhyjzDjN.js → c4Diagram-AAUBKEIU-CUAFMlUG.js} +1 -1
  261. package/web-shell/assets/channel-BMwLrwLW.js +1 -0
  262. package/web-shell/assets/{chunk-2J33WTMH-BB9eyHrx.js → chunk-2J33WTMH-CuV8n90B.js} +1 -1
  263. package/web-shell/assets/{chunk-4BX2VUAB-BeV7ce_J.js → chunk-4BX2VUAB-BUzl_kls.js} +1 -1
  264. package/web-shell/assets/{chunk-55IACEB6-DO7kXDiV.js → chunk-55IACEB6-BnDBLX6A.js} +1 -1
  265. package/web-shell/assets/{chunk-727SXJPM-B27MPznD.js → chunk-727SXJPM-B83uTOjm.js} +1 -1
  266. package/web-shell/assets/{chunk-AQP2D5EJ-DHIjqjD_.js → chunk-AQP2D5EJ-DM3HLgpT.js} +1 -1
  267. package/web-shell/assets/{chunk-FMBD7UC4-DabMqyN2.js → chunk-FMBD7UC4-CSQ5hgyb.js} +1 -1
  268. package/web-shell/assets/{chunk-ND2GUHAM-Dw7Nnnxc.js → chunk-ND2GUHAM-BWOF4SxX.js} +1 -1
  269. package/web-shell/assets/{chunk-QZHKN3VN-DdaZew1Q.js → chunk-QZHKN3VN-BsOH9LMi.js} +1 -1
  270. package/web-shell/assets/classDiagram-4FO5ZUOK-BGDv98jY.js +1 -0
  271. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BGDv98jY.js +1 -0
  272. package/web-shell/assets/{cose-bilkent-S5V4N54A-CgBpCYH5.js → cose-bilkent-S5V4N54A-IENqH2iJ.js} +1 -1
  273. package/web-shell/assets/{dagre-BM42HDAG-BB4IU8G0.js → dagre-BM42HDAG--dyzDTGo.js} +1 -1
  274. package/web-shell/assets/{diagram-2AECGRRQ-BcUTHU37.js → diagram-2AECGRRQ-BE7Dcqof.js} +1 -1
  275. package/web-shell/assets/{diagram-5GNKFQAL-B6Lyihyv.js → diagram-5GNKFQAL-Cr8-5OTj.js} +1 -1
  276. package/web-shell/assets/{diagram-KO2AKTUF-CRIJOjpG.js → diagram-KO2AKTUF-Bzey3uAY.js} +1 -1
  277. package/web-shell/assets/{diagram-LMA3HP47-DdNiwWWT.js → diagram-LMA3HP47-sErl28Xb.js} +1 -1
  278. package/web-shell/assets/{diagram-OG6HWLK6-Dz4b32Do.js → diagram-OG6HWLK6-Dq30ATIo.js} +1 -1
  279. package/web-shell/assets/{erDiagram-TEJ5UH35-D-8NGw77.js → erDiagram-TEJ5UH35-BkCoEfVW.js} +1 -1
  280. package/web-shell/assets/{flowDiagram-I6XJVG4X-Dun26LyM.js → flowDiagram-I6XJVG4X-DHwO0rrI.js} +1 -1
  281. package/web-shell/assets/{ganttDiagram-6RSMTGT7-F10Hu1Gc.js → ganttDiagram-6RSMTGT7-s7vAPxWq.js} +1 -1
  282. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Bf8Ez6-D.js → gitGraphDiagram-PVQCEYII-CQxhwPOU.js} +1 -1
  283. package/web-shell/assets/index-Bckpjr-I.css +5 -0
  284. package/web-shell/assets/{index-BXqw-nGq.js → index-CF4wApWp.js} +1 -1
  285. package/web-shell/assets/index-DwEr9HEW.js +1768 -0
  286. package/web-shell/assets/{infoDiagram-5YYISTIA-DVgTMLvj.js → infoDiagram-5YYISTIA-BnFrD0bq.js} +1 -1
  287. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-uT-KepvK.js → ishikawaDiagram-YF4QCWOH-Bf9zK5NK.js} +1 -1
  288. package/web-shell/assets/{journeyDiagram-JHISSGLW-Vg_XadQf.js → journeyDiagram-JHISSGLW-CyGAhsxi.js} +1 -1
  289. package/web-shell/assets/{kanban-definition-UN3LZRKU-Dyv1ESBE.js → kanban-definition-UN3LZRKU-CbsK5akB.js} +1 -1
  290. package/web-shell/assets/{linear-BMIepYX3.js → linear-cQsF4P8D.js} +1 -1
  291. package/web-shell/assets/{mermaid.core-zA8pJ9ag.js → mermaid.core-Z4HVqrKY.js} +5 -5
  292. package/web-shell/assets/{mindmap-definition-RKZ34NQL-BCW_BZ_5.js → mindmap-definition-RKZ34NQL-CYnrBo_f.js} +1 -1
  293. package/web-shell/assets/{pieDiagram-4H26LBE5-DseNEGp2.js → pieDiagram-4H26LBE5-CBzOfhrs.js} +1 -1
  294. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-6Z7wr1Fi.js → quadrantDiagram-W4KKPZXB-D4LK1Ebn.js} +1 -1
  295. package/web-shell/assets/{requirementDiagram-4Y6WPE33-CVOlCRPf.js → requirementDiagram-4Y6WPE33-Bzti2Lcj.js} +1 -1
  296. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-CGhgrUJZ.js → sankeyDiagram-5OEKKPKP-yTBw5Z2s.js} +1 -1
  297. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-dlqmpLuQ.js → sequenceDiagram-3UESZ5HK-D07UVRiZ.js} +1 -1
  298. package/web-shell/assets/{stateDiagram-AJRCARHV-B9EW10Xb.js → stateDiagram-AJRCARHV-UE_lHsTn.js} +1 -1
  299. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DC6xgXjX.js +1 -0
  300. package/web-shell/assets/{timeline-definition-PNZ67QCA-BBRh0mgZ.js → timeline-definition-PNZ67QCA-DRvYdiTs.js} +1 -1
  301. package/web-shell/assets/{vennDiagram-CIIHVFJN-B8Gs-REP.js → vennDiagram-CIIHVFJN-CQLIXs0u.js} +1 -1
  302. package/web-shell/assets/{wardley-L42UT6IY-D_y80Ur7.js → wardley-L42UT6IY-JZz_Xqse.js} +1 -1
  303. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-D-CNfHJ-.js → wardleyDiagram-YWT4CUSO--i7BiJwB.js} +1 -1
  304. package/web-shell/assets/{xychartDiagram-2RQKCTM6-DQ5CvELo.js → xychartDiagram-2RQKCTM6-Bkc-bW0S.js} +1 -1
  305. package/web-shell/index.html +2 -2
  306. package/chunks/chunk-6PEXNQTX.js +0 -68
  307. package/chunks/chunk-IUFV6FYU.js +0 -81
  308. package/web-shell/assets/channel-Cu8qd6OB.js +0 -1
  309. package/web-shell/assets/classDiagram-4FO5ZUOK-BI3KrXhq.js +0 -1
  310. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BI3KrXhq.js +0 -1
  311. package/web-shell/assets/index-QQlUCJGg.css +0 -5
  312. package/web-shell/assets/index-hcgjV7vS.js +0 -1768
  313. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CJTZJJ5X.js +0 -1
  314. package/chunks/{anthropicContentGenerator-DTMVEL5M.js → anthropicContentGenerator-SSFE2753.js} +9 -9
@@ -100,9 +100,10 @@ Open QQ and send a message to your bot. You should see the response arrive in yo
100
100
 
101
101
  To use the bot in QQ groups:
102
102
 
103
- 1. Set `groupPolicy` to `"allowlist"` or `"open"` in your channel config
103
+ 1. Set `groupPolicy` to `"allowlist"`, `"pairing"`, or `"open"` in your channel config
104
104
  2. Add the bot to a QQ group via the QQ Bot Open Platform dashboard or by having a group admin invite it
105
105
  3. Group members must **@mention** the bot to trigger a response
106
+ 4. If using `groupPolicy: "pairing"`, approve the group's pairing request once before responses start. Note that once a group is approved, **any member of that group** can use the bot; `senderPolicy` and `allowedUsers` do not gate members of an approved group.
106
107
 
107
108
  QQ Bot API V2 only delivers group messages that @mention the bot — the bot does not see all group messages. By default, `requireMention` is `true` and should be left that way for QQ.
108
109
 
@@ -159,7 +160,8 @@ Token refresh continues across WebSocket reconnects — the channel never goes o
159
160
 
160
161
  ### Bot doesn't respond in groups
161
162
 
162
- - Check that `groupPolicy` is set to `"allowlist"` or `"open"` (default is `"disabled"`)
163
+ - Check that `groupPolicy` is set to `"allowlist"`, `"pairing"`, or `"open"` (default is `"disabled"`)
164
+ - If using `"pairing"`, verify the group's pairing request has been approved
163
165
  - **You must @mention the bot** — QQ only delivers messages that tag the bot
164
166
  - Verify the bot has been added to the group
165
167
 
@@ -70,10 +70,11 @@ Then open your bot in Telegram and send a message. You should see "Working..." a
70
70
 
71
71
  To use the bot in Telegram groups:
72
72
 
73
- 1. Set `groupPolicy` to `"allowlist"` or `"open"` in your channel config
73
+ 1. Set `groupPolicy` to `"allowlist"`, `"pairing"`, or `"open"` in your channel config
74
74
  2. **Disable privacy mode** in BotFather: `/mybots` → select your bot → Bot Settings → Group Privacy → Turn Off
75
75
  3. Add the bot to a group. If it was already in the group, **remove and re-add it** (Telegram caches privacy settings from when the bot joined)
76
76
  4. If using `groupPolicy: "allowlist"`, add the group's chat ID to `groups` in your config
77
+ 5. If using `groupPolicy: "pairing"`, approve the group's pairing request once before responses start. Note that once a group is approved, **any member of that group** can use the bot; `senderPolicy` and `allowedUsers` do not gate members of an approved group.
77
78
 
78
79
  By default, the bot requires an @mention or a reply to respond in groups. Set `"requireMention": false` for a specific group to make it respond to all messages (useful for dedicated task groups). See [Group Chats](./overview#group-chats) for full details.
79
80
 
@@ -105,8 +106,9 @@ The agent's markdown responses are automatically converted to Telegram-compatibl
105
106
 
106
107
  ### Bot doesn't respond in groups
107
108
 
108
- - Check that `groupPolicy` is set to `"allowlist"` or `"open"` (default is `"disabled"`)
109
+ - Check that `groupPolicy` is set to `"allowlist"`, `"pairing"`, or `"open"` (default is `"disabled"`)
109
110
  - If using `"allowlist"`, verify the group's chat ID is in the `groups` config
111
+ - If using `"pairing"`, verify the group's pairing request has been approved
110
112
  - Make sure **Group Privacy is turned off** in BotFather — without this, the bot can't see non-command messages in groups
111
113
  - If you changed privacy mode after adding the bot to a group, **remove and re-add the bot** to the group
112
114
  - By default, the bot requires an @mention or a reply. Send `@yourbotname hello` to test
@@ -79,7 +79,7 @@ Open WeCom and send a message to the intelligent robot.
79
79
  - `pairing`: users must pair before using the bot.
80
80
  - `open`: anyone who can message the robot can use it.
81
81
 
82
- For groups, set `groupPolicy` to `"allowlist"` or `"open"`. WeCom only delivers group messages that mention the intelligent robot, so every delivered group callback is treated as mentioned. The `requireMention` setting cannot enable responses to unmentioned group messages because those messages are not delivered to the bot.
82
+ For groups, set `groupPolicy` to `"allowlist"`, `"pairing"`, or `"open"`. Under `"pairing"`, the group's first mention creates a pairing request that must be approved once before responses start. Note that under `groupPolicy: "pairing"`, access is granted per group: once a group is approved, **any member of that group** can use the bot; `senderPolicy` and `allowedUsers` do not gate members of an approved group. WeCom only delivers group messages that mention the intelligent robot, so every delivered group callback is treated as mentioned. The `requireMention` setting cannot enable responses to unmentioned group messages because those messages are not delivered to the bot.
83
83
 
84
84
  ### Group Mention Compatibility
85
85
 
@@ -225,6 +225,10 @@ A finding is skipped when its fix would change intended behavior, would need cha
225
225
 
226
226
  Confirmed findings are canonicalized into `.qwen/tmp/qwen-review-<target>-findings.json` before anything else consumes them — the terminal report, the saved Markdown report, and the PR review JSON all read that one artifact instead of re-typing the list. Each finding carries a unique `id` (what outcomes and resolved anchors join on), `severity`, `confidence`, `source`, `summary`, a `shortSummary` capped at 60 characters for list rendering, `failureScenario`, and one or more `locations` — a pattern-aggregated finding keeps **one location per occurrence**, so each still gets its own inline comment.
227
227
 
228
+ **Before anything else, the review checks that it is running your code.** Every `qwen review …` step runs the built bundle, not the working tree, so a review command edited since the last build takes no effect and the run measures the old behaviour. The build records a digest of the review sources it bundled; `parse-args` re-derives it and compares, and `drive` checks again, because the verifier brief sends agents straight there without a step 1. On a mismatch it says on stderr that the bundle was not built from these sources, and what to rebuild. The check runs when the CLI resolves to the bundled `dist/cli.js` (the `qwen` binary, or `node dist/cli.js`); launchers that run unbundled output, such as `npm start` and `npm run dev`, skip it. Two cases it cannot compare are treated differently: a checkout whose build predates the recording is told the check could not run and why, and an installed package — which has no sources to differ from — is left silent. The digest covers the review commands, the file that registers them, the review-only lease they import from outside their directory, and the bundled review skill; it does not follow those into the shared helpers they import, so a quiet run means the review code matches the bundle rather than that the whole tree does.
229
+
230
+ **A Critical the base tree already failed is held back, not filed.** When a test command failed and the merge base could be built, `test-delta` records which failing files also fail without the pull request. Canonicalization reads that measurement back (`qwen review findings --test-delta`, beside `--outcomes`): a Critical whose own text names one of those files is lowered to a Suggestion, keeps its evidence, gains the measurement that demoted it and a `heldByMeasurement` field, and the demotion is announced. A test that was already red is not a test this pull request turns red — and if it now fails for a _new_ reason, say which test, quote both sides, and file it at Critical again: a finding that already carries the measurement and is raised anyway is left where you put it.
231
+
228
232
  The command validates on write: a duplicate id, a finding with no failure scenario, an empty locations array, or an unknown severity is an error rather than a silently mangled entry.
229
233
 
230
234
  ## Evidence Images in PR Comments
@@ -119,7 +119,7 @@ Commands for managing AI tools and models.
119
119
  | `/arena` | Manage Arena sessions | `/arena start`, `/arena stop`, `/arena status`, `/arena select` (alias `choose`) |
120
120
  | `/goal` | Set a goal — keep working until condition met | `/goal <condition>`, `/goal clear` |
121
121
  | `/tasks` | List background tasks | `/tasks` |
122
- | `/workflows` | Inspect workflow runs | `/workflows`, `/workflows <runId>` |
122
+ | `/workflows` | Inspect workflow runs; cooperatively pause/resume a background run | `/workflows`, `/workflows <runId>`, `/workflows p <runId>` |
123
123
  | `/lsp` | Show LSP server status | `/lsp` |
124
124
  | `/trust` | Manage folder trust settings | `/trust` |
125
125
 
@@ -522,6 +522,8 @@ The `permissionDecision` value controls whether the tool runs:
522
522
  - `"deny"` — block the tool; it does not execute and an error is returned to the model.
523
523
  - `"ask"` — pause and ask the user to confirm the tool call in the TUI before it runs. Confirming runs the tool once; declining cancels it. In contexts that cannot prompt for confirmation — headless (`--prompt`) runs and background subagents — `"ask"` falls back to `"deny"`.
524
524
 
525
+ For `"ask"`, the TUI displays `permissionDecisionReason` as literal text rather than interpreting inline Markdown. This keeps formatting markers and link targets visible to the user.
526
+
525
527
  **Note**: While standard hook output fields like `decision` and `reason` are technically supported by the underlying class, the official interface expects the `hookSpecificOutput` with `permissionDecision` and `permissionDecisionReason`.
526
528
 
527
529
  **Example Output**:
@@ -634,6 +636,56 @@ When both fields are present, prompt-hook payloads contain overlapping text and
634
636
 
635
637
  Sequential UserPromptSubmit hooks can append `additionalContext` to `prompt`; `submitted_prompt` continues to represent the captured submission. Function hooks are trusted same-process code and are not constrained by an immutability guarantee.
636
638
 
639
+ When the final hook output contains non-empty `additionalContext`, Qwen first
640
+ sanitizes the value and then sends it to the model as a separate text part:
641
+
642
+ ```xml
643
+ <qwen:user-prompt-submit-context>
644
+ sanitized hook context
645
+ </qwen:user-prompt-submit-context>
646
+ ```
647
+
648
+ The tag tells the model and transcript consumers that the part came from a
649
+ configured hook rather than from the user prompt. It is a provenance marker,
650
+ not authentication, authorization, or a general trust boundary.
651
+
652
+ For a `UserQuery` with this added context, the session JSONL record preserves
653
+ the model-bound parts, including the tagged part, and adds the following
654
+ `systemPayload`:
655
+
656
+ ```json
657
+ {
658
+ "displayText": "pre-hook display projection",
659
+ "hookContext": "sanitized hook context"
660
+ }
661
+ ```
662
+
663
+ This two-field payload is written only for this kind of user-prompt record.
664
+ `hookContext` intentionally duplicates the tagged part so offline and
665
+ third-party consumers can identify its provenance without parsing model text.
666
+ `displayText` is the pre-hook display projection and never includes the hook
667
+ context. For a supported interactive TUI submission it is the raw composer
668
+ projection carried by `submitted_prompt`; ACP, headless, `serve`, SDK, remote
669
+ input, and other paths without that provenance record the expanded pre-hook
670
+ prompt instead.
671
+
672
+ Transcript display consumers treat `displayText` as this user-prompt projection
673
+ when `systemPayload.hookContext` is a string. For compatibility with released
674
+ `displayText`-only user-prompt records, a complete tagged context in the final
675
+ part after at least one other part is equivalent pairing evidence. Notification,
676
+ cron, and mid-turn records can also have `displayText`, but those values are
677
+ compact display labels and must not be substituted for their model-bound text
678
+ without that evidence.
679
+ Legacy bare-context records keep their model-bound display behavior because the
680
+ context cannot be separated reliably. For metadata-free records that use the
681
+ current tagged shape, compatibility consumers may remove the same complete
682
+ final tagged part; they must not infer that arbitrary tag-like user text is hook
683
+ provenance.
684
+
685
+ Sensitive prompt telemetry attributes, when enabled, and managed auto-memory
686
+ recall both use the pre-hook prompt. They do not include
687
+ `UserPromptSubmit`-added context.
688
+
637
689
  **Output Options**:
638
690
 
639
691
  - `decision`: "allow", "deny", "block", or "ask"
@@ -8,6 +8,7 @@
8
8
  - **Agent Client Protocol**: Full support for ACP enabling advanced IDE interactions
9
9
  - **Symbol management**: #-mention files to add them to the conversation context
10
10
  - **Conversation history**: Access to past conversations within the IDE
11
+ - **Context usage**: See the current context-window occupancy while Qwen Code works
11
12
 
12
13
  ### Requirements
13
14
 
@@ -396,6 +396,8 @@ Notes:
396
396
  | `--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. |
397
397
  | `--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. |
398
398
  | `--memory-budget-mb <n>` | 50% of cgroup/host | Total memory budget in MB for the whole daemon process tree. When unset, derived as 50% of the cgroup limit or host memory; either way the effective value is capped at resolved available memory, and both the configured and effective figures are reported. Currently observation only — it does not change how any `qwen --acp` child is sized. Resolved figures appear under `limits.memory` in `GET /daemon/status`, alongside registered and live child counts and advisory per-child shares under `runtime.memory`. A host too small for the minimum reports `insufficientMemory` rather than being clamped upward; because the derived fraction is 50%, any host under ~2 GB trips this. Pass an explicit `--memory-budget-mb 1024` on such a host to override the derived figure (the flag still requires at least 1024 MB of available memory to clear the warning). Must be an integer in `[1024, 1048576]`. |
399
+ | `--memory-pressure-mode <mode>` | `observe` | Whether the daemon turns its own memory reading into a verdict. `observe` (default) reports the pressure level under `runtime.memory.pressure` in `GET /daemon/status` and raises a `daemon_memory_pressure` issue — a `warning`, so the overall `status` leaves `ok` — whenever the level leaves `normal`. `off` still reports every figure, including the level, but raises no issue, so the overall `status` is unchanged; use it while calibrating, or if you alert on the top-level status. The level is the worse of two ratios: RSS against available memory (what the cgroup OOM killer watches) and V8 heap used against this process's heap ceiling. It covers the daemon root process only; compare it against `runtime.memory.children.rssBytes` for the children. Nothing remediates in either mode. One of `off`, `observe`. |
400
+ | `--child-heap-mode <mode>` | `observe` | Whether the daemon models a per-child heap partition of `--memory-budget-mb`. `observe` (default) reports what it would apply — `limits.memory.childHeap.perChildCeilingMb` and `maxConcurrentChildren` — and counts spawns that would have exceeded the limit. **Nothing is applied**: no child is sized from the budget and no spawn is refused. `off` models nothing, and says so on the wire: `maxConcurrentChildren` and `perChildCeilingMb` are both `null` rather than carrying a partition you switched off. A refusal count of 0 does **not** mean the partition would be safe to apply: children still run on the much larger host-derived ceiling, so a workload needing more old space than the modeled ceiling looks perfectly healthy here. Applying the partition ships with the measurement that can answer that. |
399
401
  | `--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`. |
400
402
  | `--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` is separately capped by `--max-journal-events` and `--max-journal-bytes`. 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. |
401
403
  | `--max-journal-events <n>` | `10000` | Per-session cap on the number of raw events retained in the in-flight live journal (the current unfinished turn). When exceeded, the oldest journal entries are dropped and a `history_truncated` marker is prepended. Must be a positive safe integer. |
@@ -554,7 +556,8 @@ provider decision with their normal tool policy and isolation boundary.
554
556
  - **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.
555
557
  - **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.
556
558
  - **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.
557
- - **A spawned `qwen --acp` child receives its owning runtime's effective environment.** The daemon freezes a process-env base, applies that workspace's settings/env-file overlay to a runtime-local snapshot, and never writes the overlay back to `process.env`; same-named keys in another runtime do not cross over. `QWEN_SERVER_TOKEN` is scrubbed before spawn because the agent does not need the daemon bearer. Base credentials such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `QWEN_*`, and `DASHSCOPE_API_KEY` otherwise pass through unless the runtime overlay changes them. **This is intentional, not a sandbox.** The agent runs as the same UID with shell-tool access, so anything in `~/.bashrc`, `~/.aws/credentials`, or `~/.npmrc` is reachable by prompt injection regardless. Environment isolation between runtimes is not an operating-system security boundary; do not run `qwen serve` under an identity that has credentials you would not trust the agent with.
559
+ - **A spawned `qwen --acp` child receives its owning runtime's effective environment.** The daemon freezes a process-env base, applies that workspace's settings/env-file overlay to a runtime-local snapshot, and never writes the overlay back to `process.env`; same-named keys in another runtime do not cross over. `QWEN_SERVER_TOKEN` is scrubbed before spawn because the agent does not need the daemon bearer. Loader-affecting variables (`NODE_OPTIONS`, `npm_config_node_options` and npm's config-file redirects, `NODE_PATH`, `LD_PRELOAD`, `LD_AUDIT`, `DYLD_INSERT_LIBRARIES`, `BASH_ENV`, `ZDOTDIR`, exported bash function definitions `BASH_FUNC_*`) are likewise never passed to session subprocesses — the daemon scrubs them from its own `process.env` and from the frozen base env that session-hosting children spawn with (the base env keeps them only under the `DEV=true` harness, whose `.ts` entries still need the tsx loader), and `.env` / `settings.json` `env` sources reject them (see [settings](./configuration/settings.md)); this applies to every session the daemon hosts. Base credentials such as `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, `QWEN_*`, and `DASHSCOPE_API_KEY` otherwise pass through unless the runtime overlay changes them. **This is intentional, not a sandbox.** The agent runs as the same UID with shell-tool access, so anything in `~/.bashrc`, `~/.aws/credentials`, or `~/.npmrc` is reachable by prompt injection regardless. Environment isolation between runtimes is not an operating-system security boundary; do not run `qwen serve` under an identity that has credentials you would not trust the agent with.
560
+ - **Agent text reads are child-local and follow the regular CLI permission rules, not the workspace filesystem boundary.** Direct `read_file` can reach host text paths outside every registered workspace: external paths default to confirmation, and allow rules or approval modes may approve them automatically. Approved reads use the configurable CLI output limits rather than the workspace filesystem's returned-output, full-snapshot, and large-text scan caps. This applies to every shared text-read consumer, so the pre-reads performed by write, edit, notebook, sed, and artifact operations lose those caps together with the workspace filesystem's read audit, symlink rejection, and read-side TOCTOU protections — see [the design doc](../design/daemon-local-text-reads.md) for the exact list. Because a confirmation payload is built by reading the file, an out-of-workspace diff is fanned out to **every** attached SSE subscriber before anyone approves it — in the interactive CLI that content is seen only by the person at the terminal. Treat authenticated daemon clients as the same security principal. HTTP filesystem routes remain workspace-scoped and still refuse these paths, agent discovery-tool behavior is unchanged, and final ACP `writeTextFile` content writes continue through the workspace filesystem.
558
561
  - **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.
559
562
  - **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.
560
563
  - **Graceful shutdown** — SIGINT/SIGTERM drain the agent children before closing the listener (10s deadline per child).
@@ -18,42 +18,42 @@ This document lists the available keyboard shortcuts in Qwen Code.
18
18
 
19
19
  ## Input Prompt
20
20
 
21
- | Shortcut | Description |
22
- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
23
- | `!` | Toggle shell mode when the input is empty. |
24
- | `?` | Toggle keyboard shortcuts display when the input is empty. |
25
- | `/` | Open slash-command completion. |
26
- | `@` | Open completion for files, folders, and other context. |
27
- | `Space` (empty prompt) | Start voice dictation when it and a voice model are configured; hold or tap behavior follows `general.voice.mode`. |
28
- | `Ctrl+Enter` / `Cmd+Enter` / `Shift+Enter` / `Ctrl+J` | Insert a newline. |
29
- | `Down Arrow` | Row down, then snap to end, then history next. |
30
- | `Enter` | Submit the current prompt. While a response is running, steer the current turn. |
31
- | `Ctrl+Q` | Queue the current prompt or command for the next turn instead of steering; it runs after Qwen Code returns to idle. |
32
- | `Up Arrow` (at the top) / `Esc` | When queued messages are present, move them back into the input for editing. |
33
- | `Meta+D` / `Meta+Delete` / `Ctrl+Delete` | Delete the word to the right of the cursor. |
34
- | `Tab` | Autocomplete the current suggestion if one exists. |
35
- | `Up Arrow` | Row up, then snap to start, then history prev. |
36
- | `Ctrl+A` / `Home` | Move the cursor to the beginning of the line. |
37
- | `Ctrl+B` / `Left Arrow` | Move the cursor one character to the left. |
38
- | `Ctrl+C` | Clear the input prompt |
39
- | `Esc` (double press) | Clear the input prompt. |
40
- | `Ctrl+D` / `Delete` | Delete the character to the right of the cursor. |
41
- | `Ctrl+E` / `End` | Move the cursor to the end of the line. |
42
- | `Ctrl+F` / `Right Arrow` | Move the cursor one character to the right. |
43
- | `Ctrl+H` / `Backspace` | Delete the character to the left of the cursor. |
44
- | `Ctrl+K` | Delete from the cursor to the end of the line. |
45
- | `Ctrl+Left Arrow` / `Meta+Left Arrow` / `Meta+B` | Move the cursor one word to the left. |
46
- | `Ctrl+N` | Row down, then snap to end, then history next. |
47
- | `Ctrl+P` | Row up, then snap to start, then history prev. |
48
- | `Ctrl+R` | Reverse search through input/shell history. |
49
- | `Ctrl+Y` | Retry the last failed request. |
50
- | `Ctrl+Right Arrow` / `Meta+Right Arrow` / `Meta+F` | Move the cursor one word to the right. |
51
- | `Ctrl+U` | Delete from the cursor to the beginning of the line. |
52
- | `Ctrl+V` / `Option+V` (Windows: `Alt+V`) | Paste clipboard content. If the clipboard contains an image, it will be saved and a reference to it will be inserted in the prompt. |
53
- | `Ctrl+W` / `Meta+Backspace` / `Ctrl+Backspace` | Delete the word to the left of the cursor. |
54
- | `Ctrl+X` | Open the current input in an external editor. |
55
- | `Ctrl+Z` | Undo the last input edit. |
56
- | `Ctrl+Shift+Z` | Redo the last undone input edit. |
21
+ | Shortcut | Description |
22
+ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
+ | `!` | Toggle shell mode when the input is empty. |
24
+ | `?` | Toggle keyboard shortcuts display when the input is empty. |
25
+ | `/` | Open slash-command completion. |
26
+ | `@` | Open completion for files, folders, and other context. |
27
+ | `Space` (empty prompt) | Start voice dictation when it and a voice model are configured; hold or tap behavior follows `general.voice.mode`. |
28
+ | `Ctrl+Enter` / `Cmd+Enter` / `Shift+Enter` / `Ctrl+J` | Insert a newline. |
29
+ | `Down Arrow` | Row down, then snap to end, then history next. |
30
+ | `Enter` | Submit the current prompt. While a response is running, steer the current turn. |
31
+ | `Ctrl+Q` | Queue the current prompt or command for the next turn instead of steering; it runs after Qwen Code returns to idle. |
32
+ | `Up Arrow` (at the top) / `Esc` | When queued messages are present, move them back into the input for editing (`Up Arrow` at the top whenever the input is shown; `Esc` only when the agent is idle). While the agent is responding and the input is empty, `Esc` cancels the ongoing request instead (queued messages are then moved back into the input). |
33
+ | `Meta+D` / `Meta+Delete` / `Ctrl+Delete` | Delete the word to the right of the cursor. |
34
+ | `Tab` | Autocomplete the current suggestion if one exists. |
35
+ | `Up Arrow` | Row up, then snap to start, then history prev. |
36
+ | `Ctrl+A` / `Home` | Move the cursor to the beginning of the line. |
37
+ | `Ctrl+B` / `Left Arrow` | Move the cursor one character to the left. |
38
+ | `Ctrl+C` | Clear the input prompt |
39
+ | `Esc` (double press) | Clear the input prompt. |
40
+ | `Ctrl+D` / `Delete` | Delete the character to the right of the cursor. |
41
+ | `Ctrl+E` / `End` | Move the cursor to the end of the line. |
42
+ | `Ctrl+F` / `Right Arrow` | Move the cursor one character to the right. |
43
+ | `Ctrl+H` / `Backspace` | Delete the character to the left of the cursor. |
44
+ | `Ctrl+K` | Delete from the cursor to the end of the line. |
45
+ | `Ctrl+Left Arrow` / `Meta+Left Arrow` / `Meta+B` | Move the cursor one word to the left. |
46
+ | `Ctrl+N` | Row down, then snap to end, then history next. |
47
+ | `Ctrl+P` | Row up, then snap to start, then history prev. |
48
+ | `Ctrl+R` | Reverse search through input/shell history. |
49
+ | `Ctrl+Y` | Retry the last failed request. |
50
+ | `Ctrl+Right Arrow` / `Meta+Right Arrow` / `Meta+F` | Move the cursor one word to the right. |
51
+ | `Ctrl+U` | Delete from the cursor to the beginning of the line. |
52
+ | `Ctrl+V` / `Option+V` (Windows: `Alt+V`) | Paste clipboard content. If the clipboard contains an image, it will be saved and a reference to it will be inserted in the prompt. |
53
+ | `Ctrl+W` / `Meta+Backspace` / `Ctrl+Backspace` | Delete the word to the left of the cursor. |
54
+ | `Ctrl+X` | Open the current input in an external editor. |
55
+ | `Ctrl+Z` | Undo the last input edit. |
56
+ | `Ctrl+Shift+Z` | Redo the last undone input edit. |
57
57
 
58
58
  ## Foreground Shell
59
59
 
@@ -65,6 +65,20 @@ These shortcuts apply while an interactive foreground shell command is running.
65
65
  | `Ctrl+Shift+Up` / `Ctrl+Shift+Down` | Scroll the focused shell up or down. |
66
66
  | `Ctrl+B` | Promote the shell to a background task. The child keeps running, the agent's turn unblocks, and the shell appears in `/tasks` and the Background tasks dialog. |
67
67
 
68
+ ## Background tasks dialog
69
+
70
+ Focus the Background tasks pill in the footer (use `Down Arrow` from an empty composer — this moves through the live-agent panel and, if present, the Arena tab bar first) and press `Enter` to open the dialog. It lists background agents, shells, monitors, workflow runs, and memory dreams.
71
+
72
+ | Shortcut | Description |
73
+ | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
74
+ | `Up Arrow` / `Down Arrow` | Move the selection between tasks. |
75
+ | `Enter` | Open the detail view for the selected task. |
76
+ | `x` | Stop the selected task (abandon a paused agent). A foreground agent that blocks your turn needs a second `x` to confirm. |
77
+ | `r` | Resume the selected paused agent. |
78
+ | `p` | Cooperatively pause or resume the selected background workflow run. No new agents start while paused, but script code between agent calls keeps running. |
79
+ | `s` | Save the script of a finished (completed, failed, or cancelled) workflow run (detail view only). |
80
+ | `Left Arrow` / `Esc` | Return to the list from the detail view, or close the dialog. |
81
+
68
82
  ## Suggestions
69
83
 
70
84
  | Shortcut | Description |
@@ -53,6 +53,10 @@ Then run:
53
53
  # : | "${QWEN_CODE_CLI:-qwen}" review parse-args --stdin | tee .qwen/tmp/qwen-review-parse-args.json
54
54
  ```
55
55
 
56
+ **If any `qwen review …` command prints `review: the bundle these commands run from was NOT built from the review sources in this tree`, stop and tell the user before doing anything else.** Every step below runs the built bundle, so a review source changed since that build takes no effect and this run measures the old behaviour — silently. That is true of bundled launches; an `npm start` or `npm run dev` session runs the `tsc` output in `packages/cli/dist/` instead, which lags `src/` the same way but is a layout this check does not cover — there `npm run build:packages` is what refreshes what runs. Measured on 2026-08-02: a round against #8368 exercised commands that had merged that morning and were simply absent from the binary, and reproduced a bug whose fix had merged but was not in the build — it had to be discarded. The user reads your summary, not this stderr, so a line you do not repeat is a line nobody sees. Say what it said, and let them decide whether to rebuild or to read every result as being about the older build. (A related note, `review: could not check whether the bundle is current`, means the same risk is present and unmeasurable — pass it on the same way.)
57
+
58
+ You cannot fix this yourself: the skill you are reading comes from that same bundle, so any instruction here is already as old as the code it is warning about.
59
+
56
60
  (Step 9 removes these files with the other temp files.)
57
61
 
58
62
  **Keep the verdict file** — for _your_ reading, not as authorisation. It is how you know the target, the effort and whether `--comment` was effective. It is **not** what lets Step 7 post: `submit` deliberately ignores this JSON and re-parses the CLI's verbatim record of what the user typed, because this file is a document _you_ write, and a run that wanted to post could simply write `effective: true` into it. Step 9's cleanup sweeps it with the rest.
@@ -76,7 +80,15 @@ At every effort level, the mechanics of obtaining the diff — worktree flow, di
76
80
 
77
81
  The parser already classified the target, so there is nothing to disambiguate by hand. For a `pr-url` target, determine if the local repo can access this PR:
78
82
 
79
- 1. Check if any git remote matches the URL's **host and owner/repo — by exact segment equality, never substring**: run `git remote -v` and parse each remote URL structurally (`git@<host>:<owner>/<repo>.git` and `https://<host>/<owner>/<repo>(.git)` are the two shapes). A remote matches only when its host equals the verdict's `host` AND its `<owner>/<repo>` (with any `.git` suffix stripped) equals the verdict's `owner/repo`, both compared case-insensitively as whole segments — `shao/qwen-code` does NOT match a `wenshao/qwen-code` remote, and a `github.com` PR does not match a same-named repo on another host. Substring "contains" matching once allowed exactly those, which is reviewing one repository and posting to another. This still handles forks — a local clone with an `upstream` remote pointing to the target repository matches that repository's PRs exactly.
83
+ 1. Run the remote matcher it applies the exact host + owner/repo segment-equality rule in code, and you do not re-derive it (a substring comparison once matched `shao/qwen-code` against a `wenshao/qwen-code` remote — one review read one repository and posted to another; a `github.com` PR matching a same-named repo on another host is the same bug wearing a host):
84
+
85
+ ```bash
86
+ "${QWEN_CODE_CLI:-qwen}" review match-remote \
87
+ --owner <the verdict's owner> --repo <the verdict's repo> --host <the verdict's host>
88
+ ```
89
+
90
+ Exit 0 prints the matching remote's name — forks included: a clone whose `upstream` points to the target repository matches that repository's PRs exactly. Exit 6 means no remote matches — go to item 3. Exit 7 means several match; tell the user and stop rather than picking one. Any other exit is fail-closed like the other gates: report it and stop.
91
+
80
92
  2. If a matching remote is found, proceed with the **normal worktree flow** — use that remote name (instead of hardcoded `origin`) for `git fetch <remote> pull/<number>/head:qwen-review/pr-<number>`. In Step 7, use the owner/repo from the URL for posting comments.
81
93
 
82
94
  For a `pr-url` whose `host` is not `github.com` (GitHub Enterprise), **pass `--host <host>` to every review subcommand that talks to GitHub — `fetch-pr`, `pr-context`, `comment-status`, `presubmit`, and `compose-review`** — which routes all of their `gh` calls via GH_HOST in code; a forgotten host cannot silently retarget them at github.com. The `gh` commands you run directly are still yours to route: prefix Agent 0's `gh pr view`/`gh issue view`, Step 6's residual body fetch, and the Step 7 submission with `GH_HOST=<host> ` (e.g. `GH_HOST=github.example.com gh api ...`). `gh` defaults to `github.com`, so a dropped host makes a call read from and post to the wrong site's `owner/repo`.
@@ -110,12 +122,21 @@ Based on the parsed `target.type`:
110
122
  **Where `<owner>/<repo>` and `<remote>` come from — do not guess either.** For a `pr-url` target both are already decided: the URL carries the owner/repo, and the remote is the one matched against it above. For a bare **`pr-number`** there is no URL, and a PR number alone says nothing about which repository it belongs to. Derive it:
111
123
 
112
124
  ```bash
113
- gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"'
125
+ gh repo view --json owner,name,url \
126
+ --jq '"\(.owner.login)/\(.name) \(.url | sub("^[a-z]+://"; "") | split("/")[0])"'
114
127
  ```
115
128
 
116
- That is the same command Step 7 already uses to decide where to post, and it resolves through `gh`'s default-repo which in a fork clone is the **upstream**, where the PR actually lives. Then pick the remote **whose URL is that owner/repo**, by the same exact-segment parse of `git remote -v` described above. Do not default to `origin`: in the standard fork layout `origin` is the _fork_, which has no `pull/<n>/head` ref for an upstream PR, and `fetch-pr` fails. In an upstream-as-`origin` clone the same rule lands on `origin` anyway, so one procedure is correct for both.
129
+ That is the same `gh repo view` resolution Step 7 already uses to decide where to post it resolves through `gh`'s default-repo, which in a fork clone is the **upstream**, where the PR actually lives and the second token is the host `gh` resolved that repo at (the URL's authority; an explicit port survives, and the matcher strips it). Pass that host to the matcher: `gh` also resolves a host through its own auth config (`gh auth login --hostname …`, no GH_HOST exported), which the matcher cannot see, so omitting `--host` would compare such a GHE repo against the github.com default and stop at exit 6 even though every later `gh` call routes at the GHE host. Then resolve the remote with the same matcher Step 1's pr-url path uses same rule, same exit codes:
117
130
 
118
- Guessing the owner/repo here is not a recoverable mistake — a guessed repo has already stopped a review before it read a line of code (measured; DESIGN.md — The guessed fork repo). If `gh repo view` and the remote scan disagree, or no remote matches, say so and stop rather than picking one.
131
+ ```bash
132
+ "${QWEN_CODE_CLI:-qwen}" review match-remote \
133
+ --owner <owner from gh repo view> --repo <repo from gh repo view> \
134
+ --host <host from gh repo view>
135
+ ```
136
+
137
+ Do not default to `origin`: in the standard fork layout `origin` is the _fork_, which has no `pull/<n>/head` ref for an upstream PR, and `fetch-pr` fails. In an upstream-as-`origin` clone the matcher lands on `origin` anyway, so one procedure is correct for both.
138
+
139
+ Guessing the owner/repo here is not a recoverable mistake — a guessed repo has already stopped a review before it read a line of code (measured; DESIGN.md — The guessed fork repo). If `gh repo view` fails, or the matcher exits 6 (no remote matches) or 7 (several do), say so and stop rather than picking one.
119
140
 
120
141
  Read `.qwen/tmp/qwen-review-pr-<n>-fetch.json` for: `worktreePath`, `baseRefName`, `headRefName`, `fetchedSha` (use as the **HEAD commit SHA** for Step 7), `isCrossRepository`, `diffStat` (files / additions / deletions), `emptyDiff` (**stop here**: the branch tree is byte-identical to its merge base — the work already landed or was superseded; tell the user and recommend close-as-superseded instead of fanning out agents over zero hunks), `collapsedFromUpstream` (disclose in the summary: overlapping merged PRs have collapsed this one to a residual — the review scope is the recomputed diff, and body claims about the rest are description-of-history, which Agent 0 should read accordingly), and `prDescriptionHasHan` (the PR description contains Chinese — every posted inline comment must then be bilingual; see Step 7). If the command fails (auth, network, PR not found), inform the user and stop.
121
142
 
@@ -190,7 +211,7 @@ Read from it:
190
211
  - `diffLines`, `diffChars`, and `srcDiffLines` / `testDiffLines` / `docsDiffLines` / `generatedDiffLines`
191
212
  - `chunks[]` — contiguous, non-overlapping line ranges tiling the whole diff. Each entry has `id`, `startLine`, `endLine` (1-based, inclusive), `lines`, `chars`, an `oversized` flag, and `files[]` naming the source files and new-side line ranges it covers. A chunk with `oversized: true` may exceed what one `read_file` call returns.
192
213
  - `files[]` — per-file `kind` (`source` / `test` / `generated`), `hunks[]` new-side ranges (Step 7 validates comment anchors against these), `addedRanges[]` and `diffRange` (present only on `heavy` files — the exact lines the PR wrote, and where that file's own diff lives, so an invariant agent can see what was deleted), change counts, and the `heavy` flag
193
- - `budget` — how much walking the **size-elastic** parts of this run owe, derived from `srcDiffLines` the same way the topology gate is, and recorded here rather than passed as a flag so every reader sees one number. `inlineAngles` and `sweep` scope Step 3C's low pass; `specialistCap` is the Agent 8 ceiling (**0** below 80 source lines — "one domain dominates the diff" is a judgement, and a judgement made about forty lines finds a dominant domain every time, because forty lines are usually all one thing); `verifyShard` is Step 4's findings-per-verifier. **It never scales a dimension away** — which agents a review owes is the roster's answer and the roster reads `effort`, so a size input cannot become a back door into shrinking coverage. Nothing here is yours to override: a budget the caller can inflate is a budget that gets inflated. **A plan with no `budget` field** (written by an older CLI — the version-skew this skill has already measured once) falls back to the pre-budget flat behaviour, which errs toward more coverage, never less: walk all six angles, run the sweep, cap Agent 8 at 2, shard verification at 8.
214
+ - `budget` — how much walking the **size-elastic** parts of this run owe, derived from `srcDiffLines` the same way the topology gate is, and recorded here rather than passed as a flag so every reader sees one number. `inlineAngles` and `sweep` scope Step 3C's low pass; `specialistCap` is the Agent 8 ceiling (**0** below 80 source lines — "one domain dominates the diff" is a judgement, and a judgement made about forty lines finds a dominant domain every time, because forty lines are usually all one thing); `verifyShard` is Step 4's findings-per-verifier; `agentToolBudget` is the base rate of the soft tool-call ceiling `agent-prompt` bakes into every finder and auditor brief — not the verifier's, not Agent 7's, and not Agent 0's, whose mandatory work scales with the linked issues rather than the diff. The ceiling is per **launch**: a scoped agent (a chunk, a heavy file) gets an allowance derived from its own territory — never above the plan's recorded allowance, which is clamped into the budget's own band in both directions, so the plan stays the one number every launch answers to — and every launch's assigned reads ride on top of the allowance rather than inside it, so a huge diff's mandatory chunk reads can never exhaust the exploration a whole-diff role owes — because a wave's wall clock is its slowest agent and the slowest agent is reliably one that kept exploring past any recall gain: the same 14-agent fan-out has measured 11.7 and 41 minutes on comparable diffs, the difference being individual agents spending 40-100 calls walking the tree (measured; DESIGN.md — The forty-one minute wave). The ceiling is soft and the briefs restate the recall rule beside it: at the budget an agent stops **exploring**, never reporting — findings in hand are filed, and each stopped check is disclosed on its own line in the fixed form `Budget gap: <the check>`, which `check-coverage` parses out of the transcripts (its report's `budgetGaps`) — see Step 3D for the ruling each gap is owed. **It never scales a dimension away** — which agents a review owes is the roster's answer and the roster reads `effort`, so a size input cannot become a back door into shrinking coverage. Nothing here is yours to override: a budget the caller can inflate is a budget that gets inflated. **A plan with no `budget` field** (written by an older CLI — the version-skew this skill has already measured once) falls back to the pre-budget flat behaviour, which errs toward more coverage, never less: walk all six angles, run the sweep, cap Agent 8 at 2, shard verification at 8.
194
215
 
195
216
  A chunk is read with `read_file(file_path=diffPathAbsolute, offset=startLine - 1, limit=endLine - startLine + 1)` — `offset` is 0-based.
196
217
 
@@ -409,6 +430,8 @@ It reads the harness's own per-agent transcripts: a record you do not author, ar
409
430
 
410
431
  Why this is a command and not a paragraph: **the review approved a pull request that no agent read.** Every prose defence against exactly this failure went unperformed in a real dogfood (measured; DESIGN.md — The Approve over an unread diff).
411
432
 
433
+ **The coverage report also carries `budgetGaps`** — the `Budget gap: <the check>` lines agents disclosed when the soft tool-call ceiling stopped a check (the format is fixed so this detection is a parse, not a memory; it never fails the gate, because failing on disclosure teaches agents not to disclose). Detection is the CLI's; the ruling is yours, exactly as with whiffs: a gap that names an incomplete **required** trace — the callers of a changed export, a security path, the re-establishment of removed behaviour — joins `unreviewedDimensions`, which forbids an Approve; a gap naming only optional depth is carried into the report's "Not reviewed" section — `compose-review` renders every parsed gap there mechanically, so the disclosure reaches the author even if you relay nothing; your ruling adds only the capping entries. A budget gap is the ceiling working, not an agent failing — never relaunch an agent over one. A disclosure costs no coverage credit and never fails the gate — an arithmetic that only ever bites the discloser teaches agents not to disclose. One consequence is the CLI's, not yours: the reverse-audit retirement judges a receipt with its `Budget gap:` lines stripped, so the disclosure can neither serve as the receipt's substance (a return whose only substance is its gaps does not retire its chunk) nor block a receipt that is substantive without it (a proven territory walk that found nothing new still retires — the gap is ruled on, not re-audited). When your ruling promotes a gap into `unreviewedDimensions`, write it self-explained, with the gap's own text as the scope — `<the gap's text> — stopped at the agent tool budget` — the em-dash reason renders verbatim instead of under the whiffed-agent explanation, and `compose-review` drops its own mechanical line for any gap your entry echoes, so the body never says it twice.
434
+
412
435
  The roll-call below is still worth writing for your own reading — but it is not what stops this any more:
413
436
 
414
437
  ```
@@ -14,21 +14,21 @@ import "./chunk-4NFY2S7N.js";
14
14
  import "./chunk-2MIN6GRR.js";
15
15
  import "./chunk-QHTIBUWB.js";
16
16
  import "./chunk-RKUWKYED.js";
17
- import "./chunk-Y7E5LNLO.js";
17
+ import "./chunk-GXSNGY5M.js";
18
18
  import "./chunk-GOFAQQZA.js";
19
19
  import "./chunk-5M6IDOMF.js";
20
20
  import "./chunk-TWPJO254.js";
21
21
  import "./chunk-H6XPXXMH.js";
22
- import "./chunk-CNIID3TV.js";
22
+ import "./chunk-2UUMVNYT.js";
23
23
  import "./chunk-MVUQRLOH.js";
24
24
  import "./chunk-XCWO3SMQ.js";
25
25
  import "./chunk-7MH4J33A.js";
26
26
  import "./chunk-6PVPNMXU.js";
27
- import "./chunk-RMH5OWLD.js";
27
+ import "./chunk-VXZ5HAOV.js";
28
28
  import "./chunk-IRH27ZC2.js";
29
29
  import "./chunk-QHWCP53L.js";
30
30
  import "./chunk-GNPNYXJB.js";
31
- import "./chunk-Y4NGLFGJ.js";
31
+ import "./chunk-HUWENAHO.js";
32
32
  import "./chunk-O6GEWCJA.js";
33
33
  import "./chunk-T26EAKDL.js";
34
34
  import "./chunk-ZPJWUGCS.js";
@@ -37,37 +37,41 @@ import "./chunk-J6SZID63.js";
37
37
  import "./chunk-KRXPRVGL.js";
38
38
  import "./chunk-GM463R2B.js";
39
39
  import "./chunk-SEZ556DZ.js";
40
- import "./chunk-CJXIIILK.js";
41
- import "./chunk-3K7FH2KQ.js";
42
- import "./chunk-BVWVWGLE.js";
40
+ import "./chunk-2FRY5CRX.js";
41
+ import "./chunk-67N6HB5H.js";
42
+ import "./chunk-WAUGQKUU.js";
43
+ import "./chunk-PLFATELK.js";
44
+ import "./chunk-L4N6TIP7.js";
45
+ import "./chunk-SAH4BD2J.js";
46
+ import "./chunk-CPG6P4GG.js";
43
47
  import "./chunk-S6LOFUVP.js";
44
- import "./chunk-LZC3B5N2.js";
48
+ import "./chunk-2J3OJGTL.js";
49
+ import "./chunk-IA7TGCN2.js";
45
50
  import "./chunk-K623ENWT.js";
46
51
  import "./chunk-AQ37AY7B.js";
47
52
  import "./chunk-EQL65XGA.js";
48
- import "./chunk-IIJEYBNH.js";
49
- import "./chunk-22NBYCPD.js";
53
+ import "./chunk-3P2LV43B.js";
50
54
  import "./chunk-NAVJD2PQ.js";
51
- import "./chunk-3ULCB3NE.js";
52
- import "./chunk-BGG4MBYD.js";
55
+ import "./chunk-HV76SFIA.js";
56
+ import "./chunk-4PYCZH2V.js";
57
+ import "./chunk-P3QQPMQA.js";
58
+ import "./chunk-SR7RZ4MS.js";
59
+ import "./chunk-M6HMMKVG.js";
53
60
  import "./chunk-DGEIYUC3.js";
54
61
  import "./chunk-MPHPFVKK.js";
55
62
  import "./chunk-AXMWHKXA.js";
56
- import "./chunk-DJ2GSRLV.js";
57
- import "./chunk-33ACCIIY.js";
58
- import "./chunk-L4N6TIP7.js";
59
- import "./chunk-2J3OJGTL.js";
60
- import "./chunk-P3QQPMQA.js";
61
- import "./chunk-M6HMMKVG.js";
62
63
  import "./chunk-GLCZKT5V.js";
64
+ import "./chunk-DJ2GSRLV.js";
63
65
  import "./chunk-EI3HZX6C.js";
64
- import "./chunk-2U3WZGZG.js";
66
+ import "./chunk-3PY4LPJF.js";
65
67
  import "./chunk-WOJZWRAZ.js";
66
68
  import "./chunk-VGC4I5JJ.js";
67
69
  import "./chunk-FVKHVJZQ.js";
68
- import "./chunk-NG2R4N5O.js";
69
- import "./chunk-IC4Z6LX6.js";
70
- import "./chunk-6EOI4HOK.js";
70
+ import "./chunk-COBO5EBO.js";
71
+ import "./chunk-6ZRFAKXK.js";
72
+ import "./chunk-PYQADEFD.js";
73
+ import "./chunk-M3STHEMM.js";
74
+ import "./chunk-F6WFNA7U.js";
71
75
  import "./chunk-46UV252V.js";
72
76
  import "./chunk-ZBVS26BY.js";
73
77
  import "./chunk-KKBPOU75.js";