@qwen-code/qwen-code 0.22.3 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. package/README.md +30 -0
  2. package/bundled/computer-use/SKILL.md +116 -180
  3. package/bundled/goal-draft/SKILL.md +5 -1
  4. package/bundled/qc-helper/docs/common-workflow.md +32 -0
  5. package/bundled/qc-helper/docs/configuration/auth.md +6 -6
  6. package/bundled/qc-helper/docs/configuration/model-providers.md +8 -2
  7. package/bundled/qc-helper/docs/configuration/settings.md +63 -58
  8. package/bundled/qc-helper/docs/extension/introduction.md +1 -1
  9. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  10. package/bundled/qc-helper/docs/features/approval-mode.md +3 -0
  11. package/bundled/qc-helper/docs/features/auto-mode.md +34 -17
  12. package/bundled/qc-helper/docs/features/channels/dingtalk.md +4 -2
  13. package/bundled/qc-helper/docs/features/channels/dws.md +6 -2
  14. package/bundled/qc-helper/docs/features/channels/overview.md +5 -2
  15. package/bundled/qc-helper/docs/features/code-review.md +2 -2
  16. package/bundled/qc-helper/docs/features/commands.md +79 -1
  17. package/bundled/qc-helper/docs/features/computer-use.md +2 -2
  18. package/bundled/qc-helper/docs/features/goals.md +9 -3
  19. package/bundled/qc-helper/docs/features/headless.md +16 -1
  20. package/bundled/qc-helper/docs/features/hooks.md +8 -3
  21. package/bundled/qc-helper/docs/features/memory.md +1 -0
  22. package/bundled/qc-helper/docs/features/output-styles.md +38 -0
  23. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +17 -7
  24. package/bundled/qc-helper/docs/qwen-serve.md +74 -55
  25. package/bundled/review/SKILL.md +16 -7
  26. package/bundled/review/references/posting.md +3 -3
  27. package/chunks/MaxSizedBox-B3D7545A.js +111 -0
  28. package/chunks/{StandaloneSessionPicker-2FJAOLGG.js → StandaloneSessionPicker-QUMO4LLQ.js} +88 -86
  29. package/chunks/{acp-startup-profiler-GNYAL6LI.js → acp-startup-profiler-M4X5F3VK.js} +2 -2
  30. package/chunks/{acpAgent-2ZMIJAFV.js → acpAgent-2GTFCIEP.js} +2041 -444
  31. package/chunks/{agent-X5WX3L2I.js → agent-XKF5SZWU.js} +46 -46
  32. package/chunks/agent-headless-OC2IB55D.js +85 -0
  33. package/chunks/{anthropicContentGenerator-YVTB6QX7.js → anthropicContentGenerator-L76MR5OR.js} +53 -20
  34. package/chunks/{artifact-tool-XSMPHZBT.js → artifact-tool-MYCL2QCS.js} +3 -4
  35. package/chunks/{askUserQuestion-4SWJY65V.js → askUserQuestion-THQZMG44.js} +45 -7
  36. package/chunks/bridge-IHSBI2YJ.js +118 -0
  37. package/chunks/{build-INBK7IXX.js → build-63BIOYWK.js} +1 -1
  38. package/chunks/{ca-7HPYOYSZ.js → ca-BNU7YNDE.js} +3 -0
  39. package/chunks/{channel-management-service-HQ6KDS7C.js → channel-management-service-4MTCEGJB.js} +4 -4
  40. package/chunks/channel-settings-store-BVKWAI2T.js +121 -0
  41. package/chunks/{channel-worker-group-6NA6BBZV.js → channel-worker-group-47F4ISUZ.js} +7 -7
  42. package/chunks/{channel-worker-manager-NEZ2J6RK.js → channel-worker-manager-I5Y44GYR.js} +51 -10
  43. package/chunks/{channel-worker-supervisor-FKU7DIHJ.js → channel-worker-supervisor-6VCLUXFE.js} +4 -4
  44. package/chunks/{chunk-PPKZ7JOE.js → chunk-22UH7VTP.js} +1 -1
  45. package/chunks/chunk-24FVUD5P.js +49 -0
  46. package/chunks/{chunk-MZCJWS5Y.js → chunk-2M3EWQNG.js} +20 -0
  47. package/chunks/{chunk-7T52W4SW.js → chunk-32LU3APX.js} +1 -1
  48. package/chunks/{chunk-42IDLQWS.js → chunk-373DQUVA.js} +48 -13
  49. package/chunks/{chunk-MSBO7X2W.js → chunk-37JFWFCD.js} +1 -1
  50. package/chunks/{chunk-3JXM2CVW.js → chunk-3AKCBZVW.js} +3 -3
  51. package/chunks/{chunk-TVC6HQ2U.js → chunk-3JQZVCBI.js} +2 -2
  52. package/chunks/{chunk-2LNNVAUV.js → chunk-3L724BJ5.js} +246 -15
  53. package/chunks/{chunk-E7REAOTN.js → chunk-47ECGEJC.js} +4 -0
  54. package/chunks/{chunk-WNPDGUJO.js → chunk-47RYEQW5.js} +2 -3
  55. package/chunks/{chunk-TZBSGJ6C.js → chunk-4BGDFKQE.js} +7 -7
  56. package/chunks/{chunk-PZ66FRIC.js → chunk-4F7GQGXB.js} +11772 -4773
  57. package/chunks/{chunk-DMLVSW7L.js → chunk-4HVH57J3.js} +713 -9
  58. package/chunks/{chunk-CMHFCLBU.js → chunk-4LIFGNI4.js} +1 -1
  59. package/chunks/{chunk-3SZC4VP4.js → chunk-4M24B5J5.js} +88 -49
  60. package/chunks/{chunk-BOWFGCEU.js → chunk-4PSDSCW3.js} +3 -3
  61. package/chunks/chunk-4UANMABT.js +1026 -0
  62. package/chunks/{chunk-M3QRM3DE.js → chunk-54C6PIGT.js} +5 -5
  63. package/chunks/{chunk-HP5LR5HL.js → chunk-5EIOJGCR.js} +4 -4
  64. package/chunks/{chunk-64REQJJ2.js → chunk-5H5S4UY5.js} +3 -3
  65. package/chunks/chunk-5IENVM7Z.js +35 -0
  66. package/chunks/{chunk-I6LYRJPB.js → chunk-5Q5RC2WE.js} +2 -2
  67. package/chunks/{chunk-WGY3AVGM.js → chunk-5RTTI4GE.js} +79 -5
  68. package/chunks/{chunk-KID24ZFN.js → chunk-64QH2UC6.js} +13 -1
  69. package/chunks/{chunk-MF7HCQWZ.js → chunk-65HWLGA7.js} +3 -3
  70. package/chunks/{chunk-OU5APVWO.js → chunk-6A2D4QSO.js} +13 -7
  71. package/chunks/chunk-6HUXPLB5.js +110 -0
  72. package/chunks/{chunk-VQUGEVGR.js → chunk-7IKXTGZT.js} +1 -1
  73. package/chunks/{chunk-UTLCH2FK.js → chunk-7JMGTOH7.js} +437 -136
  74. package/chunks/{chunk-7LOELM2I.js → chunk-7RB56BRJ.js} +3 -3
  75. package/chunks/{chunk-NIFYWDYN.js → chunk-7TBU7PU2.js} +1 -1
  76. package/chunks/{chunk-V2NDP3I4.js → chunk-7XL4WRXM.js} +2 -2
  77. package/chunks/chunk-ADJD4LZF.js +210 -0
  78. package/chunks/{chunk-T7KMERIX.js → chunk-ADYN7P2Y.js} +2 -2
  79. package/chunks/{chunk-TPI7O7HR.js → chunk-AHYTURFB.js} +1 -1
  80. package/chunks/{chunk-LUEHOUHM.js → chunk-AI35S34R.js} +3 -3
  81. package/chunks/{chunk-CIZCL2MW.js → chunk-ALUYNJPM.js} +1486 -2172
  82. package/chunks/{chunk-ABS25QER.js → chunk-ANVG3BVV.js} +1 -1
  83. package/chunks/{chunk-6ZPDLGHN.js → chunk-AZJLY2XZ.js} +5 -5
  84. package/chunks/{chunk-A3LWD5MK.js → chunk-BA4WJC4L.js} +1 -1
  85. package/chunks/{chunk-W3JH33JE.js → chunk-BFY33IB4.js} +18 -10
  86. package/chunks/{chunk-N4X7G4J2.js → chunk-BHTYRHJF.js} +1 -1
  87. package/chunks/{chunk-TEBDFQBZ.js → chunk-BJXCYUGM.js} +11 -6
  88. package/chunks/{chunk-7VMIMAVB.js → chunk-C2VWOXHS.js} +8 -8
  89. package/chunks/{chunk-XHF7WQ6B.js → chunk-C4TIXFDZ.js} +16 -5
  90. package/chunks/chunk-CHEIIBT3.js +40 -0
  91. package/chunks/chunk-CVX63TFJ.js +348 -0
  92. package/chunks/{chunk-RXFQM6FQ.js → chunk-DMEUXLSS.js} +16 -1
  93. package/chunks/{chunk-EKSCLBBF.js → chunk-DQCKVAF5.js} +23 -5
  94. package/chunks/{chunk-734C6JGI.js → chunk-DSX7KQPM.js} +5195 -666
  95. package/chunks/{chunk-4CMJKUND.js → chunk-DTVQSSNM.js} +67 -2
  96. package/chunks/{chunk-BKWNKLZB.js → chunk-DYTW3QVG.js} +24 -9
  97. package/chunks/{chunk-C2X7KY45.js → chunk-E4JNFXNI.js} +3 -3
  98. package/chunks/{chunk-UHQFIS7N.js → chunk-EAHOJF6V.js} +28 -4
  99. package/chunks/{chunk-YLSQLSH7.js → chunk-EBDGRBZX.js} +24 -16
  100. package/chunks/{chunk-DJBQCO2E.js → chunk-EFTPIZIC.js} +412 -3
  101. package/chunks/{chunk-6DIGWMGT.js → chunk-EIJT2PQ6.js} +2 -2
  102. package/chunks/{chunk-4TT3IVGA.js → chunk-EIY7SUPZ.js} +1 -1
  103. package/chunks/{chunk-XQFT3QUF.js → chunk-ENYUKMFK.js} +1 -1
  104. package/chunks/{chunk-ZWJDJ6RU.js → chunk-EVFDRBUM.js} +157 -153
  105. package/chunks/{chunk-4VPCTGH6.js → chunk-EWRW2WQC.js} +15 -9
  106. package/chunks/{chunk-VBCPNIQD.js → chunk-F33GFWPR.js} +47 -184
  107. package/chunks/{chunk-ERFDKH32.js → chunk-F47DITLZ.js} +19 -8
  108. package/chunks/{chunk-73RM4POK.js → chunk-F7NF2IOE.js} +7 -7
  109. package/chunks/{chunk-EB6QRGHM.js → chunk-FD5SJOWT.js} +10 -7
  110. package/chunks/{chunk-SS5SDCD3.js → chunk-FRICLXCZ.js} +7 -7
  111. package/chunks/{chunk-NU7RKEZR.js → chunk-FUO5V5KI.js} +14 -7
  112. package/chunks/{chunk-G6FECKTJ.js → chunk-G5PBOQWI.js} +9 -6
  113. package/chunks/{chunk-CAJTKR6W.js → chunk-G7HBEEX7.js} +15 -9
  114. package/chunks/{chunk-4QHPPXK2.js → chunk-GB4UKWY5.js} +2 -2
  115. package/chunks/{chunk-QYMAKPY5.js → chunk-GH2S4GD5.js} +350 -12
  116. package/chunks/{chunk-LHBUKJG2.js → chunk-GXUTFQXK.js} +28 -25
  117. package/chunks/{chunk-KJO2LBUK.js → chunk-H43PSPYS.js} +5 -5
  118. package/chunks/{chunk-XSG6G3G6.js → chunk-HJBHMANB.js} +12 -14
  119. package/chunks/chunk-HRPFBHW7.js +336 -0
  120. package/chunks/{chunk-6PJOTWAN.js → chunk-HT5S5TRQ.js} +1 -1
  121. package/chunks/{chunk-HCOBAG2L.js → chunk-HWVUSYSN.js} +3 -8
  122. package/chunks/{chunk-2OUD5T67.js → chunk-I2TMJPCV.js} +213 -185
  123. package/chunks/{chunk-CLWO3B77.js → chunk-I4NRYS6A.js} +11 -11
  124. package/chunks/{chunk-V7EESTJV.js → chunk-I5N4EAS6.js} +1 -1
  125. package/chunks/{chunk-K5KXUXWC.js → chunk-IG4W5SJR.js} +3 -3
  126. package/chunks/{chunk-FROAFEFB.js → chunk-IPATA3T2.js} +3 -3
  127. package/chunks/{chunk-NKLP3DCK.js → chunk-IQAFKVXS.js} +1 -1
  128. package/chunks/{chunk-AYHQZBJ4.js → chunk-IRKQ4YYX.js} +3 -3
  129. package/chunks/{chunk-J3NNHTV6.js → chunk-J5TTWBZK.js} +6 -0
  130. package/chunks/{chunk-QFCDF5PL.js → chunk-JHN7UIDW.js} +1 -1
  131. package/chunks/{chunk-AVNATYLY.js → chunk-JJKNYRFY.js} +1 -1
  132. package/chunks/{chunk-CQH5KTKC.js → chunk-JR42V4UY.js} +1 -1
  133. package/chunks/chunk-JS73NNWF.js +30 -0
  134. package/chunks/{chunk-NV55WWD6.js → chunk-JUARRUMA.js} +802 -2011
  135. package/chunks/chunk-JX6XHPTX.js +26 -0
  136. package/chunks/{chunk-5JTIYALA.js → chunk-JZWOCUZ3.js} +1 -1
  137. package/chunks/{chunk-P2G476QN.js → chunk-KEVYJSI4.js} +13 -13
  138. package/chunks/{chunk-B466ZSHZ.js → chunk-KFN2IZYR.js} +3 -3
  139. package/chunks/{chunk-JWALNCLT.js → chunk-KGV55H53.js} +1 -1
  140. package/chunks/{chunk-23RFD54N.js → chunk-KHP66DFN.js} +1 -1
  141. package/chunks/{chunk-2SXSLSQE.js → chunk-KM3XVTMO.js} +12 -6
  142. package/chunks/{chunk-GPGU4S2N.js → chunk-KMU3ZHH4.js} +3 -3
  143. package/chunks/chunk-KOGW3YWJ.js +2054 -0
  144. package/chunks/{chunk-NMOD2FXQ.js → chunk-L26ONV2Y.js} +8 -8
  145. package/chunks/chunk-L34XSHIZ.js +28 -0
  146. package/chunks/{chunk-SEONHUS3.js → chunk-LAUEEBDL.js} +2 -0
  147. package/chunks/{chunk-3WK3QDNV.js → chunk-LB3WQQJK.js} +2 -2
  148. package/chunks/{chunk-URE3QBBB.js → chunk-LEPCWS5A.js} +3 -3
  149. package/chunks/{chunk-36GSQ3MM.js → chunk-LHBNR6EU.js} +2 -2
  150. package/chunks/{chunk-V4264FEG.js → chunk-LKODFJRD.js} +1 -1
  151. package/chunks/{chunk-PADPMMYM.js → chunk-LOBDDFYK.js} +5 -29
  152. package/chunks/{chunk-BXDAPVQU.js → chunk-LU77UT4D.js} +28 -4
  153. package/chunks/{chunk-RFIDDFAL.js → chunk-M4KFODIP.js} +1 -1
  154. package/chunks/{chunk-CFJY4DGX.js → chunk-M4LBBSVP.js} +4 -2
  155. package/chunks/{chunk-KYWTPLBJ.js → chunk-MOF6VZN2.js} +2 -2
  156. package/chunks/{chunk-DJPASAUV.js → chunk-MP6YZ4RK.js} +4829 -3638
  157. package/chunks/{chunk-T26EAKDL.js → chunk-N2TNM3QB.js} +2 -6
  158. package/chunks/{chunk-2TNL5KPM.js → chunk-N4QWUPDM.js} +7 -0
  159. package/chunks/{chunk-7S226YTK.js → chunk-NFIDVZND.js} +11 -1
  160. package/chunks/{chunk-ZEYFMJQA.js → chunk-NQ4L2CMD.js} +83 -18
  161. package/chunks/{chunk-ZZUKP7HV.js → chunk-NRL5CUZT.js} +1 -1
  162. package/chunks/{chunk-WXEA74YB.js → chunk-NSUKQ4DN.js} +9 -3
  163. package/chunks/chunk-NUHOLAQ6.js +59 -0
  164. package/chunks/{chunk-DJEZ55D4.js → chunk-NVVJTUSL.js} +336 -140
  165. package/chunks/{chunk-3XKLXHGK.js → chunk-NXKOVOM5.js} +9 -9
  166. package/chunks/{chunk-5Q372OFJ.js → chunk-O4KNCAX4.js} +57 -10
  167. package/chunks/{chunk-GOXKNSDZ.js → chunk-O5CD7T4T.js} +40 -9
  168. package/chunks/{chunk-XIQ5HQ2F.js → chunk-OBTWL6ZW.js} +1 -1
  169. package/chunks/{chunk-PDQGMSZK.js → chunk-ODZF64DM.js} +1 -1
  170. package/chunks/{chunk-5MK45KZ3.js → chunk-OHOO527W.js} +1 -1
  171. package/chunks/{chunk-36LGBEM6.js → chunk-OHU2H5CS.js} +1 -1
  172. package/chunks/{chunk-JB4JIVTJ.js → chunk-OKTNXDVO.js} +1 -1
  173. package/chunks/{chunk-CETB5XY4.js → chunk-ORFIYTI2.js} +1 -1
  174. package/chunks/{chunk-7E7UCJHS.js → chunk-OSHQMOBS.js} +18 -17
  175. package/chunks/chunk-OSSTATJF.js +1310 -0
  176. package/chunks/chunk-P6UIF2OW.js +400 -0
  177. package/chunks/{chunk-U54AYGEC.js → chunk-PB7JBAHF.js} +15 -49
  178. package/chunks/{chunk-Y5S7LBOZ.js → chunk-PCRBLMIN.js} +17 -3
  179. package/chunks/{chunk-WAOIHTJS.js → chunk-PDAKFU7M.js} +1 -1
  180. package/chunks/{chunk-YTDVNSUQ.js → chunk-QAK5475D.js} +1 -1
  181. package/chunks/{chunk-ST5MDGH3.js → chunk-QI27MKNQ.js} +27 -19
  182. package/chunks/{chunk-MK2GIB46.js → chunk-QJGYU5PG.js} +1 -1
  183. package/chunks/{chunk-SMPR7SPO.js → chunk-QJNDUTOL.js} +45 -239
  184. package/chunks/{chunk-MQM5PJML.js → chunk-QJVZLILI.js} +1 -1
  185. package/chunks/{chunk-B5PHIJGI.js → chunk-QKDNS6FU.js} +2 -2
  186. package/chunks/{chunk-ZU4UDIWX.js → chunk-QQD2GART.js} +15 -9
  187. package/chunks/{chunk-62GQFYID.js → chunk-RAFQIHN2.js} +3 -3
  188. package/chunks/{chunk-MO3FC2WT.js → chunk-RJUVTJEZ.js} +1 -1
  189. package/chunks/{chunk-M6FOJXW3.js → chunk-RKW36UWC.js} +1 -1
  190. package/chunks/{chunk-GBJBJ4HX.js → chunk-RM4WT2XB.js} +4 -26
  191. package/chunks/{chunk-VGIFXISB.js → chunk-RN3YGDCA.js} +7 -5
  192. package/chunks/{chunk-DYXFD5RO.js → chunk-S2T7H5MI.js} +1 -1
  193. package/chunks/{chunk-FTF2YIZ5.js → chunk-S6H3ELPG.js} +1 -1
  194. package/chunks/{chunk-4NDLQAY2.js → chunk-SI7WDR3U.js} +524 -16
  195. package/chunks/{chunk-2YOHKHYR.js → chunk-SRF4KTAG.js} +6 -6
  196. package/chunks/{chunk-ZZMSC3RG.js → chunk-STCVJXQB.js} +24 -24
  197. package/chunks/{chunk-ST5V3ZOC.js → chunk-SULZPKTA.js} +3 -3
  198. package/chunks/{chunk-6X7EU5TI.js → chunk-SX2QIMJV.js} +9 -7
  199. package/chunks/{chunk-V5J4J5TP.js → chunk-TJYRTS4S.js} +2 -20
  200. package/chunks/{chunk-C3PEFRKD.js → chunk-TMKTOTMQ.js} +5 -5
  201. package/chunks/{chunk-ISKH4QX3.js → chunk-TQHPVKO6.js} +4 -4
  202. package/chunks/{chunk-HVC3PNVC.js → chunk-TSZSGQ3N.js} +1 -1
  203. package/chunks/{chunk-ICURCKIU.js → chunk-U4DJ5XB3.js} +594 -91
  204. package/chunks/{chunk-TTX2JUE6.js → chunk-U6D2PPMN.js} +1 -1
  205. package/chunks/{chunk-GVIVASYK.js → chunk-UAKRDON5.js} +4 -4
  206. package/chunks/{chunk-D5LUXLUH.js → chunk-UJ4DUYIH.js} +18 -4
  207. package/chunks/{chunk-VTHREBQM.js → chunk-UKYXYWI2.js} +2 -2
  208. package/chunks/{chunk-ZYMLPEZQ.js → chunk-UM2FFKXN.js} +3 -3
  209. package/chunks/{chunk-2OBKDPZZ.js → chunk-UPFRILIL.js} +2 -2
  210. package/chunks/{chunk-2HYKTO7V.js → chunk-UUASLXHW.js} +55 -6
  211. package/chunks/chunk-V5U2NZNJ.js +29 -0
  212. package/chunks/{chunk-P5Y23G2L.js → chunk-V7RNNPGC.js} +1 -18
  213. package/chunks/{chunk-Q2MSPKIJ.js → chunk-VBWD6C27.js} +1 -1
  214. package/chunks/chunk-VGHZT6JR.js +51 -0
  215. package/chunks/{chunk-MPNBVAEU.js → chunk-VNAYZAFX.js} +4 -4
  216. package/chunks/chunk-VPSIC437.js +780 -0
  217. package/chunks/{chunk-AIAOIFY4.js → chunk-VWTSRH6C.js} +92 -17
  218. package/chunks/{chunk-4K7KNVWH.js → chunk-VYIUNFEA.js} +3 -3
  219. package/chunks/{chunk-EQSBPBZ3.js → chunk-WP4AX3XD.js} +5 -7
  220. package/chunks/{chunk-BFPESSTR.js → chunk-XEAAO654.js} +1 -1
  221. package/chunks/{chunk-RU7BK6B3.js → chunk-XLXAZLDR.js} +3 -3
  222. package/chunks/{chunk-EFWRMA2I.js → chunk-YPWZTR7F.js} +3 -3
  223. package/chunks/{chunk-XF63PKEN.js → chunk-ZDFQGHZH.js} +1 -1
  224. package/chunks/{chunk-OZ6KS6KW.js → chunk-ZGCKTAL5.js} +6 -1
  225. package/chunks/chunk-ZHO2CW6D.js +205 -0
  226. package/chunks/chunk-ZJ2LM2SI.js +198 -0
  227. package/chunks/{chunk-AYFA7MZV.js → chunk-ZKFTS3OV.js} +6 -6
  228. package/chunks/{chunk-HMJ2P3SV.js → chunk-ZL4HFSL6.js} +91 -29
  229. package/chunks/{chunk-DJECZIJX.js → chunk-ZTPGUFQV.js} +30 -8
  230. package/chunks/{chunk-7EQQR46F.js → chunk-ZVP4PWBU.js} +1 -1
  231. package/chunks/chunk-bdqvmfwv-ZTSOWAFE.js +17446 -0
  232. package/chunks/config-utils-LVSYDLHZ.js +114 -0
  233. package/chunks/contextCommand-TZD7UAJK.js +107 -0
  234. package/chunks/{core-runtime-AXB6SK5D.js → core-runtime-B4UKKIAQ.js} +63 -62
  235. package/chunks/{create-sub-session-23ITIELI.js → create-sub-session-LUPWEUHR.js} +3 -3
  236. package/chunks/{create-sub-session-4QNE64MR.js → create-sub-session-NJ24B4US.js} +94 -66
  237. package/chunks/{cron-create-KJ4IY6PP.js → cron-create-CRSPET3H.js} +4 -4
  238. package/chunks/{cron-delete-MBLQCAYY.js → cron-delete-DB77SZTU.js} +4 -4
  239. package/chunks/{cron-list-DWH2PQ47.js → cron-list-U2JNYWV6.js} +4 -4
  240. package/chunks/{daemon-3GNHB3M2.js → daemon-RKDGBFLK.js} +613 -102
  241. package/chunks/{daemon-git-worktree-guard-IVAJJWYK.js → daemon-git-worktree-guard-O2HPOBAB.js} +62 -61
  242. package/chunks/daemon-status-provider-GRRVCJFW.js +117 -0
  243. package/chunks/daemon-trust-policy-YJL442BK.js +113 -0
  244. package/chunks/{daemon-trust-policy-monitor-KGGROSIV.js → daemon-trust-policy-monitor-JL7F4Y4Q.js} +68 -67
  245. package/chunks/{de-X6HLSIFE.js → de-T4BLOKEC.js} +3 -0
  246. package/chunks/deferred-core-runtime-S32AYVZI.js +115 -0
  247. package/chunks/{devtools-JCG4K2NZ.js → devtools-VDRJYPZF.js} +1 -1
  248. package/chunks/{discovery-X2NV535U.js → discovery-TUM3ZQ6U.js} +2 -2
  249. package/chunks/{display-image-BE7I6ZB6.js → display-image-73C7XNRK.js} +5 -5
  250. package/chunks/{dist-LVZCXVPF.js → dist-62OZ7QXB.js} +44 -26
  251. package/chunks/{dist-GFN5DCBX.js → dist-EDHQIBYD.js} +152 -63
  252. package/chunks/{dist-N6W6E753.js → dist-GT64AAUR.js} +135 -26
  253. package/chunks/{dist-6BPYWHVD.js → dist-JVXT4VUJ.js} +14 -7
  254. package/chunks/{dist-4WXLCBDR.js → dist-L6URO6CK.js} +12 -5
  255. package/chunks/{dist-5VXFRTWU.js → dist-LXFYIJNG.js} +866 -172
  256. package/chunks/{dist-SWQMYP2Q.js → dist-PDGNRVPY.js} +27 -8
  257. package/chunks/{dist-NSV4NBPK.js → dist-QAF5DO3Y.js} +380 -83
  258. package/chunks/{dist-HZNT6GQS.js → dist-ZCJLKQSP.js} +28 -14
  259. package/chunks/earlyInputCapture-BBPCIVZG.js +108 -0
  260. package/chunks/{edit-LEQLAGPZ.js → edit-SUGXY63Y.js} +47 -47
  261. package/chunks/{en-YLXBXM4Z.js → en-2RATMNX7.js} +5 -0
  262. package/chunks/{enter-worktree-35QCAAFP.js → enter-worktree-B6USKSIK.js} +7 -7
  263. package/chunks/{enterPlanMode-ONQN3WHE.js → enterPlanMode-MDX4RVVL.js} +48 -48
  264. package/chunks/{environment-UANTR7A4.js → environment-VN6RXDVN.js} +63 -62
  265. package/chunks/errors-UEY36PIT.js +114 -0
  266. package/chunks/{exit-worktree-XQD6D543.js → exit-worktree-DLQ73SJH.js} +10 -8
  267. package/chunks/exitPlanMode-EPHIEDAA.js +83 -0
  268. package/chunks/{fast-path-WUL7UZ6H.js → fast-path-Y73R42LV.js} +8 -7
  269. package/chunks/{fast-path-settings-XH426LUU.js → fast-path-settings-MFUR3IWK.js} +3 -3
  270. package/chunks/{fr-FTZWF462.js → fr-BGHGYX6A.js} +3 -0
  271. package/chunks/{glob-Y54QUWDY.js → glob-DMGH7EZN.js} +47 -47
  272. package/chunks/goal-tools-3RF3PXCL.js +99 -0
  273. package/chunks/{grep-5GPICQBU.js → grep-AJVLCVXC.js} +9 -7
  274. package/chunks/handleAutoUpdate-HVWQT2AU.js +110 -0
  275. package/chunks/i18n-5OR7NTRZ.js +125 -0
  276. package/chunks/{image-gen-J6FDGUZP.js → image-gen-VOIDOHOB.js} +8 -8
  277. package/chunks/initializer-JE5RQSOE.js +114 -0
  278. package/chunks/installationInfo-KO3CCSCK.js +108 -0
  279. package/chunks/{ja-2GL5FKYJ.js → ja-G3FTD5XE.js} +3 -0
  280. package/chunks/{keychain-token-storage-37XPR34V.js → keychain-token-storage-REZVMJA6.js} +2 -2
  281. package/chunks/list-3IORSFIY.js +117 -0
  282. package/chunks/list-agents-SBMONIUK.js +128 -0
  283. package/chunks/{llm-NSAVK5V3.js → llm-K26SUDVK.js} +223 -140
  284. package/chunks/{llm-content-generator-AY2QKXHE.js → llm-content-generator-TT6EAUD4.js} +11 -12
  285. package/chunks/loadedSettingsAdapter-KLLFZF3M.js +111 -0
  286. package/chunks/{loggingContentGenerator-DSFQHXIF.js → loggingContentGenerator-EYQBA4M4.js} +66 -65
  287. package/chunks/{loop-wakeup-XJFONSQ7.js → loop-wakeup-QA6SHCZT.js} +5 -5
  288. package/chunks/{ls-3VAT2J7A.js → ls-HEJNCEYO.js} +4 -4
  289. package/chunks/{lsp-5W7IRUBH.js → lsp-WOQKNZP6.js} +2 -2
  290. package/chunks/{managed-npm-update-TSWENTK5.js → managed-npm-update-HIJTODQT.js} +61 -60
  291. package/chunks/mcp-A2UEHETW.js +111 -0
  292. package/chunks/{monitor-RW4GWJHB.js → monitor-DKNZQAB2.js} +46 -46
  293. package/chunks/{node-QKLNSZMX.js → node-UETAYMMO.js} +3 -3
  294. package/chunks/nonInteractiveCli-YA47F2F4.js +190 -0
  295. package/chunks/{notebook-edit-CQNYS5OR.js → notebook-edit-MGHTRL2D.js} +47 -47
  296. package/chunks/{open-with-auth-YN3QZHVM.js → open-with-auth-D6JD6LDS.js} +3 -3
  297. package/chunks/{openaiContentGenerator-J6QIF7EX.js → openaiContentGenerator-ZJIEQ3ZJ.js} +26 -28
  298. package/chunks/pidfile-ETHAZNMY.js +112 -0
  299. package/chunks/{processUtils-GPHNANKZ.js → processUtils-UY3SAJJZ.js} +2 -2
  300. package/chunks/prompt-terminal-ledger-GZ747VYE.js +106 -0
  301. package/chunks/{pt-XN2YWJVM.js → pt-D73IFYT7.js} +3 -0
  302. package/chunks/{qwenContentGenerator-WWDXPYQI.js → qwenContentGenerator-VI4KATRY.js} +58 -58
  303. package/chunks/{qwenOAuth2-OF5WRBQT.js → qwenOAuth2-7AOCKSOQ.js} +7 -7
  304. package/chunks/{read-file-FQUQHC6N.js → read-file-P7F4P7LV.js} +11 -13
  305. package/chunks/{read-mcp-resource-XD257PGJ.js → read-mcp-resource-GLAGB6R7.js} +2 -2
  306. package/chunks/{record-artifact-VW23GS4F.js → record-artifact-SWVR7NSU.js} +4 -4
  307. package/chunks/renderer-selection-M4UN63VJ.js +99 -0
  308. package/chunks/{report-findings-AO5VYFLR.js → report-findings-AL5YW3KI.js} +5 -5
  309. package/chunks/{request-shutdown-BCLA3JV2.js → request-shutdown-5YK4IZ54.js} +8 -7
  310. package/chunks/resumeHistoryUtils-DPZKFW24.js +119 -0
  311. package/chunks/ripGrep-C7LJKUPZ.js +37 -0
  312. package/chunks/{ru-OLTMFJEW.js → ru-QMISLKRH.js} +3 -0
  313. package/chunks/{run-qwen-serve-5X6IDZER.js → run-qwen-serve-OGTEEUR2.js} +589 -251
  314. package/chunks/{runtime-HK27GMPF.js → runtime-LNBLEMZS.js} +73 -72
  315. package/chunks/scheduled-tasks-FLDYZQOF.js +128 -0
  316. package/chunks/{scheduler-WD4MHMO5.js → scheduler-73YXGUGW.js} +62 -61
  317. package/chunks/{sdk-exporters-grpc-G5IT4XS4.js → sdk-exporters-grpc-MXTVSE3C.js} +2 -2
  318. package/chunks/{sdk-exporters-http-TTU2CHBU.js → sdk-exporters-http-3JO5TJNU.js} +4 -4
  319. package/chunks/{sdk-impl-UUMVYMAL.js → sdk-impl-HZAUUTHJ.js} +6 -6
  320. package/chunks/{send-message-AJ4OCUBV.js → send-message-JC7NJTY6.js} +166 -35
  321. package/chunks/serve-3UR2H4CV.js +119 -0
  322. package/chunks/{server-GO2N5DH7.js → server-AOYZVVOM.js} +2904 -860
  323. package/chunks/{session-IFNHTUBT.js → session-UAWFNFGI.js} +119 -114
  324. package/chunks/session-attachments-root-ZCGXQQTR.js +104 -0
  325. package/chunks/{session-pr-refresh-I3UBWMVP.js → session-pr-refresh-CT2INROL.js} +157 -88
  326. package/chunks/{settings-L6N54CU6.js → settings-BHRGDASJ.js} +67 -66
  327. package/chunks/{shell-4Y5LLW6N.js → shell-YHOGC7TO.js} +46 -46
  328. package/chunks/{skill-YOWTRAKQ.js → skill-ZGBKNCHQ.js} +131 -97
  329. package/chunks/skill-settings-AKSP665O.js +119 -0
  330. package/chunks/spawnChannel-N25MBB6F.js +112 -0
  331. package/chunks/standalone-update-XGPWJDRN.js +119 -0
  332. package/chunks/start-opentui-ui-FZ4USOU7.js +55342 -0
  333. package/chunks/{startInteractiveUI-XDFSHBZD.js → startInteractiveUI-E2WQJUOA.js} +3509 -4706
  334. package/chunks/{syntheticOutput-ML43GEFN.js → syntheticOutput-HJNZSEHN.js} +3 -3
  335. package/chunks/{task-create-QN4LYRSE.js → task-create-6RSD54S5.js} +12 -12
  336. package/chunks/{task-list-JPLGK45U.js → task-list-IQSACPOM.js} +34 -11
  337. package/chunks/{task-stop-CXEH5L2D.js → task-stop-HE2LRQNW.js} +2 -2
  338. package/chunks/{task-update-IWEOJFV2.js → task-update-XAJ2NYOA.js} +13 -14
  339. package/chunks/{team-create-OOPXCDBA.js → team-create-SOKMYSQU.js} +54 -55
  340. package/chunks/{team-delete-RZVVSGCY.js → team-delete-NGNNKGMG.js} +25 -8
  341. package/chunks/{team-plan-approval-DSX5EWAT.js → team-plan-approval-U7ZWXYAY.js} +46 -46
  342. package/chunks/terminal-image-renderer-KKM4OBLO.js +117 -0
  343. package/chunks/theme-manager-GQHF3A7T.js +103 -0
  344. package/chunks/{todoWrite-WDJNQEMW.js → todoWrite-5UTVUXHA.js} +39 -9
  345. package/chunks/{tool-search-J5Q6U7DN.js → tool-search-IAI2RVWT.js} +21 -19
  346. package/chunks/total-session-admission-G4CGCSTG.js +113 -0
  347. package/chunks/trustedFolders-D2I3FDPB.js +123 -0
  348. package/chunks/{update-relaunch-SIKHLHVR.js → update-relaunch-5RWKZAL3.js} +5 -5
  349. package/chunks/updateCheck-ZXOQDFEI.js +119 -0
  350. package/chunks/useAutoAcceptIndicator-6EK4QGAH.js +121 -0
  351. package/chunks/{validateNonInterActiveAuth-JUDQP6V4.js → validateNonInterActiveAuth-QPFEKATS.js} +113 -109
  352. package/chunks/{version-C63GDDWN.js → version-JKNG7YDH.js} +1 -1
  353. package/chunks/{web-fetch-FOQZMNSC.js → web-fetch-X3AHIIHW.js} +16 -19
  354. package/chunks/{web-search-PUJTBFUC.js → web-search-K2FMOGS5.js} +10 -11
  355. package/chunks/{web-shell-static-HNB4FDOE.js → web-shell-static-POZHGGXE.js} +5 -4
  356. package/chunks/{workflow-Y5IPINVH.js → workflow-TOLPAK5G.js} +213 -119
  357. package/chunks/workspace-providers-status-PCJK3RC7.js +115 -0
  358. package/chunks/{workspace-registration-store-SMJWI2AI.js → workspace-registration-store-KQWVVW4Y.js} +2 -1
  359. package/chunks/workspace-registry-YNIOB6HJ.js +122 -0
  360. package/chunks/workspace-runtime-coordinator-WG2RNEN7.js +123 -0
  361. package/chunks/workspace-service-G4ZNBOFH.js +127 -0
  362. package/chunks/workspace-skills-status-FMTPPMWC.js +114 -0
  363. package/chunks/{workspace-trust-reconciler-PLIDLJZX.js → workspace-trust-reconciler-IBDFQBQS.js} +76 -77
  364. package/chunks/wrapper-JH3IFHT2.js +35 -0
  365. package/chunks/write-file-YTLFY2S5.js +88 -0
  366. package/chunks/{zh-UNY63FR3.js → zh-25DF7OGK.js} +5 -0
  367. package/chunks/{zh-TW-RPTMRTHG.js → zh-TW-5EDMZVGK.js} +5 -0
  368. package/chunks/{zoom-image-LYQD7BQA.js → zoom-image-IFXSN74N.js} +11 -13
  369. package/cli.js +131 -90
  370. package/locales/ca.js +6 -0
  371. package/locales/de.js +6 -0
  372. package/locales/en.js +9 -0
  373. package/locales/fr.js +6 -0
  374. package/locales/ja.js +6 -0
  375. package/locales/pt.js +6 -0
  376. package/locales/ru.js +6 -0
  377. package/locales/zh-TW.js +9 -0
  378. package/locales/zh.js +9 -0
  379. package/package.json +3 -3
  380. package/web-shell/assets/{abnfDiagram-VCTEODGH-TRCMSA_6.js → abnfDiagram-VCTEODGH-Cxf7xE_Z.js} +1 -1
  381. package/web-shell/assets/{arc-D9Uls5b3.js → arc-ESi1eNkE.js} +1 -1
  382. package/web-shell/assets/{architectureDiagram-5GKGNRK7-Bwb8jPXg.js → architectureDiagram-5GKGNRK7-D9l7-bDo.js} +1 -1
  383. package/web-shell/assets/{blockDiagram-NRAW4CY4-DHj71TSX.js → blockDiagram-NRAW4CY4-Bc8DEasw.js} +1 -1
  384. package/web-shell/assets/{c4Diagram-UCG6FXSJ-uKBBdbyr.js → c4Diagram-UCG6FXSJ-Dimb2Hmh.js} +1 -1
  385. package/web-shell/assets/channel-B7ohGDil.js +1 -0
  386. package/web-shell/assets/{chunk-2Q5K7J3B-BZd0Phrl.js → chunk-2Q5K7J3B-jVDmOpAQ.js} +1 -1
  387. package/web-shell/assets/{chunk-5VM5RSS4-7KNeNBqN.js → chunk-5VM5RSS4-DbG_SwdB.js} +1 -1
  388. package/web-shell/assets/{chunk-F27PBJKO-BeboS7Fi.js → chunk-F27PBJKO-QEc4cY1v.js} +1 -1
  389. package/web-shell/assets/{chunk-G27WJ6UU-RV3JONoj.js → chunk-G27WJ6UU-iJ36lQ3X.js} +1 -1
  390. package/web-shell/assets/{chunk-JWPE2WC7-Yw9FCFsP.js → chunk-JWPE2WC7-DuArnVtF.js} +1 -1
  391. package/web-shell/assets/{chunk-LCL6LL3I-GIMnydDe.js → chunk-LCL6LL3I-DxOf1zwL.js} +1 -1
  392. package/web-shell/assets/{chunk-POPQ4Y6H-Cfrux7bL.js → chunk-POPQ4Y6H-lVLu9Ild.js} +1 -1
  393. package/web-shell/assets/{chunk-SVP7TREG-BlvIN0CO.js → chunk-SVP7TREG-C6XYlIer.js} +1 -1
  394. package/web-shell/assets/{chunk-XXDRQBXY-DMs7Rr4t.js → chunk-XXDRQBXY-CiG2j2Ji.js} +1 -1
  395. package/web-shell/assets/classDiagram-DTDB5LWJ-DdFpqpfD.js +1 -0
  396. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DdFpqpfD.js +1 -0
  397. package/web-shell/assets/{cose-bilkent-JH36ORCC-DNGqTNwI.js → cose-bilkent-JH36ORCC-DGVHMMVm.js} +1 -1
  398. package/web-shell/assets/{cynefin-OW5HDTMX-CojMpaoH.js → cynefin-OW5HDTMX-D6cgpCnH.js} +1 -1
  399. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-DF07YXGo.js → cynefinDiagram-5FMLGOSQ-BKv4Z-UX.js} +1 -1
  400. package/web-shell/assets/{dagre-3AP2YEHR-17-4WtCH.js → dagre-3AP2YEHR-B4ABMIG-.js} +1 -1
  401. package/web-shell/assets/{diagram-S7CK7UJ4-G3Wuyz9m.js → diagram-S7CK7UJ4-DgCkp_Lm.js} +1 -1
  402. package/web-shell/assets/{diagram-UQ7AKVKN-nyWIKZ8P.js → diagram-UQ7AKVKN-FG0FNokz.js} +1 -1
  403. package/web-shell/assets/{diagram-VSXAHHWV-tKHhmYSC.js → diagram-VSXAHHWV-JgkP9qg-.js} +1 -1
  404. package/web-shell/assets/{diagram-VX7I27RA-CpDf1hYk.js → diagram-VX7I27RA-ADh2x83l.js} +1 -1
  405. package/web-shell/assets/{diagram-Z3DM3KII-Cah2IFXG.js → diagram-Z3DM3KII-yXqoYF1J.js} +1 -1
  406. package/web-shell/assets/{ebnfDiagram-PWID7BFC-DNaCkgxy.js → ebnfDiagram-PWID7BFC-Duk83Ek_.js} +1 -1
  407. package/web-shell/assets/{erDiagram-SSCWMZ5O-CAdRgcf1.js → erDiagram-SSCWMZ5O-DMdvxySG.js} +1 -1
  408. package/web-shell/assets/{flowDiagram-A5DVABFB-CMUJAShL.js → flowDiagram-A5DVABFB-DHjVgSji.js} +1 -1
  409. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-o-_MUNey.js → ganttDiagram-EL5Y4UJY-DMM9DkCE.js} +1 -1
  410. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-_aG-2Z7O.js → gitGraphDiagram-WWUBYQGX-t_ug9vO8.js} +1 -1
  411. package/web-shell/assets/index-BGZRqbRo.css +36 -0
  412. package/web-shell/assets/index-DRri_6_x.js +2067 -0
  413. package/web-shell/assets/{index-BK_NKxiJ.js → index-zqvnpGHv.js} +1 -1
  414. package/web-shell/assets/{infoDiagram-RXCK75RN-qJPeZbGP.js → infoDiagram-RXCK75RN-eT1fANNm.js} +1 -1
  415. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-7Om4vNo1.js → ishikawaDiagram-5VMMS53U-k3evzZNn.js} +1 -1
  416. package/web-shell/assets/{journeyDiagram-EYS64GPL-BNtXqmBW.js → journeyDiagram-EYS64GPL-CGim3EAi.js} +1 -1
  417. package/web-shell/assets/{kanban-definition-3QL26DDD-COgFec8P.js → kanban-definition-3QL26DDD-WHfJo-22.js} +1 -1
  418. package/web-shell/assets/{layout-B9n81PC9.js → layout-DkqIaFlJ.js} +1 -1
  419. package/web-shell/assets/{linear-Bb6nXZQq.js → linear-Bdkd3mCz.js} +1 -1
  420. package/web-shell/assets/{mermaid.core-Cgrm3JVT.js → mermaid.core-CGw0LkT_.js} +6 -6
  421. package/web-shell/assets/{mindmap-definition-FBJOCRG2-TKwLTjnG.js → mindmap-definition-FBJOCRG2-C9V4rBvo.js} +1 -1
  422. package/web-shell/assets/{pegDiagram-XKGWAZYB-BJPuvlpi.js → pegDiagram-XKGWAZYB-CwoI2T5G.js} +1 -1
  423. package/web-shell/assets/{pieDiagram-E7YTZNPT-D01VkNsW.js → pieDiagram-E7YTZNPT-DaTmBmPG.js} +1 -1
  424. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-C4hHsiv-.js → quadrantDiagram-AXDQQJYC-plh6MyGI.js} +1 -1
  425. package/web-shell/assets/{railroadDiagram-O6MQD6OU-CuEO4xK2.js → railroadDiagram-O6MQD6OU-D_b-S0iK.js} +1 -1
  426. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-D5J_vIo5.js → requirementDiagram-EFPCY7ZU-zUzTN7VE.js} +1 -1
  427. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-DQKY223V.js → sankeyDiagram-P5KCCOFB-m6AhoD0l.js} +1 -1
  428. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-D27YV_cm.js → sequenceDiagram-WJ2MYXX4-Cwhzsine.js} +1 -1
  429. package/web-shell/assets/{sizeCapture-X5ZJPWSS-TJg8UcwV.js → sizeCapture-X5ZJPWSS-CcZuKIae.js} +1 -1
  430. package/web-shell/assets/{stateDiagram-HBIQ2CUA-CmnPzUIx.js → stateDiagram-HBIQ2CUA-CFoiJwD_.js} +1 -1
  431. package/web-shell/assets/stateDiagram-v2-4QOOHH4V--H8HdEmk.js +1 -0
  432. package/web-shell/assets/{swimlanes-XN3QIQJK-ByeP3_Nu.js → swimlanes-XN3QIQJK-CgS9hcaV.js} +1 -1
  433. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ShE9OIgf.js +8 -0
  434. package/web-shell/assets/{timeline-definition-24CTP7MA-BsFA5juR.js → timeline-definition-24CTP7MA-Dzzc05t9.js} +1 -1
  435. package/web-shell/assets/{vennDiagram-4TSXK5OY-DREP2ECo.js → vennDiagram-4TSXK5OY-DemK0f7Y.js} +1 -1
  436. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-iyd9lKi2.js → wardleyDiagram-VM6X3IG4-CquLxtMr.js} +1 -1
  437. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-CVr1_j9q.js → xychartDiagram-S5SC5T6Z-BTBKTM5g.js} +1 -1
  438. package/web-shell/index.html +196 -2
  439. package/chunks/MaxSizedBox-X42SXBJH.js +0 -110
  440. package/chunks/agent-headless-IZM25LJA.js +0 -85
  441. package/chunks/bridge-ME6QXZNA.js +0 -119
  442. package/chunks/channel-settings-store-PEOI7XCG.js +0 -120
  443. package/chunks/chunk-7J6OTNGO.js +0 -424
  444. package/chunks/chunk-BWORX6FA.js +0 -135
  445. package/chunks/chunk-CPBF7KYF.js +0 -51
  446. package/chunks/chunk-H72BQNM3.js +0 -645
  447. package/chunks/chunk-JHYH6PYQ.js +0 -3096
  448. package/chunks/chunk-SS4MRMKE.js +0 -3525
  449. package/chunks/chunk-T4EFG2P5.js +0 -113
  450. package/chunks/chunk-XZA32HII.js +0 -19
  451. package/chunks/chunk-ZYNTSXWK.js +0 -32
  452. package/chunks/config-utils-R6M3TA34.js +0 -113
  453. package/chunks/contextCommand-ZCAP23J6.js +0 -106
  454. package/chunks/daemon-status-provider-K3SJ5C2U.js +0 -117
  455. package/chunks/daemon-trust-policy-DOR3YG62.js +0 -112
  456. package/chunks/deferred-core-runtime-WOYLUQQ7.js +0 -114
  457. package/chunks/earlyInputCapture-OHBEVO4K.js +0 -107
  458. package/chunks/errors-WAK6KFBC.js +0 -113
  459. package/chunks/exitPlanMode-UEYBG6P5.js +0 -83
  460. package/chunks/goal-tools-PTD3MBA7.js +0 -411
  461. package/chunks/handleAutoUpdate-FP3NWNSG.js +0 -109
  462. package/chunks/i18n-INIU5X7A.js +0 -124
  463. package/chunks/initializer-TYODV6GE.js +0 -113
  464. package/chunks/installationInfo-AAPKYDSZ.js +0 -107
  465. package/chunks/list-TUODDN6J.js +0 -116
  466. package/chunks/list-agents-DI3YFTDT.js +0 -80
  467. package/chunks/loadedSettingsAdapter-KJCLZ3C4.js +0 -110
  468. package/chunks/mcp-MWSAPFOL.js +0 -110
  469. package/chunks/nonInteractiveCli-JXKL343Q.js +0 -185
  470. package/chunks/pidfile-QOIQZFT2.js +0 -111
  471. package/chunks/prompt-terminal-ledger-FOMFTYOM.js +0 -105
  472. package/chunks/resumeHistoryUtils-NSGF3UCB.js +0 -118
  473. package/chunks/ripGrep-4CAT6SKV.js +0 -39
  474. package/chunks/scheduled-tasks-MN2ZZ5P6.js +0 -127
  475. package/chunks/serve-2XCHPPGG.js +0 -118
  476. package/chunks/skill-settings-ZL4JY5UE.js +0 -118
  477. package/chunks/spawnChannel-ZST6XJVJ.js +0 -112
  478. package/chunks/standalone-update-THVU3OKY.js +0 -118
  479. package/chunks/terminal-image-renderer-KS25G33E.js +0 -114
  480. package/chunks/theme-manager-YMZNG45F.js +0 -102
  481. package/chunks/total-session-admission-PVN64JVV.js +0 -114
  482. package/chunks/trustedFolders-FATSC4YI.js +0 -122
  483. package/chunks/updateCheck-D3YG2WCD.js +0 -118
  484. package/chunks/useAutoAcceptIndicator-ILINOSAS.js +0 -120
  485. package/chunks/workspace-providers-status-IJ4VHFMB.js +0 -114
  486. package/chunks/workspace-registry-BTGZIMPK.js +0 -123
  487. package/chunks/workspace-service-SIN67ITC.js +0 -126
  488. package/chunks/workspace-skills-status-F3RKCUIX.js +0 -113
  489. package/chunks/write-file-PAIGB33C.js +0 -88
  490. package/web-shell/assets/channel-CXjVLaBa.js +0 -1
  491. package/web-shell/assets/classDiagram-DTDB5LWJ-DANEijO3.js +0 -1
  492. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DANEijO3.js +0 -1
  493. package/web-shell/assets/index-Ci-z4zWY.js +0 -1913
  494. package/web-shell/assets/index-LDlXZRHA.css +0 -36
  495. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DNKPyrDc.js +0 -1
  496. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ZL1HPC6w.js +0 -8
  497. /package/chunks/{chunk-FOGQO4FG.js → chunk-JA5CBKRP.js} +0 -0
@@ -4,9 +4,9 @@ import {
4
4
  require_dist,
5
5
  require_follow_redirects,
6
6
  require_form_data
7
- } from "./chunk-XIQ5HQ2F.js";
7
+ } from "./chunk-OBTWL6ZW.js";
8
8
  import "./chunk-K6KS3LTN.js";
9
- import "./chunk-7E7UCJHS.js";
9
+ import "./chunk-OSHQMOBS.js";
10
10
  import {
11
11
  ChannelBase,
12
12
  isTerminalTaskLifecycleType,
@@ -14,14 +14,14 @@ import {
14
14
  sanitizePromptText,
15
15
  sanitizeSenderName,
16
16
  truncateUtf16Units
17
- } from "./chunk-ICURCKIU.js";
17
+ } from "./chunk-U4DJ5XB3.js";
18
18
  import "./chunk-IW6RQPQB.js";
19
19
  import "./chunk-CQ35AJ4Z.js";
20
20
  import "./chunk-DMTGGOSA.js";
21
21
  import "./chunk-YQ3U5MUC.js";
22
22
  import {
23
23
  wrapper_default
24
- } from "./chunk-J3NNHTV6.js";
24
+ } from "./chunk-J5TTWBZK.js";
25
25
  import "./chunk-RVIGZBIT.js";
26
26
  import {
27
27
  init_esbuild_shims
@@ -39,8 +39,8 @@ init_esbuild_shims();
39
39
  init_esbuild_shims();
40
40
  import { mkdirSync, rmSync, writeFileSync } from "node:fs";
41
41
  import { randomUUID as randomUUID5 } from "node:crypto";
42
- import { basename as basename2, join } from "node:path";
43
- import { tmpdir as tmpdir2 } from "node:os";
42
+ import { basename as basename3, join } from "node:path";
43
+ import { tmpdir as tmpdir3 } from "node:os";
44
44
  import { Buffer as Buffer2 } from "node:buffer";
45
45
 
46
46
  // node_modules/dingtalk-stream-sdk-nodejs/dist/index.mjs
@@ -5792,9 +5792,21 @@ var DWClient = class extends EventEmitter2 {
5792
5792
 
5793
5793
  // packages/channels/dingtalk/dist/markdown.js
5794
5794
  init_esbuild_shims();
5795
- var CHUNK_LIMIT = 3800;
5796
- function splitChunks(text) {
5797
- if (!text || text.length <= CHUNK_LIMIT) {
5795
+ var DINGTALK_CHUNK_LIMIT = 3800;
5796
+ function escapeDingTalkMarkdown(value) {
5797
+ return value.replace(/([\\`*_[\]{}()#+.!|>~:-])/gu, "\\$1");
5798
+ }
5799
+ __name(escapeDingTalkMarkdown, "escapeDingTalkMarkdown");
5800
+ function safeUtf16SliceEnd(value, end) {
5801
+ if (end <= 0 || end >= value.length)
5802
+ return end;
5803
+ const previous = value.charCodeAt(end - 1);
5804
+ const next = value.charCodeAt(end);
5805
+ return previous >= 55296 && previous <= 56319 && next >= 56320 && next <= 57343 ? end - 1 : end;
5806
+ }
5807
+ __name(safeUtf16SliceEnd, "safeUtf16SliceEnd");
5808
+ function splitChunks(text, chunkLimit = DINGTALK_CHUNK_LIMIT) {
5809
+ if (!text || text.length <= chunkLimit) {
5798
5810
  return [text];
5799
5811
  }
5800
5812
  const chunks = [];
@@ -5814,11 +5826,15 @@ function splitChunks(text) {
5814
5826
  let lineOpenedFenceInBuffer = false;
5815
5827
  while (remaining.length > 0 || prefixPending) {
5816
5828
  const prefix = prefixPending ? "\n" : "";
5817
- const fitsAsFinalPiece = remaining.length <= CHUNK_LIMIT - buf.length - prefix.length;
5829
+ const fitsAsFinalPiece = remaining.length <= chunkLimit - buf.length - prefix.length;
5818
5830
  const closeFenceOverhead = inCode && !(closesCodeFence && fitsAsFinalPiece) || !inCode && leavesCodeFenceOpen ? "\n```".length : 0;
5819
- const available = CHUNK_LIMIT - closeFenceOverhead - buf.length - prefix.length;
5831
+ const available = chunkLimit - closeFenceOverhead - buf.length - prefix.length;
5820
5832
  if (available <= 0) {
5821
- flush(inCode || lineOpenedFenceInBuffer);
5833
+ const keepCodeOpen = inCode || lineOpenedFenceInBuffer;
5834
+ if (buf === (keepCodeOpen ? "```" : "")) {
5835
+ throw new RangeError("chunk limit cannot contain one Unicode character");
5836
+ }
5837
+ flush(keepCodeOpen);
5822
5838
  continue;
5823
5839
  }
5824
5840
  let pieceLength = Math.min(available, remaining.length);
@@ -5830,8 +5846,13 @@ function splitChunks(text) {
5830
5846
  }
5831
5847
  }
5832
5848
  }
5849
+ pieceLength = safeUtf16SliceEnd(remaining, pieceLength);
5833
5850
  if (pieceLength === 0 && remaining.length > 0) {
5834
- flush(inCode || lineOpenedFenceInBuffer);
5851
+ const keepCodeOpen = inCode || lineOpenedFenceInBuffer;
5852
+ if (!buf || keepCodeOpen && buf === "```") {
5853
+ throw new RangeError("chunk limit cannot contain one Unicode character");
5854
+ }
5855
+ flush(keepCodeOpen);
5835
5856
  continue;
5836
5857
  }
5837
5858
  const piece = remaining.slice(0, pieceLength);
@@ -5868,8 +5889,8 @@ function extractTitle(text) {
5868
5889
  return cleaned || "Reply";
5869
5890
  }
5870
5891
  __name(extractTitle, "extractTitle");
5871
- function normalizeDingTalkMarkdown(text) {
5872
- return splitChunks(text);
5892
+ function normalizeDingTalkMarkdown(text, chunkLimit = DINGTALK_CHUNK_LIMIT) {
5893
+ return splitChunks(text, chunkLimit);
5873
5894
  }
5874
5895
  __name(normalizeDingTalkMarkdown, "normalizeDingTalkMarkdown");
5875
5896
 
@@ -6156,8 +6177,15 @@ __name(uploadDingTalkImage, "uploadDingTalkImage");
6156
6177
 
6157
6178
  // packages/channels/dingtalk/dist/outbound-file.js
6158
6179
  init_esbuild_shims();
6180
+ import { closeSync as closeSync2, constants, fstatSync as fstatSync2, openSync as openSync2, readSync as readSync2, realpathSync as realpathSync2, statSync } from "node:fs";
6181
+ import { tmpdir as tmpdir2 } from "node:os";
6182
+ import { basename as basename2, extname as extname2, isAbsolute as isAbsolute2, relative as relative2, sep } from "node:path";
6159
6183
  var FILE_OPENING = "[FILE:";
6184
+ var MEDIA_UPLOAD_API2 = "https://oapi.dingtalk.com/media/upload";
6185
+ var MEDIA_UPLOAD_TIMEOUT_MS2 = 3e4;
6160
6186
  var MAX_FILE_PATH_CHARS = 4096;
6187
+ var MAX_FILE_BYTES = 20 * 1024 * 1024;
6188
+ var AUTH_ERROR_CODES2 = /* @__PURE__ */ new Set([40014, 42001]);
6161
6189
  var MAX_FILES_PER_RESPONSE = 5;
6162
6190
  var FILE_UNAVAILABLE_NOTICE = "[File delivery unavailable]";
6163
6191
  var OutboundFileProjector = class {
@@ -6256,6 +6284,104 @@ function withFileUnavailableNotice(text) {
6256
6284
  return `${safe}${safe ? "\n" : ""}${FILE_UNAVAILABLE_NOTICE}`;
6257
6285
  }
6258
6286
  __name(withFileUnavailableNotice, "withFileUnavailableNotice");
6287
+ function safeFileName(filePath) {
6288
+ return basename2(filePath).replace(/[\p{Cc}\p{Cf}[\]]+/gu, "_").slice(0, 200) || "file";
6289
+ }
6290
+ __name(safeFileName, "safeFileName");
6291
+ function isInside2(filePath, directory) {
6292
+ const child = relative2(directory, filePath);
6293
+ return child === "" || !isAbsolute2(child) && child !== ".." && !child.startsWith(`..${sep}`);
6294
+ }
6295
+ __name(isInside2, "isInside");
6296
+ function readValidatedFile(filePath, workspaceDir) {
6297
+ if (!isAbsolute2(filePath))
6298
+ throw new Error("File path must be absolute");
6299
+ let realPath;
6300
+ try {
6301
+ realPath = realpathSync2(filePath);
6302
+ } catch {
6303
+ throw new Error("File not found");
6304
+ }
6305
+ const roots = [
6306
+ workspaceDir,
6307
+ tmpdir2(),
6308
+ ...process.platform === "win32" ? [] : ["/tmp"]
6309
+ ].map((root) => realpathSync2(root));
6310
+ if (!roots.some((root) => isInside2(realPath, root))) {
6311
+ throw new Error("File path outside allowed directories");
6312
+ }
6313
+ if (!statSync(realPath).isFile())
6314
+ throw new Error("Not a regular file");
6315
+ const descriptor = openSync2(realPath, constants.O_RDONLY | constants.O_NONBLOCK | (constants.O_NOFOLLOW ?? 0));
6316
+ try {
6317
+ const stats = fstatSync2(descriptor);
6318
+ if (!stats.isFile())
6319
+ throw new Error("Not a regular file");
6320
+ if (stats.size === 0)
6321
+ throw new Error("File is empty");
6322
+ if (stats.size > MAX_FILE_BYTES)
6323
+ throw new Error("File is too large");
6324
+ const data = Buffer.allocUnsafe(stats.size + 1);
6325
+ let bytesRead = 0;
6326
+ while (bytesRead < data.length) {
6327
+ const count = readSync2(descriptor, data, bytesRead, data.length - bytesRead, bytesRead);
6328
+ if (count === 0)
6329
+ break;
6330
+ bytesRead += count;
6331
+ }
6332
+ if (bytesRead !== stats.size)
6333
+ throw new Error("File changed while read");
6334
+ const fileName = safeFileName(realPath);
6335
+ return {
6336
+ data: data.subarray(0, bytesRead),
6337
+ fileName,
6338
+ fileType: extname2(fileName).slice(1).toLowerCase() || "file"
6339
+ };
6340
+ } finally {
6341
+ closeSync2(descriptor);
6342
+ }
6343
+ }
6344
+ __name(readValidatedFile, "readValidatedFile");
6345
+ function sanitizeApiMessage2(message, accessToken) {
6346
+ const value = String(message ?? "");
6347
+ return (accessToken ? value.replaceAll(accessToken, "[redacted]") : value).replace(/[\r\n\t]+/g, " ").slice(0, 200);
6348
+ }
6349
+ __name(sanitizeApiMessage2, "sanitizeApiMessage");
6350
+ async function uploadDingTalkFile(file, accessToken) {
6351
+ const form = new FormData();
6352
+ form.append("media", new Blob([file.data], { type: "application/octet-stream" }), file.fileName);
6353
+ let response;
6354
+ try {
6355
+ const url2 = new URL(MEDIA_UPLOAD_API2);
6356
+ url2.searchParams.set("access_token", accessToken);
6357
+ url2.searchParams.set("type", "file");
6358
+ response = await fetch(url2, {
6359
+ method: "POST",
6360
+ body: form,
6361
+ signal: AbortSignal.timeout(MEDIA_UPLOAD_TIMEOUT_MS2)
6362
+ });
6363
+ } catch {
6364
+ throw new DingTalkMediaUploadError("DingTalk file upload failed: network request failed", false);
6365
+ }
6366
+ let payload;
6367
+ try {
6368
+ const parsed = await response.json();
6369
+ payload = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
6370
+ } catch {
6371
+ throw new DingTalkMediaUploadError(`DingTalk file upload failed: HTTP ${response.status} invalid JSON response`, response.status === 401);
6372
+ }
6373
+ const errcode = typeof payload["errcode"] === "number" ? payload["errcode"] : void 0;
6374
+ if (!response.ok || errcode !== void 0 && errcode !== 0) {
6375
+ const detail = sanitizeApiMessage2(payload["errmsg"], accessToken);
6376
+ throw new DingTalkMediaUploadError(`DingTalk file upload failed: HTTP ${response.status}${errcode === void 0 ? "" : ` errcode=${errcode}`}${detail ? ` ${detail}` : ""}`, response.status === 401 || errcode !== void 0 && AUTH_ERROR_CODES2.has(errcode));
6377
+ }
6378
+ const mediaId = typeof payload["media_id"] === "string" ? payload["media_id"] : typeof payload["mediaId"] === "string" ? payload["mediaId"] : void 0;
6379
+ if (!mediaId) {
6380
+ throw new DingTalkMediaUploadError("DingTalk file upload failed: response did not include a MediaID", false);
6381
+ }
6382
+ return mediaId;
6383
+ }
6384
+ __name(uploadDingTalkFile, "uploadDingTalkFile");
6259
6385
 
6260
6386
  // packages/channels/dingtalk/dist/DingtalkConnectionManager.js
6261
6387
  init_esbuild_shims();
@@ -6569,6 +6695,25 @@ var STATUS_CARD_TEMPLATE_ID = "675cde2f-f526-40cb-b828-f5b2b57b8b77.schema";
6569
6695
  var QUESTION_CARD_TEMPLATE_ID = "c2a6355b-9724-4f7e-9653-d33fcb3311bb.schema";
6570
6696
  var DINGTALK_API = "https://api.dingtalk.com";
6571
6697
  var CARD_FETCH_TIMEOUT_MS = 1e4;
6698
+ function isRetryableStatus(status) {
6699
+ return status === 408 || status === 425 || status === 429 || status >= 500 && status <= 599;
6700
+ }
6701
+ __name(isRetryableStatus, "isRetryableStatus");
6702
+ var DingtalkCardRequestError = class extends Error {
6703
+ static {
6704
+ __name(this, "DingtalkCardRequestError");
6705
+ }
6706
+ retryable;
6707
+ constructor(message, retryable) {
6708
+ super(message);
6709
+ this.retryable = retryable;
6710
+ this.name = "DingtalkCardRequestError";
6711
+ }
6712
+ };
6713
+ function isRetryableDingtalkCardError(error) {
6714
+ return !(error instanceof DingtalkCardRequestError) || error.retryable;
6715
+ }
6716
+ __name(isRetryableDingtalkCardError, "isRetryableDingtalkCardError");
6572
6717
  function stringifyCardParamMap(cardParamMap) {
6573
6718
  return Object.fromEntries(Object.entries(cardParamMap).map(([key, value]) => [
6574
6719
  key,
@@ -6617,7 +6762,7 @@ var DingtalkInteractiveCardClient = class {
6617
6762
  if (Array.isArray(deliveries)) {
6618
6763
  const failure = deliveries.find((entry) => entry !== null && typeof entry === "object" && entry.success === false);
6619
6764
  if (failure) {
6620
- throw new Error(`${input.templateId}: ${typeof failure.errorMsg === "string" && failure.errorMsg.trim() ? failure.errorMsg.trim() : "DingTalk card delivery failed"}`);
6765
+ throw new DingtalkCardRequestError(`${input.templateId}: ${typeof failure.errorMsg === "string" && failure.errorMsg.trim() ? failure.errorMsg.trim() : "DingTalk card delivery failed"}`, false);
6621
6766
  }
6622
6767
  }
6623
6768
  }
@@ -6642,21 +6787,28 @@ var DingtalkInteractiveCardClient = class {
6642
6787
  });
6643
6788
  }
6644
6789
  async request(path, method, body, templateId) {
6645
- const token = await this.options.getAccessToken();
6646
- const response = await this.fetch(`${DINGTALK_API}${path}`, {
6647
- method,
6648
- headers: {
6649
- "Content-Type": "application/json",
6650
- "x-acs-dingtalk-access-token": token
6651
- },
6652
- body: JSON.stringify(body),
6653
- signal: AbortSignal.timeout(CARD_FETCH_TIMEOUT_MS)
6654
- });
6655
- if (!response.ok) {
6656
- const detail = (await response.text().catch(() => "")).slice(0, 300);
6657
- throw new Error(`DingTalk Card OpenAPI ${method} ${path} failed${templateId ? ` for ${templateId}` : ""}: HTTP ${response.status}${detail ? ` ${detail}` : ""}`);
6790
+ for (let attempt = 0; ; attempt++) {
6791
+ const token = await this.options.getAccessToken();
6792
+ const response = await this.fetch(`${DINGTALK_API}${path}`, {
6793
+ method,
6794
+ headers: {
6795
+ "Content-Type": "application/json",
6796
+ "x-acs-dingtalk-access-token": token
6797
+ },
6798
+ body: JSON.stringify(body),
6799
+ signal: AbortSignal.timeout(CARD_FETCH_TIMEOUT_MS)
6800
+ });
6801
+ if (response.status === 401 && attempt === 0) {
6802
+ this.options.invalidateAccessToken(token);
6803
+ await response.body?.cancel();
6804
+ continue;
6805
+ }
6806
+ if (!response.ok) {
6807
+ const detail = (await response.text().catch(() => "")).slice(0, 300);
6808
+ throw new DingtalkCardRequestError(`DingTalk Card OpenAPI ${method} ${path} failed${templateId ? ` for ${templateId}` : ""}: HTTP ${response.status}${detail ? ` ${detail}` : ""}`, isRetryableStatus(response.status));
6809
+ }
6810
+ return response.json().catch(() => void 0);
6658
6811
  }
6659
- return response.json().catch(() => void 0);
6660
6812
  }
6661
6813
  };
6662
6814
 
@@ -6783,8 +6935,11 @@ init_esbuild_shims();
6783
6935
  import { randomUUID as randomUUID2 } from "node:crypto";
6784
6936
  var FLUSH_INTERVAL_MS = 500;
6785
6937
  var STATUS_REFRESH_INTERVAL_MS = 1e3;
6938
+ var CONTENT_SYNC_INTERVAL_SECONDS = 5;
6786
6939
  var BREAKER_PROBE_INTERVAL_MS = 3e4;
6787
6940
  var MAX_CONSECUTIVE_STATUS_FAILURES = 3;
6941
+ var INITIAL_RETRY_INTERVAL_MS = 1e3;
6942
+ var MAX_RETRY_INTERVAL_MS = 3e4;
6788
6943
  var CONTENT_LIMIT = 2e4;
6789
6944
  var TRUNCATION_MARKER = "[Earlier output truncated]\n";
6790
6945
  function boundContent(content) {
@@ -6802,10 +6957,13 @@ var StatusCardController = class {
6802
6957
  recordsByOutTrack = /* @__PURE__ */ new Map();
6803
6958
  segmentIdsByRun = /* @__PURE__ */ new Map();
6804
6959
  terminalSegmentIds = /* @__PURE__ */ new Set();
6960
+ disposed = false;
6805
6961
  constructor(options) {
6806
6962
  this.options = options;
6807
6963
  }
6808
6964
  ensure(segment, target) {
6965
+ if (this.disposed)
6966
+ return;
6809
6967
  if (this.terminalSegmentIds.has(segment.segmentId))
6810
6968
  return;
6811
6969
  if (!this.recordsBySegment.has(segment.segmentId)) {
@@ -6813,6 +6971,8 @@ var StatusCardController = class {
6813
6971
  }
6814
6972
  }
6815
6973
  replace(segment, target, content) {
6974
+ if (this.disposed)
6975
+ return;
6816
6976
  if (this.terminalSegmentIds.has(segment.segmentId))
6817
6977
  return;
6818
6978
  const record = this.recordsBySegment.get(segment.segmentId);
@@ -6823,22 +6983,27 @@ var StatusCardController = class {
6823
6983
  if (record.terminal)
6824
6984
  return;
6825
6985
  record.content = boundContent(content);
6986
+ record.contentVersion++;
6826
6987
  if (record.streamFailed)
6827
6988
  return;
6828
- record.pendingSnapshot = sanitizeStreamingImageMarkers(record.content);
6989
+ record.hasPendingWrite = true;
6829
6990
  this.scheduleFlush(record);
6830
6991
  }
6831
6992
  /**
6832
6993
  * Whether a created, still-running status card is displaying content for
6833
6994
  * this segment. Awaits the in-flight creation so a boundary decision made
6834
6995
  * while creation is pending does not race it. A latched stream failure
6835
- * means the card can never show further content, so it is not live.
6996
+ * means the card can never show further content, so it is not live. A
6997
+ * creation that is backing off for a retry is not awaited either (see
6998
+ * `awaitDelivery`).
6836
6999
  */
6837
7000
  async isCardLive(segmentId) {
7001
+ if (this.disposed)
7002
+ return false;
6838
7003
  const record = this.recordsBySegment.get(segmentId);
6839
7004
  if (!record || record.terminal || record.streamFailed)
6840
7005
  return false;
6841
- return record.ready;
7006
+ return this.awaitDelivery(record);
6842
7007
  }
6843
7008
  /**
6844
7009
  * Drain any pending snapshot so callers can treat the card's current
@@ -6847,23 +7012,64 @@ var StatusCardController = class {
6847
7012
  * caller can fall back instead of claiming delivery.
6848
7013
  */
6849
7014
  async flushPending(segmentId) {
7015
+ if (this.disposed)
7016
+ return false;
6850
7017
  const record = this.recordsBySegment.get(segmentId);
6851
7018
  if (!record || record.terminal)
6852
7019
  return false;
6853
- if (!await record.ready)
7020
+ if (!await this.awaitDelivery(record))
6854
7021
  return false;
6855
7022
  while (!record.terminal && !record.streamFailed) {
6856
7023
  if (record.flushTimer) {
6857
7024
  clearTimeout(record.flushTimer);
6858
7025
  record.flushTimer = void 0;
6859
7026
  }
7027
+ if (record.streamRetryTimer) {
7028
+ clearTimeout(record.streamRetryTimer);
7029
+ record.streamRetryTimer = void 0;
7030
+ }
7031
+ const failureVersion = record.streamFailureVersion;
6860
7032
  this.flush(record);
6861
7033
  await record.writeChain;
6862
- if (record.pendingSnapshot === void 0)
7034
+ if (record.streamFailureVersion !== failureVersion)
7035
+ return false;
7036
+ if (!record.hasPendingWrite)
6863
7037
  break;
6864
7038
  }
6865
7039
  return !record.terminal && !record.streamFailed;
6866
7040
  }
7041
+ abandon(segmentId) {
7042
+ const record = this.recordsBySegment.get(segmentId);
7043
+ if (!record || record.terminal)
7044
+ return;
7045
+ record.terminal = true;
7046
+ record.hasPendingWrite = false;
7047
+ void record.ready.then((ready) => {
7048
+ if (!ready)
7049
+ return;
7050
+ void this.options.client.updateInstance({
7051
+ outTrackId: record.outTrackId,
7052
+ cardParamMap: {
7053
+ flowStatus: 3,
7054
+ hasAction: "false",
7055
+ stop_action: "false"
7056
+ }
7057
+ }).catch(() => {
7058
+ });
7059
+ });
7060
+ this.removeRecord(record);
7061
+ }
7062
+ /**
7063
+ * Resolves once the card is known to be delivered (or not) without waiting
7064
+ * through a creation backoff: `creationAttempt` is the failed attempt until
7065
+ * the retry actually starts, so a boundary reached mid-backoff falls back
7066
+ * to text while the retry keeps running for later output.
7067
+ */
7068
+ async awaitDelivery(record) {
7069
+ if (!await record.creationAttempt)
7070
+ return false;
7071
+ return record.ready;
7072
+ }
6867
7073
  createRecord(segment, target, initialContent = "") {
6868
7074
  const outTrackId = `qwen-status-${randomUUID2()}`;
6869
7075
  const record = {
@@ -6876,13 +7082,21 @@ var StatusCardController = class {
6876
7082
  content: boundContent(initialContent),
6877
7083
  startedAt: Date.now(),
6878
7084
  lastStatusSecond: 0,
7085
+ lastContentSyncSecond: 0,
6879
7086
  ready: Promise.resolve(false),
7087
+ creationAttempt: Promise.resolve(false),
6880
7088
  terminal: false,
6881
7089
  streamFailed: false,
7090
+ streamFailureVersion: 0,
7091
+ createRetryAttempt: 0,
7092
+ streamRetryAttempt: 0,
7093
+ terminalRetryAttempt: 0,
6882
7094
  consecutiveStatusFailures: 0,
6883
7095
  stopClaimed: false,
6884
7096
  forbiddenActors: /* @__PURE__ */ new Set(),
6885
7097
  lastWriteAt: Date.now(),
7098
+ contentVersion: 0,
7099
+ hasPendingWrite: false,
6886
7100
  writeChain: Promise.resolve()
6887
7101
  };
6888
7102
  this.recordsBySegment.set(record.segmentId, record);
@@ -6904,6 +7118,8 @@ var StatusCardController = class {
6904
7118
  void this.finalize(segmentId, boundContent(error), "Failed", true);
6905
7119
  }
6906
7120
  cancelRun(runId, reason) {
7121
+ if (this.disposed)
7122
+ return;
6907
7123
  for (const segmentId of [...this.segmentIdsByRun.get(runId) ?? []]) {
6908
7124
  const record = this.recordsBySegment.get(segmentId);
6909
7125
  if (!record)
@@ -6912,6 +7128,8 @@ var StatusCardController = class {
6912
7128
  }
6913
7129
  }
6914
7130
  claimStop(outTrackId, actorId) {
7131
+ if (this.disposed)
7132
+ return { kind: "ignored", actorId };
6915
7133
  const record = this.recordsByOutTrack.get(outTrackId);
6916
7134
  if (!record || record.terminal || record.stopClaimed) {
6917
7135
  return { kind: "ignored", actorId };
@@ -6940,44 +7158,72 @@ var StatusCardController = class {
6940
7158
  };
6941
7159
  }
6942
7160
  async create(record, target) {
6943
- try {
6944
- const initialContent = sanitizeStreamingImageMarkers(record.content);
6945
- await this.options.client.createAndDeliver({
6946
- templateId: STATUS_CARD_TEMPLATE_ID,
6947
- outTrackId: record.outTrackId,
6948
- target,
6949
- cardParamMap: {
6950
- content: initialContent,
6951
- flowStatus: 2,
6952
- statusLine: this.statusLine(record, "Running").text,
6953
- hasAction: "true",
6954
- stop_action: "true"
6955
- }
7161
+ for (; ; ) {
7162
+ let settleAttempt;
7163
+ record.creationAttempt = new Promise((resolve) => {
7164
+ settleAttempt = resolve;
6956
7165
  });
7166
+ try {
7167
+ await this.options.client.createAndDeliver({
7168
+ templateId: STATUS_CARD_TEMPLATE_ID,
7169
+ outTrackId: record.outTrackId,
7170
+ target,
7171
+ cardParamMap: {
7172
+ content: sanitizeStreamingImageMarkers(record.content),
7173
+ flowStatus: 2,
7174
+ statusLine: this.statusLine(record, "Running").text,
7175
+ hasAction: "true",
7176
+ stop_action: "true"
7177
+ }
7178
+ });
7179
+ settleAttempt(true);
7180
+ break;
7181
+ } catch (error) {
7182
+ settleAttempt(false);
7183
+ this.options.onError?.("status card creation", error);
7184
+ if (this.disposed || record.terminal || !isRetryableDingtalkCardError(error)) {
7185
+ return false;
7186
+ }
7187
+ if (!await this.waitForCreationRetry(record))
7188
+ return false;
7189
+ }
7190
+ }
7191
+ if (this.disposed)
7192
+ return false;
7193
+ if (this.recordsBySegment.get(record.segmentId) !== record)
7194
+ return true;
7195
+ try {
6957
7196
  await this.options.client.openOrUpdateStream({
6958
7197
  outTrackId: record.outTrackId,
6959
7198
  key: "content",
6960
- content: initialContent,
7199
+ content: sanitizeStreamingImageMarkers(record.content),
6961
7200
  finalize: false
6962
7201
  });
6963
- return true;
6964
7202
  } catch (error) {
6965
- this.options.onError?.("status card creation", error);
6966
- await this.options.client.updateInstance({
6967
- outTrackId: record.outTrackId,
6968
- cardParamMap: {
6969
- flowStatus: 3,
6970
- statusLine: "Unavailable",
6971
- hasAction: "false",
6972
- stop_action: "false"
6973
- }
6974
- }).catch(() => {
6975
- });
6976
- return false;
7203
+ this.handleStreamFailure(record, error);
6977
7204
  }
7205
+ return true;
7206
+ }
7207
+ /**
7208
+ * Sleeps for the next creation backoff. Resolves false when finalization or
7209
+ * disposal abandons the creation so `ready` settles without waiting.
7210
+ */
7211
+ waitForCreationRetry(record) {
7212
+ const delay = this.retryDelay(record.createRetryAttempt++);
7213
+ return new Promise((resolve) => {
7214
+ const settle2 = /* @__PURE__ */ __name((resumed) => {
7215
+ if (record.createRetryTimer)
7216
+ clearTimeout(record.createRetryTimer);
7217
+ record.createRetryTimer = void 0;
7218
+ record.abandonCreation = void 0;
7219
+ resolve(resumed);
7220
+ }, "settle");
7221
+ record.abandonCreation = () => settle2(false);
7222
+ record.createRetryTimer = setTimeout(() => settle2(true), delay);
7223
+ });
6978
7224
  }
6979
7225
  scheduleFlush(record) {
6980
- if (record.flushTimer || record.inFlight || record.terminal)
7226
+ if (record.flushTimer || record.streamRetryTimer || record.inFlight || record.terminal)
6981
7227
  return;
6982
7228
  const delay = Math.max(0, FLUSH_INTERVAL_MS - (Date.now() - record.lastWriteAt));
6983
7229
  record.flushTimer = setTimeout(() => {
@@ -6986,42 +7232,44 @@ var StatusCardController = class {
6986
7232
  }, delay);
6987
7233
  }
6988
7234
  flush(record) {
6989
- if (record.terminal || record.inFlight || record.pendingSnapshot === void 0)
7235
+ if (this.disposed || record.terminal || record.streamFailed || record.inFlight || !record.hasPendingWrite)
6990
7236
  return;
6991
- const content = record.pendingSnapshot;
6992
- record.pendingSnapshot = void 0;
7237
+ record.hasPendingWrite = false;
7238
+ let sentVersion;
7239
+ let contentWritten = false;
6993
7240
  const write = record.writeChain.then(async () => {
6994
7241
  const ready = await record.ready;
6995
- if (!ready || record.terminal)
7242
+ if (!ready || record.terminal || record.streamFailed)
6996
7243
  return;
7244
+ sentVersion = record.contentVersion;
6997
7245
  await this.options.client.openOrUpdateStream({
6998
7246
  outTrackId: record.outTrackId,
6999
7247
  key: "content",
7000
- content,
7248
+ content: sanitizeStreamingImageMarkers(record.content),
7001
7249
  finalize: false
7002
7250
  });
7251
+ contentWritten = true;
7252
+ record.streamRetryAttempt = 0;
7003
7253
  await this.updateRunningStatus(record);
7004
- }).catch((error) => {
7005
- record.streamFailed = true;
7006
- record.pendingSnapshot = void 0;
7007
- if (record.statusTimer) {
7008
- clearTimeout(record.statusTimer);
7009
- record.statusTimer = void 0;
7010
- }
7011
- this.options.onError?.("status card streaming", error);
7012
- });
7254
+ }).catch((error) => this.handleStreamFailure(record, error));
7013
7255
  const tracked = write.finally(() => {
7014
7256
  if (record.inFlight === tracked) {
7015
7257
  record.inFlight = void 0;
7016
7258
  }
7017
7259
  record.lastWriteAt = Date.now();
7018
- if (record.pendingSnapshot !== void 0)
7260
+ if (contentWritten && record.contentVersion === sentVersion) {
7261
+ record.hasPendingWrite = false;
7262
+ }
7263
+ if (record.hasPendingWrite && record.contentVersion !== sentVersion) {
7019
7264
  this.scheduleFlush(record);
7265
+ }
7020
7266
  });
7021
7267
  record.inFlight = tracked;
7022
7268
  record.writeChain = tracked;
7023
7269
  }
7024
7270
  async finalize(segmentId, content, state, isError, retainedContent) {
7271
+ if (this.disposed)
7272
+ return false;
7025
7273
  const record = this.recordsBySegment.get(segmentId);
7026
7274
  if (!record || record.terminal)
7027
7275
  return false;
@@ -7036,58 +7284,165 @@ var StatusCardController = class {
7036
7284
  if (record.flushTimer)
7037
7285
  clearTimeout(record.flushTimer);
7038
7286
  record.flushTimer = void 0;
7287
+ if (record.streamRetryTimer)
7288
+ clearTimeout(record.streamRetryTimer);
7289
+ record.streamRetryTimer = void 0;
7039
7290
  if (record.statusTimer)
7040
7291
  clearTimeout(record.statusTimer);
7041
7292
  record.statusTimer = void 0;
7042
- record.pendingSnapshot = void 0;
7293
+ record.hasPendingWrite = false;
7294
+ record.abandonCreation?.();
7295
+ if (!await record.ready) {
7296
+ this.removeRecord(record);
7297
+ return false;
7298
+ }
7299
+ await record.writeChain;
7300
+ const retained = content || (retainedContent ? retainedContent(record.content) : record.content);
7301
+ record.terminalIntent = {
7302
+ content: boundContent(sanitizeStreamingImageMarkers(retained)),
7303
+ isError,
7304
+ statusLine: this.statusLine(record, state).text,
7305
+ streamFinalizeSettled: false
7306
+ };
7307
+ return this.attemptFinalization(record);
7308
+ }
7309
+ async attemptFinalization(record) {
7310
+ if (this.disposed)
7311
+ return false;
7312
+ if (this.recordsBySegment.get(record.segmentId) !== record)
7313
+ return false;
7314
+ const intent = record.terminalIntent;
7315
+ if (!intent)
7316
+ return false;
7317
+ if (!intent.streamFinalizeSettled) {
7318
+ try {
7319
+ await this.options.client.openOrUpdateStream({
7320
+ outTrackId: record.outTrackId,
7321
+ key: "content",
7322
+ content: "",
7323
+ finalize: true,
7324
+ isError: intent.isError
7325
+ });
7326
+ intent.streamFinalizeSettled = true;
7327
+ } catch (error) {
7328
+ if (!isRetryableDingtalkCardError(error)) {
7329
+ intent.streamFinalizeSettled = true;
7330
+ }
7331
+ this.options.onError?.("status card finalization", error);
7332
+ }
7333
+ }
7334
+ if (this.disposed)
7335
+ return false;
7043
7336
  try {
7044
- if (!await record.ready)
7045
- return false;
7046
- await record.writeChain;
7047
- const retained = content || (retainedContent ? retainedContent(record.content) : record.content);
7048
- const finalContent = boundContent(sanitizeStreamingImageMarkers(retained));
7049
- await this.options.client.openOrUpdateStream({
7050
- outTrackId: record.outTrackId,
7051
- key: "content",
7052
- content: "",
7053
- finalize: true,
7054
- isError
7055
- });
7056
7337
  await this.options.client.updateInstance({
7057
7338
  outTrackId: record.outTrackId,
7058
7339
  cardParamMap: {
7059
7340
  blockList: JSON.stringify([
7060
7341
  {
7061
7342
  type: 0,
7062
- markdown: finalContent
7343
+ markdown: intent.content
7063
7344
  }
7064
7345
  ]),
7065
- content: finalContent,
7066
- copy_content: finalContent,
7346
+ content: intent.content,
7347
+ copy_content: intent.content,
7067
7348
  flowStatus: 3,
7068
- statusLine: this.statusLine(record, state).text,
7349
+ statusLine: intent.statusLine,
7069
7350
  hasAction: "false",
7070
7351
  stop_action: "false"
7071
7352
  }
7072
7353
  });
7073
7354
  record.content = "";
7355
+ this.removeRecord(record);
7074
7356
  return true;
7075
7357
  } catch (error) {
7076
7358
  this.options.onError?.("status card finalization", error);
7077
- return false;
7078
- } finally {
7079
- if (this.recordsBySegment.get(segmentId) === record) {
7080
- this.recordsBySegment.delete(segmentId);
7081
- }
7082
- if (this.recordsByOutTrack.get(record.outTrackId) === record) {
7083
- this.recordsByOutTrack.delete(record.outTrackId);
7359
+ if (isRetryableDingtalkCardError(error)) {
7360
+ this.scheduleTerminalRetry(record);
7361
+ return true;
7362
+ } else {
7363
+ this.removeRecord(record);
7084
7364
  }
7085
- const segmentIds = this.segmentIdsByRun.get(record.runId);
7086
- segmentIds?.delete(segmentId);
7087
- if (segmentIds?.size === 0) {
7088
- this.segmentIdsByRun.delete(record.runId);
7365
+ return false;
7366
+ }
7367
+ }
7368
+ scheduleStreamRetry(record) {
7369
+ if (this.disposed || record.terminal || record.streamFailed || record.streamRetryTimer) {
7370
+ return;
7371
+ }
7372
+ const delay = this.retryDelay(record.streamRetryAttempt++);
7373
+ record.streamRetryTimer = setTimeout(() => {
7374
+ record.streamRetryTimer = void 0;
7375
+ if (this.disposed || record.terminal || record.streamFailed)
7376
+ return;
7377
+ this.flush(record);
7378
+ }, delay);
7379
+ }
7380
+ scheduleTerminalRetry(record) {
7381
+ if (this.disposed || !record.terminalIntent || record.terminalRetryTimer) {
7382
+ return;
7383
+ }
7384
+ const delay = this.retryDelay(record.terminalRetryAttempt++);
7385
+ record.terminalRetryTimer = setTimeout(() => {
7386
+ record.terminalRetryTimer = void 0;
7387
+ if (this.disposed)
7388
+ return;
7389
+ void this.attemptFinalization(record);
7390
+ }, delay);
7391
+ }
7392
+ handleStreamFailure(record, error) {
7393
+ record.streamFailureVersion++;
7394
+ if (!this.disposed && !record.terminal && isRetryableDingtalkCardError(error)) {
7395
+ record.hasPendingWrite = true;
7396
+ this.scheduleStreamRetry(record);
7397
+ } else if (!record.terminal) {
7398
+ record.streamFailed = true;
7399
+ record.hasPendingWrite = false;
7400
+ if (record.statusTimer) {
7401
+ clearTimeout(record.statusTimer);
7402
+ record.statusTimer = void 0;
7089
7403
  }
7090
7404
  }
7405
+ this.options.onError?.("status card streaming", error);
7406
+ }
7407
+ retryDelay(attempt) {
7408
+ return Math.min(INITIAL_RETRY_INTERVAL_MS * 2 ** Math.min(attempt, 10), MAX_RETRY_INTERVAL_MS);
7409
+ }
7410
+ removeRecord(record) {
7411
+ record.abandonCreation?.();
7412
+ if (record.flushTimer)
7413
+ clearTimeout(record.flushTimer);
7414
+ if (record.streamRetryTimer)
7415
+ clearTimeout(record.streamRetryTimer);
7416
+ if (record.terminalRetryTimer)
7417
+ clearTimeout(record.terminalRetryTimer);
7418
+ if (record.statusTimer)
7419
+ clearTimeout(record.statusTimer);
7420
+ record.flushTimer = void 0;
7421
+ record.streamRetryTimer = void 0;
7422
+ record.terminalRetryTimer = void 0;
7423
+ record.statusTimer = void 0;
7424
+ if (this.recordsBySegment.get(record.segmentId) === record) {
7425
+ this.recordsBySegment.delete(record.segmentId);
7426
+ }
7427
+ if (this.recordsByOutTrack.get(record.outTrackId) === record) {
7428
+ this.recordsByOutTrack.delete(record.outTrackId);
7429
+ }
7430
+ const segmentIds = this.segmentIdsByRun.get(record.runId);
7431
+ segmentIds?.delete(record.segmentId);
7432
+ if (segmentIds?.size === 0) {
7433
+ this.segmentIdsByRun.delete(record.runId);
7434
+ }
7435
+ }
7436
+ dispose() {
7437
+ if (this.disposed)
7438
+ return;
7439
+ this.disposed = true;
7440
+ for (const record of [...this.recordsBySegment.values()]) {
7441
+ record.terminal = true;
7442
+ record.hasPendingWrite = false;
7443
+ this.removeRecord(record);
7444
+ }
7445
+ this.terminalSegmentIds.clear();
7091
7446
  }
7092
7447
  statusLine(record, state) {
7093
7448
  const second = Math.max(0, Math.floor((Date.now() - record.startedAt) / 1e3));
@@ -7098,17 +7453,23 @@ var StatusCardController = class {
7098
7453
  };
7099
7454
  }
7100
7455
  async updateRunningStatus(record) {
7101
- if (record.terminal || record.streamFailed)
7456
+ if (this.disposed || record.terminal || record.streamFailed)
7102
7457
  return;
7103
7458
  const status = this.statusLine(record, "Running");
7104
7459
  if (status.second === record.lastStatusSecond)
7105
7460
  return;
7461
+ const syncContent = status.second - record.lastContentSyncSecond >= CONTENT_SYNC_INTERVAL_SECONDS;
7106
7462
  try {
7107
7463
  await this.options.client.updateInstance({
7108
7464
  outTrackId: record.outTrackId,
7109
- cardParamMap: { statusLine: status.text }
7465
+ cardParamMap: {
7466
+ ...syncContent ? { content: sanitizeStreamingImageMarkers(record.content) } : {},
7467
+ statusLine: status.text
7468
+ }
7110
7469
  });
7111
7470
  record.lastStatusSecond = status.second;
7471
+ if (syncContent)
7472
+ record.lastContentSyncSecond = status.second;
7112
7473
  record.consecutiveStatusFailures = 0;
7113
7474
  if (record.statusTimer) {
7114
7475
  clearTimeout(record.statusTimer);
@@ -7121,13 +7482,13 @@ var StatusCardController = class {
7121
7482
  }
7122
7483
  }
7123
7484
  scheduleStatusRefresh(record, intervalMs = STATUS_REFRESH_INTERVAL_MS) {
7124
- if (record.terminal || record.streamFailed || record.statusTimer)
7485
+ if (this.disposed || record.terminal || record.streamFailed || record.statusTimer)
7125
7486
  return;
7126
7487
  const elapsed = Math.max(0, Date.now() - record.startedAt);
7127
7488
  const delay = Math.max(50, intervalMs - elapsed % intervalMs);
7128
7489
  record.statusTimer = setTimeout(() => {
7129
7490
  record.statusTimer = void 0;
7130
- if (record.terminal || record.streamFailed)
7491
+ if (this.disposed || record.terminal || record.streamFailed)
7131
7492
  return;
7132
7493
  const refresh = record.writeChain.then(() => this.updateRunningStatus(record));
7133
7494
  record.writeChain = refresh;
@@ -7208,7 +7569,7 @@ var QuestionCardController = class {
7208
7569
  }
7209
7570
  await this.finalize(record, "cancelled");
7210
7571
  try {
7211
- await this.options.sendFallback(context.target.chatId, this.fallbackText(context));
7572
+ await this.options.sendFallback(context.target.chatId, this.fallbackText(context), ...context.sourceLabel ? [context.sourceLabel] : []);
7212
7573
  } catch (fallbackError) {
7213
7574
  this.options.onError?.("question fallback delivery", fallbackError);
7214
7575
  }
@@ -7350,22 +7711,22 @@ var QuestionCardController = class {
7350
7711
  const cardParamMap = {
7351
7712
  submitted: {
7352
7713
  card_status: "submitted",
7353
- question_desc: "Submitted.",
7714
+ question_desc: this.withSourceLabel(record.context, "Submitted."),
7354
7715
  form_btn_text: "Submitted"
7355
7716
  },
7356
7717
  expired: {
7357
7718
  card_status: "expired",
7358
- question_desc: "This question expired. Please retry.",
7719
+ question_desc: this.withSourceLabel(record.context, "This question expired. Please retry."),
7359
7720
  form_btn_text: "Expired"
7360
7721
  },
7361
7722
  resolved_outside_presenter: {
7362
7723
  card_status: "expired",
7363
- question_desc: "Resolved outside this card.",
7724
+ question_desc: this.withSourceLabel(record.context, "Resolved outside this card."),
7364
7725
  form_btn_text: "Expired"
7365
7726
  },
7366
7727
  cancelled: {
7367
7728
  card_status: "cancelled",
7368
- question_desc: "Cancelled.",
7729
+ question_desc: this.withSourceLabel(record.context, "Cancelled."),
7369
7730
  form_btn_text: "Cancelled"
7370
7731
  }
7371
7732
  };
@@ -7374,7 +7735,9 @@ var QuestionCardController = class {
7374
7735
  outTrackId: record.outTrackId,
7375
7736
  cardParamMap: {
7376
7737
  ...cardParamMap[record.terminalState],
7377
- ...record.terminalDescription ? { question_desc: record.terminalDescription } : {}
7738
+ ...record.terminalDescription ? {
7739
+ question_desc: this.withSourceLabel(record.context, record.terminalDescription)
7740
+ } : {}
7378
7741
  }
7379
7742
  });
7380
7743
  } catch (error) {
@@ -7434,7 +7797,7 @@ var QuestionCardController = class {
7434
7797
  return {
7435
7798
  question_id: context.requestId,
7436
7799
  question_title: first.header,
7437
- question_desc: first.question,
7800
+ question_desc: this.withSourceLabel(context, first.question),
7438
7801
  card_status: "pending",
7439
7802
  form_btn_text: "Submit",
7440
7803
  selected_text: "",
@@ -7470,19 +7833,27 @@ var QuestionCardController = class {
7470
7833
  return `The interactive question could not be delivered, so this request was cancelled. Please retry.
7471
7834
  ${questions}`;
7472
7835
  }
7836
+ withSourceLabel(context, text) {
7837
+ if (!context.sourceLabel)
7838
+ return text;
7839
+ const label = escapeDingTalkMarkdown(context.sourceLabel);
7840
+ return `${label}
7841
+
7842
+ ${text}`;
7843
+ }
7473
7844
  };
7474
7845
 
7475
7846
  // packages/channels/dingtalk/dist/interaction-presenter.js
7476
7847
  init_esbuild_shims();
7477
7848
  import { randomUUID as randomUUID4 } from "node:crypto";
7478
- function escapeMarkdownText(text) {
7849
+ function escapeSenderMarkdownText(text) {
7479
7850
  return text.replace(/([\\`*_[\]{}()#+.!|>~-])/gu, "\\$1");
7480
7851
  }
7481
- __name(escapeMarkdownText, "escapeMarkdownText");
7852
+ __name(escapeSenderMarkdownText, "escapeSenderMarkdownText");
7482
7853
  function formatSenderPrefixes(sender) {
7483
7854
  const senderName = sanitizeSenderName(sender.senderName);
7484
7855
  return {
7485
- senderPrefix: `@${escapeMarkdownText(senderName)}`,
7856
+ senderPrefix: `@${escapeSenderMarkdownText(senderName)}`,
7486
7857
  senderRawPrefix: `@${senderName}`
7487
7858
  };
7488
7859
  }
@@ -7498,7 +7869,7 @@ var DingtalkInteractionPresenter = class {
7498
7869
  constructor(options) {
7499
7870
  this.options = options;
7500
7871
  }
7501
- registerRun(runId, ownerId, target, sessionId = "", sender) {
7872
+ registerRun(runId, ownerId, target, sessionId = "", sender, sourceLabel) {
7502
7873
  this.runs.set(runId, {
7503
7874
  runId,
7504
7875
  ownerId,
@@ -7514,10 +7885,12 @@ var DingtalkInteractionPresenter = class {
7514
7885
  chatId: target.chatId,
7515
7886
  senderId: ownerId,
7516
7887
  isGroup: target.isGroup
7517
- }
7888
+ },
7889
+ sourceLabel
7518
7890
  },
7519
7891
  projectionChain: Promise.resolve(),
7520
7892
  ...target.isGroup && sender ? formatSenderPrefixes(sender) : {},
7893
+ ...sourceLabel ? { sourceLabel } : {},
7521
7894
  terminal: false
7522
7895
  });
7523
7896
  }
@@ -7529,7 +7902,7 @@ var DingtalkInteractionPresenter = class {
7529
7902
  void this.enqueue(run, () => {
7530
7903
  const statusCards = this.options.statusCards;
7531
7904
  const target = this.cardTarget(statusContext.target);
7532
- statusCards?.ensure(statusContext, target);
7905
+ statusCards?.replace(statusContext, target, this.withSourcePrefix(run, ""));
7533
7906
  });
7534
7907
  }
7535
7908
  appendOutput(segment, chunk) {
@@ -7550,7 +7923,7 @@ var DingtalkInteractionPresenter = class {
7550
7923
  run.activeSegmentId = segment.segmentId;
7551
7924
  const statusContext = this.ensureStatusContext(run, segment);
7552
7925
  void this.enqueue(run, () => {
7553
- this.options.statusCards?.replace(statusContext, this.cardTarget(statusContext.target), presentation.content);
7926
+ this.options.statusCards?.replace(statusContext, this.cardTarget(statusContext.target), this.withSourcePrefix(run, presentation.content));
7554
7927
  });
7555
7928
  }
7556
7929
  closeOutput(segmentId, text, reason, segment) {
@@ -7594,7 +7967,8 @@ var DingtalkInteractionPresenter = class {
7594
7967
  const fallbackText2 = stripPartialImageMarker(text || presentation.content);
7595
7968
  if (!fallbackText2 || !this.options.sendFallback)
7596
7969
  return false;
7597
- await this.options.sendFallback(presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
7970
+ await this.sendFallback(run, presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
7971
+ statusCards?.abandon(statusContext.segmentId);
7598
7972
  return true;
7599
7973
  }
7600
7974
  if (reason === "input_requested") {
@@ -7605,7 +7979,8 @@ var DingtalkInteractionPresenter = class {
7605
7979
  const fallbackText2 = stripPartialImageMarker(text || presentation.content);
7606
7980
  if (!fallbackText2 || !this.options.sendFallback)
7607
7981
  return false;
7608
- await this.options.sendFallback(presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
7982
+ await this.sendFallback(run, presentation.context.target.chatId, fallbackText2, presentation.context.sessionId);
7983
+ statusCards?.abandon(statusContext.segmentId);
7609
7984
  return true;
7610
7985
  }
7611
7986
  statusCards?.ensure(statusContext, this.cardTarget(statusContext.target));
@@ -7615,7 +7990,8 @@ var DingtalkInteractionPresenter = class {
7615
7990
  const fallbackText = stripPartialImageMarker(text || presentation.content);
7616
7991
  if (!fallbackText || !this.options.sendFallback)
7617
7992
  return false;
7618
- await this.options.sendFallback(presentation.context.target.chatId, fallbackText, presentation.context.sessionId);
7993
+ await this.sendFallback(run, presentation.context.target.chatId, fallbackText, presentation.context.sessionId);
7994
+ statusCards?.abandon(statusContext.segmentId);
7619
7995
  return true;
7620
7996
  });
7621
7997
  }
@@ -7657,7 +8033,7 @@ var DingtalkInteractionPresenter = class {
7657
8033
  } else {
7658
8034
  const statusContext = run.statusContext;
7659
8035
  if (statusContext) {
7660
- await this.options.statusCards?.complete(statusContext.segmentId, "", (retained) => retained ? this.withSenderPrefix(run, retained) : retained);
8036
+ await this.options.statusCards?.complete(statusContext.segmentId, "", (retained) => retained ? this.withSenderPrefix(run, this.withoutRenderedSourcePrefix(run, retained)) : retained);
7661
8037
  }
7662
8038
  }
7663
8039
  });
@@ -7700,7 +8076,7 @@ var DingtalkInteractionPresenter = class {
7700
8076
  if (!delivered || !this.options.sendFallback)
7701
8077
  return;
7702
8078
  run.cardDelivered = void 0;
7703
- await this.options.sendFallback(delivered.chatId, delivered.text, delivered.sessionId);
8079
+ await this.sendFallback(run, delivered.chatId, delivered.text, delivered.sessionId);
7704
8080
  }
7705
8081
  enqueue(run, operation) {
7706
8082
  const result = run.projectionChain.then(operation);
@@ -7717,14 +8093,38 @@ var DingtalkInteractionPresenter = class {
7717
8093
  return `${TRUNCATION_MARKER}${content.slice(content.length - (limit - TRUNCATION_MARKER.length))}`;
7718
8094
  }
7719
8095
  withSenderPrefix(run, content) {
7720
- if (!run.senderPrefix)
8096
+ const prefixes = [
8097
+ run.senderPrefix,
8098
+ run.sourceLabel ? escapeDingTalkMarkdown(run.sourceLabel) : void 0
8099
+ ].filter((value) => Boolean(value));
8100
+ if (prefixes.length === 0)
7721
8101
  return this.boundContent(content);
7722
8102
  const body = this.withoutExistingSenderPrefix(run, content);
8103
+ const prefix = prefixes.join("\n\n");
7723
8104
  if (!body)
7724
- return run.senderPrefix;
8105
+ return prefix;
7725
8106
  const separator = "\n\n";
7726
- const bodyLimit = Math.max(0, CONTENT_LIMIT - run.senderPrefix.length - separator.length);
7727
- return `${run.senderPrefix}${separator}${this.boundContent(body, bodyLimit)}`;
8107
+ const bodyLimit = Math.max(0, CONTENT_LIMIT - prefix.length - separator.length);
8108
+ return `${prefix}${separator}${this.boundContent(body, bodyLimit)}`;
8109
+ }
8110
+ withSourcePrefix(run, content) {
8111
+ if (!run.sourceLabel)
8112
+ return this.boundContent(content);
8113
+ const sourceLabel = escapeDingTalkMarkdown(run.sourceLabel);
8114
+ if (!content)
8115
+ return sourceLabel;
8116
+ return `${sourceLabel}
8117
+
8118
+ ${this.boundContent(content, Math.max(0, CONTENT_LIMIT - sourceLabel.length - 2))}`;
8119
+ }
8120
+ async sendFallback(run, chatId, text, sessionId) {
8121
+ if (!this.options.sendFallback)
8122
+ return;
8123
+ if (run.sourceLabel) {
8124
+ await this.options.sendFallback(chatId, text, sessionId, run.sourceLabel);
8125
+ return;
8126
+ }
8127
+ await this.options.sendFallback(chatId, text, sessionId);
7728
8128
  }
7729
8129
  withoutExistingSenderPrefix(run, content) {
7730
8130
  const prefixes = /* @__PURE__ */ new Set([run.senderPrefix, run.senderRawPrefix]);
@@ -7750,6 +8150,17 @@ var DingtalkInteractionPresenter = class {
7750
8150
  }
7751
8151
  return body;
7752
8152
  }
8153
+ withoutRenderedSourcePrefix(run, content) {
8154
+ if (!run.sourceLabel)
8155
+ return content;
8156
+ const rendered = escapeDingTalkMarkdown(run.sourceLabel);
8157
+ if (content === rendered)
8158
+ return "";
8159
+ const prefix = `${rendered}
8160
+
8161
+ `;
8162
+ return content.startsWith(prefix) ? content.slice(prefix.length) : content;
8163
+ }
7753
8164
  ensureStatusContext(run, segment) {
7754
8165
  if (run.statusContext)
7755
8166
  return run.statusContext;
@@ -7980,9 +8391,102 @@ var EMOTION_RETRY_BASE_DELAY_MS = 250;
7980
8391
  var GROUP_MSG_API = "https://api.dingtalk.com/v1.0/robot/groupMessages/send";
7981
8392
  var DIRECT_MSG_API = "https://api.dingtalk.com/v1.0/robot/oToMessages/batchSend";
7982
8393
  var PROACTIVE_MSG_KEY = "sampleMarkdown";
8394
+ var PROACTIVE_FILE_MSG_KEY = "sampleFile";
7983
8395
  var TOKEN_API = "https://oapi.dingtalk.com/gettoken";
7984
8396
  var PROACTIVE_FETCH_TIMEOUT_MS = 15e3;
8397
+ var ROBOT_MESSAGE_HOSTS = /* @__PURE__ */ new Set(["api.dingtalk.com", "oapi.dingtalk.com"]);
8398
+ var PERMANENT_TOKEN_ERROR_CODES = /* @__PURE__ */ new Set([
8399
+ 40001,
8400
+ 40013,
8401
+ 40089,
8402
+ 40096,
8403
+ 90002,
8404
+ 90003
8405
+ ]);
7985
8406
  var REPLY_FETCH_TIMEOUT_MS = 15e3;
8407
+ function presentInboundError(error) {
8408
+ const parts = [];
8409
+ let status;
8410
+ try {
8411
+ if (error instanceof Error) {
8412
+ if (typeof error.name === "string")
8413
+ parts.push(error.name);
8414
+ if (typeof error.message === "string")
8415
+ parts.push(error.message);
8416
+ } else if (typeof error === "string") {
8417
+ parts.push(error);
8418
+ }
8419
+ if (typeof error === "object" && error !== null) {
8420
+ const record = error;
8421
+ if (typeof record["code"] === "string")
8422
+ parts.push(record["code"]);
8423
+ if (typeof record["status"] === "number")
8424
+ status = record["status"];
8425
+ const body = record["body"];
8426
+ if (typeof body === "string") {
8427
+ parts.push(body);
8428
+ } else if (typeof body === "object" && body !== null) {
8429
+ const bodyRecord = body;
8430
+ for (const key of ["code", "errorKind", "message"]) {
8431
+ if (typeof bodyRecord[key] === "string")
8432
+ parts.push(bodyRecord[key]);
8433
+ }
8434
+ }
8435
+ }
8436
+ } catch {
8437
+ return {
8438
+ status: "Processing failed",
8439
+ nextStep: "Try again. If it keeps failing, contact the bot administrator."
8440
+ };
8441
+ }
8442
+ const diagnostic = parts.join(" ").slice(0, 2e3).toLowerCase();
8443
+ if (status === 401 || status === 403 || /unauthor|forbidden|authentication|credential|invalid.?token/.test(diagnostic)) {
8444
+ return {
8445
+ status: "Bot configuration error",
8446
+ nextStep: "Contact the bot administrator."
8447
+ };
8448
+ }
8449
+ if (status === 408 || status === 504 || /timeout|timed?\s+out|deadline/.test(diagnostic)) {
8450
+ return {
8451
+ status: "Request timed out",
8452
+ nextStep: "Try again. For a large request, split it into smaller parts."
8453
+ };
8454
+ }
8455
+ if (/cancel|abort/.test(diagnostic)) {
8456
+ return {
8457
+ status: "Request was cancelled",
8458
+ nextStep: "Send the request again if you still need it."
8459
+ };
8460
+ }
8461
+ if (status === 429 || /overload|rate.?limit|queue.?full|too many|busy|pending prompts full/.test(diagnostic)) {
8462
+ return {
8463
+ status: "Service is busy",
8464
+ nextStep: "Try again in a moment."
8465
+ };
8466
+ }
8467
+ if (status === 502 || status === 503 || /unavailable|econn|enotfound|etimedout|network|socket|fetch failed|connection|session[_ ](?:not[ _]found|closing)|workspace[_ ]draining|transport closed/.test(diagnostic)) {
8468
+ return {
8469
+ status: "Service is temporarily unavailable",
8470
+ nextStep: "Try again in a moment. If it keeps failing, contact the bot administrator."
8471
+ };
8472
+ }
8473
+ return {
8474
+ status: "Processing failed",
8475
+ nextStep: "Try again. If it keeps failing, contact the bot administrator."
8476
+ };
8477
+ }
8478
+ __name(presentInboundError, "presentInboundError");
8479
+ function formatInboundErrorMessage(error, reference) {
8480
+ const presentation = presentInboundError(error);
8481
+ return [
8482
+ "**Unable to process this message**",
8483
+ "",
8484
+ `**Status:** ${presentation.status}`,
8485
+ `**Next step:** ${presentation.nextStep}`,
8486
+ `**Reference:** \`${reference}\``
8487
+ ].join("\n");
8488
+ }
8489
+ __name(formatInboundErrorMessage, "formatInboundErrorMessage");
7986
8490
  var GENERATED_MEDIA_EXT = {
7987
8491
  "image/jpeg": "jpg",
7988
8492
  "image/png": "png",
@@ -8002,6 +8506,15 @@ var IMAGE_INSTRUCTIONS = [
8002
8506
  "",
8003
8507
  "Only use a real image file inside the workspace or system temporary directory."
8004
8508
  ].join("\n");
8509
+ var FILE_INSTRUCTIONS = [
8510
+ "",
8511
+ "When the user explicitly asks for a completed local file, send it by writing this on its own line:",
8512
+ "`[FILE: /absolute/path/to/file]` (without the backticks)",
8513
+ "",
8514
+ "Use at most five non-empty files inside the workspace or system temporary directory.",
8515
+ "File paths containing ] are not supported.",
8516
+ "Do not claim delivery succeeded; DingTalk shows successful files separately and reports failures in the final text."
8517
+ ].join("\n");
8005
8518
  function collectNonBotMentionIds(data) {
8006
8519
  if (!Array.isArray(data.atUsers) || typeof data.chatbotUserId !== "string") {
8007
8520
  return [];
@@ -8083,6 +8596,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8083
8596
  } else if (!this.config.instructions.includes("[IMAGE:")) {
8084
8597
  this.config.instructions += IMAGE_INSTRUCTIONS;
8085
8598
  }
8599
+ if (config.blockStreaming !== "on" && !this.config.instructions.includes("[FILE:")) {
8600
+ this.config.instructions += FILE_INSTRUCTIONS;
8601
+ }
8086
8602
  this.interactiveCardConfig = parseDingtalkInteractiveCardConfig(config.interactiveCards);
8087
8603
  if (!config.clientId || !config.clientSecret) {
8088
8604
  throw new Error(`Channel "${name}" requires clientId and clientSecret for DingTalk.`);
@@ -8096,7 +8612,12 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8096
8612
  if (this.interactiveCardConfig.enabled) {
8097
8613
  this.interactiveCardClient = new DingtalkInteractiveCardClient({
8098
8614
  robotCode: config.clientId,
8099
- getAccessToken: /* @__PURE__ */ __name(() => this.getProactiveToken(), "getAccessToken")
8615
+ getAccessToken: /* @__PURE__ */ __name(() => this.getProactiveToken(), "getAccessToken"),
8616
+ invalidateAccessToken: /* @__PURE__ */ __name((token) => {
8617
+ if (this.proactiveToken?.token === token) {
8618
+ this.proactiveToken = void 0;
8619
+ }
8620
+ }, "invalidateAccessToken")
8100
8621
  });
8101
8622
  if (this.interactiveCardConfig.statusCard.enabled && config.blockStreaming !== "on") {
8102
8623
  this.statusCardController = new StatusCardController({
@@ -8113,7 +8634,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8113
8634
  this.questionCardController = new QuestionCardController({
8114
8635
  client: this.interactiveCardClient,
8115
8636
  timeoutMs: this.interactiveCardConfig.questionCard.timeoutMs,
8116
- sendFallback: /* @__PURE__ */ __name((chatId, text) => this.sendMessage(chatId, text), "sendFallback"),
8637
+ sendFallback: /* @__PURE__ */ __name((chatId, text, sourceLabel) => this.sendReply(chatId, text, void 0, sourceLabel), "sendFallback"),
8117
8638
  reserveRunProjection: /* @__PURE__ */ __name((runId) => this.interactionPresenter?.reserveProjection(runId), "reserveRunProjection"),
8118
8639
  onError: /* @__PURE__ */ __name((operation, error) => {
8119
8640
  process.stderr.write(`[DingTalk:${this.name}] ${operation} failed: ${sanitizeLogText(String(error), 300)}
@@ -8126,7 +8647,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8126
8647
  statusCards: this.statusCardController,
8127
8648
  questionCards: this.questionCardController,
8128
8649
  ...config.blockStreaming !== "on" ? {
8129
- sendFallback: /* @__PURE__ */ __name((chatId, text, sessionId) => this.sendFallbackReply(chatId, text, sessionId), "sendFallback")
8650
+ sendFallback: /* @__PURE__ */ __name((chatId, text, sessionId, sourceLabel) => this.sendFallbackReply(chatId, text, sessionId, sourceLabel), "sendFallback")
8130
8651
  } : {}
8131
8652
  });
8132
8653
  }
@@ -8315,24 +8836,135 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8315
8836
  static isUnroutableGroupMessage(isGroup, conversationId) {
8316
8837
  return isGroup && !conversationId;
8317
8838
  }
8318
- projectOutgoingFileText(text, streamed) {
8839
+ resolveSessionWebhook(chatId) {
8840
+ const value = this.webhooks.get(chatId);
8841
+ if (!value)
8842
+ return void 0;
8843
+ try {
8844
+ const url2 = new URL(value);
8845
+ return url2.protocol === "https:" && url2.port === "" && ROBOT_MESSAGE_HOSTS.has(url2.hostname) ? url2.toString() : void 0;
8846
+ } catch {
8847
+ return void 0;
8848
+ }
8849
+ }
8850
+ async uploadOutboundFile(filePath) {
8851
+ const file = readValidatedFile(filePath, this.config.cwd);
8852
+ for (let attempt = 0; attempt < 2; attempt++) {
8853
+ const token = await this.getProactiveToken();
8854
+ try {
8855
+ return { file, mediaId: await uploadDingTalkFile(file, token) };
8856
+ } catch (error) {
8857
+ if (error instanceof DingTalkMediaUploadError && error.authFailure && attempt === 0) {
8858
+ this.proactiveToken = void 0;
8859
+ continue;
8860
+ }
8861
+ throw error;
8862
+ }
8863
+ }
8864
+ throw new Error("DingTalk file upload returned no MediaID");
8865
+ }
8866
+ async deliverFiles(paths, send, preflight) {
8867
+ const notices = [];
8868
+ for (const filePath of paths) {
8869
+ const displayName = safeFileName(filePath);
8870
+ try {
8871
+ preflight?.();
8872
+ const { file, mediaId } = await this.uploadOutboundFile(filePath);
8873
+ await send(file, mediaId);
8874
+ } catch (error) {
8875
+ process.stderr.write(`[DingTalk:${this.name}] outbound file delivery failed (${sanitizeLogText(displayName, 200)}): ${sanitizeLogText(error instanceof Error ? error.message : String(error), 300)}
8876
+ `);
8877
+ notices.push(`[File delivery failed: ${displayName}]`);
8878
+ }
8879
+ }
8880
+ return notices;
8881
+ }
8882
+ async sendSessionFile(chatId, file, mediaId) {
8883
+ const webhook = this.resolveSessionWebhook(chatId);
8884
+ if (!webhook)
8885
+ throw new Error("DingTalk session webhook unavailable");
8886
+ let response;
8887
+ try {
8888
+ response = await fetch(webhook, {
8889
+ method: "POST",
8890
+ redirect: "error",
8891
+ headers: { "Content-Type": "application/json" },
8892
+ body: JSON.stringify({
8893
+ msgtype: "file",
8894
+ file: {
8895
+ mediaId,
8896
+ fileName: file.fileName,
8897
+ fileType: file.fileType
8898
+ }
8899
+ }),
8900
+ signal: AbortSignal.timeout(REPLY_FETCH_TIMEOUT_MS)
8901
+ });
8902
+ } catch {
8903
+ throw new Error("DingTalk file delivery failed: network request failed");
8904
+ }
8905
+ const body = await response.text().catch(() => "");
8906
+ if (!response.ok) {
8907
+ throw new Error(`DingTalk file delivery failed: HTTP ${response.status}`);
8908
+ }
8909
+ if (!body.trim())
8910
+ return;
8911
+ let data;
8912
+ try {
8913
+ const parsed = JSON.parse(body);
8914
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
8915
+ return;
8916
+ data = parsed;
8917
+ } catch {
8918
+ return;
8919
+ }
8920
+ const code = data["errcode"] ?? data["code"];
8921
+ if (code !== void 0 && String(code) !== "0") {
8922
+ throw new Error(`DingTalk file delivery failed: API code ${code}`);
8923
+ }
8924
+ }
8925
+ appendFileNotices(text, notices) {
8926
+ if (notices.length === 0)
8927
+ return text;
8928
+ const prefix = text.trimEnd();
8929
+ return `${prefix}${prefix ? "\n" : ""}${notices.join("\n")}`;
8930
+ }
8931
+ async prepareReplyOutput(chatId, text, streamed) {
8932
+ return this.prepareFileOutput(text, (file, mediaId) => this.sendSessionFile(chatId, file, mediaId), streamed, () => {
8933
+ if (!this.resolveSessionWebhook(chatId)) {
8934
+ throw new Error("DingTalk session webhook unavailable");
8935
+ }
8936
+ });
8937
+ }
8938
+ async prepareFileOutput(text, send, streamed, preflight) {
8319
8939
  const projection = projectFileText(text);
8320
8940
  const streamedMarkers = streamed ? streamed.result("").markerCount : 0;
8321
- if (projection.markerCount === 0 && streamedMarkers === 0) {
8322
- return projection.text;
8323
- }
8324
- process.stderr.write(`[DingTalk:${this.name}] file markers redacted (final=${projection.markerCount}, streamed=${streamedMarkers})
8941
+ if (projection.markerCount > 0 || streamedMarkers > 0) {
8942
+ process.stderr.write(`[DingTalk:${this.name}] file markers projected (final=${projection.markerCount}, streamed=${streamedMarkers})
8325
8943
  `);
8326
- return withFileUnavailableNotice(projection.text);
8944
+ }
8945
+ if (this.config.blockStreaming === "on" && (projection.markerCount > 0 || streamedMarkers > 0)) {
8946
+ return this.prepareOutgoingText(withFileUnavailableNotice(projection.text));
8947
+ }
8948
+ const notices = [];
8949
+ if (projection.invalidMarkers > 0) {
8950
+ notices.push("[File delivery failed: invalid marker]");
8951
+ }
8952
+ if (projection.excessMarkers > 0) {
8953
+ notices.push("[File delivery failed: response file limit exceeded]");
8954
+ }
8955
+ if (streamedMarkers > projection.markerCount) {
8956
+ notices.push(FILE_UNAVAILABLE_NOTICE);
8957
+ }
8958
+ notices.push(...await this.deliverFiles(projection.paths, send, preflight));
8959
+ return this.prepareOutgoingText(this.appendFileNotices(projection.text, notices));
8327
8960
  }
8328
- async prepareOutgoingText(text, streamed) {
8329
- const fileSafeText = this.projectOutgoingFileText(text, streamed);
8330
- const markers = findImageMarkers(fileSafeText);
8961
+ async prepareOutgoingText(text) {
8962
+ const markers = findImageMarkers(text);
8331
8963
  if (markers.length === 0)
8332
- return fileSafeText;
8964
+ return text;
8333
8965
  const replacements = [];
8334
8966
  for (const marker of markers) {
8335
- const fileName = basename2(marker.path).replace(/[\r\n[\]]+/g, "_").slice(0, 100) || "image";
8967
+ const fileName = basename3(marker.path).replace(/[\r\n[\]]+/g, "_").slice(0, 100) || "image";
8336
8968
  try {
8337
8969
  const image = readValidatedImage(marker.path, {
8338
8970
  workspaceDir: this.config.cwd
@@ -8361,20 +8993,29 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8361
8993
  replacements.push(`[Image delivery failed: ${fileName}]`);
8362
8994
  }
8363
8995
  }
8364
- return replaceImageMarkers(fileSafeText, markers, replacements);
8996
+ return replaceImageMarkers(text, markers, replacements);
8365
8997
  }
8366
- async sendReply(chatId, text, atUserId) {
8998
+ async sendReply(chatId, text, atUserId, sourceLabel, prepared = false) {
8367
8999
  const webhook = this.webhooks.get(chatId);
8368
9000
  if (!webhook) {
8369
9001
  process.stderr.write(`[DingTalk:${this.name}] No webhook for chatId ${chatId}, cannot send.
8370
9002
  `);
8371
9003
  return;
8372
9004
  }
8373
- const outgoingText = await this.prepareOutgoingText(text);
9005
+ const outgoingText = prepared ? text : await this.prepareReplyOutput(chatId, text);
9006
+ if (!outgoingText.trim())
9007
+ return;
8374
9008
  const mentionPrefix = atUserId ? `@${atUserId}
8375
9009
 
8376
9010
  ` : "";
8377
- const chunks = normalizeDingTalkMarkdown(mentionPrefix + outgoingText);
9011
+ const sourcePrefix = sourceLabel && outgoingText.trim().length > 0 ? `${escapeDingTalkMarkdown(sourceLabel)}
9012
+
9013
+ ` : "";
9014
+ const contentLimit = DINGTALK_CHUNK_LIMIT - mentionPrefix.length - sourcePrefix.length;
9015
+ if (contentLimit <= 0) {
9016
+ throw new Error("DingTalk source label exceeds the message limit.");
9017
+ }
9018
+ const chunks = normalizeDingTalkMarkdown(outgoingText, contentLimit).map((chunk, index) => `${index === 0 ? mentionPrefix : ""}${sourcePrefix}${chunk}`);
8378
9019
  const title = extractTitle(outgoingText);
8379
9020
  for (let i = 0; i < chunks.length; i++) {
8380
9021
  const chunk = chunks[i];
@@ -8418,6 +9059,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8418
9059
  async sendMessage(chatId, text) {
8419
9060
  await this.sendReply(chatId, text);
8420
9061
  }
9062
+ async sendThreadMessage(chatId, _threadId, text, sourceLabel) {
9063
+ await this.sendReply(chatId, text, void 0, sourceLabel);
9064
+ }
8421
9065
  supportsProactiveSend() {
8422
9066
  return true;
8423
9067
  }
@@ -8436,11 +9080,20 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8436
9080
  * Single-shot cold send: a failed chunk aborts the remainder (already-sent
8437
9081
  * chunks are not recalled) and the error surfaces in the loop's lastError.
8438
9082
  */
8439
- async pushProactive(target, text) {
9083
+ async pushProactive(target, text, sourceLabel) {
8440
9084
  if (!text.trim())
8441
9085
  return;
8442
- const outgoingText = await this.prepareOutgoingText(text);
8443
- const chunks = normalizeDingTalkMarkdown(outgoingText);
9086
+ const outgoingText = await this.prepareFileOutput(text, (file, mediaId) => this.sendProactiveFile(target, file, mediaId));
9087
+ if (!outgoingText.trim())
9088
+ return;
9089
+ const sourcePrefix = sourceLabel ? `${escapeDingTalkMarkdown(sourceLabel)}
9090
+
9091
+ ` : "";
9092
+ const contentLimit = DINGTALK_CHUNK_LIMIT - sourcePrefix.length;
9093
+ if (contentLimit <= 0) {
9094
+ throw new Error("DingTalk source label exceeds the message limit.");
9095
+ }
9096
+ const chunks = normalizeDingTalkMarkdown(outgoingText, contentLimit).map((chunk) => `${sourcePrefix}${chunk}`);
8444
9097
  const title = extractTitle(outgoingText);
8445
9098
  for (let i = 0; i < chunks.length; i++) {
8446
9099
  await this.sendProactiveChunk(target, i === 0 ? title : `${title} (cont.)`, chunks[i], `chunk ${i + 1}/${chunks.length}`);
@@ -8466,7 +9119,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8466
9119
  const errmsg = sanitizeLogText(String(data.errmsg ?? ""), 200);
8467
9120
  process.stderr.write(`[DingTalk:${this.name}] access token request failed: gettoken errcode=${data.errcode} ${errmsg}
8468
9121
  `);
8469
- throw new Error(`DingTalk access token request failed: gettoken errcode=${data.errcode}${errmsg ? ` ${errmsg}` : ""}`);
9122
+ throw new DingtalkCardRequestError(`DingTalk access token request failed: gettoken errcode=${data.errcode}${errmsg ? ` ${errmsg}` : ""}`, !PERMANENT_TOKEN_ERROR_CODES.has(Number(data.errcode)));
8470
9123
  }
8471
9124
  this.proactiveToken = {
8472
9125
  token: data.access_token,
@@ -8492,6 +9145,12 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8492
9145
  }, "\u5361\u7247\u64CD\u4F5C", "\u4F60\u65E0\u6743\u64CD\u4F5C\u8FD9\u5F20\u5361\u7247\uFF0C\u4EC5\u4EFB\u52A1\u53D1\u8D77\u4EBA\u53EF\u4EE5\u63D0\u4EA4\u6216\u505C\u6B62\u3002", "card interaction feedback");
8493
9146
  }
8494
9147
  async sendProactiveChunk(target, title, text, chunkLabel) {
9148
+ return this.sendProactivePayload(target, PROACTIVE_MSG_KEY, { title, text }, chunkLabel);
9149
+ }
9150
+ async sendProactiveFile(target, file, mediaId) {
9151
+ return this.sendProactivePayload(target, PROACTIVE_FILE_MSG_KEY, { mediaId, fileName: file.fileName, fileType: file.fileType }, `file ${file.fileName}`);
9152
+ }
9153
+ async sendProactivePayload(target, msgKey, msgParam, chunkLabel) {
8495
9154
  const targetKind = target.isGroup === true ? "group" : "dm";
8496
9155
  for (let attempt = 0; ; attempt++) {
8497
9156
  const token = await this.getProactiveToken();
@@ -8507,8 +9166,8 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8507
9166
  body: JSON.stringify({
8508
9167
  robotCode: this.config.clientId,
8509
9168
  ...targetBody,
8510
- msgKey: PROACTIVE_MSG_KEY,
8511
- msgParam: JSON.stringify({ title, text })
9169
+ msgKey,
9170
+ msgParam: JSON.stringify(msgParam)
8512
9171
  }),
8513
9172
  signal: AbortSignal.timeout(PROACTIVE_FETCH_TIMEOUT_MS)
8514
9173
  });
@@ -8529,6 +9188,27 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8529
9188
  `);
8530
9189
  throw new Error(`DingTalk proactive send failed: HTTP ${resp.status}${detail ? ` ${detail}` : ""}`);
8531
9190
  }
9191
+ if (target.isGroup === true) {
9192
+ if (msgKey !== PROACTIVE_FILE_MSG_KEY) {
9193
+ await resp.body?.cancel();
9194
+ return;
9195
+ }
9196
+ let data;
9197
+ try {
9198
+ const parsed = await resp.json();
9199
+ data = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
9200
+ } catch {
9201
+ throw new Error("DingTalk file delivery failed: invalid JSON response");
9202
+ }
9203
+ const code = data["errcode"] ?? data["code"];
9204
+ if (code !== void 0 && String(code) !== "0") {
9205
+ throw new Error(`DingTalk file delivery failed: API code ${code}`);
9206
+ }
9207
+ if (typeof data["processQueryKey"] !== "string" || !data["processQueryKey"].trim()) {
9208
+ throw new Error("DingTalk file delivery failed: missing processQueryKey");
9209
+ }
9210
+ return;
9211
+ }
8532
9212
  if (target.isGroup === false) {
8533
9213
  let data;
8534
9214
  try {
@@ -8548,6 +9228,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8548
9228
  `);
8549
9229
  throw new Error("DingTalk proactive send failed: direct recipient rate limited");
8550
9230
  }
9231
+ if (msgKey === PROACTIVE_FILE_MSG_KEY && !data.processQueryKey?.trim()) {
9232
+ throw new Error("DingTalk file delivery failed: missing processQueryKey");
9233
+ }
8551
9234
  return;
8552
9235
  }
8553
9236
  await resp.body?.cancel();
@@ -8612,6 +9295,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8612
9295
  if (this.dedupTimer) {
8613
9296
  clearInterval(this.dedupTimer);
8614
9297
  }
9298
+ this.statusCardController?.dispose();
8615
9299
  this.activeReactionKeys.clear();
8616
9300
  this.sessionReactionKeys.clear();
8617
9301
  if (this.connectionManager) {
@@ -8733,7 +9417,8 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8733
9417
  if (event.runId && event.owner && inboundOwner?.ownerId === event.owner.id) {
8734
9418
  this.cardRuns.set(event.runId, inboundOwner);
8735
9419
  this.cardRunBySession.set(event.sessionId, event.runId);
8736
- this.interactionPresenter?.registerRun(event.runId, event.owner.id, inboundOwner.target, event.sessionId, inboundOwner.sender);
9420
+ const sourceLabel = this.getResponseSourceLabel(event.sessionId);
9421
+ this.interactionPresenter?.registerRun(event.runId, event.owner.id, inboundOwner.target, event.sessionId, inboundOwner.sender, ...sourceLabel ? [sourceLabel] : []);
8737
9422
  this.interactionPresenter?.startStatusCard(event.runId);
8738
9423
  }
8739
9424
  return;
@@ -8873,7 +9558,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8873
9558
  const tail = state.projector.complete();
8874
9559
  if (!tail.trim())
8875
9560
  return;
8876
- void this.sendReply(chatId, tail).catch((err) => {
9561
+ void this.sendReply(chatId, tail, void 0, this.getResponseSourceLabel(sessionId)).catch((err) => {
8877
9562
  process.stderr.write(`[DingTalk:${this.name}] projector tail delivery failed for session ${sessionId}: ${err instanceof Error ? err.message : String(err)}
8878
9563
  `);
8879
9564
  });
@@ -8883,13 +9568,13 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8883
9568
  * the session's block-streaming projector: a second sender interleaving with
8884
9569
  * mid-projection state can swallow the send or split a held marker.
8885
9570
  */
8886
- async deliverBackgroundReply(chatId, text, sessionId) {
9571
+ async deliverBackgroundReply(chatId, text, sessionId, sourceLabel) {
8887
9572
  if (this.config.blockStreaming !== "on") {
8888
- return super.deliverBackgroundReply(chatId, text, sessionId);
9573
+ return super.deliverBackgroundReply(chatId, text, sessionId, sourceLabel);
8889
9574
  }
8890
- await this.sendReply(chatId, text);
9575
+ await this.sendReply(chatId, text, void 0, sourceLabel);
8891
9576
  }
8892
- async sendResponseMessage(chatId, text, sessionId) {
9577
+ async sendResponseMessage(chatId, text, sessionId, sourceLabel, prepared = false) {
8893
9578
  let outgoingText = text;
8894
9579
  let consumesMention = true;
8895
9580
  if (this.config.blockStreaming === "on") {
@@ -8902,7 +9587,7 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8902
9587
  const atUserId = consumesMention && this.atSender ? this.sessionMentionTargets.get(sessionId) : void 0;
8903
9588
  if (atUserId)
8904
9589
  this.sessionMentionTargets.delete(sessionId);
8905
- await this.sendReply(chatId, outgoingText, atUserId);
9590
+ await this.sendReply(chatId, outgoingText, atUserId, sourceLabel ?? this.getResponseSourceLabel(sessionId), prepared);
8906
9591
  }
8907
9592
  projectBlockStreamChunk(text, sessionId) {
8908
9593
  let state = this.blockFileProjectors.get(sessionId);
@@ -8925,21 +9610,21 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
8925
9610
  }
8926
9611
  return { text: outgoingText, hasContent };
8927
9612
  }
8928
- async sendFallbackReply(chatId, text, sessionId) {
9613
+ async sendFallbackReply(chatId, text, sessionId, sourceLabel) {
8929
9614
  const atUserId = this.atSender ? this.sessionMentionTargets.get(sessionId) : void 0;
8930
- await this.sendReply(chatId, text, atUserId);
9615
+ await this.sendReply(chatId, text, atUserId, sourceLabel);
8931
9616
  }
8932
9617
  async onResponseComplete(chatId, text, sessionId, segment) {
8933
9618
  const streamed = segment ? this.fileProjectors.get(segment.runId)?.projector : void 0;
8934
9619
  if (segment)
8935
9620
  this.fileProjectors.delete(segment.runId);
8936
- const outgoingText = await this.prepareOutgoingText(text, streamed);
9621
+ const outgoingText = await this.prepareReplyOutput(chatId, text, streamed);
8937
9622
  if (segment && this.interactionPresenter) {
8938
9623
  if (await this.interactionPresenter.closeOutput(segment.segmentId, outgoingText, "completed", segment)) {
8939
9624
  return;
8940
9625
  }
8941
9626
  }
8942
- await this.sendResponseMessage(chatId, outgoingText, sessionId);
9627
+ await this.sendResponseMessage(chatId, outgoingText, sessionId, segment?.sourceLabel, true);
8943
9628
  }
8944
9629
  onOutputSegmentEnd(_chatId, _sessionId, segment, reason) {
8945
9630
  if (reason === "completed" || reason === "failed" || reason === "cancelled") {
@@ -9205,9 +9890,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
9205
9890
  let filePath;
9206
9891
  let safeName;
9207
9892
  try {
9208
- dir = join(tmpdir2(), "channel-files", randomUUID5());
9893
+ dir = join(tmpdir3(), "channel-files", randomUUID5());
9209
9894
  mkdirSync(dir, { recursive: true });
9210
- safeName = basename2(typeof fileName === "string" ? fileName : "") || `dingtalk_${mediaType}_${Date.now()}.${GENERATED_MEDIA_EXT[media.mimeType] ?? "bin"}`;
9895
+ safeName = basename3(typeof fileName === "string" ? fileName : "") || `dingtalk_${mediaType}_${Date.now()}.${GENERATED_MEDIA_EXT[media.mimeType] ?? "bin"}`;
9211
9896
  filePath = join(dir, safeName);
9212
9897
  writeFileSync(filePath, media.buffer);
9213
9898
  } catch (error) {
@@ -9311,9 +9996,18 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
9311
9996
  }
9312
9997
  }) : this.handleInbound(envelope);
9313
9998
  processMessage.catch((err) => {
9314
- process.stderr.write(`[DingTalk:${this.name}] Error handling message: ${err}
9999
+ const reference = randomUUID5().slice(0, 8);
10000
+ let errorSummary = "Unknown error";
10001
+ try {
10002
+ errorSummary = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
10003
+ } catch {
10004
+ }
10005
+ process.stderr.write(`[DingTalk:${this.name}] Error handling message ref=${reference}: ${sanitizeLogText(errorSummary, 300)}
9315
10006
  `);
9316
- this.sendMessage(chatId, "Sorry, something went wrong processing your message.").catch(() => {
10007
+ const fallbackMessage = formatInboundErrorMessage(err, reference);
10008
+ const sourceLabel = this.getInboundErrorSourceLabel(envelope);
10009
+ const delivery = sourceLabel ? this.sendThreadMessage(chatId, envelope.threadId, fallbackMessage, sourceLabel) : this.sendMessage(chatId, fallbackMessage);
10010
+ delivery.catch(() => {
9317
10011
  });
9318
10012
  });
9319
10013
  } catch (err) {