@qwen-code/qwen-code 0.21.1 → 0.21.2-nightly.20260801.bc382c3ff

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 (367) hide show
  1. package/bundled/qc-helper/docs/configuration/settings.md +9 -7
  2. package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
  3. package/bundled/qc-helper/docs/features/channels/github.md +49 -10
  4. package/bundled/qc-helper/docs/features/channels/gitlab.md +177 -0
  5. package/bundled/qc-helper/docs/features/code-review.md +20 -0
  6. package/bundled/qc-helper/docs/features/commands.md +1 -0
  7. package/bundled/qc-helper/docs/features/hooks.md +135 -18
  8. package/bundled/qc-helper/docs/features/memory.md +27 -0
  9. package/bundled/qc-helper/docs/features/skills.md +14 -0
  10. package/bundled/qc-helper/docs/features/sub-agents.md +55 -8
  11. package/bundled/qc-helper/docs/features/tool-use-summaries.md +7 -7
  12. package/bundled/qc-helper/docs/qwen-serve.md +28 -6
  13. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +2 -2
  14. package/bundled/review/SKILL.md +1 -1
  15. package/chunks/{MaxSizedBox-VI3ROJJA.js → MaxSizedBox-CDHTDITS.js} +45 -40
  16. package/chunks/{StandaloneSessionPicker-LYXKD2EV.js → StandaloneSessionPicker-L63HUAHP.js} +65 -60
  17. package/chunks/{acp-startup-profiler-DFVPFQ6C.js → acp-startup-profiler-3RICG2YW.js} +2 -2
  18. package/chunks/{acpAgent-WN5SRDQO.js → acpAgent-6WVVT2P3.js} +962 -599
  19. package/chunks/{agent-K6ECSM64.js → agent-KDM4CBOU.js} +40 -35
  20. package/chunks/agent-headless-AS7K2K57.js +79 -0
  21. package/chunks/{anthropicContentGenerator-V2QOGVYD.js → anthropicContentGenerator-WCBYB6JG.js} +337 -27
  22. package/chunks/{artifact-tool-6K6U7XYJ.js → artifact-tool-ANV4CFCR.js} +2 -2
  23. package/chunks/{askUserQuestion-GD2IJJ7I.js → askUserQuestion-MALEB47H.js} +2 -2
  24. package/chunks/{bridge-3KJEWDNE.js → bridge-JNEW6FES.js} +46 -41
  25. package/chunks/{build-S6DO7LMM.js → build-GDBLPA24.js} +1 -1
  26. package/chunks/{ca-6W3SK7OQ.js → ca-4OJN75WT.js} +46 -5
  27. package/chunks/{channel-management-service-XR7GZSWF.js → channel-management-service-QOO7TD3T.js} +21 -6
  28. package/chunks/{channel-settings-store-HW4FXXUA.js → channel-settings-store-4CSMTR4L.js} +47 -42
  29. package/chunks/{channel-worker-group-XDPTDWTX.js → channel-worker-group-ERSUOPIR.js} +8 -8
  30. package/chunks/{channel-worker-manager-YYEHVRRE.js → channel-worker-manager-X247YDQ7.js} +8 -8
  31. package/chunks/{channel-worker-supervisor-74HTWA2G.js → channel-worker-supervisor-ORJIEEPP.js} +4 -4
  32. package/chunks/{chunk-VWOOBLTY.js → chunk-25QQVOCG.js} +5 -5
  33. package/chunks/{chunk-CAPPWD3X.js → chunk-2A6MHYIA.js} +3 -3
  34. package/chunks/{chunk-2XSLTRFZ.js → chunk-2CTKGIFR.js} +2 -2
  35. package/chunks/{chunk-DZLYR4U3.js → chunk-2DNKEBXY.js} +1 -1
  36. package/chunks/{chunk-UWMLWVCA.js → chunk-2IIJTXYF.js} +26 -10
  37. package/chunks/{chunk-JYBU6YUE.js → chunk-2M5N3DHY.js} +1 -1
  38. package/chunks/{chunk-AQIDMUGU.js → chunk-2PNQQ4UR.js} +2 -2
  39. package/chunks/{chunk-OKF7JF3R.js → chunk-2UISUFHQ.js} +3 -3
  40. package/chunks/{chunk-2LQTH543.js → chunk-33FNCQSY.js} +2 -2
  41. package/chunks/{chunk-M7OONWYU.js → chunk-3LGZEYOF.js} +4 -2
  42. package/chunks/{chunk-ZURDMIDR.js → chunk-3MHPWQ2M.js} +242 -76
  43. package/chunks/{chunk-UHUSJ6X7.js → chunk-3RXUYQJI.js} +25 -6
  44. package/chunks/{chunk-E5Z2AVNV.js → chunk-3SH53ANB.js} +0 -11
  45. package/chunks/{chunk-BNWB5CYE.js → chunk-3WXMXT7C.js} +22 -11
  46. package/chunks/{chunk-A2D5BAVP.js → chunk-42IKVPST.js} +1 -1
  47. package/chunks/{chunk-2DN4J57Y.js → chunk-432XCUHF.js} +1 -1
  48. package/chunks/{chunk-EVKE2FZL.js → chunk-433VD3HX.js} +4 -4
  49. package/chunks/{chunk-Q43KPN7X.js → chunk-434YCHSV.js} +6 -6
  50. package/chunks/{chunk-5TBMQLGG.js → chunk-4LKVQFHM.js} +2 -2
  51. package/chunks/{chunk-YDLJGZHL.js → chunk-4NFY2S7N.js} +0 -33
  52. package/chunks/{chunk-6PE7N3A4.js → chunk-5UJ6A3CH.js} +145 -10
  53. package/chunks/{chunk-GNR2RNMP.js → chunk-5UZITEHA.js} +3 -3
  54. package/chunks/chunk-6FMJLI5M.js +1591 -0
  55. package/chunks/{chunk-RPLGZJV2.js → chunk-6O5DVH27.js} +1 -1
  56. package/chunks/{chunk-2RFKHEXL.js → chunk-6PLDPT2C.js} +1 -1
  57. package/chunks/{chunk-7AEJDLRA.js → chunk-7IYLHTTM.js} +3 -3
  58. package/chunks/{chunk-65PQENQP.js → chunk-7K2WTPQO.js} +5 -5
  59. package/chunks/{chunk-P4WOAOJW.js → chunk-7MY2AR5A.js} +72 -26
  60. package/chunks/{chunk-GXIJHV66.js → chunk-A2A34TSB.js} +3 -3
  61. package/chunks/{chunk-XWWKIXVD.js → chunk-A5YZ3FA2.js} +2 -1
  62. package/chunks/{chunk-64LQLPL7.js → chunk-A6SX5TAH.js} +3 -3
  63. package/chunks/{chunk-SZ3KHTDR.js → chunk-AKA24BGO.js} +1 -1
  64. package/chunks/chunk-AQ37AY7B.js +93 -0
  65. package/chunks/{chunk-2N7CODY5.js → chunk-AQEWCKX4.js} +2 -2
  66. package/chunks/{chunk-KCO4FLFJ.js → chunk-AYB4HSBI.js} +3 -3
  67. package/chunks/{chunk-WZRWHXFE.js → chunk-BFHXDAR7.js} +1 -1
  68. package/chunks/{chunk-L55JWS76.js → chunk-BGXZBI5B.js} +1 -1
  69. package/chunks/{chunk-5MKRTI4T.js → chunk-BKUN5QHP.js} +7 -7
  70. package/chunks/{chunk-Y4IHBGBP.js → chunk-BV4QX43X.js} +1 -1
  71. package/chunks/{chunk-PB3MBFKG.js → chunk-C4L2MEIT.js} +4 -4
  72. package/chunks/{chunk-TCIFAA7K.js → chunk-CHCLO3M7.js} +14 -14
  73. package/chunks/{chunk-CVHIL5IG.js → chunk-CWEIMFFW.js} +13 -6
  74. package/chunks/{chunk-2FAK6PNM.js → chunk-DUIJ2IXG.js} +5 -13
  75. package/chunks/{chunk-T2QMKU3R.js → chunk-DVGTU5TC.js} +19 -7
  76. package/chunks/{chunk-LGAOC3ZS.js → chunk-DYA25Y7U.js} +1 -1
  77. package/chunks/{chunk-SGFT55XI.js → chunk-E4WHKETF.js} +32 -4
  78. package/chunks/{chunk-WBL3FJEU.js → chunk-FC4KQFCS.js} +1 -1
  79. package/chunks/{chunk-MHAIJPTD.js → chunk-FJHA23GM.js} +12 -12
  80. package/chunks/{chunk-S7W2GKIO.js → chunk-G7XXKQYS.js} +2 -0
  81. package/chunks/{chunk-MR5EAQ5M.js → chunk-GALUTA2C.js} +1 -1
  82. package/chunks/{chunk-7I5GTCT4.js → chunk-GB3AB7TR.js} +4008 -3648
  83. package/chunks/{chunk-QIZKCVM3.js → chunk-GHJM2C2T.js} +6 -8
  84. package/chunks/chunk-GOFAQQZA.js +132 -0
  85. package/chunks/{chunk-BCZFQXWK.js → chunk-GTM6IHBB.js} +2 -2
  86. package/chunks/{chunk-5ZF5XXTS.js → chunk-GVISB2OH.js} +2 -2
  87. package/chunks/{chunk-FNMZK765.js → chunk-H36SETQS.js} +1 -1
  88. package/chunks/{chunk-UBEPNVDI.js → chunk-H4346YW5.js} +28 -16
  89. package/chunks/{chunk-CQL64ESB.js → chunk-H4DSRWAS.js} +24 -13
  90. package/chunks/{chunk-YGF33UXG.js → chunk-H6MC6VQX.js} +222 -173
  91. package/chunks/{chunk-GZXCZHCT.js → chunk-I3G5JWBV.js} +1 -1
  92. package/chunks/{chunk-Y6AXW2OG.js → chunk-I5GNT6ZS.js} +7 -1
  93. package/chunks/{chunk-GEBV2JGB.js → chunk-I6FAHB4N.js} +1 -1
  94. package/chunks/{chunk-UPUG4GXM.js → chunk-I7JDGNG6.js} +3 -3
  95. package/chunks/{chunk-JHNRZMHI.js → chunk-II6WPWHY.js} +9 -9
  96. package/chunks/{chunk-B4AJNNOL.js → chunk-J26HHFI5.js} +1 -1
  97. package/chunks/{chunk-S3TWXGKA.js → chunk-JE7KQ2UP.js} +4 -2
  98. package/chunks/{chunk-ZHBO7WVX.js → chunk-JELIWHXD.js} +1 -1
  99. package/chunks/{chunk-3EFXSQCM.js → chunk-JRIDA5HF.js} +7 -7
  100. package/chunks/{chunk-TFRMVU6R.js → chunk-K4CGQN4Q.js} +1 -1
  101. package/chunks/{chunk-WUZ7H6DP.js → chunk-K5Q62CGR.js} +1 -1
  102. package/chunks/{chunk-JCW2R7WC.js → chunk-K623ENWT.js} +3 -79
  103. package/chunks/{chunk-T2NCM2ET.js → chunk-K6KS3LTN.js} +2 -749
  104. package/chunks/{chunk-TDL6LB4K.js → chunk-KG22G46Y.js} +22 -10
  105. package/chunks/{chunk-GATT5TKW.js → chunk-KKN2IE7Q.js} +1 -1
  106. package/chunks/{chunk-JMONIXMJ.js → chunk-KVUBYJDM.js} +2 -2
  107. package/chunks/{chunk-TBBV36Y4.js → chunk-KXSYDCP2.js} +4 -4
  108. package/chunks/{chunk-EIF3FXTB.js → chunk-LAPK3GLC.js} +121 -18
  109. package/chunks/chunk-LBOVL47Y.js +29 -0
  110. package/chunks/{chunk-U3E3UQAA.js → chunk-LBWNSLJK.js} +4 -4
  111. package/chunks/{chunk-S4WJVPZW.js → chunk-LL4U3BSH.js} +15 -7
  112. package/chunks/{chunk-657BH7VM.js → chunk-LRJWFR6L.js} +4 -4
  113. package/chunks/{chunk-PT722TDT.js → chunk-M2F5PLOW.js} +770 -125
  114. package/chunks/{chunk-3L2SPEBH.js → chunk-M744OFVE.js} +1 -1
  115. package/chunks/{chunk-VYOXCEPJ.js → chunk-MBKPUM5Y.js} +1 -1
  116. package/chunks/chunk-MISUEWB4.js +8749 -0
  117. package/chunks/{chunk-PONHVBRT.js → chunk-MOHAWIAW.js} +2 -2
  118. package/chunks/{chunk-HMRM2A3U.js → chunk-MSIVKDRC.js} +4 -4
  119. package/chunks/{record-artifact-XAMSFSW4.js → chunk-MYT7N6QH.js} +22 -7
  120. package/chunks/{chunk-X5WNMMIA.js → chunk-NGWYUZZO.js} +11510 -15137
  121. package/chunks/{chunk-PQNHRFJC.js → chunk-NYX53SV4.js} +0 -2
  122. package/chunks/{chunk-6RPMI2AB.js → chunk-NZB4NDJL.js} +10 -10
  123. package/chunks/{chunk-BGTQCTQW.js → chunk-O2ZYHG33.js} +6 -5
  124. package/chunks/chunk-O6GEWCJA.js +21 -0
  125. package/chunks/{chunk-JX27F6QS.js → chunk-OBAIHYFT.js} +1 -1
  126. package/chunks/{chunk-BPZKP57P.js → chunk-OCRM53TT.js} +3 -3
  127. package/chunks/{chunk-V7RNNPGC.js → chunk-P5Y23G2L.js} +18 -1
  128. package/chunks/{chunk-FTD6DP4T.js → chunk-PDDYAXL2.js} +5 -1
  129. package/chunks/{chunk-JSD33JG6.js → chunk-PGEGUNH5.js} +67 -10
  130. package/chunks/{chunk-A4COXFB3.js → chunk-PGP7Y3RQ.js} +5 -5
  131. package/chunks/{chunk-T3O2B4XO.js → chunk-PHODQP2V.js} +6 -6
  132. package/chunks/{chunk-BMFALVGQ.js → chunk-PXA5AWHY.js} +1 -1
  133. package/chunks/chunk-QL4TN4HS.js +59 -0
  134. package/chunks/{chunk-W4MIWP6M.js → chunk-QMBEW7EW.js} +2 -2
  135. package/chunks/{chunk-U4VTUMMK.js → chunk-QONSRAEV.js} +1 -1
  136. package/chunks/{chunk-LW3RFMG7.js → chunk-QYPT3QUD.js} +3 -3
  137. package/chunks/{chunk-TV64SXKD.js → chunk-RGJ4JWSU.js} +131 -48
  138. package/chunks/{chunk-75MIQ3LV.js → chunk-RPYYTL7E.js} +61 -13
  139. package/chunks/{chunk-52ZSWYEG.js → chunk-SK2UKB45.js} +1 -1
  140. package/chunks/{chunk-PLDQBIO6.js → chunk-SWEBEXPI.js} +1 -1
  141. package/chunks/chunk-T3CHYWJZ.js +758 -0
  142. package/chunks/{chunk-VCPIZRYH.js → chunk-TFFMATHX.js} +9 -7
  143. package/chunks/{chunk-J7OACQDE.js → chunk-TNVKFQXQ.js} +458 -97
  144. package/chunks/{chunk-A3NDJ5SB.js → chunk-TYERNYH4.js} +2 -2
  145. package/chunks/{chunk-GKX7E4CO.js → chunk-U25CMJYY.js} +1 -1
  146. package/chunks/{chunk-7XATOOE7.js → chunk-UH7Z7Y45.js} +1 -1
  147. package/chunks/{chunk-XFZYFU3I.js → chunk-UHQ3L6GC.js} +1 -1
  148. package/chunks/{chunk-GZ3RCT54.js → chunk-UHTJC7O3.js} +1 -1
  149. package/chunks/{chunk-XZC5VLBZ.js → chunk-UKZEXS6K.js} +6 -0
  150. package/chunks/{chunk-LO4ROVP4.js → chunk-UOFFZNXV.js} +111 -13
  151. package/chunks/{chunk-5YKDXHUY.js → chunk-URN76TKR.js} +2 -2
  152. package/chunks/{chunk-T4TXDL7G.js → chunk-UWLG4UCE.js} +132 -35
  153. package/chunks/{chunk-KAMYKP7E.js → chunk-UWSXFI6E.js} +1 -1
  154. package/chunks/{chunk-7BAU433D.js → chunk-VS3GXRNZ.js} +1198 -240
  155. package/chunks/{chunk-EJGJIBRS.js → chunk-VWF42XC6.js} +3 -3
  156. package/chunks/{chunk-RCUQIPTN.js → chunk-W7XZ3KP5.js} +1 -1
  157. package/chunks/{chunk-OCESJA77.js → chunk-WISQLM4Q.js} +1197 -1154
  158. package/chunks/{chunk-NOKIVHOL.js → chunk-WK4TJUEA.js} +1 -1
  159. package/chunks/{chunk-JFMA7Y5M.js → chunk-WP4HGHFG.js} +5 -5
  160. package/chunks/{chunk-4G2BISNC.js → chunk-XC2VAFVZ.js} +1 -1
  161. package/chunks/{chunk-2LKVPASC.js → chunk-XC656O42.js} +3 -3
  162. package/chunks/{chunk-5KTQXHPY.js → chunk-XCLLRKY5.js} +3 -3
  163. package/chunks/{chunk-HV26XH34.js → chunk-XFDPIC4P.js} +3 -3
  164. package/chunks/{chunk-JTV5K7NH.js → chunk-XSA5EKTJ.js} +1 -1
  165. package/chunks/{chunk-75GFAX4R.js → chunk-YAVY33G4.js} +1 -1
  166. package/chunks/{chunk-WBSMNTSV.js → chunk-YXEVDA66.js} +2 -2
  167. package/chunks/{chunk-7DXQIJID.js → chunk-ZRFJ75D7.js} +3 -3
  168. package/chunks/{chunk-XBYYDKAZ.js → chunk-ZTN6OA5J.js} +8 -7
  169. package/chunks/{computer-use-ZTIDHMMA.js → computer-use-Z4NCIIJN.js} +40 -35
  170. package/chunks/{config-utils-NYSXDMEQ.js → config-utils-64LM6OEQ.js} +4 -4
  171. package/chunks/{contextCommand-2PIEU37Z.js → contextCommand-HVM7XFCB.js} +43 -38
  172. package/chunks/{core-runtime-3XEYLQFK.js → core-runtime-NL3ZBHBU.js} +40 -35
  173. package/chunks/{create-sub-session-SBYUMSSS.js → create-sub-session-AM32K2HD.js} +2 -2
  174. package/chunks/{create-sub-session-R76FVXCI.js → create-sub-session-XHSCDYFU.js} +43 -38
  175. package/chunks/{cron-create-2QK6TCEC.js → cron-create-HPXYE6C5.js} +4 -4
  176. package/chunks/{cron-delete-FDCDFYMG.js → cron-delete-FPVNTKPK.js} +4 -4
  177. package/chunks/{cron-list-XN3WVBTP.js → cron-list-ZEI6PAAV.js} +4 -4
  178. package/chunks/{daemon-Q2AB5Z23.js → daemon-PCNCI5YU.js} +72 -3
  179. package/chunks/daemon-status-provider-XD23SNAM.js +94 -0
  180. package/chunks/{daemon-trust-policy-ILUDTLHD.js → daemon-trust-policy-NOHK7IW5.js} +46 -41
  181. package/chunks/{daemon-trust-policy-monitor-HS3PKKRO.js → daemon-trust-policy-monitor-ZBTSR333.js} +46 -41
  182. package/chunks/{de-SY6O76BF.js → de-A6TI4LBB.js} +46 -5
  183. package/chunks/{deferred-core-runtime-X4QV662U.js → deferred-core-runtime-JJBHKM2C.js} +40 -35
  184. package/chunks/{dist-HVRQ2CFL.js → dist-4LAMY2SK.js} +1180 -5
  185. package/chunks/{dist-DOLYHMXE.js → dist-4T4NCJFL.js} +2 -2
  186. package/chunks/dist-7KOL6OMD.js +13467 -0
  187. package/chunks/{dist-SSU66DM4.js → dist-BH76AT7N.js} +1 -1
  188. package/chunks/{dist-BSTVRPMT.js → dist-BXA3JXVQ.js} +541 -19
  189. package/chunks/{dist-SV7Q3AWJ.js → dist-OEEFI6UU.js} +12 -9
  190. package/chunks/{dist-YGBBMK3Z.js → dist-SMLVOWKV.js} +5 -4
  191. package/chunks/{dist-IXQEQWRG.js → dist-V2RK6S6Q.js} +1 -1
  192. package/chunks/{earlyInputCapture-XKLZT7ZD.js → earlyInputCapture-KLAZDAIP.js} +41 -36
  193. package/chunks/{edit-HHGIOTQ2.js → edit-YQZWCISX.js} +40 -35
  194. package/chunks/{en-NBK3JKCE.js → en-RESOFG55.js} +46 -5
  195. package/chunks/{enter-worktree-ZN7PUQ46.js → enter-worktree-WLVWI3FP.js} +40 -35
  196. package/chunks/{enterPlanMode-EIFIDSIV.js → enterPlanMode-6RYXFQUD.js} +40 -35
  197. package/chunks/{environment-XXQ75D2Q.js → environment-DXJTXSVT.js} +43 -38
  198. package/chunks/{errors-4GMVU7CK.js → errors-XGAGG2S2.js} +43 -38
  199. package/chunks/{exit-worktree-GXMI4ATY.js → exit-worktree-C4276VPP.js} +40 -35
  200. package/chunks/{exitPlanMode-34UVY7M6.js → exitPlanMode-MM5HIRUF.js} +40 -35
  201. package/chunks/{fast-path-VPIVA7L6.js → fast-path-PIXYOHCH.js} +6 -2
  202. package/chunks/{fr-4KG5V7UT.js → fr-QF7RI5ZE.js} +46 -5
  203. package/chunks/{gemini-4BWIK4WD.js → gemini-43RLVUNP.js} +158 -96
  204. package/chunks/{geminiContentGenerator-3XVV5MSS.js → geminiContentGenerator-PNQ4TSID.js} +6 -6
  205. package/chunks/{glob-TZ2ABCJG.js → glob-ZMBQKAU5.js} +40 -35
  206. package/chunks/goal-tools-Y767F7LZ.js +335 -0
  207. package/chunks/{grep-BEF463NA.js → grep-HSV37W2Q.js} +40 -35
  208. package/chunks/handleAutoUpdate-QDHZPBAY.js +85 -0
  209. package/chunks/{i18n-FMM5FDXR.js → i18n-ME22A6RN.js} +42 -37
  210. package/chunks/{image-gen-HHVLF7HS.js → image-gen-IFC7ZWSB.js} +9 -9
  211. package/chunks/{initializer-625TIAIO.js → initializer-J7H2CHVB.js} +47 -42
  212. package/chunks/{installationInfo-6AM4I2Y3.js → installationInfo-R7FXPQN5.js} +41 -36
  213. package/chunks/{ja-F3GSQXMF.js → ja-URQESVGW.js} +46 -5
  214. package/chunks/{keychain-token-storage-72IYCAZV.js → keychain-token-storage-7BT4TQ2A.js} +2 -2
  215. package/chunks/{kittyProtocolDetector-MBRTDRBK.js → kittyProtocolDetector-BFLAKYXH.js} +1 -1
  216. package/chunks/list-OYDIBA4N.js +93 -0
  217. package/chunks/{list-agents-R6KDXQR3.js → list-agents-GATIBBQQ.js} +2 -2
  218. package/chunks/{loadedSettingsAdapter-SPUTNKAV.js → loadedSettingsAdapter-OK6GK2GE.js} +46 -41
  219. package/chunks/{loggingContentGenerator-LKOF7XI7.js → loggingContentGenerator-U4ZEG4GL.js} +53 -38
  220. package/chunks/{loop-wakeup-3IQKCYAH.js → loop-wakeup-3DZMQQQQ.js} +13 -6
  221. package/chunks/{ls-DKZ37A7N.js → ls-7F4GHXIH.js} +4 -4
  222. package/chunks/{lsp-QNWN7KN3.js → lsp-6FEHVBWI.js} +2 -2
  223. package/chunks/{managed-npm-update-ACQGGIN5.js → managed-npm-update-PGKAJLLO.js} +43 -38
  224. package/chunks/mcp-S4DXJD2G.js +87 -0
  225. package/chunks/{monitor-DF52UVHI.js → monitor-E5ZFMT74.js} +40 -35
  226. package/chunks/nonInteractiveCli-HNOHKEPE.js +149 -0
  227. package/chunks/{notebook-edit-FCWS4XVN.js → notebook-edit-6QDN6VZJ.js} +40 -35
  228. package/chunks/{openaiContentGenerator-7LDK3DCJ.js → openaiContentGenerator-3NLB2C5O.js} +19 -19
  229. package/chunks/{pidfile-6ERW3DF4.js → pidfile-ZMOIUGG6.js} +41 -36
  230. package/chunks/{processUtils-COKZAMUP.js → processUtils-E4QGQVWW.js} +2 -2
  231. package/chunks/{pt-EQ33KWEN.js → pt-EEEQXRUI.js} +46 -5
  232. package/chunks/{qwenContentGenerator-TKWUMR7N.js → qwenContentGenerator-2LFRWJTM.js} +46 -41
  233. package/chunks/{qwenOAuth2-7HMU47SF.js → qwenOAuth2-N32BUQDC.js} +8 -8
  234. package/chunks/{read-file-X6DRC574.js → read-file-GLDCWZBG.js} +11 -11
  235. package/chunks/{read-mcp-resource-GFTWYXMK.js → read-mcp-resource-AFS3UKZO.js} +2 -2
  236. package/chunks/record-artifact-ECZSCEG5.js +21 -0
  237. package/chunks/{resumeHistoryUtils-PFPM2GWM.js → resumeHistoryUtils-F5BE5QDW.js} +48 -43
  238. package/chunks/ripGrep-T23Y4AGY.js +77 -0
  239. package/chunks/{ru-7OZAUKGG.js → ru-WGZDYQAB.js} +46 -5
  240. package/chunks/{run-qwen-serve-TSTCO4XE.js → run-qwen-serve-TI2HGLLU.js} +290 -75
  241. package/chunks/{runtime-DAUPSUKI.js → runtime-WCWM3DO7.js} +53 -46
  242. package/chunks/{scheduler-KMADMT26.js → scheduler-2QZO5AV5.js} +40 -35
  243. package/chunks/{sdk-exporters-http-WO556XNU.js → sdk-exporters-http-IKNWQJNV.js} +3 -3
  244. package/chunks/{sdk-impl-LPAVACSF.js → sdk-impl-7CUUMQDB.js} +3 -3
  245. package/chunks/{send-message-SAWK4DZX.js → send-message-X7G2JSII.js} +6 -11
  246. package/chunks/{serve-NNRWS6F4.js → serve-DZOMYUFU.js} +46 -41
  247. package/chunks/{server-WEH7DVCH.js → server-N4AJRKIQ.js} +2269 -1016
  248. package/chunks/{session-WXC56V2I.js → session-GS6AKMN7.js} +151 -86
  249. package/chunks/{settings-DJDXFDZ3.js → settings-CUN3SELH.js} +50 -45
  250. package/chunks/{shell-JN5VRQXD.js → shell-NGBFVXC5.js} +40 -35
  251. package/chunks/{skill-SGXPKJCS.js → skill-SC2BSO75.js} +30 -16
  252. package/chunks/{skill-settings-VJ5PDMZI.js → skill-settings-XVPCPW5K.js} +45 -40
  253. package/chunks/{spawnChannel-ETMJW7YX.js → spawnChannel-RILO4YY3.js} +42 -37
  254. package/chunks/{standalone-update-MK3Z7KBI.js → standalone-update-TMLT6LVJ.js} +43 -38
  255. package/chunks/{startInteractiveUI-ZCGIXPGT.js → startInteractiveUI-J45WOEOU.js} +883 -1112
  256. package/chunks/{syntheticOutput-355CB6CJ.js → syntheticOutput-FHRY3BPQ.js} +3 -3
  257. package/chunks/{task-create-INGWNUG4.js → task-create-LAQXBIHC.js} +11 -10
  258. package/chunks/{task-list-5XNNGTF4.js → task-list-V6K5DRDH.js} +6 -6
  259. package/chunks/{task-stop-4ROAOBXH.js → task-stop-LQXE52L6.js} +2 -2
  260. package/chunks/{task-update-CRK5VWWZ.js → task-update-NXRCXSPB.js} +11 -10
  261. package/chunks/{team-create-QQGAJG7P.js → team-create-W3EVWCTA.js} +40 -35
  262. package/chunks/{team-delete-S2RCXA4P.js → team-delete-Z4KGO7RC.js} +6 -6
  263. package/chunks/{team-plan-approval-RT7Q5R6O.js → team-plan-approval-URYVKJF4.js} +40 -35
  264. package/chunks/theme-manager-CUAMS2NI.js +81 -0
  265. package/chunks/{todoWrite-7WM3VDMY.js → todoWrite-OFIZDI7P.js} +32 -4
  266. package/chunks/{tool-search-Z3Z4AYKP.js → tool-search-DCICFL32.js} +15 -14
  267. package/chunks/total-session-admission-3ZTAXVUK.js +89 -0
  268. package/chunks/{trustedFolders-X2JEIO57.js → trustedFolders-EVCN36O5.js} +42 -37
  269. package/chunks/{update-relaunch-VWNPYDIP.js → update-relaunch-XLW46RHQ.js} +5 -5
  270. package/chunks/{updateCheck-KAQH67DV.js → updateCheck-ZHVXDAIH.js} +44 -39
  271. package/chunks/{useAutoAcceptIndicator-JH6BCF7S.js → useAutoAcceptIndicator-ZGD6BJSP.js} +50 -45
  272. package/chunks/{validateNonInterActiveAuth-GIUJ2UFS.js → validateNonInterActiveAuth-R3BAQFDY.js} +88 -83
  273. package/chunks/{version-BGLYIJUY.js → version-PMWREGCG.js} +1 -1
  274. package/chunks/{web-fetch-OTDU4VQF.js → web-fetch-PGN27SGF.js} +14 -14
  275. package/chunks/{web-search-FP6SIHPR.js → web-search-KW4UNMRE.js} +8 -8
  276. package/chunks/{workflow-YCIVBYSB.js → workflow-SN3TJBTJ.js} +363 -310
  277. package/chunks/workspace-providers-status-O3HUZGGR.js +90 -0
  278. package/chunks/{workspace-registration-store-OTMS3H4C.js → workspace-registration-store-M3FJ74RS.js} +2 -2
  279. package/chunks/{workspace-registry-O63R6IZ4.js → workspace-registry-U7ISW23N.js} +47 -42
  280. package/chunks/{workspace-service-M6LLHKJ5.js → workspace-service-VH6IWADT.js} +53 -48
  281. package/chunks/{workspace-skills-status-C2V7BAIS.js → workspace-skills-status-XANARSZS.js} +48 -43
  282. package/chunks/{workspace-trust-reconciler-IBUPOUJN.js → workspace-trust-reconciler-35EFR4GC.js} +53 -48
  283. package/chunks/write-file-NCRSGUDT.js +79 -0
  284. package/chunks/{zh-H3YDK5QW.js → zh-OHX23Q44.js} +43 -5
  285. package/chunks/{zh-TW-JYCP7XUA.js → zh-TW-4G7YKDAQ.js} +43 -5
  286. package/chunks/zoom-image-X7CIADYC.js +224 -0
  287. package/cli.js +55 -48
  288. package/locales/ca.js +60 -4
  289. package/locales/de.js +62 -4
  290. package/locales/en.js +59 -4
  291. package/locales/fr.js +64 -4
  292. package/locales/ja.js +61 -4
  293. package/locales/pt.js +60 -4
  294. package/locales/ru.js +63 -4
  295. package/locales/zh-TW.js +52 -4
  296. package/locales/zh.js +52 -4
  297. package/package.json +3 -3
  298. package/web-shell/assets/{arc-75-Wdeo3.js → arc-CaMTqKio.js} +1 -1
  299. package/web-shell/assets/{architectureDiagram-3BPJPVTR-FKeXQbyP.js → architectureDiagram-3BPJPVTR-Bjxztij2.js} +1 -1
  300. package/web-shell/assets/{blockDiagram-GPEHLZMM-CY0vc-A3.js → blockDiagram-GPEHLZMM-BYJzeHi9.js} +1 -1
  301. package/web-shell/assets/{c4Diagram-AAUBKEIU-CNP-A-8u.js → c4Diagram-AAUBKEIU-fYAa-Eil.js} +1 -1
  302. package/web-shell/assets/channel-LEZei0-5.js +1 -0
  303. package/web-shell/assets/{chunk-2J33WTMH-GybS4Gii.js → chunk-2J33WTMH-B1OTlTml.js} +1 -1
  304. package/web-shell/assets/{chunk-4BX2VUAB-02H91V8v.js → chunk-4BX2VUAB-DNj4uy6k.js} +1 -1
  305. package/web-shell/assets/{chunk-55IACEB6-D3M-2VT6.js → chunk-55IACEB6-DAqNmg3c.js} +1 -1
  306. package/web-shell/assets/{chunk-727SXJPM-CCu29u4H.js → chunk-727SXJPM-BwB4ddxE.js} +1 -1
  307. package/web-shell/assets/{chunk-AQP2D5EJ-CaFKWgrn.js → chunk-AQP2D5EJ-DmHR_UZs.js} +1 -1
  308. package/web-shell/assets/{chunk-FMBD7UC4-ZZpPqIwQ.js → chunk-FMBD7UC4-BlfOXumo.js} +1 -1
  309. package/web-shell/assets/{chunk-ND2GUHAM-D22DqGs8.js → chunk-ND2GUHAM-BKogiSy7.js} +1 -1
  310. package/web-shell/assets/{chunk-QZHKN3VN-Bu85S0fw.js → chunk-QZHKN3VN-DEclVrOF.js} +1 -1
  311. package/web-shell/assets/classDiagram-4FO5ZUOK-BiaRhfvf.js +1 -0
  312. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BiaRhfvf.js +1 -0
  313. package/web-shell/assets/{cose-bilkent-S5V4N54A-f1CK1Gwe.js → cose-bilkent-S5V4N54A-CwtS21WT.js} +1 -1
  314. package/web-shell/assets/{dagre-BM42HDAG-D0Ow8F_n.js → dagre-BM42HDAG-BAAIlB4p.js} +1 -1
  315. package/web-shell/assets/{diagram-2AECGRRQ-BPrmTWp8.js → diagram-2AECGRRQ-ChljtF_V.js} +1 -1
  316. package/web-shell/assets/{diagram-5GNKFQAL-HccuFAzy.js → diagram-5GNKFQAL-BIXVd31-.js} +1 -1
  317. package/web-shell/assets/{diagram-KO2AKTUF-BrS76mbA.js → diagram-KO2AKTUF-BEiBaS15.js} +1 -1
  318. package/web-shell/assets/{diagram-LMA3HP47-V7T9lU-5.js → diagram-LMA3HP47-C-g4tWKM.js} +1 -1
  319. package/web-shell/assets/{diagram-OG6HWLK6-DKidyJMR.js → diagram-OG6HWLK6-CNCCbNQG.js} +1 -1
  320. package/web-shell/assets/{erDiagram-TEJ5UH35-DBadZIkp.js → erDiagram-TEJ5UH35-v8ysnsdI.js} +1 -1
  321. package/web-shell/assets/{flowDiagram-I6XJVG4X-BymfqdNJ.js → flowDiagram-I6XJVG4X-LKVlLjwA.js} +1 -1
  322. package/web-shell/assets/{ganttDiagram-6RSMTGT7-DOw340jf.js → ganttDiagram-6RSMTGT7-DA5MrKYG.js} +1 -1
  323. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-_8EiD8sl.js → gitGraphDiagram-PVQCEYII-Cyg5fe6d.js} +1 -1
  324. package/web-shell/assets/index-BgOcEaVt.js +1756 -0
  325. package/web-shell/assets/index-C2GE3DAF.js +74 -0
  326. package/web-shell/assets/{index-CKIadvET.js → index-CKdUkVVS.js} +1 -1
  327. package/web-shell/assets/index-DA5Lvscv.css +5 -0
  328. package/web-shell/assets/{infoDiagram-5YYISTIA-D61KYQBu.js → infoDiagram-5YYISTIA-SLsfu3Qd.js} +1 -1
  329. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-CsiXSpNx.js → ishikawaDiagram-YF4QCWOH-CmHOmTNx.js} +1 -1
  330. package/web-shell/assets/{journeyDiagram-JHISSGLW-Sdfionyh.js → journeyDiagram-JHISSGLW-C3gM_HFQ.js} +1 -1
  331. package/web-shell/assets/{kanban-definition-UN3LZRKU-C3WI3Cnl.js → kanban-definition-UN3LZRKU-BbHD7duM.js} +1 -1
  332. package/web-shell/assets/{linear-Dpigcc62.js → linear-CSBvm435.js} +1 -1
  333. package/web-shell/assets/{mermaid.core-Ct97pqgW.js → mermaid.core-CPMw15lU.js} +5 -5
  334. package/web-shell/assets/{mindmap-definition-RKZ34NQL-BzeaN0rB.js → mindmap-definition-RKZ34NQL-C_tNqXQW.js} +1 -1
  335. package/web-shell/assets/{pieDiagram-4H26LBE5-CvjgcbVD.js → pieDiagram-4H26LBE5-DH_N-8yY.js} +1 -1
  336. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-BUzgTNdH.js → quadrantDiagram-W4KKPZXB-CRbS8UkN.js} +1 -1
  337. package/web-shell/assets/{requirementDiagram-4Y6WPE33-B7zKlgUQ.js → requirementDiagram-4Y6WPE33-DJgdZPZn.js} +1 -1
  338. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-Bb9CQgrT.js → sankeyDiagram-5OEKKPKP-vhL1y5zx.js} +1 -1
  339. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DJ6V7itG.js → sequenceDiagram-3UESZ5HK-UQthhFwd.js} +1 -1
  340. package/web-shell/assets/{stateDiagram-AJRCARHV-IImflERY.js → stateDiagram-AJRCARHV-CAywEm20.js} +1 -1
  341. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-lfJQHw-7.js +1 -0
  342. package/web-shell/assets/{timeline-definition-PNZ67QCA-6Q_uWHKh.js → timeline-definition-PNZ67QCA-CLO8b3FD.js} +1 -1
  343. package/web-shell/assets/{vennDiagram-CIIHVFJN-TmyKyjwv.js → vennDiagram-CIIHVFJN-BNAAh0Mu.js} +1 -1
  344. package/web-shell/assets/{wardley-L42UT6IY-CRh9uiPv.js → wardley-L42UT6IY-CUY7bLpN.js} +1 -1
  345. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-59TKAW8w.js → wardleyDiagram-YWT4CUSO-CSg_ORdW.js} +1 -1
  346. package/web-shell/assets/{xychartDiagram-2RQKCTM6-GCSUIK2L.js → xychartDiagram-2RQKCTM6-BjffV208.js} +1 -1
  347. package/web-shell/index.html +2 -2
  348. package/chunks/agent-headless-NO4Y2HOE.js +0 -74
  349. package/chunks/chunk-6QIGFD5W.js +0 -82
  350. package/chunks/chunk-HGT6JR3U.js +0 -177
  351. package/chunks/daemon-status-provider-3XJI6CAL.js +0 -89
  352. package/chunks/handleAutoUpdate-L6ERF36Y.js +0 -80
  353. package/chunks/list-L2GA674Y.js +0 -88
  354. package/chunks/mcp-SZLHKFJW.js +0 -82
  355. package/chunks/nonInteractiveCli-5T7KYKLK.js +0 -144
  356. package/chunks/ripGrep-OWV2IVJC.js +0 -72
  357. package/chunks/theme-manager-EEWIQJ7J.js +0 -76
  358. package/chunks/total-session-admission-44JKRWQD.js +0 -84
  359. package/chunks/workspace-providers-status-S35YAIUS.js +0 -85
  360. package/chunks/write-file-3BZC3EAE.js +0 -72
  361. package/chunks/zoom-image-TZ6S2O57.js +0 -351
  362. package/web-shell/assets/channel-DPYMT76A.js +0 -1
  363. package/web-shell/assets/classDiagram-4FO5ZUOK--JstsIgL.js +0 -1
  364. package/web-shell/assets/classDiagram-v2-Q7XG4LA2--JstsIgL.js +0 -1
  365. package/web-shell/assets/index-D1eXNRHe.js +0 -1389
  366. package/web-shell/assets/index-DVLD4CQq.css +0 -5
  367. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CYI_YoNR.js +0 -1
@@ -125,7 +125,7 @@ Settings are organized into categories. Most settings should be placed within th
125
125
  | `ui.showCitations` | boolean | Show citations for generated text in the chat. | `false` |
126
126
  | `ui.history.collapseOnResume` | boolean | Whether to collapse history by default when resuming a session. Can be toggled via `/history collapse-on-resume` and `/history expand-on-resume`. | `false` |
127
127
  | `ui.history.collapsePreviewCount` | number | Number of most recent user turns to keep visible when `ui.history.collapseOnResume` is enabled. `0` collapses all restored history by default; `-1` shows all restored history. | `0` |
128
- | `ui.compactMode` | boolean | Retired in the terminal UI. The CLI now always shows the compact, type-based tool view in the main transcript; press `Ctrl+O` to open the full-detail transcript instead of toggling a mode. Still honored by the web shell. | `false` |
128
+ | `ui.compactMode` | boolean | Retired in the terminal UI. The CLI now always shows the compact, type-based tool view in the main transcript; press `Ctrl+O` to toggle expanded detail mode (expand or collapse all thinking blocks and tool outputs inline) instead of toggling a mode. Still honored by the web shell. | `false` |
129
129
  | `ui.shellOutputMaxLines` | number | Max number of shell output lines shown inline. Set to `0` to disable the cap and show full output. Hidden lines are surfaced via the `+N lines` indicator. Errors, `!`-prefix user-initiated commands, confirming tools, and focused embedded shells always show full output. | `5` |
130
130
  | `ui.enableWelcomeBack` | boolean | Show welcome back dialog when returning to a project with conversation history. When enabled, Qwen Code will automatically detect if you're returning to a project with a previously generated project summary (`.qwen/PROJECT_SUMMARY.md`) and show a dialog allowing you to continue your previous conversation or start fresh. If you choose **Start new chat session**, that choice is remembered for the current project until the project summary changes. This feature integrates with the `/summary` command and quit confirmation dialog. | `true` |
131
131
  | `ui.accessibility.enableLoadingPhrases` | boolean | Enable loading phrases (disable for accessibility). | `true` |
@@ -337,6 +337,7 @@ If you are experiencing performance issues with file searching (e.g., with `@` c
337
337
  | `tools.computerUse.maxImageDimension` | number | Longest-edge pixel cap applied to cua-driver screenshots (via `set_config`'s `max_image_dimension`). `-1` (default) keeps cua-driver's built-in default (1568); `0` disables resizing (full resolution); a positive value caps the longest edge. Lower caps cut vision-token cost at the expense of fine detail. | `-1` | Requires restart: Yes. Env override: `QWEN_COMPUTER_USE_MAX_IMAGE_DIMENSION` (a non-negative integer; takes precedence over this setting) |
338
338
  | `tools.computerUse.idleTimeoutMs` | number | Milliseconds to keep the cua-driver process alive after the last `computer_use__*` call. The default is `300000` (5 minutes). Set to `0` to keep it running until Qwen Code exits. | `300000` | Requires restart: Yes |
339
339
  | `tools.toolSearch.enabled` | boolean | Load MCP tools on demand via ToolSearch to reduce prompt size. Disable this for models that rely on prefix-based KV caching (e.g. DeepSeek) to keep the prompt prefix stable and maximize cache hit rates. | `true` | Requires restart: Yes |
340
+ | `tools.toolSearch.threshold` | number | Context-window percentage used as the session-start budget for preloading deferred tools (bundled built-ins and MCP alike). When the combined schemas of every deferred tool fit within this budget, they are all declared upfront instead of loaded on demand via ToolSearch — a stable declaration list keeps prefix KV caches valid for the whole session. Set `0` to always load deferred tools on demand. | `10` | Requires restart: Yes |
340
341
 
341
342
  > [!note]
342
343
  >
@@ -496,11 +497,12 @@ execute when typed.
496
497
 
497
498
  Controls which [Skills](../features/skills) are exposed to the model.
498
499
 
499
- | Setting | Type | Description | Default |
500
- | ------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- |
501
- | `skills.disabled` | array of strings | Hard-disabled skill names. Matched case-insensitively and **merged as a union** across settings scopes, so project settings cannot override a user or system entry. Hidden skills do not appear in `<available_skills>` or as `/<name>` slash commands. | `undefined` |
502
- | `skills.defaultDisabled` | array of strings | Skill names that start disabled but can be opted into through `skills.enabled`. Matched case-insensitively and merged as a union across settings scopes. | `undefined` |
503
- | `skills.enabled` | array of strings | Explicit opt-ins that override matching `skills.defaultDisabled` entries. Matched case-insensitively and merged as a union across settings scopes. This setting cannot override `skills.disabled`. | `undefined` |
500
+ | Setting | Type | Description | Default |
501
+ | ------------------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- |
502
+ | `skills.disabledLevels` | array of strings | Skill discovery levels to skip entirely. Supported values are `project`, `user`, `extension`, and `bundled`. Merged as a union across settings scopes. Use `["bundled"]` to hide every bundled skill while retaining host-provided skills. Note: `skills.directories` entries are discovered at the `user` level, so `["user"]` hides those too. | `undefined` |
503
+ | `skills.disabled` | array of strings | Hard-disabled skill names. Matched case-insensitively and **merged as a union** across settings scopes, so project settings cannot override a user or system entry. Hidden skills do not appear in `<available_skills>` or as `/<name>` slash commands. | `undefined` |
504
+ | `skills.defaultDisabled` | array of strings | Skill names that start disabled but can be opted into through `skills.enabled`. Matched case-insensitively and merged as a union across settings scopes. | `undefined` |
505
+ | `skills.enabled` | array of strings | Explicit opt-ins that override matching `skills.defaultDisabled` entries. Matched case-insensitively and merged as a union across settings scopes. This setting cannot override `skills.disabled` or re-enable skills from a `skills.disabledLevels`-excluded level. | `undefined` |
504
506
 
505
507
  The precedence is `skills.disabled` > `skills.enabled` > `skills.defaultDisabled`. For example, a user can put a skill in `defaultDisabled` and a project can add the same name to `enabled`; a hard `disabled` entry at any scope still wins.
506
508
 
@@ -854,7 +856,7 @@ To help us improve Qwen Code, we collect anonymized usage statistics. This data
854
856
 
855
857
  **What we collect:**
856
858
 
857
- - **Tool Calls:** We log the names of the tools that are called, whether they succeed or fail, and how long they take to execute. We do not collect the arguments passed to the tools or any data returned by them.
859
+ - **Tool Calls:** We log the names and categories (native or MCP) of the tools that are called, their terminal status (success, error, or cancelled), and how long they take to execute. We do not collect the arguments passed to the tools or any data returned by them.
858
860
  - **API Requests:** We log the model used for each request, the duration of the request, and whether it was successful. We do not collect the content of the prompts or responses.
859
861
  - **Session Information:** We collect information about the configuration of the CLI, such as the enabled tools and the approval mode.
860
862
 
@@ -7,5 +7,6 @@ export default {
7
7
  feishu: 'Feishu',
8
8
  qqbot: 'QQ Bot',
9
9
  github: 'GitHub',
10
+ gitlab: 'GitLab',
10
11
  plugins: 'Plugins',
11
12
  };
@@ -4,7 +4,8 @@ This guide covers setting up a Qwen Code channel that monitors GitHub notificati
4
4
 
5
5
  ## Prerequisites
6
6
 
7
- - A GitHub account (or a dedicated bot account)
7
+ - A GitHub account for the channel. Use a dedicated bot account when the PAT
8
+ owner also needs to operate the channel.
8
9
  - A GitHub Personal Access Token (PAT) with `notifications` and `public_repo` (or `repo`) scopes
9
10
 
10
11
  ## Creating a Token
@@ -26,10 +27,12 @@ Add the channel to `~/.qwen/settings.json`:
26
27
  "type": "github",
27
28
  "token": "$GITHUB_TOKEN",
28
29
  "pollInterval": 60000,
30
+ "reasonFilter": ["mention", "review_requested", "assign"],
29
31
  "senderPolicy": "allowlist",
30
- "allowedUsers": ["your-github-username"],
32
+ "allowedUsers": ["operator-github-username"],
31
33
  "sessionScope": "chat_thread",
32
34
  "cwd": "/path/to/your/project",
35
+ "blockStreaming": "off",
33
36
  "groupPolicy": "open",
34
37
  "groups": {
35
38
  "*": { "requireMention": true }
@@ -45,6 +48,13 @@ Set the token as an environment variable:
45
48
  export GITHUB_TOKEN="ghp_your_token_here"
46
49
  ```
47
50
 
51
+ The PAT owner cannot trigger its own channel: GitHub self-activity does not
52
+ provide a usable notification, and the adapter intentionally ignores its own
53
+ comments to prevent reply loops. If the PAT owner needs to operate the channel,
54
+ use a separate bot-owned PAT and put only operator accounts in `allowedUsers`.
55
+ Startup rejects an allowlist containing only the PAT owner and warns when the
56
+ PAT owner appears alongside other operators.
57
+
48
58
  ### GitHub Enterprise
49
59
 
50
60
  For GitHub Enterprise Server, set `baseUrl`:
@@ -57,14 +67,22 @@ For GitHub Enterprise Server, set `baseUrl`:
57
67
 
58
68
  ## Configuration Options
59
69
 
60
- | Option | Default | Description |
61
- | ------------------------- | ------------------------ | -------------------------------------------------------------------------------- |
62
- | `token` | (required) | Classic PAT with `notifications` scope |
63
- | `pollInterval` | `60000` | Poll interval in ms |
64
- | `baseUrl` | `https://api.github.com` | API base URL (for GHE) |
65
- | `groupPolicy` | `"disabled"` | Must be `"open"` for notifications to flow |
66
- | `senderPolicy` | `"allowlist"` | Who can trigger the bot |
67
- | `groups.*.requireMention` | `true` | Require @mentions for ordinary comments; directed notification reasons still run |
70
+ | Option | Default | Description |
71
+ | ------------------------- | ------------------------ | --------------------------------------------------------------------------------------------- |
72
+ | `token` | (required) | Classic PAT with `notifications` scope |
73
+ | `pollInterval` | `60000` | Poll interval in ms |
74
+ | `baseUrl` | `https://api.github.com` | API base URL (for GHE) |
75
+ | `groupPolicy` | `"disabled"` | Must be `"open"` for notifications to flow |
76
+ | `senderPolicy` | `"allowlist"` | Who can trigger the bot |
77
+ | `groups.*.requireMention` | `true` | Require @mentions for ordinary comments; directed notification reasons still run |
78
+ | `blockStreaming` | `"off"` | Always forced to `"off"`; intermediate model chunks aren't published; `"on"` is not supported |
79
+ | `reasonFilter` | unset | Optional allowlist of GitHub notification reasons to process |
80
+
81
+ Use `reasonFilter` to drop noisy notification classes such as `ci_activity` or `state_change`. Do not use `reasonFilter: ["mention"]` as a replacement for `groups.*.requireMention`: GitHub's `mention` reason is sticky at the thread level, so real new @mentions can arrive later under `comment`, `subscribed`, `author`, or other reasons and would be skipped.
82
+
83
+ Valid `reasonFilter` values are `mention`, `review_requested`, `assign`, `author`, `comment`, `ci_activity`, `manual`, `state_change`, `subscribed`, `team_mention`, `security_alert`, `approval_requested`, `invitation`, `member_feature_requested`, and `security_advisory_credit`.
84
+
85
+ Filtered notifications are still marked read before they are skipped. Removing the filter later will not replay notifications the channel already skipped.
68
86
 
69
87
  ## ⚠️ Security
70
88
 
@@ -92,6 +110,27 @@ The comment window is `(previousCursor, currentMaxUpdatedAt]` — comments alrea
92
110
 
93
111
  Non-comment activity (push, label changes) bumps the notification's `updated_at` but produces zero new comments in the window, so re-fetched threads are skipped without triggering the agent.
94
112
 
113
+ ## Response Feedback
114
+
115
+ For an accepted issue or pull-request comment, the channel adds GitHub's `👀` reaction while the agent is working, then removes it when the run completes, fails, or is cancelled. Both operations are best-effort: a reaction API or permission failure is logged and never prevents the final response.
116
+
117
+ ### Final-only output
118
+
119
+ The GitHub channel always forces final-only delivery. The adapter sets `blockStreaming` to `"off"`, so intermediate model chunks are never published as separate comments and `blockStreaming: "on"` is not supported.
120
+
121
+ ```json
122
+ {
123
+ "blockStreaming": "off"
124
+ }
125
+ ```
126
+
127
+ If GitHub returns a definite no-write delivery failure, such as a rate-limit
128
+ response, the channel stores the final reply in
129
+ `~/.qwen/channels/<workspace-scope>/<channel>-<name-hash>-github-pending-deliveries.json`
130
+ with private file permissions and retries it on the next channel start.
131
+ Ambiguous delivery failures are not retried automatically because GitHub may
132
+ have created the comment.
133
+
95
134
  ## Known Limitations
96
135
 
97
136
  - **First start skips existing unread notifications.** The cursor initializes to "now" on first launch. Notifications created before the bot starts are not processed unless the thread receives new activity afterwards.
@@ -0,0 +1,177 @@
1
+ # GitLab
2
+
3
+ This guide covers setting up a Qwen Code channel that monitors GitLab todos and responds to mentions on issues and merge requests.
4
+
5
+ ## Prerequisites
6
+
7
+ - A GitLab account (or a dedicated bot account)
8
+ - A GitLab Personal Access Token with `read_api` and `api` scopes
9
+
10
+ ## Creating a Token
11
+
12
+ 1. Go to **Preferences → Access Tokens**
13
+ 2. Create a token with these scopes:
14
+ - **read_api** — read todos and project data
15
+ - **api** — post notes (comments) on issues/MRs
16
+ 3. Save the token securely as an environment variable
17
+
18
+ ## Configuration
19
+
20
+ Add the channel to `~/.qwen/settings.json`:
21
+
22
+ ```json
23
+ {
24
+ "channels": {
25
+ "my-gitlab": {
26
+ "type": "gitlab",
27
+ "token": "$GITLAB_TOKEN",
28
+ "pollInterval": 60000,
29
+ "senderPolicy": "open",
30
+ "sessionScope": "chat_thread",
31
+ "cwd": "/path/to/your/project",
32
+ "groupPolicy": "open",
33
+ "action_prompt_template": {
34
+ "mentioned": "Project: %project% | URL: %project_url% | Author: %author% | Type: %target_type% | IID: %iid% | Title: %title% | Description: %description% | TodoID: %todo_id%"
35
+ }
36
+ }
37
+ }
38
+ }
39
+ ```
40
+
41
+ Set the token as an environment variable:
42
+
43
+ ```bash
44
+ export GITLAB_TOKEN="glpat-your_token_here"
45
+ ```
46
+
47
+ ### Self-hosted GitLab
48
+
49
+ For self-hosted instances, set `baseUrl`:
50
+
51
+ ```json
52
+ {
53
+ "baseUrl": "https://gitlab.example.com"
54
+ }
55
+ ```
56
+
57
+ ## Configuration Options
58
+
59
+ | Option | Default | Description |
60
+ | ------------------------ | ------------------------- | ---------------------------------------------------------- |
61
+ | `token` | (required) | PAT with `read_api` + `api` scopes |
62
+ | `pollInterval` | `60000` | Poll interval in ms |
63
+ | `baseUrl` | `https://gitlab.com` | GitLab instance URL |
64
+ | `action_prompt_template` | (required for processing) | Maps GitLab action names to metadata templates |
65
+ | `groupPolicy` | `"disabled"` | Must be `"open"`, or `"allowlist"` with the project listed |
66
+ | `senderPolicy` | `"allowlist"` | Who can trigger the bot |
67
+
68
+ ## action_prompt_template
69
+
70
+ This field controls which todo actions are processed and how metadata is rendered. Only actions with a configured template are dispatched; all others are skipped and marked done.
71
+
72
+ ```json
73
+ {
74
+ "action_prompt_template": {
75
+ "mentioned": "Project: %project% | Author: %author% | Title: %title%"
76
+ }
77
+ }
78
+ ```
79
+
80
+ The `directly_addressed` action (comment starting with `@bot`) automatically falls back to the `mentioned` template if not explicitly configured.
81
+
82
+ ### Available Action Keys
83
+
84
+ | Key | Trigger |
85
+ | --------------------- | ------------------------------------------------------------------------ |
86
+ | `mentioned` | Someone @mentions the bot in a comment or description (not at the start) |
87
+ | `directly_addressed` | A comment **starts with** `@bot` (falls back to `mentioned` template) |
88
+ | `assigned` | Someone assigns the bot to an issue/MR |
89
+ | `review_requested` | Someone requests the bot as a reviewer on an MR |
90
+ | `approval_required` | An MR requires the bot's approval (approval rules) |
91
+ | `marked` | Someone marks the bot's comment/issue/MR (star) |
92
+ | `build_failed` | A CI/CD pipeline fails on the bot's branch/MR |
93
+ | `unmergeable` | An MR the bot is involved with becomes unmergeable (conflicts) |
94
+ | `merge_train_removed` | An MR is removed from the merge train |
95
+
96
+ Only keys present in `action_prompt_template` are processed. Unconfigured actions are skipped and marked done silently.
97
+
98
+ ### Template Variables
99
+
100
+ | Variable | Value |
101
+ | --------------- | --------------------------------- |
102
+ | `%project%` | Project path (e.g., `owner/repo`) |
103
+ | `%project_url%` | Full project URL |
104
+ | `%author%` | Todo author username |
105
+ | `%target_type%` | `Issue` or `MergeRequest` |
106
+ | `%iid%` | Issue/MR internal ID |
107
+ | `%title%` | Issue/MR title |
108
+ | `%description%` | Issue/MR description body |
109
+ | `%todo_id%` | GitLab todo ID |
110
+ | `%%` | Literal `%` (escape) |
111
+
112
+ Unknown variables are preserved as-is in the output.
113
+
114
+ ### Prompt Assembly
115
+
116
+ The template renders into `envelope.metadata` (structured context). The triggering text (`todo.body` or description) goes into `envelope.text` (primary prompt). The base class assembles the final prompt sent to the agent:
117
+
118
+ ```
119
+ [alice] please fix this bug
120
+
121
+ Project: owner/repo | URL: https://gitlab.com/owner/repo | Author: alice | Type: Issue | IID: 42 | Title: Test Issue | Description: ... | TodoID: 100
122
+ ```
123
+
124
+ - Line 1: `[sender]` prefix + `envelope.text` (with `@bot` stripped)
125
+ - Line 3: `envelope.metadata` (rendered template, sanitized)
126
+
127
+ You do **not** need a `%body%` variable — the comment/description text is always the primary prompt content, and the template provides supplementary context below it.
128
+
129
+ ## ⚠️ Security
130
+
131
+ On a **public project**, setting `senderPolicy: "open"` allows **any GitLab user** who @mentions the bot to submit prompts that drive the agent in your `cwd`.
132
+
133
+ Always use `senderPolicy: "allowlist"` with explicit `allowedUsers` on public projects.
134
+
135
+ ## Mention Detection
136
+
137
+ The adapter always sets `isMentioned = true` on dispatched envelopes, because GitLab has already determined the mention when creating the todo. The `action_prompt_template` config is the real event filter — only actions with a configured template are processed. The `@bot` mention is stripped from the message text before dispatch via `stripBotMention`.
138
+
139
+ ### ⚠️ groupPolicy Must Be "open" or "allowlist"
140
+
141
+ `groupPolicy` must be set to `"open"`, or `"allowlist"` with the project explicitly listed, for todos to be processed. The default value `"disabled"` drops all mentions: todos are marked done and the cursor advances, but no dispatch occurs. A rejection is logged (`preflight rejected reason=group_disabled`) but the todo is still consumed. If your bot is not responding to mentions, check that `groupPolicy` is not `"disabled"`.
142
+
143
+ ## How It Works
144
+
145
+ The adapter uses GitLab's Todos API as the message source:
146
+
147
+ 1. **Poll** `GET /todos?state=pending` for new todos
148
+ 2. **First-poll drain**: if the cursor has never been initialized (`initialized: false`), all pending todos are marked done without dispatch and the cursor advances to the max todo ID. This prevents a backlog flood on first start.
149
+ 3. **Clean up stale todos**: todos with `id <= cursor` are marked done (best-effort) to prevent them from being re-fetched on every poll
150
+ 4. **Filter** by `id > cursor` and configured `action_prompt_template`
151
+ 5. **Detect mention type** via `target_url` anchor:
152
+ - `#note_123` present → comment mention → text is `todo.body` (the comment)
153
+ - No anchor → description mention → text is the issue/MR description
154
+ 6. **Dispatch** the envelope through `handleInbound` (requires `groupPolicy: "open"` or `"allowlist"` with the project listed)
155
+ 7. **Advance cursor** and **mark todo done** (best-effort)
156
+
157
+ The cursor (`lastProcessedId`) advances regardless of dispatch success or failure. Failed dispatches post a ⚠️ error comment on the issue/MR and are not retried — the user can re-mention the bot to trigger a new todo.
158
+
159
+ ## Response Feedback
160
+
161
+ For an accepted comment mention (note with `#note_` anchor), the channel adds a 👀 award emoji to the note while the agent is working, then removes it when the run completes, fails, or is cancelled. Both operations are best-effort: an award emoji API or permission failure is logged and never prevents the final response.
162
+
163
+ Description mentions (no `#note_` anchor) do not receive an award emoji because there is no specific note to react to.
164
+
165
+ ## Known Limitations
166
+
167
+ - **First start skips existing pending todos.** The cursor initializes to `{ lastProcessedId: 0, initialized: false }` on first launch. On the first poll cycle, all pre-existing pending todos are marked done without dispatch (the `initialized` flag gates this one-time drain), preventing a backlog flood.
168
+ - The bot does not read prior conversation history — only the triggering content is processed.
169
+ - **Confidential (internal) notes:** If someone @mentions the bot in a confidential note, the todo body contains that internal text and the agent will process it. The bot's reply is always posted as a **public** note, potentially exposing internal discussion. GitLab's todo API does not expose note visibility, so the adapter cannot filter this. Avoid @mentioning the bot in confidential notes.
170
+ - Requires `read_api` + `api` PAT scopes. Group-level or project-level tokens work if they have these scopes.
171
+ - Todos for Epics, Designs, and Alerts are skipped (only Issues and MRs are processed).
172
+
173
+ ## Starting the Channel
174
+
175
+ ```bash
176
+ qwen channel start my-gitlab
177
+ ```
@@ -277,6 +277,26 @@ The deterministic halves of the pipeline — argument parsing (`qwen review pars
277
277
 
278
278
  Every run ends with one machine-readable line (`Review complete: <target> — <disposition>`), so scripts and CI wrappers can detect completion and outcome with a single `^Review complete: ` match.
279
279
 
280
+ ## Headless runs (`qwen review run`)
281
+
282
+ `/review` is interactive. When a script or CI job needs to run a review and act on its outcome, use the headless wrapper:
283
+
284
+ ```bash
285
+ qwen review run [target] [--json] [--fail-on request-changes] [--comment] [--quiet]
286
+ ```
287
+
288
+ `target` is a PR number, a PR URL, or a file path; omit it to review the local working tree. The command runs this build's own CLI non-interactively (with stdin closed, so slash-command detection survives), streams the child's progress to **stderr**, and prints the verdict to **stdout** — or, with `--json`, the full result object. The verdict is read from the artifact `compose-review` writes (the same JSON the skill treats as the verdict authority), never parsed from the model's prose.
289
+
290
+ The exit code is the contract a gate should read:
291
+
292
+ | Exit | Meaning |
293
+ | ---- | ------------------------------------------------------------------------------------------------- |
294
+ | `0` | The review completed (whatever it decided) |
295
+ | `1` | It never reached a verdict — the child failed, timed out, or left no composed artifact |
296
+ | `3` | It completed with `REQUEST_CHANGES` **and** `--fail-on request-changes` was set (opt-in blocking) |
297
+
298
+ `3` (not `2`) lets a gate distinguish "the review is blocking" from "the tool broke" — yargs already uses `1` for usage errors — without parsing any output. `--timeout-minutes` (default 120, floored at 1) terminates a hung review and exits `1`, and cancelling the command (Ctrl+C / SIGTERM) terminates the review's process group rather than orphaning it.
299
+
280
300
  ## Cross-file Impact Analysis
281
301
 
282
302
  A dedicated cross-file tracer (Agent 1c) owns this walk end-to-end. When code changes modify exported functions, classes, or interfaces, it searches for all callers and checks compatibility:
@@ -83,6 +83,7 @@ Commands for managing AI tools and models.
83
83
  | `/import-config` | Import MCP servers from Claude configs | `/import-config all`, `/import-config claude-code`, `/import-config claude-desktop --scope user\|project` |
84
84
  | `/tools` | Display currently available tool list | `/tools`, `/tools desc` |
85
85
  | `/skills` | Open the Skills panel to browse, search, toggle, and launch skills | `/skills`, `/<skill-name>` |
86
+ | `/curator` | Inspect, pin, archive, or restore inactive project auto-skills | `/curator`, `/curator run --dry-run`, `/curator pin <directory>`, `/curator restore <directory>` |
86
87
  | `/plan` | Switch to plan mode or exit plan mode | `/plan`, `/plan <task>`, `/plan exit` |
87
88
  | `/approval-mode` | Change the tool-approval mode (current session only) | `/approval-mode`, `/approval-mode auto-edit` |
88
89
  | → `plan` | Analysis only, no execution (secure review) | `/approval-mode plan` |
@@ -103,6 +103,24 @@ HTTP hooks send hook input as POST requests to specified URLs. They support URL
103
103
  - **DNS Validation**: Validates domain resolution before requests to prevent DNS rebinding attacks
104
104
  - **Environment Variable Interpolation**: `${VAR}` syntax, only allows variables in `allowedEnvVars` whitelist
105
105
 
106
+ #### Allowing private-network hooks (managed environments only)
107
+
108
+ By default, HTTP hooks cannot target private or link-local IP ranges. In platform-managed environments where the hook receiver is a first-party, VPC-internal endpoint (for example, an internal API gateway resolving to `172.16.0.0/12`), you can relax the IP-range checks with:
109
+
110
+ ```json
111
+ {
112
+ "security": {
113
+ "allowPrivateNetworkHooks": true
114
+ }
115
+ }
116
+ ```
117
+
118
+ - This setting is **only honored from User, System, and SystemDefaults settings scopes**. A value set in Workspace (project) settings is ignored and logged as a warning, so a cloned repository can never self-grant this bypass.
119
+ - The flag relaxes only the general private/CGNAT/link-local **range** checks. Cloud metadata endpoints stay blocked in every configuration: the `BLOCKED_HOSTS` list is matched literally (`metadata.google.internal`, `metadata.azure.internal`, ...), and the metadata IPs `169.254.169.254` and `100.100.100.200` are blocked in all serialized forms (including IPv4-mapped IPv6 such as `::ffff:a9fe:a9fe`) and after DNS resolution.
120
+ - The `security.allowedHttpHookUrls` whitelist still applies independently. In managed environments, pair this flag with a whitelist so only the intended internal endpoints are reachable.
121
+
122
+ > **Warning:** Enabling this flag lets hooks reach internal infrastructure on your network. Enable it only in trusted, managed settings — never in a repository you do not control.
123
+
106
124
  **Example:**
107
125
 
108
126
  ```json
@@ -129,6 +147,87 @@ HTTP hooks send hook input as POST requests to specified URLs. They support URL
129
147
  }
130
148
  ```
131
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
+
132
231
  ### Function Hooks
133
232
 
134
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.
@@ -237,24 +336,25 @@ When `ok` is `false`, Qwen Code will continue working and use the `reason` as co
237
336
 
238
337
  Hooks fire at specific points during a Qwen Code session. Different events support different matchers to filter trigger conditions.
239
338
 
240
- | Event | Triggered When | Matcher Target |
241
- | :------------------- | :---------------------------------------- | :------------------------------------------------------------- |
242
- | `PreToolUse` | Before tool execution | Tool id (`write_file`, `read_file`, `run_shell_command`, etc.) |
243
- | `PostToolUse` | After successful tool execution | Tool id |
244
- | `PostToolUseFailure` | After tool execution fails | Tool id |
245
- | `UserPromptSubmit` | Before supported model invocations | None |
246
- | `SessionStart` | When session starts or resumes | Source (`startup`, `resume`, `clear`, `compact`) |
247
- | `SessionEnd` | When session ends | Reason (`clear`, `logout`, `prompt_input_exit`, etc.) |
248
- | `MessageDisplay` | Repeatedly, as the reply streams | None (always fires) |
249
- | `Stop` | When Claude prepares to conclude response | None (always fires) |
250
- | `SubagentStart` | When subagent starts | Agent type (`Bash`, `Explorer`, `Plan`, etc.) |
251
- | `SubagentStop` | When subagent stops | Agent type |
252
- | `PreCompact` | Before conversation compaction | Trigger (`manual`, `auto`) |
253
- | `Notification` | When notifications are sent | Type (`permission_prompt`, `idle_prompt`, `auth_success`) |
254
- | `PermissionRequest` | When permission dialog is shown | Tool id |
255
- | `PermissionDenied` | When tool permission is denied | Tool id |
256
- | `TodoCreated` | When a new todo item is created | None (always fires) |
257
- | `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) |
258
358
 
259
359
  ### Matcher Patterns
260
360
 
@@ -266,6 +366,7 @@ Hooks fire at specific points during a Qwen Code session. Different events suppo
266
366
  | Subagent Events | `SubagentStart`, `SubagentStop` | ✅ Regex | Agent type: `Bash`, `Explorer`, etc. |
267
367
  | Session Events | `SessionStart` | ✅ Regex | Source: `startup`, `resume`, `clear`, `compact` |
268
368
  | Session Events | `SessionEnd` | ✅ Regex | Reason: `clear`, `logout`, `prompt_input_exit`, etc. |
369
+ | Session Events | `SessionDelete` | ❌ No | N/A |
269
370
  | Notification Events | `Notification` | ✅ Exact match | Type: `permission_prompt`, `idle_prompt`, `auth_success` |
270
371
  | Compact Events | `PreCompact` | ✅ Exact match | Trigger: `manual`, `auto` |
271
372
  | Todo Events | `TodoCreated`, `TodoCompleted` | ❌ No | N/A |
@@ -539,6 +640,8 @@ Sequential UserPromptSubmit hooks can append `additionalContext` to `prompt`; `s
539
640
  - `reason`: human-readable explanation for the decision
540
641
  - `hookSpecificOutput.additionalContext`: additional context to append to the prompt (optional)
541
642
 
643
+ When sent to the model, injected `additionalContext` is appended as its own message part wrapped in a reserved `<qwen:user-prompt-submit-context>...</qwen:user-prompt-submit-context>` tag, so it stays distinguishable from user-authored text in model history and session transcripts. Angle brackets in hook output are escaped before wrapping, so hook content cannot close or forge the tag. The session transcript also records the user's original prompt text separately; the interactive TUI and the ACP/export transcript-replay path display that original text rather than the injected context.
644
+
542
645
  **Note**: Since UserPromptSubmitOutput extends HookOutput, all standard fields are available but only additionalContext in hookSpecificOutput is specifically defined for this event.
543
646
 
544
647
  **Example Output**:
@@ -599,6 +702,20 @@ Sequential UserPromptSubmit hooks can append `additionalContext` to `prompt`; `s
599
702
 
600
703
  - Standard hook output fields (typically not used for blocking)
601
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
+
602
719
  #### MessageDisplay
603
720
 
604
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.