@qwen-code/qwen-code 0.21.0 → 0.21.1-nightly.20260731.702932cc7

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 (423) hide show
  1. package/bundled/qc-helper/docs/configuration/model-providers.md +2 -0
  2. package/bundled/qc-helper/docs/configuration/settings.md +39 -28
  3. package/bundled/qc-helper/docs/features/channels/_meta.ts +2 -0
  4. package/bundled/qc-helper/docs/features/channels/github.md +139 -0
  5. package/bundled/qc-helper/docs/features/channels/gitlab.md +171 -0
  6. package/bundled/qc-helper/docs/features/channels/overview.md +61 -6
  7. package/bundled/qc-helper/docs/features/code-review.md +21 -1
  8. package/bundled/qc-helper/docs/features/hooks.md +72 -15
  9. package/bundled/qc-helper/docs/features/mcp.md +9 -1
  10. package/bundled/qc-helper/docs/features/scheduled-tasks.md +3 -1
  11. package/bundled/qc-helper/docs/features/sub-agents.md +42 -8
  12. package/bundled/qc-helper/docs/qwen-serve.md +11 -7
  13. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +2 -2
  14. package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
  15. package/bundled/review/DESIGN.md +19 -0
  16. package/bundled/review/SKILL.md +120 -61
  17. package/chunks/MaxSizedBox-LAFHK4VO.js +88 -0
  18. package/chunks/{StandaloneSessionPicker-BIRMPLRD.js → StandaloneSessionPicker-EMNOBN3S.js} +71 -68
  19. package/chunks/{acp-startup-profiler-RV3IV562.js → acp-startup-profiler-2C4A5ZTJ.js} +2 -2
  20. package/chunks/{acpAgent-6J2U72PQ.js → acpAgent-ERFA6HWV.js} +1674 -591
  21. package/chunks/agent-PLKF6JK4.js +84 -0
  22. package/chunks/agent-headless-JAORDQ63.js +78 -0
  23. package/chunks/{anthropicContentGenerator-75BKLTSP.js → anthropicContentGenerator-OFHSZJBF.js} +79 -27
  24. package/chunks/{artifact-tool-Y5T7GG7F.js → artifact-tool-RDN2W7ND.js} +4 -4
  25. package/chunks/{askUserQuestion-2H6747FR.js → askUserQuestion-OZERWH5R.js} +4 -4
  26. package/chunks/bridge-NYOBVRIT.js +94 -0
  27. package/chunks/{build-RV63TIRH.js → build-GDBLPA24.js} +1 -1
  28. package/chunks/{ca-25EDXPFZ.js → ca-6W3SK7OQ.js} +6 -1
  29. package/chunks/channel-management-service-5S7YCWX5.js +418 -0
  30. package/chunks/channel-settings-store-NLOKYO23.js +91 -0
  31. package/chunks/{channel-worker-group-2ZD7TVAT.js → channel-worker-group-OVWGYMZS.js} +11 -6
  32. package/chunks/{channel-worker-manager-4OA4BCGB.js → channel-worker-manager-H55GKOQA.js} +11 -6
  33. package/chunks/{channel-worker-supervisor-V7KCFJTS.js → channel-worker-supervisor-CABBXYHK.js} +7 -5
  34. package/chunks/{chunk-RIBKPMRP.js → chunk-23F4XGWO.js} +19 -6
  35. package/chunks/{chunk-ACY3A37B.js → chunk-25VHI5T7.js} +23 -18
  36. package/chunks/{chunk-MZAXJAUM.js → chunk-26JK4RPD.js} +1 -1
  37. package/chunks/{chunk-6GMVPFB2.js → chunk-2IIJTXYF.js} +45 -16
  38. package/chunks/{chunk-BPJSQIJX.js → chunk-2J3OJGTL.js} +0 -2
  39. package/chunks/{chunk-2X55UKQE.js → chunk-2JZR3B4A.js} +3 -3
  40. package/chunks/{chunk-7JURR4JT.js → chunk-2OQUICDM.js} +167 -81
  41. package/chunks/{chunk-ZJHVAS7M.js → chunk-2YCYFWYZ.js} +4 -5
  42. package/chunks/{chunk-3QMGYBFN.js → chunk-3APUUXRF.js} +1 -80
  43. package/chunks/{chunk-MUP3T3AD.js → chunk-3I6DUGQD.js} +1 -35
  44. package/chunks/{chunk-JVPM2ULZ.js → chunk-3XZ5SSNR.js} +6 -6
  45. package/chunks/chunk-42VPM33K.js +319 -0
  46. package/chunks/{chunk-VAK25FTU.js → chunk-45IOTAUS.js} +1 -1
  47. package/chunks/chunk-45UYUCJ6.js +363 -0
  48. package/chunks/{chunk-JZA3JUDJ.js → chunk-4KP2F2TE.js} +1 -1
  49. package/chunks/{chunk-IO3IX5Q4.js → chunk-4YJQD2IO.js} +1 -1
  50. package/chunks/{chunk-JXJFVC6E.js → chunk-5G6XUGXO.js} +61 -14
  51. package/chunks/{chunk-ZOIFNCKL.js → chunk-5NNHICSA.js} +3 -23
  52. package/chunks/{chunk-A4UCTEB5.js → chunk-5WV5S2GT.js} +0 -1
  53. package/chunks/{chunk-RHLZR4E5.js → chunk-675H6PLP.js} +1 -1
  54. package/chunks/chunk-6FMJLI5M.js +1591 -0
  55. package/chunks/chunk-6MPDY6ZG.js +76 -0
  56. package/chunks/{chunk-PSOO6YXD.js → chunk-6NUWQ3R7.js} +9 -7
  57. package/chunks/{chunk-7MVVZO4N.js → chunk-6ZRWX46I.js} +4 -4
  58. package/chunks/{chunk-TPRQ7RZH.js → chunk-76E5Y3UZ.js} +3117 -993
  59. package/chunks/{chunk-UUUTRMI2.js → chunk-7ULQIS27.js} +1 -1
  60. package/chunks/{chunk-BKHWX6I2.js → chunk-A5BZ722X.js} +11 -3
  61. package/chunks/{chunk-TEHGS6UP.js → chunk-A5T5W7PR.js} +154 -16
  62. package/chunks/{chunk-VIA5XA4U.js → chunk-A5UODYG3.js} +4 -1
  63. package/chunks/{chunk-JLU636DO.js → chunk-ALMR3E6Q.js} +1 -0
  64. package/chunks/{chunk-EBJQ6AXW.js → chunk-ANDVK2JN.js} +358 -14
  65. package/chunks/{chunk-TOFQCPDC.js → chunk-AOHY3QJ3.js} +14 -8
  66. package/chunks/chunk-AQ37AY7B.js +93 -0
  67. package/chunks/{chunk-PJIZUQVC.js → chunk-AZQ3DT76.js} +2 -2
  68. package/chunks/{chunk-LKEJ26GS.js → chunk-B3TA3IF5.js} +16 -11
  69. package/chunks/{chunk-Q4M4MDQ4.js → chunk-B43QHWY6.js} +1 -1
  70. package/chunks/{chunk-UH3WSE5L.js → chunk-B4AJNNOL.js} +1 -6
  71. package/chunks/{chunk-K36B6G2O.js → chunk-B6FOGNGH.js} +5 -5
  72. package/chunks/{chunk-PWVFN2LF.js → chunk-BP2H5K25.js} +1 -1
  73. package/chunks/{chunk-LB6DUZ26.js → chunk-BTWSGZCT.js} +264 -185
  74. package/chunks/{chunk-ZNAUOR2I.js → chunk-BZBPT52P.js} +2 -2
  75. package/chunks/{chunk-L26JL52R.js → chunk-CBBP4BMC.js} +64 -67
  76. package/chunks/{chunk-ZD6UTE4A.js → chunk-CNTR4GR6.js} +1 -1
  77. package/chunks/{chunk-3SJ43L4W.js → chunk-CPZAH673.js} +6 -0
  78. package/chunks/{chunk-EPDRMGT4.js → chunk-D4HTUMGX.js} +4 -28
  79. package/chunks/{chunk-QAF7NMK7.js → chunk-D7CQTWRS.js} +1 -1
  80. package/chunks/{chunk-XVNQMZ2I.js → chunk-DGEIYUC3.js} +0 -1
  81. package/chunks/{chunk-BPZALHVR.js → chunk-DI35ZN7T.js} +1 -1
  82. package/chunks/{chunk-IKCX4CCL.js → chunk-DKPJUF5F.js} +118 -95
  83. package/chunks/{chunk-DLWL3Z7A.js → chunk-DSFHVTWD.js} +3 -3
  84. package/chunks/{chunk-FSITMZJH.js → chunk-DYRYLJ3O.js} +18 -9
  85. package/chunks/{chunk-NL7LTRLR.js → chunk-E2BHWIDT.js} +48 -72
  86. package/chunks/{chunk-UDX5OBWR.js → chunk-E2FN6SM7.js} +94 -4
  87. package/chunks/{chunk-USTWD7QV.js → chunk-E6CJ2SMM.js} +26 -16
  88. package/chunks/{chunk-KMQ33DO4.js → chunk-EDB7A72S.js} +4 -4
  89. package/chunks/{chunk-7ZCNENPP.js → chunk-FANRZEAJ.js} +1 -1
  90. package/chunks/{chunk-WBL3FJEU.js → chunk-FC4KQFCS.js} +1 -1
  91. package/chunks/{chunk-5NBDS5S6.js → chunk-FCYYAB4S.js} +162 -7
  92. package/chunks/{chunk-OKY7HXPG.js → chunk-FJ5WUMUQ.js} +2 -2
  93. package/chunks/{chunk-PHOF65IG.js → chunk-FRXG4ARO.js} +36273 -44436
  94. package/chunks/{chunk-FQK6JAFG.js → chunk-FS674JW4.js} +4 -4
  95. package/chunks/chunk-FYJ7W2PI.js +194 -0
  96. package/chunks/{chunk-BULDBTYC.js → chunk-G7XXKQYS.js} +3 -28
  97. package/chunks/{chunk-LS77BEZP.js → chunk-GLCZKT5V.js} +1 -5
  98. package/chunks/{chunk-VRYUBFMC.js → chunk-GRUAVQQR.js} +1 -1
  99. package/chunks/{chunk-MVSUYZDT.js → chunk-GWV7DI3S.js} +4 -4
  100. package/chunks/{chunk-A5L3JMUA.js → chunk-HC45LTEN.js} +18 -4
  101. package/chunks/{chunk-PC6JANNU.js → chunk-HKRVXYDN.js} +4 -4
  102. package/chunks/{chunk-GZXCZHCT.js → chunk-I3G5JWBV.js} +1 -1
  103. package/chunks/{chunk-4WIZGAH3.js → chunk-I5BT7ADR.js} +6 -58
  104. package/chunks/{chunk-GSN55ZRI.js → chunk-ID3O7PRB.js} +19 -7
  105. package/chunks/{chunk-L5UHQJTJ.js → chunk-IGTHU3T4.js} +1 -1
  106. package/chunks/{chunk-BIQWWWJN.js → chunk-IIUGIWWY.js} +1 -1
  107. package/chunks/{chunk-RWTEFFPU.js → chunk-JCJ7LKNA.js} +6140 -5616
  108. package/chunks/{chunk-S3TWXGKA.js → chunk-JE7KQ2UP.js} +4 -2
  109. package/chunks/{chunk-PWTZEM3C.js → chunk-JXVC2PL3.js} +3 -37
  110. package/chunks/chunk-JYBU6YUE.js +378 -0
  111. package/chunks/{chunk-RF3EXIHJ.js → chunk-K3PFMM5U.js} +49 -26
  112. package/chunks/{chunk-JCW2R7WC.js → chunk-K623ENWT.js} +3 -79
  113. package/chunks/{chunk-T2NCM2ET.js → chunk-K6KS3LTN.js} +2 -749
  114. package/chunks/chunk-KWHKHSIS.js +81 -0
  115. package/chunks/{chunk-DHHOYAPR.js → chunk-L2E5GFAG.js} +7 -7
  116. package/chunks/{chunk-2W3OOD4W.js → chunk-L55JWS76.js} +6 -3
  117. package/chunks/{chunk-E5TUC6CA.js → chunk-LHKCY7DY.js} +3 -3
  118. package/chunks/{chunk-NH6KE4JX.js → chunk-LOY7RWQG.js} +3 -3
  119. package/chunks/{chunk-U7M2DMGW.js → chunk-M4MSAE7U.js} +130 -5
  120. package/chunks/{chunk-IJTOWOD7.js → chunk-MB32MS4U.js} +92 -9
  121. package/chunks/{chunk-PR75REBZ.js → chunk-MM7TH7ZM.js} +12 -82
  122. package/chunks/{chunk-FODK6UMO.js → chunk-MPHPFVKK.js} +0 -2
  123. package/chunks/{chunk-M5JM7OSF.js → chunk-N4ACHWNH.js} +2 -3
  124. package/chunks/{chunk-JESCGQM3.js → chunk-NAVJD2PQ.js} +8 -7
  125. package/chunks/{chunk-J56UI34H.js → chunk-NBD76HUW.js} +4 -2
  126. package/chunks/{chunk-2SCDWPXI.js → chunk-NC4U4I3Y.js} +5 -5
  127. package/chunks/{chunk-H4SBPHSA.js → chunk-NNL7WPPK.js} +3 -3
  128. package/chunks/{chunk-YBL3QUDD.js → chunk-NQCXWP5D.js} +1 -1
  129. package/chunks/{chunk-CIKQ7KKO.js → chunk-NVFSGPIF.js} +954 -444
  130. package/chunks/{chunk-6OUGMXDC.js → chunk-NWNEANAT.js} +7 -7
  131. package/chunks/chunk-O6GEWCJA.js +21 -0
  132. package/chunks/chunk-OCPBI7J5.js +18 -0
  133. package/chunks/{chunk-KIM5GUMA.js → chunk-OE6F6ZWQ.js} +589 -220
  134. package/chunks/{chunk-SQCQ4KO2.js → chunk-P5DEY3NF.js} +380 -317
  135. package/chunks/{chunk-2JZBVYTU.js → chunk-Q3T5KA2V.js} +1 -8
  136. package/chunks/{chunk-MB4MZHMJ.js → chunk-QARJNL2V.js} +211 -522
  137. package/chunks/{chunk-YH6G52F2.js → chunk-QCXGC7QB.js} +4 -4
  138. package/chunks/chunk-QDK4F2N5.js +1252 -0
  139. package/chunks/{chunk-VDDGDZMA.js → chunk-QHWCP53L.js} +14 -7
  140. package/chunks/{chunk-VULLI6WQ.js → chunk-QIERF2GQ.js} +6 -6
  141. package/chunks/{chunk-TGILQ3YH.js → chunk-QQTJK5GB.js} +200 -77
  142. package/chunks/{chunk-H5FFA6TH.js → chunk-QTHQ6Z5X.js} +16 -3
  143. package/chunks/{chunk-5I2IWRSH.js → chunk-R2XWGR75.js} +2 -2
  144. package/chunks/{chunk-YPE6A4GC.js → chunk-RT7FNC2O.js} +2 -2
  145. package/chunks/{chunk-OFDOK3VM.js → chunk-RX7NJOPE.js} +8 -13
  146. package/chunks/{chunk-6AM5D4ME.js → chunk-S6LOFUVP.js} +0 -12
  147. package/chunks/{chunk-K4XWPEWB.js → chunk-SHN4KHDK.js} +4 -33
  148. package/chunks/{chunk-VYPFXUCB.js → chunk-SZ3KHTDR.js} +1 -1
  149. package/chunks/chunk-T26EAKDL.js +13 -0
  150. package/chunks/chunk-T3CHYWJZ.js +758 -0
  151. package/chunks/{chunk-FNQ6T3CV.js → chunk-TEGJSJDF.js} +10 -7
  152. package/chunks/{chunk-RZIX2G32.js → chunk-THPORXSI.js} +1 -1
  153. package/chunks/{chunk-OHNBB4XR.js → chunk-THVU3RNH.js} +1 -1
  154. package/chunks/{record-artifact-RQKFYO5B.js → chunk-TIRRPCFS.js} +22 -7
  155. package/chunks/{chunk-ETSW4KLJ.js → chunk-TUCOXPHJ.js} +2 -2
  156. package/chunks/{chunk-63P4EL5V.js → chunk-TZTAV5RH.js} +1 -1
  157. package/chunks/{chunk-LK7CHLVP.js → chunk-U4VTUMMK.js} +0 -60
  158. package/chunks/{chunk-3RN6GBKS.js → chunk-U5CODIJW.js} +1 -1
  159. package/chunks/chunk-UU2B5YG6.js +2196 -0
  160. package/chunks/{chunk-R5AFZNQW.js → chunk-VAVHTGU4.js} +15 -8
  161. package/chunks/{chunk-2NH6DYI4.js → chunk-VHPFWR2O.js} +12 -12
  162. package/chunks/{chunk-IKYJHJNF.js → chunk-VOMQ2P6B.js} +3 -3
  163. package/chunks/{chunk-ZFDTEDCF.js → chunk-VX22DUW2.js} +6 -6
  164. package/chunks/{chunk-HTR4WV6U.js → chunk-W4RQUHY3.js} +31 -1
  165. package/chunks/{chunk-M4FMGVY4.js → chunk-WQP7BKWA.js} +3 -3
  166. package/chunks/{chunk-LH2BYDQ5.js → chunk-X2E5TFJ5.js} +18 -12
  167. package/chunks/{chunk-COH43MRJ.js → chunk-XCGIMOLN.js} +27 -1
  168. package/chunks/{chunk-YX324OPW.js → chunk-XDS22O52.js} +1 -1
  169. package/chunks/chunk-XP4L6KS3.js +463 -0
  170. package/chunks/{chunk-6FGBXPWM.js → chunk-XQK4XXTN.js} +38 -44
  171. package/chunks/{chunk-55DJUCI2.js → chunk-XWYPFDB5.js} +53 -43
  172. package/chunks/{chunk-Y34KJKDC.js → chunk-Y7BVNVVW.js} +1 -1
  173. package/chunks/{chunk-IPUUTYMV.js → chunk-YDLJGZHL.js} +1 -1
  174. package/chunks/{chunk-HIJQF5B5.js → chunk-YGE3IXJP.js} +1 -1
  175. package/chunks/{chunk-LQIW3YFY.js → chunk-YJFPRUWX.js} +9 -7
  176. package/chunks/{chunk-J24WCGIN.js → chunk-YQIIG4NA.js} +4 -4
  177. package/chunks/{chunk-BJX6ZSUK.js → chunk-YUFIEIWC.js} +2 -2
  178. package/chunks/{chunk-NIBLUX3Y.js → chunk-Z3S5EMOW.js} +148 -21
  179. package/chunks/{chunk-WCXCRJYB.js → chunk-Z3YLHKB7.js} +1 -1
  180. package/chunks/chunk-Z4X5MTRT.js +133 -0
  181. package/chunks/{chunk-UW5EOVUN.js → chunk-ZBVS26BY.js} +4 -4
  182. package/chunks/{chunk-HTO4JFDZ.js → chunk-ZPJWUGCS.js} +0 -1
  183. package/chunks/{chunk-X5XDDSSH.js → chunk-ZPZ7ZJEE.js} +28 -5
  184. package/chunks/{computer-use-SOQ4E3VX.js → computer-use-GOM42LNK.js} +53 -50
  185. package/chunks/{config-utils-7V7GGIW6.js → config-utils-WADIDWGG.js} +4 -3
  186. package/chunks/contextCommand-6LVPTIWD.js +83 -0
  187. package/chunks/core-runtime-253XV2DB.js +137 -0
  188. package/chunks/{create-sub-session-QRJLW5BV.js → create-sub-session-45POYEVP.js} +50 -47
  189. package/chunks/{create-sub-session-IWW2IZ2T.js → create-sub-session-62YZWVAY.js} +3 -3
  190. package/chunks/{cron-create-YIID5XAW.js → cron-create-6E7GIQTG.js} +6 -6
  191. package/chunks/{cron-delete-ZVHYCEP2.js → cron-delete-JD26XY3W.js} +5 -5
  192. package/chunks/{cron-list-XEGS463Q.js → cron-list-CUWFB44G.js} +6 -6
  193. package/chunks/{daemon-YO6433NF.js → daemon-PCNCI5YU.js} +428 -18
  194. package/chunks/daemon-status-provider-AKALDYJJ.js +93 -0
  195. package/chunks/daemon-trust-policy-XB7ZSQFQ.js +88 -0
  196. package/chunks/daemon-trust-policy-monitor-FUTKP42Q.js +175 -0
  197. package/chunks/{de-HGRCYDEJ.js → de-SY6O76BF.js} +6 -1
  198. package/chunks/deferred-core-runtime-RKLCO7V5.js +92 -0
  199. package/chunks/dist-26BIMQT6.js +4487 -0
  200. package/chunks/{dist-F6IBUDR4.js → dist-2PERFI23.js} +12 -9
  201. package/chunks/{dist-46NQKLTW.js → dist-OAOC5OV4.js} +2 -2
  202. package/chunks/{dist-YFNEUWSE.js → dist-PVEAFLHY.js} +5 -4
  203. package/chunks/{dist-AIKFMUKK.js → dist-SL2LUMML.js} +1449 -14
  204. package/chunks/dist-ULIG4M5H.js +13415 -0
  205. package/chunks/{dist-WEAHOXDM.js → dist-WGMNT3JQ.js} +2 -1
  206. package/chunks/{dist-BBLXMS3N.js → dist-ZHXOBXDN.js} +3 -3
  207. package/chunks/earlyInputCapture-FCWU47OB.js +85 -0
  208. package/chunks/{edit-OBDSQURM.js → edit-TTACM3LN.js} +51 -48
  209. package/chunks/{en-MTWBNGDO.js → en-NBK3JKCE.js} +9 -1
  210. package/chunks/{enter-worktree-U6MRPQ2P.js → enter-worktree-R34GFDX6.js} +51 -48
  211. package/chunks/{enterPlanMode-BC5QUZZ2.js → enterPlanMode-KJPBB6G5.js} +51 -48
  212. package/chunks/environment-IJG3N2PR.js +105 -0
  213. package/chunks/errors-MRON5OJD.js +91 -0
  214. package/chunks/esm-K5FARBNI.js +5548 -0
  215. package/chunks/{exit-worktree-DGNYMECB.js → exit-worktree-UBA66Y4I.js} +51 -48
  216. package/chunks/exitPlanMode-SMSPGNSK.js +76 -0
  217. package/chunks/{fast-path-JJZFJANL.js → fast-path-ZBAMZDCP.js} +16 -6
  218. package/chunks/{fr-45RLL55O.js → fr-4KG5V7UT.js} +6 -1
  219. package/chunks/{gemini-QS36EBZV.js → gemini-XFT7HRNL.js} +106 -99
  220. package/chunks/{geminiContentGenerator-AG4KB6CV.js → geminiContentGenerator-XD3MLYQX.js} +40 -11
  221. package/chunks/{getMachineId-bsd-V7W3GODC.js → getMachineId-bsd-FG7IUY6U.js} +1 -1
  222. package/chunks/{getMachineId-darwin-TDO75DQP.js → getMachineId-darwin-GLCJI2RA.js} +1 -1
  223. package/chunks/{getMachineId-linux-TF43WQT2.js → getMachineId-linux-O6OPPAKO.js} +1 -1
  224. package/chunks/{getMachineId-unsupported-ZGUO3TXT.js → getMachineId-unsupported-S6CKYVGC.js} +1 -1
  225. package/chunks/{getMachineId-win-ECFYZZFQ.js → getMachineId-win-X5SRNEH7.js} +1 -1
  226. package/chunks/{glob-V7R3PSK3.js → glob-HFKY7HXZ.js} +51 -48
  227. package/chunks/goal-tools-HGO6VXPB.js +335 -0
  228. package/chunks/{grep-QYPSK7OP.js → grep-EO5Z3PFV.js} +53 -49
  229. package/chunks/handleAutoUpdate-WRENFE6C.js +84 -0
  230. package/chunks/i18n-ZG5OTVSV.js +100 -0
  231. package/chunks/{image-gen-Z3VPGKRC.js → image-gen-CKWZ4MJI.js} +12 -12
  232. package/chunks/initializer-FYPLLRC7.js +89 -0
  233. package/chunks/installationInfo-5RV4HRMC.js +83 -0
  234. package/chunks/{ja-B7DF7DFG.js → ja-F3GSQXMF.js} +6 -1
  235. package/chunks/{keychain-token-storage-MDTG3WRM.js → keychain-token-storage-IKO4G53C.js} +3 -3
  236. package/chunks/lib-RUF3WZA6.js +9 -0
  237. package/chunks/list-ZNWVL3AT.js +92 -0
  238. package/chunks/{list-agents-5KJJHR6I.js → list-agents-PXJ7ZUFB.js} +3 -3
  239. package/chunks/loadedSettingsAdapter-GQGNHP5I.js +86 -0
  240. package/chunks/{loggingContentGenerator-HS3S5H3Q.js → loggingContentGenerator-MS5DFAWH.js} +78 -113
  241. package/chunks/{loop-wakeup-FXKNNYSY.js → loop-wakeup-Y26NQZ5I.js} +15 -8
  242. package/chunks/{ls-NTK6VOQJ.js → ls-ONQTTMQR.js} +5 -5
  243. package/chunks/{lsp-2JI24STP.js → lsp-YGHHRGMD.js} +3 -3
  244. package/chunks/{managed-npm-update-JYEMMXA3.js → managed-npm-update-67AK4GTL.js} +51 -48
  245. package/chunks/mcp-FVQ4VTLM.js +86 -0
  246. package/chunks/{monitor-R3ODH5U6.js → monitor-BXB33EOZ.js} +51 -48
  247. package/chunks/nonInteractiveCli-CN2GYSN3.js +148 -0
  248. package/chunks/{notebook-edit-BNOK452R.js → notebook-edit-FKYRBV4L.js} +51 -48
  249. package/chunks/{openaiContentGenerator-WMCU3O2H.js → openaiContentGenerator-UUXV5DGU.js} +26 -27
  250. package/chunks/pidfile-MV347TTZ.js +89 -0
  251. package/chunks/process-registry-2CHQBXH5.js +157 -0
  252. package/chunks/{processUtils-RT7UNCC2.js → processUtils-LKFG52RV.js} +2 -2
  253. package/chunks/{pt-22Q3FP73.js → pt-EQ33KWEN.js} +6 -1
  254. package/chunks/{qwenContentGenerator-HHCRK4SX.js → qwenContentGenerator-3WYI2HRW.js} +56 -53
  255. package/chunks/{qwenOAuth2-OWLB5AKH.js → qwenOAuth2-B46MW45O.js} +10 -10
  256. package/chunks/read-file-ACSHVWP3.js +29 -0
  257. package/chunks/{read-mcp-resource-4DKQWGHD.js → read-mcp-resource-U2IJN5HM.js} +4 -4
  258. package/chunks/record-artifact-MGPJ7EG4.js +21 -0
  259. package/chunks/resumeHistoryUtils-AMS4767B.js +94 -0
  260. package/chunks/ripGrep-BAPM2UKC.js +76 -0
  261. package/chunks/{ru-FZCNZHDC.js → ru-7OZAUKGG.js} +6 -1
  262. package/chunks/{run-qwen-serve-FU6HEM4J.js → run-qwen-serve-JEN6FO2A.js} +1018 -263
  263. package/chunks/runtime-WVP22ISH.js +122 -0
  264. package/chunks/{scheduler-G2ZS2Z7E.js → scheduler-HTX5ACVR.js} +50 -47
  265. package/chunks/{sdk-exporters-grpc-AK3LGHNO.js → sdk-exporters-grpc-54L4LS5L.js} +4 -4
  266. package/chunks/{sdk-exporters-http-FYBSUCPD.js → sdk-exporters-http-4BQANSJ6.js} +7 -7
  267. package/chunks/{sdk-impl-GMVPB7NB.js → sdk-impl-Z4VXWVFX.js} +14 -14
  268. package/chunks/{send-message-Q6OOR6BR.js → send-message-PMP4ATVM.js} +8 -13
  269. package/chunks/serve-ELQIVNWN.js +92 -0
  270. package/chunks/{server-4UMH7OIZ.js → server-JNW2NOSQ.js} +5288 -1364
  271. package/chunks/{session-K3O3Q2SV.js → session-NC356XNS.js} +102 -95
  272. package/chunks/{settings-CR2EWTBA.js → settings-73RMIOJ6.js} +54 -51
  273. package/chunks/shell-NMHF5TFG.js +86 -0
  274. package/chunks/{skill-I3SDA4MB.js → skill-XPGXHEKO.js} +22 -22
  275. package/chunks/skill-settings-5IGIJDGA.js +94 -0
  276. package/chunks/spawnChannel-T5THBHFN.js +85 -0
  277. package/chunks/standalone-update-ODXEPDLP.js +95 -0
  278. package/chunks/{startInteractiveUI-SLZGHRPH.js → startInteractiveUI-S27DXVAE.js} +1241 -905
  279. package/chunks/{syntheticOutput-I3757IWH.js → syntheticOutput-D7E6ZFKR.js} +4 -4
  280. package/chunks/task-create-NFCYD43L.js +26 -0
  281. package/chunks/{task-list-FOPULZEP.js → task-list-TAVMGEVD.js} +7 -7
  282. package/chunks/{task-stop-H6RHXFVQ.js → task-stop-ZDF2UJRM.js} +3 -3
  283. package/chunks/{task-update-M57TFZJT.js → task-update-6L7LHGEX.js} +12 -11
  284. package/chunks/{team-create-YJALH5D2.js → team-create-CTLQWTJ2.js} +53 -50
  285. package/chunks/{team-delete-QE2UXJL7.js → team-delete-DPGGRQBU.js} +7 -7
  286. package/chunks/{team-plan-approval-34QFYKGN.js → team-plan-approval-WKRUAPJ4.js} +51 -48
  287. package/chunks/theme-manager-XQHXQQX6.js +80 -0
  288. package/chunks/{todoWrite-VQ7FKOHL.js → todoWrite-2UO5G6G6.js} +34 -6
  289. package/chunks/{tool-search-NF7GB6LE.js → tool-search-45YINAJA.js} +21 -22
  290. package/chunks/total-session-admission-QPUKGHKO.js +88 -0
  291. package/chunks/trustedFolders-YMUTRHEQ.js +98 -0
  292. package/chunks/{update-relaunch-WBUZJC5O.js → update-relaunch-PZUXTVHC.js} +5 -5
  293. package/chunks/updateCheck-IZAN4XTB.js +95 -0
  294. package/chunks/useAutoAcceptIndicator-CGL2MAYE.js +96 -0
  295. package/chunks/{validateNonInterActiveAuth-3R223G3R.js → validateNonInterActiveAuth-GBGNJ65K.js} +97 -90
  296. package/chunks/{version-HS7YSFHV.js → version-Z7EX24NZ.js} +1 -1
  297. package/chunks/{web-fetch-NKCSG7ZE.js → web-fetch-ETTT2H3V.js} +19 -21
  298. package/chunks/{web-search-S62WAP4S.js → web-search-Y3ZSVRJ6.js} +13 -13
  299. package/chunks/{workflow-QAGU5RU4.js → workflow-ATRJSAO7.js} +52 -49
  300. package/chunks/workspace-providers-status-YM3WLW3N.js +89 -0
  301. package/chunks/{workspace-registration-store-24JMHDGF.js → workspace-registration-store-4EGNCIPG.js} +1 -1
  302. package/chunks/workspace-registry-NGZOZKQP.js +96 -0
  303. package/chunks/workspace-service-SVWOXX2B.js +103 -0
  304. package/chunks/workspace-skills-status-YZHZ3PT5.js +89 -0
  305. package/chunks/workspace-trust-reconciler-GGBQV2U5.js +349 -0
  306. package/chunks/write-file-HLGCEB72.js +78 -0
  307. package/chunks/xterm-headless-NTYVIBT3.js +3475 -0
  308. package/chunks/{zh-LUIGBD55.js → zh-H3YDK5QW.js} +9 -1
  309. package/chunks/{zh-TW-F5KG2IYD.js → zh-TW-JYCP7XUA.js} +9 -1
  310. package/chunks/zoom-image-LDECT475.js +224 -0
  311. package/cli.js +50 -16
  312. package/locales/ca.js +7 -2
  313. package/locales/de.js +7 -2
  314. package/locales/en.js +10 -2
  315. package/locales/fr.js +7 -2
  316. package/locales/ja.js +7 -2
  317. package/locales/pt.js +7 -2
  318. package/locales/ru.js +7 -2
  319. package/locales/zh-TW.js +10 -2
  320. package/locales/zh.js +10 -2
  321. package/package.json +5 -4
  322. package/web-shell/assets/{arc-DcbWnB9T.js → arc-Dpy_U6Bb.js} +1 -1
  323. package/web-shell/assets/{architectureDiagram-3BPJPVTR-kMMF5sud.js → architectureDiagram-3BPJPVTR-DgDOg-c5.js} +1 -1
  324. package/web-shell/assets/{blockDiagram-GPEHLZMM-Htl9vTJS.js → blockDiagram-GPEHLZMM-tADd9Ja3.js} +1 -1
  325. package/web-shell/assets/{c4Diagram-AAUBKEIU-BnZnm0mQ.js → c4Diagram-AAUBKEIU-68wj9MCU.js} +1 -1
  326. package/web-shell/assets/channel-Do7fFnFl.js +1 -0
  327. package/web-shell/assets/{chunk-2J33WTMH-DziB7kDG.js → chunk-2J33WTMH-DjJLOeVU.js} +1 -1
  328. package/web-shell/assets/{chunk-4BX2VUAB-CmkD8daw.js → chunk-4BX2VUAB-CMbzGeVC.js} +1 -1
  329. package/web-shell/assets/{chunk-55IACEB6-CHAd9A_U.js → chunk-55IACEB6-SlKgejv9.js} +1 -1
  330. package/web-shell/assets/{chunk-727SXJPM-Dqaam3fE.js → chunk-727SXJPM-CijXssHZ.js} +1 -1
  331. package/web-shell/assets/{chunk-AQP2D5EJ-D_-saBYM.js → chunk-AQP2D5EJ-D8w25nvR.js} +1 -1
  332. package/web-shell/assets/{chunk-FMBD7UC4-B9r_veWD.js → chunk-FMBD7UC4-Bv9dcx_e.js} +1 -1
  333. package/web-shell/assets/{chunk-ND2GUHAM-B3EaCSpL.js → chunk-ND2GUHAM-Bzf6sAOd.js} +1 -1
  334. package/web-shell/assets/{chunk-QZHKN3VN-CYq8x9mn.js → chunk-QZHKN3VN-whNoNeW5.js} +1 -1
  335. package/web-shell/assets/classDiagram-4FO5ZUOK-By_XOP3X.js +1 -0
  336. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-By_XOP3X.js +1 -0
  337. package/web-shell/assets/{cose-bilkent-S5V4N54A-D0ng4uiB.js → cose-bilkent-S5V4N54A-rpQS44Lz.js} +1 -1
  338. package/web-shell/assets/{dagre-BM42HDAG-DCZollQv.js → dagre-BM42HDAG-Ck7VE6nT.js} +1 -1
  339. package/web-shell/assets/{diagram-2AECGRRQ-Dfk2pWS0.js → diagram-2AECGRRQ-CgRrsodR.js} +1 -1
  340. package/web-shell/assets/{diagram-5GNKFQAL-kX38ltWR.js → diagram-5GNKFQAL-CsTZtE5A.js} +1 -1
  341. package/web-shell/assets/{diagram-KO2AKTUF-CJz2vsXh.js → diagram-KO2AKTUF-D5EAdVq4.js} +1 -1
  342. package/web-shell/assets/{diagram-LMA3HP47-BvMLZm_7.js → diagram-LMA3HP47-DNrjHC7Z.js} +1 -1
  343. package/web-shell/assets/{diagram-OG6HWLK6-l7kfStkO.js → diagram-OG6HWLK6-ClJSJGgC.js} +1 -1
  344. package/web-shell/assets/{erDiagram-TEJ5UH35-BSVa8GGT.js → erDiagram-TEJ5UH35-DuVnos_y.js} +1 -1
  345. package/web-shell/assets/{flowDiagram-I6XJVG4X-CoawKIXH.js → flowDiagram-I6XJVG4X-DEpIVl1s.js} +1 -1
  346. package/web-shell/assets/{ganttDiagram-6RSMTGT7-DFUDH0zF.js → ganttDiagram-6RSMTGT7-COnQM2-C.js} +1 -1
  347. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-Y2pvpT4e.js → gitGraphDiagram-PVQCEYII-C-lX5H3_.js} +1 -1
  348. package/web-shell/assets/index-C2GE3DAF.js +74 -0
  349. package/web-shell/assets/{index-D0GX0zZf.js → index-DfcyS2E7.js} +1 -1
  350. package/web-shell/assets/index-Qxt6kN7i.js +1700 -0
  351. package/web-shell/assets/index-bo0Z8hfu.css +5 -0
  352. package/web-shell/assets/{infoDiagram-5YYISTIA-CU8_zLiX.js → infoDiagram-5YYISTIA-D0WP-wmU.js} +1 -1
  353. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-AVQiV0DU.js → ishikawaDiagram-YF4QCWOH-DgsI3Clu.js} +1 -1
  354. package/web-shell/assets/{journeyDiagram-JHISSGLW-DQ0VSKa3.js → journeyDiagram-JHISSGLW-4yCoMZO6.js} +1 -1
  355. package/web-shell/assets/{kanban-definition-UN3LZRKU-BqnWqsE_.js → kanban-definition-UN3LZRKU-D_05au1N.js} +1 -1
  356. package/web-shell/assets/{linear-BkoihsaA.js → linear-B38fDz0Q.js} +1 -1
  357. package/web-shell/assets/{mermaid.core-5RJs-31j.js → mermaid.core-aGNwTaHi.js} +5 -5
  358. package/web-shell/assets/{mindmap-definition-RKZ34NQL-D33Bxnpd.js → mindmap-definition-RKZ34NQL-C2yf_5WM.js} +1 -1
  359. package/web-shell/assets/{pieDiagram-4H26LBE5-BuEAw3BH.js → pieDiagram-4H26LBE5-DiHABBT-.js} +1 -1
  360. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-Kox_usEq.js → quadrantDiagram-W4KKPZXB-W9xkeAGe.js} +1 -1
  361. package/web-shell/assets/{requirementDiagram-4Y6WPE33-CNjeUif0.js → requirementDiagram-4Y6WPE33-BGmRXl9k.js} +1 -1
  362. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-BCd2OL_U.js → sankeyDiagram-5OEKKPKP-CvOmT43_.js} +1 -1
  363. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-CF2ZTsz0.js → sequenceDiagram-3UESZ5HK-C8pdd0Z-.js} +1 -1
  364. package/web-shell/assets/{stateDiagram-AJRCARHV-qenSzHtm.js → stateDiagram-AJRCARHV-C-CYdFx2.js} +1 -1
  365. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BieEHeN9.js +1 -0
  366. package/web-shell/assets/{timeline-definition-PNZ67QCA-B5DyWdgs.js → timeline-definition-PNZ67QCA-w2KQn1cI.js} +1 -1
  367. package/web-shell/assets/{vennDiagram-CIIHVFJN-DqP4I_o_.js → vennDiagram-CIIHVFJN-DuorhRku.js} +1 -1
  368. package/web-shell/assets/{wardley-L42UT6IY-CJe2e4mg.js → wardley-L42UT6IY-BAXm2cWy.js} +1 -1
  369. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BMDSw-Rr.js → wardleyDiagram-YWT4CUSO-8PHaOXn5.js} +1 -1
  370. package/web-shell/assets/{xychartDiagram-2RQKCTM6-BTVZYkxD.js → xychartDiagram-2RQKCTM6-Do84JFSc.js} +1 -1
  371. package/web-shell/index.html +2 -2
  372. package/chunks/MaxSizedBox-5DPPWPGT.js +0 -85
  373. package/chunks/agent-6ODUANDO.js +0 -81
  374. package/chunks/agent-headless-7BYQTMHW.js +0 -75
  375. package/chunks/bridge-ZUB64FAE.js +0 -90
  376. package/chunks/chunk-LEH5C7FV.js +0 -232
  377. package/chunks/chunk-SZRN75WQ.js +0 -29
  378. package/chunks/chunk-UGYMA4EI.js +0 -219
  379. package/chunks/chunk-Z2BC6UJ5.js +0 -8575
  380. package/chunks/contextCommand-JLHYA34Z.js +0 -80
  381. package/chunks/daemon-status-provider-2233Q37D.js +0 -89
  382. package/chunks/earlyInputCapture-A7NDU3PF.js +0 -82
  383. package/chunks/environment-W5UFC2CH.js +0 -102
  384. package/chunks/errors-M7CLORXH.js +0 -88
  385. package/chunks/exitPlanMode-GXTBWQAR.js +0 -403
  386. package/chunks/handleAutoUpdate-6DBEZYPV.js +0 -81
  387. package/chunks/i18n-VUJJZIMU.js +0 -97
  388. package/chunks/initializer-UWAK5U5O.js +0 -86
  389. package/chunks/installationInfo-6O2YAA52.js +0 -80
  390. package/chunks/list-GB4ESM3T.js +0 -89
  391. package/chunks/loadedSettingsAdapter-OT6JVQ7U.js +0 -83
  392. package/chunks/mcp-6DBDJPFU.js +0 -83
  393. package/chunks/nonInteractiveCli-MOYCYBBU.js +0 -141
  394. package/chunks/pidfile-TFRZZZIO.js +0 -86
  395. package/chunks/read-file-APMO3PSX.js +0 -31
  396. package/chunks/resumeHistoryUtils-6KRYEAWZ.js +0 -91
  397. package/chunks/ripGrep-BEJDEDXW.js +0 -73
  398. package/chunks/runtime-XXRRTNP6.js +0 -118
  399. package/chunks/serve-7BSTXJ4T.js +0 -89
  400. package/chunks/shell-HH3PF3A2.js +0 -83
  401. package/chunks/spawnChannel-RWNDBXGA.js +0 -82
  402. package/chunks/src-GE4TTTML.js +0 -3147
  403. package/chunks/standalone-update-Q6WFRZZQ.js +0 -92
  404. package/chunks/task-create-N7WQSGYA.js +0 -25
  405. package/chunks/theme-manager-SWRILQHI.js +0 -77
  406. package/chunks/total-session-admission-DLHHHLD3.js +0 -84
  407. package/chunks/trustedFolders-KHXHY6PY.js +0 -93
  408. package/chunks/updateCheck-RKL6M5XN.js +0 -92
  409. package/chunks/useAutoAcceptIndicator-CFQ5BUJL.js +0 -93
  410. package/chunks/workspace-providers-status-QSVZUETE.js +0 -86
  411. package/chunks/workspace-registry-UT4RBNBM.js +0 -88
  412. package/chunks/workspace-service-JFWRUS4V.js +0 -98
  413. package/chunks/workspace-skills-status-ZBBKJOI2.js +0 -85
  414. package/chunks/write-file-VHIXW5M7.js +0 -73
  415. package/web-shell/assets/channel-Cq7YKtfC.js +0 -1
  416. package/web-shell/assets/classDiagram-4FO5ZUOK-CQ9aC1Tg.js +0 -1
  417. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CQ9aC1Tg.js +0 -1
  418. package/web-shell/assets/index-D9haPt0X.css +0 -5
  419. package/web-shell/assets/index-ckX9Pq5k.js +0 -1230
  420. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-B7W4zlCr.js +0 -1
  421. package/chunks/{chunk-TARRHLLG.js → chunk-QUGAUQGJ.js} +25 -25
  422. package/chunks/{chunk-U7ZFW55U.js → chunk-VOQXFAY5.js} +977 -977
  423. /package/chunks/{chunk-LXXMOYPL.js → chunk-VXZBKKQR.js} +0 -0
@@ -4,14 +4,15 @@ import {
4
4
  require_follow_redirects,
5
5
  require_form_data,
6
6
  require_proxy_from_env
7
- } from "./chunk-S3TWXGKA.js";
8
- import "./chunk-T2NCM2ET.js";
7
+ } from "./chunk-JE7KQ2UP.js";
8
+ import "./chunk-K6KS3LTN.js";
9
+ import "./chunk-T3CHYWJZ.js";
9
10
  import {
10
11
  ChannelBase,
11
12
  isTerminalTaskLifecycleType,
12
13
  sanitizeLogText,
13
14
  sanitizeSenderName
14
- } from "./chunk-RWTEFFPU.js";
15
+ } from "./chunk-JCJ7LKNA.js";
15
16
  import "./chunk-UDXSXLER.js";
16
17
  import "./chunk-H6XPXXMH.js";
17
18
  import "./chunk-CR3C7WXL.js";
@@ -36,9 +37,9 @@ init_esbuild_shims();
36
37
  // packages/channels/dingtalk/dist/DingtalkAdapter.js
37
38
  init_esbuild_shims();
38
39
  import { mkdirSync, writeFileSync } from "node:fs";
39
- import { randomUUID } from "node:crypto";
40
- import { basename, join } from "node:path";
41
- import { tmpdir } from "node:os";
40
+ import { randomUUID as randomUUID4 } from "node:crypto";
41
+ import { basename as basename2, join } from "node:path";
42
+ import { tmpdir as tmpdir2 } from "node:os";
42
43
  import { Buffer as Buffer2 } from "node:buffer";
43
44
 
44
45
  // node_modules/dingtalk-stream-sdk-nodejs/dist/index.mjs
@@ -47,6 +48,7 @@ init_esbuild_shims();
47
48
  // node_modules/dingtalk-stream-sdk-nodejs/dist/constants.mjs
48
49
  init_esbuild_shims();
49
50
  var TOPIC_ROBOT = "/v1.0/im/bot/messages/get";
51
+ var TOPIC_CARD = "/v1.0/card/instances/callback";
50
52
 
51
53
  // node_modules/dingtalk-stream-sdk-nodejs/dist/client.mjs
52
54
  init_esbuild_shims();
@@ -4460,6 +4462,210 @@ async function downloadMedia(downloadCode, robotCode, accessToken) {
4460
4462
  }
4461
4463
  __name(downloadMedia, "downloadMedia");
4462
4464
 
4465
+ // packages/channels/dingtalk/dist/outbound-image.js
4466
+ init_esbuild_shims();
4467
+ import { closeSync, fstatSync, openSync, readFileSync, readSync, realpathSync } from "node:fs";
4468
+ import { tmpdir } from "node:os";
4469
+ import { basename, extname, isAbsolute, relative } from "node:path";
4470
+ var MEDIA_UPLOAD_API = "https://oapi.dingtalk.com/media/upload";
4471
+ var MEDIA_UPLOAD_TIMEOUT_MS = 3e4;
4472
+ var MAX_IMAGE_BYTES = 20 * 1024 * 1024;
4473
+ var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".gif", ".bmp"]);
4474
+ var AUTH_ERROR_CODES = /* @__PURE__ */ new Set([40014, 42001]);
4475
+ var DingTalkMediaUploadError = class extends Error {
4476
+ static {
4477
+ __name(this, "DingTalkMediaUploadError");
4478
+ }
4479
+ authFailure;
4480
+ constructor(message, authFailure) {
4481
+ super(message);
4482
+ this.authFailure = authFailure;
4483
+ this.name = "DingTalkMediaUploadError";
4484
+ }
4485
+ };
4486
+ function maskCode(text) {
4487
+ const masked = text.split("");
4488
+ const blank = /* @__PURE__ */ __name((start, end) => {
4489
+ for (let i = start; i < end; i++) {
4490
+ if (masked[i] !== "\n")
4491
+ masked[i] = " ";
4492
+ }
4493
+ }, "blank");
4494
+ let offset = 0;
4495
+ while (offset < text.length) {
4496
+ if (text[offset] === "`") {
4497
+ let runLength = 1;
4498
+ while (text[offset + runLength] === "`")
4499
+ runLength++;
4500
+ const delimiter = "`".repeat(runLength);
4501
+ const closing = text.indexOf(delimiter, offset + runLength);
4502
+ const newline = runLength >= 3 ? -1 : text.indexOf("\n", offset + runLength);
4503
+ const closesBeforeNewline = closing !== -1 && (newline === -1 || closing < newline);
4504
+ const end = closesBeforeNewline ? closing + runLength : newline === -1 ? text.length : newline;
4505
+ blank(offset, end);
4506
+ offset = end;
4507
+ continue;
4508
+ }
4509
+ offset++;
4510
+ }
4511
+ return masked.join("");
4512
+ }
4513
+ __name(maskCode, "maskCode");
4514
+ function findImageMarkers(text) {
4515
+ const visibleText = maskCode(text);
4516
+ const markerPattern = /\[IMAGE:\s*([^\]\r\n]+)\]/gi;
4517
+ const markers = [];
4518
+ for (const match of visibleText.matchAll(markerPattern)) {
4519
+ const path = match[1]?.trim();
4520
+ if (!path || match.index === void 0)
4521
+ continue;
4522
+ markers.push({
4523
+ start: match.index,
4524
+ end: match.index + match[0].length,
4525
+ path
4526
+ });
4527
+ }
4528
+ return markers;
4529
+ }
4530
+ __name(findImageMarkers, "findImageMarkers");
4531
+ function replaceImageMarkers(text, markers, replacements) {
4532
+ if (markers.length !== replacements.length) {
4533
+ throw new Error("Image marker replacement count mismatch");
4534
+ }
4535
+ let result = text;
4536
+ for (let i = markers.length - 1; i >= 0; i--) {
4537
+ const marker = markers[i];
4538
+ result = result.slice(0, marker.start) + replacements[i] + result.slice(marker.end);
4539
+ }
4540
+ return result;
4541
+ }
4542
+ __name(replaceImageMarkers, "replaceImageMarkers");
4543
+ function sanitizeStreamingImageMarkers(text) {
4544
+ const markers = findImageMarkers(text);
4545
+ let result = replaceImageMarkers(text, markers, markers.map(() => "[Image pending]"));
4546
+ const visibleText = maskCode(result);
4547
+ const partialMarker = /\[(?:I(?:M(?:A(?:G(?:E(?::[^\]\r\n]*)?)?)?)?)?)?$/i.exec(visibleText);
4548
+ if (partialMarker?.index !== void 0) {
4549
+ result = `${result.slice(0, partialMarker.index)}[Image pending]`;
4550
+ }
4551
+ return result;
4552
+ }
4553
+ __name(sanitizeStreamingImageMarkers, "sanitizeStreamingImageMarkers");
4554
+ function isInside(realPath, directory) {
4555
+ const pathFromDirectory = relative(directory, realPath);
4556
+ return pathFromDirectory === "" || !pathFromDirectory.startsWith("..") && !isAbsolute(pathFromDirectory);
4557
+ }
4558
+ __name(isInside, "isInside");
4559
+ function detectImageMime(data) {
4560
+ if (data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71) {
4561
+ return "image/png";
4562
+ }
4563
+ if (data[0] === 255 && data[1] === 216 && data[2] === 255) {
4564
+ return "image/jpeg";
4565
+ }
4566
+ if (data[0] === 71 && data[1] === 73 && data[2] === 70) {
4567
+ return "image/gif";
4568
+ }
4569
+ if (data[0] === 66 && data[1] === 77) {
4570
+ return "image/bmp";
4571
+ }
4572
+ throw new Error("Unrecognized image format");
4573
+ }
4574
+ __name(detectImageMime, "detectImageMime");
4575
+ function readValidatedImage(imagePath, options) {
4576
+ if (!isAbsolute(imagePath)) {
4577
+ throw new Error(`Image path must be absolute: ${imagePath}`);
4578
+ }
4579
+ const extension = extname(imagePath).toLowerCase();
4580
+ if (!IMAGE_EXTENSIONS.has(extension)) {
4581
+ throw new Error(`Image extension not allowed: ${extension}`);
4582
+ }
4583
+ let realPath;
4584
+ try {
4585
+ realPath = realpathSync(imagePath);
4586
+ } catch {
4587
+ throw new Error(`Image file not found: ${imagePath}`);
4588
+ }
4589
+ const allowedDirectories = [
4590
+ realpathSync(options.workspaceDir),
4591
+ realpathSync(options.temporaryDir ?? tmpdir())
4592
+ ];
4593
+ if (!allowedDirectories.some((directory) => isInside(realPath, directory))) {
4594
+ throw new Error(`Image path outside allowed directories: ${realPath}`);
4595
+ }
4596
+ const descriptor = openSync(realPath, "r");
4597
+ try {
4598
+ const stats = fstatSync(descriptor);
4599
+ if (!stats.isFile()) {
4600
+ throw new Error(`Not a regular file: ${realPath}`);
4601
+ }
4602
+ if (stats.size > MAX_IMAGE_BYTES) {
4603
+ throw new Error(`Image too large: ${stats.size} bytes (max ${MAX_IMAGE_BYTES})`);
4604
+ }
4605
+ const header = Buffer.alloc(16);
4606
+ const bytesRead = readSync(descriptor, header, 0, header.length, 0);
4607
+ const mimeType = detectImageMime(header.subarray(0, bytesRead));
4608
+ const expectedMime = {
4609
+ ".png": "image/png",
4610
+ ".jpg": "image/jpeg",
4611
+ ".jpeg": "image/jpeg",
4612
+ ".gif": "image/gif",
4613
+ ".bmp": "image/bmp"
4614
+ };
4615
+ if (mimeType !== expectedMime[extension]) {
4616
+ throw new Error(`Image type mismatch: ${extension} expects ${expectedMime[extension]} but got ${mimeType}`);
4617
+ }
4618
+ return {
4619
+ data: readFileSync(descriptor),
4620
+ fileName: basename(realPath),
4621
+ mimeType
4622
+ };
4623
+ } finally {
4624
+ closeSync(descriptor);
4625
+ }
4626
+ }
4627
+ __name(readValidatedImage, "readValidatedImage");
4628
+ function sanitizeApiMessage(message, accessToken) {
4629
+ const value = String(message ?? "");
4630
+ return (accessToken ? value.replaceAll(accessToken, "[redacted]") : value).replace(/[\r\n\t]+/g, " ").slice(0, 200);
4631
+ }
4632
+ __name(sanitizeApiMessage, "sanitizeApiMessage");
4633
+ async function uploadDingTalkImage(image, accessToken) {
4634
+ const form = new FormData();
4635
+ form.append("media", new Blob([image.data], { type: image.mimeType }), image.fileName);
4636
+ let response;
4637
+ try {
4638
+ const url2 = new URL(MEDIA_UPLOAD_API);
4639
+ url2.searchParams.set("access_token", accessToken);
4640
+ url2.searchParams.set("type", "image");
4641
+ response = await fetch(url2, {
4642
+ method: "POST",
4643
+ body: form,
4644
+ signal: AbortSignal.timeout(MEDIA_UPLOAD_TIMEOUT_MS)
4645
+ });
4646
+ } catch {
4647
+ throw new DingTalkMediaUploadError("DingTalk media upload failed: network request failed", false);
4648
+ }
4649
+ let payload;
4650
+ try {
4651
+ const parsed = await response.json();
4652
+ payload = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
4653
+ } catch {
4654
+ throw new DingTalkMediaUploadError(`DingTalk media upload failed: HTTP ${response.status} invalid JSON response`, response.status === 401);
4655
+ }
4656
+ const errcode = typeof payload["errcode"] === "number" ? payload["errcode"] : void 0;
4657
+ if (!response.ok || errcode !== void 0 && errcode !== 0) {
4658
+ const detail = sanitizeApiMessage(payload["errmsg"], accessToken);
4659
+ throw new DingTalkMediaUploadError(`DingTalk media upload failed: HTTP ${response.status}${errcode === void 0 ? "" : ` errcode=${errcode}`}${detail ? ` ${detail}` : ""}`, response.status === 401 || errcode !== void 0 && AUTH_ERROR_CODES.has(errcode));
4660
+ }
4661
+ const mediaId = typeof payload["media_id"] === "string" ? payload["media_id"] : typeof payload["mediaId"] === "string" ? payload["mediaId"] : void 0;
4662
+ if (!mediaId) {
4663
+ throw new DingTalkMediaUploadError("DingTalk media upload failed: response did not include a MediaID", false);
4664
+ }
4665
+ return mediaId;
4666
+ }
4667
+ __name(uploadDingTalkImage, "uploadDingTalkImage");
4668
+
4463
4669
  // packages/channels/dingtalk/dist/DingtalkConnectionManager.js
4464
4670
  init_esbuild_shims();
4465
4671
  var SOCKET_OPEN = 1;
@@ -4765,6 +4971,994 @@ var DingtalkConnectionManager = class {
4765
4971
  }
4766
4972
  };
4767
4973
 
4974
+ // packages/channels/dingtalk/dist/interactive-card-client.js
4975
+ init_esbuild_shims();
4976
+ import { randomUUID } from "node:crypto";
4977
+ var STATUS_CARD_TEMPLATE_ID = "675cde2f-f526-40cb-b828-f5b2b57b8b77.schema";
4978
+ var QUESTION_CARD_TEMPLATE_ID = "c2a6355b-9724-4f7e-9653-d33fcb3311bb.schema";
4979
+ var DINGTALK_API = "https://api.dingtalk.com";
4980
+ var CARD_FETCH_TIMEOUT_MS = 1e4;
4981
+ function stringifyCardParamMap(cardParamMap) {
4982
+ return Object.fromEntries(Object.entries(cardParamMap).map(([key, value]) => [
4983
+ key,
4984
+ typeof value === "string" ? value : JSON.stringify(value)
4985
+ ]));
4986
+ }
4987
+ __name(stringifyCardParamMap, "stringifyCardParamMap");
4988
+ var DingtalkInteractiveCardClient = class {
4989
+ static {
4990
+ __name(this, "DingtalkInteractiveCardClient");
4991
+ }
4992
+ options;
4993
+ fetch;
4994
+ constructor(options) {
4995
+ this.options = options;
4996
+ this.fetch = options.fetch ?? globalThis.fetch;
4997
+ }
4998
+ async createAndDeliver(input) {
4999
+ const targetModel = input.target.isGroup ? {
5000
+ imGroupOpenDeliverModel: {
5001
+ robotCode: this.options.robotCode,
5002
+ extension: { dynamicSummary: "true" }
5003
+ }
5004
+ } : {
5005
+ imRobotOpenDeliverModel: {
5006
+ spaceType: "IM_ROBOT",
5007
+ robotCode: this.options.robotCode,
5008
+ extension: { dynamicSummary: "true" }
5009
+ }
5010
+ };
5011
+ const data = await this.request("/v1.0/card/instances/createAndDeliver", "POST", {
5012
+ cardTemplateId: input.templateId,
5013
+ outTrackId: input.outTrackId,
5014
+ cardData: {
5015
+ cardParamMap: stringifyCardParamMap(input.cardParamMap)
5016
+ },
5017
+ callbackType: "STREAM",
5018
+ imGroupOpenSpaceModel: { supportForward: true },
5019
+ imRobotOpenSpaceModel: { supportForward: true },
5020
+ openSpaceId: input.target.isGroup ? `dtv1.card//IM_GROUP.${input.target.chatId}` : `dtv1.card//IM_ROBOT.${input.target.chatId}`,
5021
+ userIdType: 1,
5022
+ ...targetModel
5023
+ }, input.templateId);
5024
+ const result = data && typeof data === "object" ? data.result : void 0;
5025
+ const deliveries = result?.deliverResults;
5026
+ if (Array.isArray(deliveries)) {
5027
+ const failure = deliveries.find((entry) => entry !== null && typeof entry === "object" && entry.success === false);
5028
+ if (failure) {
5029
+ throw new Error(`${input.templateId}: ${typeof failure.errorMsg === "string" && failure.errorMsg.trim() ? failure.errorMsg.trim() : "DingTalk card delivery failed"}`);
5030
+ }
5031
+ }
5032
+ }
5033
+ async openOrUpdateStream(input) {
5034
+ await this.request("/v1.0/card/streaming", "PUT", {
5035
+ outTrackId: input.outTrackId,
5036
+ guid: randomUUID(),
5037
+ key: input.key,
5038
+ content: input.content,
5039
+ isFull: true,
5040
+ isFinalize: input.finalize,
5041
+ isError: input.isError ?? false
5042
+ });
5043
+ }
5044
+ async updateInstance(input) {
5045
+ await this.request("/v1.0/card/instances", "PUT", {
5046
+ outTrackId: input.outTrackId,
5047
+ cardData: {
5048
+ cardParamMap: stringifyCardParamMap(input.cardParamMap)
5049
+ },
5050
+ cardUpdateOptions: { updateCardDataByKey: true }
5051
+ });
5052
+ }
5053
+ async request(path, method, body, templateId) {
5054
+ const token = await this.options.getAccessToken();
5055
+ const response = await this.fetch(`${DINGTALK_API}${path}`, {
5056
+ method,
5057
+ headers: {
5058
+ "Content-Type": "application/json",
5059
+ "x-acs-dingtalk-access-token": token
5060
+ },
5061
+ body: JSON.stringify(body),
5062
+ signal: AbortSignal.timeout(CARD_FETCH_TIMEOUT_MS)
5063
+ });
5064
+ if (!response.ok) {
5065
+ const detail = (await response.text().catch(() => "")).slice(0, 300);
5066
+ throw new Error(`DingTalk Card OpenAPI ${method} ${path} failed${templateId ? ` for ${templateId}` : ""}: HTTP ${response.status}${detail ? ` ${detail}` : ""}`);
5067
+ }
5068
+ return response.json().catch(() => void 0);
5069
+ }
5070
+ };
5071
+
5072
+ // packages/channels/dingtalk/dist/interactive-card-types.js
5073
+ init_esbuild_shims();
5074
+ var DEFAULT_QUESTION_TIMEOUT_MS = 27e4;
5075
+ function asRecord(value) {
5076
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
5077
+ }
5078
+ __name(asRecord, "asRecord");
5079
+ function parseEmbeddedRecord(value) {
5080
+ if (typeof value !== "string") {
5081
+ return asRecord(value);
5082
+ }
5083
+ try {
5084
+ return asRecord(JSON.parse(value));
5085
+ } catch {
5086
+ return void 0;
5087
+ }
5088
+ }
5089
+ __name(parseEmbeddedRecord, "parseEmbeddedRecord");
5090
+ function parseBooleanLike(value) {
5091
+ return value === true || value === "true" || value === 1 || value === "1";
5092
+ }
5093
+ __name(parseBooleanLike, "parseBooleanLike");
5094
+ function optionalBoolean(value, path, fallback) {
5095
+ if (value === void 0)
5096
+ return fallback;
5097
+ if (typeof value !== "boolean") {
5098
+ throw new Error(`DingTalk interactiveCards.${path} must be a boolean.`);
5099
+ }
5100
+ return value;
5101
+ }
5102
+ __name(optionalBoolean, "optionalBoolean");
5103
+ function parseDingtalkInteractiveCardConfig(value) {
5104
+ if (value !== void 0 && !asRecord(value)) {
5105
+ throw new Error("DingTalk interactiveCards must be an object.");
5106
+ }
5107
+ const configured = value !== void 0;
5108
+ const root = asRecord(value) ?? {};
5109
+ const status = asRecord(root["statusCard"]);
5110
+ const question = asRecord(root["questionCard"]);
5111
+ if (root["statusCard"] !== void 0 && !status) {
5112
+ throw new Error("DingTalk interactiveCards.statusCard must be an object.");
5113
+ }
5114
+ if (root["questionCard"] !== void 0 && !question) {
5115
+ throw new Error("DingTalk interactiveCards.questionCard must be an object.");
5116
+ }
5117
+ const timeoutMs = question?.["timeoutMs"] === void 0 ? DEFAULT_QUESTION_TIMEOUT_MS : question["timeoutMs"];
5118
+ if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0) {
5119
+ throw new Error("DingTalk interactiveCards.questionCard.timeoutMs must be a finite positive number.");
5120
+ }
5121
+ return {
5122
+ enabled: optionalBoolean(root["enabled"], "enabled", configured),
5123
+ statusCard: {
5124
+ enabled: optionalBoolean(status?.["enabled"], "statusCard.enabled", true)
5125
+ },
5126
+ questionCard: {
5127
+ enabled: optionalBoolean(question?.["enabled"], "questionCard.enabled", true),
5128
+ timeoutMs
5129
+ }
5130
+ };
5131
+ }
5132
+ __name(parseDingtalkInteractiveCardConfig, "parseDingtalkInteractiveCardConfig");
5133
+ function parseDingtalkCardCallback(value) {
5134
+ const root = parseEmbeddedRecord(value);
5135
+ if (!root)
5136
+ return void 0;
5137
+ const embeddedValue = parseEmbeddedRecord(root["value"]);
5138
+ const embeddedContent = parseEmbeddedRecord(root["content"]);
5139
+ const privateSources = [embeddedValue, embeddedContent, root].map((source) => parseEmbeddedRecord(source?.["cardPrivateData"])).filter((source) => source !== void 0);
5140
+ const sources = [
5141
+ embeddedValue,
5142
+ embeddedContent,
5143
+ ...privateSources,
5144
+ root
5145
+ ].filter((source) => source !== void 0);
5146
+ const pickString = /* @__PURE__ */ __name((...keys) => {
5147
+ for (const source of sources) {
5148
+ for (const key of keys) {
5149
+ const candidate = source[key];
5150
+ if (typeof candidate === "string" && candidate.trim()) {
5151
+ return candidate.trim();
5152
+ }
5153
+ }
5154
+ }
5155
+ return void 0;
5156
+ }, "pickString");
5157
+ const privateData = privateSources[0];
5158
+ const actionIds = privateData?.["actionIds"];
5159
+ const actionId = (Array.isArray(actionIds) && typeof actionIds[0] === "string" && actionIds[0].trim() ? actionIds[0].trim() : void 0) ?? pickString("actionValue", "eventKey", "actionId");
5160
+ const outTrackId = pickString("outTrackId");
5161
+ const actorId = parseDingtalkCardActorId(root);
5162
+ if (!outTrackId || !actionId || !actorId)
5163
+ return void 0;
5164
+ const params = sources.map((source) => parseEmbeddedRecord(source["params"])).find((source) => source !== void 0);
5165
+ const formData = sources.flatMap((source) => [
5166
+ parseEmbeddedRecord(source["formData"]),
5167
+ parseEmbeddedRecord(parseEmbeddedRecord(source["params"])?.["form"])
5168
+ ]).find((source) => source !== void 0);
5169
+ const hasCancelField = params !== void 0 && Object.prototype.hasOwnProperty.call(params, "user_cancel");
5170
+ return {
5171
+ outTrackId,
5172
+ actionId,
5173
+ actorId,
5174
+ formData: formData ?? {},
5175
+ hasBusinessPayload: formData !== void 0 || hasCancelField,
5176
+ isCancel: hasCancelField && parseBooleanLike(params["user_cancel"])
5177
+ };
5178
+ }
5179
+ __name(parseDingtalkCardCallback, "parseDingtalkCardCallback");
5180
+ function parseDingtalkCardActorId(value) {
5181
+ const root = parseEmbeddedRecord(value);
5182
+ if (!root)
5183
+ return void 0;
5184
+ return ["userId", "senderStaffId", "senderId"].map((key) => root[key]).find((candidate) => typeof candidate === "string" && candidate.trim().length > 0)?.trim();
5185
+ }
5186
+ __name(parseDingtalkCardActorId, "parseDingtalkCardActorId");
5187
+
5188
+ // packages/channels/dingtalk/dist/status-card-controller.js
5189
+ init_esbuild_shims();
5190
+ import { randomUUID as randomUUID2 } from "node:crypto";
5191
+ var FLUSH_INTERVAL_MS = 500;
5192
+ var CONTENT_LIMIT = 2e4;
5193
+ var TRUNCATION_MARKER = "[Earlier output truncated]\n";
5194
+ function boundContent(content) {
5195
+ if (content.length <= CONTENT_LIMIT)
5196
+ return content;
5197
+ return `${TRUNCATION_MARKER}${content.slice(content.length - (CONTENT_LIMIT - TRUNCATION_MARKER.length))}`;
5198
+ }
5199
+ __name(boundContent, "boundContent");
5200
+ var StatusCardController = class {
5201
+ static {
5202
+ __name(this, "StatusCardController");
5203
+ }
5204
+ options;
5205
+ recordsBySegment = /* @__PURE__ */ new Map();
5206
+ recordsByOutTrack = /* @__PURE__ */ new Map();
5207
+ segmentIdsByRun = /* @__PURE__ */ new Map();
5208
+ terminalSegmentIds = /* @__PURE__ */ new Set();
5209
+ constructor(options) {
5210
+ this.options = options;
5211
+ }
5212
+ append(segment, target, chunk) {
5213
+ if (!chunk || this.terminalSegmentIds.has(segment.segmentId))
5214
+ return;
5215
+ let record = this.recordsBySegment.get(segment.segmentId);
5216
+ if (!record) {
5217
+ record = this.createRecord(segment, target);
5218
+ }
5219
+ if (record.terminal)
5220
+ return;
5221
+ record.content = boundContent(record.content + chunk);
5222
+ if (record.streamFailed)
5223
+ return;
5224
+ record.pendingSnapshot = sanitizeStreamingImageMarkers(record.content);
5225
+ this.scheduleFlush(record);
5226
+ }
5227
+ createRecord(segment, target) {
5228
+ const outTrackId = `qwen-status-${randomUUID2()}`;
5229
+ const record = {
5230
+ segmentId: segment.segmentId,
5231
+ runId: segment.runId,
5232
+ sessionId: segment.sessionId,
5233
+ ownerId: segment.owner.id,
5234
+ target,
5235
+ outTrackId,
5236
+ content: "",
5237
+ startedAt: Date.now(),
5238
+ lastStatusSecond: 0,
5239
+ ready: Promise.resolve(false),
5240
+ terminal: false,
5241
+ streamFailed: false,
5242
+ stopClaimed: false,
5243
+ forbiddenActors: /* @__PURE__ */ new Set(),
5244
+ lastWriteAt: Date.now(),
5245
+ writeChain: Promise.resolve()
5246
+ };
5247
+ this.recordsBySegment.set(record.segmentId, record);
5248
+ this.recordsByOutTrack.set(outTrackId, record);
5249
+ const segmentIds = this.segmentIdsByRun.get(record.runId) ?? /* @__PURE__ */ new Set();
5250
+ segmentIds.add(record.segmentId);
5251
+ this.segmentIdsByRun.set(record.runId, segmentIds);
5252
+ record.ready = this.create(record, target);
5253
+ return record;
5254
+ }
5255
+ complete(segmentId, text) {
5256
+ return this.finalize(segmentId, boundContent(text), "Completed", false);
5257
+ }
5258
+ fail(segmentId, error) {
5259
+ void this.finalize(segmentId, boundContent(error), "Failed", true);
5260
+ }
5261
+ cancelRun(runId, reason) {
5262
+ for (const segmentId of [...this.segmentIdsByRun.get(runId) ?? []]) {
5263
+ const record = this.recordsBySegment.get(segmentId);
5264
+ if (!record)
5265
+ continue;
5266
+ void this.finalize(segmentId, sanitizeStreamingImageMarkers(record.content), reason === "cancel_command" ? "Stopped" : "Cancelled", false);
5267
+ }
5268
+ }
5269
+ claimStop(outTrackId, actorId) {
5270
+ const record = this.recordsByOutTrack.get(outTrackId);
5271
+ if (!record || record.terminal || record.stopClaimed) {
5272
+ return { kind: "ignored", actorId };
5273
+ }
5274
+ if (record.ownerId !== actorId) {
5275
+ if (record.forbiddenActors.has(actorId)) {
5276
+ return { kind: "ignored" };
5277
+ }
5278
+ record.forbiddenActors.add(actorId);
5279
+ return { kind: "forbidden", actorId, target: record.target };
5280
+ }
5281
+ record.stopClaimed = true;
5282
+ return {
5283
+ kind: "accepted",
5284
+ execute: /* @__PURE__ */ __name(async () => {
5285
+ const cancelled = await this.options.cancelRun(record.sessionId, record.runId);
5286
+ if (this.recordsByOutTrack.get(outTrackId) !== record || record.terminal) {
5287
+ return;
5288
+ }
5289
+ if (!cancelled) {
5290
+ record.stopClaimed = false;
5291
+ return;
5292
+ }
5293
+ this.cancelRun(record.runId, "cancel_command");
5294
+ }, "execute")
5295
+ };
5296
+ }
5297
+ async create(record, target) {
5298
+ try {
5299
+ await this.options.client.createAndDeliver({
5300
+ templateId: STATUS_CARD_TEMPLATE_ID,
5301
+ outTrackId: record.outTrackId,
5302
+ target,
5303
+ cardParamMap: {
5304
+ content: "",
5305
+ flowStatus: 2,
5306
+ statusLine: this.statusLine(record, "Running").text,
5307
+ hasAction: "true",
5308
+ stop_action: "true"
5309
+ }
5310
+ });
5311
+ await this.options.client.openOrUpdateStream({
5312
+ outTrackId: record.outTrackId,
5313
+ key: "content",
5314
+ content: "",
5315
+ finalize: false
5316
+ });
5317
+ return true;
5318
+ } catch (error) {
5319
+ this.options.onError?.("status card creation", error);
5320
+ await this.options.client.updateInstance({
5321
+ outTrackId: record.outTrackId,
5322
+ cardParamMap: {
5323
+ flowStatus: 3,
5324
+ statusLine: "Unavailable",
5325
+ hasAction: "false",
5326
+ stop_action: "false"
5327
+ }
5328
+ }).catch(() => {
5329
+ });
5330
+ return false;
5331
+ }
5332
+ }
5333
+ scheduleFlush(record) {
5334
+ if (record.flushTimer || record.inFlight || record.terminal)
5335
+ return;
5336
+ const delay = Math.max(0, FLUSH_INTERVAL_MS - (Date.now() - record.lastWriteAt));
5337
+ record.flushTimer = setTimeout(() => {
5338
+ record.flushTimer = void 0;
5339
+ this.flush(record);
5340
+ }, delay);
5341
+ }
5342
+ flush(record) {
5343
+ if (record.terminal || record.inFlight || record.pendingSnapshot === void 0)
5344
+ return;
5345
+ const content = record.pendingSnapshot;
5346
+ record.pendingSnapshot = void 0;
5347
+ const write = record.writeChain.then(async () => {
5348
+ const ready = await record.ready;
5349
+ if (!ready || record.terminal)
5350
+ return;
5351
+ await this.options.client.openOrUpdateStream({
5352
+ outTrackId: record.outTrackId,
5353
+ key: "content",
5354
+ content,
5355
+ finalize: false
5356
+ });
5357
+ await this.updateRunningStatus(record);
5358
+ }).catch((error) => {
5359
+ record.streamFailed = true;
5360
+ record.pendingSnapshot = void 0;
5361
+ this.options.onError?.("status card streaming", error);
5362
+ });
5363
+ const tracked = write.finally(() => {
5364
+ if (record.inFlight === tracked) {
5365
+ record.inFlight = void 0;
5366
+ }
5367
+ record.lastWriteAt = Date.now();
5368
+ if (record.pendingSnapshot !== void 0)
5369
+ this.scheduleFlush(record);
5370
+ });
5371
+ record.inFlight = tracked;
5372
+ record.writeChain = tracked;
5373
+ }
5374
+ async finalize(segmentId, content, state, isError) {
5375
+ const record = this.recordsBySegment.get(segmentId);
5376
+ if (!record || record.terminal)
5377
+ return false;
5378
+ record.terminal = true;
5379
+ this.terminalSegmentIds.add(segmentId);
5380
+ while (this.terminalSegmentIds.size > 1e3) {
5381
+ const oldest = this.terminalSegmentIds.values().next().value;
5382
+ if (oldest === void 0)
5383
+ break;
5384
+ this.terminalSegmentIds.delete(oldest);
5385
+ }
5386
+ if (record.flushTimer)
5387
+ clearTimeout(record.flushTimer);
5388
+ record.flushTimer = void 0;
5389
+ record.pendingSnapshot = void 0;
5390
+ try {
5391
+ if (!await record.ready)
5392
+ return false;
5393
+ await record.writeChain;
5394
+ const finalContent = boundContent(sanitizeStreamingImageMarkers(content || record.content));
5395
+ await this.options.client.openOrUpdateStream({
5396
+ outTrackId: record.outTrackId,
5397
+ key: "content",
5398
+ content: "",
5399
+ finalize: true,
5400
+ isError
5401
+ });
5402
+ await this.options.client.updateInstance({
5403
+ outTrackId: record.outTrackId,
5404
+ cardParamMap: {
5405
+ blockList: JSON.stringify([
5406
+ {
5407
+ type: 0,
5408
+ markdown: finalContent
5409
+ }
5410
+ ]),
5411
+ content: finalContent,
5412
+ copy_content: finalContent,
5413
+ flowStatus: 3,
5414
+ statusLine: this.statusLine(record, state).text,
5415
+ hasAction: "false",
5416
+ stop_action: "false"
5417
+ }
5418
+ });
5419
+ record.content = "";
5420
+ return true;
5421
+ } catch (error) {
5422
+ this.options.onError?.("status card finalization", error);
5423
+ return false;
5424
+ } finally {
5425
+ if (this.recordsBySegment.get(segmentId) === record) {
5426
+ this.recordsBySegment.delete(segmentId);
5427
+ }
5428
+ if (this.recordsByOutTrack.get(record.outTrackId) === record) {
5429
+ this.recordsByOutTrack.delete(record.outTrackId);
5430
+ }
5431
+ const segmentIds = this.segmentIdsByRun.get(record.runId);
5432
+ segmentIds?.delete(segmentId);
5433
+ if (segmentIds?.size === 0) {
5434
+ this.segmentIdsByRun.delete(record.runId);
5435
+ }
5436
+ }
5437
+ }
5438
+ statusLine(record, state) {
5439
+ const second = Math.max(0, Math.floor((Date.now() - record.startedAt) / 1e3));
5440
+ const model = this.options.model?.trim();
5441
+ return {
5442
+ text: [state, model, `${second}s`].filter(Boolean).join(" \xB7 "),
5443
+ second
5444
+ };
5445
+ }
5446
+ async updateRunningStatus(record) {
5447
+ if (record.terminal)
5448
+ return;
5449
+ const status = this.statusLine(record, "Running");
5450
+ if (status.second === record.lastStatusSecond)
5451
+ return;
5452
+ try {
5453
+ await this.options.client.updateInstance({
5454
+ outTrackId: record.outTrackId,
5455
+ cardParamMap: { statusLine: status.text }
5456
+ });
5457
+ record.lastStatusSecond = status.second;
5458
+ } catch (error) {
5459
+ this.options.onError?.("status card metadata", error);
5460
+ }
5461
+ }
5462
+ };
5463
+
5464
+ // packages/channels/dingtalk/dist/question-card-controller.js
5465
+ init_esbuild_shims();
5466
+ import { randomUUID as randomUUID3 } from "node:crypto";
5467
+ var OTHER_OPTION_VALUE = "__qwen_other__";
5468
+ var QuestionCardController = class {
5469
+ static {
5470
+ __name(this, "QuestionCardController");
5471
+ }
5472
+ options;
5473
+ byRequest = /* @__PURE__ */ new Map();
5474
+ byOutTrack = /* @__PURE__ */ new Map();
5475
+ activeByScope = /* @__PURE__ */ new Map();
5476
+ pendingByRun = /* @__PURE__ */ new Map();
5477
+ nextSequence = 0;
5478
+ constructor(options) {
5479
+ this.options = options;
5480
+ }
5481
+ async present(context, target) {
5482
+ const scopeKey = this.scopeKey(context);
5483
+ const active = this.activeByScope.get(scopeKey);
5484
+ if (active?.state === "reserved" || active?.state === "pending") {
5485
+ if (active.context.runId === context.runId) {
5486
+ return { kind: "unsupported" };
5487
+ }
5488
+ if (active.state === "pending")
5489
+ this.reserveTerminalProjection(active);
5490
+ void this.finalize(active, "expired", "A newer question is available. Answer the latest card.");
5491
+ }
5492
+ const record = {
5493
+ context,
5494
+ target,
5495
+ outTrackId: `qwen-question-${randomUUID3()}`,
5496
+ scopeKey,
5497
+ sequence: this.nextSequence++,
5498
+ state: "reserved",
5499
+ delivered: false,
5500
+ forbiddenActors: /* @__PURE__ */ new Set()
5501
+ };
5502
+ this.byRequest.set(context.requestId, record);
5503
+ this.byOutTrack.set(record.outTrackId, record);
5504
+ this.activeByScope.set(record.scopeKey, record);
5505
+ const unsubscribe = context.onSettled((reason) => {
5506
+ if (record.state === "claimed")
5507
+ return;
5508
+ if (record.state === "pending")
5509
+ this.reserveTerminalProjection(record);
5510
+ void this.finalize(record, reason === "resolved_outside_presenter" ? "resolved_outside_presenter" : "cancelled");
5511
+ });
5512
+ record.unsubscribe = unsubscribe;
5513
+ if (record.state === "terminal")
5514
+ unsubscribe();
5515
+ try {
5516
+ await this.options.client.createAndDeliver({
5517
+ templateId: QUESTION_CARD_TEMPLATE_ID,
5518
+ outTrackId: record.outTrackId,
5519
+ target,
5520
+ cardParamMap: this.cardData(context)
5521
+ });
5522
+ record.delivered = true;
5523
+ } catch (error) {
5524
+ this.options.onError?.("question card creation", error);
5525
+ if (record.state === "terminal") {
5526
+ return { kind: "presented" };
5527
+ }
5528
+ await this.finalize(record, "cancelled");
5529
+ try {
5530
+ await this.options.sendFallback(context.target.chatId, this.fallbackText(context));
5531
+ } catch (fallbackError) {
5532
+ this.options.onError?.("question fallback delivery", fallbackError);
5533
+ }
5534
+ await context.respond({ outcome: { outcome: "cancelled" } });
5535
+ return { kind: "handled" };
5536
+ }
5537
+ if (record.state !== "reserved") {
5538
+ await this.projectTerminal(record);
5539
+ return { kind: "presented" };
5540
+ }
5541
+ const latest = this.activeByScope.get(record.scopeKey);
5542
+ if (latest && latest.sequence > record.sequence) {
5543
+ await this.finalize(record, "expired", "A newer question is available. Answer the latest card.");
5544
+ return { kind: "presented" };
5545
+ }
5546
+ record.state = "pending";
5547
+ this.activeByScope.set(record.scopeKey, record);
5548
+ const pending = this.pendingByRun.get(context.runId) ?? /* @__PURE__ */ new Set();
5549
+ pending.add(context.requestId);
5550
+ this.pendingByRun.set(context.runId, pending);
5551
+ record.timer = setTimeout(() => {
5552
+ void this.expire(record);
5553
+ }, this.options.timeoutMs);
5554
+ record.timer.unref?.();
5555
+ return { kind: "presented" };
5556
+ }
5557
+ claim(callback) {
5558
+ const record = this.byOutTrack.get(callback.outTrackId);
5559
+ if (!record || record.state !== "pending") {
5560
+ return { kind: "ignored", actorId: callback.actorId };
5561
+ }
5562
+ if (record.context.owner.id !== callback.actorId) {
5563
+ if (record.forbiddenActors.has(callback.actorId)) {
5564
+ return { kind: "ignored" };
5565
+ }
5566
+ record.forbiddenActors.add(callback.actorId);
5567
+ return {
5568
+ kind: "forbidden",
5569
+ actorId: callback.actorId,
5570
+ target: record.target
5571
+ };
5572
+ }
5573
+ if (callback.hasBusinessPayload === false) {
5574
+ return { kind: "ignored", actorId: callback.actorId };
5575
+ }
5576
+ if (callback.isCancel || callback.actionId === "cancel") {
5577
+ this.reserveTerminalProjection(record);
5578
+ record.state = "claimed";
5579
+ return {
5580
+ kind: "accepted",
5581
+ execute: /* @__PURE__ */ __name(() => this.respond(record, "cancelled"), "execute")
5582
+ };
5583
+ }
5584
+ if (callback.actionId !== "submit" && callback.actionId !== record.context.requestId) {
5585
+ return { kind: "ignored", actorId: callback.actorId };
5586
+ }
5587
+ const answers = this.parseAnswers(record, callback.formData);
5588
+ if (!answers)
5589
+ return { kind: "ignored", actorId: callback.actorId };
5590
+ this.reserveTerminalProjection(record);
5591
+ record.state = "claimed";
5592
+ return {
5593
+ kind: "accepted",
5594
+ execute: /* @__PURE__ */ __name(() => this.respond(record, "submitted", answers), "execute")
5595
+ };
5596
+ }
5597
+ cancelRun(runId, terminalState = "cancelled") {
5598
+ const requestIds = [...this.pendingByRun.get(runId) ?? []];
5599
+ for (const requestId of requestIds) {
5600
+ const record = this.byRequest.get(requestId);
5601
+ if (record) {
5602
+ this.reserveTerminalProjection(record);
5603
+ void this.finalize(record, terminalState, terminalState === "expired" ? "This question is no longer available." : void 0);
5604
+ }
5605
+ }
5606
+ }
5607
+ async respond(record, terminalState, answers) {
5608
+ try {
5609
+ const accepted = await record.context.respond(terminalState === "submitted" ? {
5610
+ outcome: {
5611
+ outcome: "selected",
5612
+ optionId: record.context.submitOptionId
5613
+ },
5614
+ answers
5615
+ } : { outcome: { outcome: "cancelled" } });
5616
+ await this.finalize(record, accepted ? terminalState : "expired", accepted ? void 0 : "This question is no longer available.");
5617
+ } catch (error) {
5618
+ this.options.onError?.("question response", error);
5619
+ await this.finalize(record, "expired", "This question is no longer available.");
5620
+ }
5621
+ }
5622
+ async expire(record) {
5623
+ if (record.state !== "pending")
5624
+ return;
5625
+ this.reserveTerminalProjection(record);
5626
+ await this.finalize(record, "expired");
5627
+ try {
5628
+ await record.context.respond({ outcome: { outcome: "cancelled" } });
5629
+ } catch (error) {
5630
+ this.options.onError?.("expired question cancellation", error);
5631
+ }
5632
+ }
5633
+ async finalize(record, state, description) {
5634
+ if (record.state === "terminal")
5635
+ return;
5636
+ record.state = "terminal";
5637
+ record.terminalState = state;
5638
+ record.terminalDescription = description;
5639
+ if (record.timer)
5640
+ clearTimeout(record.timer);
5641
+ record.timer = void 0;
5642
+ record.unsubscribe?.();
5643
+ record.unsubscribe = void 0;
5644
+ this.byRequest.delete(record.context.requestId);
5645
+ this.byOutTrack.delete(record.outTrackId);
5646
+ if (this.activeByScope.get(record.scopeKey) === record) {
5647
+ this.activeByScope.delete(record.scopeKey);
5648
+ }
5649
+ const pending = this.pendingByRun.get(record.context.runId);
5650
+ pending?.delete(record.context.requestId);
5651
+ if (pending?.size === 0)
5652
+ this.pendingByRun.delete(record.context.runId);
5653
+ if (record.delivered) {
5654
+ const finishTerminalProjection = record.finishTerminalProjection;
5655
+ record.finishTerminalProjection = void 0;
5656
+ if (finishTerminalProjection) {
5657
+ await finishTerminalProjection(() => this.projectTerminal(record));
5658
+ } else {
5659
+ await this.projectTerminal(record);
5660
+ }
5661
+ }
5662
+ }
5663
+ reserveTerminalProjection(record) {
5664
+ record.finishTerminalProjection ??= this.options.reserveRunProjection?.(record.context.runId);
5665
+ }
5666
+ async projectTerminal(record) {
5667
+ if (!record.terminalState)
5668
+ return;
5669
+ const cardParamMap = {
5670
+ submitted: {
5671
+ card_status: "submitted",
5672
+ question_desc: "Submitted.",
5673
+ form_btn_text: "Submitted"
5674
+ },
5675
+ expired: {
5676
+ card_status: "expired",
5677
+ question_desc: "This question expired. Please retry.",
5678
+ form_btn_text: "Expired"
5679
+ },
5680
+ resolved_outside_presenter: {
5681
+ card_status: "expired",
5682
+ question_desc: "Resolved outside this card.",
5683
+ form_btn_text: "Expired"
5684
+ },
5685
+ cancelled: {
5686
+ card_status: "cancelled",
5687
+ question_desc: "Cancelled.",
5688
+ form_btn_text: "Cancelled"
5689
+ }
5690
+ };
5691
+ try {
5692
+ await this.options.client.updateInstance({
5693
+ outTrackId: record.outTrackId,
5694
+ cardParamMap: {
5695
+ ...cardParamMap[record.terminalState],
5696
+ ...record.terminalDescription ? { question_desc: record.terminalDescription } : {}
5697
+ }
5698
+ });
5699
+ } catch (error) {
5700
+ this.options.onError?.("question card finalization", error);
5701
+ }
5702
+ }
5703
+ parseAnswers(record, formData) {
5704
+ const allowed = new Set(record.context.questions.flatMap((question) => [
5705
+ question.answerKey,
5706
+ this.otherAnswerKey(question.answerKey)
5707
+ ]));
5708
+ if (Object.keys(formData).some((key) => !allowed.has(key))) {
5709
+ return void 0;
5710
+ }
5711
+ const answers = {};
5712
+ for (const question of record.context.questions) {
5713
+ const values = this.readAnswerValues(formData[question.answerKey]);
5714
+ if (values.length === 0 || !question.multiSelect && values.length !== 1)
5715
+ return void 0;
5716
+ const optionLabels = new Set(question.options.map((option) => option.label));
5717
+ const customValue = this.readAnswerValues(formData[this.otherAnswerKey(question.answerKey)])[0]?.trim();
5718
+ const normalized = [];
5719
+ for (const value of values) {
5720
+ if (value === OTHER_OPTION_VALUE) {
5721
+ if (!customValue)
5722
+ return void 0;
5723
+ normalized.push(customValue);
5724
+ } else if (optionLabels.has(value)) {
5725
+ normalized.push(value);
5726
+ } else {
5727
+ return void 0;
5728
+ }
5729
+ }
5730
+ answers[question.answerKey] = normalized.join(", ");
5731
+ }
5732
+ return answers;
5733
+ }
5734
+ readAnswerValues(value) {
5735
+ if (typeof value === "string")
5736
+ return value.trim() ? [value.trim()] : [];
5737
+ if (Array.isArray(value)) {
5738
+ return value.filter((item) => typeof item === "string").map((item) => item.trim()).filter(Boolean);
5739
+ }
5740
+ if (value !== null && typeof value === "object") {
5741
+ return this.readAnswerValues(value["value"]);
5742
+ }
5743
+ return [];
5744
+ }
5745
+ otherAnswerKey(answerKey) {
5746
+ return `${answerKey}_other`;
5747
+ }
5748
+ scopeKey(context) {
5749
+ return `${context.sessionId}\0${context.owner.id}`;
5750
+ }
5751
+ cardData(context) {
5752
+ const first = context.questions[0];
5753
+ return {
5754
+ question_id: context.requestId,
5755
+ question_title: first.header,
5756
+ question_desc: first.question,
5757
+ card_status: "pending",
5758
+ form_btn_text: "Submit",
5759
+ selected_text: "",
5760
+ selected_values: "[]",
5761
+ form: {
5762
+ fields: context.questions.flatMap((question) => [
5763
+ {
5764
+ name: question.answerKey,
5765
+ label: question.question,
5766
+ type: question.multiSelect ? "MULTI_CHECKBOX_GROUP" : "CHECKBOX_GROUP",
5767
+ required: true,
5768
+ options: [
5769
+ ...question.options.map((option) => ({
5770
+ value: option.label,
5771
+ text: option.label
5772
+ })),
5773
+ { value: OTHER_OPTION_VALUE, text: "Other" }
5774
+ ]
5775
+ },
5776
+ {
5777
+ name: this.otherAnswerKey(question.answerKey),
5778
+ label: `${question.header}: Other`,
5779
+ type: "TEXT",
5780
+ required: false,
5781
+ placeholder: "Enter a custom answer when Other is selected"
5782
+ }
5783
+ ])
5784
+ }
5785
+ };
5786
+ }
5787
+ fallbackText(context) {
5788
+ const questions = context.questions.map((question) => `- ${question.question}: ${question.options.map((option) => option.label).join(", ")}`).join("\n");
5789
+ return `The interactive question could not be delivered, so this request was cancelled. Please retry.
5790
+ ${questions}`;
5791
+ }
5792
+ };
5793
+
5794
+ // packages/channels/dingtalk/dist/interaction-presenter.js
5795
+ init_esbuild_shims();
5796
+ var DingtalkInteractionPresenter = class {
5797
+ static {
5798
+ __name(this, "DingtalkInteractionPresenter");
5799
+ }
5800
+ options;
5801
+ runs = /* @__PURE__ */ new Map();
5802
+ segments = /* @__PURE__ */ new Map();
5803
+ terminalSegmentIds = /* @__PURE__ */ new Set();
5804
+ constructor(options) {
5805
+ this.options = options;
5806
+ }
5807
+ registerRun(runId, ownerId, target) {
5808
+ this.runs.set(runId, {
5809
+ ownerId,
5810
+ target,
5811
+ projectionChain: Promise.resolve(),
5812
+ terminal: false
5813
+ });
5814
+ }
5815
+ appendOutput(segment, chunk) {
5816
+ const run = this.runs.get(segment.runId);
5817
+ if (!run || run.terminal || run.ownerId !== segment.owner.id || run.target.chatId !== segment.target.chatId || run.target.isGroup !== segment.target.isGroup || !chunk || this.terminalSegmentIds.has(segment.segmentId)) {
5818
+ return;
5819
+ }
5820
+ const existing = this.segments.get(segment.segmentId);
5821
+ if (existing && existing.run !== run)
5822
+ return;
5823
+ const presentation = existing ?? {
5824
+ run,
5825
+ context: segment,
5826
+ content: ""
5827
+ };
5828
+ presentation.content = this.boundContent(presentation.content + chunk);
5829
+ this.segments.set(segment.segmentId, presentation);
5830
+ run.activeSegmentId = segment.segmentId;
5831
+ if (!this.options.statusCards)
5832
+ return;
5833
+ void this.enqueue(run, () => {
5834
+ this.options.statusCards?.append(segment, this.cardTarget(segment.target), chunk);
5835
+ });
5836
+ }
5837
+ closeOutput(segmentId, text, reason, segment) {
5838
+ let presentation = this.segments.get(segmentId);
5839
+ if (!presentation && segment && text) {
5840
+ this.appendOutput(segment, text);
5841
+ presentation = this.segments.get(segmentId);
5842
+ }
5843
+ if (!presentation)
5844
+ return Promise.resolve(false);
5845
+ const run = presentation.run;
5846
+ if (run.terminal)
5847
+ return Promise.resolve(false);
5848
+ this.segments.delete(segmentId);
5849
+ this.addTerminalSegment(segmentId);
5850
+ if (run.activeSegmentId === segmentId) {
5851
+ run.activeSegmentId = void 0;
5852
+ }
5853
+ return this.enqueue(run, async () => {
5854
+ const statusCards = this.options.statusCards;
5855
+ if (reason === "failed") {
5856
+ statusCards?.fail(segmentId, text);
5857
+ return statusCards !== void 0;
5858
+ }
5859
+ if (reason === "cancelled") {
5860
+ return statusCards !== void 0;
5861
+ }
5862
+ const completed = statusCards !== void 0 && await statusCards.complete(segmentId, text);
5863
+ if (completed)
5864
+ return true;
5865
+ const fallbackText = text || presentation.content;
5866
+ if (!fallbackText || !this.options.sendFallback)
5867
+ return false;
5868
+ await this.options.sendFallback(presentation.context.target.chatId, fallbackText, presentation.context.sessionId);
5869
+ return true;
5870
+ });
5871
+ }
5872
+ presentInput(context) {
5873
+ const run = this.runs.get(context.runId);
5874
+ if (!run || run.terminal || run.ownerId !== context.owner.id || run.target.chatId !== context.target.chatId || run.target.isGroup !== context.target.isGroup) {
5875
+ return Promise.resolve({ kind: "unsupported" });
5876
+ }
5877
+ const questionCards = this.options.questionCards;
5878
+ if (!questionCards)
5879
+ return Promise.resolve({ kind: "unsupported" });
5880
+ return questionCards.present(context, this.cardTarget(context.target));
5881
+ }
5882
+ terminalizeRun(runId, terminal, detail = "") {
5883
+ const run = this.runs.get(runId);
5884
+ if (!run || run.terminal)
5885
+ return;
5886
+ this.options.questionCards?.cancelRun(runId, terminal === "cancelled" && (detail === "cancel_command" || detail === "clear") ? "cancelled" : "expired");
5887
+ run.terminal = true;
5888
+ const activeSegmentId = run.activeSegmentId;
5889
+ run.activeSegmentId = void 0;
5890
+ if (activeSegmentId) {
5891
+ this.segments.delete(activeSegmentId);
5892
+ this.addTerminalSegment(activeSegmentId);
5893
+ }
5894
+ const finalization = this.enqueue(run, async () => {
5895
+ if (terminal === "failed" && activeSegmentId) {
5896
+ this.options.statusCards?.fail(activeSegmentId, detail);
5897
+ } else if (terminal === "cancelled") {
5898
+ this.options.statusCards?.cancelRun(runId, detail === "cancel_command" ? "cancel_command" : "dropped");
5899
+ } else if (activeSegmentId) {
5900
+ await this.options.statusCards?.complete(activeSegmentId, detail);
5901
+ }
5902
+ });
5903
+ void finalization.then(() => {
5904
+ if (this.runs.get(runId) === run)
5905
+ this.runs.delete(runId);
5906
+ }, () => {
5907
+ if (this.runs.get(runId) === run)
5908
+ this.runs.delete(runId);
5909
+ });
5910
+ }
5911
+ reserveProjection(runId) {
5912
+ const run = this.runs.get(runId);
5913
+ if (!run || run.terminal)
5914
+ return void 0;
5915
+ let supplyOperation;
5916
+ const operation = new Promise((resolve) => {
5917
+ supplyOperation = resolve;
5918
+ });
5919
+ const result = this.enqueue(run, async () => {
5920
+ const execute = await operation;
5921
+ await execute();
5922
+ });
5923
+ let supplied = false;
5924
+ return (execute) => {
5925
+ if (!supplied) {
5926
+ supplied = true;
5927
+ supplyOperation(execute);
5928
+ }
5929
+ return result;
5930
+ };
5931
+ }
5932
+ enqueue(run, operation) {
5933
+ const result = run.projectionChain.then(operation);
5934
+ run.projectionChain = result.then(() => void 0, () => void 0);
5935
+ return result;
5936
+ }
5937
+ boundContent(content) {
5938
+ const limit = 2e4;
5939
+ const marker = "[Earlier output truncated]\n";
5940
+ if (content.length <= limit)
5941
+ return content;
5942
+ return `${marker}${content.slice(content.length - (limit - marker.length))}`;
5943
+ }
5944
+ cardTarget(target) {
5945
+ const isGroup = target.isGroup === true;
5946
+ return {
5947
+ chatId: isGroup ? target.chatId : target.senderId,
5948
+ isGroup
5949
+ };
5950
+ }
5951
+ addTerminalSegment(segmentId) {
5952
+ this.terminalSegmentIds.add(segmentId);
5953
+ while (this.terminalSegmentIds.size > 1e3) {
5954
+ const oldest = this.terminalSegmentIds.values().next().value;
5955
+ if (oldest === void 0)
5956
+ break;
5957
+ this.terminalSegmentIds.delete(oldest);
5958
+ }
5959
+ }
5960
+ };
5961
+
4768
5962
  // packages/channels/dingtalk/dist/DingtalkAdapter.js
4769
5963
  var DEDUP_TTL_MS = 5 * 60 * 1e3;
4770
5964
  var ACK_REACTION_NAME = "\u{1F440}";
@@ -4780,6 +5974,15 @@ var TOKEN_API = "https://oapi.dingtalk.com/gettoken";
4780
5974
  var PROACTIVE_FETCH_TIMEOUT_MS = 15e3;
4781
5975
  var TEXT_MESSAGE_LIMIT = 3800;
4782
5976
  var mentionTarget = Symbol("mentionTarget");
5977
+ var IMAGE_INSTRUCTIONS = [
5978
+ "",
5979
+ "If you created an image file (screenshot, chart, etc.), you can send it to the user by writing:",
5980
+ "`[IMAGE: /absolute/path/to/file.png]` (without the backticks)",
5981
+ "",
5982
+ "The marker is stripped from text and the image is uploaded automatically.",
5983
+ "",
5984
+ "Only use a real image file inside the workspace or system temporary directory."
5985
+ ].join("\n");
4783
5986
  function withNonBotMentionContext(data, text) {
4784
5987
  if (!Array.isArray(data.atUsers) || typeof data.chatbotUserId !== "string") {
4785
5988
  return text;
@@ -4848,9 +6051,28 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
4848
6051
  * on (re)connect, so a long-lived socket serves a stale one after ~2h.
4849
6052
  */
4850
6053
  proactiveToken;
6054
+ interactiveCardConfig;
6055
+ interactiveCardClient;
6056
+ statusCardController;
6057
+ questionCardController;
6058
+ interactionPresenter;
6059
+ inboundCardOwners = /* @__PURE__ */ new Map();
6060
+ cardRunBySession = /* @__PURE__ */ new Map();
6061
+ cardRuns = /* @__PURE__ */ new Map();
4851
6062
  constructor(name, config, bridge, options) {
4852
6063
  super(name, config, bridge, options);
4853
6064
  this.atSender = config["atSender"] === true;
6065
+ if (!this.config.instructions) {
6066
+ this.config.instructions = [
6067
+ "## DingTalk Channel",
6068
+ "",
6069
+ "You are responding through DingTalk.",
6070
+ IMAGE_INSTRUCTIONS
6071
+ ].join("\n");
6072
+ } else if (!this.config.instructions.includes("[IMAGE:")) {
6073
+ this.config.instructions += IMAGE_INSTRUCTIONS;
6074
+ }
6075
+ this.interactiveCardConfig = parseDingtalkInteractiveCardConfig(config.interactiveCards);
4854
6076
  if (!config.clientId || !config.clientSecret) {
4855
6077
  throw new Error(`Channel "${name}" requires clientId and clientSecret for DingTalk.`);
4856
6078
  }
@@ -4860,6 +6082,44 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
4860
6082
  }
4861
6083
  const useConnectionManager = rawUseConnectionManager ?? true;
4862
6084
  this.client = this.createClient(useConnectionManager);
6085
+ if (this.interactiveCardConfig.enabled) {
6086
+ this.interactiveCardClient = new DingtalkInteractiveCardClient({
6087
+ robotCode: config.clientId,
6088
+ getAccessToken: /* @__PURE__ */ __name(() => this.getProactiveToken(), "getAccessToken")
6089
+ });
6090
+ if (this.interactiveCardConfig.statusCard.enabled && config.blockStreaming !== "on") {
6091
+ this.statusCardController = new StatusCardController({
6092
+ client: this.interactiveCardClient,
6093
+ cancelRun: /* @__PURE__ */ __name((sessionId, runId) => this.requestPromptRunCancellation(sessionId, runId), "cancelRun"),
6094
+ ...config.model ? { model: config.model } : {},
6095
+ onError: /* @__PURE__ */ __name((operation, error) => {
6096
+ process.stderr.write(`[DingTalk:${this.name}] ${operation} failed: ${sanitizeLogText(String(error), 300)}
6097
+ `);
6098
+ }, "onError")
6099
+ });
6100
+ }
6101
+ if (this.interactiveCardConfig.questionCard.enabled) {
6102
+ this.questionCardController = new QuestionCardController({
6103
+ client: this.interactiveCardClient,
6104
+ timeoutMs: this.interactiveCardConfig.questionCard.timeoutMs,
6105
+ sendFallback: /* @__PURE__ */ __name((chatId, text) => this.sendMessage(chatId, text), "sendFallback"),
6106
+ reserveRunProjection: /* @__PURE__ */ __name((runId) => this.interactionPresenter?.reserveProjection(runId), "reserveRunProjection"),
6107
+ onError: /* @__PURE__ */ __name((operation, error) => {
6108
+ process.stderr.write(`[DingTalk:${this.name}] ${operation} failed: ${sanitizeLogText(String(error), 300)}
6109
+ `);
6110
+ }, "onError")
6111
+ });
6112
+ }
6113
+ if (this.statusCardController || this.questionCardController) {
6114
+ this.interactionPresenter = new DingtalkInteractionPresenter({
6115
+ statusCards: this.statusCardController,
6116
+ questionCards: this.questionCardController,
6117
+ ...config.blockStreaming !== "on" ? {
6118
+ sendFallback: /* @__PURE__ */ __name((chatId, text, sessionId) => this.sendResponseMessage(chatId, text, sessionId), "sendFallback")
6119
+ } : {}
6120
+ });
6121
+ }
6122
+ }
4863
6123
  if (useConnectionManager) {
4864
6124
  this.connectionManager = new DingtalkConnectionManager({
4865
6125
  initialClient: this.client,
@@ -4901,6 +6161,47 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
4901
6161
  });
4902
6162
  this.onMessage(msg);
4903
6163
  });
6164
+ if (this.interactiveCardConfig.enabled) {
6165
+ client.registerCallbackListener(TOPIC_CARD, (msg) => {
6166
+ this.onCardCallback(client, msg);
6167
+ });
6168
+ }
6169
+ }
6170
+ onCardCallback(client, msg) {
6171
+ const callback = parseDingtalkCardCallback(msg.data);
6172
+ const actorId = callback?.actorId ?? parseDingtalkCardActorId(msg.data);
6173
+ let result;
6174
+ try {
6175
+ result = callback ? this.routeCardCallback(callback) : { kind: "ignored", ...actorId ? { actorId } : {} };
6176
+ } catch (err) {
6177
+ process.stderr.write(`[DingTalk:${this.name}] card callback routing failed: ${sanitizeLogText(String(err), 200)}
6178
+ `);
6179
+ result = { kind: "ignored", ...actorId ? { actorId } : {} };
6180
+ }
6181
+ client.send(msg.headers.messageId, {
6182
+ status: EventAck.SUCCESS,
6183
+ message: "ok"
6184
+ });
6185
+ if (result.kind === "accepted") {
6186
+ void result.execute().catch((err) => {
6187
+ process.stderr.write(`[DingTalk:${this.name}] card callback action failed: ${sanitizeLogText(String(err), 200)}
6188
+ `);
6189
+ });
6190
+ } else if (result.kind === "forbidden") {
6191
+ void this.sendCardInteractionFeedback(result.actorId, result.target).catch((err) => {
6192
+ process.stderr.write(`[DingTalk:${this.name}] card interaction feedback failed: ${sanitizeLogText(String(err), 200)}
6193
+ `);
6194
+ });
6195
+ }
6196
+ }
6197
+ routeCardCallback(callback) {
6198
+ if (callback.actionId === "btn_stop") {
6199
+ return this.statusCardController?.claimStop(callback.outTrackId, callback.actorId) ?? { kind: "ignored", actorId: callback.actorId };
6200
+ }
6201
+ return this.questionCardController?.claim(callback) ?? {
6202
+ kind: "ignored",
6203
+ actorId: callback.actorId
6204
+ };
4904
6205
  }
4905
6206
  onDownStream(raw, client) {
4906
6207
  this.connectionManager?.noteActivity(client);
@@ -5003,23 +6304,66 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5003
6304
  static isUnroutableGroupMessage(isGroup, conversationId) {
5004
6305
  return isGroup && !conversationId;
5005
6306
  }
5006
- async sendReply(chatId, text) {
6307
+ async prepareOutgoingText(text) {
6308
+ const markers = findImageMarkers(text);
6309
+ if (markers.length === 0)
6310
+ return text;
6311
+ const replacements = [];
6312
+ for (const marker of markers) {
6313
+ const fileName = basename2(marker.path).replace(/[\r\n[\]]+/g, "_").slice(0, 100) || "image";
6314
+ try {
6315
+ const image = readValidatedImage(marker.path, {
6316
+ workspaceDir: this.config.cwd
6317
+ });
6318
+ let mediaId;
6319
+ for (let attempt = 0; attempt < 2; attempt++) {
6320
+ const token = await this.getProactiveToken();
6321
+ try {
6322
+ mediaId = await uploadDingTalkImage(image, token);
6323
+ break;
6324
+ } catch (error) {
6325
+ if (error instanceof DingTalkMediaUploadError && error.authFailure && attempt === 0) {
6326
+ this.proactiveToken = void 0;
6327
+ continue;
6328
+ }
6329
+ throw error;
6330
+ }
6331
+ }
6332
+ if (!mediaId) {
6333
+ throw new Error("DingTalk media upload returned no MediaID");
6334
+ }
6335
+ replacements.push(`![image](${mediaId})`);
6336
+ } catch (error) {
6337
+ process.stderr.write(`[DingTalk:${this.name}] outbound image upload failed (${sanitizeLogText(fileName, 100)}): ${sanitizeLogText(error instanceof Error ? error.message : String(error), 300)}
6338
+ `);
6339
+ replacements.push(`[Image delivery failed: ${fileName}]`);
6340
+ }
6341
+ }
6342
+ return replaceImageMarkers(text, markers, replacements);
6343
+ }
6344
+ async sendReply(chatId, text, atUserId) {
5007
6345
  const webhook = this.webhooks.get(chatId);
5008
6346
  if (!webhook) {
5009
6347
  process.stderr.write(`[DingTalk:${this.name}] No webhook for chatId ${chatId}, cannot send.
5010
6348
  `);
5011
6349
  return;
5012
6350
  }
5013
- const chunks = normalizeDingTalkMarkdown(text);
5014
- const title = extractTitle(text);
6351
+ const outgoingText = await this.prepareOutgoingText(text);
6352
+ const mentionPrefix = atUserId ? `@${atUserId}
6353
+
6354
+ ` : "";
6355
+ const chunks = normalizeDingTalkMarkdown(mentionPrefix + outgoingText);
6356
+ const title = extractTitle(outgoingText);
5015
6357
  for (let i = 0; i < chunks.length; i++) {
5016
6358
  const chunk = chunks[i];
6359
+ const isMention = i === 0 && atUserId !== void 0;
5017
6360
  const body = {
5018
6361
  msgtype: "markdown",
5019
6362
  markdown: {
5020
6363
  title: i === 0 ? title : `${title} (cont.)`,
5021
6364
  text: chunk
5022
- }
6365
+ },
6366
+ ...isMention ? { at: { atUserIds: [atUserId] } } : {}
5023
6367
  };
5024
6368
  const resp = await fetch(webhook, {
5025
6369
  method: "POST",
@@ -5093,8 +6437,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5093
6437
  async pushProactive(target, text) {
5094
6438
  if (!text.trim())
5095
6439
  return;
5096
- const chunks = normalizeDingTalkMarkdown(text);
5097
- const title = extractTitle(text);
6440
+ const outgoingText = await this.prepareOutgoingText(text);
6441
+ const chunks = normalizeDingTalkMarkdown(outgoingText);
6442
+ const title = extractTitle(outgoingText);
5098
6443
  for (let i = 0; i < chunks.length; i++) {
5099
6444
  await this.sendProactiveChunk(target, i === 0 ? title : `${title} (cont.)`, chunks[i], `chunk ${i + 1}/${chunks.length}`);
5100
6445
  }
@@ -5128,6 +6473,22 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5128
6473
  };
5129
6474
  return data.access_token;
5130
6475
  }
6476
+ sendCardInteractionFeedback(actorId, target) {
6477
+ if (target?.isGroup) {
6478
+ return this.sendProactiveChunk({
6479
+ channelName: this.name,
6480
+ senderId: actorId,
6481
+ chatId: target.chatId,
6482
+ isGroup: true
6483
+ }, "\u5361\u7247\u64CD\u4F5C", "\u4EC5\u4EFB\u52A1\u53D1\u8D77\u4EBA\u53EF\u4EE5\u64CD\u4F5C\u8FD9\u5F20\u5361\u7247\uFF0C\u672C\u6B21\u64CD\u4F5C\u672A\u751F\u6548\u3002", "card interaction feedback");
6484
+ }
6485
+ return this.sendProactiveChunk({
6486
+ channelName: this.name,
6487
+ senderId: actorId,
6488
+ chatId: actorId,
6489
+ isGroup: false
6490
+ }, "\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");
6491
+ }
5131
6492
  async sendProactiveChunk(target, title, text, chunkLabel) {
5132
6493
  const targetKind = target.isGroup === true ? "group" : "dm";
5133
6494
  for (let attempt = 0; ; attempt++) {
@@ -5337,6 +6698,12 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5337
6698
  }
5338
6699
  this.sessionMentionTargets.delete(sessionId);
5339
6700
  this.textReplySessions.delete(sessionId);
6701
+ const cardRunId = this.cardRunBySession.get(sessionId);
6702
+ if (cardRunId) {
6703
+ this.cardRunBySession.delete(sessionId);
6704
+ this.interactionPresenter?.terminalizeRun(cardRunId, "cancelled");
6705
+ this.cardRuns.delete(cardRunId);
6706
+ }
5340
6707
  const keys = this.sessionReactionKeys.get(sessionId);
5341
6708
  if (keys) {
5342
6709
  this.sessionReactionKeys.delete(sessionId);
@@ -5353,12 +6720,33 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5353
6720
  onTaskLifecycle(event) {
5354
6721
  if (event.type === "started") {
5355
6722
  this.startReaction(event.chatId, event.messageId, event.sessionId);
6723
+ const inboundOwner = event.messageId ? this.inboundCardOwners.get(event.messageId) : void 0;
6724
+ if (event.messageId)
6725
+ this.inboundCardOwners.delete(event.messageId);
6726
+ if (event.runId && event.owner && inboundOwner?.ownerId === event.owner.id) {
6727
+ this.cardRuns.set(event.runId, inboundOwner);
6728
+ this.cardRunBySession.set(event.sessionId, event.runId);
6729
+ this.interactionPresenter?.registerRun(event.runId, event.owner.id, inboundOwner.target);
6730
+ }
5356
6731
  return;
5357
6732
  }
5358
6733
  if (isTerminalTaskLifecycleType(event.type)) {
5359
6734
  if (event.messageId)
5360
6735
  this.mentionTargets.delete(event.messageId);
5361
6736
  this.stopReaction(event.chatId, event.messageId, event.sessionId);
6737
+ if (event.runId) {
6738
+ if (event.type === "failed") {
6739
+ this.interactionPresenter?.terminalizeRun(event.runId, "failed", event.error);
6740
+ } else if (event.type === "cancelled") {
6741
+ this.interactionPresenter?.terminalizeRun(event.runId, "cancelled", event.reason);
6742
+ } else {
6743
+ this.interactionPresenter?.terminalizeRun(event.runId, "completed");
6744
+ }
6745
+ this.cardRuns.delete(event.runId);
6746
+ if (this.cardRunBySession.get(event.sessionId) === event.runId) {
6747
+ this.cardRunBySession.delete(event.sessionId);
6748
+ }
6749
+ }
5362
6750
  }
5363
6751
  }
5364
6752
  onPromptBufferDropped(_chatId, sessionId, messageIds) {
@@ -5405,6 +6793,21 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5405
6793
  if (!await this.preflightInbound(envelope))
5406
6794
  return;
5407
6795
  const messageId = envelope.messageId;
6796
+ if (messageId && envelope.senderId) {
6797
+ this.inboundCardOwners.delete(messageId);
6798
+ this.inboundCardOwners.set(messageId, {
6799
+ ownerId: envelope.senderId,
6800
+ target: {
6801
+ chatId: envelope.chatId,
6802
+ isGroup: envelope.isGroup
6803
+ }
6804
+ });
6805
+ if (this.inboundCardOwners.size > 1e3) {
6806
+ const oldest = this.inboundCardOwners.keys().next().value;
6807
+ if (oldest !== void 0)
6808
+ this.inboundCardOwners.delete(oldest);
6809
+ }
6810
+ }
5408
6811
  const atUserId = envelope[mentionTarget];
5409
6812
  if (this.atSender && messageId && atUserId) {
5410
6813
  this.mentionTargets.set(messageId, atUserId);
@@ -5439,11 +6842,43 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5439
6842
  if (atUserId)
5440
6843
  this.sessionMentionTargets.delete(sessionId);
5441
6844
  if (this.textReplySessions.has(sessionId)) {
6845
+ if (findImageMarkers(text).length > 0) {
6846
+ await this.sendReply(chatId, text, atUserId);
6847
+ return;
6848
+ }
5442
6849
  await this.sendTextReply(chatId, text, atUserId);
5443
6850
  return;
5444
6851
  }
5445
6852
  await this.sendReply(chatId, text);
5446
6853
  }
6854
+ async onResponseComplete(chatId, text, sessionId, segment) {
6855
+ if (segment && this.interactionPresenter) {
6856
+ const outgoingText = await this.prepareOutgoingText(text);
6857
+ if (await this.interactionPresenter.closeOutput(segment.segmentId, outgoingText, "completed", segment)) {
6858
+ return;
6859
+ }
6860
+ }
6861
+ await this.sendResponseMessage(chatId, text, sessionId);
6862
+ }
6863
+ onOutputSegmentEnd(_chatId, _sessionId, segment, reason) {
6864
+ if (!this.interactionPresenter)
6865
+ return;
6866
+ return this.interactionPresenter.closeOutput(segment.segmentId, "", reason, segment).then(() => void 0);
6867
+ }
6868
+ onResponseChunk(_chatId, chunk, _sessionId, segment) {
6869
+ if (segment)
6870
+ this.interactionPresenter?.appendOutput(segment, chunk);
6871
+ }
6872
+ async presentUserInputRequest(context) {
6873
+ const run = this.cardRuns.get(context.runId);
6874
+ if (!run || run.ownerId !== context.owner.id) {
6875
+ return { kind: "unsupported" };
6876
+ }
6877
+ if (!this.questionCardController || !this.interactionPresenter) {
6878
+ return { kind: "unsupported" };
6879
+ }
6880
+ return this.interactionPresenter.presentInput(context);
6881
+ }
5447
6882
  /**
5448
6883
  * Extract quoted/referenced message context from a reply.
5449
6884
  * DingTalk provides this via text.repliedMsg (newer) or quoteMessage (legacy).
@@ -5600,9 +7035,9 @@ var DingtalkChannel = class _DingtalkChannel extends ChannelBase {
5600
7035
  }
5601
7036
  ];
5602
7037
  } else {
5603
- const dir = join(tmpdir(), "channel-files", randomUUID());
7038
+ const dir = join(tmpdir2(), "channel-files", randomUUID4());
5604
7039
  mkdirSync(dir, { recursive: true });
5605
- const safeName = basename(fileName || "") || `dingtalk_${mediaType}_${Date.now()}`;
7040
+ const safeName = basename2(fileName || "") || `dingtalk_${mediaType}_${Date.now()}`;
5606
7041
  const filePath = join(dir, safeName);
5607
7042
  writeFileSync(filePath, media.buffer);
5608
7043
  if (envelope.text === `(file: ${fileName || "file"})` || envelope.text === "(audio)" || envelope.text === "(video)") {