@qwen-code/qwen-code 0.21.2 → 0.21.3

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 (351) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +41 -38
  2. package/bundled/qc-helper/docs/features/channels/github.md +7 -0
  3. package/bundled/qc-helper/docs/features/channels/gitlab.md +6 -0
  4. package/bundled/qc-helper/docs/features/code-review.md +78 -23
  5. package/bundled/qc-helper/docs/features/commands.md +2 -0
  6. package/bundled/qc-helper/docs/features/hooks.md +115 -18
  7. package/bundled/qc-helper/docs/features/memory.md +27 -0
  8. package/bundled/qc-helper/docs/features/skills.md +46 -1
  9. package/bundled/qc-helper/docs/features/sub-agents.md +42 -9
  10. package/bundled/qc-helper/docs/features/tool-use-summaries.md +7 -7
  11. package/bundled/qc-helper/docs/qwen-serve.md +21 -1
  12. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +13 -13
  13. package/bundled/qc-helper/docs/support/troubleshooting.md +6 -1
  14. package/bundled/review/DESIGN.md +167 -32
  15. package/bundled/review/SKILL.md +156 -32
  16. package/chunks/{MaxSizedBox-TQBQ247P.js → MaxSizedBox-OJR636GP.js} +40 -38
  17. package/chunks/{StandaloneSessionPicker-2HPTKCLX.js → StandaloneSessionPicker-AMMBF5UY.js} +62 -59
  18. package/chunks/{acp-startup-profiler-2C4A5ZTJ.js → acp-startup-profiler-3RICG2YW.js} +2 -2
  19. package/chunks/{acpAgent-PS6EDGH3.js → acpAgent-M57LVIQA.js} +662 -560
  20. package/chunks/{agent-VDOUB35F.js → agent-PE37ARLM.js} +36 -34
  21. package/chunks/{agent-headless-EO53EFS2.js → agent-headless-45ASME4R.js} +36 -34
  22. package/chunks/{anthropicContentGenerator-OFHSZJBF.js → anthropicContentGenerator-WCBYB6JG.js} +337 -27
  23. package/chunks/{artifact-tool-RDN2W7ND.js → artifact-tool-TBOYEKTY.js} +2 -2
  24. package/chunks/{askUserQuestion-OZERWH5R.js → askUserQuestion-23Y5WZFJ.js} +2 -2
  25. package/chunks/{bridge-W7AZSRZQ.js → bridge-K3ZRPO4D.js} +42 -40
  26. package/chunks/{ca-6W3SK7OQ.js → ca-4OJN75WT.js} +46 -5
  27. package/chunks/{channel-management-service-5S7YCWX5.js → channel-management-service-IXJ2MZTS.js} +7 -7
  28. package/chunks/{channel-settings-store-JFVRSNER.js → channel-settings-store-PEAR3IME.js} +43 -41
  29. package/chunks/{channel-worker-group-OVWGYMZS.js → channel-worker-group-NDG4WOOZ.js} +8 -8
  30. package/chunks/{channel-worker-manager-H55GKOQA.js → channel-worker-manager-ZCW6UW34.js} +8 -8
  31. package/chunks/{channel-worker-supervisor-CABBXYHK.js → channel-worker-supervisor-ATGFTZRN.js} +4 -4
  32. package/chunks/{chunk-W3UKBMSI.js → chunk-22YFMJBW.js} +84 -8
  33. package/chunks/{chunk-6MPDY6ZG.js → chunk-24ER7UV4.js} +1 -1
  34. package/chunks/{chunk-QDK4F2N5.js → chunk-2DNKEBXY.js} +1 -1
  35. package/chunks/{chunk-D6MDRSZ6.js → chunk-2LZCLQIS.js} +22 -11
  36. package/chunks/{chunk-JYBU6YUE.js → chunk-2M5N3DHY.js} +1 -1
  37. package/chunks/{chunk-KR32NIAN.js → chunk-2MI7ZTRT.js} +10 -10
  38. package/chunks/{chunk-LHKCY7DY.js → chunk-2UISUFHQ.js} +3 -3
  39. package/chunks/{chunk-JXVC2PL3.js → chunk-33FNCQSY.js} +2 -2
  40. package/chunks/{chunk-NBD76HUW.js → chunk-3LGZEYOF.js} +2 -2
  41. package/chunks/{chunk-CO2U743O.js → chunk-3MWNROHB.js} +4 -4
  42. package/chunks/{chunk-E2BHWIDT.js → chunk-3RXUYQJI.js} +6 -2
  43. package/chunks/{chunk-E5Z2AVNV.js → chunk-3SH53ANB.js} +0 -11
  44. package/chunks/{chunk-LYI2PZDK.js → chunk-3XF4WT3B.js} +2 -2
  45. package/chunks/{chunk-N4ACHWNH.js → chunk-432XCUHF.js} +1 -1
  46. package/chunks/{chunk-FNDXMN7I.js → chunk-4AGGSHCH.js} +774 -205
  47. package/chunks/{chunk-DUNI4EBW.js → chunk-4K3RV3OA.js} +80 -50
  48. package/chunks/{chunk-L2E5GFAG.js → chunk-4LKVQFHM.js} +2 -2
  49. package/chunks/{chunk-YDLJGZHL.js → chunk-4NFY2S7N.js} +0 -33
  50. package/chunks/{chunk-JLZ3RBQG.js → chunk-5JPVOYWA.js} +144 -11
  51. package/chunks/{chunk-6TAASXWL.js → chunk-5VYFXHY2.js} +3 -3
  52. package/chunks/{chunk-EU5TBFJI.js → chunk-6NE5NTHJ.js} +2 -2
  53. package/chunks/{chunk-XQK4XXTN.js → chunk-6O5DVH27.js} +1 -1
  54. package/chunks/{chunk-2RFKHEXL.js → chunk-6PLDPT2C.js} +1 -1
  55. package/chunks/{chunk-3APUUXRF.js → chunk-A5YZ3FA2.js} +2 -1
  56. package/chunks/{chunk-SHN4KHDK.js → chunk-A6SX5TAH.js} +3 -3
  57. package/chunks/{chunk-SZ3KHTDR.js → chunk-AKA24BGO.js} +1 -1
  58. package/chunks/{chunk-Q3T5KA2V.js → chunk-BFHXDAR7.js} +1 -1
  59. package/chunks/{chunk-L55JWS76.js → chunk-BGXZBI5B.js} +1 -1
  60. package/chunks/{chunk-P5VC5USY.js → chunk-BKGA75MU.js} +1 -1
  61. package/chunks/{chunk-2KKCCLPT.js → chunk-BKXTHMOZ.js} +1 -1
  62. package/chunks/{chunk-V4XNUDPE.js → chunk-BSKUTHLO.js} +15 -7
  63. package/chunks/{chunk-MM7TH7ZM.js → chunk-CFDR3GNL.js} +18 -3
  64. package/chunks/{chunk-E2FN6SM7.js → chunk-CIUUYB23.js} +5 -5
  65. package/chunks/{chunk-A7Y5H4TX.js → chunk-D2GPKXCQ.js} +7 -7
  66. package/chunks/{chunk-JCJ7LKNA.js → chunk-DIEFUBV6.js} +1644 -1570
  67. package/chunks/{chunk-GL4JOZXU.js → chunk-DSGJLHM3.js} +4 -4
  68. package/chunks/{chunk-675H6PLP.js → chunk-DYA25Y7U.js} +1 -1
  69. package/chunks/{chunk-3I6DUGQD.js → chunk-E4WHKETF.js} +32 -4
  70. package/chunks/{chunk-CU47KXB5.js → chunk-EGYJRIDF.js} +6 -6
  71. package/chunks/{chunk-6CQWRWUC.js → chunk-EIMKVOSF.js} +3 -3
  72. package/chunks/{chunk-QTERJVPZ.js → chunk-EKTCKZV5.js} +1 -0
  73. package/chunks/{chunk-NHFEMWAZ.js → chunk-FF75UUB2.js} +1 -1
  74. package/chunks/{chunk-L32VV3ZJ.js → chunk-FG63DZQA.js} +12 -12
  75. package/chunks/{chunk-FCYYAB4S.js → chunk-FHPKHXHT.js} +3 -3
  76. package/chunks/{chunk-GJ2GBPBD.js → chunk-FXVHVCNA.js} +5 -5
  77. package/chunks/{chunk-56Z7QEAQ.js → chunk-GMSBXEH4.js} +16 -16
  78. package/chunks/chunk-GOFAQQZA.js +132 -0
  79. package/chunks/{chunk-YUFIEIWC.js → chunk-GTM6IHBB.js} +2 -2
  80. package/chunks/{chunk-HIVKI6O6.js → chunk-H35Q5CEG.js} +9 -7
  81. package/chunks/{chunk-FJ5WUMUQ.js → chunk-H36SETQS.js} +1 -1
  82. package/chunks/{chunk-AUOULH6Q.js → chunk-H6FIBBXK.js} +1610 -2196
  83. package/chunks/{chunk-VEMNQMHA.js → chunk-H6ZYP74A.js} +5 -13
  84. package/chunks/{chunk-TTJZAIFP.js → chunk-HEBW74ZW.js} +3 -3
  85. package/chunks/{chunk-6FMJLI5M.js → chunk-HFVW54NL.js} +41 -6
  86. package/chunks/{chunk-44F4LBWZ.js → chunk-HIXVWF7I.js} +56 -18
  87. package/chunks/{chunk-EQNUDTL6.js → chunk-HUIQ4FYC.js} +2 -2
  88. package/chunks/{chunk-5NNHICSA.js → chunk-I7JDGNG6.js} +3 -3
  89. package/chunks/{chunk-PVNQRENX.js → chunk-IF6K42YJ.js} +1 -1
  90. package/chunks/{chunk-PJOHNFIY.js → chunk-IWGTGH4G.js} +5 -5
  91. package/chunks/{chunk-B4AJNNOL.js → chunk-J26HHFI5.js} +1 -1
  92. package/chunks/{chunk-CNTR4GR6.js → chunk-JELIWHXD.js} +1 -1
  93. package/chunks/{chunk-V25K5ID7.js → chunk-K2J5JZ6B.js} +1 -1
  94. package/chunks/{chunk-IGTHU3T4.js → chunk-KKN2IE7Q.js} +1 -1
  95. package/chunks/{chunk-TZTAV5RH.js → chunk-KVUBYJDM.js} +2 -2
  96. package/chunks/{chunk-3F2WDAV6.js → chunk-KXWERR6P.js} +14 -14
  97. package/chunks/{chunk-JJPKFJBT.js → chunk-L7FTDKCD.js} +3 -3
  98. package/chunks/chunk-LBOVL47Y.js +29 -0
  99. package/chunks/{chunk-FS674JW4.js → chunk-LBWNSLJK.js} +3 -3
  100. package/chunks/{chunk-I5BT7ADR.js → chunk-LGT3YMLN.js} +4 -4
  101. package/chunks/{chunk-UV6KF7T3.js → chunk-LZV2BZPL.js} +3 -3
  102. package/chunks/{chunk-P755N4CS.js → chunk-M5LIY7Y6.js} +6 -6
  103. package/chunks/{chunk-YGE3IXJP.js → chunk-M744OFVE.js} +1 -1
  104. package/chunks/{chunk-NTDH4IML.js → chunk-MCXMWLFT.js} +7 -7
  105. package/chunks/chunk-MISUEWB4.js +8749 -0
  106. package/chunks/{chunk-TEGJSJDF.js → chunk-MOHAWIAW.js} +2 -2
  107. package/chunks/{chunk-KXDONCPU.js → chunk-MTR4JWQJ.js} +4 -4
  108. package/chunks/{chunk-RSVPYAGK.js → chunk-MUEJ4R3E.js} +5 -5
  109. package/chunks/{chunk-PCK4B6LR.js → chunk-N42C2FU3.js} +1 -1
  110. package/chunks/{chunk-WWCMSZII.js → chunk-NW57GHNL.js} +71 -7
  111. package/chunks/{chunk-PQNHRFJC.js → chunk-NYX53SV4.js} +0 -2
  112. package/chunks/{chunk-QARJNL2V.js → chunk-O2ZYHG33.js} +5 -4
  113. package/chunks/{chunk-V7RNNPGC.js → chunk-P5Y23G2L.js} +18 -1
  114. package/chunks/{chunk-GURGAJTX.js → chunk-PDDYAXL2.js} +4 -1
  115. package/chunks/chunk-PWCQRLM5.js +1170 -0
  116. package/chunks/{chunk-VMX5RZQH.js → chunk-Q3G5L5KF.js} +18 -9
  117. package/chunks/{chunk-DQ2O5QOJ.js → chunk-QDWLUXKP.js} +1 -1
  118. package/chunks/chunk-QL4TN4HS.js +59 -0
  119. package/chunks/{chunk-E6CJ2SMM.js → chunk-QMBEW7EW.js} +2 -2
  120. package/chunks/{chunk-U4VTUMMK.js → chunk-QONSRAEV.js} +1 -1
  121. package/chunks/{chunk-DEEABGH2.js → chunk-QPSYIV2O.js} +3320 -536
  122. package/chunks/{chunk-Q5WZTTWE.js → chunk-QWDVZH24.js} +6 -8
  123. package/chunks/{chunk-2LEOZTBT.js → chunk-QWW6I2UO.js} +111 -26
  124. package/chunks/{chunk-LOY7RWQG.js → chunk-QYPT3QUD.js} +3 -3
  125. package/chunks/{chunk-6PQPKTXP.js → chunk-R7XNRHYD.js} +1 -1
  126. package/chunks/{chunk-7SJN2IWT.js → chunk-RCXCGZG6.js} +5 -5
  127. package/chunks/{chunk-HX6RLYUO.js → chunk-RL6J3BPE.js} +4 -4
  128. package/chunks/{chunk-Z3S5EMOW.js → chunk-RPYYTL7E.js} +60 -12
  129. package/chunks/{chunk-MB32MS4U.js → chunk-RR224BUP.js} +215 -174
  130. package/chunks/{chunk-H6I4PGRV.js → chunk-SKSF3LGQ.js} +4 -4
  131. package/chunks/{chunk-77V3VIKL.js → chunk-SQ3YD5MI.js} +9 -9
  132. package/chunks/{chunk-CBBP4BMC.js → chunk-SRY26X4H.js} +72 -206
  133. package/chunks/{chunk-RDJOB6S3.js → chunk-TXABHVZD.js} +1 -1
  134. package/chunks/{chunk-R2XWGR75.js → chunk-TYERNYH4.js} +2 -2
  135. package/chunks/chunk-TZTBZ25J.js +222 -0
  136. package/chunks/{chunk-45IOTAUS.js → chunk-U25CMJYY.js} +1 -1
  137. package/chunks/{chunk-7ULQIS27.js → chunk-UEJESCS7.js} +1 -1
  138. package/chunks/{chunk-HC45LTEN.js → chunk-UH7Z7Y45.js} +1 -1
  139. package/chunks/{chunk-CPZAH673.js → chunk-UKZEXS6K.js} +2 -0
  140. package/chunks/{chunk-54YCNSK5.js → chunk-UQDFEU47.js} +4113 -10152
  141. package/chunks/{chunk-XP4L6KS3.js → chunk-URN76TKR.js} +2 -2
  142. package/chunks/{chunk-XUGZYLDH.js → chunk-UWSXFI6E.js} +1 -1
  143. package/chunks/{chunk-AOHY3QJ3.js → chunk-VA5NLVPT.js} +3 -3
  144. package/chunks/{chunk-PZEXDV3H.js → chunk-VUNRNRN6.js} +71 -43
  145. package/chunks/{chunk-FANRZEAJ.js → chunk-VWOVHOTT.js} +1 -1
  146. package/chunks/{chunk-QTHQ6Z5X.js → chunk-WK4TJUEA.js} +1 -1
  147. package/chunks/{chunk-ZPZ7ZJEE.js → chunk-WUC6ZFXO.js} +1 -1
  148. package/chunks/{chunk-7KAXXBER.js → chunk-WY2ENRDN.js} +3 -3
  149. package/chunks/{chunk-TIRRPCFS.js → chunk-X6QNZOTC.js} +1 -1
  150. package/chunks/{chunk-KWHKHSIS.js → chunk-X6WUYMOV.js} +8 -8
  151. package/chunks/{chunk-IIUGIWWY.js → chunk-XC2VAFVZ.js} +1 -1
  152. package/chunks/{chunk-D4HTUMGX.js → chunk-XC656O42.js} +3 -3
  153. package/chunks/{chunk-RG64CDT2.js → chunk-XMJO6C44.js} +131 -48
  154. package/chunks/{chunk-ZMOJ7ISP.js → chunk-XUMAD5IT.js} +1 -1
  155. package/chunks/{chunk-THVU3RNH.js → chunk-YAVY33G4.js} +1 -1
  156. package/chunks/{chunk-YANIWTRZ.js → chunk-YPUHMQXV.js} +1 -1
  157. package/chunks/{chunk-QCXGC7QB.js → chunk-YU6TBRTA.js} +3 -3
  158. package/chunks/{chunk-OFZKFPYG.js → chunk-YWMDTMAU.js} +3 -3
  159. package/chunks/{chunk-DSFHVTWD.js → chunk-YXEVDA66.js} +2 -2
  160. package/chunks/{chunk-JE2CEOBO.js → chunk-ZGSUFIL5.js} +4 -4
  161. package/chunks/{chunk-BBIQAX4V.js → chunk-ZJES4C3I.js} +30 -18
  162. package/chunks/{computer-use-5QWCFNKD.js → computer-use-UJMK6JQU.js} +36 -34
  163. package/chunks/{config-utils-WADIDWGG.js → config-utils-7COTJMWK.js} +4 -4
  164. package/chunks/{contextCommand-4Z7T7TUM.js → contextCommand-4YABGF4S.js} +40 -38
  165. package/chunks/{core-runtime-6N4EFC2Q.js → core-runtime-7M4VM3DA.js} +36 -34
  166. package/chunks/{create-sub-session-AEREHZBQ.js → create-sub-session-HOFDW4N7.js} +39 -37
  167. package/chunks/{create-sub-session-62YZWVAY.js → create-sub-session-J32WC64U.js} +2 -2
  168. package/chunks/{cron-create-6E7GIQTG.js → cron-create-HMFSHIAR.js} +4 -4
  169. package/chunks/{cron-delete-JD26XY3W.js → cron-delete-ZJFHOX57.js} +4 -4
  170. package/chunks/{cron-list-CUWFB44G.js → cron-list-ZEX2NBMN.js} +4 -4
  171. package/chunks/{daemon-PCNCI5YU.js → daemon-CCIX4BMG.js} +47 -6
  172. package/chunks/{daemon-status-provider-DDF7C5M7.js → daemon-status-provider-W2U5Q3J5.js} +47 -45
  173. package/chunks/{daemon-trust-policy-Q4KSOJTR.js → daemon-trust-policy-IFICWPXP.js} +42 -40
  174. package/chunks/{daemon-trust-policy-monitor-V6FTE3IY.js → daemon-trust-policy-monitor-GX7EO6FW.js} +42 -40
  175. package/chunks/{de-SY6O76BF.js → de-A6TI4LBB.js} +46 -5
  176. package/chunks/{deferred-core-runtime-GHJ5GQHK.js → deferred-core-runtime-U36OOOKE.js} +36 -34
  177. package/chunks/display-image-VS3TXYQH.js +184 -0
  178. package/chunks/{dist-ZHXOBXDN.js → dist-3BMEUGTG.js} +1 -1
  179. package/chunks/{dist-26BIMQT6.js → dist-4KAX7CCL.js} +289 -27
  180. package/chunks/{dist-OAOC5OV4.js → dist-7JGAAQSC.js} +2 -2
  181. package/chunks/{dist-SL2LUMML.js → dist-A7H2KKUC.js} +1 -1
  182. package/chunks/{dist-2PERFI23.js → dist-DPPHJAVL.js} +3 -3
  183. package/chunks/{dist-PVEAFLHY.js → dist-HVBMEYWK.js} +1 -1
  184. package/chunks/{dist-ULIG4M5H.js → dist-NEBRI7WO.js} +67 -15
  185. package/chunks/{dist-WGMNT3JQ.js → dist-SFQ34F4M.js} +24 -6
  186. package/chunks/{earlyInputCapture-TQXLLISD.js → earlyInputCapture-5ZWDH3SB.js} +37 -35
  187. package/chunks/{edit-FJEUV6KZ.js → edit-J7SW6UP6.js} +36 -34
  188. package/chunks/{en-NBK3JKCE.js → en-L4UQDLWW.js} +57 -6
  189. package/chunks/{enter-worktree-7GE3TZ4P.js → enter-worktree-NRLOHRB6.js} +36 -34
  190. package/chunks/{enterPlanMode-KR5TMPCJ.js → enterPlanMode-GDSTEFSM.js} +36 -34
  191. package/chunks/{environment-SWL3CMB3.js → environment-KHYEKG5W.js} +39 -37
  192. package/chunks/{errors-XQE7BGZV.js → errors-VNLAJV3O.js} +39 -37
  193. package/chunks/{exit-worktree-CHKTYNCV.js → exit-worktree-ARVID7DF.js} +36 -34
  194. package/chunks/{exitPlanMode-QYAG6LWX.js → exitPlanMode-4ZFY7KUH.js} +36 -34
  195. package/chunks/{fast-path-Z2K7W6DC.js → fast-path-KA65VREJ.js} +9 -5
  196. package/chunks/{fr-4KG5V7UT.js → fr-QF7RI5ZE.js} +46 -5
  197. package/chunks/{gemini-YU4XKEDG.js → gemini-5PMCNPF7.js} +149 -90
  198. package/chunks/{geminiContentGenerator-ZZX6NBO4.js → geminiContentGenerator-NFSYJ4HA.js} +6 -6
  199. package/chunks/{glob-VYF5CXSX.js → glob-F3EAUDAX.js} +36 -34
  200. package/chunks/{goal-tools-HGO6VXPB.js → goal-tools-SPQ5M6D3.js} +3 -3
  201. package/chunks/{grep-5DP5ZUTW.js → grep-UJMPVZER.js} +36 -34
  202. package/chunks/{handleAutoUpdate-UVBJ56DL.js → handleAutoUpdate-MG4FRZPN.js} +42 -40
  203. package/chunks/{i18n-UQNYHEUD.js → i18n-EVHV4ZF3.js} +38 -36
  204. package/chunks/{image-gen-WHPIZNWF.js → image-gen-UC7XVHI7.js} +9 -9
  205. package/chunks/{initializer-GMIICF4W.js → initializer-O5B6HUBI.js} +43 -41
  206. package/chunks/{installationInfo-4MGG4WVI.js → installationInfo-2LIKCNVX.js} +37 -35
  207. package/chunks/{ja-F3GSQXMF.js → ja-URQESVGW.js} +46 -5
  208. package/chunks/{keychain-token-storage-IKO4G53C.js → keychain-token-storage-7BT4TQ2A.js} +2 -2
  209. package/chunks/{kittyProtocolDetector-MBRTDRBK.js → kittyProtocolDetector-BFLAKYXH.js} +1 -1
  210. package/chunks/{list-CPN2W334.js → list-BPKIE3Z4.js} +45 -43
  211. package/chunks/{list-agents-PXJ7ZUFB.js → list-agents-TWEGRJWO.js} +2 -2
  212. package/chunks/{loadedSettingsAdapter-ZQAV5NDO.js → loadedSettingsAdapter-NGLFF4V4.js} +42 -40
  213. package/chunks/{loggingContentGenerator-5E7W4IEP.js → loggingContentGenerator-7TFESRG5.js} +52 -37
  214. package/chunks/{loop-wakeup-Y26NQZ5I.js → loop-wakeup-6LLEOQYV.js} +5 -5
  215. package/chunks/{ls-ONQTTMQR.js → ls-H5WX22VK.js} +4 -4
  216. package/chunks/{lsp-YGHHRGMD.js → lsp-G6FXYEIS.js} +2 -2
  217. package/chunks/{managed-npm-update-MKKAXYXA.js → managed-npm-update-CLZGGV7F.js} +39 -37
  218. package/chunks/{mcp-V5NTJF6X.js → mcp-X5OZOOXX.js} +42 -40
  219. package/chunks/{monitor-CO3ASY6E.js → monitor-TGSVSAZZ.js} +36 -34
  220. package/chunks/nonInteractiveCli-GUMJ5JLG.js +150 -0
  221. package/chunks/{notebook-edit-Z7AEE6FM.js → notebook-edit-EZISE7IC.js} +36 -34
  222. package/chunks/{openaiContentGenerator-CA3MQOP3.js → openaiContentGenerator-ZAKS5A6P.js} +18 -18
  223. package/chunks/{pidfile-NL7MKDRU.js → pidfile-PCMBX4LR.js} +37 -35
  224. package/chunks/{processUtils-PB5K2DYH.js → processUtils-2CSVE5BW.js} +2 -2
  225. package/chunks/{pt-EQ33KWEN.js → pt-EEEQXRUI.js} +46 -5
  226. package/chunks/{qwenContentGenerator-JYFNDCOS.js → qwenContentGenerator-S3H6PIC4.js} +42 -40
  227. package/chunks/{qwenOAuth2-W2ALKQDD.js → qwenOAuth2-MNU425VE.js} +8 -8
  228. package/chunks/{read-file-IEOR5H5W.js → read-file-HXJXHBI6.js} +10 -10
  229. package/chunks/{read-mcp-resource-U2IJN5HM.js → read-mcp-resource-DRZSI3HE.js} +2 -2
  230. package/chunks/{record-artifact-MGPJ7EG4.js → record-artifact-IPIRWMFY.js} +3 -3
  231. package/chunks/{resumeHistoryUtils-BNBTP5AS.js → resumeHistoryUtils-4QAMC2S6.js} +44 -42
  232. package/chunks/{ripGrep-UMQODKEB.js → ripGrep-MCETPF2E.js} +36 -34
  233. package/chunks/{ru-7OZAUKGG.js → ru-WGZDYQAB.js} +46 -5
  234. package/chunks/{run-qwen-serve-RN2R6QQW.js → run-qwen-serve-3NMODTXV.js} +219 -55
  235. package/chunks/{runtime-QFJ2MJF5.js → runtime-AQOV7DVP.js} +49 -45
  236. package/chunks/{scheduler-AMYUFOZI.js → scheduler-DN7SZ6ZE.js} +36 -34
  237. package/chunks/{sdk-exporters-http-4BQANSJ6.js → sdk-exporters-http-IKNWQJNV.js} +2 -2
  238. package/chunks/{sdk-impl-Z4VXWVFX.js → sdk-impl-7CUUMQDB.js} +2 -2
  239. package/chunks/{send-message-PMP4ATVM.js → send-message-HGCVVDTZ.js} +5 -4
  240. package/chunks/{serve-EIIYJVX3.js → serve-WZB45HVT.js} +42 -40
  241. package/chunks/{server-EP2LLAPD.js → server-GOTZFEEZ.js} +616 -387
  242. package/chunks/{session-GMPZBLOW.js → session-23LOFLWN.js} +149 -87
  243. package/chunks/{settings-LN7RNKBS.js → settings-LI2ORVXC.js} +41 -39
  244. package/chunks/{shell-EM2OWU5X.js → shell-GLC6OP3C.js} +36 -34
  245. package/chunks/{skill-T5VPSK73.js → skill-C7W6M4GO.js} +27 -14
  246. package/chunks/{skill-settings-GMR3GMNY.js → skill-settings-W25NCK5I.js} +41 -39
  247. package/chunks/{spawnChannel-YPCU62DI.js → spawnChannel-OHJLEBLD.js} +38 -36
  248. package/chunks/{standalone-update-JAKIM2NF.js → standalone-update-E4V5V7WT.js} +39 -37
  249. package/chunks/{startInteractiveUI-YETQWGYF.js → startInteractiveUI-FKILLW7Q.js} +1815 -1034
  250. package/chunks/{syntheticOutput-D7E6ZFKR.js → syntheticOutput-EYL7DWO7.js} +3 -3
  251. package/chunks/{task-create-NFCYD43L.js → task-create-CSCEG4SM.js} +10 -9
  252. package/chunks/{task-list-TAVMGEVD.js → task-list-6CVQPORX.js} +6 -6
  253. package/chunks/{task-stop-ZDF2UJRM.js → task-stop-Y5ZTFVRX.js} +2 -2
  254. package/chunks/{task-update-6L7LHGEX.js → task-update-C52LNFU5.js} +10 -9
  255. package/chunks/{team-create-LFJ6HGNY.js → team-create-HBIJ7NHT.js} +36 -34
  256. package/chunks/{team-delete-DPGGRQBU.js → team-delete-CE7DC53R.js} +6 -6
  257. package/chunks/{team-plan-approval-C2KLSDGO.js → team-plan-approval-IBJOKS4J.js} +36 -34
  258. package/chunks/terminal-image-renderer-BOQJPVLB.js +89 -0
  259. package/chunks/{theme-manager-JQ3ZGBP5.js → theme-manager-NSS7VLUD.js} +37 -35
  260. package/chunks/{todoWrite-2UO5G6G6.js → todoWrite-YKAA57W2.js} +107 -36
  261. package/chunks/{tool-search-FAZBFRJZ.js → tool-search-DEAS54VG.js} +13 -12
  262. package/chunks/{total-session-admission-5CALIVYO.js → total-session-admission-4LWTX3WD.js} +43 -41
  263. package/chunks/{trustedFolders-KOPSP44S.js → trustedFolders-NF3J2TA7.js} +38 -36
  264. package/chunks/{update-relaunch-6QL2TICS.js → update-relaunch-WUHRH5V3.js} +5 -5
  265. package/chunks/{updateCheck-4Q6RIKFW.js → updateCheck-7EG4BLBH.js} +41 -39
  266. package/chunks/{useAutoAcceptIndicator-Q5BMKZV3.js → useAutoAcceptIndicator-ZRV56GVP.js} +46 -44
  267. package/chunks/{validateNonInterActiveAuth-GKOC5F6Z.js → validateNonInterActiveAuth-WC2FPE3I.js} +86 -84
  268. package/chunks/{version-VSATY2LD.js → version-6SS7KCUP.js} +1 -1
  269. package/chunks/{web-fetch-JCLKL6NL.js → web-fetch-Y5QQMPKA.js} +13 -13
  270. package/chunks/{web-search-DSQTFUBX.js → web-search-QKKEU723.js} +8 -8
  271. package/chunks/{workflow-M6QAVKVJ.js → workflow-PWIU6Q2M.js} +418 -304
  272. package/chunks/{workspace-providers-status-YKLTLMJA.js → workspace-providers-status-B2DM6FNK.js} +45 -43
  273. package/chunks/{workspace-registration-store-5DMGKU64.js → workspace-registration-store-7Y33TTHJ.js} +2 -2
  274. package/chunks/{workspace-registry-PTYUSYXX.js → workspace-registry-TSNJKLPC.js} +43 -41
  275. package/chunks/{workspace-service-25ML3T47.js → workspace-service-4I2QHDX4.js} +50 -48
  276. package/chunks/{workspace-skills-status-YKZWOYRX.js → workspace-skills-status-HVXNWVGR.js} +44 -42
  277. package/chunks/{workspace-trust-reconciler-5FI2S3OS.js → workspace-trust-reconciler-RDBBGMWP.js} +49 -47
  278. package/chunks/{write-file-AY7VLP5X.js → write-file-RQ4DG5RY.js} +36 -34
  279. package/chunks/{zh-H3YDK5QW.js → zh-72XPUG5P.js} +54 -6
  280. package/chunks/{zh-TW-JYCP7XUA.js → zh-TW-LTB4SRH3.js} +54 -6
  281. package/chunks/{zoom-image-S4LJZMD5.js → zoom-image-O5YCB7WN.js} +10 -10
  282. package/cli.js +32 -48
  283. package/locales/ca.js +60 -4
  284. package/locales/de.js +62 -4
  285. package/locales/en.js +76 -6
  286. package/locales/fr.js +64 -4
  287. package/locales/ja.js +61 -4
  288. package/locales/pt.js +60 -4
  289. package/locales/ru.js +63 -4
  290. package/locales/zh-TW.js +67 -6
  291. package/locales/zh.js +67 -6
  292. package/package.json +3 -3
  293. package/web-shell/assets/{arc-xjArKHU2.js → arc-Bd7d781i.js} +1 -1
  294. package/web-shell/assets/{architectureDiagram-3BPJPVTR-BgrQDNYG.js → architectureDiagram-3BPJPVTR-CpnOJqNE.js} +1 -1
  295. package/web-shell/assets/{blockDiagram-GPEHLZMM-CXxWC-1_.js → blockDiagram-GPEHLZMM-NxVTiWnk.js} +1 -1
  296. package/web-shell/assets/{c4Diagram-AAUBKEIU-Dx1tLm3v.js → c4Diagram-AAUBKEIU-BWT75l82.js} +1 -1
  297. package/web-shell/assets/channel-A434sWK5.js +1 -0
  298. package/web-shell/assets/{chunk-2J33WTMH-CBxjogVR.js → chunk-2J33WTMH-Dzz03hk6.js} +1 -1
  299. package/web-shell/assets/{chunk-4BX2VUAB-izb-rY5W.js → chunk-4BX2VUAB-DRF-egfm.js} +1 -1
  300. package/web-shell/assets/{chunk-55IACEB6-NzLyvSb8.js → chunk-55IACEB6-Co15vq5x.js} +1 -1
  301. package/web-shell/assets/{chunk-727SXJPM-DVyKb0dl.js → chunk-727SXJPM-DHSUk1J7.js} +1 -1
  302. package/web-shell/assets/{chunk-AQP2D5EJ-BtqL7NzB.js → chunk-AQP2D5EJ-Br8u_E2R.js} +1 -1
  303. package/web-shell/assets/{chunk-FMBD7UC4-iNpdKIO0.js → chunk-FMBD7UC4-DXbPTnqF.js} +1 -1
  304. package/web-shell/assets/{chunk-ND2GUHAM-DI7cbFmX.js → chunk-ND2GUHAM-BleQdi4d.js} +1 -1
  305. package/web-shell/assets/{chunk-QZHKN3VN-3Y_-xFYs.js → chunk-QZHKN3VN-CqgBf-95.js} +1 -1
  306. package/web-shell/assets/classDiagram-4FO5ZUOK-CwPuhldB.js +1 -0
  307. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CwPuhldB.js +1 -0
  308. package/web-shell/assets/{cose-bilkent-S5V4N54A--raRatZn.js → cose-bilkent-S5V4N54A-WS7b13Yg.js} +1 -1
  309. package/web-shell/assets/{dagre-BM42HDAG-B8SU70mO.js → dagre-BM42HDAG-v_55ki8o.js} +1 -1
  310. package/web-shell/assets/{diagram-2AECGRRQ-ewgoakXo.js → diagram-2AECGRRQ-DaYAjbdK.js} +1 -1
  311. package/web-shell/assets/{diagram-5GNKFQAL-Bm_JLTnS.js → diagram-5GNKFQAL-D_Hy-L64.js} +1 -1
  312. package/web-shell/assets/{diagram-KO2AKTUF-DEIUjUy9.js → diagram-KO2AKTUF-dB06cZyD.js} +1 -1
  313. package/web-shell/assets/{diagram-LMA3HP47-C2Wmrpj-.js → diagram-LMA3HP47-DzSluD4F.js} +1 -1
  314. package/web-shell/assets/{diagram-OG6HWLK6-CtYe6bFx.js → diagram-OG6HWLK6-Cvb6CeXQ.js} +1 -1
  315. package/web-shell/assets/{erDiagram-TEJ5UH35-DfpHcWLV.js → erDiagram-TEJ5UH35-7eB2Hmov.js} +1 -1
  316. package/web-shell/assets/{flowDiagram-I6XJVG4X-CAiUhio5.js → flowDiagram-I6XJVG4X-B08iGCw_.js} +1 -1
  317. package/web-shell/assets/{ganttDiagram-6RSMTGT7-CYc7ezr4.js → ganttDiagram-6RSMTGT7-BgsrCHq-.js} +1 -1
  318. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-70lbkcRS.js → gitGraphDiagram-PVQCEYII-DQLurQ2i.js} +1 -1
  319. package/web-shell/assets/{index-Ww86nT9f.js → index-B_1Z0Mgr.js} +1 -1
  320. package/web-shell/assets/index-Bi1dP2mU.css +5 -0
  321. package/web-shell/assets/index-DJ-z1Oba.js +1756 -0
  322. package/web-shell/assets/{infoDiagram-5YYISTIA-C7e8DWPa.js → infoDiagram-5YYISTIA-DXZGO8qB.js} +1 -1
  323. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-BYLr2op-.js → ishikawaDiagram-YF4QCWOH-g7gbuH2w.js} +1 -1
  324. package/web-shell/assets/{journeyDiagram-JHISSGLW-hEibAHKX.js → journeyDiagram-JHISSGLW-euefICGn.js} +1 -1
  325. package/web-shell/assets/{kanban-definition-UN3LZRKU-F2rt8Uhp.js → kanban-definition-UN3LZRKU-Dws8-mjG.js} +1 -1
  326. package/web-shell/assets/{linear-DPhyNezd.js → linear-C63F0tyh.js} +1 -1
  327. package/web-shell/assets/{mermaid.core-ZUtnug0n.js → mermaid.core-fLrhp_4-.js} +5 -5
  328. package/web-shell/assets/{mindmap-definition-RKZ34NQL-DDWcMoi8.js → mindmap-definition-RKZ34NQL-qRkydfT-.js} +1 -1
  329. package/web-shell/assets/{pieDiagram-4H26LBE5-CTRKzw1_.js → pieDiagram-4H26LBE5-BZ0wQaKN.js} +1 -1
  330. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-CAEwYG_z.js → quadrantDiagram-W4KKPZXB-Fjq6GbSZ.js} +1 -1
  331. package/web-shell/assets/{requirementDiagram-4Y6WPE33-CRjnH9D9.js → requirementDiagram-4Y6WPE33-CqWvjLHU.js} +1 -1
  332. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-LPQT_sOd.js → sankeyDiagram-5OEKKPKP-VcXX6PVZ.js} +1 -1
  333. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-Ht2Iqvb0.js → sequenceDiagram-3UESZ5HK-BJSRtxFr.js} +1 -1
  334. package/web-shell/assets/{stateDiagram-AJRCARHV-CIUdqOXu.js → stateDiagram-AJRCARHV-Dt9zUwmZ.js} +1 -1
  335. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CCxQt56w.js +1 -0
  336. package/web-shell/assets/{timeline-definition-PNZ67QCA-BcilneZF.js → timeline-definition-PNZ67QCA-DQwlNRws.js} +1 -1
  337. package/web-shell/assets/{vennDiagram-CIIHVFJN-BljwiiH1.js → vennDiagram-CIIHVFJN-DwxjUEtQ.js} +1 -1
  338. package/web-shell/assets/{wardley-L42UT6IY-DeKjkYjq.js → wardley-L42UT6IY-D3QdMSpJ.js} +1 -1
  339. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-L3U1H7KG.js → wardleyDiagram-YWT4CUSO-BddN8oK8.js} +1 -1
  340. package/web-shell/assets/{xychartDiagram-2RQKCTM6-IJnWsgMT.js → xychartDiagram-2RQKCTM6-BUNuBrRJ.js} +1 -1
  341. package/web-shell/index.html +2 -2
  342. package/chunks/chunk-4KP2F2TE.js +0 -82
  343. package/chunks/chunk-HGT6JR3U.js +0 -177
  344. package/chunks/nonInteractiveCli-ZJYEOO7U.js +0 -148
  345. package/web-shell/assets/channel-B1cyk94G.js +0 -1
  346. package/web-shell/assets/classDiagram-4FO5ZUOK-BpBYZoRE.js +0 -1
  347. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BpBYZoRE.js +0 -1
  348. package/web-shell/assets/index-C1k3PDuU.css +0 -5
  349. package/web-shell/assets/index-DZLIXILO.js +0 -1750
  350. package/web-shell/assets/insert-DmRbh9Rv.svg +0 -1
  351. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BmqqQZ6w.js +0 -1
@@ -147,6 +147,87 @@ By default, HTTP hooks cannot target private or link-local IP ranges. In platfor
147
147
  }
148
148
  ```
149
149
 
150
+ **Example: External Judgment Service Adapter**
151
+
152
+ The `remote-security-check` config above expects `http://127.0.0.1:8080/hooks/pre-tool-use` to
153
+ already be running a service that speaks this contract (POST `{tool_name, tool_input, ...}` in,
154
+ `hookSpecificOutput.permissionDecision` out). Here is a minimal, stdlib-only adapter that fills
155
+ in that missing half, wired to one concrete judgment backend so the whole thing is runnable and
156
+ testable end to end rather than a stub. Only the `review()` function is backend-specific — swap
157
+ its body and request/response shape for whichever service you use; everything else (the server,
158
+ the fail-open handling, the hook response shape) stays the same regardless of backend.
159
+
160
+ _Disclosure: the backend used below, [invinoveritas](https://api.babyblueviper.com), is a
161
+ service the author is affiliated with — used here because it was the one that could be
162
+ verified end to end for this example, not an endorsement. Any HTTP service that returns a
163
+ JSON verdict works equally well; only `review()` needs to change._
164
+
165
+ _Data handling: with `matcher: "*"`, the full `tool_input` of **every** tool call is sent to
166
+ the judgment backend — treat that input as sensitive (it may contain file contents, paths, or
167
+ secrets). Narrow the matcher (e.g. to `run_shell_command`) if you only need to judge shell
168
+ commands._
169
+
170
+ ```python
171
+ #!/usr/bin/env python3
172
+ # judgment_hook.py -- run: JUDGMENT_API_KEY=... python3 judgment_hook.py
173
+ import json, os, sys, urllib.request
174
+ from http.server import BaseHTTPRequestHandler, HTTPServer
175
+
176
+ JUDGMENT_API_KEY = os.environ["JUDGMENT_API_KEY"]
177
+ JUDGMENT_URL = os.environ.get("JUDGMENT_URL", "https://api.babyblueviper.com/review")
178
+
179
+ def review(tool_name, tool_input):
180
+ """POST the call to the judgment backend and return its verdict. This is the
181
+ one function to change for a different backend -- request/response shape
182
+ below matches invinoveritas's /review; adapt both to your own backend's
183
+ contract if you swap it out."""
184
+ body = json.dumps({
185
+ "artifact": json.dumps({"tool_name": tool_name, "tool_input": tool_input}),
186
+ "artifact_type": "shell_command" if tool_name in ("run_shell_command", "shell") else "general",
187
+ "context": f"qwen-code PreToolUse: {tool_name}",
188
+ }).encode()
189
+ req = urllib.request.Request(
190
+ JUDGMENT_URL, data=body,
191
+ headers={"Authorization": f"Bearer {JUDGMENT_API_KEY}", "Content-Type": "application/json"},
192
+ )
193
+ # Keep this below the HTTP hook's own timeout (10s in the config above), so a "deny"
194
+ # verdict is always returned before the hook gives up and fails open on its own.
195
+ with urllib.request.urlopen(req, timeout=8) as resp:
196
+ return json.loads(resp.read()) # response includes a "verdict" field: "reject" denies, anything else allows
197
+
198
+ class Handler(BaseHTTPRequestHandler):
199
+ def do_POST(self):
200
+ payload = json.loads(self.rfile.read(int(self.headers.get("Content-Length", 0))) or b"{}")
201
+ tool_name, tool_input = payload.get("tool_name", "unknown"), payload.get("tool_input", {})
202
+ try:
203
+ verdict = review(tool_name, tool_input)
204
+ decision = "deny" if verdict.get("verdict") == "reject" else "allow"
205
+ reason = verdict.get("summary", f"judgment verdict: {verdict.get('verdict')}")
206
+ except Exception as e:
207
+ decision, reason = "allow", "judgment backend unavailable, failing open" # never block on a review-side outage
208
+ print(f"judgment backend unavailable for {tool_name}, failing open: {e}", file=sys.stderr)
209
+ out = {"continue": True, "decision": decision, "hookSpecificOutput": {
210
+ "hookEventName": "PreToolUse", "permissionDecision": decision, "permissionDecisionReason": reason,
211
+ }}
212
+ body = json.dumps(out).encode()
213
+ self.send_response(200)
214
+ self.send_header("Content-Type", "application/json")
215
+ self.send_header("Content-Length", str(len(body)))
216
+ self.end_headers()
217
+ self.wfile.write(body)
218
+ def log_message(self, *a): pass
219
+
220
+ if __name__ == "__main__":
221
+ HTTPServer(("127.0.0.1", 8080), Handler).serve_forever()
222
+ ```
223
+
224
+ Tested live end to end against the real production API above: a genuinely destructive input
225
+ (`{"tool_name": "run_shell_command", "tool_input": {"command": "rm -rf /important_data"}}`)
226
+ returned `permissionDecision: "deny"` with a real explanation; a benign one (`ls -la`) returned
227
+ `"allow"`. Fails open on any network/timeout/malformed-response issue from the judgment
228
+ backend, so an outage never blocks legitimate tool calls — same discipline the `command`-hook
229
+ examples above apply with their own exit codes.
230
+
150
231
  ### Function Hooks
151
232
 
152
233
  Function hooks directly call registered JavaScript/TypeScript functions. They are used internally by the Skill system and are not currently exposed as a public API for end users.
@@ -255,24 +336,25 @@ When `ok` is `false`, Qwen Code will continue working and use the `reason` as co
255
336
 
256
337
  Hooks fire at specific points during a Qwen Code session. Different events support different matchers to filter trigger conditions.
257
338
 
258
- | Event | Triggered When | Matcher Target |
259
- | :------------------- | :---------------------------------------- | :------------------------------------------------------------- |
260
- | `PreToolUse` | Before tool execution | Tool id (`write_file`, `read_file`, `run_shell_command`, etc.) |
261
- | `PostToolUse` | After successful tool execution | Tool id |
262
- | `PostToolUseFailure` | After tool execution fails | Tool id |
263
- | `UserPromptSubmit` | Before supported model invocations | None |
264
- | `SessionStart` | When session starts or resumes | Source (`startup`, `resume`, `clear`, `compact`) |
265
- | `SessionEnd` | When session ends | Reason (`clear`, `logout`, `prompt_input_exit`, etc.) |
266
- | `MessageDisplay` | Repeatedly, as the reply streams | None (always fires) |
267
- | `Stop` | When Claude prepares to conclude response | None (always fires) |
268
- | `SubagentStart` | When subagent starts | Agent type (`Bash`, `Explorer`, `Plan`, etc.) |
269
- | `SubagentStop` | When subagent stops | Agent type |
270
- | `PreCompact` | Before conversation compaction | Trigger (`manual`, `auto`) |
271
- | `Notification` | When notifications are sent | Type (`permission_prompt`, `idle_prompt`, `auth_success`) |
272
- | `PermissionRequest` | When permission dialog is shown | Tool id |
273
- | `PermissionDenied` | When tool permission is denied | Tool id |
274
- | `TodoCreated` | When a new todo item is created | None (always fires) |
275
- | `TodoCompleted` | When a todo item is marked as completed | None (always fires) |
339
+ | Event | Triggered When | Matcher Target |
340
+ | :------------------- | :---------------------------------------------- | :------------------------------------------------------------- |
341
+ | `PreToolUse` | Before tool execution | Tool id (`write_file`, `read_file`, `run_shell_command`, etc.) |
342
+ | `PostToolUse` | After successful tool execution | Tool id |
343
+ | `PostToolUseFailure` | After tool execution fails | Tool id |
344
+ | `UserPromptSubmit` | Before supported model invocations | None |
345
+ | `SessionStart` | When session starts or resumes | Source (`startup`, `resume`, `clear`, `compact`) |
346
+ | `SessionEnd` | When session ends | Reason (`clear`, `logout`, `prompt_input_exit`, etc.) |
347
+ | `SessionDelete` | After an explicitly selected session is deleted | None |
348
+ | `MessageDisplay` | Repeatedly, as the reply streams | None (always fires) |
349
+ | `Stop` | When Claude prepares to conclude response | None (always fires) |
350
+ | `SubagentStart` | When subagent starts | Agent type (`Bash`, `Explorer`, `Plan`, etc.) |
351
+ | `SubagentStop` | When subagent stops | Agent type |
352
+ | `PreCompact` | Before conversation compaction | Trigger (`manual`, `auto`) |
353
+ | `Notification` | When notifications are sent | Type (`permission_prompt`, `idle_prompt`, `auth_success`) |
354
+ | `PermissionRequest` | When permission dialog is shown | Tool id |
355
+ | `PermissionDenied` | When tool permission is denied | Tool id |
356
+ | `TodoCreated` | When a new todo item is created | None (always fires) |
357
+ | `TodoCompleted` | When a todo item is marked as completed | None (always fires) |
276
358
 
277
359
  ### Matcher Patterns
278
360
 
@@ -284,6 +366,7 @@ Hooks fire at specific points during a Qwen Code session. Different events suppo
284
366
  | Subagent Events | `SubagentStart`, `SubagentStop` | ✅ Regex | Agent type: `Bash`, `Explorer`, etc. |
285
367
  | Session Events | `SessionStart` | ✅ Regex | Source: `startup`, `resume`, `clear`, `compact` |
286
368
  | Session Events | `SessionEnd` | ✅ Regex | Reason: `clear`, `logout`, `prompt_input_exit`, etc. |
369
+ | Session Events | `SessionDelete` | ❌ No | N/A |
287
370
  | Notification Events | `Notification` | ✅ Exact match | Type: `permission_prompt`, `idle_prompt`, `auth_success` |
288
371
  | Compact Events | `PreCompact` | ✅ Exact match | Trigger: `manual`, `auto` |
289
372
  | Todo Events | `TodoCreated`, `TodoCompleted` | ❌ No | N/A |
@@ -619,6 +702,20 @@ When sent to the model, injected `additionalContext` is appended as its own mess
619
702
 
620
703
  - Standard hook output fields (typically not used for blocking)
621
704
 
705
+ #### SessionDelete
706
+
707
+ **Purpose**: Runs after an explicitly selected session has been permanently deleted. This event is fire-and-forget: output and failures cannot undo the deletion.
708
+
709
+ **Event-specific fields**:
710
+
711
+ ```json
712
+ {
713
+ "deleted_session_id": "the session that was deleted"
714
+ }
715
+ ```
716
+
717
+ The hook uses the deleting runtime's normal session fields (`session_id`, `transcript_path`, and `cwd`); over ACP, `transcript_path` is empty because the deleting runtime has no transcript of its own. `SessionDelete` currently fires for the interactive `/delete` flow and ACP's explicit `deleteSession` method; daemon REST batch deletion and internal cleanup do not emit it.
718
+
622
719
  #### MessageDisplay
623
720
 
624
721
  **Purpose**: Fires repeatedly as the assistant's reply streams — before `Stop`, which fires once at the end of the turn. Useful for live narration, incremental logging, or any consumer that wants to react to the reply as it's written rather than after the fact. This is a **fire-and-forget** event - hook output and exit codes are ignored.
@@ -95,6 +95,33 @@ Auto-memory files live at `~/.qwen/projects/<project>/memory/`. All branches of
95
95
 
96
96
  Everything saved is plain markdown — you can open, edit, or delete any file at any time.
97
97
 
98
+ #### Pinned memory
99
+
100
+ Put hand-curated documents that automatic memory maintenance should preserve
101
+ under `pinned/` in a managed-memory directory, for example
102
+ `~/.qwen/projects/<project>/memory/pinned/architecture.md` or
103
+ `~/.qwen/memories/pinned/preferences.md`. Use the same frontmatter as other
104
+ memory documents. Valid pinned files are readable by Qwen and are included the
105
+ next time `MEMORY.md` is rebuilt, under the same size and file-count limits as
106
+ other memory documents.
107
+
108
+ Only the top-level `pinned/` directory directly inside a managed-memory root is
109
+ protected; nested directories such as `memory/project/pinned/` are ordinary
110
+ writable memory. Automatic extraction and Dream workers match the reserved
111
+ directory name case-insensitively.
112
+
113
+ Automatic extraction is instructed to leave pinned records and their valid
114
+ index entries unchanged, while Dream is instructed to skip `pinned/` during
115
+ consolidation. Both automatic extraction and forked Dream workers, including
116
+ background cleanup, enforce the pinned-file boundary on their write and edit
117
+ tools, including paths that resolve through a symlink into `pinned/`; their
118
+ existing read-only shell policy blocks command-line deletion. You still control
119
+ these files directly and can remove them with an explicit `/forget` request.
120
+
121
+ > **Note:** The visible `/dream` slash command runs on the main Agent. It
122
+ > receives the same skip instruction, but does not yet receive the forked
123
+ > worker's deterministic per-turn tool gate.
124
+
98
125
  ### Periodic cleanup
99
126
 
100
127
  Qwen periodically goes through its saved memories to remove duplicates and clean up outdated entries. This runs automatically in the background once a day after enough sessions have accumulated. You can trigger it manually with `/dream` if you want it to run now.
@@ -38,6 +38,33 @@ Start typing `/` to autocomplete and browse available Skills alongside their des
38
38
 
39
39
  Skills are stored as directories containing a `SKILL.md` file.
40
40
 
41
+ ### Generate a project Skill with `/learn`
42
+
43
+ Use `/learn` to distill an existing knowledge source into a reusable project
44
+ Skill:
45
+
46
+ ```text
47
+ /learn https://docs.example.com/api
48
+ /learn ~/projects/acme-sdk
49
+ /learn Our deploy process: run migrate, deploy the service, then check health
50
+ ```
51
+
52
+ The command runs as a normal agent turn and creates the result under
53
+ `.qwen/skills/learned-skill-<name>/SKILL.md` with `source: learned` in its
54
+ frontmatter. Review the generated instructions before using or sharing them.
55
+
56
+ `/learn` also accepts local or direct-link `.mp4`, `.webm`, `.mov`, and `.m4v`
57
+ videos. Add text after the path or URL to focus the generated Skill on one part
58
+ of the tutorial:
59
+
60
+ ```text
61
+ /learn ./tutorial.mp4 focus on the deployment workflow
62
+ ```
63
+
64
+ Video learning requires a video-capable model on an OpenAI-compatible provider.
65
+ YouTube page URLs are not direct video input; download the video into the
66
+ workspace and pass its local path instead.
67
+
41
68
  ### Personal Skills
42
69
 
43
70
  Personal Skills are available across all your projects. Store them in `~/.qwen/skills/`:
@@ -68,6 +95,20 @@ Use project Skills for:
68
95
 
69
96
  Project Skills can be checked into git and automatically become available to teammates.
70
97
 
98
+ ### Maintain auto-generated project Skills
99
+
100
+ Qwen Code tracks successful uses of generated project Skills locally, including while new Auto Skill generation is disabled, so re-enabling maintenance cannot mistake a recently used skill for an inactive one. When **Auto Skill** is enabled, it periodically moves inactive generated Skills out of the active library. Only directories named `.qwen/skills/auto-skill-*` whose `SKILL.md` frontmatter contains `source: auto-skill` are managed; personal, extension, bundled, and hand-authored Skills are never selected.
101
+
102
+ - After 30 days without a successful use or `SKILL.md` edit, an auto-skill is marked stale.
103
+ - After 90 days, its complete directory is moved to `.qwen/archived-skills/`. Nothing is permanently deleted.
104
+ - Automatic maintenance runs at most once every 7 days in trusted workspaces. Each newly observed auto-skill gets a full grace period before maintenance begins.
105
+ - A pinned auto-skill is excluded from automatic stale and archive transitions until it is unpinned.
106
+ - Archived directory names remain reserved, and an existing archive destination skips only that collision rather than stopping maintenance for other skills.
107
+
108
+ Use `/curator` to see active, stale, archived, and pinned auto-skills. Run `/curator run --dry-run` to preview a maintenance pass, `/curator run` to apply it immediately, `/curator pin <directory>` or `/curator unpin <directory>` to control per-skill maintenance, or `/curator restore <directory>` to move an archived auto-skill back into the active library.
109
+
110
+ Status and dry-run previews are available in safe mode and untrusted workspaces. Applying maintenance, changing pins, and restoring archived auto-skills require a trusted workspace outside safe mode.
111
+
71
112
  ## Write `SKILL.md`
72
113
 
73
114
  Create a `SKILL.md` file with YAML frontmatter and Markdown content:
@@ -183,6 +224,7 @@ Qwen Code discovers Skills from:
183
224
  - Personal Skills: `~/.qwen/skills/`
184
225
  - Project Skills: `.qwen/skills/`
185
226
  - Extension Skills: Skills provided by installed extensions
227
+ - Bundled Skills: Skills shipped with Qwen Code
186
228
 
187
229
  ### Extension Skills
188
230
 
@@ -310,7 +352,10 @@ code ~/.qwen/skills/my-skill/SKILL.md
310
352
  code .qwen/skills/my-skill/SKILL.md
311
353
  ```
312
354
 
313
- Changes take effect the next time you start Qwen Code. If Qwen Code is already running, restart it to load the updates.
355
+ During a normal session, Qwen Code watches personal and project Skill
356
+ directories. Adding, editing, or removing a Skill refreshes the Skill list and
357
+ invocation state automatically after a short delay. Bare mode does not start
358
+ these watchers, so restart Qwen Code to load Skill changes in that mode.
314
359
 
315
360
  ## Remove a Skill
316
361
 
@@ -29,24 +29,57 @@ Tool responses and pure system reminders do not count as user turns. Regular nam
29
29
 
30
30
  Only `subagent_type: "fork"` accepts `fork_tools`. The array may contain exact canonical tool names, such as `read_file` and `grep_search`, or MCP server patterns such as `mcp__github`. The fork still receives the same model-visible tool declarations as an unrestricted fork, preserving its prompt-cache prefix, but its task prompt identifies the restriction and a call not matched by `fork_tools` is rejected before scheduling or approval.
31
31
 
32
- - Omitting `fork_tools` preserves unrestricted fork execution.
32
+ - Forks never execute `ask_user_question`; when user input is required, they report the blocker to their parent agent.
33
+ - Omitting `fork_tools` allows every other inherited tool.
33
34
  - An empty array rejects every tool call.
34
- - `*` is not accepted; omit `fork_tools` when unrestricted execution is intended.
35
+ - `*` is not accepted; omit `fork_tools` to allow every otherwise-executable inherited tool.
35
36
  - Tool names cannot have surrounding whitespace. Wildcards are accepted only as `mcp__*` or as a trailing MCP tool-prefix pattern such as `mcp__github__read_*`.
36
37
  - `mcp__*` intentionally allows every MCP tool while still denying unlisted built-in tools.
37
38
  - Shell command argument patterns are not supported. Listing `run_shell_command` allows that tool to proceed through its normal permission checks but does not pre-approve any command.
38
39
 
39
40
  This is a per-invocation restriction supplied by the caller. It narrows a child fork's capabilities but is not an administrator-enforced security sandbox because the caller can omit or expand the list.
40
41
 
42
+ ## Reusing Fork Restrictions with `fork_profile`
43
+
44
+ A project can save a named fork restriction in `.qwen/fork-profiles/<name>.md` and select it with `fork_profile`. This is useful when several calls need the same tool boundary and task guidance:
45
+
46
+ ```markdown
47
+ ---
48
+ name: ro-research
49
+ tools:
50
+ - read_file
51
+ - grep_search
52
+ - glob
53
+ - mcp__search__*
54
+ promptHint: |
55
+ Work read-only. Prefer targeted searches and cite file evidence.
56
+ ---
57
+ ```
58
+
59
+ Then launch the fork with:
60
+
61
+ ```text
62
+ agent(description="Research", prompt="Inspect the retry path", subagent_type="fork", fork_profile="ro-research")
63
+ ```
64
+
65
+ - `fork_profile` is valid only for a fork and cannot be combined with `fork_tools` or a named teammate.
66
+ - Profiles are currently project-only. The requested name, filename, and frontmatter `name` must match exactly. The profile must resolve to a regular file inside `.qwen/fork-profiles/` and cannot exceed 64 KiB.
67
+ - `tools` is required and follows the `fork_tools` rules, including empty-array deny-all behavior.
68
+ - `promptHint` is optional and limited to 200 characters. It is escaped and framed as project-supplied guidance after the fork directive and before the authoritative tool restriction; it does not change the inherited system instruction or model-visible tool declarations. Profile files are frontmatter-only, so non-blank Markdown after the closing `---` is rejected instead of silently ignored.
69
+ - The profile is resolved once at launch. A retained fork continues with the resolved tool snapshot even if the project file later changes.
70
+ - Project fork profiles are unavailable in safe mode and bare mode, which disable local customizations.
71
+
72
+ Like `fork_tools`, a fork profile is a caller-selected restriction rather than an administrator sandbox. Its optional prompt guidance is project-controlled content.
73
+
41
74
  ### How Fork Differs from Named Subagents
42
75
 
43
- | | Named Subagent | Fork Subagent |
44
- | ------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
45
- | Context | Starts fresh with no parent conversation history | Inherits all parent history by default; `fork_turns` can select a bounded recent window |
46
- | System prompt | Uses its own configured prompt | Uses parent's exact system prompt (for cache sharing) |
47
- | Tools | Configured declaration set | Keeps the parent-derived declaration set; `fork_tools` can independently narrow execution without changing that set |
48
- | Execution | Background by default; supports an explicit foreground opt-out | Always detached; parent continues immediately |
49
- | Use case | Specialized tasks (testing, docs) | Parallel tasks that need the current context |
76
+ | | Named Subagent | Fork Subagent |
77
+ | ------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
78
+ | Context | Starts fresh with no parent conversation history | Inherits all parent history by default; `fork_turns` can select a bounded recent window |
79
+ | System prompt | Uses its own configured prompt | Uses parent's exact system prompt (for cache sharing) |
80
+ | Tools | Configured declaration set without interactive question tools | Keeps the parent-derived declaration set for caching; execution always rejects `ask_user_question`, and `fork_tools` or `fork_profile` can independently narrow it without changing that declaration |
81
+ | Execution | Background by default; supports an explicit foreground opt-out | Always detached; parent continues immediately |
82
+ | Use case | Specialized tasks (testing, docs) | Parallel tasks that need the current context |
50
83
 
51
84
  ### When Fork is Used
52
85
 
@@ -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: 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.
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 `Ctrl+O` expanded detail mode, 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
 
@@ -18,11 +18,11 @@ In the main transcript, a completed collapsible batch folds into a single labele
18
18
  ╰──────────────────────────────────────────────╯
19
19
  ```
20
20
 
21
- The full per-tool output is a keystroke away: press `Ctrl+O` to open the full-detail transcript.
21
+ The full per-tool output is a keystroke away: press `Ctrl+O` to toggle expanded detail mode.
22
22
 
23
- ### Full-detail transcript (`Ctrl+O`) and force-expanded groups
23
+ ### Expanded detail mode (`Ctrl+O`) and force-expanded groups
24
24
 
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:
25
+ When a group is force-expanded — in `Ctrl+O` expanded detail mode, 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:
26
26
 
27
27
  ```
28
28
  ╭──────────────────────────────────────────────╮
@@ -122,7 +122,7 @@ These settings can be configured in `settings.json`:
122
122
 
123
123
  Three points that tend to trip up a first read of this feature:
124
124
 
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.
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. Toggling `Ctrl+O` expanded detail mode afterwards does **not** trigger a new call — both the collapsed and the expanded rendering read from the same `tool_use_summary` history entry that was captured the first time.
126
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.
127
127
  3. **Main-agent batches only.** The trigger lives in the main session's turn loop (`useGeminiStream`), so:
128
128
  - ✅ Shell, MCP, file operations, and the `Task` / subagent tool _call itself_ (as it appears in the main batch) are summarized.
@@ -132,7 +132,7 @@ Three points that tend to trip up a first read of this feature:
132
132
 
133
133
  ## Display behavior
134
134
 
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.
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 toggle expanded detail mode, where each tool renders individually with the summary as a trailing `● <label>` line below the group.
136
136
 
137
137
  ```json
138
138
  {
@@ -170,5 +170,5 @@ If you do not want the extra cost, turn the feature off via `experimental.emitTo
170
170
 
171
171
  ## Related
172
172
 
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.
173
+ - [Expanded detail mode](../configuration/settings#ui) — press `Ctrl+O` to expand all tool outputs inline; the summary replaces the generic tool-group header for completed groups in the main view.
174
174
  - [Followup Suggestions](./followup-suggestions) — another fast-model-driven UX enhancement that shares the same `fastModel` setting.
@@ -388,10 +388,11 @@ Notes:
388
388
  | `--require-auth` | `false` | Refuse to start without a bearer token, even on loopback. Hardens the `127.0.0.1` developer default for shared dev hosts / CI runners / multi-tenant workstations where any local user can hit the listener. Boots only with `--token` or `QWEN_SERVER_TOKEN` set; gates `/health` behind the bearer too. |
389
389
  | `--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. |
390
390
  | `--tls-key <path>` | — | Path to a PEM private key file. Must be paired with `--tls-cert`. |
391
- | `--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). |
391
+ | `--max-sessions <n>` | `32` | 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). |
392
392
  | `--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 with several startup/restored workspaces, the daemon derives a fixed cap from the per-workspace limit and the startup workspace count; later dynamic registration does not recompute it. |
393
393
  | `--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. |
394
394
  | `--workspace <path>` | `process.cwd()` | Absolute workspace directory 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 values are rejected. Session requests whose canonical `cwd` is not registered return `400 workspace_mismatch`. |
395
+ | `--memory-project-scope <mode>` | `git-root` | Project-memory partitioning mode. `git-root` (default) shares memory among workspaces resolved to the same Git root; `workspace` keys memory by the exact registered workspace directory so each daemon workspace gets its own isolated memory. Overrides `QWEN_CODE_MEMORY_PROJECT_SCOPE` when provided; an unrecognized env value is ignored with a one-time warning and falls back to `git-root`. Switching to `workspace` does not migrate existing git-root project memory — those entries stop being visible until you switch back. |
395
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. |
396
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. |
397
398
  | `--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`. |
@@ -406,6 +407,25 @@ Notes:
406
407
  | `--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). |
407
408
  | `--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. |
408
409
 
410
+ > **Memory project scope caveats.**
411
+ >
412
+ > - **Daemon vs. standalone CLI.** `--memory-project-scope` (and
413
+ > `QWEN_CODE_MEMORY_PROJECT_SCOPE`) only affects daemon-managed runtimes.
414
+ > A standalone `qwen` TUI started in the same directory still uses the
415
+ > git-root scope unless the environment variable is exported globally. To keep
416
+ > both entry points consistent, pin the scope in the workspace `.env` or
417
+ > `settings.env` so every process that reads the workspace agrees.
418
+ > - **Directory-name collisions.** The storage key is derived by
419
+ > `sanitizeCwd`, which replaces every non-alphanumeric character with
420
+ > `-`. Sibling directories that differ only in punctuation (e.g.
421
+ > `feature_1` and `feature-1`) map to the same memory directory even
422
+ > under `workspace` scope. Avoid such naming when relying on workspace
423
+ > isolation.
424
+ > - **Normalization differs between flag and env var.** The environment variable
425
+ > is trimmed and lowercased (`" Workspace "` works); the CLI flag is
426
+ > matched case-sensitively by yargs `choices` (`--memory-project-scope
427
+ Workspace` is rejected). Use lowercase values when copying between the two.
428
+
409
429
  > **Sizing the load knobs.** `--max-sessions` is the per-workspace fresh-session cap. `--max-total-sessions`, when set, is the daemon-wide fresh-session cap.
410
430
  > Three other layers also limit load — when sizing for a high-concurrency
411
431
  > deployment, tune them together:
@@ -10,7 +10,7 @@ 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` | 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. |
13
+ | `Ctrl+O` | Toggle expanded detail mode: expand or collapse all thinking blocks and tool outputs inline. Press again to collapse. When `ui.useTerminalBuffer` is off, toggling redraws the full conversation with untruncated output into terminal scrollback. |
14
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). |
@@ -45,7 +45,7 @@ This document lists the available keyboard shortcuts in Qwen Code.
45
45
  | `Ctrl+Y` | Retry the last failed request. |
46
46
  | `Ctrl+Right Arrow` / `Meta+Right Arrow` / `Meta+F` | Move the cursor one word to the right. |
47
47
  | `Ctrl+U` | Delete from the cursor to the beginning of the line. |
48
- | `Ctrl+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. |
48
+ | `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. |
49
49
  | `Ctrl+W` / `Meta+Backspace` / `Ctrl+Backspace` | Delete the word to the left of the cursor. |
50
50
  | `Ctrl+X` | Open the current input in an external editor. |
51
51
 
@@ -71,23 +71,23 @@ This document lists the available keyboard shortcuts in Qwen Code.
71
71
 
72
72
  Active when `ui.useTerminalBuffer` is enabled (Settings → UI → Virtualized History), screen reader mode is off, and Qwen Code is running in a compatible interactive terminal (`stdout` is a TTY, CI is inactive, and `TERM` is not `dumb`), which is the default for ordinary non-screen-reader sessions. In that mode conversation history is rendered inside an in-app viewport instead of the host terminal scrollback, so the keys below replace the terminal's native scroll.
73
73
 
74
- | Shortcut | Description |
75
- | --------------- | ---------------------------------------------------- |
76
- | `Shift+Up` | Scroll history up one line. |
77
- | `Shift+Down` | Scroll history down one line. |
78
- | `PgUp` | Scroll history up one page (viewport height). |
79
- | `PgDn` | Scroll history down one page (viewport height). |
80
- | `Ctrl+Home` | Jump to the top of the conversation. |
81
- | `Ctrl+End` | Jump to the bottom (and re-engage live auto-follow). |
82
- | **Mouse wheel** | Scroll history (3 lines per tick). |
74
+ | Shortcut | Description |
75
+ | --------------- | ------------------------------------------------------------------------------- |
76
+ | `Shift+Up` | Scroll history up one line. |
77
+ | `Shift+Down` | Scroll history down one line. |
78
+ | `PgUp` | Scroll history up one page (viewport height). |
79
+ | `PgDn` | Scroll history down one page (viewport height). |
80
+ | `Ctrl+Home` | Jump to the top of the conversation. |
81
+ | `Ctrl+End` | Jump to the bottom (and re-engage live auto-follow). |
82
+ | **Mouse wheel** | Scroll history (3 lines per tick). Requires `ui.mouseTracking` (on by default). |
83
83
 
84
- When `ui.useTerminalBuffer` is on, the terminal forwards mouse events to qwen-code so the wheel can drive the in-app viewport. As a side effect, native click-and-drag text selection is consumed by the program, so qwen-code provides its own: **drag to select text in the history viewport, double-click to select a word, triple-click to select a line.** The selection is highlighted and copied to the clipboard when you release the mouse (works locally, over SSH via OSC 52, and inside tmux). A single click clears the selection; scrolling or new output clears it too. Selection is limited to the visible viewport for now. You can still fall back to the terminal's own selection by holding `Shift` (or `Option` on macOS Terminal / iTerm) while dragging.
84
+ When `ui.useTerminalBuffer` is on and `ui.mouseTracking` is enabled (the default), the terminal forwards mouse events to qwen-code so the wheel can drive the in-app viewport. As a side effect, native click-and-drag text selection is consumed by the program, so qwen-code provides its own: **drag to select text in the history viewport, double-click to select a word, triple-click to select a line.** The selection is highlighted and copied to the clipboard when you release the mouse (works locally, over SSH via OSC 52, and inside tmux). A single click clears the selection; scrolling or new output clears it too. Selection is limited to the visible viewport for now. You can still fall back to the terminal's own selection by holding `Shift` (or `Option` on macOS Terminal / iTerm) while dragging. Set `ui.mouseTracking` to `false` to stop qwen-code from capturing the mouse entirely; that restores the terminal's native right-click menu, OSC 8 hyperlink clicks, and click-and-drag selection, but the in-app viewport no longer responds to the mouse, so use the keyboard shortcuts above to scroll.
85
85
 
86
86
  ### tmux trackpad scrolling
87
87
 
88
88
  Inside tmux, some terminals translate trackpad or wheel gestures into plain `Up Arrow` and `Down Arrow` sequences before qwen-code sees them. Those bytes are identical to real arrow-key presses, so qwen-code cannot tell whether you meant to scroll the viewport or navigate prompt history.
89
89
 
90
- If trackpad scrolling changes the prompt history in tmux, make sure `ui.useTerminalBuffer` is enabled; then use `Shift+Up` / `Shift+Down`, or the mouse wheel when tmux forwards wheel events to the app. If you prefer host scrollback, adjust your tmux mouse bindings for wheel events.
90
+ If trackpad scrolling changes the prompt history in tmux, make sure `ui.useTerminalBuffer` is enabled; then use `Shift+Up` / `Shift+Down`, or the mouse wheel when tmux forwards wheel events to the app (requires `ui.mouseTracking`). If you prefer host scrollback, adjust your tmux mouse bindings for wheel events.
91
91
 
92
92
  ## IDE Integration
93
93
 
@@ -100,7 +100,12 @@ This guide provides solutions to common issues and debugging tips, including top
100
100
  - **Trackpad scrolling in tmux changes prompt history instead of scrolling the conversation**
101
101
  - **Issue:** In a tmux session, trackpad or wheel scrolling may cycle through previous prompts, similar to pressing `Up Arrow` or `Down Arrow`.
102
102
  - **Cause:** tmux can translate wheel gestures into plain arrow-key sequences. Those sequences are indistinguishable from real arrow-key presses by the time qwen-code receives them.
103
- - **Solution:** If screen reader mode is disabled, make sure `ui.useTerminalBuffer` is enabled; then use `Shift+Up` / `Shift+Down`, or the mouse wheel when tmux forwards wheel events to the app. If you prefer host scrollback, adjust your tmux mouse bindings for wheel events.
103
+ - **Solution:** If screen reader mode is disabled, make sure `ui.useTerminalBuffer` is enabled; then use `Shift+Up` / `Shift+Down`, or the mouse wheel when tmux forwards wheel events to the app (requires `ui.mouseTracking`). If you prefer host scrollback, adjust your tmux mouse bindings for wheel events.
104
+
105
+ - **Right-click does nothing, links do not open, or text cannot be selected in the terminal**
106
+ - **Issue:** Native right-click context menus, OSC 8 hyperlink clicks (Ctrl+Click or plain click on URLs), and terminal-native text selection stop working while Qwen Code is running.
107
+ - **Cause:** When `ui.mouseTracking` is enabled (the default), Qwen Code captures all mouse events via SGR mouse tracking to power in-app text selection, click-to-position, row hover, and viewport scrolling. The terminal forwards every mouse event to the app instead of handling it natively.
108
+ - **Solution:** Set `"ui.mouseTracking": false` in your `settings.json` to restore native right-click menus and clickable URL links. This turns off all in-app mouse interaction. In Virtualized History (`ui.useTerminalBuffer: true`, the default), the wheel will no longer scroll the transcript — use `Shift+↑/↓`, `PgUp/PgDn`, or `Ctrl+Home/End` instead. To also restore native terminal scrollback, set `"ui.useTerminalBuffer": false`. Requires restart.
104
109
 
105
110
  ## IDE Companion not connecting
106
111