@qwen-code/qwen-code 0.22.2-preview.0 → 0.22.2

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 (379) hide show
  1. package/bundled/goal-draft/SKILL.md +109 -0
  2. package/bundled/qc-helper/docs/configuration/settings.md +12 -12
  3. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  4. package/bundled/qc-helper/docs/features/commands.md +2 -1
  5. package/bundled/qc-helper/docs/features/goals.md +58 -0
  6. package/bundled/qc-helper/docs/features/headless.md +13 -11
  7. package/bundled/qc-helper/docs/features/status-line.md +3 -3
  8. package/chunks/MaxSizedBox-X5FZSNAJ.js +112 -0
  9. package/chunks/{StandaloneSessionPicker-KFMJILVY.js → StandaloneSessionPicker-AVLI6VJP.js} +76 -76
  10. package/chunks/{acpAgent-KNFTTDWL.js → acpAgent-MXEAN54C.js} +994 -277
  11. package/chunks/{agent-6V6MZOA7.js → agent-PJIPDWHB.js} +41 -41
  12. package/chunks/agent-headless-B4JVD7UK.js +87 -0
  13. package/chunks/{anthropicContentGenerator-U76GTVB6.js → anthropicContentGenerator-HGMBACVE.js} +7 -7
  14. package/chunks/{artifact-tool-XDJCZZCF.js → artifact-tool-5YT4QF7Y.js} +2 -2
  15. package/chunks/{askUserQuestion-ZXXERLEV.js → askUserQuestion-4SWJY65V.js} +2 -2
  16. package/chunks/bridge-FKZTVIS3.js +121 -0
  17. package/chunks/{channel-management-service-HXXS3HOZ.js → channel-management-service-X4AZ6IXX.js} +1 -1
  18. package/chunks/channel-settings-store-4UFCLBBG.js +117 -0
  19. package/chunks/{channel-worker-group-EVDC2P4K.js → channel-worker-group-27HMGD5S.js} +7 -6
  20. package/chunks/{channel-worker-manager-IJJZHGEI.js → channel-worker-manager-QEGX646Z.js} +9 -7
  21. package/chunks/{channel-worker-supervisor-YSKB5GVB.js → channel-worker-supervisor-UEW2WWCC.js} +5 -4
  22. package/chunks/{chunk-7QGEJI7M.js → chunk-23RFD54N.js} +1 -1
  23. package/chunks/{chunk-K5PNJ6VL.js → chunk-2K6ORIHJ.js} +13 -13
  24. package/chunks/{chunk-OGZAQWJP.js → chunk-2NYCN6F2.js} +11 -11
  25. package/chunks/chunk-2TNL5KPM.js +49 -0
  26. package/chunks/{chunk-ZEADBZLO.js → chunk-3AFMQUTI.js} +3 -3
  27. package/chunks/{chunk-LRLMDV5X.js → chunk-3DXFGHAJ.js} +185 -174
  28. package/chunks/{chunk-73WFGVIZ.js → chunk-3FDFA4MZ.js} +3 -3
  29. package/chunks/{chunk-WBT3STGU.js → chunk-3I6UTTDX.js} +1 -1
  30. package/chunks/{chunk-FVDQ5E67.js → chunk-3JGZSIDA.js} +3 -3
  31. package/chunks/{chunk-JJJD6QCC.js → chunk-3SGB2UHX.js} +15 -10
  32. package/chunks/{chunk-77TOMRBG.js → chunk-43GGFFLY.js} +3 -3
  33. package/chunks/{chunk-ZJG323IA.js → chunk-43UYNAWX.js} +6 -4
  34. package/chunks/{chunk-T2HMXHYA.js → chunk-4CDSK5AZ.js} +6 -6
  35. package/chunks/chunk-4CMJKUND.js +95 -0
  36. package/chunks/{chunk-EB4VDXNI.js → chunk-4FTKQNWJ.js} +1 -1
  37. package/chunks/{chunk-PAJGKZAA.js → chunk-4HV6HH33.js} +10 -8
  38. package/chunks/{chunk-BQBUZDDH.js → chunk-4J657AJR.js} +3 -3
  39. package/chunks/{chunk-BU7OUDQB.js → chunk-4JWNNLPT.js} +4 -4
  40. package/chunks/{chunk-4N6UAPD3.js → chunk-4MQEPP3Y.js} +9 -84
  41. package/chunks/{chunk-I6HWGOWD.js → chunk-5O72BNDD.js} +93 -14
  42. package/chunks/{chunk-IKN3IUJP.js → chunk-5XBFCMWD.js} +2 -2
  43. package/chunks/{chunk-2YDYDDE2.js → chunk-66KDY3LV.js} +3 -3
  44. package/chunks/{chunk-UVDOONRU.js → chunk-6CGL7E7G.js} +2 -2
  45. package/chunks/{chunk-SLEWBQWM.js → chunk-6DIGWMGT.js} +2 -2
  46. package/chunks/{chunk-SKNVVYIJ.js → chunk-6IUNAPLR.js} +3 -3
  47. package/chunks/{chunk-VUZY6MEQ.js → chunk-6LFJEACX.js} +4 -4
  48. package/chunks/{chunk-H2MDBYLL.js → chunk-6LFTG244.js} +8 -8
  49. package/chunks/{chunk-PVBT5QPD.js → chunk-6PJOTWAN.js} +1 -1
  50. package/chunks/{chunk-4IDJQOCO.js → chunk-77RG5SFQ.js} +1 -1
  51. package/chunks/{chunk-SDVF6A42.js → chunk-7DJCPZE3.js} +3 -3
  52. package/chunks/{chunk-ELY4QVIB.js → chunk-7EQQR46F.js} +1 -1
  53. package/chunks/{chunk-H4JK2A2V.js → chunk-7UYV53BC.js} +1 -1
  54. package/chunks/{chunk-6HOU52QX.js → chunk-A7YP63XN.js} +4 -4
  55. package/chunks/{chunk-E4I5MVBR.js → chunk-ABS25QER.js} +1 -1
  56. package/chunks/{chunk-XO4NGYRP.js → chunk-AGR5UROZ.js} +5 -5
  57. package/chunks/{chunk-5T4LWWNX.js → chunk-B7CDU2SL.js} +2 -2
  58. package/chunks/{chunk-GQAIZL3H.js → chunk-BAJKAAOY.js} +68 -64
  59. package/chunks/{chunk-DWRFOH3G.js → chunk-BBWV7ONL.js} +3 -3
  60. package/chunks/{chunk-4TPAG3O7.js → chunk-BFPESSTR.js} +1 -1
  61. package/chunks/{chunk-RUJTCU46.js → chunk-BNMF3K5X.js} +20 -19
  62. package/chunks/{chunk-IPQA4SR5.js → chunk-BWORX6FA.js} +1 -1
  63. package/chunks/{chunk-BKDAF7ES.js → chunk-BXDAPVQU.js} +2 -2
  64. package/chunks/{chunk-FY62MBPS.js → chunk-C6K43ZDE.js} +4 -4
  65. package/chunks/{chunk-JUIJ3FXC.js → chunk-CAJTKR6W.js} +5 -5
  66. package/chunks/{chunk-EADEZDPO.js → chunk-CCBZDVUA.js} +30 -25
  67. package/chunks/{chunk-DP7LABIB.js → chunk-CMHFCLBU.js} +1 -1
  68. package/chunks/{chunk-5AFPOEY3.js → chunk-CPGJJJLU.js} +1 -1
  69. package/chunks/{chunk-LRKMQPMD.js → chunk-CQH5KTKC.js} +1 -1
  70. package/chunks/{chunk-EWBY3PFB.js → chunk-CSMI4FP5.js} +1 -1
  71. package/chunks/{chunk-JECO75XD.js → chunk-D5LUXLUH.js} +2 -2
  72. package/chunks/{chunk-TQYZG5DU.js → chunk-DZWPESIF.js} +3 -3
  73. package/chunks/{chunk-5Y2JCJAH.js → chunk-EFUM7RVY.js} +15 -2
  74. package/chunks/{chunk-3UZCLCXR.js → chunk-EKSCLBBF.js} +3 -3
  75. package/chunks/{chunk-LJP2BBMK.js → chunk-EOGELB3H.js} +4 -4
  76. package/chunks/{chunk-624NHDGB.js → chunk-ERFDKH32.js} +11 -0
  77. package/chunks/{chunk-RQAMNZ4Y.js → chunk-F5SZP77N.js} +310 -78
  78. package/chunks/{chunk-SQPOJ4ZI.js → chunk-F6FV3C5K.js} +12 -7
  79. package/chunks/{chunk-C2BAEV64.js → chunk-F7TNAPZ4.js} +9 -7
  80. package/chunks/{chunk-OAAPGZVH.js → chunk-FBSSIAAQ.js} +6 -6
  81. package/chunks/{chunk-2FN2HNTI.js → chunk-FDY5RMGH.js} +2 -2
  82. package/chunks/{chunk-U66FXEH2.js → chunk-FY76G3G5.js} +5 -5
  83. package/chunks/{chunk-LKOSBI2M.js → chunk-G34IR3D6.js} +9 -9
  84. package/chunks/{chunk-ZWKGZB2K.js → chunk-H2WDGQ6D.js} +3 -3
  85. package/chunks/chunk-H72BQNM3.js +645 -0
  86. package/chunks/{chunk-ILPXSKGQ.js → chunk-HVEYF6VT.js} +2 -2
  87. package/chunks/{chunk-EAV3TENS.js → chunk-HVQ3B7FF.js} +2 -2
  88. package/chunks/{chunk-MI7CMXPU.js → chunk-IJKTMLBE.js} +1 -1
  89. package/chunks/{chunk-IN66KO3N.js → chunk-IK5BW3CS.js} +2 -2
  90. package/chunks/{chunk-5NV2AN56.js → chunk-IOPCFOTF.js} +3 -3
  91. package/chunks/{chunk-O3BUXIPM.js → chunk-IZIVM7LZ.js} +3 -3
  92. package/chunks/{chunk-I6VVOZDK.js → chunk-J2OSJFP3.js} +2 -2
  93. package/chunks/{chunk-AYVIGUUK.js → chunk-JB4JIVTJ.js} +1 -1
  94. package/chunks/{chunk-76WGY6LW.js → chunk-JCQD3INC.js} +3 -3
  95. package/chunks/{chunk-CITGRGCM.js → chunk-JHS74YAB.js} +4 -1
  96. package/chunks/{chunk-GXWY24QS.js → chunk-JSC3H3TD.js} +33 -10
  97. package/chunks/{chunk-NUHCXGAD.js → chunk-JSHHYW6T.js} +4 -4
  98. package/chunks/{chunk-5CW26JIE.js → chunk-JU4EEXC7.js} +2 -2
  99. package/chunks/{chunk-T6OODF2U.js → chunk-JWALNCLT.js} +1 -1
  100. package/chunks/{chunk-DX5FZGHZ.js → chunk-K2NQPH5D.js} +3 -3
  101. package/chunks/{chunk-VLY6XOBY.js → chunk-KEKZFOL6.js} +1 -1
  102. package/chunks/{chunk-RUQBJS34.js → chunk-KUX5D6DK.js} +1200 -339
  103. package/chunks/{chunk-UX3IFLJM.js → chunk-L2M46FP5.js} +149 -22
  104. package/chunks/{chunk-6US7BF3G.js → chunk-L6BZRIUL.js} +2 -2
  105. package/chunks/{chunk-BGWT7VBV.js → chunk-L6YT5H34.js} +4 -4
  106. package/chunks/{chunk-W2WRNJKX.js → chunk-LDP5OD6N.js} +5 -5
  107. package/chunks/{chunk-QB5DD75E.js → chunk-LXIBMVRN.js} +7 -7
  108. package/chunks/{chunk-GNMJNDZE.js → chunk-M6FOJXW3.js} +1 -1
  109. package/chunks/{chunk-OX44MOAN.js → chunk-MIIVI25Q.js} +3 -3
  110. package/chunks/{chunk-K3LPAED5.js → chunk-MQM5PJML.js} +24 -4
  111. package/chunks/{chunk-27ONXAFY.js → chunk-NIFYWDYN.js} +1 -1
  112. package/chunks/{chunk-IJVDHPKD.js → chunk-NU7RKEZR.js} +2 -2
  113. package/chunks/{chunk-MB4OCRQ2.js → chunk-O2UN57NX.js} +2 -2
  114. package/chunks/{chunk-TWUA5EIL.js → chunk-OIP7C4FE.js} +5 -5
  115. package/chunks/{chunk-UCSV2IZW.js → chunk-OIVXBW3W.js} +3 -3
  116. package/chunks/{chunk-TOF4UZHH.js → chunk-P2SU6ZTI.js} +3 -3
  117. package/chunks/{chunk-N4B7VPXK.js → chunk-P5GGM4KS.js} +5 -5
  118. package/chunks/{chunk-ZKAZP2ZG.js → chunk-PDMJ3KGS.js} +2 -2
  119. package/chunks/{chunk-RRKNX553.js → chunk-PDQGMSZK.js} +1 -1
  120. package/chunks/{chunk-3UXJFOB3.js → chunk-PFCQ62V4.js} +5 -5
  121. package/chunks/{chunk-JLGFGPZJ.js → chunk-PKAYJDB3.js} +2 -2
  122. package/chunks/{chunk-GTUKW3I6.js → chunk-PPKZ7JOE.js} +1 -1
  123. package/chunks/{chunk-HOANA6GC.js → chunk-Q26AYA62.js} +4 -4
  124. package/chunks/{chunk-WEGXPP5E.js → chunk-QFCDF5PL.js} +1 -1
  125. package/chunks/{chunk-4PLAO7FS.js → chunk-QP4C6WCE.js} +3 -3
  126. package/chunks/{chunk-3B5DCAQU.js → chunk-R4PMVSR5.js} +27 -25
  127. package/chunks/{chunk-7JJUFI36.js → chunk-RIEFGNTP.js} +579 -3419
  128. package/chunks/{chunk-7XKW4CVK.js → chunk-RJC5EIKY.js} +4 -4
  129. package/chunks/chunk-RKFGE7JH.js +93 -0
  130. package/chunks/{chunk-CPPYZHBN.js → chunk-RU7BK6B3.js} +1 -1
  131. package/chunks/{chunk-GZJUCMH4.js → chunk-RUGNCYNO.js} +11 -633
  132. package/chunks/{chunk-ZLTEQYNC.js → chunk-SFPGAQUL.js} +2 -2
  133. package/chunks/{chunk-K6FURWIX.js → chunk-SJ3ZUWFK.js} +26 -4
  134. package/chunks/{chunk-DEYPMJPD.js → chunk-SMPR7SPO.js} +1 -1
  135. package/chunks/{chunk-7CWEZQ6T.js → chunk-STUJ7IMZ.js} +0 -77
  136. package/chunks/{chunk-O5YGAEQS.js → chunk-T32W2JHI.js} +6 -6
  137. package/chunks/chunk-T3WXYEZ4.js +304 -0
  138. package/chunks/{chunk-D6XO27Z5.js → chunk-TGWAQ5RB.js} +750 -296
  139. package/chunks/{chunk-EC5BONC3.js → chunk-TPI7O7HR.js} +1 -1
  140. package/chunks/{chunk-OI2DR6QB.js → chunk-TRZTNIQ6.js} +2 -2
  141. package/chunks/{chunk-T2CRBIDJ.js → chunk-TTX2JUE6.js} +1 -1
  142. package/chunks/{chunk-2NNTE2ED.js → chunk-UHQFIS7N.js} +15 -0
  143. package/chunks/{chunk-KOJ6MHD5.js → chunk-UTLCH2FK.js} +1 -1
  144. package/chunks/{chunk-7DPKPBOQ.js → chunk-V2NDP3I4.js} +2 -2
  145. package/chunks/{chunk-RQ5ASDFQ.js → chunk-V4QXXQJ2.js} +3 -3
  146. package/chunks/{chunk-BVE5EMIG.js → chunk-V5J4J5TP.js} +2 -2
  147. package/chunks/{chunk-X2UOOG5V.js → chunk-VQUGEVGR.js} +1 -1
  148. package/chunks/{chunk-XJS54K4A.js → chunk-VTHREBQM.js} +2 -2
  149. package/chunks/{chunk-V3GINY6K.js → chunk-VVW4ZNFY.js} +3 -3
  150. package/chunks/{chunk-YT5XN3HV.js → chunk-W5MJJ2V7.js} +1 -1
  151. package/chunks/{chunk-FPH6TXD3.js → chunk-WAOIHTJS.js} +1 -1
  152. package/chunks/{chunk-FN5C6C7G.js → chunk-WKK5BQNP.js} +151 -60
  153. package/chunks/chunk-XDFHY4R3.js +1584 -0
  154. package/chunks/{chunk-L436XFLJ.js → chunk-XDLEZ5HX.js} +1 -1
  155. package/chunks/{chunk-VL4YX3FH.js → chunk-XF63PKEN.js} +1 -1
  156. package/chunks/{chunk-3FSBMAYD.js → chunk-XQFT3QUF.js} +1 -1
  157. package/chunks/{chunk-2MHGD7EE.js → chunk-XRSOI3DL.js} +1 -1
  158. package/chunks/{chunk-FJWICLG7.js → chunk-Y3QL45LS.js} +1 -1
  159. package/chunks/{chunk-RCDXSEJ5.js → chunk-Y6LSMB6J.js} +1 -1
  160. package/chunks/{chunk-2SERYG4T.js → chunk-YTDVNSUQ.js} +1 -1
  161. package/chunks/{chunk-4X5GYZFO.js → chunk-Z7FLBQPR.js} +7 -7
  162. package/chunks/{chunk-3BV7TZNQ.js → chunk-Z7TGYN5F.js} +3 -3
  163. package/chunks/{chunk-4Z3PSHN4.js → chunk-ZFKOCECU.js} +2 -2
  164. package/chunks/chunk-ZGXYO7DY.js +3416 -0
  165. package/chunks/{chunk-E6FGMDFQ.js → chunk-ZU4UDIWX.js} +19 -1
  166. package/chunks/config-utils-BBOCOGZW.js +113 -0
  167. package/chunks/contextCommand-EET67MQ2.js +108 -0
  168. package/chunks/{core-runtime-6TBMEULI.js → core-runtime-677KFX6Q.js} +53 -53
  169. package/chunks/{create-sub-session-RVHSWVAP.js → create-sub-session-23ITIELI.js} +3 -3
  170. package/chunks/{create-sub-session-SAOMTP62.js → create-sub-session-JKZAYZX7.js} +160 -79
  171. package/chunks/{cron-create-IJGVR5R2.js → cron-create-KJ4IY6PP.js} +57 -10
  172. package/chunks/{cron-delete-4N5BI6GL.js → cron-delete-MBLQCAYY.js} +4 -4
  173. package/chunks/{cron-list-2CATIPUX.js → cron-list-DWH2PQ47.js} +4 -4
  174. package/chunks/{daemon-NAYK4XXU.js → daemon-MJQUO7RA.js} +28 -1
  175. package/chunks/{daemon-git-worktree-guard-TYLESM6G.js → daemon-git-worktree-guard-6MVAAZZZ.js} +53 -53
  176. package/chunks/daemon-status-provider-RFKZOK3S.js +119 -0
  177. package/chunks/daemon-trust-policy-DRZPFB4Q.js +114 -0
  178. package/chunks/{daemon-trust-policy-monitor-WWX7I7P6.js → daemon-trust-policy-monitor-B5U6TQX5.js} +59 -59
  179. package/chunks/deferred-core-runtime-BBVIOP24.js +116 -0
  180. package/chunks/{display-image-DR55LL6M.js → display-image-BE7I6ZB6.js} +5 -5
  181. package/chunks/{dist-FVJZSIO4.js → dist-ILDBUWDB.js} +71 -19
  182. package/chunks/{dist-6H6RZ5H6.js → dist-QODVOVWI.js} +58 -35
  183. package/chunks/earlyInputCapture-2JOMMNQ4.js +109 -0
  184. package/chunks/{edit-GBDKI5DZ.js → edit-BSV6YRVW.js} +42 -42
  185. package/chunks/{en-6MDBWMTG.js → en-YLXBXM4Z.js} +2 -1
  186. package/chunks/{enter-worktree-UOZ6ZTP7.js → enter-worktree-MQXFFPKM.js} +7 -7
  187. package/chunks/{enterPlanMode-2KTIPPM3.js → enterPlanMode-PKNF35FE.js} +41 -41
  188. package/chunks/{environment-XJ75LJ6N.js → environment-MOZMPUHR.js} +55 -55
  189. package/chunks/errors-DMPQVYJL.js +115 -0
  190. package/chunks/{exit-worktree-G2QATUCV.js → exit-worktree-L344UY7K.js} +7 -7
  191. package/chunks/{exitPlanMode-AUMYTFIQ.js → exitPlanMode-UE4FGCY4.js} +41 -41
  192. package/chunks/{fast-path-TU7U2ETU.js → fast-path-773PV7PU.js} +5 -5
  193. package/chunks/{gemini-FKMYDP64.js → gemini-IP4FJAP5.js} +101 -100
  194. package/chunks/{geminiContentGenerator-WSHP7CSR.js → geminiContentGenerator-PUNEBWJW.js} +8 -8
  195. package/chunks/{glob-EOM6XK7H.js → glob-CZHOWUEA.js} +41 -41
  196. package/chunks/{goal-tools-CNVXMSZD.js → goal-tools-YZQJXTGH.js} +9 -8
  197. package/chunks/{grep-3NLSS32D.js → grep-5GPICQBU.js} +6 -6
  198. package/chunks/handleAutoUpdate-SGXKTQM6.js +111 -0
  199. package/chunks/{i18n-XX7U2Q3X.js → i18n-B42HKHKH.js} +54 -54
  200. package/chunks/{image-gen-63NN2H5N.js → image-gen-HAYOEQ4O.js} +9 -9
  201. package/chunks/initializer-FB66WYR3.js +115 -0
  202. package/chunks/installationInfo-Y7AULNMX.js +109 -0
  203. package/chunks/{keychain-token-storage-3MGFRYGM.js → keychain-token-storage-37XPR34V.js} +2 -2
  204. package/chunks/list-2HWGSVRA.js +118 -0
  205. package/chunks/{list-agents-EXRSHIDJ.js → list-agents-DI3YFTDT.js} +2 -2
  206. package/chunks/loadedSettingsAdapter-7Y7IEI6T.js +112 -0
  207. package/chunks/{loggingContentGenerator-TUDGCVUG.js → loggingContentGenerator-2GGZNGLG.js} +35 -22
  208. package/chunks/{loop-wakeup-XBPB2BRO.js → loop-wakeup-XJFONSQ7.js} +5 -5
  209. package/chunks/{ls-WFONAND2.js → ls-3VAT2J7A.js} +4 -4
  210. package/chunks/{lsp-DUKPDUXN.js → lsp-5W7IRUBH.js} +2 -2
  211. package/chunks/{managed-npm-update-5K4FWFX2.js → managed-npm-update-5TEV2E3J.js} +54 -54
  212. package/chunks/mcp-QGG5NMJJ.js +112 -0
  213. package/chunks/{monitor-UUHIAGT7.js → monitor-FI7PY36Z.js} +41 -41
  214. package/chunks/nonInteractiveCli-4LO2TL72.js +186 -0
  215. package/chunks/{notebook-edit-GZPB3Q57.js → notebook-edit-TPGMGBST.js} +42 -42
  216. package/chunks/{openaiContentGenerator-RPP6YBS3.js → openaiContentGenerator-SUCYANUZ.js} +24 -24
  217. package/chunks/pidfile-JMF2CLMY.js +113 -0
  218. package/chunks/{processUtils-ENAY2GSA.js → processUtils-IQZBYWSB.js} +2 -2
  219. package/chunks/prompt-terminal-ledger-DCZO6S7C.js +107 -0
  220. package/chunks/{qwenContentGenerator-GLUZVJAU.js → qwenContentGenerator-J4TXFGJT.js} +46 -46
  221. package/chunks/{qwenOAuth2-JIYAWXTW.js → qwenOAuth2-RF33DNZW.js} +8 -8
  222. package/chunks/{read-file-75R5LUWQ.js → read-file-QE2B5FTX.js} +12 -12
  223. package/chunks/{read-mcp-resource-7A7NFSFL.js → read-mcp-resource-XD257PGJ.js} +2 -2
  224. package/chunks/{record-artifact-CPJ4IJSD.js → record-artifact-RZGZBENU.js} +4 -4
  225. package/chunks/{report-findings-VFM5DENC.js → report-findings-Q3SYKKW5.js} +5 -5
  226. package/chunks/{request-shutdown-AXVOFN5C.js → request-shutdown-BCLA3JV2.js} +7 -7
  227. package/chunks/resumeHistoryUtils-CZ4JRDVW.js +120 -0
  228. package/chunks/{ripGrep-FNLXQYBS.js → ripGrep-R6B6HWPX.js} +17 -17
  229. package/chunks/{run-qwen-serve-FJD4VMI2.js → run-qwen-serve-TPHZMSXJ.js} +148 -319
  230. package/chunks/{runtime-INDSJB4K.js → runtime-TTIGSBM4.js} +62 -62
  231. package/chunks/scheduled-tasks-QB4ZVUQS.js +129 -0
  232. package/chunks/{scheduler-Z52TCSUG.js → scheduler-YRUG22M7.js} +55 -55
  233. package/chunks/{sdk-exporters-http-XXSKBD2C.js → sdk-exporters-http-KCJ4ZFG7.js} +2 -2
  234. package/chunks/{sdk-impl-VPNBLV7I.js → sdk-impl-HLSEDAEP.js} +4 -4
  235. package/chunks/{send-message-A2GXDX3B.js → send-message-Y5I6NYAM.js} +7 -7
  236. package/chunks/serve-MXXCDAQN.js +120 -0
  237. package/chunks/{server-PSN5OOSX.js → server-DFUSSSHI.js} +19760 -19444
  238. package/chunks/{session-JPE34X6Q.js → session-3TEHNENZ.js} +100 -99
  239. package/chunks/{settings-IVGC4UYK.js → settings-VOZYKLTT.js} +58 -58
  240. package/chunks/{shell-A5PZGPBR.js → shell-6RTKZVMI.js} +41 -41
  241. package/chunks/{skill-UUXQPDEH.js → skill-FEOKFX26.js} +22 -21
  242. package/chunks/{skill-settings-WVRXLTK4.js → skill-settings-VA4XVYVL.js} +58 -58
  243. package/chunks/spawnChannel-F6WVP723.js +114 -0
  244. package/chunks/{standalone-update-IRFRNGAA.js → standalone-update-RGILUQVK.js} +55 -55
  245. package/chunks/{startInteractiveUI-MC4GLL6G.js → startInteractiveUI-WHJPFOGH.js} +2757 -2223
  246. package/chunks/{syntheticOutput-5AJ444QT.js → syntheticOutput-ML43GEFN.js} +3 -3
  247. package/chunks/{task-create-CDJSOEQD.js → task-create-TMSV7RD5.js} +11 -11
  248. package/chunks/{task-list-BELMPA75.js → task-list-W55RBFRX.js} +5 -5
  249. package/chunks/{task-stop-U3S3KZG2.js → task-stop-CXEH5L2D.js} +2 -2
  250. package/chunks/{task-update-77VCFDDZ.js → task-update-N536I4GQ.js} +11 -11
  251. package/chunks/{team-create-WO5ZBCFW.js → team-create-QYSWCYCL.js} +41 -41
  252. package/chunks/{team-delete-YWFXX77L.js → team-delete-FJRFX33M.js} +5 -5
  253. package/chunks/{team-plan-approval-KAVKRN7U.js → team-plan-approval-P7DAD644.js} +41 -41
  254. package/chunks/{terminal-image-renderer-SMRRNI6Z.js → terminal-image-renderer-SMQE46UJ.js} +55 -55
  255. package/chunks/theme-manager-RFO5WWFF.js +104 -0
  256. package/chunks/{todoWrite-435EO2CS.js → todoWrite-WDJNQEMW.js} +43 -25
  257. package/chunks/{tool-search-FBN6OC6U.js → tool-search-F2EMIAPV.js} +17 -17
  258. package/chunks/total-session-admission-HTVTP4BS.js +116 -0
  259. package/chunks/{trustedFolders-B4LPJBFK.js → trustedFolders-7OCNMUQE.js} +54 -54
  260. package/chunks/{update-relaunch-X5TJVKVG.js → update-relaunch-4GF3OXMB.js} +5 -5
  261. package/chunks/{updateCheck-JCLP5JFT.js → updateCheck-7QBDXZRT.js} +56 -56
  262. package/chunks/useAutoAcceptIndicator-UI4SNL2O.js +122 -0
  263. package/chunks/{validateNonInterActiveAuth-W7HYH5ZN.js → validateNonInterActiveAuth-BPPA563H.js} +96 -95
  264. package/chunks/{version-JG4J76GL.js → version-ANP4TS6O.js} +1 -1
  265. package/chunks/{web-fetch-SPLMEDWF.js → web-fetch-QJADSAH3.js} +16 -16
  266. package/chunks/{web-search-PNW6OEH6.js → web-search-7TTQKEKM.js} +9 -9
  267. package/chunks/{workflow-QHOIIXJO.js → workflow-5XN6XSOT.js} +105 -60
  268. package/chunks/workspace-providers-status-PDFZWL5Q.js +116 -0
  269. package/chunks/{workspace-registration-store-H375IYR2.js → workspace-registration-store-XKVW2YVH.js} +1 -1
  270. package/chunks/{workspace-registry-XTLCD7Z2.js → workspace-registry-23R7XRB5.js} +61 -59
  271. package/chunks/workspace-service-MUYO2QIC.js +131 -0
  272. package/chunks/workspace-skills-status-IKECTOOQ.js +115 -0
  273. package/chunks/{workspace-trust-reconciler-6SC6RKQE.js → workspace-trust-reconciler-KLGOB53D.js} +67 -65
  274. package/chunks/write-file-GGRBB5TZ.js +90 -0
  275. package/chunks/{zh-TW-MV4FWFB6.js → zh-TW-RPTMRTHG.js} +2 -1
  276. package/chunks/{zh-X3WGU6SI.js → zh-UNY63FR3.js} +2 -1
  277. package/chunks/{zoom-image-WGNPZ572.js → zoom-image-6ASG6J4C.js} +12 -12
  278. package/cli.js +14 -14
  279. package/locales/en.js +2 -0
  280. package/locales/zh-TW.js +2 -0
  281. package/locales/zh.js +2 -0
  282. package/package.json +3 -3
  283. package/web-shell/assets/{abnfDiagram-VCTEODGH-yq7z7Anb.js → abnfDiagram-VCTEODGH-uS-vtfs3.js} +1 -1
  284. package/web-shell/assets/{arc-CbJO0xnT.js → arc-BSTnk5pu.js} +1 -1
  285. package/web-shell/assets/{architectureDiagram-5GKGNRK7-CRh89421.js → architectureDiagram-5GKGNRK7-DCMyiqzy.js} +1 -1
  286. package/web-shell/assets/{blockDiagram-NRAW4CY4-C75KAhKv.js → blockDiagram-NRAW4CY4-C7_gt0r1.js} +1 -1
  287. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BzlMveFB.js → c4Diagram-UCG6FXSJ-BeQg2L8B.js} +1 -1
  288. package/web-shell/assets/channel-CENAhErJ.js +1 -0
  289. package/web-shell/assets/{chunk-2Q5K7J3B-DA8QDX3a.js → chunk-2Q5K7J3B-DnV9bKBe.js} +1 -1
  290. package/web-shell/assets/{chunk-5VM5RSS4-Bgu7gQ7Y.js → chunk-5VM5RSS4-rT1GAcT7.js} +1 -1
  291. package/web-shell/assets/{chunk-F27PBJKO-BOew7pIK.js → chunk-F27PBJKO-BcgSxqGA.js} +1 -1
  292. package/web-shell/assets/{chunk-G27WJ6UU-DHx1I-hO.js → chunk-G27WJ6UU-Bw1ZhyZq.js} +1 -1
  293. package/web-shell/assets/{chunk-JWPE2WC7-SarFW0WU.js → chunk-JWPE2WC7-D4iDw-96.js} +1 -1
  294. package/web-shell/assets/{chunk-LCL6LL3I-BLzP083Z.js → chunk-LCL6LL3I-D3MB3GTZ.js} +1 -1
  295. package/web-shell/assets/{chunk-POPQ4Y6H-Bmkv_iKm.js → chunk-POPQ4Y6H-Cep2ndrS.js} +1 -1
  296. package/web-shell/assets/{chunk-SVP7TREG-MPx9r1N2.js → chunk-SVP7TREG-BuahMHJc.js} +1 -1
  297. package/web-shell/assets/{chunk-XXDRQBXY-Ck-09rKG.js → chunk-XXDRQBXY-BdujIvJY.js} +1 -1
  298. package/web-shell/assets/classDiagram-DTDB5LWJ-CM6FArGH.js +1 -0
  299. package/web-shell/assets/classDiagram-v2-JRS7N3AN-CM6FArGH.js +1 -0
  300. package/web-shell/assets/{cose-bilkent-JH36ORCC-DWm6lfOG.js → cose-bilkent-JH36ORCC-CGLLUbF8.js} +1 -1
  301. package/web-shell/assets/{cynefin-OW5HDTMX-DcBUyr5R.js → cynefin-OW5HDTMX-D6kDsRSh.js} +1 -1
  302. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-Df8qmd_p.js → cynefinDiagram-5FMLGOSQ-CCy78qZx.js} +1 -1
  303. package/web-shell/assets/{dagre-3AP2YEHR-DDmGspD7.js → dagre-3AP2YEHR-D5gJuJsf.js} +1 -1
  304. package/web-shell/assets/{diagram-S7CK7UJ4-BK_qFvbi.js → diagram-S7CK7UJ4-ZwEZ5W__.js} +1 -1
  305. package/web-shell/assets/{diagram-UQ7AKVKN-Uw3AP_bi.js → diagram-UQ7AKVKN-B036APjv.js} +1 -1
  306. package/web-shell/assets/{diagram-VSXAHHWV-CJOQKxY7.js → diagram-VSXAHHWV-BfDJ57Fq.js} +1 -1
  307. package/web-shell/assets/{diagram-VX7I27RA-DhdvZna5.js → diagram-VX7I27RA-Wha0p5rT.js} +1 -1
  308. package/web-shell/assets/{diagram-Z3DM3KII-edQU0nlP.js → diagram-Z3DM3KII-L20bz2K1.js} +1 -1
  309. package/web-shell/assets/{ebnfDiagram-PWID7BFC-4kugBEsO.js → ebnfDiagram-PWID7BFC-D1ZM0Cp7.js} +1 -1
  310. package/web-shell/assets/{erDiagram-SSCWMZ5O-BMkFivWO.js → erDiagram-SSCWMZ5O-CMtA19v8.js} +1 -1
  311. package/web-shell/assets/{flowDiagram-A5DVABFB-BM1ea8g-.js → flowDiagram-A5DVABFB-D96m326S.js} +1 -1
  312. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-CXj_cKRf.js → ganttDiagram-EL5Y4UJY-BuHiYG2o.js} +1 -1
  313. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-D0nEqwqu.js → gitGraphDiagram-WWUBYQGX-Ck3NmkSw.js} +1 -1
  314. package/web-shell/assets/index-8hXIpvo4.js +1865 -0
  315. package/web-shell/assets/{index-B6JN54Pd.js → index-CBGz4Qjl.js} +1 -1
  316. package/web-shell/assets/{index-C-XlQn24.css → index-DclEv91i.css} +1 -1
  317. package/web-shell/assets/{infoDiagram-RXCK75RN-DF7aGGbQ.js → infoDiagram-RXCK75RN-B6DAOyXe.js} +1 -1
  318. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-CZYNX1lL.js → ishikawaDiagram-5VMMS53U-Bpg-joFo.js} +1 -1
  319. package/web-shell/assets/{journeyDiagram-EYS64GPL-CvrqMUz1.js → journeyDiagram-EYS64GPL-BclrHzGa.js} +1 -1
  320. package/web-shell/assets/{kanban-definition-3QL26DDD-BZNJQZBj.js → kanban-definition-3QL26DDD-5gJzNTYG.js} +1 -1
  321. package/web-shell/assets/{layout-Bf83x7D6.js → layout-CEz_1L8z.js} +1 -1
  322. package/web-shell/assets/{linear-Bkc3ES2f.js → linear-CBjTq9Hc.js} +1 -1
  323. package/web-shell/assets/{mermaid.core-C6xuovwz.js → mermaid.core-Dzhbxx_I.js} +6 -6
  324. package/web-shell/assets/{mindmap-definition-FBJOCRG2-DzH6gVRg.js → mindmap-definition-FBJOCRG2-DQdVqlBF.js} +1 -1
  325. package/web-shell/assets/{pegDiagram-XKGWAZYB-DCvLh2fa.js → pegDiagram-XKGWAZYB-D1JZlYXL.js} +1 -1
  326. package/web-shell/assets/{pieDiagram-E7YTZNPT-BtjVlx_6.js → pieDiagram-E7YTZNPT-BmkpYL0w.js} +1 -1
  327. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-IbroqxFe.js → quadrantDiagram-AXDQQJYC-DRvD6co5.js} +1 -1
  328. package/web-shell/assets/{railroadDiagram-O6MQD6OU-BvMykiWW.js → railroadDiagram-O6MQD6OU-CEdjDuoo.js} +1 -1
  329. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-D-HHMyrh.js → requirementDiagram-EFPCY7ZU-BCHG-ie8.js} +1 -1
  330. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-C0XXhB6d.js → sankeyDiagram-P5KCCOFB-C9cZMnye.js} +1 -1
  331. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DseAXj5d.js → sequenceDiagram-WJ2MYXX4-DYHRV4zL.js} +1 -1
  332. package/web-shell/assets/{sizeCapture-X5ZJPWSS-Cek2EweK.js → sizeCapture-X5ZJPWSS-DlK21aye.js} +1 -1
  333. package/web-shell/assets/{stateDiagram-HBIQ2CUA-yLv8wafW.js → stateDiagram-HBIQ2CUA-BrmZssvk.js} +1 -1
  334. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-B2Q7XDaE.js +1 -0
  335. package/web-shell/assets/{swimlanes-XN3QIQJK-Cwz-opvE.js → swimlanes-XN3QIQJK-D9xfcayR.js} +1 -1
  336. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-DpZPOSbX.js +8 -0
  337. package/web-shell/assets/{timeline-definition-24CTP7MA-BJuFD7OG.js → timeline-definition-24CTP7MA-D4gdDL_d.js} +1 -1
  338. package/web-shell/assets/{vennDiagram-4TSXK5OY-CNAavdoV.js → vennDiagram-4TSXK5OY-DdhIExjI.js} +1 -1
  339. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-DaIjAidq.js → wardleyDiagram-VM6X3IG4-C9RS_Zof.js} +1 -1
  340. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-DkcQXjTy.js → xychartDiagram-S5SC5T6Z-orRgmxWk.js} +1 -1
  341. package/web-shell/index.html +2 -2
  342. package/chunks/MaxSizedBox-XYQOMOBE.js +0 -112
  343. package/chunks/agent-headless-3ZC4LX3E.js +0 -87
  344. package/chunks/bridge-LFFLHLU5.js +0 -119
  345. package/chunks/channel-settings-store-CAL2HWAH.js +0 -117
  346. package/chunks/chunk-JS73NNWF.js +0 -30
  347. package/chunks/chunk-VGHZT6JR.js +0 -51
  348. package/chunks/config-utils-YMJNA25D.js +0 -113
  349. package/chunks/contextCommand-WMPSNKPG.js +0 -108
  350. package/chunks/daemon-status-provider-YBQAZD3G.js +0 -118
  351. package/chunks/daemon-trust-policy-O75ZSIJN.js +0 -114
  352. package/chunks/deferred-core-runtime-MGCCR6LA.js +0 -116
  353. package/chunks/earlyInputCapture-2EJKJET3.js +0 -109
  354. package/chunks/errors-XEI3SJRV.js +0 -115
  355. package/chunks/handleAutoUpdate-S4CLP36D.js +0 -111
  356. package/chunks/initializer-D3CA3272.js +0 -115
  357. package/chunks/installationInfo-HVDQOSIE.js +0 -109
  358. package/chunks/list-XUDSTGT3.js +0 -118
  359. package/chunks/loadedSettingsAdapter-ZOJ4QEID.js +0 -112
  360. package/chunks/mcp-QJ6AUYE5.js +0 -112
  361. package/chunks/nonInteractiveCli-PAWO75YO.js +0 -185
  362. package/chunks/pidfile-RF3WUFKR.js +0 -113
  363. package/chunks/prompt-terminal-ledger-4CCXZ2LF.js +0 -107
  364. package/chunks/resumeHistoryUtils-GFPJD2XB.js +0 -120
  365. package/chunks/serve-GVD2WXVL.js +0 -120
  366. package/chunks/spawnChannel-KTURLD4B.js +0 -113
  367. package/chunks/theme-manager-A7CPN7F4.js +0 -104
  368. package/chunks/total-session-admission-B7U6UWKQ.js +0 -114
  369. package/chunks/useAutoAcceptIndicator-VBT3NKDM.js +0 -122
  370. package/chunks/workspace-providers-status-653DTR35.js +0 -116
  371. package/chunks/workspace-service-KVJWACCS.js +0 -131
  372. package/chunks/workspace-skills-status-TRJ2VWGU.js +0 -115
  373. package/chunks/write-file-EAZSJZKR.js +0 -90
  374. package/web-shell/assets/channel-B3sGR79J.js +0 -1
  375. package/web-shell/assets/classDiagram-DTDB5LWJ-sTGo0K3v.js +0 -1
  376. package/web-shell/assets/classDiagram-v2-JRS7N3AN-sTGo0K3v.js +0 -1
  377. package/web-shell/assets/index-DLjXM0dn.js +0 -1860
  378. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DeThXnol.js +0 -1
  379. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-GW0R1ZSv.js +0 -8
@@ -0,0 +1,1584 @@
1
+ // Force strict mode and setup for ESM
2
+ "use strict";
3
+ import {
4
+ parseChannelDelivery
5
+ } from "./chunk-4CMJKUND.js";
6
+ import {
7
+ parseCallerSuppliedSessionId
8
+ } from "./chunk-ZEZKIS2K.js";
9
+ import {
10
+ isInternalWorkspaceRuntime
11
+ } from "./chunk-NYWWQ437.js";
12
+ import {
13
+ SessionNotFoundError
14
+ } from "./chunk-ERFDKH32.js";
15
+ import {
16
+ canonicalizeWorkspace
17
+ } from "./chunk-6PLDPT2C.js";
18
+ import {
19
+ isChannelDeliveryError
20
+ } from "./chunk-RKFGE7JH.js";
21
+ import {
22
+ SessionService,
23
+ stripTerminalControlSequences
24
+ } from "./chunk-TGWAQ5RB.js";
25
+ import {
26
+ MAX_JOBS,
27
+ nextDurableFireMs
28
+ } from "./chunk-EKSCLBBF.js";
29
+ import {
30
+ nextFireTime,
31
+ parseCron
32
+ } from "./chunk-IRH27ZC2.js";
33
+ import {
34
+ appendCronRun,
35
+ generateCronTaskId,
36
+ readCronTasks,
37
+ taskHasLegacyCondition,
38
+ updateCronTasks
39
+ } from "./chunk-D5LUXLUH.js";
40
+ import {
41
+ Storage
42
+ } from "./chunk-UHQFIS7N.js";
43
+ import {
44
+ writeStderrLine
45
+ } from "./chunk-KGJGEEVR.js";
46
+ import {
47
+ init_esbuild_shims
48
+ } from "./chunk-5O2XNYP6.js";
49
+ import {
50
+ __name
51
+ } from "./chunk-J2S4EL5Y.js";
52
+
53
+ // packages/cli/src/serve/routes/scheduled-tasks.ts
54
+ init_esbuild_shims();
55
+ import { isDeepStrictEqual } from "node:util";
56
+
57
+ // packages/cli/src/serve/workspace-route-runtime.ts
58
+ init_esbuild_shims();
59
+ import * as fs from "node:fs";
60
+ import path from "node:path";
61
+ function resolveWorkspaceEntryFromParam(registry, req, res, paramName = "workspace") {
62
+ const selector = req.params[paramName] ?? "";
63
+ const byId = registry.getEntryByWorkspaceId(selector);
64
+ if (byId) return byId;
65
+ if (!isPortableAbsolutePath(selector)) {
66
+ res.status(400).json({
67
+ error: `\`:${paramName}\` must decode to a workspace id or absolute path`,
68
+ code: "workspace_mismatch"
69
+ });
70
+ return null;
71
+ }
72
+ const exact = registry.getEntryByWorkspaceCwd(selector);
73
+ if (exact) return exact;
74
+ if (path.isAbsolute(selector) && !isUncPath(selector)) {
75
+ try {
76
+ const canonicalSelector = canonicalizeWorkspace(selector);
77
+ const canonicalMatch = registry.getEntryByWorkspaceCwd(canonicalSelector);
78
+ if (canonicalMatch) return canonicalMatch;
79
+ for (const candidate of registry.listEntries()) {
80
+ if (canonicalizeWorkspace(candidate.workspaceCwd) === canonicalSelector) {
81
+ return candidate;
82
+ }
83
+ }
84
+ } catch {
85
+ }
86
+ }
87
+ const normalizedSelector = normalizePortableAbsolutePath(selector);
88
+ const entry = registry.listEntries().find(
89
+ (candidate) => normalizePortableAbsolutePath(candidate.workspaceCwd) === normalizedSelector
90
+ );
91
+ if (!entry) {
92
+ sendWorkspaceMismatch(res, registry);
93
+ return null;
94
+ }
95
+ return entry;
96
+ }
97
+ __name(resolveWorkspaceEntryFromParam, "resolveWorkspaceEntryFromParam");
98
+ function isPortableAbsolutePath(value) {
99
+ return path.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || /^\\\\[^\\]+\\[^\\]+/.test(value);
100
+ }
101
+ __name(isPortableAbsolutePath, "isPortableAbsolutePath");
102
+ function isUncPath(value) {
103
+ return /^\\\\[^\\]+\\[^\\]+/.test(value);
104
+ }
105
+ __name(isUncPath, "isUncPath");
106
+ function normalizePortableAbsolutePath(value) {
107
+ if (/^[A-Za-z]:[\\/]/.test(value) || /^\\\\[^\\]+\\[^\\]+/.test(value)) {
108
+ return path.win32.normalize(value).toLowerCase();
109
+ }
110
+ return path.resolve(value);
111
+ }
112
+ __name(normalizePortableAbsolutePath, "normalizePortableAbsolutePath");
113
+ function resolveRegisteredWorkspaceRuntimeByPathSelector(registry, selector) {
114
+ const exact = registry.getByWorkspaceCwd(selector);
115
+ if (exact) return exact;
116
+ if (path.isAbsolute(selector) && !isUncPath(selector)) {
117
+ try {
118
+ const canonicalSelector = canonicalizeWorkspace(selector);
119
+ const canonicalMatch = registry.getByWorkspaceCwd(canonicalSelector);
120
+ if (canonicalMatch) return canonicalMatch;
121
+ for (const runtime of registry.list()) {
122
+ if (canonicalizeWorkspace(runtime.workspaceCwd) === canonicalSelector) {
123
+ return runtime;
124
+ }
125
+ }
126
+ } catch {
127
+ }
128
+ }
129
+ const normalizedSelector = normalizePortableAbsolutePath(selector);
130
+ return registry.list().find(
131
+ (runtime) => normalizePortableAbsolutePath(runtime.workspaceCwd) === normalizedSelector
132
+ );
133
+ }
134
+ __name(resolveRegisteredWorkspaceRuntimeByPathSelector, "resolveRegisteredWorkspaceRuntimeByPathSelector");
135
+ function resolveManagedWorkspaceRuntimeByPathSelector(registry, selector) {
136
+ const exact = registry.getManagedByWorkspaceCwd(selector);
137
+ if (exact && !isInternalWorkspaceRuntime(exact)) return exact;
138
+ if (path.isAbsolute(selector) && !isUncPath(selector)) {
139
+ try {
140
+ const canonicalSelector = canonicalizeWorkspace(selector);
141
+ const canonicalMatch = registry.getManagedByWorkspaceCwd(canonicalSelector);
142
+ if (canonicalMatch && !isInternalWorkspaceRuntime(canonicalMatch)) {
143
+ return canonicalMatch;
144
+ }
145
+ for (const runtime of registry.listManaged()) {
146
+ if (isInternalWorkspaceRuntime(runtime)) continue;
147
+ if (canonicalizeWorkspace(runtime.workspaceCwd) === canonicalSelector) {
148
+ return runtime;
149
+ }
150
+ }
151
+ } catch {
152
+ }
153
+ }
154
+ const normalizedSelector = normalizePortableAbsolutePath(selector);
155
+ return registry.listManaged().find(
156
+ (runtime) => !isInternalWorkspaceRuntime(runtime) && normalizePortableAbsolutePath(runtime.workspaceCwd) === normalizedSelector
157
+ );
158
+ }
159
+ __name(resolveManagedWorkspaceRuntimeByPathSelector, "resolveManagedWorkspaceRuntimeByPathSelector");
160
+ function resolveWorkspaceRuntimeFromParam(registry, req, res, paramName = "workspace") {
161
+ const entry = resolveWorkspaceEntryFromParam(registry, req, res, paramName);
162
+ if (!entry) return null;
163
+ const runtime = entry.state === "active" ? entry.current?.runtime : void 0;
164
+ if (!runtime) {
165
+ sendWorkspaceRuntimeUnavailable(res, entry);
166
+ return null;
167
+ }
168
+ return runtime;
169
+ }
170
+ __name(resolveWorkspaceRuntimeFromParam, "resolveWorkspaceRuntimeFromParam");
171
+ function resolveTrustedRuntime(registry, req, res, paramName = "workspace") {
172
+ const runtime = resolveWorkspaceRuntimeFromParam(
173
+ registry,
174
+ req,
175
+ res,
176
+ paramName
177
+ );
178
+ if (!runtime) return null;
179
+ return requireTrustedWorkspaceRuntime(runtime, res) ? runtime : null;
180
+ }
181
+ __name(resolveTrustedRuntime, "resolveTrustedRuntime");
182
+ function resolveWorkspaceRuntimeWithLiveCompatibilityFromParam(registry, req, res, paramName = "workspace") {
183
+ if (typeof registry.getManagedEntryByWorkspaceId !== "function" || typeof registry.getManagedEntryByWorkspaceCwd !== "function") {
184
+ return resolveWorkspaceRuntimeFromParam(registry, req, res, paramName);
185
+ }
186
+ const selector = req.params[paramName] ?? "";
187
+ let entry = registry.getManagedEntryByWorkspaceId(selector);
188
+ if (!entry && isPortableAbsolutePath(selector)) {
189
+ entry = registry.getManagedEntryByWorkspaceCwd(selector);
190
+ }
191
+ if (!entry?.internal) {
192
+ return resolveWorkspaceRuntimeFromParam(registry, req, res, paramName);
193
+ }
194
+ const runtime = entry.state === "active" ? entry.current?.runtime : void 0;
195
+ if (!runtime) {
196
+ sendConversationRuntimeUnavailable(res);
197
+ return null;
198
+ }
199
+ return runtime;
200
+ }
201
+ __name(resolveWorkspaceRuntimeWithLiveCompatibilityFromParam, "resolveWorkspaceRuntimeWithLiveCompatibilityFromParam");
202
+ function sendConversationRuntimeUnavailable(res) {
203
+ res.set("Retry-After", "1");
204
+ res.status(503).json({
205
+ error: "The Conversations runtime is temporarily unavailable.",
206
+ code: "conversation_runtime_unavailable",
207
+ retryable: true
208
+ });
209
+ }
210
+ __name(sendConversationRuntimeUnavailable, "sendConversationRuntimeUnavailable");
211
+ function sendWorkspaceRuntimeUnavailable(res, entry) {
212
+ res.set("Retry-After", "1");
213
+ res.status(503).json({
214
+ error: "Workspace runtime is not active.",
215
+ code: "workspace_runtime_unavailable",
216
+ ...entry ? { workspaceCwd: entry.workspaceCwd, workspaceId: entry.workspaceId } : {}
217
+ });
218
+ }
219
+ __name(sendWorkspaceRuntimeUnavailable, "sendWorkspaceRuntimeUnavailable");
220
+ function isGenerationClosedError(error) {
221
+ return Boolean(
222
+ error && typeof error === "object" && "code" in error && error.code === "workspace_generation_closed"
223
+ );
224
+ }
225
+ __name(isGenerationClosedError, "isGenerationClosedError");
226
+ function sendGenerationClosedError(res, error) {
227
+ if (!isGenerationClosedError(error)) return false;
228
+ sendWorkspaceRuntimeUnavailable(res);
229
+ return true;
230
+ }
231
+ __name(sendGenerationClosedError, "sendGenerationClosedError");
232
+ function resolveManagedWorkspaceRuntimeFromParam(registry, req, res, paramName = "workspace") {
233
+ const selector = req.params[paramName] ?? "";
234
+ const byId = registry.getManagedByWorkspaceId(selector);
235
+ if (byId && !isInternalWorkspaceRuntime(byId)) return byId;
236
+ if (!isPortableAbsolutePath(selector)) {
237
+ res.status(400).json({
238
+ error: `\`:${paramName}\` must decode to a workspace id or absolute path`,
239
+ code: "workspace_mismatch"
240
+ });
241
+ return null;
242
+ }
243
+ const runtime = resolveManagedWorkspaceRuntimeByPathSelector(
244
+ registry,
245
+ selector
246
+ );
247
+ if (!runtime) {
248
+ res.status(400).json({
249
+ error: "Workspace mismatch: the requested workspace is not registered with this daemon.",
250
+ code: "workspace_mismatch"
251
+ });
252
+ return null;
253
+ }
254
+ return runtime;
255
+ }
256
+ __name(resolveManagedWorkspaceRuntimeFromParam, "resolveManagedWorkspaceRuntimeFromParam");
257
+ function requireTrustedWorkspaceRuntime(runtime, res) {
258
+ if (runtime.trusted) return true;
259
+ sendUntrustedWorkspaceResponse(res);
260
+ return false;
261
+ }
262
+ __name(requireTrustedWorkspaceRuntime, "requireTrustedWorkspaceRuntime");
263
+ function sendUntrustedWorkspaceResponse(res, extra) {
264
+ res.status(403).json({
265
+ error: "Workspace is not trusted.",
266
+ code: "untrusted_workspace",
267
+ ...extra
268
+ });
269
+ }
270
+ __name(sendUntrustedWorkspaceResponse, "sendUntrustedWorkspaceResponse");
271
+ function getWorkspaceRouteContext(req) {
272
+ return req.workspaceRouteContext;
273
+ }
274
+ __name(getWorkspaceRouteContext, "getWorkspaceRouteContext");
275
+ function setWorkspaceRouteContext(req, context) {
276
+ req.workspaceRouteContext = context;
277
+ }
278
+ __name(setWorkspaceRouteContext, "setWorkspaceRouteContext");
279
+ function sendWorkspaceMismatch(res, registry) {
280
+ res.status(400).json({
281
+ error: "Workspace mismatch: the requested workspace is not registered with this daemon.",
282
+ code: "workspace_mismatch",
283
+ workspaceCount: registry.listEntries().length
284
+ });
285
+ }
286
+ __name(sendWorkspaceMismatch, "sendWorkspaceMismatch");
287
+ function resolveContainedCwd(req, workspaceCwd) {
288
+ const rawCwd = req.query["cwd"];
289
+ if (typeof rawCwd !== "string" || rawCwd.length === 0) {
290
+ return workspaceCwd;
291
+ }
292
+ try {
293
+ const resolved = fs.realpathSync(path.resolve(rawCwd));
294
+ const root = fs.realpathSync(workspaceCwd);
295
+ const rel = path.relative(root, resolved);
296
+ if (!rel.startsWith("..") && !path.isAbsolute(rel)) {
297
+ return resolved;
298
+ }
299
+ } catch {
300
+ }
301
+ return workspaceCwd;
302
+ }
303
+ __name(resolveContainedCwd, "resolveContainedCwd");
304
+ function resolveContainedCwdOrFail(req, workspaceCwd) {
305
+ const rawCwd = req.query["cwd"];
306
+ if (rawCwd === void 0) {
307
+ return workspaceCwd;
308
+ }
309
+ if (typeof rawCwd !== "string" || rawCwd.length === 0) {
310
+ return null;
311
+ }
312
+ try {
313
+ const resolved = fs.realpathSync(path.resolve(rawCwd));
314
+ const root = fs.realpathSync(workspaceCwd);
315
+ const rel = path.relative(root, resolved);
316
+ if (!rel.startsWith("..") && !path.isAbsolute(rel)) {
317
+ return resolved;
318
+ }
319
+ } catch {
320
+ }
321
+ return null;
322
+ }
323
+ __name(resolveContainedCwdOrFail, "resolveContainedCwdOrFail");
324
+
325
+ // packages/cli/src/serve/routes/scheduled-tasks.ts
326
+ var MAX_SCHEDULED_TASKS = MAX_JOBS;
327
+ var MAX_PROMPT_LENGTH = 1e5;
328
+ var MAX_NAME_LENGTH = 200;
329
+ var MAX_CRON_LENGTH = 200;
330
+ var MAX_SESSION_NAME_LENGTH = 60;
331
+ function scheduledTaskSessionName(label) {
332
+ const cleaned = stripTerminalControlSequences(label).replace(/[\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/g, "").trim().replace(/\s+/g, " ");
333
+ let short = cleaned;
334
+ if (cleaned.length > MAX_SESSION_NAME_LENGTH) {
335
+ let cut = MAX_SESSION_NAME_LENGTH - 1;
336
+ const boundary = cleaned.charCodeAt(cut - 1);
337
+ if (boundary >= 55296 && boundary <= 56319) cut -= 1;
338
+ short = `${cleaned.slice(0, cut)}\u2026`;
339
+ }
340
+ return `\u23F0 ${short}`;
341
+ }
342
+ __name(scheduledTaskSessionName, "scheduledTaskSessionName");
343
+ var ExistingSessionScheduledTaskCreateError = class extends Error {
344
+ constructor(status, code, message) {
345
+ super(message);
346
+ this.status = status;
347
+ this.code = code;
348
+ this.name = "ExistingSessionScheduledTaskCreateError";
349
+ }
350
+ static {
351
+ __name(this, "ExistingSessionScheduledTaskCreateError");
352
+ }
353
+ };
354
+ function assertReusableScheduledTaskSession(target, sessionId, allowActivePrompt, assertCallerPromptActive) {
355
+ const { bridge, workspaceCwd } = target;
356
+ if (!bridge) {
357
+ throw new ExistingSessionScheduledTaskCreateError(
358
+ 409,
359
+ "session_binding_unavailable",
360
+ "Session management is not available for this workspace"
361
+ );
362
+ }
363
+ assertCallerPromptActive?.();
364
+ let owner;
365
+ try {
366
+ owner = target.resolveLiveSessionOwner?.(sessionId);
367
+ } catch (error) {
368
+ writeStderrLine(
369
+ `qwen serve: failed to resolve scheduled-task session owner '${sessionId}': ${error instanceof Error ? error.message : String(error)}`
370
+ );
371
+ throw new ExistingSessionScheduledTaskCreateError(
372
+ 500,
373
+ "scheduled_tasks_session_failed",
374
+ "Failed to look up the requested session"
375
+ );
376
+ }
377
+ if (owner?.kind === "unavailable") {
378
+ throw new ExistingSessionScheduledTaskCreateError(
379
+ 503,
380
+ "workspace_runtime_unavailable",
381
+ "The workspace runtime is unavailable"
382
+ );
383
+ }
384
+ if (owner?.kind === "ambiguous") {
385
+ throw new ExistingSessionScheduledTaskCreateError(
386
+ 500,
387
+ "ambiguous_session_owner",
388
+ `Session owner is ambiguous for "${sessionId}"`
389
+ );
390
+ }
391
+ if (owner?.kind === "found" && owner.runtime.workspaceCwd !== workspaceCwd) {
392
+ throw new ExistingSessionScheduledTaskCreateError(
393
+ 400,
394
+ "session_workspace_mismatch",
395
+ "The requested session belongs to a different workspace; use that workspace's scheduled-task endpoint"
396
+ );
397
+ }
398
+ let summary;
399
+ try {
400
+ summary = bridge.getSessionSummary(sessionId);
401
+ } catch (error) {
402
+ if (error instanceof SessionNotFoundError) {
403
+ throw new ExistingSessionScheduledTaskCreateError(
404
+ 404,
405
+ "session_not_found",
406
+ `Session '${sessionId}' was not found`
407
+ );
408
+ }
409
+ writeStderrLine(
410
+ `qwen serve: failed to look up scheduled-task session '${sessionId}': ${error instanceof Error ? error.message : String(error)}`
411
+ );
412
+ throw new ExistingSessionScheduledTaskCreateError(
413
+ 500,
414
+ "scheduled_tasks_session_failed",
415
+ "Failed to look up the requested session"
416
+ );
417
+ }
418
+ if (summary.workspaceCwd !== workspaceCwd) {
419
+ throw new ExistingSessionScheduledTaskCreateError(
420
+ 400,
421
+ "session_workspace_mismatch",
422
+ "The requested session belongs to a different workspace; use that workspace's scheduled-task endpoint"
423
+ );
424
+ }
425
+ if (!allowActivePrompt && summary.hasActivePrompt || (summary.pendingInteractionCount ?? 0) > 0) {
426
+ throw new ExistingSessionScheduledTaskCreateError(
427
+ 409,
428
+ "session_busy",
429
+ allowActivePrompt ? "The caller session has a pending interaction; resolve it before binding the session to a task" : "The requested session is busy; wait for its active prompt or pending interaction to finish before binding it to a task"
430
+ );
431
+ }
432
+ if (summary.sourceType === "scheduled_task") {
433
+ throw new ExistingSessionScheduledTaskCreateError(
434
+ 409,
435
+ "session_already_bound",
436
+ "The requested session is already reserved for a scheduled task"
437
+ );
438
+ }
439
+ if (summary.parentSessionId !== void 0 || summary.sourceId !== void 0 || summary.sourceType !== void 0 && summary.sourceType !== "default") {
440
+ throw new ExistingSessionScheduledTaskCreateError(
441
+ 409,
442
+ "session_source_ineligible",
443
+ "The requested session source cannot own a scheduled task"
444
+ );
445
+ }
446
+ }
447
+ __name(assertReusableScheduledTaskSession, "assertReusableScheduledTaskSession");
448
+ async function createScheduledTaskWithExistingSession(target, input, options) {
449
+ if (input.cron.length === 0 || input.cron.length > MAX_CRON_LENGTH || validateCron(input.cron) !== null) {
450
+ throw new ExistingSessionScheduledTaskCreateError(
451
+ 400,
452
+ "invalid_cron",
453
+ "The scheduled-task cron expression is invalid"
454
+ );
455
+ }
456
+ const prompt = input.prompt.trim();
457
+ if (prompt.length === 0 || prompt.length > MAX_PROMPT_LENGTH) {
458
+ throw new ExistingSessionScheduledTaskCreateError(
459
+ 400,
460
+ "invalid_prompt",
461
+ "The scheduled-task prompt is invalid"
462
+ );
463
+ }
464
+ const allowActivePrompt = options.source === "cron-tool";
465
+ const assertCallerPromptActive = options.source === "cron-tool" ? options.assertCallerPromptActive : void 0;
466
+ assertReusableScheduledTaskSession(
467
+ target,
468
+ input.sessionId,
469
+ allowActivePrompt,
470
+ assertCallerPromptActive
471
+ );
472
+ target.assertGenerationOpen?.();
473
+ if (options.source === "rest") {
474
+ const ensurePersisted = target.bridge?.ensureDefaultSessionPersisted;
475
+ if (!ensurePersisted) {
476
+ throw new ExistingSessionScheduledTaskCreateError(
477
+ 409,
478
+ "session_binding_unavailable",
479
+ "Session persistence is not available for this workspace"
480
+ );
481
+ }
482
+ try {
483
+ await ensurePersisted.call(target.bridge, input.sessionId);
484
+ } catch (error) {
485
+ target.assertGenerationOpen?.();
486
+ if (error instanceof SessionNotFoundError) {
487
+ throw new ExistingSessionScheduledTaskCreateError(
488
+ 404,
489
+ "session_not_found",
490
+ `Session '${input.sessionId}' was not found`
491
+ );
492
+ }
493
+ writeStderrLine(
494
+ `qwen serve: failed to persist scheduled-task session '${input.sessionId}': ${error instanceof Error ? error.message : String(error)}`
495
+ );
496
+ throw new ExistingSessionScheduledTaskCreateError(
497
+ 500,
498
+ "session_persistence_failed",
499
+ "Failed to persist the requested session"
500
+ );
501
+ }
502
+ target.assertGenerationOpen?.();
503
+ }
504
+ const now = Date.now();
505
+ const task = {
506
+ id: generateCronTaskId(),
507
+ cron: input.cron,
508
+ prompt,
509
+ recurring: input.recurring,
510
+ createdAt: now,
511
+ lastFiredAt: now - now % 6e4,
512
+ enabled: input.enabled !== false,
513
+ sessionId: input.sessionId,
514
+ sessionOwnedByTask: false,
515
+ ...input.delivery !== void 0 ? { delivery: input.delivery } : {},
516
+ ...input.name !== void 0 ? { name: input.name } : {}
517
+ };
518
+ let before;
519
+ let after;
520
+ await runWithScheduledTaskTarget(
521
+ target,
522
+ () => updateCronTasks(
523
+ target.workspaceCwd,
524
+ (tasks) => {
525
+ assertReusableScheduledTaskSession(
526
+ target,
527
+ input.sessionId,
528
+ allowActivePrompt,
529
+ assertCallerPromptActive
530
+ );
531
+ if (tasks.some((candidate) => candidate.sessionId === input.sessionId)) {
532
+ throw new ExistingSessionScheduledTaskCreateError(
533
+ 409,
534
+ "session_already_bound",
535
+ "The requested session is already bound to another scheduled task"
536
+ );
537
+ }
538
+ if (tasks.length >= MAX_SCHEDULED_TASKS) {
539
+ throw new ExistingSessionScheduledTaskCreateError(
540
+ 409,
541
+ "max_tasks_reached",
542
+ `Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`
543
+ );
544
+ }
545
+ before = tasks;
546
+ after = [...tasks, task];
547
+ return after;
548
+ },
549
+ { assertCanCommit: target.assertGenerationOpen }
550
+ )
551
+ );
552
+ try {
553
+ target.assertGenerationOpen?.();
554
+ } catch (error) {
555
+ await rollbackCronMutation(target, before, after, "scheduled-task create");
556
+ throw error;
557
+ }
558
+ return task;
559
+ }
560
+ __name(createScheduledTaskWithExistingSession, "createScheduledTaskWithExistingSession");
561
+ function requireOpenGeneration(target, res) {
562
+ try {
563
+ target.assertGenerationOpen?.();
564
+ return true;
565
+ } catch (error) {
566
+ if (sendGenerationClosedError(res, error)) return false;
567
+ throw error;
568
+ }
569
+ }
570
+ __name(requireOpenGeneration, "requireOpenGeneration");
571
+ async function rollbackCronMutation(target, before, after, route) {
572
+ if (!before || !after) return;
573
+ await runWithScheduledTaskTarget(
574
+ target,
575
+ () => updateCronTasks(
576
+ target.workspaceCwd,
577
+ (tasks) => isDeepStrictEqual(tasks, after) ? before : tasks
578
+ )
579
+ ).catch((error) => {
580
+ writeStderrLine(
581
+ `qwen serve: ${route} failed to roll back a stale task mutation: ${error instanceof Error ? error.message : String(error)}`
582
+ );
583
+ });
584
+ }
585
+ __name(rollbackCronMutation, "rollbackCronMutation");
586
+ async function teardownBoundSession(target, sessionId) {
587
+ if (target.cleanupSession) {
588
+ await target.cleanupSession(sessionId).catch(() => {
589
+ });
590
+ } else if (target.bridge) {
591
+ await target.bridge.closeSession(sessionId).catch(() => {
592
+ });
593
+ const removed = await new SessionService(target.workspaceCwd, {
594
+ runtimeBaseDir: target.runtimeBaseDir
595
+ }).removeSession(sessionId).catch(() => false);
596
+ if (removed) target.bridge.markSessionCatalogChanged?.();
597
+ }
598
+ }
599
+ __name(teardownBoundSession, "teardownBoundSession");
600
+ async function runWithScheduledTaskTarget(target, fn) {
601
+ const result = target.runtimeBaseDir === void 0 ? fn() : Storage.runWithResolvedRuntimeBaseDir(target.runtimeBaseDir, fn);
602
+ return await result;
603
+ }
604
+ __name(runWithScheduledTaskTarget, "runWithScheduledTaskTarget");
605
+ function sendActivityGateError(res, error) {
606
+ if (!error || typeof error !== "object" || error.code !== "daemon_draining") {
607
+ return false;
608
+ }
609
+ res.status(503).json({
610
+ error: "The daemon is draining and no longer accepts work.",
611
+ code: "daemon_draining"
612
+ });
613
+ return true;
614
+ }
615
+ __name(sendActivityGateError, "sendActivityGateError");
616
+ function computeNextRunAt(task) {
617
+ if (task.enabled === false) return null;
618
+ return nextDurableFireMs(task);
619
+ }
620
+ __name(computeNextRunAt, "computeNextRunAt");
621
+ function toView(task) {
622
+ return {
623
+ id: task.id,
624
+ name: typeof task.name === "string" && task.name.length > 0 ? task.name : null,
625
+ cron: task.cron,
626
+ prompt: task.prompt,
627
+ recurring: task.recurring,
628
+ // Absent enabled defaults to enabled — tool-created tasks never write it.
629
+ // A legacy guarded task (isolated run mode + precondition, both removed) is
630
+ // reported as NOT runnable — `enabled: false` with no `nextRunAt` — so the
631
+ // management UI never shows it as active or offers a Run affordance for a
632
+ // task the scheduler refuses to fire. Fail closed on the read path too, not
633
+ // just the tick. `POST /:id/run` rejects it as a second guard.
634
+ enabled: task.enabled !== false && !taskHasLegacyCondition(task),
635
+ createdAt: task.createdAt,
636
+ lastFiredAt: task.lastFiredAt,
637
+ nextRunAt: taskHasLegacyCondition(task) ? null : computeNextRunAt(task),
638
+ // The task's bound session (its run-history transcript), or null for an
639
+ // unbound tool-created/legacy task.
640
+ sessionId: typeof task.sessionId === "string" && task.sessionId.length > 0 ? task.sessionId : null,
641
+ // Absent runs (tool-created / never-fired) normalizes to [] so the client
642
+ // never special-cases undefined.
643
+ runs: Array.isArray(task.runs) ? task.runs : [],
644
+ ...task.delivery !== void 0 ? { delivery: task.delivery } : {}
645
+ };
646
+ }
647
+ __name(toView, "toView");
648
+ function validateCron(cron) {
649
+ try {
650
+ parseCron(cron);
651
+ nextFireTime(cron, /* @__PURE__ */ new Date());
652
+ return null;
653
+ } catch (err) {
654
+ return err instanceof Error ? err.message : String(err);
655
+ }
656
+ }
657
+ __name(validateCron, "validateCron");
658
+ function canonicalCron(cron) {
659
+ try {
660
+ const f = parseCron(cron);
661
+ const s = /* @__PURE__ */ __name((set) => [...set].sort((a, b) => a - b).join(","), "s");
662
+ return [
663
+ s(f.minute),
664
+ s(f.hour),
665
+ s(f.dayOfMonth),
666
+ s(f.month),
667
+ s(f.dayOfWeek),
668
+ f.domIsWild ? "W" : "",
669
+ f.dowIsWild ? "W" : ""
670
+ ].join("|");
671
+ } catch {
672
+ return null;
673
+ }
674
+ }
675
+ __name(canonicalCron, "canonicalCron");
676
+ function registerScheduledTaskCrudRoutes(app, deps) {
677
+ const {
678
+ prefix,
679
+ resolveTarget,
680
+ mutate,
681
+ safeBody,
682
+ channelDeliveryAuthorizations
683
+ } = deps;
684
+ const base = `${prefix}/scheduled-tasks`;
685
+ const withTarget = /* @__PURE__ */ __name((handler) => async (req, res) => {
686
+ const target = resolveTarget(req, res);
687
+ if (!target) return;
688
+ const operation = /* @__PURE__ */ __name(async () => {
689
+ if (!requireOpenGeneration(target, res)) return;
690
+ await handler(req, res, target);
691
+ }, "operation");
692
+ try {
693
+ if (target.activity) {
694
+ await target.activity.run(operation);
695
+ } else {
696
+ await operation();
697
+ }
698
+ } catch (error) {
699
+ if (sendActivityGateError(res, error)) return;
700
+ throw error;
701
+ }
702
+ }, "withTarget");
703
+ app.get(
704
+ base,
705
+ withTarget(async (_req, res, target) => {
706
+ try {
707
+ const tasks = await runWithScheduledTaskTarget(
708
+ target,
709
+ () => readCronTasks(target.workspaceCwd)
710
+ );
711
+ if (!requireOpenGeneration(target, res)) return;
712
+ res.status(200).json({ v: 1, tasks: tasks.map(toView) });
713
+ } catch (err) {
714
+ if (sendActivityGateError(res, err)) return;
715
+ writeStderrLine(
716
+ `qwen serve: GET ${base} failed: ${err instanceof Error ? err.message : String(err)}`
717
+ );
718
+ res.status(500).json({
719
+ error: "Failed to read scheduled tasks (the tasks file may be corrupt)",
720
+ code: "scheduled_tasks_read_failed"
721
+ });
722
+ }
723
+ })
724
+ );
725
+ app.post(
726
+ base,
727
+ mutate(),
728
+ withTarget(async (req, res, target) => {
729
+ const { workspaceCwd, bridge } = target;
730
+ const body = safeBody(req);
731
+ const cron = typeof body["cron"] === "string" ? body["cron"].trim() : "";
732
+ if (cron.length === 0) {
733
+ res.status(400).json({
734
+ error: "`cron` is required and must be a non-empty string",
735
+ code: "invalid_cron"
736
+ });
737
+ return;
738
+ }
739
+ if (cron.length > MAX_CRON_LENGTH) {
740
+ res.status(400).json({
741
+ error: `\`cron\` exceeds ${MAX_CRON_LENGTH}-character limit`,
742
+ code: "invalid_cron"
743
+ });
744
+ return;
745
+ }
746
+ const cronError = validateCron(cron);
747
+ if (cronError) {
748
+ res.status(400).json({ error: cronError, code: "invalid_cron" });
749
+ return;
750
+ }
751
+ const prompt = typeof body["prompt"] === "string" ? body["prompt"].trim() : "";
752
+ if (prompt.length === 0) {
753
+ res.status(400).json({
754
+ error: "`prompt` is required and must be a non-empty string",
755
+ code: "invalid_prompt"
756
+ });
757
+ return;
758
+ }
759
+ if (prompt.length > MAX_PROMPT_LENGTH) {
760
+ res.status(400).json({
761
+ error: `\`prompt\` exceeds ${MAX_PROMPT_LENGTH}-character limit`,
762
+ code: "invalid_prompt"
763
+ });
764
+ return;
765
+ }
766
+ const nameResult = parseNameField(body["name"]);
767
+ if (nameResult.error) {
768
+ res.status(400).json({ error: nameResult.error, code: "invalid_name" });
769
+ return;
770
+ }
771
+ if (body["recurring"] !== void 0 && typeof body["recurring"] !== "boolean") {
772
+ res.status(400).json({
773
+ error: "`recurring` must be a boolean",
774
+ code: "invalid_recurring"
775
+ });
776
+ return;
777
+ }
778
+ if (body["enabled"] !== void 0 && typeof body["enabled"] !== "boolean") {
779
+ res.status(400).json({
780
+ error: "`enabled` must be a boolean",
781
+ code: "invalid_enabled"
782
+ });
783
+ return;
784
+ }
785
+ const parsedSessionId = parseCallerSuppliedSessionId(body["sessionId"]);
786
+ if (parsedSessionId.kind === "invalid") {
787
+ res.status(400).json({
788
+ error: '`sessionId` must be an RFC UUID v1-v5 (e.g. "550e8400-e29b-41d4-a716-446655440000")',
789
+ code: "invalid_session_id"
790
+ });
791
+ return;
792
+ }
793
+ const providedSessionId = parsedSessionId.kind === "valid" ? parsedSessionId.sessionId : void 0;
794
+ let delivery;
795
+ if (body["delivery"] !== void 0) {
796
+ try {
797
+ delivery = parseChannelDelivery(body["delivery"]);
798
+ } catch (err) {
799
+ if (!isChannelDeliveryError(err)) throw err;
800
+ res.status(400).json({ error: err.message, code: err.code });
801
+ return;
802
+ }
803
+ }
804
+ const removedField = findRemovedTaskField(body);
805
+ if (removedField) {
806
+ res.status(400).json(removedFieldError(removedField));
807
+ return;
808
+ }
809
+ const recurring = body["recurring"] !== false;
810
+ const enabled = body["enabled"] !== false;
811
+ const taskId = generateCronTaskId();
812
+ if (providedSessionId !== void 0) {
813
+ try {
814
+ const task2 = await createScheduledTaskWithExistingSession(
815
+ target,
816
+ {
817
+ sessionId: providedSessionId,
818
+ cron,
819
+ prompt,
820
+ recurring,
821
+ enabled,
822
+ ...delivery !== void 0 ? { delivery } : {},
823
+ ...nameResult.value !== void 0 ? { name: nameResult.value } : {}
824
+ },
825
+ { source: "rest" }
826
+ );
827
+ if (task2.delivery && task2.sessionId) {
828
+ channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd, {
829
+ sessionId: task2.sessionId,
830
+ taskId: task2.id,
831
+ target: task2.delivery.target,
832
+ recurring: task2.recurring,
833
+ lastFiredAt: task2.lastFiredAt ?? void 0
834
+ });
835
+ }
836
+ res.status(201).json(toView(task2));
837
+ } catch (error) {
838
+ if (error instanceof ExistingSessionScheduledTaskCreateError) {
839
+ if (error.code === "workspace_runtime_unavailable") {
840
+ res.set("Retry-After", "1");
841
+ }
842
+ res.status(error.status).json({ error: error.message, code: error.code });
843
+ return;
844
+ }
845
+ if (sendActivityGateError(res, error)) return;
846
+ if (sendGenerationClosedError(res, error)) return;
847
+ writeStderrLine(
848
+ `qwen serve: POST ${base} failed to create a task for session '${providedSessionId}': ${error instanceof Error ? error.message : String(error)}`
849
+ );
850
+ res.status(500).json({
851
+ error: "Failed to create scheduled task",
852
+ code: "scheduled_tasks_write_failed"
853
+ });
854
+ }
855
+ return;
856
+ }
857
+ let boundSessionId;
858
+ let sessionMintedHere = false;
859
+ if (bridge) {
860
+ try {
861
+ const tasks = await runWithScheduledTaskTarget(
862
+ target,
863
+ () => readCronTasks(workspaceCwd)
864
+ );
865
+ if (tasks.length >= MAX_SCHEDULED_TASKS) {
866
+ res.status(409).json({
867
+ error: `Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,
868
+ code: "max_tasks_reached"
869
+ });
870
+ return;
871
+ }
872
+ } catch {
873
+ }
874
+ if (!requireOpenGeneration(target, res)) return;
875
+ try {
876
+ const session = await runWithScheduledTaskTarget(
877
+ target,
878
+ () => bridge.spawnOrAttach({
879
+ workspaceCwd,
880
+ sessionScope: "thread",
881
+ sourceType: "scheduled_task",
882
+ sourceId: taskId
883
+ })
884
+ );
885
+ boundSessionId = session.sessionId;
886
+ sessionMintedHere = true;
887
+ if (!requireOpenGeneration(target, res)) {
888
+ await teardownBoundSession(target, boundSessionId);
889
+ return;
890
+ }
891
+ try {
892
+ await runWithScheduledTaskTarget(
893
+ target,
894
+ async () => bridge.updateSessionMetadata(boundSessionId, {
895
+ displayName: scheduledTaskSessionName(
896
+ nameResult.value ?? prompt
897
+ )
898
+ })
899
+ );
900
+ } catch {
901
+ }
902
+ } catch (err) {
903
+ if (sendActivityGateError(res, err)) return;
904
+ if (sendGenerationClosedError(res, err)) return;
905
+ writeStderrLine(
906
+ `qwen serve: POST ${base} failed to create the task's session: ${err instanceof Error ? err.message : String(err)}`
907
+ );
908
+ res.status(500).json({
909
+ error: "Failed to create the task's session",
910
+ code: "scheduled_tasks_session_failed"
911
+ });
912
+ return;
913
+ }
914
+ }
915
+ const now = Date.now();
916
+ const task = {
917
+ id: taskId,
918
+ cron,
919
+ prompt,
920
+ recurring,
921
+ createdAt: now,
922
+ // Pin to the creation minute so the scheduler can't fire during the
923
+ // minute the task was created — same guard cronScheduler.create uses.
924
+ lastFiredAt: now - now % 6e4,
925
+ enabled,
926
+ ...delivery !== void 0 ? { delivery } : {},
927
+ ...boundSessionId !== void 0 ? {
928
+ sessionId: boundSessionId
929
+ } : {},
930
+ ...nameResult.value !== void 0 ? { name: nameResult.value } : {}
931
+ };
932
+ const rollbackSession = /* @__PURE__ */ __name(async () => {
933
+ if (boundSessionId !== void 0 && sessionMintedHere) {
934
+ await teardownBoundSession(target, boundSessionId);
935
+ }
936
+ }, "rollbackSession");
937
+ let overCap = false;
938
+ let rollbackBefore;
939
+ let rollbackAfter;
940
+ try {
941
+ await runWithScheduledTaskTarget(
942
+ target,
943
+ () => updateCronTasks(
944
+ workspaceCwd,
945
+ (tasks) => {
946
+ if (tasks.length >= MAX_SCHEDULED_TASKS) {
947
+ overCap = true;
948
+ return tasks;
949
+ }
950
+ rollbackBefore = tasks;
951
+ rollbackAfter = [...tasks, task];
952
+ return rollbackAfter;
953
+ },
954
+ { assertCanCommit: target.assertGenerationOpen }
955
+ )
956
+ );
957
+ } catch (err) {
958
+ await rollbackSession();
959
+ if (sendActivityGateError(res, err)) return;
960
+ if (sendGenerationClosedError(res, err)) return;
961
+ writeStderrLine(
962
+ `qwen serve: POST ${base} failed: ${err instanceof Error ? err.message : String(err)}`
963
+ );
964
+ res.status(500).json({
965
+ error: "Failed to create scheduled task",
966
+ code: "scheduled_tasks_write_failed"
967
+ });
968
+ return;
969
+ }
970
+ if (rollbackBefore && rollbackAfter) {
971
+ try {
972
+ target.assertGenerationOpen?.();
973
+ } catch (error) {
974
+ await rollbackCronMutation(
975
+ target,
976
+ rollbackBefore,
977
+ rollbackAfter,
978
+ `POST ${base}`
979
+ );
980
+ await rollbackSession();
981
+ if (sendGenerationClosedError(res, error)) return;
982
+ throw error;
983
+ }
984
+ }
985
+ if (overCap) {
986
+ await rollbackSession();
987
+ res.status(409).json({
988
+ error: `Maximum number of scheduled tasks (${MAX_SCHEDULED_TASKS}) reached`,
989
+ code: "max_tasks_reached"
990
+ });
991
+ return;
992
+ }
993
+ if (task.delivery && task.sessionId) {
994
+ channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd, {
995
+ sessionId: task.sessionId,
996
+ taskId: task.id,
997
+ target: task.delivery.target,
998
+ recurring: task.recurring,
999
+ lastFiredAt: task.lastFiredAt ?? void 0
1000
+ });
1001
+ }
1002
+ res.status(201).json(toView(task));
1003
+ })
1004
+ );
1005
+ app.patch(
1006
+ `${base}/:id`,
1007
+ mutate(),
1008
+ withTarget(async (req, res, target) => {
1009
+ const { workspaceCwd, bridge } = target;
1010
+ const id = typeof req.params["id"] === "string" ? req.params["id"] : "";
1011
+ if (id.length === 0) {
1012
+ res.status(400).json({ error: "Task id is required", code: "invalid_id" });
1013
+ return;
1014
+ }
1015
+ const body = safeBody(req);
1016
+ const patch = {};
1017
+ let clearName = false;
1018
+ let clearDelivery = false;
1019
+ const removedPatchField = findRemovedTaskField(body);
1020
+ if (removedPatchField) {
1021
+ res.status(400).json(removedFieldError(removedPatchField));
1022
+ return;
1023
+ }
1024
+ if ("cron" in body) {
1025
+ const cron = typeof body["cron"] === "string" ? body["cron"].trim() : "";
1026
+ if (cron.length === 0 || cron.length > MAX_CRON_LENGTH) {
1027
+ res.status(400).json({
1028
+ error: "`cron` must be a non-empty string within the length limit",
1029
+ code: "invalid_cron"
1030
+ });
1031
+ return;
1032
+ }
1033
+ const cronError = validateCron(cron);
1034
+ if (cronError) {
1035
+ res.status(400).json({ error: cronError, code: "invalid_cron" });
1036
+ return;
1037
+ }
1038
+ patch.cron = cron;
1039
+ }
1040
+ if ("prompt" in body) {
1041
+ const prompt = typeof body["prompt"] === "string" ? body["prompt"].trim() : "";
1042
+ if (prompt.length === 0 || prompt.length > MAX_PROMPT_LENGTH) {
1043
+ res.status(400).json({
1044
+ error: "`prompt` must be a non-empty string within the length limit",
1045
+ code: "invalid_prompt"
1046
+ });
1047
+ return;
1048
+ }
1049
+ patch.prompt = prompt;
1050
+ }
1051
+ if ("name" in body) {
1052
+ const nameResult = parseNameField(body["name"]);
1053
+ if (nameResult.error) {
1054
+ res.status(400).json({ error: nameResult.error, code: "invalid_name" });
1055
+ return;
1056
+ }
1057
+ if (nameResult.value === void 0) {
1058
+ clearName = true;
1059
+ } else {
1060
+ patch.name = nameResult.value;
1061
+ }
1062
+ }
1063
+ if ("recurring" in body) {
1064
+ if (typeof body["recurring"] !== "boolean") {
1065
+ res.status(400).json({
1066
+ error: "`recurring` must be a boolean",
1067
+ code: "invalid_recurring"
1068
+ });
1069
+ return;
1070
+ }
1071
+ patch.recurring = body["recurring"];
1072
+ }
1073
+ if ("enabled" in body) {
1074
+ if (typeof body["enabled"] !== "boolean") {
1075
+ res.status(400).json({
1076
+ error: "`enabled` must be a boolean",
1077
+ code: "invalid_enabled"
1078
+ });
1079
+ return;
1080
+ }
1081
+ patch.enabled = body["enabled"];
1082
+ }
1083
+ if ("delivery" in body) {
1084
+ if (body["delivery"] === null) {
1085
+ clearDelivery = true;
1086
+ } else {
1087
+ try {
1088
+ patch.delivery = parseChannelDelivery(body["delivery"]);
1089
+ } catch (err) {
1090
+ if (!isChannelDeliveryError(err)) throw err;
1091
+ res.status(400).json({ error: err.message, code: err.code });
1092
+ return;
1093
+ }
1094
+ }
1095
+ }
1096
+ if (Object.keys(patch).length === 0 && !clearName && !clearDelivery) {
1097
+ res.status(400).json({
1098
+ error: "No updatable fields provided",
1099
+ code: "empty_patch"
1100
+ });
1101
+ return;
1102
+ }
1103
+ let found = false;
1104
+ let updated;
1105
+ let blockedByArchive = false;
1106
+ let blockedLegacy = false;
1107
+ let rollbackBefore;
1108
+ let rollbackAfter;
1109
+ try {
1110
+ await runWithScheduledTaskTarget(
1111
+ target,
1112
+ () => updateCronTasks(
1113
+ workspaceCwd,
1114
+ (tasks) => {
1115
+ const idx = tasks.findIndex((t) => t.id === id);
1116
+ if (idx === -1) return tasks;
1117
+ found = true;
1118
+ const current = tasks[idx];
1119
+ if (patch.enabled === true && taskHasLegacyCondition(current)) {
1120
+ blockedLegacy = true;
1121
+ return tasks;
1122
+ }
1123
+ if (patch.enabled === true && current.disabledByArchive === true) {
1124
+ blockedByArchive = true;
1125
+ return tasks;
1126
+ }
1127
+ const next = { ...current, ...patch };
1128
+ if (clearName) delete next.name;
1129
+ if (clearDelivery) delete next.delivery;
1130
+ const justReEnabled = current.enabled === false && patch.enabled === true;
1131
+ const cronChanged = patch.cron !== void 0 && canonicalCron(patch.cron) !== canonicalCron(current.cron);
1132
+ const becameRecurring = patch.recurring === true && current.recurring !== true;
1133
+ const becameOneShot = patch.recurring === false && current.recurring !== false;
1134
+ {
1135
+ const now = Date.now();
1136
+ const minute = now - now % 6e4;
1137
+ if (next.recurring && (justReEnabled || cronChanged || becameRecurring)) {
1138
+ next.lastFiredAt = minute;
1139
+ } else if (!next.recurring && (justReEnabled || cronChanged || becameOneShot)) {
1140
+ next.createdAt = now;
1141
+ next.lastFiredAt = minute;
1142
+ }
1143
+ }
1144
+ updated = next;
1145
+ rollbackBefore = tasks;
1146
+ rollbackAfter = tasks.map((t, i) => i === idx ? next : t);
1147
+ return rollbackAfter;
1148
+ },
1149
+ { assertCanCommit: target.assertGenerationOpen }
1150
+ )
1151
+ );
1152
+ } catch (err) {
1153
+ if (sendActivityGateError(res, err)) return;
1154
+ if (sendGenerationClosedError(res, err)) return;
1155
+ writeStderrLine(
1156
+ `qwen serve: PATCH ${base}/${id} failed: ${err instanceof Error ? err.message : String(err)}`
1157
+ );
1158
+ res.status(500).json({
1159
+ error: "Failed to update scheduled task",
1160
+ code: "scheduled_tasks_write_failed"
1161
+ });
1162
+ return;
1163
+ }
1164
+ if (rollbackBefore && rollbackAfter) {
1165
+ try {
1166
+ target.assertGenerationOpen?.();
1167
+ } catch (error) {
1168
+ await rollbackCronMutation(
1169
+ target,
1170
+ rollbackBefore,
1171
+ rollbackAfter,
1172
+ `PATCH ${base}/${id}`
1173
+ );
1174
+ if (sendGenerationClosedError(res, error)) return;
1175
+ throw error;
1176
+ }
1177
+ }
1178
+ if (blockedLegacy) {
1179
+ res.status(409).json({
1180
+ error: "This task uses the removed isolated run mode with a precondition and can no longer be enabled or run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",
1181
+ code: "task_legacy_unsupported"
1182
+ });
1183
+ return;
1184
+ }
1185
+ if (blockedByArchive) {
1186
+ res.status(409).json({
1187
+ error: "This task was disabled by archiving its session; unarchive the session to re-enable it.",
1188
+ code: "task_session_archived"
1189
+ });
1190
+ return;
1191
+ }
1192
+ if (!found || !updated) {
1193
+ res.status(404).json({ error: "Task not found", code: "task_not_found" });
1194
+ return;
1195
+ }
1196
+ const effectiveLabelChanged = patch.name !== void 0 || clearName || patch.prompt !== void 0 && updated.name === void 0;
1197
+ if (bridge && updated.sessionId && updated.sessionOwnedByTask !== false && effectiveLabelChanged) {
1198
+ try {
1199
+ bridge.updateSessionMetadata(updated.sessionId, {
1200
+ displayName: scheduledTaskSessionName(
1201
+ updated.name ?? updated.prompt
1202
+ )
1203
+ });
1204
+ } catch {
1205
+ }
1206
+ }
1207
+ if (updated.delivery && updated.sessionId) {
1208
+ channelDeliveryAuthorizations?.registerScheduledTask(workspaceCwd, {
1209
+ sessionId: updated.sessionId,
1210
+ taskId: updated.id,
1211
+ target: updated.delivery.target,
1212
+ recurring: updated.recurring,
1213
+ lastFiredAt: updated.lastFiredAt ?? void 0
1214
+ });
1215
+ }
1216
+ if (clearDelivery && updated.sessionId) {
1217
+ channelDeliveryAuthorizations?.revokeScheduledTask(
1218
+ workspaceCwd,
1219
+ updated.sessionId,
1220
+ updated.id
1221
+ );
1222
+ }
1223
+ res.status(200).json(toView(updated));
1224
+ })
1225
+ );
1226
+ app.delete(
1227
+ `${base}/:id`,
1228
+ mutate(),
1229
+ withTarget(async (req, res, target) => {
1230
+ const { workspaceCwd, bridge } = target;
1231
+ const id = typeof req.params["id"] === "string" ? req.params["id"] : "";
1232
+ if (id.length === 0) {
1233
+ res.status(400).json({ error: "Task id is required", code: "invalid_id" });
1234
+ return;
1235
+ }
1236
+ let boundSessionId;
1237
+ let sessionOwnedByTask = true;
1238
+ let removed = false;
1239
+ let rollbackBefore;
1240
+ let rollbackAfter;
1241
+ try {
1242
+ await runWithScheduledTaskTarget(
1243
+ target,
1244
+ () => updateCronTasks(
1245
+ workspaceCwd,
1246
+ (tasks) => {
1247
+ const idx = tasks.findIndex((t) => t.id === id);
1248
+ if (idx === -1) return tasks;
1249
+ const match = tasks[idx].sessionId;
1250
+ if (typeof match === "string" && match.length > 0) {
1251
+ boundSessionId = match;
1252
+ sessionOwnedByTask = tasks[idx].sessionOwnedByTask !== false;
1253
+ }
1254
+ removed = true;
1255
+ rollbackBefore = tasks;
1256
+ rollbackAfter = tasks.filter((_, i) => i !== idx);
1257
+ return rollbackAfter;
1258
+ },
1259
+ { assertCanCommit: target.assertGenerationOpen }
1260
+ )
1261
+ );
1262
+ } catch (err) {
1263
+ if (sendActivityGateError(res, err)) return;
1264
+ if (sendGenerationClosedError(res, err)) return;
1265
+ writeStderrLine(
1266
+ `qwen serve: DELETE ${base}/${id} failed: ${err instanceof Error ? err.message : String(err)}`
1267
+ );
1268
+ res.status(500).json({
1269
+ error: "Failed to delete scheduled task",
1270
+ code: "scheduled_tasks_write_failed"
1271
+ });
1272
+ return;
1273
+ }
1274
+ if (rollbackBefore && rollbackAfter) {
1275
+ try {
1276
+ target.assertGenerationOpen?.();
1277
+ } catch (error) {
1278
+ await rollbackCronMutation(
1279
+ target,
1280
+ rollbackBefore,
1281
+ rollbackAfter,
1282
+ `DELETE ${base}/${id}`
1283
+ );
1284
+ if (sendGenerationClosedError(res, error)) return;
1285
+ throw error;
1286
+ }
1287
+ }
1288
+ if (!removed) {
1289
+ res.status(404).json({ error: "Task not found", code: "task_not_found" });
1290
+ return;
1291
+ }
1292
+ if (boundSessionId && sessionOwnedByTask && bridge) {
1293
+ try {
1294
+ await runWithScheduledTaskTarget(
1295
+ target,
1296
+ () => bridge.closeSession(boundSessionId)
1297
+ );
1298
+ } catch (error) {
1299
+ if (sendActivityGateError(res, error)) return;
1300
+ }
1301
+ }
1302
+ if (boundSessionId) {
1303
+ channelDeliveryAuthorizations?.revokeScheduledTask(
1304
+ workspaceCwd,
1305
+ boundSessionId,
1306
+ id
1307
+ );
1308
+ }
1309
+ res.status(200).json({ deleted: true, id });
1310
+ })
1311
+ );
1312
+ app.post(
1313
+ `${base}/:id/run`,
1314
+ mutate(),
1315
+ withTarget(async (req, res, target) => {
1316
+ const { workspaceCwd } = target;
1317
+ const id = typeof req.params["id"] === "string" ? req.params["id"] : "";
1318
+ if (id.length === 0) {
1319
+ res.status(400).json({ error: "Task id is required", code: "invalid_id" });
1320
+ return;
1321
+ }
1322
+ const now = Date.now();
1323
+ let found = false;
1324
+ let blockedDisabled = false;
1325
+ let blockedLegacy = false;
1326
+ let updated;
1327
+ let rollbackBefore;
1328
+ let rollbackAfter;
1329
+ try {
1330
+ await runWithScheduledTaskTarget(
1331
+ target,
1332
+ () => updateCronTasks(
1333
+ workspaceCwd,
1334
+ (tasks) => {
1335
+ const idx = tasks.findIndex((t) => t.id === id);
1336
+ if (idx === -1) return tasks;
1337
+ found = true;
1338
+ const current = tasks[idx];
1339
+ if (taskHasLegacyCondition(current)) {
1340
+ blockedLegacy = true;
1341
+ return tasks;
1342
+ }
1343
+ if (current.enabled === false) {
1344
+ blockedDisabled = true;
1345
+ return tasks;
1346
+ }
1347
+ const next = {
1348
+ ...current,
1349
+ lastFiredAt: now,
1350
+ runs: appendCronRun(current.runs, {
1351
+ at: now,
1352
+ kind: "manual",
1353
+ ...current.sessionId ? { sessionId: current.sessionId } : {}
1354
+ })
1355
+ };
1356
+ updated = next;
1357
+ rollbackBefore = tasks;
1358
+ const nextTasks = !current.recurring ? tasks.filter((_, i) => i !== idx) : tasks.map((t, i) => i === idx ? next : t);
1359
+ rollbackAfter = nextTasks;
1360
+ return nextTasks;
1361
+ },
1362
+ { assertCanCommit: target.assertGenerationOpen }
1363
+ )
1364
+ );
1365
+ } catch (err) {
1366
+ if (sendActivityGateError(res, err)) return;
1367
+ if (sendGenerationClosedError(res, err)) return;
1368
+ writeStderrLine(
1369
+ `qwen serve: POST ${base}/${id}/run failed: ${err instanceof Error ? err.message : String(err)}`
1370
+ );
1371
+ res.status(500).json({
1372
+ error: "Failed to record scheduled task run",
1373
+ code: "scheduled_tasks_write_failed"
1374
+ });
1375
+ return;
1376
+ }
1377
+ if (rollbackBefore && rollbackAfter) {
1378
+ try {
1379
+ target.assertGenerationOpen?.();
1380
+ } catch (error) {
1381
+ await rollbackCronMutation(
1382
+ target,
1383
+ rollbackBefore,
1384
+ rollbackAfter,
1385
+ `POST ${base}/${id}/run`
1386
+ );
1387
+ if (sendGenerationClosedError(res, error)) return;
1388
+ throw error;
1389
+ }
1390
+ }
1391
+ if (blockedLegacy) {
1392
+ res.status(409).json({
1393
+ error: "This task uses the removed isolated run mode with a precondition and can no longer run. Recreate it (and call the `create_sub_session` tool from the prompt if you need per-run isolation).",
1394
+ code: "task_legacy_unsupported"
1395
+ });
1396
+ return;
1397
+ }
1398
+ if (blockedDisabled) {
1399
+ res.status(409).json({
1400
+ error: "Cannot run a disabled task; enable it first (unarchive its session if it was archived).",
1401
+ code: "task_disabled"
1402
+ });
1403
+ return;
1404
+ }
1405
+ if (!found || !updated) {
1406
+ res.status(404).json({ error: "Task not found", code: "task_not_found" });
1407
+ return;
1408
+ }
1409
+ if (!updated.recurring && updated.sessionId) {
1410
+ channelDeliveryAuthorizations?.revokeScheduledTask(
1411
+ workspaceCwd,
1412
+ updated.sessionId,
1413
+ updated.id
1414
+ );
1415
+ }
1416
+ const view = toView(updated);
1417
+ if (!updated.recurring) view.nextRunAt = null;
1418
+ res.status(200).json(view);
1419
+ })
1420
+ );
1421
+ }
1422
+ __name(registerScheduledTaskCrudRoutes, "registerScheduledTaskCrudRoutes");
1423
+ function registerScheduledTasksRoutes(app, deps) {
1424
+ const {
1425
+ boundWorkspace,
1426
+ mutate,
1427
+ safeBody,
1428
+ bridge,
1429
+ channelDeliveryAuthorizations
1430
+ } = deps;
1431
+ registerScheduledTaskCrudRoutes(app, {
1432
+ prefix: "",
1433
+ resolveTarget: /* @__PURE__ */ __name((_req, res) => {
1434
+ const runtime = deps.getRuntime?.();
1435
+ if (deps.getRuntime && !runtime) {
1436
+ res.set("Retry-After", "1");
1437
+ res.status(503).json({
1438
+ error: "Workspace runtime is not active",
1439
+ code: "workspace_runtime_unavailable"
1440
+ });
1441
+ return null;
1442
+ }
1443
+ if (runtime && !requireTrustedWorkspaceRuntime(runtime, res)) return null;
1444
+ return {
1445
+ workspaceCwd: boundWorkspace,
1446
+ ...runtime ? {
1447
+ runtimeBaseDir: runtime.sessionRuntimeBaseDir,
1448
+ ...deps.cleanupSession ? {
1449
+ cleanupSession: /* @__PURE__ */ __name((sessionId) => deps.cleanupSession(runtime, sessionId), "cleanupSession")
1450
+ } : {}
1451
+ } : {},
1452
+ // The runtime bridge only refines an ENABLED deps bridge; it must never
1453
+ // re-enable binding when deps `bridge` is undefined. server.ts passes
1454
+ // the bridge only when resident task-session management is on, and a
1455
+ // bound task must always have something to keep it resident + rehydrate
1456
+ // it — the same gate the qualified surface enforces below.
1457
+ bridge: bridge === void 0 ? void 0 : runtime?.bridge ?? bridge,
1458
+ ...runtime?.generationGuard ? {
1459
+ assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
1460
+ } : {},
1461
+ ...deps.workspaceRegistry ? {
1462
+ resolveLiveSessionOwner: /* @__PURE__ */ __name((sessionId) => deps.workspaceRegistry.resolveLiveSessionOwner(sessionId), "resolveLiveSessionOwner")
1463
+ } : {}
1464
+ };
1465
+ }, "resolveTarget"),
1466
+ mutate,
1467
+ safeBody,
1468
+ channelDeliveryAuthorizations
1469
+ });
1470
+ }
1471
+ __name(registerScheduledTasksRoutes, "registerScheduledTasksRoutes");
1472
+ function registerWorkspaceQualifiedScheduledTasksRoutes(app, deps) {
1473
+ const {
1474
+ workspaceRegistry,
1475
+ mutate,
1476
+ safeBody,
1477
+ manageScheduledTaskSessions,
1478
+ channelDeliveryAuthorizations,
1479
+ cleanupSession
1480
+ } = deps;
1481
+ registerScheduledTaskCrudRoutes(app, {
1482
+ prefix: "/workspaces/:workspace",
1483
+ resolveTarget: /* @__PURE__ */ __name((req, res) => {
1484
+ const runtime = resolveWorkspaceRuntimeWithLiveCompatibilityFromParam(
1485
+ workspaceRegistry,
1486
+ req,
1487
+ res
1488
+ );
1489
+ if (!runtime) return null;
1490
+ if (!requireTrustedWorkspaceRuntime(runtime, res)) return null;
1491
+ if (runtime.provenance === "live-conversation" && !deps.conversationRuntimeActivity) {
1492
+ sendConversationRuntimeUnavailable(res);
1493
+ return null;
1494
+ }
1495
+ if (runtime.provenance === "live-conversation" && req.method === "POST" && req.params["id"] === void 0 && parseCallerSuppliedSessionId(safeBody(req)["sessionId"]).kind === "absent") {
1496
+ res.status(400).json({
1497
+ error: "Generic scheduled tasks cannot create sessions in the Conversations workspace.",
1498
+ code: "live_session_creation_reserved"
1499
+ });
1500
+ return null;
1501
+ }
1502
+ return {
1503
+ workspaceCwd: runtime.workspaceCwd,
1504
+ runtimeBaseDir: runtime.sessionRuntimeBaseDir,
1505
+ ...runtime.provenance === "live-conversation" && deps.conversationRuntimeActivity ? { activity: deps.conversationRuntimeActivity } : {},
1506
+ ...cleanupSession ? {
1507
+ cleanupSession: /* @__PURE__ */ __name((sessionId) => cleanupSession(runtime, sessionId), "cleanupSession")
1508
+ } : {},
1509
+ // Mirror the primary surface: only bind a session when management is on,
1510
+ // so a bound task always has something to keep it resident + rehydrate it.
1511
+ bridge: manageScheduledTaskSessions ? runtime.bridge : void 0,
1512
+ ...runtime.generationGuard ? {
1513
+ assertGenerationOpen: /* @__PURE__ */ __name(() => runtime.generationGuard?.assertOpen(), "assertGenerationOpen")
1514
+ } : {},
1515
+ resolveLiveSessionOwner: /* @__PURE__ */ __name((sessionId) => workspaceRegistry.resolveLiveSessionOwner(sessionId), "resolveLiveSessionOwner")
1516
+ };
1517
+ }, "resolveTarget"),
1518
+ mutate,
1519
+ safeBody,
1520
+ channelDeliveryAuthorizations
1521
+ });
1522
+ }
1523
+ __name(registerWorkspaceQualifiedScheduledTasksRoutes, "registerWorkspaceQualifiedScheduledTasksRoutes");
1524
+ var REMOVED_TASK_FIELDS = ["runMode", "condition"];
1525
+ function findRemovedTaskField(body) {
1526
+ return REMOVED_TASK_FIELDS.find((field) => field in body);
1527
+ }
1528
+ __name(findRemovedTaskField, "findRemovedTaskField");
1529
+ function removedFieldError(field) {
1530
+ return {
1531
+ error: `\`${field}\` is no longer supported: the isolated scheduled-task run mode was removed. Every task now runs in its bound session; call the \`create_sub_session\` tool from the task prompt for per-run isolation.`,
1532
+ code: "unsupported_field"
1533
+ };
1534
+ }
1535
+ __name(removedFieldError, "removedFieldError");
1536
+ function parseNameField(raw) {
1537
+ if (raw === void 0 || raw === null) return { value: void 0 };
1538
+ if (typeof raw !== "string") {
1539
+ return { error: "`name` must be a string" };
1540
+ }
1541
+ const trimmed = raw.trim();
1542
+ if (trimmed.length === 0) return { value: void 0 };
1543
+ if (trimmed.length > MAX_NAME_LENGTH) {
1544
+ return { error: `\`name\` exceeds ${MAX_NAME_LENGTH}-character limit` };
1545
+ }
1546
+ return { value: trimmed };
1547
+ }
1548
+ __name(parseNameField, "parseNameField");
1549
+
1550
+ export {
1551
+ resolveWorkspaceEntryFromParam,
1552
+ isPortableAbsolutePath,
1553
+ resolveRegisteredWorkspaceRuntimeByPathSelector,
1554
+ resolveManagedWorkspaceRuntimeByPathSelector,
1555
+ resolveWorkspaceRuntimeFromParam,
1556
+ resolveTrustedRuntime,
1557
+ resolveWorkspaceRuntimeWithLiveCompatibilityFromParam,
1558
+ sendConversationRuntimeUnavailable,
1559
+ sendWorkspaceRuntimeUnavailable,
1560
+ isGenerationClosedError,
1561
+ sendGenerationClosedError,
1562
+ resolveManagedWorkspaceRuntimeFromParam,
1563
+ requireTrustedWorkspaceRuntime,
1564
+ sendUntrustedWorkspaceResponse,
1565
+ getWorkspaceRouteContext,
1566
+ setWorkspaceRouteContext,
1567
+ resolveContainedCwd,
1568
+ resolveContainedCwdOrFail,
1569
+ scheduledTaskSessionName,
1570
+ ExistingSessionScheduledTaskCreateError,
1571
+ createScheduledTaskWithExistingSession,
1572
+ registerScheduledTasksRoutes,
1573
+ registerWorkspaceQualifiedScheduledTasksRoutes
1574
+ };
1575
+ /**
1576
+ * @license
1577
+ * Copyright 2026 Qwen Team
1578
+ * SPDX-License-Identifier: Apache-2.0
1579
+ */
1580
+ /**
1581
+ * @license
1582
+ * Copyright 2025 Qwen Team
1583
+ * SPDX-License-Identifier: Apache-2.0
1584
+ */