@qwen-code/qwen-code 0.21.1-simplify-system-prompt.0 → 0.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/bundled/qc-helper/docs/configuration/model-providers.md +2 -0
  2. package/bundled/qc-helper/docs/configuration/settings.md +38 -28
  3. package/bundled/qc-helper/docs/features/channels/_meta.ts +1 -0
  4. package/bundled/qc-helper/docs/features/channels/github.md +107 -0
  5. package/bundled/qc-helper/docs/features/channels/overview.md +61 -6
  6. package/bundled/qc-helper/docs/features/code-review.md +1 -1
  7. package/bundled/qc-helper/docs/features/hooks.md +52 -15
  8. package/bundled/qc-helper/docs/features/mcp.md +9 -1
  9. package/bundled/qc-helper/docs/features/scheduled-tasks.md +3 -1
  10. package/bundled/qc-helper/docs/features/sub-agents.md +20 -0
  11. package/bundled/qc-helper/docs/qwen-serve.md +4 -2
  12. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +2 -2
  13. package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
  14. package/bundled/review/DESIGN.md +19 -0
  15. package/bundled/review/SKILL.md +120 -61
  16. package/chunks/MaxSizedBox-VI3ROJJA.js +84 -0
  17. package/chunks/{StandaloneSessionPicker-O6RKBPU4.js → StandaloneSessionPicker-LYXKD2EV.js} +66 -68
  18. package/chunks/{acp-startup-profiler-RV3IV562.js → acp-startup-profiler-DFVPFQ6C.js} +2 -2
  19. package/chunks/{acpAgent-HYFVXVDR.js → acpAgent-WN5SRDQO.js} +1317 -542
  20. package/chunks/agent-K6ECSM64.js +80 -0
  21. package/chunks/agent-headless-NO4Y2HOE.js +74 -0
  22. package/chunks/{anthropicContentGenerator-LXUXMOE7.js → anthropicContentGenerator-V2QOGVYD.js} +61 -20
  23. package/chunks/{artifact-tool-Y5T7GG7F.js → artifact-tool-6K6U7XYJ.js} +4 -4
  24. package/chunks/{askUserQuestion-2H6747FR.js → askUserQuestion-GD2IJJ7I.js} +4 -4
  25. package/chunks/bridge-3KJEWDNE.js +90 -0
  26. package/chunks/{build-RV63TIRH.js → build-S6DO7LMM.js} +1 -1
  27. package/chunks/{ca-25EDXPFZ.js → ca-6W3SK7OQ.js} +6 -1
  28. package/chunks/{channel-management-service-G74LFADV.js → channel-management-service-XR7GZSWF.js} +4 -4
  29. package/chunks/channel-settings-store-HW4FXXUA.js +87 -0
  30. package/chunks/{channel-worker-group-PTJIJSKC.js → channel-worker-group-XDPTDWTX.js} +9 -5
  31. package/chunks/{channel-worker-manager-WIMGM2FD.js → channel-worker-manager-YYEHVRRE.js} +9 -5
  32. package/chunks/{channel-worker-supervisor-KUFTR6P5.js → channel-worker-supervisor-74HTWA2G.js} +5 -4
  33. package/chunks/{chunk-M5JM7OSF.js → chunk-2DN4J57Y.js} +2 -3
  34. package/chunks/{chunk-WDSWXQU3.js → chunk-2FAK6PNM.js} +2 -2
  35. package/chunks/{chunk-BPJSQIJX.js → chunk-2J3OJGTL.js} +0 -2
  36. package/chunks/{chunk-EPDRMGT4.js → chunk-2LKVPASC.js} +4 -28
  37. package/chunks/{chunk-PWTZEM3C.js → chunk-2LQTH543.js} +3 -37
  38. package/chunks/{chunk-PANH4R3B.js → chunk-2N7CODY5.js} +18 -12
  39. package/chunks/{chunk-ER5LWJR6.js → chunk-2XSLTRFZ.js} +3 -3
  40. package/chunks/{chunk-6PSLCFQ2.js → chunk-3EFXSQCM.js} +18 -9
  41. package/chunks/{chunk-HIJQF5B5.js → chunk-3L2SPEBH.js} +1 -1
  42. package/chunks/{chunk-BIQWWWJN.js → chunk-4G2BISNC.js} +1 -1
  43. package/chunks/{chunk-B4UMZKMU.js → chunk-52ZSWYEG.js} +1 -1
  44. package/chunks/{chunk-YAF5VNU7.js → chunk-5KTQXHPY.js} +4 -5
  45. package/chunks/{chunk-2YZJCM5T.js → chunk-5MKRTI4T.js} +4 -4
  46. package/chunks/{chunk-DHHOYAPR.js → chunk-5TBMQLGG.js} +7 -7
  47. package/chunks/{chunk-A4UCTEB5.js → chunk-5WV5S2GT.js} +0 -1
  48. package/chunks/{chunk-FY3M44RD.js → chunk-5YKDXHUY.js} +3 -3
  49. package/chunks/{chunk-TF2X2WCT.js → chunk-5ZF5XXTS.js} +2 -2
  50. package/chunks/{chunk-K4XWPEWB.js → chunk-64LQLPL7.js} +4 -33
  51. package/chunks/{chunk-B7QDM6Z7.js → chunk-657BH7VM.js} +2 -2
  52. package/chunks/{chunk-5THCYPLO.js → chunk-65PQENQP.js} +14 -7
  53. package/chunks/{chunk-J6D3VXCC.js → chunk-6PE7N3A4.js} +17 -6
  54. package/chunks/{chunk-JZA3JUDJ.js → chunk-6QIGFD5W.js} +1 -1
  55. package/chunks/{chunk-Z5BLYMZM.js → chunk-6RPMI2AB.js} +6 -6
  56. package/chunks/{chunk-OHNBB4XR.js → chunk-75GFAX4R.js} +1 -1
  57. package/chunks/{chunk-BO4XCS7P.js → chunk-75MIQ3LV.js} +20 -85
  58. package/chunks/{chunk-52O2CIUL.js → chunk-7AEJDLRA.js} +130 -5
  59. package/chunks/{chunk-BYFNTGKI.js → chunk-7BAU433D.js} +2287 -941
  60. package/chunks/{chunk-ZE5WPL4I.js → chunk-7DXQIJID.js} +3 -3
  61. package/chunks/{chunk-ML52PL6O.js → chunk-7I5GTCT4.js} +483 -248
  62. package/chunks/{chunk-A5L3JMUA.js → chunk-7XATOOE7.js} +18 -4
  63. package/chunks/{chunk-C3NS4F2Q.js → chunk-A2D5BAVP.js} +1 -1
  64. package/chunks/{chunk-5I2IWRSH.js → chunk-A3NDJ5SB.js} +2 -2
  65. package/chunks/{chunk-2JM6GZ5D.js → chunk-A4COXFB3.js} +8 -13
  66. package/chunks/{chunk-CC4N4M36.js → chunk-AQIDMUGU.js} +1 -1
  67. package/chunks/{chunk-PJIZUQVC.js → chunk-AZQ3DT76.js} +2 -2
  68. package/chunks/{chunk-UH3WSE5L.js → chunk-B4AJNNOL.js} +1 -6
  69. package/chunks/{chunk-BJX6ZSUK.js → chunk-BCZFQXWK.js} +2 -2
  70. package/chunks/{chunk-SRZ6DXVG.js → chunk-BGTQCTQW.js} +44 -136
  71. package/chunks/{chunk-PSWQZHEA.js → chunk-BMFALVGQ.js} +1 -1
  72. package/chunks/{chunk-XHRTVPG2.js → chunk-BNWB5CYE.js} +7 -7
  73. package/chunks/{chunk-P5V4T7NK.js → chunk-BPZKP57P.js} +11 -3
  74. package/chunks/{chunk-2OM7GEXO.js → chunk-CAPPWD3X.js} +3 -3
  75. package/chunks/{chunk-LNURQEMZ.js → chunk-CQL64ESB.js} +7 -7
  76. package/chunks/{chunk-TOFQCPDC.js → chunk-CVHIL5IG.js} +4 -5
  77. package/chunks/{chunk-XVNQMZ2I.js → chunk-DGEIYUC3.js} +0 -1
  78. package/chunks/{chunk-BPZALHVR.js → chunk-DI35ZN7T.js} +1 -1
  79. package/chunks/{chunk-SQBYH7PX.js → chunk-DZLYR4U3.js} +1 -1
  80. package/chunks/{chunk-JALU3ZDU.js → chunk-EIF3FXTB.js} +117 -24
  81. package/chunks/{chunk-TQCBGUHN.js → chunk-EJGJIBRS.js} +5 -5
  82. package/chunks/{chunk-5U4IPFBR.js → chunk-EVKE2FZL.js} +4 -4
  83. package/chunks/{chunk-OKY7HXPG.js → chunk-FNMZK765.js} +2 -2
  84. package/chunks/{chunk-KU5XMLDK.js → chunk-FTD6DP4T.js} +3 -1
  85. package/chunks/chunk-FYJ7W2PI.js +194 -0
  86. package/chunks/{chunk-L5UHQJTJ.js → chunk-GATT5TKW.js} +1 -1
  87. package/chunks/{chunk-MVS3NS2N.js → chunk-GEBV2JGB.js} +28 -5
  88. package/chunks/{chunk-VAK25FTU.js → chunk-GKX7E4CO.js} +1 -1
  89. package/chunks/{chunk-LS77BEZP.js → chunk-GLCZKT5V.js} +1 -5
  90. package/chunks/{chunk-N3FAY5CM.js → chunk-GNR2RNMP.js} +157 -4
  91. package/chunks/{chunk-YH6G52F2.js → chunk-GXIJHV66.js} +4 -4
  92. package/chunks/{chunk-HV3G62R6.js → chunk-GZ3RCT54.js} +1 -1
  93. package/chunks/{chunk-QY5MMZ6O.js → chunk-HMRM2A3U.js} +3 -3
  94. package/chunks/chunk-HV26XH34.js +319 -0
  95. package/chunks/{chunk-M4UKFCZ2.js → chunk-J7OACQDE.js} +193 -155
  96. package/chunks/{chunk-3HBZKBMQ.js → chunk-JFMA7Y5M.js} +5 -5
  97. package/chunks/{chunk-OJGCZBB7.js → chunk-JHNRZMHI.js} +41 -36
  98. package/chunks/{chunk-63P4EL5V.js → chunk-JMONIXMJ.js} +1 -1
  99. package/chunks/{chunk-L26JL52R.js → chunk-JSD33JG6.js} +47 -64
  100. package/chunks/{chunk-KIUFNBHR.js → chunk-JTV5K7NH.js} +1 -1
  101. package/chunks/{chunk-PHVR5UUY.js → chunk-JX27F6QS.js} +1 -1
  102. package/chunks/chunk-JYBU6YUE.js +378 -0
  103. package/chunks/{chunk-A6UO2C7C.js → chunk-KAMYKP7E.js} +167 -81
  104. package/chunks/{chunk-LG4GZIVV.js → chunk-KCO4FLFJ.js} +4 -4
  105. package/chunks/{chunk-2W3OOD4W.js → chunk-L55JWS76.js} +6 -3
  106. package/chunks/{chunk-RHLZR4E5.js → chunk-LGAOC3ZS.js} +1 -1
  107. package/chunks/{chunk-DM22XS4K.js → chunk-LO4ROVP4.js} +261 -15
  108. package/chunks/{chunk-NH6KE4JX.js → chunk-LW3RFMG7.js} +3 -3
  109. package/chunks/{chunk-J56UI34H.js → chunk-M7OONWYU.js} +2 -2
  110. package/chunks/{chunk-V6VRAM7B.js → chunk-MHAIJPTD.js} +12 -12
  111. package/chunks/{chunk-FODK6UMO.js → chunk-MPHPFVKK.js} +0 -2
  112. package/chunks/{chunk-LZEMEFKY.js → chunk-MR5EAQ5M.js} +1 -1
  113. package/chunks/{chunk-JESCGQM3.js → chunk-NAVJD2PQ.js} +8 -7
  114. package/chunks/{chunk-H5FFA6TH.js → chunk-NOKIVHOL.js} +16 -3
  115. package/chunks/{chunk-6OUGMXDC.js → chunk-NWNEANAT.js} +7 -7
  116. package/chunks/{chunk-B6ZJ7SI6.js → chunk-OCESJA77.js} +391 -328
  117. package/chunks/chunk-OCPBI7J5.js +18 -0
  118. package/chunks/{chunk-E5TUC6CA.js → chunk-OKF7JF3R.js} +3 -3
  119. package/chunks/{chunk-2Q3OT4OV.js → chunk-P4WOAOJW.js} +141 -64
  120. package/chunks/{chunk-4M377AZG.js → chunk-PB3MBFKG.js} +6 -6
  121. package/chunks/{chunk-QPDRAXDJ.js → chunk-PLDQBIO6.js} +1 -1
  122. package/chunks/{chunk-FNQ6T3CV.js → chunk-PONHVBRT.js} +10 -7
  123. package/chunks/{chunk-RWS5VYWC.js → chunk-PT722TDT.js} +267 -378
  124. package/chunks/chunk-Q43KPN7X.js +2196 -0
  125. package/chunks/{chunk-VDDGDZMA.js → chunk-QHWCP53L.js} +14 -7
  126. package/chunks/{chunk-SASBXAQL.js → chunk-QIZKCVM3.js} +4 -4
  127. package/chunks/{chunk-32MVHM4T.js → chunk-RCUQIPTN.js} +1 -1
  128. package/chunks/{chunk-6FGBXPWM.js → chunk-RPLGZJV2.js} +38 -44
  129. package/chunks/{chunk-3IXOIAKE.js → chunk-S4WJVPZW.js} +18 -6
  130. package/chunks/{chunk-6AM5D4ME.js → chunk-S6LOFUVP.js} +0 -12
  131. package/chunks/{chunk-INADJJGW.js → chunk-S7W2GKIO.js} +0 -2
  132. package/chunks/{chunk-MUP3T3AD.js → chunk-SGFT55XI.js} +1 -35
  133. package/chunks/{chunk-VYPFXUCB.js → chunk-SZ3KHTDR.js} +1 -1
  134. package/chunks/chunk-T26EAKDL.js +13 -0
  135. package/chunks/{chunk-3MSHSCSN.js → chunk-T2QMKU3R.js} +79 -1
  136. package/chunks/{chunk-VFSJ5VRH.js → chunk-T3O2B4XO.js} +3 -3
  137. package/chunks/{chunk-MSLKI6C2.js → chunk-T4TXDL7G.js} +32 -21
  138. package/chunks/{chunk-E5WH5O3C.js → chunk-TBBV36Y4.js} +4 -4
  139. package/chunks/{chunk-VV6XU5L7.js → chunk-TCIFAA7K.js} +16 -11
  140. package/chunks/{chunk-DN6ZX5AY.js → chunk-TDL6LB4K.js} +46 -11
  141. package/chunks/{chunk-W4CQXHT6.js → chunk-TFRMVU6R.js} +1 -1
  142. package/chunks/{chunk-GDIPH4JY.js → chunk-TV64SXKD.js} +6 -6
  143. package/chunks/{chunk-FQK6JAFG.js → chunk-U3E3UQAA.js} +4 -4
  144. package/chunks/{chunk-7FZEBPKS.js → chunk-UBEPNVDI.js} +23 -18
  145. package/chunks/{chunk-NL7LTRLR.js → chunk-UHUSJ6X7.js} +29 -68
  146. package/chunks/{chunk-ZOIFNCKL.js → chunk-UPUG4GXM.js} +3 -23
  147. package/chunks/{chunk-6GMVPFB2.js → chunk-UWMLWVCA.js} +19 -6
  148. package/chunks/{chunk-U7TXFVUN.js → chunk-VCPIZRYH.js} +118 -95
  149. package/chunks/{chunk-LNARWLZQ.js → chunk-VWOOBLTY.js} +2 -2
  150. package/chunks/{chunk-I7XZ3RY5.js → chunk-VYOXCEPJ.js} +1 -1
  151. package/chunks/{chunk-USTWD7QV.js → chunk-W4MIWP6M.js} +26 -16
  152. package/chunks/{chunk-DLWL3Z7A.js → chunk-WBSMNTSV.js} +3 -3
  153. package/chunks/{chunk-G4WFQUYQ.js → chunk-WUZ7H6DP.js} +1 -1
  154. package/chunks/{chunk-2JZBVYTU.js → chunk-WZRWHXFE.js} +1 -8
  155. package/chunks/{chunk-DM4Q4JJH.js → chunk-X5WNMMIA.js} +22506 -33611
  156. package/chunks/{chunk-MK7VQDN3.js → chunk-XBYYDKAZ.js} +7 -6
  157. package/chunks/{chunk-COH43MRJ.js → chunk-XCGIMOLN.js} +27 -1
  158. package/chunks/{chunk-BRRAJXPA.js → chunk-XFZYFU3I.js} +1 -1
  159. package/chunks/{chunk-3QMGYBFN.js → chunk-XWWKIXVD.js} +1 -80
  160. package/chunks/{chunk-3SJ43L4W.js → chunk-XZC5VLBZ.js} +2 -0
  161. package/chunks/{chunk-UUUTRMI2.js → chunk-Y4IHBGBP.js} +1 -1
  162. package/chunks/{chunk-PR75REBZ.js → chunk-Y6AXW2OG.js} +12 -82
  163. package/chunks/{chunk-IPUUTYMV.js → chunk-YDLJGZHL.js} +1 -1
  164. package/chunks/{chunk-3JAQDSXN.js → chunk-YGF33UXG.js} +70 -8
  165. package/chunks/chunk-Z4X5MTRT.js +133 -0
  166. package/chunks/{chunk-UW5EOVUN.js → chunk-ZBVS26BY.js} +4 -4
  167. package/chunks/{chunk-ZD6UTE4A.js → chunk-ZHBO7WVX.js} +1 -1
  168. package/chunks/{chunk-HTO4JFDZ.js → chunk-ZPJWUGCS.js} +0 -1
  169. package/chunks/{chunk-66RMLJHC.js → chunk-ZURDMIDR.js} +355 -143
  170. package/chunks/{computer-use-DOFAHZAB.js → computer-use-ZTIDHMMA.js} +48 -50
  171. package/chunks/{config-utils-VFQXVGNR.js → config-utils-NYSXDMEQ.js} +4 -4
  172. package/chunks/contextCommand-2PIEU37Z.js +79 -0
  173. package/chunks/core-runtime-3XEYLQFK.js +133 -0
  174. package/chunks/{create-sub-session-7543K2QA.js → create-sub-session-R76FVXCI.js} +45 -47
  175. package/chunks/{create-sub-session-IWW2IZ2T.js → create-sub-session-SBYUMSSS.js} +3 -3
  176. package/chunks/{cron-create-YIID5XAW.js → cron-create-2QK6TCEC.js} +6 -6
  177. package/chunks/{cron-delete-ZVHYCEP2.js → cron-delete-FDCDFYMG.js} +5 -5
  178. package/chunks/{cron-list-XEGS463Q.js → cron-list-XN3WVBTP.js} +6 -6
  179. package/chunks/{daemon-VOMQW7KZ.js → daemon-Q2AB5Z23.js} +167 -15
  180. package/chunks/daemon-status-provider-3XJI6CAL.js +89 -0
  181. package/chunks/daemon-trust-policy-ILUDTLHD.js +84 -0
  182. package/chunks/daemon-trust-policy-monitor-HS3PKKRO.js +171 -0
  183. package/chunks/{de-HGRCYDEJ.js → de-SY6O76BF.js} +6 -1
  184. package/chunks/deferred-core-runtime-X4QV662U.js +88 -0
  185. package/chunks/dist-BSTVRPMT.js +4227 -0
  186. package/chunks/{dist-NNVBBOGU.js → dist-DOLYHMXE.js} +2 -2
  187. package/chunks/{dist-RTJFMNEZ.js → dist-HVRQ2CFL.js} +271 -11
  188. package/chunks/{dist-ANLAT3GS.js → dist-IXQEQWRG.js} +2 -1
  189. package/chunks/{dist-BRB6EXK4.js → dist-SSU66DM4.js} +3 -3
  190. package/chunks/{dist-KTYYJ2C5.js → dist-SV7Q3AWJ.js} +1 -1
  191. package/chunks/{dist-K6Y4E7FX.js → dist-YGBBMK3Z.js} +1 -1
  192. package/chunks/earlyInputCapture-XKLZT7ZD.js +81 -0
  193. package/chunks/{edit-RIEOJWKB.js → edit-HHGIOTQ2.js} +47 -49
  194. package/chunks/{en-MTWBNGDO.js → en-NBK3JKCE.js} +9 -1
  195. package/chunks/{enter-worktree-OGK5FQ3R.js → enter-worktree-ZN7PUQ46.js} +47 -49
  196. package/chunks/{enterPlanMode-IWZYALIB.js → enterPlanMode-EIFIDSIV.js} +47 -49
  197. package/chunks/{environment-VZ7BRI4Q.js → environment-XXQ75D2Q.js} +47 -49
  198. package/chunks/errors-4GMVU7CK.js +87 -0
  199. package/chunks/esm-K5FARBNI.js +5548 -0
  200. package/chunks/{exit-worktree-4TEYVIVP.js → exit-worktree-GXMI4ATY.js} +47 -49
  201. package/chunks/exitPlanMode-34UVY7M6.js +72 -0
  202. package/chunks/{fast-path-HYE7IFEV.js → fast-path-VPIVA7L6.js} +13 -3
  203. package/chunks/{fr-45RLL55O.js → fr-4KG5V7UT.js} +6 -1
  204. package/chunks/{gemini-NGRQX3YJ.js → gemini-4BWIK4WD.js} +103 -103
  205. package/chunks/{geminiContentGenerator-FQHPFZSR.js → geminiContentGenerator-3XVV5MSS.js} +7 -7
  206. package/chunks/{getMachineId-bsd-V7W3GODC.js → getMachineId-bsd-FG7IUY6U.js} +1 -1
  207. package/chunks/{getMachineId-darwin-TDO75DQP.js → getMachineId-darwin-GLCJI2RA.js} +1 -1
  208. package/chunks/{getMachineId-linux-TF43WQT2.js → getMachineId-linux-O6OPPAKO.js} +1 -1
  209. package/chunks/{getMachineId-unsupported-ZGUO3TXT.js → getMachineId-unsupported-S6CKYVGC.js} +1 -1
  210. package/chunks/{getMachineId-win-ECFYZZFQ.js → getMachineId-win-X5SRNEH7.js} +1 -1
  211. package/chunks/{glob-FRTM3X2E.js → glob-TZ2ABCJG.js} +47 -49
  212. package/chunks/{grep-RKWVROCW.js → grep-BEF463NA.js} +49 -50
  213. package/chunks/handleAutoUpdate-L6ERF36Y.js +80 -0
  214. package/chunks/i18n-FMM5FDXR.js +96 -0
  215. package/chunks/{image-gen-WIEM7KZA.js → image-gen-HHVLF7HS.js} +12 -12
  216. package/chunks/initializer-625TIAIO.js +85 -0
  217. package/chunks/installationInfo-6AM4I2Y3.js +79 -0
  218. package/chunks/{ja-B7DF7DFG.js → ja-F3GSQXMF.js} +6 -1
  219. package/chunks/{keychain-token-storage-MDTG3WRM.js → keychain-token-storage-72IYCAZV.js} +3 -3
  220. package/chunks/lib-RUF3WZA6.js +9 -0
  221. package/chunks/list-L2GA674Y.js +88 -0
  222. package/chunks/{list-agents-5KJJHR6I.js → list-agents-R6KDXQR3.js} +3 -3
  223. package/chunks/loadedSettingsAdapter-SPUTNKAV.js +82 -0
  224. package/chunks/{loggingContentGenerator-WGM27QAW.js → loggingContentGenerator-LKOF7XI7.js} +31 -30
  225. package/chunks/{loop-wakeup-FXKNNYSY.js → loop-wakeup-3IQKCYAH.js} +7 -7
  226. package/chunks/{ls-NTK6VOQJ.js → ls-DKZ37A7N.js} +5 -5
  227. package/chunks/{lsp-2JI24STP.js → lsp-QNWN7KN3.js} +3 -3
  228. package/chunks/{managed-npm-update-JQ2CG3RH.js → managed-npm-update-ACQGGIN5.js} +46 -48
  229. package/chunks/mcp-SZLHKFJW.js +82 -0
  230. package/chunks/{monitor-7FEWXX5F.js → monitor-DF52UVHI.js} +47 -49
  231. package/chunks/nonInteractiveCli-5T7KYKLK.js +144 -0
  232. package/chunks/{notebook-edit-JGJV2K6J.js → notebook-edit-FCWS4XVN.js} +47 -49
  233. package/chunks/{openaiContentGenerator-JPVXDTAO.js → openaiContentGenerator-7LDK3DCJ.js} +25 -27
  234. package/chunks/pidfile-6ERW3DF4.js +85 -0
  235. package/chunks/process-registry-2CHQBXH5.js +157 -0
  236. package/chunks/{processUtils-V2LCK6T6.js → processUtils-COKZAMUP.js} +2 -2
  237. package/chunks/{pt-22Q3FP73.js → pt-EQ33KWEN.js} +6 -1
  238. package/chunks/{qwenContentGenerator-TICV2W2Z.js → qwenContentGenerator-TKWUMR7N.js} +51 -53
  239. package/chunks/{qwenOAuth2-XGFI5XJG.js → qwenOAuth2-7HMU47SF.js} +10 -10
  240. package/chunks/read-file-X6DRC574.js +29 -0
  241. package/chunks/{read-mcp-resource-4DKQWGHD.js → read-mcp-resource-GFTWYXMK.js} +4 -4
  242. package/chunks/{record-artifact-RQKFYO5B.js → record-artifact-XAMSFSW4.js} +3 -3
  243. package/chunks/resumeHistoryUtils-PFPM2GWM.js +90 -0
  244. package/chunks/ripGrep-OWV2IVJC.js +72 -0
  245. package/chunks/{ru-FZCNZHDC.js → ru-7OZAUKGG.js} +6 -1
  246. package/chunks/{run-qwen-serve-3VCV4I7E.js → run-qwen-serve-TSTCO4XE.js} +917 -249
  247. package/chunks/{runtime-AXJWIEDU.js → runtime-DAUPSUKI.js} +55 -57
  248. package/chunks/{scheduler-RS2I6RU5.js → scheduler-KMADMT26.js} +45 -47
  249. package/chunks/{sdk-exporters-grpc-AK3LGHNO.js → sdk-exporters-grpc-54L4LS5L.js} +4 -4
  250. package/chunks/{sdk-exporters-http-FS6ZV7MF.js → sdk-exporters-http-WO556XNU.js} +7 -7
  251. package/chunks/{sdk-impl-7FZSCSXB.js → sdk-impl-LPAVACSF.js} +10 -10
  252. package/chunks/{send-message-Q6OOR6BR.js → send-message-SAWK4DZX.js} +6 -6
  253. package/chunks/serve-NNRWS6F4.js +88 -0
  254. package/chunks/{server-HRZ23U7M.js → server-WEH7DVCH.js} +3304 -842
  255. package/chunks/{session-7XHZKTVV.js → session-WXC56V2I.js} +94 -94
  256. package/chunks/{settings-7ZGZDXAS.js → settings-DJDXFDZ3.js} +54 -56
  257. package/chunks/shell-JN5VRQXD.js +82 -0
  258. package/chunks/{skill-LIWXNLDW.js → skill-SGXPKJCS.js} +20 -22
  259. package/chunks/skill-settings-VJ5PDMZI.js +90 -0
  260. package/chunks/spawnChannel-ETMJW7YX.js +81 -0
  261. package/chunks/standalone-update-MK3Z7KBI.js +91 -0
  262. package/chunks/{startInteractiveUI-IW3CSKHA.js → startInteractiveUI-ZCGIXPGT.js} +715 -373
  263. package/chunks/{syntheticOutput-I3757IWH.js → syntheticOutput-355CB6CJ.js} +4 -4
  264. package/chunks/{task-create-N7WQSGYA.js → task-create-INGWNUG4.js} +10 -10
  265. package/chunks/{task-list-FOPULZEP.js → task-list-5XNNGTF4.js} +7 -7
  266. package/chunks/{task-stop-H6RHXFVQ.js → task-stop-4ROAOBXH.js} +3 -3
  267. package/chunks/{task-update-M57TFZJT.js → task-update-CRK5VWWZ.js} +10 -10
  268. package/chunks/{team-create-O2FROQ4R.js → team-create-QQGAJG7P.js} +49 -51
  269. package/chunks/{team-delete-QE2UXJL7.js → team-delete-S2RCXA4P.js} +7 -7
  270. package/chunks/{team-plan-approval-Q6WDBXTQ.js → team-plan-approval-RT7Q5R6O.js} +47 -49
  271. package/chunks/theme-manager-EEWIQJ7J.js +76 -0
  272. package/chunks/{todoWrite-VQ7FKOHL.js → todoWrite-7WM3VDMY.js} +7 -7
  273. package/chunks/{tool-search-APECNQ3Z.js → tool-search-Z3Z4AYKP.js} +19 -21
  274. package/chunks/total-session-admission-44JKRWQD.js +84 -0
  275. package/chunks/{tree-sitter-FS4VPMZA.js → tree-sitter-4D7QS7F6.js} +1 -1
  276. package/chunks/{tree-sitter-bash-6B46JJCV.js → tree-sitter-bash-VEJGF5XF.js} +1 -1
  277. package/chunks/trustedFolders-X2JEIO57.js +94 -0
  278. package/chunks/{update-relaunch-ON5MDJQG.js → update-relaunch-VWNPYDIP.js} +5 -5
  279. package/chunks/updateCheck-KAQH67DV.js +91 -0
  280. package/chunks/useAutoAcceptIndicator-JH6BCF7S.js +92 -0
  281. package/chunks/{validateNonInterActiveAuth-JBLKBKRD.js → validateNonInterActiveAuth-GIUJ2UFS.js} +88 -88
  282. package/chunks/{version-LTNUBQJY.js → version-BGLYIJUY.js} +1 -1
  283. package/chunks/{web-fetch-L5UTI53V.js → web-fetch-OTDU4VQF.js} +19 -21
  284. package/chunks/{web-search-KM33JOS3.js → web-search-FP6SIHPR.js} +13 -13
  285. package/chunks/{workflow-K7FAWV77.js → workflow-YCIVBYSB.js} +48 -50
  286. package/chunks/workspace-providers-status-S35YAIUS.js +85 -0
  287. package/chunks/{workspace-registration-store-6TGVDJV5.js → workspace-registration-store-OTMS3H4C.js} +1 -1
  288. package/chunks/workspace-registry-O63R6IZ4.js +92 -0
  289. package/chunks/workspace-service-M6LLHKJ5.js +99 -0
  290. package/chunks/workspace-skills-status-C2V7BAIS.js +85 -0
  291. package/chunks/workspace-trust-reconciler-IBUPOUJN.js +345 -0
  292. package/chunks/write-file-3BZC3EAE.js +72 -0
  293. package/chunks/xterm-headless-NTYVIBT3.js +3475 -0
  294. package/chunks/{zh-LUIGBD55.js → zh-H3YDK5QW.js} +9 -1
  295. package/chunks/{zh-TW-F5KG2IYD.js → zh-TW-JYCP7XUA.js} +9 -1
  296. package/chunks/zoom-image-TZ6S2O57.js +351 -0
  297. package/cli.js +13 -13
  298. package/locales/ca.js +7 -2
  299. package/locales/de.js +7 -2
  300. package/locales/en.js +10 -2
  301. package/locales/fr.js +7 -2
  302. package/locales/ja.js +7 -2
  303. package/locales/pt.js +7 -2
  304. package/locales/ru.js +7 -2
  305. package/locales/zh-TW.js +10 -2
  306. package/locales/zh.js +10 -2
  307. package/package.json +5 -4
  308. package/web-shell/assets/{arc-BbHijhiN.js → arc-75-Wdeo3.js} +1 -1
  309. package/web-shell/assets/{architectureDiagram-3BPJPVTR-Cb4B_JD0.js → architectureDiagram-3BPJPVTR-FKeXQbyP.js} +1 -1
  310. package/web-shell/assets/{blockDiagram-GPEHLZMM-Dsjlh3H-.js → blockDiagram-GPEHLZMM-CY0vc-A3.js} +1 -1
  311. package/web-shell/assets/{c4Diagram-AAUBKEIU-Cp5AeR4U.js → c4Diagram-AAUBKEIU-CNP-A-8u.js} +1 -1
  312. package/web-shell/assets/channel-DPYMT76A.js +1 -0
  313. package/web-shell/assets/{chunk-2J33WTMH-CLcY7W2e.js → chunk-2J33WTMH-GybS4Gii.js} +1 -1
  314. package/web-shell/assets/{chunk-4BX2VUAB-BUhvY2LR.js → chunk-4BX2VUAB-02H91V8v.js} +1 -1
  315. package/web-shell/assets/{chunk-55IACEB6-kDIFC_71.js → chunk-55IACEB6-D3M-2VT6.js} +1 -1
  316. package/web-shell/assets/{chunk-727SXJPM-CIBO15f2.js → chunk-727SXJPM-CCu29u4H.js} +1 -1
  317. package/web-shell/assets/{chunk-AQP2D5EJ-BJ_T_slV.js → chunk-AQP2D5EJ-CaFKWgrn.js} +1 -1
  318. package/web-shell/assets/{chunk-FMBD7UC4-BEkW35J8.js → chunk-FMBD7UC4-ZZpPqIwQ.js} +1 -1
  319. package/web-shell/assets/{chunk-ND2GUHAM-GGPxofay.js → chunk-ND2GUHAM-D22DqGs8.js} +1 -1
  320. package/web-shell/assets/{chunk-QZHKN3VN-Bifllrb6.js → chunk-QZHKN3VN-Bu85S0fw.js} +1 -1
  321. package/web-shell/assets/classDiagram-4FO5ZUOK--JstsIgL.js +1 -0
  322. package/web-shell/assets/classDiagram-v2-Q7XG4LA2--JstsIgL.js +1 -0
  323. package/web-shell/assets/{cose-bilkent-S5V4N54A-C-Add_Dp.js → cose-bilkent-S5V4N54A-f1CK1Gwe.js} +1 -1
  324. package/web-shell/assets/{dagre-BM42HDAG-B7MfwNq2.js → dagre-BM42HDAG-D0Ow8F_n.js} +1 -1
  325. package/web-shell/assets/{diagram-2AECGRRQ-CY_0zuDz.js → diagram-2AECGRRQ-BPrmTWp8.js} +1 -1
  326. package/web-shell/assets/{diagram-5GNKFQAL-VyYSbCgA.js → diagram-5GNKFQAL-HccuFAzy.js} +1 -1
  327. package/web-shell/assets/{diagram-KO2AKTUF-CBiIZ2PL.js → diagram-KO2AKTUF-BrS76mbA.js} +1 -1
  328. package/web-shell/assets/{diagram-LMA3HP47-BL3CrVOx.js → diagram-LMA3HP47-V7T9lU-5.js} +1 -1
  329. package/web-shell/assets/{diagram-OG6HWLK6-CZUPx96P.js → diagram-OG6HWLK6-DKidyJMR.js} +1 -1
  330. package/web-shell/assets/{erDiagram-TEJ5UH35-B81xHr1-.js → erDiagram-TEJ5UH35-DBadZIkp.js} +1 -1
  331. package/web-shell/assets/{flowDiagram-I6XJVG4X-EZWhir-J.js → flowDiagram-I6XJVG4X-BymfqdNJ.js} +1 -1
  332. package/web-shell/assets/{ganttDiagram-6RSMTGT7-CVFSuIAg.js → ganttDiagram-6RSMTGT7-DOw340jf.js} +1 -1
  333. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-C1H2uQDv.js → gitGraphDiagram-PVQCEYII-_8EiD8sl.js} +1 -1
  334. package/web-shell/assets/{index-BYo99NBH.js → index-CKIadvET.js} +1 -1
  335. package/web-shell/assets/index-D1eXNRHe.js +1389 -0
  336. package/web-shell/assets/index-DVLD4CQq.css +5 -0
  337. package/web-shell/assets/{infoDiagram-5YYISTIA-BwyFMlF8.js → infoDiagram-5YYISTIA-D61KYQBu.js} +1 -1
  338. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-CQ7Yhn2Y.js → ishikawaDiagram-YF4QCWOH-CsiXSpNx.js} +1 -1
  339. package/web-shell/assets/{journeyDiagram-JHISSGLW-CJn2sf0l.js → journeyDiagram-JHISSGLW-Sdfionyh.js} +1 -1
  340. package/web-shell/assets/{kanban-definition-UN3LZRKU-DaNRqwVN.js → kanban-definition-UN3LZRKU-C3WI3Cnl.js} +1 -1
  341. package/web-shell/assets/{linear-DCKODZe2.js → linear-Dpigcc62.js} +1 -1
  342. package/web-shell/assets/{mermaid.core-CTGJOk27.js → mermaid.core-Ct97pqgW.js} +5 -5
  343. package/web-shell/assets/{mindmap-definition-RKZ34NQL-BKU3_3rg.js → mindmap-definition-RKZ34NQL-BzeaN0rB.js} +1 -1
  344. package/web-shell/assets/{pieDiagram-4H26LBE5-COcwBJ82.js → pieDiagram-4H26LBE5-CvjgcbVD.js} +1 -1
  345. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-CQnQ443x.js → quadrantDiagram-W4KKPZXB-BUzgTNdH.js} +1 -1
  346. package/web-shell/assets/{requirementDiagram-4Y6WPE33-CZ2oj5cD.js → requirementDiagram-4Y6WPE33-B7zKlgUQ.js} +1 -1
  347. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-BxAv5mNu.js → sankeyDiagram-5OEKKPKP-Bb9CQgrT.js} +1 -1
  348. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CztaySPs.js → sequenceDiagram-3UESZ5HK-DJ6V7itG.js} +1 -1
  349. package/web-shell/assets/{stateDiagram-AJRCARHV-CTQT1oGD.js → stateDiagram-AJRCARHV-IImflERY.js} +1 -1
  350. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CYI_YoNR.js +1 -0
  351. package/web-shell/assets/{timeline-definition-PNZ67QCA-K9Mkex5A.js → timeline-definition-PNZ67QCA-6Q_uWHKh.js} +1 -1
  352. package/web-shell/assets/{vennDiagram-CIIHVFJN-B2rVIw76.js → vennDiagram-CIIHVFJN-TmyKyjwv.js} +1 -1
  353. package/web-shell/assets/{wardley-L42UT6IY-Z1w2JR4M.js → wardley-L42UT6IY-CRh9uiPv.js} +1 -1
  354. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-CIX9aKXf.js → wardleyDiagram-YWT4CUSO-59TKAW8w.js} +1 -1
  355. package/web-shell/assets/{xychartDiagram-2RQKCTM6-CI9DLIKB.js → xychartDiagram-2RQKCTM6-GCSUIK2L.js} +1 -1
  356. package/web-shell/index.html +2 -2
  357. package/chunks/MaxSizedBox-INHRH72H.js +0 -86
  358. package/chunks/agent-VXDAN5JK.js +0 -82
  359. package/chunks/agent-headless-K4ZMMNBD.js +0 -76
  360. package/chunks/bridge-LGPZCFHO.js +0 -91
  361. package/chunks/channel-settings-store-CHCDRTPY.js +0 -89
  362. package/chunks/chunk-SZRN75WQ.js +0 -29
  363. package/chunks/chunk-UGYMA4EI.js +0 -219
  364. package/chunks/chunk-VCBZUOSI.js +0 -8575
  365. package/chunks/contextCommand-QIZYHDR5.js +0 -81
  366. package/chunks/daemon-status-provider-OS5UWBHV.js +0 -90
  367. package/chunks/earlyInputCapture-WQT24RWD.js +0 -83
  368. package/chunks/errors-PCX25DVP.js +0 -89
  369. package/chunks/exitPlanMode-GHPUHBZJ.js +0 -423
  370. package/chunks/handleAutoUpdate-2CZQRJ66.js +0 -82
  371. package/chunks/i18n-XEQVMRKN.js +0 -98
  372. package/chunks/initializer-OVGZ4FLY.js +0 -87
  373. package/chunks/installationInfo-5UUQJI6Y.js +0 -81
  374. package/chunks/list-HODU6RXD.js +0 -90
  375. package/chunks/loadedSettingsAdapter-TYNLBALY.js +0 -84
  376. package/chunks/mcp-J3DFWX4A.js +0 -84
  377. package/chunks/nonInteractiveCli-F4GYSMHT.js +0 -144
  378. package/chunks/pidfile-4VNAR3EP.js +0 -87
  379. package/chunks/read-file-LZXUR4TO.js +0 -31
  380. package/chunks/resumeHistoryUtils-65OX3SGJ.js +0 -92
  381. package/chunks/ripGrep-2U2FRGMV.js +0 -74
  382. package/chunks/serve-W2GC47CM.js +0 -90
  383. package/chunks/shell-45IPBDP5.js +0 -84
  384. package/chunks/spawnChannel-PVXQ5AGV.js +0 -83
  385. package/chunks/src-AY65BYR7.js +0 -3166
  386. package/chunks/standalone-update-ZMFNKAEY.js +0 -93
  387. package/chunks/theme-manager-YYPZFBAH.js +0 -78
  388. package/chunks/total-session-admission-JXES723M.js +0 -85
  389. package/chunks/trustedFolders-HVI7IXUH.js +0 -94
  390. package/chunks/updateCheck-WUJGHWZZ.js +0 -93
  391. package/chunks/useAutoAcceptIndicator-CHSTZLZD.js +0 -94
  392. package/chunks/workspace-providers-status-GAKSF4LL.js +0 -87
  393. package/chunks/workspace-registry-A7NQUONG.js +0 -89
  394. package/chunks/workspace-service-STGVSO4N.js +0 -99
  395. package/chunks/workspace-skills-status-66AK3DUA.js +0 -86
  396. package/chunks/write-file-HUUCEG4P.js +0 -74
  397. package/web-shell/assets/channel-Bzdx6E8P.js +0 -1
  398. package/web-shell/assets/classDiagram-4FO5ZUOK-Cd6wbiuK.js +0 -1
  399. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Cd6wbiuK.js +0 -1
  400. package/web-shell/assets/index-B2bXx96W.js +0 -1249
  401. package/web-shell/assets/index-_8mKjx8q.css +0 -5
  402. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BjMdT6E_.js +0 -1
  403. package/chunks/{chunk-TARRHLLG.js → chunk-QUGAUQGJ.js} +25 -25
  404. package/chunks/{chunk-U7ZFW55U.js → chunk-VOQXFAY5.js} +977 -977
  405. /package/chunks/{chunk-LXXMOYPL.js → chunk-VXZBKKQR.js} +0 -0
@@ -12,6 +12,163 @@ import {
12
12
  __name
13
13
  } from "./chunk-J2S4EL5Y.js";
14
14
 
15
+ // packages/channels/base/dist/ChannelLoopTools.js
16
+ init_esbuild_shims();
17
+ var CHANNEL_LOOP_MCP_SERVER_NAME = "channel_loop";
18
+ var CLIENT_MCP_MESSAGE_METHOD = "qwen/control/client_mcp/message";
19
+ var WORKSPACE_MCP_RUNTIME_ADD_METHOD = "qwen/control/workspace/mcp/runtime-add";
20
+ var CLIENT_MCP_OVER_WS_CONFIG_FLAG = "__clientMcpOverWs";
21
+ var createTool = {
22
+ name: "channel_loop_create",
23
+ description: "Create a recurring proactive reminder or scheduled prompt for the current channel chat. Use this in channel sessions instead of cron_create.",
24
+ inputSchema: {
25
+ type: "object",
26
+ properties: {
27
+ cron: {
28
+ type: "string",
29
+ description: 'Standard 5-field cron expression in local time, for example "*/5 * * * *".'
30
+ },
31
+ prompt: {
32
+ type: "string",
33
+ description: "The message or instruction to run and proactively push to this channel chat."
34
+ },
35
+ recurring: {
36
+ type: "boolean",
37
+ description: "Whether the loop recurs. Defaults to true."
38
+ }
39
+ },
40
+ required: ["cron", "prompt"]
41
+ }
42
+ };
43
+ var listTool = {
44
+ name: "channel_loop_list",
45
+ description: "List proactive loops for the current channel chat.",
46
+ inputSchema: { type: "object", properties: {} }
47
+ };
48
+ var cancelTool = {
49
+ name: "channel_loop_cancel",
50
+ description: "Cancel a proactive loop for the current channel chat.",
51
+ inputSchema: {
52
+ type: "object",
53
+ properties: {
54
+ id: { type: "string", description: "Loop id to cancel." }
55
+ },
56
+ required: ["id"]
57
+ }
58
+ };
59
+ var CHANNEL_LOOP_MCP_TOOLS = [createTool, listTool, cancelTool];
60
+ var ChannelLoopMcpServer = class {
61
+ static {
62
+ __name(this, "ChannelLoopMcpServer");
63
+ }
64
+ handler;
65
+ constructor(handler) {
66
+ this.handler = handler;
67
+ }
68
+ async handleMessage(message, context) {
69
+ const id = message["id"];
70
+ if (id === void 0 || id === null) {
71
+ return void 0;
72
+ }
73
+ try {
74
+ const result = await this.dispatch(message, context);
75
+ return { jsonrpc: "2.0", id, result };
76
+ } catch (error) {
77
+ return {
78
+ jsonrpc: "2.0",
79
+ id,
80
+ error: {
81
+ code: -32603,
82
+ message: error instanceof Error ? error.message : String(error)
83
+ }
84
+ };
85
+ }
86
+ }
87
+ async dispatch(message, context) {
88
+ switch (message["method"]) {
89
+ case "initialize":
90
+ return {
91
+ protocolVersion: "2024-11-05",
92
+ capabilities: { tools: {} },
93
+ serverInfo: { name: CHANNEL_LOOP_MCP_SERVER_NAME, version: "0.0.1" }
94
+ };
95
+ case "tools/list":
96
+ return { tools: CHANNEL_LOOP_MCP_TOOLS };
97
+ case "tools/call":
98
+ return this.callTool(message["params"], context);
99
+ case "ping":
100
+ return {};
101
+ default:
102
+ throw new Error(`Method not found: ${String(message["method"])}`);
103
+ }
104
+ }
105
+ async callTool(rawParams, context) {
106
+ if (!context.sessionId) {
107
+ throw new Error("Missing channel session id.");
108
+ }
109
+ if (typeof rawParams !== "object" || rawParams === null) {
110
+ throw new Error("Invalid tools/call params.");
111
+ }
112
+ const params = rawParams;
113
+ const name = params["name"];
114
+ const args = typeof params["arguments"] === "object" && params["arguments"] !== null ? params["arguments"] : {};
115
+ let toolResult;
116
+ switch (name) {
117
+ case createTool.name:
118
+ toolResult = await this.handler.create(context.sessionId, readCreateInput(args));
119
+ break;
120
+ case listTool.name:
121
+ toolResult = await this.handler.list(context.sessionId);
122
+ break;
123
+ case cancelTool.name:
124
+ toolResult = await this.handler.cancel(context.sessionId, readId(args));
125
+ break;
126
+ default:
127
+ throw new Error(`Unknown channel loop tool: ${String(name)}`);
128
+ }
129
+ const result = typeof toolResult === "string" ? { text: toolResult } : toolResult;
130
+ return {
131
+ content: [{ type: "text", text: result.text }],
132
+ ...result.isError ? { isError: true } : {}
133
+ };
134
+ }
135
+ };
136
+ function readCreateInput(args) {
137
+ const cron = args["cron"];
138
+ const prompt = args["prompt"];
139
+ if (typeof cron !== "string" || cron.trim().length === 0) {
140
+ throw new Error("cron must be a non-empty string.");
141
+ }
142
+ if (typeof prompt !== "string" || prompt.trim().length === 0) {
143
+ throw new Error("prompt must be a non-empty string.");
144
+ }
145
+ const recurring = readRecurring(args["recurring"]);
146
+ return {
147
+ cron: cron.trim(),
148
+ prompt: prompt.trim(),
149
+ ...recurring !== void 0 ? { recurring } : {}
150
+ };
151
+ }
152
+ __name(readCreateInput, "readCreateInput");
153
+ function readRecurring(value) {
154
+ if (typeof value === "boolean")
155
+ return value;
156
+ if (value === "false" || value === 0)
157
+ return false;
158
+ if (value === "true" || value === 1)
159
+ return true;
160
+ return void 0;
161
+ }
162
+ __name(readRecurring, "readRecurring");
163
+ function readId(args) {
164
+ const id = args["id"];
165
+ if (typeof id !== "string" || id.trim().length === 0) {
166
+ throw new Error("id must be a non-empty string.");
167
+ }
168
+ return id.trim();
169
+ }
170
+ __name(readId, "readId");
171
+
15
172
  // packages/channels/base/dist/sanitize.js
16
173
  init_esbuild_shims();
17
174
  var PROMPT_UNSAFE_INVISIBLES = new RegExp("[\\u0080-\\u009f\\p{Cf}\\u2028\\u2029]|\\p{Variation_Selector}", "gu");
@@ -294,166 +451,8 @@ import { spawn } from "node:child_process";
294
451
  import { randomUUID } from "node:crypto";
295
452
  import { Readable, Writable } from "node:stream";
296
453
  import { EventEmitter } from "node:events";
297
-
298
- // packages/channels/base/dist/ChannelLoopTools.js
299
- init_esbuild_shims();
300
- var CHANNEL_LOOP_MCP_SERVER_NAME = "channel_loop";
301
- var CLIENT_MCP_MESSAGE_METHOD = "qwen/control/client_mcp/message";
302
- var WORKSPACE_MCP_RUNTIME_ADD_METHOD = "qwen/control/workspace/mcp/runtime-add";
303
- var CLIENT_MCP_OVER_WS_CONFIG_FLAG = "__clientMcpOverWs";
304
- var createTool = {
305
- name: "channel_loop_create",
306
- description: "Create a recurring proactive reminder or scheduled prompt for the current channel chat. Use this in channel sessions instead of cron_create.",
307
- inputSchema: {
308
- type: "object",
309
- properties: {
310
- cron: {
311
- type: "string",
312
- description: 'Standard 5-field cron expression in local time, for example "*/5 * * * *".'
313
- },
314
- prompt: {
315
- type: "string",
316
- description: "The message or instruction to run and proactively push to this channel chat."
317
- },
318
- recurring: {
319
- type: "boolean",
320
- description: "Whether the loop recurs. Defaults to true."
321
- }
322
- },
323
- required: ["cron", "prompt"]
324
- }
325
- };
326
- var listTool = {
327
- name: "channel_loop_list",
328
- description: "List proactive loops for the current channel chat.",
329
- inputSchema: { type: "object", properties: {} }
330
- };
331
- var cancelTool = {
332
- name: "channel_loop_cancel",
333
- description: "Cancel a proactive loop for the current channel chat.",
334
- inputSchema: {
335
- type: "object",
336
- properties: {
337
- id: { type: "string", description: "Loop id to cancel." }
338
- },
339
- required: ["id"]
340
- }
341
- };
342
- var CHANNEL_LOOP_MCP_TOOLS = [createTool, listTool, cancelTool];
343
- var ChannelLoopMcpServer = class {
344
- static {
345
- __name(this, "ChannelLoopMcpServer");
346
- }
347
- handler;
348
- constructor(handler) {
349
- this.handler = handler;
350
- }
351
- async handleMessage(message, context) {
352
- const id = message["id"];
353
- if (id === void 0 || id === null) {
354
- return void 0;
355
- }
356
- try {
357
- const result = await this.dispatch(message, context);
358
- return { jsonrpc: "2.0", id, result };
359
- } catch (error) {
360
- return {
361
- jsonrpc: "2.0",
362
- id,
363
- error: {
364
- code: -32603,
365
- message: error instanceof Error ? error.message : String(error)
366
- }
367
- };
368
- }
369
- }
370
- async dispatch(message, context) {
371
- switch (message["method"]) {
372
- case "initialize":
373
- return {
374
- protocolVersion: "2024-11-05",
375
- capabilities: { tools: {} },
376
- serverInfo: { name: CHANNEL_LOOP_MCP_SERVER_NAME, version: "0.0.1" }
377
- };
378
- case "tools/list":
379
- return { tools: CHANNEL_LOOP_MCP_TOOLS };
380
- case "tools/call":
381
- return this.callTool(message["params"], context);
382
- case "ping":
383
- return {};
384
- default:
385
- throw new Error(`Method not found: ${String(message["method"])}`);
386
- }
387
- }
388
- async callTool(rawParams, context) {
389
- if (!context.sessionId) {
390
- throw new Error("Missing channel session id.");
391
- }
392
- if (typeof rawParams !== "object" || rawParams === null) {
393
- throw new Error("Invalid tools/call params.");
394
- }
395
- const params = rawParams;
396
- const name = params["name"];
397
- const args = typeof params["arguments"] === "object" && params["arguments"] !== null ? params["arguments"] : {};
398
- let toolResult;
399
- switch (name) {
400
- case createTool.name:
401
- toolResult = await this.handler.create(context.sessionId, readCreateInput(args));
402
- break;
403
- case listTool.name:
404
- toolResult = await this.handler.list(context.sessionId);
405
- break;
406
- case cancelTool.name:
407
- toolResult = await this.handler.cancel(context.sessionId, readId(args));
408
- break;
409
- default:
410
- throw new Error(`Unknown channel loop tool: ${String(name)}`);
411
- }
412
- const result = typeof toolResult === "string" ? { text: toolResult } : toolResult;
413
- return {
414
- content: [{ type: "text", text: result.text }],
415
- ...result.isError ? { isError: true } : {}
416
- };
417
- }
418
- };
419
- function readCreateInput(args) {
420
- const cron = args["cron"];
421
- const prompt = args["prompt"];
422
- if (typeof cron !== "string" || cron.trim().length === 0) {
423
- throw new Error("cron must be a non-empty string.");
424
- }
425
- if (typeof prompt !== "string" || prompt.trim().length === 0) {
426
- throw new Error("prompt must be a non-empty string.");
427
- }
428
- const recurring = readRecurring(args["recurring"]);
429
- return {
430
- cron: cron.trim(),
431
- prompt: prompt.trim(),
432
- ...recurring !== void 0 ? { recurring } : {}
433
- };
434
- }
435
- __name(readCreateInput, "readCreateInput");
436
- function readRecurring(value) {
437
- if (typeof value === "boolean")
438
- return value;
439
- if (value === "false" || value === 0)
440
- return false;
441
- if (value === "true" || value === 1)
442
- return true;
443
- return void 0;
444
- }
445
- __name(readRecurring, "readRecurring");
446
- function readId(args) {
447
- const id = args["id"];
448
- if (typeof id !== "string" || id.trim().length === 0) {
449
- throw new Error("id must be a non-empty string.");
450
- }
451
- return id.trim();
452
- }
453
- __name(readId, "readId");
454
-
455
- // packages/channels/base/dist/AcpBridge.js
456
454
  var MID_TURN_QUEUE_DRAIN_METHOD = "craft/drainMidTurnQueue";
455
+ var TODO_STOP_GUARD_CONTINUATION_CLAIM_METHOD = "craft/claimTodoStopGuardContinuation";
457
456
  var ACP_EVENT_LOOP_STALL_RESTART_MS = 5 * 60 * 1e3;
458
457
  var ACP_PERMISSION_RESPONSE_TIMEOUT_MS = 5 * 60 * 1e3;
459
458
  var ACP_EVENT_LOOP_STALL_RE = /^\[perf\] acp agent event loop stall: max=(\d+(?:\.\d+)?)ms/m;
@@ -480,6 +479,8 @@ var AcpBridge = class extends EventEmitter {
480
479
  _availableCommands = [];
481
480
  channelLoopMcpServer;
482
481
  channelLoopToolHandlers = [];
482
+ knownSessionIds = /* @__PURE__ */ new Set();
483
+ sessionBindingTokens = /* @__PURE__ */ new Map();
483
484
  channelLoopMcpRegistered = false;
484
485
  channelLoopMcpRegistration = null;
485
486
  pendingPermissions = /* @__PURE__ */ new Map();
@@ -518,6 +519,8 @@ var AcpBridge = class extends EventEmitter {
518
519
  process.stderr.write(`[AcpBridge] Process exited (code=${code}, signal=${signal})
519
520
  `);
520
521
  this.resolvePendingPermissions();
522
+ this.knownSessionIds.clear();
523
+ this.sessionBindingTokens.clear();
521
524
  this.connection = null;
522
525
  this.child = null;
523
526
  this.emit("disconnected", code, signal);
@@ -556,21 +559,25 @@ var AcpBridge = class extends EventEmitter {
556
559
  });
557
560
  void this.registerChannelLoopMcpServer();
558
561
  }
559
- async newSession(cwd) {
562
+ async newSession(cwd, _options, bindingToken) {
560
563
  const conn = this.ensureConnection();
561
564
  await this.registerChannelLoopMcpServer();
562
565
  const response = await conn.newSession({ cwd, mcpServers: [] });
566
+ this.knownSessionIds.add(response.sessionId);
567
+ this.sessionBindingTokens.set(response.sessionId, bindingToken);
563
568
  return response.sessionId;
564
569
  }
565
- async loadSession(sessionId, cwd) {
570
+ async loadSession(sessionId, cwd, _options, bindingToken) {
566
571
  const conn = this.ensureConnection();
567
572
  await this.registerChannelLoopMcpServer();
568
- const response = await conn.loadSession({
573
+ await conn.loadSession({
569
574
  sessionId,
570
575
  cwd,
571
576
  mcpServers: []
572
577
  });
573
- return response.sessionId;
578
+ this.knownSessionIds.add(sessionId);
579
+ this.sessionBindingTokens.set(sessionId, bindingToken);
580
+ return sessionId;
574
581
  }
575
582
  async prompt(sessionId, text, options) {
576
583
  const conn = this.ensureConnection();
@@ -622,6 +629,19 @@ var AcpBridge = class extends EventEmitter {
622
629
  this.resolvePendingPermissions(sessionId);
623
630
  }
624
631
  }
632
+ async discardSession(sessionId, expectedBindingToken) {
633
+ if (expectedBindingToken !== void 0 && this.sessionBindingTokens.get(sessionId) !== expectedBindingToken) {
634
+ return;
635
+ }
636
+ if (!this.knownSessionIds.delete(sessionId))
637
+ return;
638
+ this.sessionBindingTokens.delete(sessionId);
639
+ this.resolvePendingPermissions(sessionId);
640
+ const conn = this.connection;
641
+ if (!conn || !this.isConnected)
642
+ return;
643
+ await conn.extMethod("qwen/control/session/close", { sessionId });
644
+ }
625
645
  async respondToPermission(requestId, response) {
626
646
  const pending = this.pendingPermissions.get(requestId);
627
647
  if (!pending) {
@@ -638,6 +658,8 @@ var AcpBridge = class extends EventEmitter {
638
658
  }
639
659
  stop() {
640
660
  this.resolvePendingPermissions();
661
+ this.knownSessionIds.clear();
662
+ this.sessionBindingTokens.clear();
641
663
  if (this.child) {
642
664
  this.child.kill();
643
665
  this.child = null;
@@ -814,7 +836,14 @@ var AcpBridge = class extends EventEmitter {
814
836
  return this.handleClientMcpMessage(params);
815
837
  }
816
838
  if (method === MID_TURN_QUEUE_DRAIN_METHOD) {
817
- return { messages: [] };
839
+ return { messages: [], hasQueuedPrompt: false };
840
+ }
841
+ if (method === TODO_STOP_GUARD_CONTINUATION_CLAIM_METHOD) {
842
+ const sessionId = typeof params["sessionId"] === "string" ? params["sessionId"] : "";
843
+ return {
844
+ claimed: this.knownSessionIds.has(sessionId),
845
+ hasQueuedPrompt: false
846
+ };
818
847
  }
819
848
  throw new Error(`Method not found: ${method}`);
820
849
  }
@@ -948,6 +977,10 @@ var DaemonChannelBridge = class extends EventEmitter2 {
948
977
  activePromptControllers = /* @__PURE__ */ new Map();
949
978
  availableCommandsBySession = /* @__PURE__ */ new Map();
950
979
  turnBarriers = /* @__PURE__ */ new Map();
980
+ channelLoopToolHandlers = [];
981
+ registeredChannelLoopMcpSessions = /* @__PURE__ */ new Set();
982
+ channelLoopMcpRegistrations = /* @__PURE__ */ new Map();
983
+ channelLoopMcpServer;
951
984
  connected = false;
952
985
  lifecycleGeneration = 0;
953
986
  latestAvailableCommandsSessionId;
@@ -998,6 +1031,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
998
1031
  await this.rejectStaleSession(session);
999
1032
  }
1000
1033
  this.attachSession(session, bindingToken);
1034
+ await this.registerChannelLoopMcpForSession(session.sessionId);
1001
1035
  return session.sessionId;
1002
1036
  }
1003
1037
  async loadSession(sessionId, cwd, options, bindingToken) {
@@ -1019,8 +1053,22 @@ var DaemonChannelBridge = class extends EventEmitter2 {
1019
1053
  throw new Error(`Daemon returned session ${session.sessionId} while loading ${sessionId}`);
1020
1054
  }
1021
1055
  this.attachSession(session, bindingToken);
1056
+ await this.registerChannelLoopMcpForSession(session.sessionId);
1022
1057
  return session.sessionId;
1023
1058
  }
1059
+ registerChannelLoopToolHandler(handler) {
1060
+ if (!this.channelLoopToolHandlers.includes(handler)) {
1061
+ this.channelLoopToolHandlers.push(handler);
1062
+ }
1063
+ this.channelLoopMcpServer ??= new ChannelLoopMcpServer({
1064
+ create: /* @__PURE__ */ __name((sessionId, input) => this.resolveChannelLoopToolHandler(sessionId).create(sessionId, input), "create"),
1065
+ list: /* @__PURE__ */ __name((sessionId) => this.resolveChannelLoopToolHandler(sessionId).list(sessionId), "list"),
1066
+ cancel: /* @__PURE__ */ __name((sessionId, id) => this.resolveChannelLoopToolHandler(sessionId).cancel(sessionId, id), "cancel")
1067
+ });
1068
+ for (const sessionId of this.sessions.keys()) {
1069
+ void this.registerChannelLoopMcpForSession(sessionId);
1070
+ }
1071
+ }
1024
1072
  async prompt(sessionId, text, options) {
1025
1073
  const session = this.ensureSession(sessionId);
1026
1074
  if (this.activePrompts.has(sessionId)) {
@@ -1177,7 +1225,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
1177
1225
  return this.connected;
1178
1226
  }
1179
1227
  attachSession(session, bindingToken) {
1180
- const replacedSession = this.removeSessionBinding(session.sessionId);
1228
+ const replacedSession = this.removeSessionBinding(session.sessionId, false);
1181
1229
  if (replacedSession) {
1182
1230
  void this.releaseSessionClient(replacedSession).catch((error) => {
1183
1231
  this.lastError = error;
@@ -1441,7 +1489,7 @@ var DaemonChannelBridge = class extends EventEmitter2 {
1441
1489
  }
1442
1490
  this.emit("sessionDied", { sessionId, reason });
1443
1491
  }
1444
- removeSessionBinding(sessionId) {
1492
+ removeSessionBinding(sessionId, unregisterChannelLoopMcp = true) {
1445
1493
  const session = this.sessions.get(sessionId);
1446
1494
  if (!session)
1447
1495
  return void 0;
@@ -1466,8 +1514,51 @@ var DaemonChannelBridge = class extends EventEmitter2 {
1466
1514
  this.respondedRequestToSession.delete(requestId);
1467
1515
  }
1468
1516
  }
1517
+ if (unregisterChannelLoopMcp) {
1518
+ this.unregisterChannelLoopMcpForSession(sessionId);
1519
+ }
1469
1520
  return session;
1470
1521
  }
1522
+ async registerChannelLoopMcpForSession(sessionId) {
1523
+ const host = this.options.channelLoopMcpHost;
1524
+ const server = this.channelLoopMcpServer;
1525
+ if (!host || !server || this.registeredChannelLoopMcpSessions.has(sessionId)) {
1526
+ return;
1527
+ }
1528
+ const pending = this.channelLoopMcpRegistrations.get(sessionId);
1529
+ if (pending) {
1530
+ await pending;
1531
+ return;
1532
+ }
1533
+ const registration = host.register(sessionId, (message) => server.handleMessage(message, { sessionId })).then(async () => {
1534
+ if (this.sessions.has(sessionId)) {
1535
+ this.registeredChannelLoopMcpSessions.add(sessionId);
1536
+ } else {
1537
+ await host.unregister(sessionId);
1538
+ }
1539
+ }).catch((error) => {
1540
+ this.lastError = error;
1541
+ }).finally(() => {
1542
+ if (this.channelLoopMcpRegistrations.get(sessionId) === registration) {
1543
+ this.channelLoopMcpRegistrations.delete(sessionId);
1544
+ }
1545
+ });
1546
+ this.channelLoopMcpRegistrations.set(sessionId, registration);
1547
+ await registration;
1548
+ }
1549
+ unregisterChannelLoopMcpForSession(sessionId) {
1550
+ if (!this.registeredChannelLoopMcpSessions.delete(sessionId))
1551
+ return;
1552
+ void this.options.channelLoopMcpHost?.unregister(sessionId).catch((error) => {
1553
+ this.lastError = error;
1554
+ });
1555
+ }
1556
+ resolveChannelLoopToolHandler(sessionId) {
1557
+ const handler = this.channelLoopToolHandlers.find((candidate) => candidate.canHandle?.(sessionId) === true || this.channelLoopToolHandlers.length === 1 && !candidate.canHandle);
1558
+ if (handler)
1559
+ return handler;
1560
+ throw new Error(`No channel loop handler matched session ${sessionId}.`);
1561
+ }
1471
1562
  getStringField(data, field, fallback) {
1472
1563
  return isRecord(data) && typeof data[field] === "string" ? data[field] : fallback;
1473
1564
  }
@@ -1963,6 +2054,9 @@ var SenderGate = class {
1963
2054
  this.allowedUsers = new Set(allowedUsers);
1964
2055
  this.pairingStore = pairingStore || null;
1965
2056
  }
2057
+ replaceAllowedUsers(users) {
2058
+ this.allowedUsers = new Set(users);
2059
+ }
1966
2060
  isAllowed(senderId) {
1967
2061
  switch (this.policy) {
1968
2062
  case "open":
@@ -2051,6 +2145,8 @@ var SessionRouter = class {
2051
2145
  switch (scope) {
2052
2146
  case "thread":
2053
2147
  return `${channelName}:${threadId || chatId}`;
2148
+ case "chat_thread":
2149
+ return threadId ? `${channelName}:${chatId}:${threadId}` : `${channelName}:${chatId}`;
2054
2150
  case "single":
2055
2151
  return `${channelName}:__single__`;
2056
2152
  case "user":
@@ -3425,7 +3521,7 @@ var ChannelBase = class {
3425
3521
  if (target.threadId !== void 0 && this.supportsProactiveSend() && this.supportsProactiveTarget(target)) {
3426
3522
  await this.pushProactive(target, text);
3427
3523
  } else {
3428
- await this.sendMessage(target.chatId, text);
3524
+ await this.sendThreadMessage(target.chatId, target.threadId, text);
3429
3525
  }
3430
3526
  } catch (err) {
3431
3527
  this.removePendingPermission(event.requestId);
@@ -3494,6 +3590,14 @@ var ChannelBase = class {
3494
3590
  this.attachBridgeEvents(bridge);
3495
3591
  }
3496
3592
  }
3593
+ /**
3594
+ * Thread-targeted delivery. Polling adapters override this to post comments
3595
+ * on a specific issue/PR. The default falls through to sendMessage(chatId,
3596
+ * text), ignoring threadId — existing IM adapters are behaviorally unchanged.
3597
+ */
3598
+ async sendThreadMessage(chatId, _threadId, text) {
3599
+ await this.sendMessage(chatId, text);
3600
+ }
3497
3601
  /**
3498
3602
  * Adapter hook for task lifecycle events — the canonical way to track task
3499
3603
  * state (onPromptStart/onPromptEnd are retained for back-compat). The prompt
@@ -3624,7 +3728,7 @@ var ChannelBase = class {
3624
3728
  if (target.threadId) {
3625
3729
  throw new Error("Channel does not support proactive loop messages for threaded targets.");
3626
3730
  }
3627
- await this.sendMessage(target.chatId, text);
3731
+ await this.sendThreadMessage(target.chatId, target.threadId, text);
3628
3732
  }
3629
3733
  async pushProactiveDelivery(target, text) {
3630
3734
  try {
@@ -3807,6 +3911,7 @@ var ChannelBase = class {
3807
3911
  alreadyPrefixed: true,
3808
3912
  referencedText: void 0,
3809
3913
  attachments: void 0,
3914
+ metadata: void 0,
3810
3915
  imageBase64: void 0,
3811
3916
  imageMimeType: void 0
3812
3917
  };
@@ -4274,6 +4379,7 @@ ${promptText}` : promptText;
4274
4379
  this.router.removeSessionId(sessionId);
4275
4380
  this.instructedSessions.delete(sessionId);
4276
4381
  this.unattendedMemorySessions.delete(sessionId);
4382
+ this.discardRetiredSession(promptBridge, sessionId, `timed-out loop ${jobId}`);
4277
4383
  process.stderr.write(`[${this.name}] retired timed out loop ${jobId} session ${sessionId} after cancel did not settle
4278
4384
  `);
4279
4385
  }
@@ -4284,6 +4390,19 @@ ${promptText}` : promptText;
4284
4390
  clearTimeout(graceTimer);
4285
4391
  }
4286
4392
  }
4393
+ discardRetiredSession(promptBridge, sessionId, reason) {
4394
+ const safeSessionId = sanitizeLogText(sessionId, 64);
4395
+ const safeReason = sanitizeLogText(reason, 128);
4396
+ try {
4397
+ void promptBridge.discardSession?.(sessionId).catch((err) => {
4398
+ process.stderr.write(`[${this.name}] failed to discard ${safeReason} session ${safeSessionId}: ${this.lifecycleError(err)}
4399
+ `);
4400
+ });
4401
+ } catch (err) {
4402
+ process.stderr.write(`[${this.name}] failed to discard ${safeReason} session ${safeSessionId}: ${this.lifecycleError(err)}
4403
+ `);
4404
+ }
4405
+ }
4287
4406
  requestActivePromptCancellation(sessionId, reason = "cancel_command") {
4288
4407
  const active = this.activePrompts.get(sessionId);
4289
4408
  if (!active) {
@@ -4422,8 +4541,11 @@ ${promptText}` : promptText;
4422
4541
  */
4423
4542
  onResponseBoundary(_chatId, _sessionId) {
4424
4543
  }
4425
- async sendResponseMessage(chatId, text, _sessionId) {
4426
- await this.sendMessage(chatId, text);
4544
+ async sendResponseMessage(chatId, text, sessionId) {
4545
+ const active = this.activePrompts.get(sessionId);
4546
+ const target = this.router.getTarget(sessionId);
4547
+ const threadId = active?.threadId ?? target?.threadId;
4548
+ await this.sendThreadMessage(chatId, threadId, text);
4427
4549
  }
4428
4550
  /**
4429
4551
  * Called when the agent's full response is ready.
@@ -4444,21 +4566,21 @@ ${promptText}` : promptText;
4444
4566
  registerCancelCommand(name = "cancel") {
4445
4567
  this.registerCommand(name, async (envelope) => {
4446
4568
  if (!this.isAuthorizedForSharedSession(envelope)) {
4447
- await this.sendMessage(envelope.chatId, "Only authorized members can cancel requests in this shared session.");
4569
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can cancel requests in this shared session.");
4448
4570
  return true;
4449
4571
  }
4450
4572
  const activeSessionId = this.findActiveSessionId(envelope);
4451
4573
  if (!activeSessionId) {
4452
- await this.sendMessage(envelope.chatId, "No request is currently running.");
4574
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No request is currently running.");
4453
4575
  return true;
4454
4576
  }
4455
4577
  const active = this.activePrompts.get(activeSessionId);
4456
4578
  if (!active) {
4457
- await this.sendMessage(envelope.chatId, "No request is currently running.");
4579
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No request is currently running.");
4458
4580
  return true;
4459
4581
  }
4460
4582
  const cancelSucceeded = await this.requestActivePromptCancellation(activeSessionId, "cancel_command");
4461
- await this.sendMessage(envelope.chatId, cancelSucceeded ? "Cancelled current request." : "Failed to cancel current request.");
4583
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, cancelSucceeded ? "Cancelled current request." : "Failed to cancel current request.");
4462
4584
  return true;
4463
4585
  });
4464
4586
  }
@@ -4590,7 +4712,7 @@ ${promptText}` : promptText;
4590
4712
  }
4591
4713
  async handlePermissionResponseCommand(envelope, args, decision) {
4592
4714
  if (!this.isAuthorizedForSharedSession(envelope)) {
4593
- await this.sendMessage(envelope.chatId, "Only authorized members can answer permission requests in this shared session.");
4715
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can answer permission requests in this shared session.");
4594
4716
  return true;
4595
4717
  }
4596
4718
  const lookup = this.pendingPermissionForEnvelope(envelope, args);
@@ -4600,16 +4722,16 @@ ${promptText}` : promptText;
4600
4722
  const title = pending2 ? `: ${sanitizeQuotedText(pending2.request.toolCall.title || "Tool use", 160)}` : "";
4601
4723
  return `- ${sanitizeQuotedText(id, 128)}${title}`;
4602
4724
  }).join("\n");
4603
- await this.sendMessage(envelope.chatId, `Multiple permission requests are pending for this chat. Reply with /${decision} <request-id>.
4725
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Multiple permission requests are pending for this chat. Reply with /${decision} <request-id>.
4604
4726
  ${requestList}`);
4605
4727
  return true;
4606
4728
  }
4607
4729
  if (lookup.kind === "none") {
4608
- await this.sendMessage(envelope.chatId, lookup.explicit ? "No pending permission request with that id for this chat." : "No pending permission request for this chat.");
4730
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, lookup.explicit ? "No pending permission request with that id for this chat." : "No pending permission request for this chat.");
4609
4731
  return true;
4610
4732
  }
4611
4733
  if (!this.bridge.respondToPermission) {
4612
- await this.sendMessage(envelope.chatId, "Permission relay is not available for this session.");
4734
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Permission relay is not available for this session.");
4613
4735
  return true;
4614
4736
  }
4615
4737
  const { pending } = lookup;
@@ -4621,7 +4743,7 @@ ${requestList}`);
4621
4743
  return optionId ? { outcome: { outcome: "selected", optionId } } : void 0;
4622
4744
  })();
4623
4745
  if (!response) {
4624
- await this.sendMessage(envelope.chatId, decision === "approve-always" ? "This permission request has no always-allow option." : "This permission request has no approvable option.");
4746
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, decision === "approve-always" ? "This permission request has no always-allow option." : "This permission request has no approvable option.");
4625
4747
  return true;
4626
4748
  }
4627
4749
  let accepted;
@@ -4631,11 +4753,11 @@ ${requestList}`);
4631
4753
  this.removePendingPermission(pending.requestId);
4632
4754
  process.stderr.write(`[${this.name}] permission response failed for request ${sanitizeLogText(pending.requestId, 128)}: ${this.lifecycleError(err)}
4633
4755
  `);
4634
- await this.sendMessage(envelope.chatId, "Failed to answer the permission request.");
4756
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Failed to answer the permission request.");
4635
4757
  return true;
4636
4758
  }
4637
4759
  this.removePendingPermission(pending.requestId);
4638
- await this.sendMessage(envelope.chatId, accepted ? decision === "approve" ? "Permission approved." : decision === "approve-always" ? "Permission approved always." : "Permission denied." : "Permission request is no longer pending.");
4760
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, accepted ? decision === "approve" ? "Permission approved." : decision === "approve-always" ? "Permission approved always." : "Permission denied." : "Permission request is no longer pending.");
4639
4761
  return true;
4640
4762
  }
4641
4763
  /** Register shared slash commands. Called from constructor. */
@@ -4685,19 +4807,20 @@ ${requestList}`);
4685
4807
  } else {
4686
4808
  this.sessionGenerations.delete(id);
4687
4809
  }
4810
+ this.discardRetiredSession(this.bridge, id, "cleared");
4688
4811
  }
4689
- await this.sendMessage(envelope.chatId, "Session cleared. The next message starts a fresh conversation.");
4812
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Session cleared. The next message starts a fresh conversation.");
4690
4813
  } else {
4691
- await this.sendMessage(envelope.chatId, "No active session to clear.");
4814
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No active session to clear.");
4692
4815
  }
4693
4816
  }, "doClear");
4694
4817
  const clearHandler = /* @__PURE__ */ __name(async (envelope, args) => {
4695
4818
  if (!this.isAuthorizedForSharedSession(envelope)) {
4696
- await this.sendMessage(envelope.chatId, "Only authorized members can clear this shared session.");
4819
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can clear this shared session.");
4697
4820
  return true;
4698
4821
  }
4699
4822
  if (this.isSharedSession(envelope) && args.toLowerCase() !== "confirm") {
4700
- await this.sendMessage(envelope.chatId, 'This clears the shared session for everyone who shares it. Re-send with "confirm" (e.g. /clear confirm) to proceed.');
4823
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'This clears the shared session for everyone who shares it. Re-send with "confirm" (e.g. /clear confirm) to proceed.');
4701
4824
  return true;
4702
4825
  }
4703
4826
  await doClear(envelope);
@@ -4711,12 +4834,12 @@ ${requestList}`);
4711
4834
  this.registerCommand("deny", (envelope, args) => this.handlePermissionResponseCommand(envelope, args, "deny"));
4712
4835
  this.registerCommand("who", async (envelope) => {
4713
4836
  if (!this.isAuthorizedForSharedSession(envelope)) {
4714
- await this.sendMessage(envelope.chatId, "Only authorized members can view this shared session.");
4837
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can view this shared session.");
4715
4838
  return true;
4716
4839
  }
4717
4840
  const active = this.router.hasSession(this.name, envelope.senderId, envelope.chatId, envelope.threadId);
4718
4841
  const scopeNote = this.config.sessionScope === "single" ? " (shared channel-wide)" : this.isSharedSession(envelope) ? envelope.isGroup ? " (shared by this group)" : "" : envelope.isGroup ? " (private to you)" : "";
4719
- await this.sendMessage(envelope.chatId, [
4842
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, [
4720
4843
  `Channel: ${this.name}`,
4721
4844
  // Identity/memory lines only for channels that opted in — keep
4722
4845
  // unconfigured channels' output unchanged.
@@ -4770,12 +4893,12 @@ ${requestList}`);
4770
4893
  }
4771
4894
  }
4772
4895
  lines.push("", "Send any text to chat with the agent.");
4773
- await this.sendMessage(envelope.chatId, lines.join("\n"));
4896
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, lines.join("\n"));
4774
4897
  return true;
4775
4898
  });
4776
4899
  this.registerCommand("status", async (envelope) => {
4777
4900
  if (!this.isAuthorizedForSharedSession(envelope)) {
4778
- await this.sendMessage(envelope.chatId, "Only authorized members can view this shared session.");
4901
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can view this shared session.");
4779
4902
  return true;
4780
4903
  }
4781
4904
  const hasSession = this.router.hasSession(this.name, envelope.senderId, envelope.chatId, envelope.threadId);
@@ -4789,18 +4912,18 @@ ${requestList}`);
4789
4912
  `Memory: ${this.memoryScope.mode}`
4790
4913
  ] : []
4791
4914
  ];
4792
- await this.sendMessage(envelope.chatId, lines.join("\n"));
4915
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, lines.join("\n"));
4793
4916
  return true;
4794
4917
  });
4795
4918
  this.registerCommand("loop", async (envelope, args) => this.handleLoopCommand(envelope, args));
4796
4919
  }
4797
4920
  async handleLoopCommand(envelope, args) {
4798
4921
  if (!this.loopController) {
4799
- await this.sendMessage(envelope.chatId, "Loops are not available.");
4922
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Loops are not available.");
4800
4923
  return true;
4801
4924
  }
4802
4925
  if (!this.isAuthorizedForSharedSession(envelope)) {
4803
- await this.sendMessage(envelope.chatId, "Only authorized members can use loops in this shared session.");
4926
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Only authorized members can use loops in this shared session.");
4804
4927
  return true;
4805
4928
  }
4806
4929
  const [subcommand = "", ...rest] = args.trim().split(/\s+/u);
@@ -4814,7 +4937,7 @@ ${requestList}`);
4814
4937
  case "cancel":
4815
4938
  return this.handleLoopCancel(envelope, rest[0]);
4816
4939
  default:
4817
- await this.sendMessage(envelope.chatId, 'Usage: /loop add "<cron>" <prompt> | /loop list | /loop inspect <id> | /loop cancel <id>');
4940
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'Usage: /loop add "<cron>" <prompt> | /loop list | /loop inspect <id> | /loop cancel <id>');
4818
4941
  return true;
4819
4942
  }
4820
4943
  }
@@ -4822,32 +4945,32 @@ ${requestList}`);
4822
4945
  if (!this.loopController)
4823
4946
  return true;
4824
4947
  if (!this.supportsProactiveSend()) {
4825
- await this.sendMessage(envelope.chatId, "This channel does not support proactive loop messages.");
4948
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "This channel does not support proactive loop messages.");
4826
4949
  return true;
4827
4950
  }
4828
4951
  if (this.config.sessionScope === "single") {
4829
- await this.sendMessage(envelope.chatId, "Loops are not supported when sessionScope is single.");
4952
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Loops are not supported when sessionScope is single.");
4830
4953
  return true;
4831
4954
  }
4832
4955
  const parsed = parseLoopAddArgs(args);
4833
4956
  if (!parsed) {
4834
- await this.sendMessage(envelope.chatId, 'Usage: /loop add "<cron>" <prompt>');
4957
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'Usage: /loop add "<cron>" <prompt>');
4835
4958
  return true;
4836
4959
  }
4837
4960
  try {
4838
4961
  this.loopController.validateCron(parsed.cron);
4839
4962
  } catch (err) {
4840
- await this.sendMessage(envelope.chatId, `Invalid cron expression: ${err instanceof Error ? err.message : String(err)}`);
4963
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Invalid cron expression: ${err instanceof Error ? err.message : String(err)}`);
4841
4964
  return true;
4842
4965
  }
4843
4966
  const target = this.loopTargetFromEnvelope(envelope);
4844
4967
  if (!this.supportsProactiveTarget(target)) {
4845
- await this.sendMessage(envelope.chatId, "This channel does not support proactive loop messages for this chat target.");
4968
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "This channel does not support proactive loop messages for this chat target.");
4846
4969
  return true;
4847
4970
  }
4848
4971
  const prompt = sanitizePromptText(parsed.prompt.trim());
4849
4972
  if (Array.from(prompt).length > MAX_LOOP_PROMPT_CHARS) {
4850
- await this.sendMessage(envelope.chatId, `Loop prompt is too long; keep it under ${MAX_LOOP_PROMPT_CHARS} characters.`);
4973
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Loop prompt is too long; keep it under ${MAX_LOOP_PROMPT_CHARS} characters.`);
4851
4974
  return true;
4852
4975
  }
4853
4976
  const input = {
@@ -4870,10 +4993,10 @@ ${requestList}`);
4870
4993
  }
4871
4994
  }
4872
4995
  if (!job) {
4873
- await this.sendMessage(envelope.chatId, `Too many loops for this chat. Cancel an existing loop before adding another.`);
4996
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Too many loops for this chat. Cancel an existing loop before adding another.`);
4874
4997
  return true;
4875
4998
  }
4876
- await this.sendMessage(envelope.chatId, `Loop ${job.id}: ${job.cron}`);
4999
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Loop ${job.id}: ${job.cron}`);
4877
5000
  return true;
4878
5001
  }
4879
5002
  async createLoopFromTool(sessionId, input) {
@@ -4975,23 +5098,23 @@ ${requestList}`);
4975
5098
  return true;
4976
5099
  const jobs = await this.loopController.listForTarget(this.name, this.loopTargetFromEnvelope(envelope));
4977
5100
  if (jobs.length === 0) {
4978
- await this.sendMessage(envelope.chatId, "No loops.");
5101
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No loops.");
4979
5102
  return true;
4980
5103
  }
4981
- await this.sendMessage(envelope.chatId, jobs.map((job) => this.formatLoopListLine(job)).join("\n"));
5104
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, jobs.map((job) => this.formatLoopListLine(job)).join("\n"));
4982
5105
  return true;
4983
5106
  }
4984
5107
  async handleLoopInspect(envelope, id) {
4985
5108
  if (!this.loopController)
4986
5109
  return true;
4987
5110
  if (!id) {
4988
- await this.sendMessage(envelope.chatId, "Usage: /loop inspect <id>");
5111
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Usage: /loop inspect <id>");
4989
5112
  return true;
4990
5113
  }
4991
5114
  const jobs = await this.loopController.listForTarget(this.name, this.loopTargetFromEnvelope(envelope));
4992
5115
  const job = jobs.find((candidate) => candidate.id === id);
4993
5116
  if (!job) {
4994
- await this.sendMessage(envelope.chatId, `No loop ${id}.`);
5117
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No loop ${id}.`);
4995
5118
  return true;
4996
5119
  }
4997
5120
  const lines = [
@@ -5013,7 +5136,7 @@ ${requestList}`);
5013
5136
  lines.push(`Last result: ${job.lastResultPreview}`);
5014
5137
  }
5015
5138
  lines.push(`Prompt: ${job.prompt}`);
5016
- await this.sendMessage(envelope.chatId, lines.join("\n"));
5139
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, lines.join("\n"));
5017
5140
  return true;
5018
5141
  }
5019
5142
  formatLoopListLine(job) {
@@ -5045,17 +5168,17 @@ ${requestList}`);
5045
5168
  if (!this.loopController)
5046
5169
  return true;
5047
5170
  if (!id) {
5048
- await this.sendMessage(envelope.chatId, "Usage: /loop cancel <id>");
5171
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Usage: /loop cancel <id>");
5049
5172
  return true;
5050
5173
  }
5051
5174
  const jobs = await this.loopController.listForTarget(this.name, this.loopTargetFromEnvelope(envelope));
5052
5175
  const match = jobs.find((job) => job.id === id);
5053
5176
  if (!match) {
5054
- await this.sendMessage(envelope.chatId, `No loop ${id}.`);
5177
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No loop ${id}.`);
5055
5178
  return true;
5056
5179
  }
5057
5180
  const disabled = await this.loopController.disable(id);
5058
- await this.sendMessage(envelope.chatId, disabled ? `Cancelled loop ${id}.` : `Failed to cancel loop ${id}.`);
5181
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, disabled ? `Cancelled loop ${id}.` : `Failed to cancel loop ${id}.`);
5059
5182
  return true;
5060
5183
  }
5061
5184
  loopTargetFromEnvelope(envelope) {
@@ -5172,7 +5295,7 @@ ${requestList}`);
5172
5295
  }
5173
5296
  async getChannelMemory(envelope) {
5174
5297
  if (!this.channelMemory) {
5175
- await this.sendMessage(envelope.chatId, "Channel memory is not configured for this channel.");
5298
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Channel memory is not configured for this channel.");
5176
5299
  return void 0;
5177
5300
  }
5178
5301
  return this.channelMemory;
@@ -5190,7 +5313,7 @@ ${requestList}`);
5190
5313
  }
5191
5314
  async handleChannelMemoryIntent(envelope, intent, options = {}) {
5192
5315
  if (intent.kind === "no_match") {
5193
- await this.sendMessage(envelope.chatId, "No matching channel memory entry.");
5316
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No matching channel memory entry.");
5194
5317
  return;
5195
5318
  }
5196
5319
  if (intent.kind === "ambiguous") {
@@ -5202,11 +5325,11 @@ ${requestList}`);
5202
5325
  entries = await channelMemory2.listChannelMemoryEntries(this.channelMemoryTarget(envelope));
5203
5326
  } catch (error) {
5204
5327
  this.logChannelMemoryError("read", envelope, this.channelMemoryErrorMessage(error));
5205
- await this.sendMessage(envelope.chatId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
5328
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
5206
5329
  return;
5207
5330
  }
5208
5331
  const selected = this.entriesForChannelMemoryIds(entries, intent.ids);
5209
- await this.sendMessage(envelope.chatId, [
5332
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, [
5210
5333
  "Multiple channel memory entries match:",
5211
5334
  ...this.renderChannelMemoryCandidates(selected)
5212
5335
  ].join("\n"));
@@ -5221,11 +5344,11 @@ ${requestList}`);
5221
5344
  entries = await channelMemory2.listChannelMemoryEntries(this.channelMemoryTarget(envelope));
5222
5345
  } catch (error) {
5223
5346
  this.logChannelMemoryError("read", envelope, this.channelMemoryErrorMessage(error));
5224
- await this.sendMessage(envelope.chatId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
5347
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
5225
5348
  return;
5226
5349
  }
5227
5350
  const selected = this.entriesForChannelMemoryIds(entries, intent.ids);
5228
- await this.sendMessage(envelope.chatId, [
5351
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, [
5229
5352
  "Channel memory (page 1/1):",
5230
5353
  ...this.renderChannelMemoryCandidates(selected)
5231
5354
  ].join("\n"));
@@ -5238,7 +5361,7 @@ ${requestList}`);
5238
5361
  if (intent.kind === "update_confirm" || intent.kind === "remove_confirm") {
5239
5362
  const pending = intent.kind === "update_confirm" ? this.takePendingChannelMemoryMutation(envelope, "update") : this.takePendingChannelMemoryMutation(envelope, "remove");
5240
5363
  if (!pending) {
5241
- await this.sendMessage(envelope.chatId, intent.kind === "update_confirm" ? "No pending channel memory update. Start a new update request first." : "No pending channel memory removal. Start a new removal request first.");
5364
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, intent.kind === "update_confirm" ? "No pending channel memory update. Start a new update request first." : "No pending channel memory removal. Start a new removal request first.");
5242
5365
  return;
5243
5366
  }
5244
5367
  const channelMemory2 = await this.getChannelMemory(envelope);
@@ -5262,15 +5385,15 @@ ${requestList}`);
5262
5385
  } catch (error) {
5263
5386
  const message = this.channelMemoryErrorMessage(error);
5264
5387
  this.logChannelMemoryError(isUpdate ? "update" : "remove", envelope, message);
5265
- await this.sendMessage(envelope.chatId, message === "Channel memory entry changed" ? "That channel memory entry changed since it was selected. View channel memory and start the operation again." : `Failed to ${isUpdate ? "update" : "remove"} channel memory: ${this.channelMemoryUserErrorMessage()}`);
5388
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, message === "Channel memory entry changed" ? "That channel memory entry changed since it was selected. View channel memory and start the operation again." : `Failed to ${isUpdate ? "update" : "remove"} channel memory: ${this.channelMemoryUserErrorMessage()}`);
5266
5389
  return;
5267
5390
  }
5268
5391
  if (!changed) {
5269
- await this.sendMessage(envelope.chatId, `No channel memory entry ${pending.id}.`);
5392
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No channel memory entry ${pending.id}.`);
5270
5393
  return;
5271
5394
  }
5272
5395
  this.invalidateUnattendedMemory(envelope);
5273
- await this.sendMessage(envelope.chatId, `Channel memory ${pending.id} ${isUpdate ? "updated" : "removed"}.`);
5396
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory ${pending.id} ${isUpdate ? "updated" : "removed"}.`);
5274
5397
  return;
5275
5398
  }
5276
5399
  if (intent.kind === "natural_update") {
@@ -5310,7 +5433,7 @@ ${requestList}`);
5310
5433
  } catch (error) {
5311
5434
  const message = this.channelMemoryErrorMessage(error);
5312
5435
  this.logChannelMemoryError("save", envelope, message);
5313
- await this.sendMessage(envelope.chatId, `Failed to save channel memory: ${this.channelMemoryUserErrorMessage()}`);
5436
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to save channel memory: ${this.channelMemoryUserErrorMessage()}`);
5314
5437
  return;
5315
5438
  }
5316
5439
  if (result.changed) {
@@ -5321,11 +5444,11 @@ ${requestList}`);
5321
5444
  }
5322
5445
  if (result.added.length > 0) {
5323
5446
  const ids = result.added.map((entry) => entry.id);
5324
- await this.sendMessage(envelope.chatId, result.duplicateIds.length > 0 ? `Channel memory saved: ${ids.join(", ")}. Skipped duplicates: ${result.duplicateIds.join(", ")}.` : ids.length === 1 ? `Channel memory ${ids[0]} saved.` : `Channel memory saved: ${ids.join(", ")}.`);
5447
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, result.duplicateIds.length > 0 ? `Channel memory saved: ${ids.join(", ")}. Skipped duplicates: ${result.duplicateIds.join(", ")}.` : ids.length === 1 ? `Channel memory ${ids[0]} saved.` : `Channel memory saved: ${ids.join(", ")}.`);
5325
5448
  } else if (result.duplicateIds.length > 0) {
5326
- await this.sendMessage(envelope.chatId, `Channel memory already contains ${result.duplicateIds.join(", ")}.`);
5449
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory already contains ${result.duplicateIds.join(", ")}.`);
5327
5450
  } else {
5328
- await this.sendMessage(envelope.chatId, "Channel memory updated.");
5451
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Channel memory updated.");
5329
5452
  }
5330
5453
  return;
5331
5454
  }
@@ -5336,27 +5459,27 @@ ${requestList}`);
5336
5459
  } catch (error) {
5337
5460
  const message = this.channelMemoryErrorMessage(error);
5338
5461
  this.logChannelMemoryError("read", envelope, message);
5339
- await this.sendMessage(envelope.chatId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
5462
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to read channel memory: ${this.channelMemoryUserErrorMessage()}`);
5340
5463
  return;
5341
5464
  }
5342
5465
  if (intent.kind === "inspect") {
5343
5466
  const entry = entries.find((candidate) => candidate.id === intent.id);
5344
- await this.sendMessage(envelope.chatId, entry ? `Channel memory ${entry.id}:
5467
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, entry ? `Channel memory ${entry.id}:
5345
5468
  ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id}.`);
5346
5469
  return;
5347
5470
  }
5348
5471
  const totalPages = Math.max(1, Math.ceil(entries.length / CHANNEL_MEMORY_PAGE_SIZE));
5349
5472
  if (intent.page > totalPages) {
5350
- await this.sendMessage(envelope.chatId, `Channel memory page ${intent.page} does not exist.`);
5473
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory page ${intent.page} does not exist.`);
5351
5474
  return;
5352
5475
  }
5353
5476
  if (entries.length === 0) {
5354
- await this.sendMessage(envelope.chatId, "No channel memory saved.");
5477
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "No channel memory saved.");
5355
5478
  return;
5356
5479
  }
5357
5480
  const pageStart = (intent.page - 1) * CHANNEL_MEMORY_PAGE_SIZE;
5358
5481
  const lines = entries.slice(pageStart, pageStart + CHANNEL_MEMORY_PAGE_SIZE).map((entry) => this.renderChannelMemoryCandidate(entry));
5359
- await this.sendMessage(envelope.chatId, [`Channel memory (page ${intent.page}/${totalPages}):`, ...lines].join("\n"));
5482
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, [`Channel memory (page ${intent.page}/${totalPages}):`, ...lines].join("\n"));
5360
5483
  return;
5361
5484
  }
5362
5485
  if (intent.kind === "update" || intent.kind === "remove") {
@@ -5372,21 +5495,21 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
5372
5495
  } catch (error) {
5373
5496
  const message = this.channelMemoryErrorMessage(error);
5374
5497
  this.logChannelMemoryError(isUpdate ? "update" : "remove", envelope, message);
5375
- await this.sendMessage(envelope.chatId, `Failed to ${isUpdate ? "update" : "remove"} channel memory: ${this.channelMemoryUserErrorMessage()}`);
5498
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to ${isUpdate ? "update" : "remove"} channel memory: ${this.channelMemoryUserErrorMessage()}`);
5376
5499
  return;
5377
5500
  }
5378
5501
  if (!changed) {
5379
- await this.sendMessage(envelope.chatId, `No channel memory entry ${id}.`);
5502
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `No channel memory entry ${id}.`);
5380
5503
  return;
5381
5504
  }
5382
5505
  this.invalidateUnattendedMemory(envelope);
5383
- await this.sendMessage(envelope.chatId, `Channel memory ${id} ${isUpdate ? "updated" : "removed"}.`);
5506
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Channel memory ${id} ${isUpdate ? "updated" : "removed"}.`);
5384
5507
  return;
5385
5508
  }
5386
5509
  if (intent.kind === "clear_confirm") {
5387
5510
  const pending = this.takePendingChannelMemoryMutation(envelope, "clear");
5388
5511
  if (!pending) {
5389
- await this.sendMessage(envelope.chatId, 'No pending clear request. Say "\u6E05\u7A7A\u8BB0\u5FC6" first.');
5512
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, 'No pending clear request. Say "\u6E05\u7A7A\u8BB0\u5FC6" first.');
5390
5513
  return;
5391
5514
  }
5392
5515
  let result;
@@ -5395,13 +5518,13 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
5395
5518
  } catch (error) {
5396
5519
  const message = this.channelMemoryErrorMessage(error);
5397
5520
  this.logChannelMemoryError("clear", envelope, message);
5398
- await this.sendMessage(envelope.chatId, `Failed to clear channel memory: ${this.channelMemoryUserErrorMessage()}`);
5521
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Failed to clear channel memory: ${this.channelMemoryUserErrorMessage()}`);
5399
5522
  return;
5400
5523
  }
5401
5524
  if (result.changed) {
5402
5525
  this.invalidateUnattendedMemory(envelope);
5403
5526
  }
5404
- await this.sendMessage(envelope.chatId, result.changed ? "Channel memory cleared." : "No channel memory saved.");
5527
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, result.changed ? "Channel memory cleared." : "No channel memory saved.");
5405
5528
  return;
5406
5529
  }
5407
5530
  const unhandled = intent;
@@ -5430,7 +5553,7 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
5430
5553
  const key = this.channelMemoryPendingKey(envelope);
5431
5554
  this.pendingChannelMemoryMutationDeliveries.set(key, mutation);
5432
5555
  try {
5433
- await this.sendMessage(envelope.chatId, message);
5556
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, message);
5434
5557
  } catch (error) {
5435
5558
  if (this.pendingChannelMemoryMutationDeliveries.get(key) === mutation) {
5436
5559
  this.pendingChannelMemoryMutationDeliveries.delete(key);
@@ -5584,15 +5707,17 @@ ${sanitizePromptText(entry.text).trim()}` : `No channel memory entry ${intent.id
5584
5707
  * Whether the resolved session is SHARED across senders. `single` collapses
5585
5708
  * the whole channel to one `__single__` session for EVERY sender — group OR
5586
5709
  * DM — so it is ALWAYS shared (even a DM maps to `__single__`). `thread` is
5587
- * shared only in a group (a DM maps to the lone caller's own chat). `user` is
5588
- * per-sender, never shared. Drives both the destructive-/clear confirm gate
5589
- * and the host-shell (`!`) gate.
5710
+ * shared only in a group (a DM maps to the lone caller's own chat).
5711
+ * `chat_thread` is always shared: it scopes by chat+thread, and a thread
5712
+ * (issue/PR discussion) can carry multiple participants even outside a
5713
+ * group. `user` is per-sender, never shared. Drives both the
5714
+ * destructive-/clear confirm gate and the host-shell (`!`) gate.
5590
5715
  */
5591
5716
  isSharedSession(envelope) {
5592
5717
  return this.isSharedSessionTarget(envelope);
5593
5718
  }
5594
5719
  isSharedSessionTarget(target) {
5595
- return this.config.sessionScope === "single" || target.isGroup === true && this.config.sessionScope === "thread";
5720
+ return this.config.sessionScope === "single" || this.config.sessionScope === "chat_thread" || target.isGroup === true && this.config.sessionScope === "thread";
5596
5721
  }
5597
5722
  /**
5598
5723
  * Whether `envelope.senderId` may act on the resolved session's destructive or
@@ -5849,7 +5974,7 @@ ${promptText}`;
5849
5974
  if (!result.allowed) {
5850
5975
  if (result.pairingCode !== void 0) {
5851
5976
  this.logPreflightRejected("sender_pairing_required");
5852
- return this.onPairingRequired(envelope.chatId, result.pairingCode).then(() => false).catch((err) => {
5977
+ return this.onPairingRequired(envelope.chatId, result.pairingCode, envelope.threadId).then(() => false).catch((err) => {
5853
5978
  process.stderr.write(`[Channel:${this.name}] pairing notification failed: ${sanitizeLogText(err instanceof Error ? err.message : String(err), 200)}
5854
5979
  `);
5855
5980
  return false;
@@ -5962,11 +6087,11 @@ ${promptText}`;
5962
6087
  `);
5963
6088
  }
5964
6089
  if (envelope.isGroup) {
5965
- await this.sendMessage(envelope.chatId, "Shell commands (`!`) are disabled in group chats.");
6090
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Shell commands (`!`) are disabled in group chats.");
5966
6091
  return;
5967
6092
  }
5968
6093
  if (this.isSharedSession(envelope)) {
5969
- await this.sendMessage(envelope.chatId, "Shell commands (`!`) are disabled in shared sessions.");
6094
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, "Shell commands (`!`) are disabled in shared sessions.");
5970
6095
  return;
5971
6096
  }
5972
6097
  }
@@ -5984,10 +6109,10 @@ ${result.output}
5984
6109
  ${fence}` : "(no output)";
5985
6110
  const exitLine = result.exitCode !== null && result.exitCode !== 0 ? `
5986
6111
  Exit code: ${result.exitCode}` : "";
5987
- await this.sendMessage(envelope.chatId, `$ ${cmd}
6112
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `$ ${cmd}
5988
6113
  ${output}${exitLine}`);
5989
6114
  } catch (error) {
5990
- await this.sendMessage(envelope.chatId, `Shell command failed: ${error instanceof Error ? error.message : String(error)}`);
6115
+ await this.sendThreadMessage(envelope.chatId, envelope.threadId, `Shell command failed: ${error instanceof Error ? error.message : String(error)}`);
5991
6116
  }
5992
6117
  return;
5993
6118
  }
@@ -6023,6 +6148,9 @@ ${promptText}`;
6023
6148
  promptText = promptText + "\n\n" + filePaths.join("\n");
6024
6149
  }
6025
6150
  }
6151
+ if (envelope.metadata) {
6152
+ promptText = promptText + "\n\n" + sanitizePromptText(envelope.metadata);
6153
+ }
6026
6154
  const groupCfg = envelope.isGroup ? this.config.groups[envelope.chatId] || this.config.groups["*"] : void 0;
6027
6155
  const mode = groupCfg?.dispatchMode || this.config.dispatchMode || "steer";
6028
6156
  const active = this.activePrompts.get(sessionId);
@@ -6300,6 +6428,7 @@ ${promptToSend}`;
6300
6428
  // Clear attachments/references — already resolved in original text
6301
6429
  referencedText: void 0,
6302
6430
  attachments: void 0,
6431
+ metadata: void 0,
6303
6432
  imageBase64: void 0,
6304
6433
  imageMimeType: void 0
6305
6434
  };
@@ -6315,14 +6444,14 @@ ${promptToSend}`;
6315
6444
  }));
6316
6445
  await current;
6317
6446
  }
6318
- async onPairingRequired(chatId, code) {
6447
+ async onPairingRequired(chatId, code, threadId) {
6319
6448
  if (code) {
6320
- await this.sendMessage(chatId, `Your pairing code is: ${code}
6449
+ await this.sendThreadMessage(chatId, threadId, `Your pairing code is: ${code}
6321
6450
 
6322
6451
  Ask the bot operator to approve you with:
6323
6452
  qwen channel pairing approve ${this.name} ${code}`);
6324
6453
  } else {
6325
- await this.sendMessage(chatId, "Too many pending pairing requests. Please try again later.");
6454
+ await this.sendThreadMessage(chatId, threadId, "Too many pending pairing requests. Please try again later.");
6326
6455
  }
6327
6456
  }
6328
6457
  };
@@ -6535,9 +6664,114 @@ function isTerminalTaskLifecycleType(type) {
6535
6664
  }
6536
6665
  __name(isTerminalTaskLifecycleType, "isTerminalTaskLifecycleType");
6537
6666
 
6667
+ // packages/channels/base/dist/PollingChannelBase.js
6668
+ init_esbuild_shims();
6669
+ import { createHash as createHash2 } from "node:crypto";
6670
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync4, renameSync as renameSync4, writeFileSync as writeFileSync4 } from "node:fs";
6671
+ import { join as join6 } from "node:path";
6672
+ import process3 from "node:process";
6673
+ var INITIAL_BACKOFF = 2e3;
6674
+ var MAX_BACKOFF = 3e4;
6675
+ var PollingChannelBase = class extends ChannelBase {
6676
+ static {
6677
+ __name(this, "PollingChannelBase");
6678
+ }
6679
+ cursor;
6680
+ abortController = new AbortController();
6681
+ running = false;
6682
+ consecutiveErrors = 0;
6683
+ abortableSleep(ms) {
6684
+ const signal = this.abortController.signal;
6685
+ return new Promise((resolve3) => {
6686
+ if (signal.aborted) {
6687
+ resolve3();
6688
+ return;
6689
+ }
6690
+ const timer = setTimeout(() => {
6691
+ signal.removeEventListener("abort", onAbort);
6692
+ resolve3();
6693
+ }, ms);
6694
+ const onAbort = /* @__PURE__ */ __name(() => {
6695
+ clearTimeout(timer);
6696
+ resolve3();
6697
+ }, "onAbort");
6698
+ signal.addEventListener("abort", onAbort, { once: true });
6699
+ });
6700
+ }
6701
+ constructor(name, config, bridge, options) {
6702
+ super(name, config, bridge, options);
6703
+ this.cursor = this.loadCursorFromDisk() ?? this.createInitialCursor();
6704
+ }
6705
+ validateCursor(parsed) {
6706
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
6707
+ return null;
6708
+ return parsed;
6709
+ }
6710
+ get pollInterval() {
6711
+ const configured = this.config.pollInterval;
6712
+ if (typeof configured === "number" && Number.isFinite(configured) && configured > 0) {
6713
+ return configured;
6714
+ }
6715
+ return 6e4;
6716
+ }
6717
+ saveCursor() {
6718
+ const path4 = this.cursorPath();
6719
+ mkdirSync4(join6(getGlobalQwenDir(), "channels"), { recursive: true });
6720
+ const tmp = `${path4}.tmp`;
6721
+ writeFileSync4(tmp, JSON.stringify(this.cursor) + "\n", "utf-8");
6722
+ renameSync4(tmp, path4);
6723
+ }
6724
+ startPollLoop() {
6725
+ if (this.running)
6726
+ return;
6727
+ this.running = true;
6728
+ this.consecutiveErrors = 0;
6729
+ this.abortController = new AbortController();
6730
+ this.runLoop();
6731
+ }
6732
+ stopPollLoop() {
6733
+ this.running = false;
6734
+ this.abortController.abort();
6735
+ }
6736
+ async runLoop() {
6737
+ const signal = this.abortController.signal;
6738
+ while (this.running && !signal.aborted) {
6739
+ try {
6740
+ await this.pollOnce();
6741
+ this.saveCursor();
6742
+ this.consecutiveErrors = 0;
6743
+ } catch (err) {
6744
+ this.consecutiveErrors++;
6745
+ const backoff = Math.min(INITIAL_BACKOFF * 2 ** (this.consecutiveErrors - 1), MAX_BACKOFF);
6746
+ process3.stderr.write(`[Channel:${this.name}] poll error (attempt ${this.consecutiveErrors}), backing off ${backoff}ms: ${err}
6747
+ `);
6748
+ await this.abortableSleep(backoff);
6749
+ continue;
6750
+ }
6751
+ await this.abortableSleep(this.pollInterval);
6752
+ }
6753
+ }
6754
+ loadCursorFromDisk() {
6755
+ try {
6756
+ const raw = readFileSync4(this.cursorPath(), "utf-8").trim();
6757
+ if (!raw)
6758
+ return null;
6759
+ return this.validateCursor(JSON.parse(raw));
6760
+ } catch {
6761
+ return null;
6762
+ }
6763
+ }
6764
+ cursorPath() {
6765
+ const encoded = this.name.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 200);
6766
+ const hash = createHash2("sha256").update(this.name).digest("hex").slice(0, 16);
6767
+ return join6(getGlobalQwenDir(), "channels", `${encoded}-${hash}-poll-cursor.json`);
6768
+ }
6769
+ };
6770
+
6538
6771
  export {
6539
6772
  resolvePath,
6540
6773
  getGlobalQwenDir,
6774
+ CHANNEL_LOOP_MCP_SERVER_NAME,
6541
6775
  sanitizeSenderName,
6542
6776
  sanitizePromptText,
6543
6777
  sanitizeLogText,
@@ -6550,7 +6784,8 @@ export {
6550
6784
  ChannelLoopScheduler,
6551
6785
  ChannelBase,
6552
6786
  ChannelLoopStore,
6553
- isTerminalTaskLifecycleType
6787
+ isTerminalTaskLifecycleType,
6788
+ PollingChannelBase
6554
6789
  };
6555
6790
  /**
6556
6791
  * @license