@qwen-code/qwen-code 0.22.1 → 0.22.2-nightly.20260828.7357136dd1

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 (418) hide show
  1. package/bundled/goal-draft/SKILL.md +109 -0
  2. package/bundled/qc-helper/docs/configuration/settings.md +13 -13
  3. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  4. package/bundled/qc-helper/docs/features/channels/overview.md +34 -3
  5. package/bundled/qc-helper/docs/features/code-review.md +3 -3
  6. package/bundled/qc-helper/docs/features/commands.md +2 -1
  7. package/bundled/qc-helper/docs/features/goals.md +58 -0
  8. package/bundled/qc-helper/docs/features/headless.md +13 -11
  9. package/bundled/qc-helper/docs/features/status-line.md +3 -3
  10. package/bundled/review/SKILL.md +70 -22
  11. package/bundled/review/references/persistence.md +7 -3
  12. package/bundled/review/references/posting.md +2 -0
  13. package/chunks/MaxSizedBox-LMWXCLDV.js +110 -0
  14. package/chunks/{StandaloneSessionPicker-XF2TVJFK.js → StandaloneSessionPicker-W3F7U3JL.js} +79 -81
  15. package/chunks/{acpAgent-GY53MJIW.js → acpAgent-EYZ6EEHD.js} +1132 -339
  16. package/chunks/{agent-7U6CC5KF.js → agent-RBLGBY65.js} +44 -46
  17. package/chunks/agent-headless-L5T4Y4OZ.js +85 -0
  18. package/chunks/{anthropicContentGenerator-U76GTVB6.js → anthropicContentGenerator-GMHML35Q.js} +10 -11
  19. package/chunks/{artifact-tool-XDJCZZCF.js → artifact-tool-XSMPHZBT.js} +11 -3
  20. package/chunks/{askUserQuestion-ZXXERLEV.js → askUserQuestion-4SWJY65V.js} +2 -2
  21. package/chunks/bridge-5LR2F2ND.js +119 -0
  22. package/chunks/{channel-management-service-HXXS3HOZ.js → channel-management-service-KHR3N6CH.js} +6 -6
  23. package/chunks/channel-settings-store-4FOAZW72.js +120 -0
  24. package/chunks/{channel-worker-group-EVDC2P4K.js → channel-worker-group-6NA6BBZV.js} +8 -7
  25. package/chunks/{channel-worker-manager-IJJZHGEI.js → channel-worker-manager-NEZ2J6RK.js} +10 -8
  26. package/chunks/{channel-worker-supervisor-YSKB5GVB.js → channel-worker-supervisor-FKU7DIHJ.js} +6 -5
  27. package/chunks/{chunk-7QGEJI7M.js → chunk-23RFD54N.js} +1 -1
  28. package/chunks/{chunk-LJP2BBMK.js → chunk-2SXSLSQE.js} +4 -4
  29. package/chunks/chunk-2TNL5KPM.js +49 -0
  30. package/chunks/chunk-335CJSNF.js +2320 -0
  31. package/chunks/chunk-36LGBEM6.js +130 -0
  32. package/chunks/{chunk-ZWKGZB2K.js → chunk-3JXM2CVW.js} +3 -3
  33. package/chunks/{chunk-ICWGPK23.js → chunk-3K6TUZHS.js} +7 -7
  34. package/chunks/{chunk-43C2II2G.js → chunk-3OOXT6CR.js} +5 -5
  35. package/chunks/{chunk-ILPXSKGQ.js → chunk-3WK3QDNV.js} +2 -2
  36. package/chunks/{chunk-2YDYDDE2.js → chunk-3XOKEVII.js} +3 -3
  37. package/chunks/chunk-3Y34Q3JV.js +1584 -0
  38. package/chunks/{chunk-ZLTEQYNC.js → chunk-42IDLQWS.js} +26 -20
  39. package/chunks/{chunk-5MK32KJV.js → chunk-454XFGH4.js} +3 -3
  40. package/chunks/chunk-4CMJKUND.js +95 -0
  41. package/chunks/{chunk-77TOMRBG.js → chunk-4K7KNVWH.js} +3 -3
  42. package/chunks/{chunk-V3GINY6K.js → chunk-4QHPPXK2.js} +16 -8
  43. package/chunks/{chunk-UCSV2IZW.js → chunk-62GQFYID.js} +3 -3
  44. package/chunks/{chunk-SLEWBQWM.js → chunk-6DIGWMGT.js} +2 -2
  45. package/chunks/{chunk-I6YW3T3W.js → chunk-6JCGO55P.js} +723 -3399
  46. package/chunks/{chunk-PVBT5QPD.js → chunk-6PJOTWAN.js} +1 -1
  47. package/chunks/{chunk-5Y2JCJAH.js → chunk-6W2IK5KC.js} +956 -17
  48. package/chunks/{chunk-A7X32SCT.js → chunk-6ZZBRRKQ.js} +5 -5
  49. package/chunks/{chunk-ELY4QVIB.js → chunk-7EQQR46F.js} +1 -1
  50. package/chunks/{chunk-4DCP3362.js → chunk-7GWQW5ID.js} +4 -4
  51. package/chunks/chunk-7J6OTNGO.js +424 -0
  52. package/chunks/{chunk-CITGRGCM.js → chunk-7TUBJBBJ.js} +4 -1
  53. package/chunks/{chunk-L436XFLJ.js → chunk-7VD6IPQM.js} +1 -1
  54. package/chunks/{chunk-E4I5MVBR.js → chunk-ABS25QER.js} +1 -1
  55. package/chunks/{chunk-2ZV3CZKI.js → chunk-AJGR6E6Z.js} +49 -32
  56. package/chunks/{chunk-HJOWQUE2.js → chunk-AU3MMVJF.js} +31 -14
  57. package/chunks/{chunk-I32QCIK7.js → chunk-AXC26UCQ.js} +1 -1
  58. package/chunks/{chunk-7AS7QX72.js → chunk-AY3BNYEQ.js} +1 -1
  59. package/chunks/{chunk-FVDQ5E67.js → chunk-B466ZSHZ.js} +3 -3
  60. package/chunks/{chunk-OI2DR6QB.js → chunk-B5OUL5EL.js} +2 -2
  61. package/chunks/{chunk-6US7BF3G.js → chunk-B5PHIJGI.js} +183 -5
  62. package/chunks/{chunk-5T4LWWNX.js → chunk-B7CDU2SL.js} +2 -2
  63. package/chunks/{chunk-4TPAG3O7.js → chunk-BFPESSTR.js} +1 -1
  64. package/chunks/{chunk-WBT3STGU.js → chunk-BKWNKLZB.js} +20 -20
  65. package/chunks/{chunk-73WFGVIZ.js → chunk-BOWFGCEU.js} +3 -3
  66. package/chunks/{chunk-EMGAVCBZ.js → chunk-BPAKYXQ3.js} +2 -2
  67. package/chunks/{chunk-IPQA4SR5.js → chunk-BWORX6FA.js} +1 -1
  68. package/chunks/{chunk-BKDAF7ES.js → chunk-BXDAPVQU.js} +2 -2
  69. package/chunks/{chunk-ZEADBZLO.js → chunk-C2X7KY45.js} +3 -3
  70. package/chunks/{chunk-T2HMXHYA.js → chunk-C3KURPP7.js} +6 -6
  71. package/chunks/{chunk-JUIJ3FXC.js → chunk-CAJTKR6W.js} +5 -5
  72. package/chunks/{chunk-2FN2HNTI.js → chunk-CFJY4DGX.js} +2 -2
  73. package/chunks/{chunk-DP7LABIB.js → chunk-CMHFCLBU.js} +1 -1
  74. package/chunks/{chunk-LRKMQPMD.js → chunk-CQH5KTKC.js} +1 -1
  75. package/chunks/{chunk-J7MLXFC5.js → chunk-CRKKHXTI.js} +185 -174
  76. package/chunks/{chunk-XNXWEGKB.js → chunk-CYAUBK46.js} +3 -3
  77. package/chunks/{chunk-JECO75XD.js → chunk-D5LUXLUH.js} +2 -2
  78. package/chunks/{chunk-SRGENTPF.js → chunk-DFDWJE6Z.js} +48 -31
  79. package/chunks/chunk-DJBQCO2E.js +842 -0
  80. package/chunks/{chunk-2CRNTW2B.js → chunk-DP4MWIM3.js} +2 -2
  81. package/chunks/{chunk-EB4VDXNI.js → chunk-DYXFD5RO.js} +182 -3
  82. package/chunks/{chunk-ODXCSIH5.js → chunk-E3XVSVKK.js} +26 -4
  83. package/chunks/{chunk-ZKAZP2ZG.js → chunk-EB6QRGHM.js} +3 -3
  84. package/chunks/{chunk-GNRVKN76.js → chunk-EKNBU2X7.js} +4 -4
  85. package/chunks/{chunk-3UZCLCXR.js → chunk-EKSCLBBF.js} +3 -3
  86. package/chunks/{chunk-624NHDGB.js → chunk-ERFDKH32.js} +11 -0
  87. package/chunks/chunk-EW5VVLJT.js +3525 -0
  88. package/chunks/{chunk-XYX474JQ.js → chunk-EWIQ3NAE.js} +2522 -2030
  89. package/chunks/{chunk-O5YGAEQS.js → chunk-FALBWZF4.js} +6 -6
  90. package/chunks/{chunk-GZJUCMH4.js → chunk-FEHMA4RO.js} +542 -654
  91. package/chunks/{chunk-2YEZNBSD.js → chunk-FMFBLTLY.js} +320 -86
  92. package/chunks/{chunk-MZS7GEC7.js → chunk-FTF2YIZ5.js} +1 -1
  93. package/chunks/{chunk-ZJG323IA.js → chunk-G6FECKTJ.js} +7 -5
  94. package/chunks/{chunk-6KS24S3X.js → chunk-GGNE3JAW.js} +1 -1
  95. package/chunks/{chunk-BQBUZDDH.js → chunk-H33EQVMG.js} +4 -4
  96. package/chunks/chunk-H72BQNM3.js +645 -0
  97. package/chunks/{chunk-5ZYZPDDF.js → chunk-HGIMWQVT.js} +30 -25
  98. package/chunks/{chunk-DCSAVGDJ.js → chunk-HOCJDUFY.js} +2 -2
  99. package/chunks/{chunk-MDZO5V2O.js → chunk-HPXV655A.js} +9 -7
  100. package/chunks/{chunk-7JPW6IYH.js → chunk-HVC3PNVC.js} +1 -1
  101. package/chunks/{chunk-2MHGD7EE.js → chunk-HYDJDQGJ.js} +1 -1
  102. package/chunks/{chunk-BDHLBR46.js → chunk-IB7FQJRY.js} +34 -11
  103. package/chunks/{chunk-E55H6BZ7.js → chunk-ICURCKIU.js} +1335 -119
  104. package/chunks/{chunk-PAJGKZAA.js → chunk-ISKH4QX3.js} +14 -12
  105. package/chunks/{chunk-3B5DCAQU.js → chunk-J6S24ZJE.js} +34 -34
  106. package/chunks/{chunk-AYVIGUUK.js → chunk-JB4JIVTJ.js} +1 -1
  107. package/chunks/{chunk-C4WBKZJT.js → chunk-JN4IWWMN.js} +4 -4
  108. package/chunks/{chunk-6HTMIKXZ.js → chunk-JUUBLSZU.js} +4 -4
  109. package/chunks/{chunk-T6OODF2U.js → chunk-JWALNCLT.js} +1 -1
  110. package/chunks/{chunk-SKNVVYIJ.js → chunk-K5KXUXWC.js} +3 -3
  111. package/chunks/{chunk-IRIX323G.js → chunk-KTJFDCX4.js} +2 -2
  112. package/chunks/{chunk-FK4H3V6S.js → chunk-LEFCFTEX.js} +6 -6
  113. package/chunks/{chunk-OQ6LTSX3.js → chunk-LEGTMYAE.js} +1 -1
  114. package/chunks/{chunk-NY3IJYAV.js → chunk-LLZA2IK3.js} +15 -9
  115. package/chunks/{chunk-5CI4AXDD.js → chunk-LNETQKBE.js} +4 -4
  116. package/chunks/{chunk-TOF4UZHH.js → chunk-LUEHOUHM.js} +3 -3
  117. package/chunks/{chunk-62PXFOK4.js → chunk-LVPZO674.js} +4 -4
  118. package/chunks/{chunk-EEQYTWGU.js → chunk-M4ORUPYI.js} +5 -5
  119. package/chunks/{chunk-GNMJNDZE.js → chunk-M6FOJXW3.js} +1 -1
  120. package/chunks/{chunk-MYLXL7F6.js → chunk-MAYHGRP4.js} +9 -9
  121. package/chunks/{chunk-K3LPAED5.js → chunk-MQM5PJML.js} +24 -4
  122. package/chunks/{chunk-SM7ZVKTF.js → chunk-MTJN7FOT.js} +7 -7
  123. package/chunks/{chunk-BGXZBI5B.js → chunk-N4X7G4J2.js} +2 -1
  124. package/chunks/{chunk-27ONXAFY.js → chunk-NIFYWDYN.js} +1 -1
  125. package/chunks/{chunk-IJVDHPKD.js → chunk-NU7RKEZR.js} +2 -2
  126. package/chunks/{chunk-R2ZJH3FV.js → chunk-NXMBRVMQ.js} +3 -3
  127. package/chunks/{chunk-JLGFGPZJ.js → chunk-OI4NY7RA.js} +2 -2
  128. package/chunks/{chunk-RRKNX553.js → chunk-PDQGMSZK.js} +1 -1
  129. package/chunks/{chunk-GTUKW3I6.js → chunk-PPKZ7JOE.js} +1 -1
  130. package/chunks/{chunk-SAH4BD2J.js → chunk-PQEISIKS.js} +67 -0
  131. package/chunks/{chunk-MW5AHWOZ.js → chunk-PWIGAMA4.js} +93 -14
  132. package/chunks/{chunk-WEGXPP5E.js → chunk-QFCDF5PL.js} +1 -1
  133. package/chunks/{chunk-EAV3TENS.js → chunk-QPTRRPZU.js} +44 -7
  134. package/chunks/{chunk-SQPOJ4ZI.js → chunk-RFI4YGMR.js} +21 -266
  135. package/chunks/{chunk-JVPFTDBK.js → chunk-RFIDDFAL.js} +1 -1
  136. package/chunks/chunk-RKFGE7JH.js +93 -0
  137. package/chunks/chunk-RNVFRIOO.js +275 -0
  138. package/chunks/{chunk-CPPYZHBN.js → chunk-RU7BK6B3.js} +1 -1
  139. package/chunks/{chunk-OT26ITEY.js → chunk-RVXDXY6I.js} +3 -3
  140. package/chunks/{chunk-W2WRNJKX.js → chunk-RWZB422L.js} +5 -5
  141. package/chunks/{chunk-6YAR6ZU3.js → chunk-RYNZQGXN.js} +19 -2
  142. package/chunks/{chunk-EKP3M4RF.js → chunk-SJ5ERAW3.js} +1 -1
  143. package/chunks/{chunk-DEYPMJPD.js → chunk-SMPR7SPO.js} +1 -1
  144. package/chunks/{chunk-3BV7TZNQ.js → chunk-SRZZY4IY.js} +3 -3
  145. package/chunks/{chunk-7CWEZQ6T.js → chunk-STUJ7IMZ.js} +0 -77
  146. package/chunks/{chunk-TKO4TLT6.js → chunk-SUX7HDNA.js} +3 -3
  147. package/chunks/{chunk-76WGY6LW.js → chunk-SVNO44PF.js} +3 -3
  148. package/chunks/{chunk-UX3IFLJM.js → chunk-SZLBBZH4.js} +150 -23
  149. package/chunks/{chunk-K63NK3KL.js → chunk-T2NKRHZZ.js} +13 -13
  150. package/chunks/{chunk-4K7NQDCG.js → chunk-T4EFG2P5.js} +18 -9
  151. package/chunks/{chunk-2NCVUT3C.js → chunk-TLHUNMO7.js} +4 -4
  152. package/chunks/{chunk-EC5BONC3.js → chunk-TPI7O7HR.js} +1 -1
  153. package/chunks/{chunk-ZXDM7DYV.js → chunk-TQHGJYR3.js} +2029 -616
  154. package/chunks/{chunk-T2CRBIDJ.js → chunk-TTX2JUE6.js} +1 -1
  155. package/chunks/{chunk-OX44MOAN.js → chunk-TW3E6YNO.js} +3 -3
  156. package/chunks/chunk-U54AYGEC.js +337 -0
  157. package/chunks/{chunk-2NNTE2ED.js → chunk-UHQFIS7N.js} +15 -0
  158. package/chunks/{chunk-KOJ6MHD5.js → chunk-UTLCH2FK.js} +1 -1
  159. package/chunks/{chunk-KCOXDRQL.js → chunk-UY3PBNY3.js} +17 -29
  160. package/chunks/{chunk-7DPKPBOQ.js → chunk-V2NDP3I4.js} +2 -2
  161. package/chunks/{chunk-47SIHHPL.js → chunk-V2QDDC5J.js} +19 -9
  162. package/chunks/{chunk-BVE5EMIG.js → chunk-V5J4J5TP.js} +2 -2
  163. package/chunks/{chunk-X2UOOG5V.js → chunk-VQUGEVGR.js} +1 -1
  164. package/chunks/{chunk-XJS54K4A.js → chunk-VTHREBQM.js} +2 -2
  165. package/chunks/{chunk-VMDURMFY.js → chunk-W6DUQ5GA.js} +11307 -10424
  166. package/chunks/{chunk-BX2BZPFJ.js → chunk-WALC5VJH.js} +4 -4
  167. package/chunks/{chunk-FPH6TXD3.js → chunk-WAOIHTJS.js} +1 -1
  168. package/chunks/{chunk-LI2HEMKO.js → chunk-WBHKK3CU.js} +4 -4
  169. package/chunks/{chunk-O3BUXIPM.js → chunk-WXEA74YB.js} +3 -3
  170. package/chunks/{chunk-NER3H7PI.js → chunk-X3ZRTCJD.js} +1 -1
  171. package/chunks/{chunk-YRLW2MSX.js → chunk-XBVNNDPK.js} +11 -4
  172. package/chunks/{chunk-VL4YX3FH.js → chunk-XF63PKEN.js} +1 -1
  173. package/chunks/{chunk-FN5C6C7G.js → chunk-XLLQJRAH.js} +190 -478
  174. package/chunks/{chunk-3FSBMAYD.js → chunk-XQFT3QUF.js} +1 -1
  175. package/chunks/{chunk-FJWICLG7.js → chunk-Y3QL45LS.js} +1 -1
  176. package/chunks/{chunk-IKN3IUJP.js → chunk-Y4TPOUEV.js} +17 -9
  177. package/chunks/{chunk-NVK4HJYQ.js → chunk-YRZX2PHA.js} +1 -1
  178. package/chunks/{chunk-2SERYG4T.js → chunk-YTDVNSUQ.js} +1 -1
  179. package/chunks/{chunk-KWFP3WV6.js → chunk-YWQ237GX.js} +4 -193
  180. package/chunks/{chunk-6E4WHQJV.js → chunk-ZTP35P4B.js} +1 -1
  181. package/chunks/{chunk-E6FGMDFQ.js → chunk-ZU4UDIWX.js} +19 -1
  182. package/chunks/config-utils-JVGAP34H.js +113 -0
  183. package/chunks/contextCommand-XDB7OSO7.js +106 -0
  184. package/chunks/{core-runtime-PKNQ63VL.js → core-runtime-XHYA2RH7.js} +59 -61
  185. package/chunks/{create-sub-session-RVHSWVAP.js → create-sub-session-23ITIELI.js} +3 -3
  186. package/chunks/{create-sub-session-PLGPY6TV.js → create-sub-session-MHYCFNCM.js} +163 -84
  187. package/chunks/{cron-create-IJGVR5R2.js → cron-create-KJ4IY6PP.js} +57 -10
  188. package/chunks/{cron-delete-4N5BI6GL.js → cron-delete-MBLQCAYY.js} +4 -4
  189. package/chunks/{cron-list-2CATIPUX.js → cron-list-DWH2PQ47.js} +4 -4
  190. package/chunks/{daemon-NAYK4XXU.js → daemon-K5XS42ID.js} +516 -3
  191. package/chunks/{daemon-git-worktree-guard-LDBJXH2U.js → daemon-git-worktree-guard-V3P5XLHB.js} +56 -58
  192. package/chunks/daemon-status-provider-KKU7ZTLM.js +117 -0
  193. package/chunks/daemon-trust-policy-TZGK34DW.js +112 -0
  194. package/chunks/{daemon-trust-policy-monitor-IGEJPHQ4.js → daemon-trust-policy-monitor-F23DD2M4.js} +62 -64
  195. package/chunks/deferred-core-runtime-LKLGBCGZ.js +114 -0
  196. package/chunks/{display-image-DR55LL6M.js → display-image-BE7I6ZB6.js} +5 -5
  197. package/chunks/{dist-DJBNNPLN.js → dist-4WXLCBDR.js} +1 -1
  198. package/chunks/{dist-TJUDJTCB.js → dist-5VXFRTWU.js} +280 -48
  199. package/chunks/{dist-6H6RZ5H6.js → dist-6BPYWHVD.js} +89 -65
  200. package/chunks/{dist-ZBVOXSKF.js → dist-GFN5DCBX.js} +74 -65
  201. package/chunks/{dist-SATKXKUR.js → dist-HZNT6GQS.js} +1 -1
  202. package/chunks/{dist-FVJZSIO4.js → dist-LVZCXVPF.js} +72 -20
  203. package/chunks/{dist-7CKN54NL.js → dist-N6W6E753.js} +71 -64
  204. package/chunks/{dist-4Q7NTUNB.js → dist-QDLFKWOL.js} +2 -2
  205. package/chunks/{dist-UQUFZDIY.js → dist-SWQMYP2Q.js} +18 -16
  206. package/chunks/earlyInputCapture-NERYFYTR.js +107 -0
  207. package/chunks/{edit-KSPVUEAS.js → edit-ACCATIXB.js} +45 -47
  208. package/chunks/{en-6MDBWMTG.js → en-YLXBXM4Z.js} +2 -1
  209. package/chunks/{enter-worktree-UOZ6ZTP7.js → enter-worktree-35QCAAFP.js} +7 -7
  210. package/chunks/{enterPlanMode-DZTABSKN.js → enterPlanMode-NEN6EPVM.js} +44 -46
  211. package/chunks/{environment-JXOSW25V.js → environment-CKWHBC5T.js} +58 -60
  212. package/chunks/errors-XTZPNQ77.js +113 -0
  213. package/chunks/{exit-worktree-G2QATUCV.js → exit-worktree-XQD6D543.js} +7 -7
  214. package/chunks/exitPlanMode-CY344X5J.js +83 -0
  215. package/chunks/{fast-path-EBS7NAVL.js → fast-path-YSOX4PAM.js} +5 -5
  216. package/chunks/{gemini-JELEKOVS.js → gemini-VQY2YCPH.js} +110 -108
  217. package/chunks/{geminiContentGenerator-I2CKP7XI.js → geminiContentGenerator-PAPXNIGU.js} +8 -8
  218. package/chunks/{glob-TDVEVPQZ.js → glob-GVCUSBBF.js} +44 -46
  219. package/chunks/{goal-tools-CNVXMSZD.js → goal-tools-5STK6OXW.js} +10 -8
  220. package/chunks/{grep-3NLSS32D.js → grep-5GPICQBU.js} +6 -6
  221. package/chunks/handleAutoUpdate-ZJPJN42W.js +109 -0
  222. package/chunks/i18n-BZYKOST7.js +124 -0
  223. package/chunks/{image-gen-63NN2H5N.js → image-gen-J6FDGUZP.js} +8 -10
  224. package/chunks/initializer-GO2C5HE3.js +113 -0
  225. package/chunks/installationInfo-WM2GXQZ6.js +107 -0
  226. package/chunks/{keychain-token-storage-3MGFRYGM.js → keychain-token-storage-37XPR34V.js} +2 -2
  227. package/chunks/list-ERDJB7PQ.js +116 -0
  228. package/chunks/{list-agents-EXRSHIDJ.js → list-agents-DI3YFTDT.js} +2 -2
  229. package/chunks/loadedSettingsAdapter-7JOCVOKV.js +110 -0
  230. package/chunks/{loggingContentGenerator-CZWUAHAI.js → loggingContentGenerator-3ONLU3BS.js} +321 -30
  231. package/chunks/{loop-wakeup-XBPB2BRO.js → loop-wakeup-XJFONSQ7.js} +5 -5
  232. package/chunks/{ls-WFONAND2.js → ls-3VAT2J7A.js} +4 -4
  233. package/chunks/{lsp-DUKPDUXN.js → lsp-5W7IRUBH.js} +2 -2
  234. package/chunks/{managed-npm-update-54W23SP5.js → managed-npm-update-TLRCC2GE.js} +57 -59
  235. package/chunks/mcp-2LH3QXR2.js +110 -0
  236. package/chunks/{monitor-A4J5QRGJ.js → monitor-P7LDAL4W.js} +44 -46
  237. package/chunks/nonInteractiveCli-E5T7PZ27.js +184 -0
  238. package/chunks/{notebook-edit-4ANFZON5.js → notebook-edit-F7KSG4WQ.js} +45 -47
  239. package/chunks/{openaiContentGenerator-JCCJJQZC.js → openaiContentGenerator-2EXCZUGN.js} +26 -28
  240. package/chunks/pidfile-P25DWA5Q.js +111 -0
  241. package/chunks/process-registry-OAEG6WGC.js +662 -0
  242. package/chunks/{processUtils-JJAR56SO.js → processUtils-PVDKBL35.js} +2 -2
  243. package/chunks/prompt-terminal-ledger-AJ7T7OIV.js +105 -0
  244. package/chunks/{qwenContentGenerator-5JM44ZSA.js → qwenContentGenerator-TBBRLWIT.js} +49 -51
  245. package/chunks/{qwenOAuth2-JIYAWXTW.js → qwenOAuth2-OF5WRBQT.js} +7 -9
  246. package/chunks/{read-file-N3E5DY7N.js → read-file-6IIY4RLJ.js} +13 -13
  247. package/chunks/{read-mcp-resource-7A7NFSFL.js → read-mcp-resource-XD257PGJ.js} +2 -2
  248. package/chunks/{record-artifact-CPJ4IJSD.js → record-artifact-VW23GS4F.js} +4 -4
  249. package/chunks/{report-findings-VFM5DENC.js → report-findings-XA3FJG3N.js} +5 -5
  250. package/chunks/{request-shutdown-AXVOFN5C.js → request-shutdown-BCLA3JV2.js} +7 -7
  251. package/chunks/resumeHistoryUtils-44IETXDY.js +118 -0
  252. package/chunks/ripGrep-E7ESZ7SS.js +39 -0
  253. package/chunks/{run-qwen-serve-IWGPZADI.js → run-qwen-serve-DXBCYW7V.js} +356 -331
  254. package/chunks/{runtime-I76HPFUE.js → runtime-RUSPD35D.js} +67 -69
  255. package/chunks/scheduled-tasks-DVRJZO6I.js +127 -0
  256. package/chunks/{scheduler-M6YL4K4I.js → scheduler-TDRB2NSY.js} +58 -60
  257. package/chunks/{sdk-exporters-http-XXSKBD2C.js → sdk-exporters-http-TTU2CHBU.js} +2 -2
  258. package/chunks/{sdk-impl-VPNBLV7I.js → sdk-impl-UUMVYMAL.js} +11 -5
  259. package/chunks/{send-message-A2GXDX3B.js → send-message-AJ4OCUBV.js} +25 -9
  260. package/chunks/serve-KITOM7OR.js +118 -0
  261. package/chunks/{server-TWXRRREO.js → server-THCOMUC2.js} +5476 -4771
  262. package/chunks/{session-IT5ZXU7A.js → session-XKR5MPXE.js} +105 -106
  263. package/chunks/session-pr-refresh-KRBH7KDA.js +278 -0
  264. package/chunks/{settings-IX5HOOCG.js → settings-YXZ4XBKK.js} +61 -63
  265. package/chunks/{shell-LZ55AAJB.js → shell-5FJ2DZ3W.js} +44 -46
  266. package/chunks/{skill-WSZ53D2R.js → skill-VMMJZ6CJ.js} +71 -26
  267. package/chunks/skill-settings-7SG4YA2W.js +118 -0
  268. package/chunks/spawnChannel-BPMIXRBI.js +112 -0
  269. package/chunks/standalone-update-QN5HFRIC.js +118 -0
  270. package/chunks/{startInteractiveUI-O6BI2OSA.js → startInteractiveUI-5A7RQFRP.js} +2902 -2289
  271. package/chunks/{syntheticOutput-5AJ444QT.js → syntheticOutput-ML43GEFN.js} +3 -3
  272. package/chunks/{task-create-CDJSOEQD.js → task-create-QN4LYRSE.js} +11 -11
  273. package/chunks/{task-list-BELMPA75.js → task-list-JPLGK45U.js} +5 -5
  274. package/chunks/{task-stop-U3S3KZG2.js → task-stop-CXEH5L2D.js} +2 -2
  275. package/chunks/{task-update-77VCFDDZ.js → task-update-IWEOJFV2.js} +11 -11
  276. package/chunks/{team-create-UF4TMQEH.js → team-create-HVGVUL2L.js} +44 -46
  277. package/chunks/{team-delete-YWFXX77L.js → team-delete-RZVVSGCY.js} +5 -5
  278. package/chunks/{team-plan-approval-U57NSR6C.js → team-plan-approval-S5A5FQWU.js} +44 -46
  279. package/chunks/terminal-image-renderer-SIVPPXDI.js +114 -0
  280. package/chunks/theme-manager-TA33UZZX.js +102 -0
  281. package/chunks/{todoWrite-435EO2CS.js → todoWrite-WDJNQEMW.js} +43 -25
  282. package/chunks/{tool-search-SV35UV72.js → tool-search-NX7IPDKP.js} +18 -18
  283. package/chunks/total-session-admission-PWXZBOVX.js +114 -0
  284. package/chunks/{trustedFolders-YKK67IP3.js → trustedFolders-V6Y4CU3F.js} +57 -59
  285. package/chunks/{update-relaunch-DX7LVA4P.js → update-relaunch-CGSX3R37.js} +5 -5
  286. package/chunks/updateCheck-T5O2WGIB.js +118 -0
  287. package/chunks/useAutoAcceptIndicator-ULBJJWPY.js +120 -0
  288. package/chunks/{validateNonInterActiveAuth-B26O4YJP.js → validateNonInterActiveAuth-E5S2JSRC.js} +101 -102
  289. package/chunks/{version-K5D7VJ4B.js → version-LS5JPU36.js} +1 -1
  290. package/chunks/{web-fetch-VFHZLLNZ.js → web-fetch-RLMFZTS3.js} +16 -18
  291. package/chunks/{web-search-AQE5A4J5.js → web-search-LMCIC4N5.js} +9 -11
  292. package/chunks/{workflow-XL6AEUZ7.js → workflow-JBXU3IGA.js} +128 -94
  293. package/chunks/workspace-providers-status-525ORQBH.js +114 -0
  294. package/chunks/{workspace-registration-store-I4U3V5LL.js → workspace-registration-store-7Y44R4LV.js} +1 -1
  295. package/chunks/workspace-registry-HS4RWUSQ.js +123 -0
  296. package/chunks/workspace-service-7PXDM6EB.js +129 -0
  297. package/chunks/workspace-skills-status-FMJGC2XI.js +113 -0
  298. package/chunks/{workspace-trust-reconciler-GJ466KCE.js → workspace-trust-reconciler-3YTWSQBY.js} +70 -70
  299. package/chunks/write-file-BVQRYQQO.js +88 -0
  300. package/chunks/{zh-TW-MV4FWFB6.js → zh-TW-RPTMRTHG.js} +2 -1
  301. package/chunks/{zh-X3WGU6SI.js → zh-UNY63FR3.js} +2 -1
  302. package/chunks/{zoom-image-NYJPC3NI.js → zoom-image-FGCELNS4.js} +13 -13
  303. package/cli.js +14 -14
  304. package/locales/en.js +2 -0
  305. package/locales/zh-TW.js +2 -0
  306. package/locales/zh.js +2 -0
  307. package/package.json +3 -3
  308. package/web-shell/assets/{abnfDiagram-VCTEODGH-yq7z7Anb.js → abnfDiagram-VCTEODGH-2XZDeWYO.js} +1 -1
  309. package/web-shell/assets/{arc-CbJO0xnT.js → arc-B6UgMh90.js} +1 -1
  310. package/web-shell/assets/{architectureDiagram-5GKGNRK7-CRh89421.js → architectureDiagram-5GKGNRK7-DZgNFeN1.js} +1 -1
  311. package/web-shell/assets/{blockDiagram-NRAW4CY4-C75KAhKv.js → blockDiagram-NRAW4CY4-DQ2wvBFN.js} +1 -1
  312. package/web-shell/assets/{c4Diagram-UCG6FXSJ-BzlMveFB.js → c4Diagram-UCG6FXSJ-DMmQMrc4.js} +1 -1
  313. package/web-shell/assets/channel-D_TyfiTx.js +1 -0
  314. package/web-shell/assets/{chunk-2Q5K7J3B-DA8QDX3a.js → chunk-2Q5K7J3B-C8Zh2e9y.js} +1 -1
  315. package/web-shell/assets/{chunk-5VM5RSS4-Bgu7gQ7Y.js → chunk-5VM5RSS4-C3LTenP8.js} +1 -1
  316. package/web-shell/assets/{chunk-F27PBJKO-BOew7pIK.js → chunk-F27PBJKO-CxABOc8n.js} +1 -1
  317. package/web-shell/assets/{chunk-G27WJ6UU-DHx1I-hO.js → chunk-G27WJ6UU-CD_JxHDC.js} +1 -1
  318. package/web-shell/assets/{chunk-JWPE2WC7-SarFW0WU.js → chunk-JWPE2WC7-BdmZPmce.js} +1 -1
  319. package/web-shell/assets/{chunk-LCL6LL3I-BLzP083Z.js → chunk-LCL6LL3I-80bcHmfK.js} +1 -1
  320. package/web-shell/assets/{chunk-POPQ4Y6H-Bmkv_iKm.js → chunk-POPQ4Y6H-CNpLZyQF.js} +1 -1
  321. package/web-shell/assets/{chunk-SVP7TREG-MPx9r1N2.js → chunk-SVP7TREG-CXlKgMv3.js} +1 -1
  322. package/web-shell/assets/{chunk-XXDRQBXY-Ck-09rKG.js → chunk-XXDRQBXY-CivyYyvL.js} +1 -1
  323. package/web-shell/assets/classDiagram-DTDB5LWJ-Bw_H3xMd.js +1 -0
  324. package/web-shell/assets/classDiagram-v2-JRS7N3AN-Bw_H3xMd.js +1 -0
  325. package/web-shell/assets/{cose-bilkent-JH36ORCC-DWm6lfOG.js → cose-bilkent-JH36ORCC-COAjRH3w.js} +1 -1
  326. package/web-shell/assets/{cynefin-OW5HDTMX-DcBUyr5R.js → cynefin-OW5HDTMX-DqU1JHO6.js} +1 -1
  327. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-Df8qmd_p.js → cynefinDiagram-5FMLGOSQ-BCLI1Bvj.js} +1 -1
  328. package/web-shell/assets/{dagre-3AP2YEHR-DDmGspD7.js → dagre-3AP2YEHR-DmAz8nqF.js} +1 -1
  329. package/web-shell/assets/{diagram-S7CK7UJ4-BK_qFvbi.js → diagram-S7CK7UJ4-Ck-5QLT5.js} +1 -1
  330. package/web-shell/assets/{diagram-UQ7AKVKN-Uw3AP_bi.js → diagram-UQ7AKVKN-C0ljX0mW.js} +1 -1
  331. package/web-shell/assets/{diagram-VSXAHHWV-CJOQKxY7.js → diagram-VSXAHHWV-DPgvT24v.js} +1 -1
  332. package/web-shell/assets/{diagram-VX7I27RA-DhdvZna5.js → diagram-VX7I27RA-D7hWr1LR.js} +1 -1
  333. package/web-shell/assets/{diagram-Z3DM3KII-edQU0nlP.js → diagram-Z3DM3KII-D59tlOta.js} +1 -1
  334. package/web-shell/assets/{ebnfDiagram-PWID7BFC-4kugBEsO.js → ebnfDiagram-PWID7BFC-CY2DDx00.js} +1 -1
  335. package/web-shell/assets/{erDiagram-SSCWMZ5O-BMkFivWO.js → erDiagram-SSCWMZ5O-AR4h8Q8k.js} +1 -1
  336. package/web-shell/assets/{flowDiagram-A5DVABFB-BM1ea8g-.js → flowDiagram-A5DVABFB-DbF0HqBz.js} +1 -1
  337. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-CXj_cKRf.js → ganttDiagram-EL5Y4UJY-J52mrIhc.js} +1 -1
  338. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-D0nEqwqu.js → gitGraphDiagram-WWUBYQGX-CcgMY5EV.js} +1 -1
  339. package/web-shell/assets/index-BjUg3vPr.css +5 -0
  340. package/web-shell/assets/index-CFwYYVFU.js +1873 -0
  341. package/web-shell/assets/{index-B6JN54Pd.js → index-MQs7l15A.js} +1 -1
  342. package/web-shell/assets/{infoDiagram-RXCK75RN-DF7aGGbQ.js → infoDiagram-RXCK75RN-Buu3ibp2.js} +1 -1
  343. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-CZYNX1lL.js → ishikawaDiagram-5VMMS53U-CoKQxnF3.js} +1 -1
  344. package/web-shell/assets/{journeyDiagram-EYS64GPL-CvrqMUz1.js → journeyDiagram-EYS64GPL-CxK35mTC.js} +1 -1
  345. package/web-shell/assets/{kanban-definition-3QL26DDD-BZNJQZBj.js → kanban-definition-3QL26DDD-tk2CHTQ1.js} +1 -1
  346. package/web-shell/assets/{layout-Bf83x7D6.js → layout-DEpMwb4u.js} +1 -1
  347. package/web-shell/assets/{linear-Bkc3ES2f.js → linear-DSQsLh53.js} +1 -1
  348. package/web-shell/assets/{mermaid.core-C6xuovwz.js → mermaid.core-DIZuPBQT.js} +6 -6
  349. package/web-shell/assets/{mindmap-definition-FBJOCRG2-DzH6gVRg.js → mindmap-definition-FBJOCRG2-CCAvk8r_.js} +1 -1
  350. package/web-shell/assets/{pegDiagram-XKGWAZYB-DCvLh2fa.js → pegDiagram-XKGWAZYB-CpJ28jxz.js} +1 -1
  351. package/web-shell/assets/{pieDiagram-E7YTZNPT-BtjVlx_6.js → pieDiagram-E7YTZNPT-ziJR2R32.js} +1 -1
  352. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-IbroqxFe.js → quadrantDiagram-AXDQQJYC-B60zE3Mh.js} +1 -1
  353. package/web-shell/assets/{railroadDiagram-O6MQD6OU-BvMykiWW.js → railroadDiagram-O6MQD6OU-M3GqQ_g1.js} +1 -1
  354. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-D-HHMyrh.js → requirementDiagram-EFPCY7ZU-ntCtYqTk.js} +1 -1
  355. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-C0XXhB6d.js → sankeyDiagram-P5KCCOFB-AYLoItcZ.js} +1 -1
  356. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-DseAXj5d.js → sequenceDiagram-WJ2MYXX4-DEWk4Mlj.js} +1 -1
  357. package/web-shell/assets/{sizeCapture-X5ZJPWSS-Cek2EweK.js → sizeCapture-X5ZJPWSS-OOWvzPay.js} +1 -1
  358. package/web-shell/assets/{stateDiagram-HBIQ2CUA-yLv8wafW.js → stateDiagram-HBIQ2CUA-BcMmvxem.js} +1 -1
  359. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DRLLqPWO.js +1 -0
  360. package/web-shell/assets/{swimlanes-XN3QIQJK-Cwz-opvE.js → swimlanes-XN3QIQJK-DuZTWWvh.js} +1 -1
  361. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-DOfLQQYt.js +8 -0
  362. package/web-shell/assets/{timeline-definition-24CTP7MA-BJuFD7OG.js → timeline-definition-24CTP7MA-CjqtZXEd.js} +1 -1
  363. package/web-shell/assets/{vennDiagram-4TSXK5OY-CNAavdoV.js → vennDiagram-4TSXK5OY-knVCVkQ4.js} +1 -1
  364. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-DaIjAidq.js → wardleyDiagram-VM6X3IG4-yoWhw0a2.js} +1 -1
  365. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-DkcQXjTy.js → xychartDiagram-S5SC5T6Z-ue14E_gL.js} +1 -1
  366. package/web-shell/index.html +3 -3
  367. package/chunks/MaxSizedBox-UUTUE42J.js +0 -112
  368. package/chunks/agent-headless-32O4L2CT.js +0 -87
  369. package/chunks/bridge-DFX2FFH4.js +0 -119
  370. package/chunks/channel-settings-store-ELLH2M4M.js +0 -117
  371. package/chunks/chunk-I6VVOZDK.js +0 -202
  372. package/chunks/chunk-JS73NNWF.js +0 -30
  373. package/chunks/chunk-K2OJUPOE.js +0 -78
  374. package/chunks/chunk-P3QQPMQA.js +0 -19
  375. package/chunks/chunk-SDVF6A42.js +0 -945
  376. package/chunks/chunk-VGHZT6JR.js +0 -51
  377. package/chunks/config-utils-7M6PCTLT.js +0 -113
  378. package/chunks/contextCommand-G4QG3TW6.js +0 -108
  379. package/chunks/daemon-status-provider-F5FEHVVG.js +0 -118
  380. package/chunks/daemon-trust-policy-C6YTU5CQ.js +0 -114
  381. package/chunks/deferred-core-runtime-GHT3GDOR.js +0 -116
  382. package/chunks/earlyInputCapture-HOSJTLWP.js +0 -109
  383. package/chunks/errors-IOXFDE4J.js +0 -115
  384. package/chunks/exitPlanMode-PZG4FXRB.js +0 -85
  385. package/chunks/handleAutoUpdate-AWAGHKOX.js +0 -111
  386. package/chunks/i18n-CYA25C5F.js +0 -126
  387. package/chunks/initializer-JD2FLNLO.js +0 -115
  388. package/chunks/installationInfo-N3DCWVWR.js +0 -109
  389. package/chunks/list-XDQAUET5.js +0 -118
  390. package/chunks/loadedSettingsAdapter-IK7H5JRK.js +0 -112
  391. package/chunks/mcp-2E7ZLMEE.js +0 -112
  392. package/chunks/nonInteractiveCli-ZNDXB62Y.js +0 -185
  393. package/chunks/pidfile-DHV2Y7UD.js +0 -113
  394. package/chunks/process-registry-PMJOA5CO.js +0 -172
  395. package/chunks/prompt-terminal-ledger-LDZ6QVYA.js +0 -107
  396. package/chunks/resumeHistoryUtils-YQRITQAG.js +0 -120
  397. package/chunks/ripGrep-NEIHKBKB.js +0 -39
  398. package/chunks/serve-XY5S63GN.js +0 -120
  399. package/chunks/skill-settings-5U7FTJIK.js +0 -120
  400. package/chunks/spawnChannel-TMC6VXGN.js +0 -113
  401. package/chunks/standalone-update-CUYGWTR4.js +0 -120
  402. package/chunks/terminal-image-renderer-DRL3BROJ.js +0 -116
  403. package/chunks/theme-manager-HHJPUDRN.js +0 -104
  404. package/chunks/total-session-admission-TQI7TCTL.js +0 -114
  405. package/chunks/updateCheck-6JRTKTUF.js +0 -120
  406. package/chunks/useAutoAcceptIndicator-MYXYSKSL.js +0 -122
  407. package/chunks/workspace-providers-status-H6TG34YV.js +0 -116
  408. package/chunks/workspace-registry-2PWNIYNI.js +0 -123
  409. package/chunks/workspace-service-4FGTUJLA.js +0 -131
  410. package/chunks/workspace-skills-status-7VOLUDT6.js +0 -115
  411. package/chunks/write-file-PWOYCT2K.js +0 -90
  412. package/web-shell/assets/channel-B3sGR79J.js +0 -1
  413. package/web-shell/assets/classDiagram-DTDB5LWJ-sTGo0K3v.js +0 -1
  414. package/web-shell/assets/classDiagram-v2-JRS7N3AN-sTGo0K3v.js +0 -1
  415. package/web-shell/assets/index-C-XlQn24.css +0 -5
  416. package/web-shell/assets/index-DLjXM0dn.js +0 -1860
  417. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DeThXnol.js +0 -1
  418. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-GW0R1ZSv.js +0 -8
@@ -0,0 +1,2320 @@
1
+ // Force strict mode and setup for ESM
2
+ "use strict";
3
+ import {
4
+ classifyTopLevelConversationSource
5
+ } from "./chunk-36LGBEM6.js";
6
+ import {
7
+ safeLogValue
8
+ } from "./chunk-RNVFRIOO.js";
9
+ import {
10
+ normalizeSessionIdForLookup,
11
+ parseCallerSuppliedSessionId
12
+ } from "./chunk-ZEZKIS2K.js";
13
+ import {
14
+ SessionArchivedError,
15
+ SessionArchivingError,
16
+ SessionConflictError,
17
+ SessionNotArchivedError,
18
+ SessionNotFoundError
19
+ } from "./chunk-ERFDKH32.js";
20
+ import {
21
+ readWorktreeSession
22
+ } from "./chunk-62GQFYID.js";
23
+ import {
24
+ SessionIdCaseConflictError,
25
+ SessionOrganizationError,
26
+ SessionOrganizationService,
27
+ SessionService,
28
+ SessionTranscriptChangedError,
29
+ SessionWriterUnavailableError,
30
+ readSessionPrs
31
+ } from "./chunk-EWIQ3NAE.js";
32
+ import {
33
+ updateCronTasks
34
+ } from "./chunk-D5LUXLUH.js";
35
+ import {
36
+ addDaemonRequestAttribute
37
+ } from "./chunk-3WK3QDNV.js";
38
+ import {
39
+ Storage
40
+ } from "./chunk-UHQFIS7N.js";
41
+ import {
42
+ writeStderrLine
43
+ } from "./chunk-KGJGEEVR.js";
44
+ import {
45
+ init_esbuild_shims
46
+ } from "./chunk-5O2XNYP6.js";
47
+ import {
48
+ __name
49
+ } from "./chunk-J2S4EL5Y.js";
50
+
51
+ // packages/cli/src/serve/server/session-list.ts
52
+ init_esbuild_shims();
53
+
54
+ // packages/cli/src/serve/session-organization-helpers.ts
55
+ init_esbuild_shims();
56
+ function createSessionOrganizationService(workspaceCwd) {
57
+ return new SessionOrganizationService(workspaceCwd, (message) => {
58
+ writeStderrLine(`qwen serve: session-org: ${message}`);
59
+ });
60
+ }
61
+ __name(createSessionOrganizationService, "createSessionOrganizationService");
62
+
63
+ // packages/cli/src/serve/server/persisted-session-list-cache.ts
64
+ init_esbuild_shims();
65
+ import path from "node:path";
66
+ var PersistedSessionListCache = class {
67
+ constructor(ttlMs, maxRetainedSummaries) {
68
+ this.ttlMs = ttlMs;
69
+ this.maxRetainedSummaries = maxRetainedSummaries;
70
+ }
71
+ static {
72
+ __name(this, "PersistedSessionListCache");
73
+ }
74
+ slots = /* @__PURE__ */ new Map();
75
+ retainedSummaries = 0;
76
+ lookup(scope, loader, options = {}) {
77
+ options.signal?.throwIfAborted();
78
+ const key = this.key(scope);
79
+ let slot = this.slots.get(key);
80
+ if (!slot) {
81
+ slot = { generation: 0 };
82
+ this.slots.set(key, slot);
83
+ }
84
+ const now = Date.now();
85
+ if (slot.value) {
86
+ const cacheAgeMs = Math.max(0, now - slot.value.completedAt);
87
+ if (cacheAgeMs < this.ttlMs) {
88
+ const snapshot = slot.value.snapshot;
89
+ return {
90
+ status: "cache_hit",
91
+ promise: Promise.resolve().then(() => {
92
+ options.signal?.throwIfAborted();
93
+ return snapshot;
94
+ }),
95
+ cacheAgeMs
96
+ };
97
+ }
98
+ this.removeValue(slot);
99
+ }
100
+ if (slot.inFlight !== void 0 && slot.inFlight.generation === slot.generation && !slot.inFlight.controller.signal.aborted) {
101
+ return {
102
+ status: "single_flight",
103
+ promise: this.attachWaiter(key, slot, slot.inFlight, options.signal)
104
+ };
105
+ }
106
+ const generation = slot.generation;
107
+ const controller = new AbortController();
108
+ const load = {
109
+ generation,
110
+ controller,
111
+ promise: void 0,
112
+ waiterCount: 0,
113
+ settled: false
114
+ };
115
+ const managed = Promise.resolve().then(() => {
116
+ controller.signal.throwIfAborted();
117
+ return loader(controller.signal);
118
+ }).then(
119
+ (snapshot) => {
120
+ load.settled = true;
121
+ const current = this.slots.get(key);
122
+ if (current === slot && current.inFlight === load) {
123
+ current.inFlight = void 0;
124
+ if (current.generation === generation && !controller.signal.aborted && snapshot.sessions.length <= this.maxRetainedSummaries) {
125
+ this.installValue(key, current, snapshot);
126
+ } else if (current.value === void 0) {
127
+ this.slots.delete(key);
128
+ }
129
+ }
130
+ return snapshot;
131
+ },
132
+ (error) => {
133
+ load.settled = true;
134
+ const current = this.slots.get(key);
135
+ if (current === slot && current.inFlight === load) {
136
+ current.inFlight = void 0;
137
+ if (current.value === void 0) this.slots.delete(key);
138
+ }
139
+ throw error;
140
+ }
141
+ );
142
+ load.promise = managed;
143
+ slot.inFlight = load;
144
+ return {
145
+ status: "scan",
146
+ promise: this.attachWaiter(key, slot, load, options.signal)
147
+ };
148
+ }
149
+ invalidate(scope) {
150
+ const key = this.key(scope);
151
+ const slot = this.slots.get(key);
152
+ if (!slot) return;
153
+ slot.generation += 1;
154
+ this.removeValue(slot);
155
+ if (slot.inFlight === void 0) this.slots.delete(key);
156
+ }
157
+ clear() {
158
+ for (const slot of this.slots.values()) {
159
+ if (slot.value) clearTimeout(slot.value.expiryTimer);
160
+ }
161
+ this.slots.clear();
162
+ this.retainedSummaries = 0;
163
+ }
164
+ installValue(key, slot, snapshot) {
165
+ const completedAt = Date.now();
166
+ this.evictFor(snapshot.sessions.length);
167
+ const remainingTtlMs = Math.max(0, this.ttlMs - (Date.now() - completedAt));
168
+ const expiryTimer = setTimeout(() => {
169
+ const current = this.slots.get(key);
170
+ if (current !== slot || current.value?.expiryTimer !== expiryTimer) {
171
+ return;
172
+ }
173
+ this.removeValue(current);
174
+ if (current.inFlight === void 0) this.slots.delete(key);
175
+ }, remainingTtlMs);
176
+ if (typeof expiryTimer.unref === "function") expiryTimer.unref();
177
+ const value = { snapshot, completedAt, expiryTimer };
178
+ slot.value = value;
179
+ this.retainedSummaries += snapshot.sessions.length;
180
+ }
181
+ evictFor(incomingSummaries) {
182
+ while (this.retainedSummaries + incomingSummaries > this.maxRetainedSummaries) {
183
+ let oldest;
184
+ for (const [key, slot] of this.slots) {
185
+ if (slot.value && (oldest === void 0 || slot.value.completedAt < oldest.completedAt)) {
186
+ oldest = { key, slot, completedAt: slot.value.completedAt };
187
+ }
188
+ }
189
+ if (!oldest) return;
190
+ this.removeValue(oldest.slot);
191
+ if (oldest.slot.inFlight === void 0) this.slots.delete(oldest.key);
192
+ }
193
+ }
194
+ removeValue(slot) {
195
+ const value = slot.value;
196
+ if (!value) return;
197
+ clearTimeout(value.expiryTimer);
198
+ this.retainedSummaries -= value.snapshot.sessions.length;
199
+ slot.value = void 0;
200
+ }
201
+ attachWaiter(key, slot, load, signal) {
202
+ load.waiterCount += 1;
203
+ return new Promise((resolve, reject) => {
204
+ let settled = false;
205
+ const settle = /* @__PURE__ */ __name((finish) => {
206
+ if (settled) return;
207
+ settled = true;
208
+ signal?.removeEventListener("abort", onAbort);
209
+ load.waiterCount -= 1;
210
+ if (load.waiterCount === 0 && !load.settled) {
211
+ load.controller.abort(
212
+ new DOMException("No active session list waiters", "AbortError")
213
+ );
214
+ const current = this.slots.get(key);
215
+ if (current === slot && current.inFlight === load) {
216
+ current.inFlight = void 0;
217
+ if (current.value === void 0) this.slots.delete(key);
218
+ }
219
+ }
220
+ finish();
221
+ }, "settle");
222
+ const onAbort = /* @__PURE__ */ __name(() => {
223
+ if (load.settled) return;
224
+ settle(() => reject(signal?.reason));
225
+ }, "onAbort");
226
+ signal?.addEventListener("abort", onAbort, { once: true });
227
+ if (signal?.aborted) onAbort();
228
+ void load.promise.then(
229
+ (snapshot) => settle(() => resolve(snapshot)),
230
+ (error) => settle(() => reject(error))
231
+ );
232
+ });
233
+ }
234
+ key(scope) {
235
+ return JSON.stringify([
236
+ path.resolve(scope.runtimeBaseDir),
237
+ scope.workspaceCwd,
238
+ scope.archiveState
239
+ ]);
240
+ }
241
+ };
242
+
243
+ // packages/cli/src/serve/server/activity-timestamp.ts
244
+ init_esbuild_shims();
245
+ function laterActivityTimestamp(live, persisted) {
246
+ const liveTime = live === void 0 ? Number.NaN : Date.parse(live);
247
+ const persistedTime = persisted === void 0 ? Number.NaN : Date.parse(persisted);
248
+ const liveValid = Number.isFinite(liveTime);
249
+ const persistedValid = Number.isFinite(persistedTime);
250
+ if (liveValid && persistedValid) {
251
+ return liveTime >= persistedTime ? live : persisted;
252
+ }
253
+ if (liveValid) return live;
254
+ if (persistedValid) return persisted;
255
+ return live ?? persisted;
256
+ }
257
+ __name(laterActivityTimestamp, "laterActivityTimestamp");
258
+
259
+ // packages/cli/src/serve/server/session-list.ts
260
+ var DEFAULT_SESSION_PAGE_SIZE = 20;
261
+ var MAX_SESSION_PAGE_SIZE = 100;
262
+ var MAX_ORGANIZED_SESSIONS = 5e4;
263
+ var MAX_EMITTED_CURSOR_SESSION_IDS = 64;
264
+ var PERSISTED_SESSION_LIST_CACHE_TTL_MS = 2e3;
265
+ var persistedSessionListCache = new PersistedSessionListCache(
266
+ PERSISTED_SESSION_LIST_CACHE_TTL_MS,
267
+ MAX_ORGANIZED_SESSIONS
268
+ );
269
+ function invalidateWorkspaceSessionListCache(options) {
270
+ for (const archiveState of options.archiveStates) {
271
+ persistedSessionListCache.invalidate({
272
+ runtimeBaseDir: options.runtimeBaseDir,
273
+ workspaceCwd: options.workspaceCwd,
274
+ archiveState
275
+ });
276
+ }
277
+ }
278
+ __name(invalidateWorkspaceSessionListCache, "invalidateWorkspaceSessionListCache");
279
+ var InvalidCursorError = class extends Error {
280
+ static {
281
+ __name(this, "InvalidCursorError");
282
+ }
283
+ constructor(cursor, kind = "numeric") {
284
+ super(`Invalid cursor: "${cursor}" is not a valid ${kind} cursor`);
285
+ this.name = "InvalidCursorError";
286
+ }
287
+ };
288
+ function parseSessionCursor(cursor) {
289
+ if (cursor === "") return void 0;
290
+ const trimmed = cursor.trim();
291
+ const parsed = Number(trimmed);
292
+ if (trimmed === "" || !Number.isFinite(parsed) || parsed < 0 || parsed > Number.MAX_SAFE_INTEGER) {
293
+ throw new InvalidCursorError(cursor);
294
+ }
295
+ return parsed;
296
+ }
297
+ __name(parseSessionCursor, "parseSessionCursor");
298
+ function parseEmittedSessionIds(value) {
299
+ if (value === void 0) return [];
300
+ if (!Array.isArray(value) || value.some((id) => typeof id !== "string" || id.length === 0)) {
301
+ return void 0;
302
+ }
303
+ return value;
304
+ }
305
+ __name(parseEmittedSessionIds, "parseEmittedSessionIds");
306
+ function parseOrganizedCursor(cursor, expected) {
307
+ if (cursor === "") return void 0;
308
+ try {
309
+ const decoded = Buffer.from(cursor, "base64url").toString("utf8");
310
+ const parsed = JSON.parse(decoded);
311
+ const last = parsed.last;
312
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.isPinned !== "boolean" || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.group !== expected.group || parsed.archiveState !== expected.archiveState || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId || parsed.conversationKind !== expected.conversationKind) {
313
+ throw new Error("invalid organized cursor");
314
+ }
315
+ const emitted = parseEmittedSessionIds(parsed.emitted);
316
+ if (emitted === void 0) {
317
+ throw new Error("invalid organized cursor");
318
+ }
319
+ return { last, emitted };
320
+ } catch {
321
+ throw new InvalidCursorError(cursor, "organized");
322
+ }
323
+ }
324
+ __name(parseOrganizedCursor, "parseOrganizedCursor");
325
+ function encodeOrganizedCursor(last, group, archiveState, sourceType, sourceId, conversationKind, emitted = []) {
326
+ return Buffer.from(
327
+ JSON.stringify({
328
+ group,
329
+ archiveState,
330
+ sourceType,
331
+ sourceId,
332
+ conversationKind,
333
+ last,
334
+ ...emitted.length > 0 ? { emitted } : {}
335
+ }),
336
+ "utf8"
337
+ ).toString("base64url");
338
+ }
339
+ __name(encodeOrganizedCursor, "encodeOrganizedCursor");
340
+ function parseLiveSessionCursor(cursor) {
341
+ if (cursor === "") return void 0;
342
+ try {
343
+ const parsed = JSON.parse(
344
+ Buffer.from(cursor, "base64url").toString("utf8")
345
+ );
346
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.activityTime !== "number" || !Number.isFinite(parsed.activityTime) || typeof parsed.sessionId !== "string" || parsed.sessionId.length === 0) {
347
+ throw new Error("invalid live cursor");
348
+ }
349
+ return parsed;
350
+ } catch {
351
+ throw new InvalidCursorError(cursor, "live");
352
+ }
353
+ }
354
+ __name(parseLiveSessionCursor, "parseLiveSessionCursor");
355
+ function encodeLiveSessionCursor(last) {
356
+ return Buffer.from(JSON.stringify(last), "utf8").toString("base64url");
357
+ }
358
+ __name(encodeLiveSessionCursor, "encodeLiveSessionCursor");
359
+ function matchesSessionMetadataSource(session, filter) {
360
+ if (filter.conversationKind === "standalone-top-level" && classifyTopLevelConversationSource(session)?.kind !== "standalone") {
361
+ return false;
362
+ }
363
+ const sourceTypeMatches = filter.sourceType === void 0 || session.sourceType === filter.sourceType || // Legacy sessions without source metadata belong to the default catalog.
364
+ filter.sourceType === "default" && session.sourceType === void 0;
365
+ return sourceTypeMatches && // sourceId remains exact; only the default source type has legacy fallback.
366
+ (filter.sourceId === void 0 || session.sourceId === filter.sourceId);
367
+ }
368
+ __name(matchesSessionMetadataSource, "matchesSessionMetadataSource");
369
+ function parseMetadataSessionCursor(cursor, expected) {
370
+ if (cursor === "") return void 0;
371
+ try {
372
+ const parsed = JSON.parse(
373
+ Buffer.from(cursor, "base64url").toString("utf8")
374
+ );
375
+ const last = parsed.last;
376
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.parentSessionId !== expected.parentSessionId || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId || parsed.conversationKind !== expected.conversationKind || parsed.archiveState !== expected.archiveState) {
377
+ throw new Error("invalid metadata cursor");
378
+ }
379
+ const emitted = parseEmittedSessionIds(
380
+ parsed.emitted
381
+ );
382
+ if (emitted === void 0) {
383
+ throw new Error("invalid metadata cursor");
384
+ }
385
+ return {
386
+ last: { activityTime: last.activityTime, sessionId: last.sessionId },
387
+ emitted
388
+ };
389
+ } catch {
390
+ throw new InvalidCursorError(
391
+ cursor,
392
+ expected.sourceType === void 0 ? "parent" : "metadata"
393
+ );
394
+ }
395
+ }
396
+ __name(parseMetadataSessionCursor, "parseMetadataSessionCursor");
397
+ function encodeMetadataSessionCursor(last, filter, archiveState, emitted = []) {
398
+ return Buffer.from(
399
+ JSON.stringify({
400
+ ...filter,
401
+ archiveState,
402
+ last,
403
+ ...emitted.length > 0 ? { emitted } : {}
404
+ }),
405
+ "utf8"
406
+ ).toString("base64url");
407
+ }
408
+ __name(encodeMetadataSessionCursor, "encodeMetadataSessionCursor");
409
+ async function enrichWorktreeSidecars(bySessionId, sessionService, archiveState = "active", signal) {
410
+ for (const [sessionId, summary] of bySessionId) {
411
+ signal?.throwIfAborted();
412
+ if (summary.worktree) continue;
413
+ let sidecar;
414
+ try {
415
+ const sidecarPath = sessionService.getWorktreeSessionPathForArchiveState(
416
+ sessionId,
417
+ archiveState
418
+ );
419
+ sidecar = signal ? await readWorktreeSession(sidecarPath, { signal }) : await readWorktreeSession(sidecarPath);
420
+ } catch {
421
+ signal?.throwIfAborted();
422
+ sidecar = null;
423
+ }
424
+ if (sidecar) {
425
+ bySessionId.set(sessionId, {
426
+ ...summary,
427
+ worktree: {
428
+ slug: sidecar.slug,
429
+ path: sidecar.worktreePath,
430
+ branch: sidecar.worktreeBranch
431
+ }
432
+ });
433
+ }
434
+ }
435
+ }
436
+ __name(enrichWorktreeSidecars, "enrichWorktreeSidecars");
437
+ async function enrichPrSidecars(bySessionId, sessionService, archiveState, signal) {
438
+ for (const [sessionId, summary] of bySessionId) {
439
+ signal?.throwIfAborted();
440
+ let sidecar;
441
+ try {
442
+ const sidecarPath = sessionService.getPrSessionPathForArchiveState(
443
+ sessionId,
444
+ archiveState
445
+ );
446
+ sidecar = signal ? await readSessionPrs(sidecarPath, { signal }) : await readSessionPrs(sidecarPath);
447
+ } catch {
448
+ signal?.throwIfAborted();
449
+ sidecar = null;
450
+ }
451
+ if (sidecar) {
452
+ bySessionId.set(sessionId, {
453
+ ...summary,
454
+ prs: sidecarToPrInfos(sidecar)
455
+ });
456
+ }
457
+ }
458
+ }
459
+ __name(enrichPrSidecars, "enrichPrSidecars");
460
+ function toSummary(item) {
461
+ return {
462
+ sessionId: item.sessionId,
463
+ workspaceCwd: item.cwd,
464
+ createdAt: item.startTime,
465
+ updatedAt: new Date(item.mtime).toISOString(),
466
+ displayName: item.customTitle || item.prompt,
467
+ ...item.parentSessionId ? { parentSessionId: item.parentSessionId } : {},
468
+ ...item.sourceType ? { sourceType: item.sourceType } : {},
469
+ ...item.sourceId !== void 0 ? { sourceId: item.sourceId } : {},
470
+ clientCount: 0,
471
+ hasActivePrompt: false,
472
+ isArchived: item.isArchived === true
473
+ };
474
+ }
475
+ __name(toSummary, "toSummary");
476
+ function mergeLiveSessionSummary(existing, live) {
477
+ const merged = {
478
+ ...existing,
479
+ ...live,
480
+ createdAt: existing.createdAt,
481
+ displayName: live.displayName ?? existing.displayName,
482
+ // Immutable lineage; the persisted transcript is authoritative, and a live
483
+ // entry only carries it when spawned this run.
484
+ parentSessionId: existing.parentSessionId ?? live.parentSessionId,
485
+ sourceType: existing.sourceType ?? live.sourceType,
486
+ sourceId: existing.sourceType !== void 0 ? existing.sourceId : live.sourceId,
487
+ updatedAt: laterActivityTimestamp(live.updatedAt, existing.updatedAt),
488
+ clientCount: live.clientCount,
489
+ hasActivePrompt: live.hasActivePrompt,
490
+ isArchived: false
491
+ };
492
+ if (existing.prs || live.prs) {
493
+ merged.prs = mergeSummaryPrs(existing.prs, live.prs);
494
+ }
495
+ return merged;
496
+ }
497
+ __name(mergeLiveSessionSummary, "mergeLiveSessionSummary");
498
+ function sidecarToPrInfos(sidecar) {
499
+ return sidecar.map(({ number, url, state }) => ({
500
+ number,
501
+ url,
502
+ ...state ? { state } : {}
503
+ }));
504
+ }
505
+ __name(sidecarToPrInfos, "sidecarToPrInfos");
506
+ function mergeSummaryPrs(persistedPrs, livePrs) {
507
+ const live = livePrs ?? [];
508
+ const persistedByNumber = new Map(
509
+ (persistedPrs ?? []).map((p) => [p.number, p])
510
+ );
511
+ return [
512
+ ...(persistedPrs ?? []).filter(
513
+ (p) => !live.some((l) => l.number === p.number)
514
+ ),
515
+ ...live.map((l) => {
516
+ const persisted = persistedByNumber.get(l.number);
517
+ return persisted?.state !== void 0 && persisted.state !== l.state ? { ...l, state: persisted.state } : l;
518
+ })
519
+ ];
520
+ }
521
+ __name(mergeSummaryPrs, "mergeSummaryPrs");
522
+ async function liveOnlySummary(live, sessionService, signal) {
523
+ const summary = {
524
+ ...live,
525
+ createdAt: live.createdAt,
526
+ clientCount: live.clientCount,
527
+ hasActivePrompt: live.hasActivePrompt,
528
+ isArchived: false
529
+ };
530
+ let sidecar;
531
+ try {
532
+ const sidecarPath = sessionService.getPrSessionPathForArchiveState(
533
+ live.sessionId,
534
+ "active"
535
+ );
536
+ sidecar = signal ? await readSessionPrs(sidecarPath, { signal }) : await readSessionPrs(sidecarPath);
537
+ } catch {
538
+ signal?.throwIfAborted();
539
+ sidecar = null;
540
+ }
541
+ if (sidecar) {
542
+ summary.prs = mergeSummaryPrs(sidecarToPrInfos(sidecar), live.prs);
543
+ }
544
+ return summary;
545
+ }
546
+ __name(liveOnlySummary, "liveOnlySummary");
547
+ function clonePersistedSummary(session) {
548
+ return {
549
+ ...session,
550
+ ...session.worktree ? { worktree: { ...session.worktree } } : {}
551
+ };
552
+ }
553
+ __name(clonePersistedSummary, "clonePersistedSummary");
554
+ async function loadAllPersistedSummaries(sessionService, archiveState, signal) {
555
+ const scanStartedAt = performance.now();
556
+ signal.throwIfAborted();
557
+ const sessions = [];
558
+ let truncated = false;
559
+ let scanPages = 0;
560
+ let cursor;
561
+ do {
562
+ scanPages += 1;
563
+ const page = await sessionService.listSessions({
564
+ cursor,
565
+ size: 1e4,
566
+ archiveState,
567
+ signal
568
+ });
569
+ signal.throwIfAborted();
570
+ const remaining = MAX_ORGANIZED_SESSIONS - sessions.length;
571
+ sessions.push(...page.items.slice(0, remaining).map(toSummary));
572
+ cursor = page.nextCursor;
573
+ if (page.items.length === 0) {
574
+ break;
575
+ }
576
+ if (page.items.length > remaining || sessions.length >= MAX_ORGANIZED_SESSIONS && cursor !== void 0) {
577
+ writeStderrLine(
578
+ `qwen serve: organized session list truncated at ${MAX_ORGANIZED_SESSIONS} sessions`
579
+ );
580
+ truncated = true;
581
+ break;
582
+ }
583
+ } while (cursor !== void 0);
584
+ const bySessionId = new Map(
585
+ sessions.map((session) => [session.sessionId, session])
586
+ );
587
+ await enrichWorktreeSidecars(
588
+ bySessionId,
589
+ sessionService,
590
+ archiveState,
591
+ signal
592
+ );
593
+ await enrichPrSidecars(bySessionId, sessionService, archiveState, signal);
594
+ signal.throwIfAborted();
595
+ return {
596
+ sessions: [...bySessionId.values()],
597
+ truncated,
598
+ scanPages,
599
+ scanDurationMs: Math.max(0, performance.now() - scanStartedAt)
600
+ };
601
+ }
602
+ __name(loadAllPersistedSummaries, "loadAllPersistedSummaries");
603
+ async function listAllPersistedSummaries(sessionService, workspaceCwd, archiveState, runtimeBaseDir, queryKind, signal) {
604
+ const lookup = persistedSessionListCache.lookup(
605
+ { runtimeBaseDir, workspaceCwd, archiveState },
606
+ (loadSignal) => loadAllPersistedSummaries(sessionService, archiveState, loadSignal),
607
+ { signal }
608
+ );
609
+ addDaemonRequestAttribute(
610
+ "qwen-code.daemon.session_list.cache_status",
611
+ lookup.status
612
+ );
613
+ addDaemonRequestAttribute(
614
+ "qwen-code.daemon.session_list.archive_state",
615
+ archiveState
616
+ );
617
+ addDaemonRequestAttribute(
618
+ "qwen-code.daemon.session_list.query_kind",
619
+ queryKind
620
+ );
621
+ if (lookup.cacheAgeMs !== void 0) {
622
+ addDaemonRequestAttribute(
623
+ "qwen-code.daemon.session_list.cache_age_ms",
624
+ lookup.cacheAgeMs
625
+ );
626
+ }
627
+ const snapshot = await lookup.promise;
628
+ signal?.throwIfAborted();
629
+ addDaemonRequestAttribute(
630
+ "qwen-code.daemon.session_list.persisted_sessions",
631
+ snapshot.sessions.length
632
+ );
633
+ addDaemonRequestAttribute(
634
+ "qwen-code.daemon.session_list.scan_pages",
635
+ snapshot.scanPages
636
+ );
637
+ addDaemonRequestAttribute(
638
+ "qwen-code.daemon.session_list.truncated",
639
+ snapshot.truncated
640
+ );
641
+ if (lookup.status !== "cache_hit") {
642
+ addDaemonRequestAttribute(
643
+ "qwen-code.daemon.session_list.scan_duration_ms",
644
+ snapshot.scanDurationMs
645
+ );
646
+ }
647
+ return snapshot;
648
+ }
649
+ __name(listAllPersistedSummaries, "listAllPersistedSummaries");
650
+ function getSummaryActivityTime(session) {
651
+ const time = Date.parse(session.updatedAt ?? session.createdAt);
652
+ return Number.isFinite(time) ? time : 0;
653
+ }
654
+ __name(getSummaryActivityTime, "getSummaryActivityTime");
655
+ function getLiveSessionCursorKey(session) {
656
+ return {
657
+ activityTime: getSummaryActivityTime(session),
658
+ sessionId: session.sessionId
659
+ };
660
+ }
661
+ __name(getLiveSessionCursorKey, "getLiveSessionCursorKey");
662
+ function compareLiveSessionCursorKeys(a, b) {
663
+ const byTime = b.activityTime - a.activityTime;
664
+ if (byTime !== 0) return byTime;
665
+ return a.sessionId.localeCompare(b.sessionId);
666
+ }
667
+ __name(compareLiveSessionCursorKeys, "compareLiveSessionCursorKeys");
668
+ function compareOrganizedSessions(activityTimeById, a, b) {
669
+ return compareOrganizedCursorKeys(
670
+ getOrganizedCursorKey(activityTimeById, a),
671
+ getOrganizedCursorKey(activityTimeById, b)
672
+ );
673
+ }
674
+ __name(compareOrganizedSessions, "compareOrganizedSessions");
675
+ function getOrganizedCursorKey(activityTimeById, session) {
676
+ return {
677
+ isPinned: session.isPinned === true,
678
+ activityTime: activityTimeById.get(session.sessionId) ?? 0,
679
+ sessionId: session.sessionId
680
+ };
681
+ }
682
+ __name(getOrganizedCursorKey, "getOrganizedCursorKey");
683
+ function compareOrganizedCursorKeys(a, b) {
684
+ const byPinned = Number(b.isPinned) - Number(a.isPinned);
685
+ if (byPinned !== 0) return byPinned;
686
+ const byTime = b.activityTime - a.activityTime;
687
+ if (byTime !== 0) return byTime;
688
+ return a.sessionId.localeCompare(b.sessionId);
689
+ }
690
+ __name(compareOrganizedCursorKeys, "compareOrganizedCursorKeys");
691
+ function nextEmittedSessionIds(options) {
692
+ const candidates = new Set(options.carried);
693
+ for (const row of options.page) {
694
+ if (options.liveSessionIds.has(row.sessionId)) {
695
+ candidates.add(row.sessionId);
696
+ }
697
+ }
698
+ const kept = [];
699
+ for (const sessionId of candidates) {
700
+ const row = options.listedById.get(sessionId);
701
+ if (!row) {
702
+ kept.push({ sessionId, persistedTime: Number.NEGATIVE_INFINITY });
703
+ continue;
704
+ }
705
+ const persistedTime = options.persistedTimeById.get(sessionId);
706
+ if (persistedTime === void 0) {
707
+ kept.push({ sessionId, persistedTime: Number.NEGATIVE_INFINITY });
708
+ continue;
709
+ }
710
+ if (options.reenters(row, persistedTime)) {
711
+ kept.push({ sessionId, persistedTime });
712
+ }
713
+ }
714
+ if (kept.length > MAX_EMITTED_CURSOR_SESSION_IDS) {
715
+ kept.sort((a, b) => a.persistedTime - b.persistedTime);
716
+ kept.length = MAX_EMITTED_CURSOR_SESSION_IDS;
717
+ }
718
+ return kept.map((entry) => entry.sessionId);
719
+ }
720
+ __name(nextEmittedSessionIds, "nextEmittedSessionIds");
721
+ function applyOrganization(session, organization) {
722
+ return {
723
+ ...session,
724
+ groupId: organization?.groupId ?? null,
725
+ color: organization?.color ?? null,
726
+ isPinned: organization?.isPinned === true,
727
+ ...organization?.pinnedAt !== void 0 ? { pinnedAt: organization.pinnedAt } : {}
728
+ };
729
+ }
730
+ __name(applyOrganization, "applyOrganization");
731
+ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, options, pageSize, readOptions) {
732
+ const archiveState = options.archiveState ?? "active";
733
+ const sessionService = new SessionService(workspaceCwd);
734
+ const organizationService = createSessionOrganizationService(workspaceCwd);
735
+ readOptions.signal?.throwIfAborted();
736
+ const snapshot = await organizationService.readSnapshot();
737
+ readOptions.signal?.throwIfAborted();
738
+ const knownGroupIds = new Set(snapshot.groups.map((group2) => group2.id));
739
+ const group = options.group ?? "all";
740
+ if (group !== "all" && group !== "pinned" && group !== "ungrouped" && !knownGroupIds.has(group)) {
741
+ throw new SessionOrganizationError(
742
+ `Group not found: ${group}`,
743
+ "group_not_found",
744
+ "group"
745
+ );
746
+ }
747
+ const cursor = options.cursor !== void 0 ? parseOrganizedCursor(options.cursor, {
748
+ group,
749
+ archiveState,
750
+ sourceType: options.sourceType,
751
+ sourceId: options.sourceId,
752
+ conversationKind: options.conversationKind
753
+ }) : void 0;
754
+ const cursorKey = cursor?.last;
755
+ const emittedBeforePage = new Set(cursor?.emitted ?? []);
756
+ const isFirstPage = cursorKey === void 0;
757
+ let liveMergeFailed = false;
758
+ const bySessionId = /* @__PURE__ */ new Map();
759
+ const persisted = await listAllPersistedSummaries(
760
+ sessionService,
761
+ workspaceCwd,
762
+ archiveState,
763
+ readOptions.runtimeBaseDir,
764
+ "organized",
765
+ readOptions.signal
766
+ );
767
+ readOptions.signal?.throwIfAborted();
768
+ for (const session of persisted.sessions) {
769
+ bySessionId.set(
770
+ session.sessionId,
771
+ applyOrganization(
772
+ clonePersistedSummary(session),
773
+ snapshot.sessions.get(session.sessionId)
774
+ )
775
+ );
776
+ }
777
+ const persistedTimeById = new Map(
778
+ persisted.sessions.map((session) => [
779
+ session.sessionId,
780
+ getSummaryActivityTime(session)
781
+ ])
782
+ );
783
+ const liveSessionIds = /* @__PURE__ */ new Set();
784
+ if (readOptions.mergeLive !== false && archiveState !== "archived") {
785
+ try {
786
+ const liveSessions = bridge.listWorkspaceSessions(workspaceCwd);
787
+ for (const live of liveSessions) {
788
+ liveSessionIds.add(live.sessionId);
789
+ const existing = bySessionId.get(live.sessionId);
790
+ const organization = snapshot.sessions.get(live.sessionId);
791
+ if (existing) {
792
+ bySessionId.set(
793
+ live.sessionId,
794
+ applyOrganization(
795
+ mergeLiveSessionSummary(existing, live),
796
+ organization
797
+ )
798
+ );
799
+ } else if (
800
+ // A live-only row has no persisted key to page by, so it stays a
801
+ // first-page-only insertion as before.
802
+ isFirstPage && // `listAllPersistedSummaries` already scanned every persisted
803
+ // session when the scan wasn't truncated, so a `sessionId` missing
804
+ // from `bySessionId` is definitively new — no disk re-check
805
+ // needed. Re-checking here raced a session that persists its
806
+ // first write (e.g. a `displayName` update) between the scan
807
+ // above and this point: `existing` stayed undefined but
808
+ // `sessionExists` flipped to true, silently dropping the live
809
+ // session from the response instead of merging it.
810
+ (!persisted.truncated || !await (readOptions.signal ? sessionService.sessionExists(live.sessionId, {
811
+ signal: readOptions.signal
812
+ }) : sessionService.sessionExists(live.sessionId)))
813
+ ) {
814
+ bySessionId.set(
815
+ live.sessionId,
816
+ applyOrganization(
817
+ await liveOnlySummary(live, sessionService, readOptions.signal),
818
+ organization
819
+ )
820
+ );
821
+ }
822
+ }
823
+ } catch (error) {
824
+ readOptions.signal?.throwIfAborted();
825
+ liveMergeFailed = true;
826
+ writeStderrLine(
827
+ `qwen serve: organized session list live merge failed; using persisted sessions only: ${error instanceof Error ? error.message : String(error)}`
828
+ );
829
+ }
830
+ }
831
+ const filtered = [...bySessionId.values()].filter((session) => {
832
+ if (!matchesSessionMetadataSource(session, options)) return false;
833
+ if (group === "all") return true;
834
+ if (group === "pinned") return session.isPinned === true;
835
+ if (group === "ungrouped")
836
+ return session.groupId == null && session.color == null;
837
+ return session.color == null && session.groupId === group;
838
+ });
839
+ readOptions.signal?.throwIfAborted();
840
+ const activityTimeById = new Map(
841
+ filtered.map((session) => [
842
+ session.sessionId,
843
+ getSummaryActivityTime(session)
844
+ ])
845
+ );
846
+ filtered.sort((a, b) => compareOrganizedSessions(activityTimeById, a, b));
847
+ readOptions.signal?.throwIfAborted();
848
+ const afterCursor = cursorKey === void 0 ? filtered : filtered.filter(
849
+ (session) => (
850
+ // A row already emitted at a live-derived key stays excluded even
851
+ // if its key regressed behind the cursor (live retirement, or a
852
+ // live-only row that persisted mid-pass).
853
+ !emittedBeforePage.has(session.sessionId) && compareOrganizedCursorKeys(
854
+ cursorKey,
855
+ getOrganizedCursorKey(activityTimeById, session)
856
+ ) < 0
857
+ )
858
+ );
859
+ const page = afterCursor.slice(0, pageSize);
860
+ let nextCursor;
861
+ if (page.length < afterCursor.length) {
862
+ const boundary = getOrganizedCursorKey(
863
+ activityTimeById,
864
+ page[page.length - 1]
865
+ );
866
+ const emitted = nextEmittedSessionIds({
867
+ carried: emittedBeforePage,
868
+ page,
869
+ liveSessionIds,
870
+ listedById: new Map(
871
+ filtered.map((session) => [session.sessionId, session])
872
+ ),
873
+ persistedTimeById,
874
+ // `isPinned` is re-read from the organization snapshot on every page
875
+ // request, so a pin flip between fetches can move the persisted key
876
+ // across the pinned/unpinned blocks. Keep the identity while the key
877
+ // could re-enter under either state.
878
+ reenters: /* @__PURE__ */ __name((row, persistedTime) => [true, false].some(
879
+ (isPinned) => compareOrganizedCursorKeys(boundary, {
880
+ isPinned,
881
+ activityTime: persistedTime,
882
+ sessionId: row.sessionId
883
+ }) < 0
884
+ ), "reenters")
885
+ });
886
+ nextCursor = encodeOrganizedCursor(
887
+ boundary,
888
+ group,
889
+ archiveState,
890
+ options.sourceType,
891
+ options.sourceId,
892
+ options.conversationKind,
893
+ emitted
894
+ );
895
+ }
896
+ return {
897
+ sessions: page,
898
+ ...nextCursor !== void 0 ? { nextCursor } : {},
899
+ ...liveMergeFailed ? { liveMergeFailed: true } : {},
900
+ ...persisted.truncated ? { truncated: true } : {}
901
+ };
902
+ }
903
+ __name(listOrganizedWorkspaceSessionsForResponse, "listOrganizedWorkspaceSessionsForResponse");
904
+ async function listWorkspaceSessionsByMetadataForResponse(bridge, workspaceCwd, options, pageSize, filter, readOptions) {
905
+ const archiveState = options.archiveState ?? "active";
906
+ const sessionService = new SessionService(workspaceCwd);
907
+ const bySessionId = /* @__PURE__ */ new Map();
908
+ const persisted = await listAllPersistedSummaries(
909
+ sessionService,
910
+ workspaceCwd,
911
+ archiveState,
912
+ readOptions.runtimeBaseDir,
913
+ "metadata",
914
+ readOptions.signal
915
+ );
916
+ readOptions.signal?.throwIfAborted();
917
+ const canonicalizeStandaloneIds = filter.conversationKind === "standalone-top-level";
918
+ const conflictedStandaloneIds = /* @__PURE__ */ new Set();
919
+ const persistedTimeById = /* @__PURE__ */ new Map();
920
+ for (const session of persisted.sessions) {
921
+ let sessionId = session.sessionId;
922
+ if (canonicalizeStandaloneIds) {
923
+ const parsed = parseCallerSuppliedSessionId(sessionId);
924
+ if (parsed.kind !== "valid") continue;
925
+ sessionId = parsed.sessionId;
926
+ if (conflictedStandaloneIds.has(sessionId)) continue;
927
+ if (bySessionId.has(sessionId)) {
928
+ bySessionId.delete(sessionId);
929
+ persistedTimeById.delete(sessionId);
930
+ conflictedStandaloneIds.add(sessionId);
931
+ continue;
932
+ }
933
+ }
934
+ bySessionId.set(sessionId, {
935
+ ...clonePersistedSummary(session),
936
+ sessionId
937
+ });
938
+ persistedTimeById.set(sessionId, getSummaryActivityTime(session));
939
+ }
940
+ const liveSessionIds = /* @__PURE__ */ new Set();
941
+ let liveMergeFailed = false;
942
+ if (readOptions.mergeLive !== false && archiveState !== "archived") {
943
+ try {
944
+ for (const live of bridge.listWorkspaceSessions(workspaceCwd)) {
945
+ let sessionId = live.sessionId;
946
+ if (canonicalizeStandaloneIds) {
947
+ const parsed = parseCallerSuppliedSessionId(sessionId);
948
+ if (parsed.kind !== "valid" || conflictedStandaloneIds.has(parsed.sessionId)) {
949
+ continue;
950
+ }
951
+ sessionId = parsed.sessionId;
952
+ }
953
+ const canonicalLive = sessionId === live.sessionId ? live : { ...live, sessionId };
954
+ liveSessionIds.add(sessionId);
955
+ const existing = bySessionId.get(sessionId);
956
+ if (existing) {
957
+ bySessionId.set(
958
+ sessionId,
959
+ mergeLiveSessionSummary(existing, canonicalLive)
960
+ );
961
+ } else if (
962
+ // See the matching comment in
963
+ // `listOrganizedWorkspaceSessionsForResponse`: an untruncated scan
964
+ // already covers every persisted session, so skip the racy
965
+ // re-check when nothing was truncated.
966
+ !persisted.truncated || !await (readOptions.signal ? sessionService.sessionExists(sessionId, {
967
+ signal: readOptions.signal
968
+ }) : sessionService.sessionExists(sessionId))
969
+ ) {
970
+ bySessionId.set(
971
+ sessionId,
972
+ await liveOnlySummary(
973
+ canonicalLive,
974
+ sessionService,
975
+ readOptions.signal
976
+ )
977
+ );
978
+ }
979
+ }
980
+ } catch (error) {
981
+ readOptions.signal?.throwIfAborted();
982
+ liveMergeFailed = true;
983
+ writeStderrLine(
984
+ `qwen serve: session metadata filter live merge failed; using persisted sessions only: ${error instanceof Error ? error.message : String(error)}`
985
+ );
986
+ }
987
+ }
988
+ const matches = [...bySessionId.values()].filter(
989
+ (session) => (filter.parentSessionId === void 0 || session.parentSessionId === filter.parentSessionId) && matchesSessionMetadataSource(session, filter)
990
+ ).sort(
991
+ (a, b) => compareLiveSessionCursorKeys(
992
+ getLiveSessionCursorKey(a),
993
+ getLiveSessionCursorKey(b)
994
+ )
995
+ );
996
+ readOptions.signal?.throwIfAborted();
997
+ const cursor = options.cursor !== void 0 && options.cursor !== "" ? parseMetadataSessionCursor(options.cursor, {
998
+ ...filter,
999
+ archiveState
1000
+ }) : void 0;
1001
+ const cursorKey = cursor?.last;
1002
+ const emittedBeforePage = new Set(cursor?.emitted ?? []);
1003
+ const afterCursor = cursorKey === void 0 ? matches : matches.filter(
1004
+ (session) => (
1005
+ // See the organized path: exclude rows already emitted at a
1006
+ // live-derived key whose key regressed behind the cursor.
1007
+ !emittedBeforePage.has(session.sessionId) && compareLiveSessionCursorKeys(
1008
+ cursorKey,
1009
+ getLiveSessionCursorKey(session)
1010
+ ) < 0
1011
+ )
1012
+ );
1013
+ const page = afterCursor.slice(0, pageSize);
1014
+ let nextCursor;
1015
+ if (page.length < afterCursor.length) {
1016
+ const boundary = getLiveSessionCursorKey(page[page.length - 1]);
1017
+ const emitted = nextEmittedSessionIds({
1018
+ carried: emittedBeforePage,
1019
+ page,
1020
+ liveSessionIds,
1021
+ listedById: new Map(
1022
+ matches.map((session) => [session.sessionId, session])
1023
+ ),
1024
+ persistedTimeById,
1025
+ reenters: /* @__PURE__ */ __name((row, persistedTime) => compareLiveSessionCursorKeys(boundary, {
1026
+ activityTime: persistedTime,
1027
+ sessionId: row.sessionId
1028
+ }) < 0, "reenters")
1029
+ });
1030
+ nextCursor = encodeMetadataSessionCursor(
1031
+ boundary,
1032
+ filter,
1033
+ archiveState,
1034
+ emitted
1035
+ );
1036
+ }
1037
+ return {
1038
+ sessions: page,
1039
+ ...nextCursor !== void 0 ? { nextCursor } : {},
1040
+ ...liveMergeFailed ? { liveMergeFailed: true } : {},
1041
+ ...persisted.truncated ? { truncated: true } : {}
1042
+ };
1043
+ }
1044
+ __name(listWorkspaceSessionsByMetadataForResponse, "listWorkspaceSessionsByMetadataForResponse");
1045
+ async function listWorkspaceSessionsForResponse(bridge, workspaceCwd, options, readOptions = {}) {
1046
+ readOptions.signal?.throwIfAborted();
1047
+ const runtimeBaseDir = new Storage(
1048
+ workspaceCwd,
1049
+ readOptions.runtimeBaseDir
1050
+ ).getRuntimeBaseDir();
1051
+ const result = await Storage.runWithResolvedRuntimeBaseDir(
1052
+ runtimeBaseDir,
1053
+ () => listWorkspaceSessionsForResponseInRuntime(bridge, workspaceCwd, options, {
1054
+ ...readOptions.mergeLive !== void 0 ? { mergeLive: readOptions.mergeLive } : {},
1055
+ ...readOptions.signal !== void 0 ? { signal: readOptions.signal } : {},
1056
+ runtimeBaseDir
1057
+ })
1058
+ );
1059
+ readOptions.signal?.throwIfAborted();
1060
+ return result;
1061
+ }
1062
+ __name(listWorkspaceSessionsForResponse, "listWorkspaceSessionsForResponse");
1063
+ async function listWorkspaceSessionsForResponseInRuntime(bridge, workspaceCwd, options, readOptions) {
1064
+ readOptions.signal?.throwIfAborted();
1065
+ const rawSize = options?.size;
1066
+ const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
1067
+ const pageSize = Math.min(Math.max(requestedSize, 1), MAX_SESSION_PAGE_SIZE);
1068
+ if (options?.view === "organized") {
1069
+ return listOrganizedWorkspaceSessionsForResponse(
1070
+ bridge,
1071
+ workspaceCwd,
1072
+ options,
1073
+ pageSize,
1074
+ readOptions
1075
+ );
1076
+ }
1077
+ if (options?.parentSessionId !== void 0 || options?.sourceType !== void 0 || options?.conversationKind !== void 0) {
1078
+ return listWorkspaceSessionsByMetadataForResponse(
1079
+ bridge,
1080
+ workspaceCwd,
1081
+ options,
1082
+ pageSize,
1083
+ {
1084
+ ...options.parentSessionId !== void 0 ? { parentSessionId: options.parentSessionId } : {},
1085
+ ...options.sourceType !== void 0 ? { sourceType: options.sourceType } : {},
1086
+ ...options.sourceId !== void 0 ? { sourceId: options.sourceId } : {},
1087
+ ...options.conversationKind !== void 0 ? { conversationKind: options.conversationKind } : {}
1088
+ },
1089
+ readOptions
1090
+ );
1091
+ }
1092
+ let numericCursor;
1093
+ if (options?.cursor != null) {
1094
+ numericCursor = parseSessionCursor(options.cursor);
1095
+ }
1096
+ const isFirstPage = numericCursor === void 0;
1097
+ const sessionService = new SessionService(workspaceCwd);
1098
+ const archiveState = options?.archiveState ?? "active";
1099
+ const persisted = await sessionService.listSessions({
1100
+ cursor: numericCursor,
1101
+ size: pageSize,
1102
+ archiveState,
1103
+ ...readOptions.signal ? { signal: readOptions.signal } : {}
1104
+ });
1105
+ readOptions.signal?.throwIfAborted();
1106
+ const bySessionId = /* @__PURE__ */ new Map();
1107
+ for (const item of persisted.items) {
1108
+ bySessionId.set(item.sessionId, toSummary(item));
1109
+ }
1110
+ await enrichWorktreeSidecars(
1111
+ bySessionId,
1112
+ sessionService,
1113
+ archiveState,
1114
+ readOptions.signal
1115
+ );
1116
+ await enrichPrSidecars(
1117
+ bySessionId,
1118
+ sessionService,
1119
+ archiveState,
1120
+ readOptions.signal
1121
+ );
1122
+ readOptions.signal?.throwIfAborted();
1123
+ if (archiveState === "archived" || readOptions.mergeLive === false) {
1124
+ const sessions2 = [...bySessionId.values()];
1125
+ const nextCursor2 = persisted.nextCursor != null ? String(persisted.nextCursor) : void 0;
1126
+ return { sessions: sessions2, nextCursor: nextCursor2 };
1127
+ }
1128
+ const liveSessions = bridge.listWorkspaceSessions(workspaceCwd);
1129
+ for (const live of liveSessions) {
1130
+ const existing = bySessionId.get(live.sessionId);
1131
+ if (existing) {
1132
+ bySessionId.set(live.sessionId, mergeLiveSessionSummary(existing, live));
1133
+ } else if (isFirstPage && // If this is a complete scan (no further pages), a missing
1134
+ // `sessionId` here is definitively new — no disk re-check needed.
1135
+ // Re-checking raced a session that persists its first write (e.g. a
1136
+ // `displayName` update) between the scan above and this point:
1137
+ // `existing` stayed undefined but `sessionExists` flipped to true,
1138
+ // silently dropping the live session from the response instead of
1139
+ // merging it.
1140
+ (persisted.nextCursor == null || !await (readOptions.signal ? sessionService.sessionExists(live.sessionId, {
1141
+ signal: readOptions.signal
1142
+ }) : sessionService.sessionExists(live.sessionId)))) {
1143
+ bySessionId.set(
1144
+ live.sessionId,
1145
+ await liveOnlySummary(live, sessionService, readOptions.signal)
1146
+ );
1147
+ }
1148
+ }
1149
+ const sessions = [...bySessionId.values()].sort((a, b) => {
1150
+ const aTime = Date.parse(a.updatedAt ?? a.createdAt);
1151
+ const bTime = Date.parse(b.updatedAt ?? b.createdAt);
1152
+ return bTime - aTime;
1153
+ });
1154
+ readOptions.signal?.throwIfAborted();
1155
+ const nextCursor = persisted.nextCursor != null ? String(persisted.nextCursor) : void 0;
1156
+ return { sessions, nextCursor };
1157
+ }
1158
+ __name(listWorkspaceSessionsForResponseInRuntime, "listWorkspaceSessionsForResponseInRuntime");
1159
+ async function listLiveWorkspaceSessionsForResponse(bridge, workspaceCwd, options, readOptions = {}) {
1160
+ const runtimeBaseDir = new Storage(
1161
+ workspaceCwd,
1162
+ readOptions.runtimeBaseDir
1163
+ ).getRuntimeBaseDir();
1164
+ return Storage.runWithResolvedRuntimeBaseDir(runtimeBaseDir, async () => {
1165
+ const rawSize = options?.size;
1166
+ const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
1167
+ const pageSize = Math.min(
1168
+ Math.max(requestedSize, 1),
1169
+ MAX_SESSION_PAGE_SIZE
1170
+ );
1171
+ const cursorKey = options?.cursor !== void 0 ? parseLiveSessionCursor(options.cursor) : void 0;
1172
+ const sessions = bridge.listWorkspaceSessions(workspaceCwd).sort(
1173
+ (a, b) => compareLiveSessionCursorKeys(
1174
+ getLiveSessionCursorKey(a),
1175
+ getLiveSessionCursorKey(b)
1176
+ )
1177
+ );
1178
+ const afterCursor = cursorKey === void 0 ? sessions : sessions.filter(
1179
+ (session) => compareLiveSessionCursorKeys(
1180
+ cursorKey,
1181
+ getLiveSessionCursorKey(session)
1182
+ ) < 0
1183
+ );
1184
+ const page = afterCursor.slice(0, pageSize);
1185
+ const sessionService = new SessionService(workspaceCwd);
1186
+ const enriched = await Promise.all(
1187
+ page.map(
1188
+ (summary) => liveOnlySummary(summary, sessionService, readOptions.signal)
1189
+ )
1190
+ );
1191
+ const nextCursor = page.length < afterCursor.length ? encodeLiveSessionCursor(
1192
+ getLiveSessionCursorKey(page[page.length - 1])
1193
+ ) : void 0;
1194
+ return {
1195
+ sessions: enriched,
1196
+ ...nextCursor !== void 0 ? { nextCursor } : {}
1197
+ };
1198
+ });
1199
+ }
1200
+ __name(listLiveWorkspaceSessionsForResponse, "listLiveWorkspaceSessionsForResponse");
1201
+ async function getWorkspaceSessionInfoForResponse(bridge, workspaceCwd, options = {}) {
1202
+ const counts = await new SessionService(workspaceCwd).getSessionInfoCounts();
1203
+ return {
1204
+ active: counts.active,
1205
+ archived: counts.archived,
1206
+ total: counts.total,
1207
+ ...options.includeLive === false ? {} : { live: bridge.listWorkspaceSessions(workspaceCwd).length },
1208
+ expensive: true,
1209
+ cost: "disk_scan",
1210
+ ...counts.truncated ? { truncated: true } : {}
1211
+ };
1212
+ }
1213
+ __name(getWorkspaceSessionInfoForResponse, "getWorkspaceSessionInfoForResponse");
1214
+ function parseSessionPageSizeQuery(raw) {
1215
+ if (typeof raw !== "string") return void 0;
1216
+ const trimmed = raw.trim();
1217
+ if (!/^[+-]?\d+$/.test(trimmed)) return void 0;
1218
+ const parsed = Number.parseInt(trimmed, 10);
1219
+ if (!Number.isFinite(parsed)) return void 0;
1220
+ if (Number.isSafeInteger(parsed)) return parsed;
1221
+ return trimmed.startsWith("-") ? 1 : MAX_SESSION_PAGE_SIZE;
1222
+ }
1223
+ __name(parseSessionPageSizeQuery, "parseSessionPageSizeQuery");
1224
+
1225
+ // packages/cli/src/serve/workspace-runtime-storage.ts
1226
+ init_esbuild_shims();
1227
+ function runWithWorkspaceRuntimeStorage(runtime, fn) {
1228
+ return Storage.runWithResolvedRuntimeBaseDir(
1229
+ runtime.sessionRuntimeBaseDir,
1230
+ fn
1231
+ );
1232
+ }
1233
+ __name(runWithWorkspaceRuntimeStorage, "runWithWorkspaceRuntimeStorage");
1234
+ function createWorkspaceRuntimeSessionService(runtime, options = {}) {
1235
+ return new SessionService(runtime.workspaceCwd, {
1236
+ ...options,
1237
+ runtimeBaseDir: runtime.sessionRuntimeBaseDir
1238
+ });
1239
+ }
1240
+ __name(createWorkspaceRuntimeSessionService, "createWorkspaceRuntimeSessionService");
1241
+
1242
+ // packages/cli/src/serve/server/session-archive.ts
1243
+ init_esbuild_shims();
1244
+
1245
+ // packages/cli/src/serve/scheduled-task-session-lifecycle.ts
1246
+ init_esbuild_shims();
1247
+ function isBoundTask(task) {
1248
+ return typeof task.sessionId === "string" && task.sessionId.length > 0;
1249
+ }
1250
+ __name(isBoundTask, "isBoundTask");
1251
+ async function disableTasksForSessions(projectRoot, sessionIds, options = {}) {
1252
+ if (sessionIds.length === 0) return;
1253
+ const targets = new Set(sessionIds);
1254
+ await updateCronTasks(
1255
+ projectRoot,
1256
+ (tasks) => {
1257
+ let changed = false;
1258
+ const next = tasks.map((task) => {
1259
+ if (isBoundTask(task) && targets.has(task.sessionId) && task.enabled !== false) {
1260
+ changed = true;
1261
+ return { ...task, enabled: false, disabledByArchive: true };
1262
+ }
1263
+ return task;
1264
+ });
1265
+ return changed ? next : tasks;
1266
+ },
1267
+ options
1268
+ );
1269
+ }
1270
+ __name(disableTasksForSessions, "disableTasksForSessions");
1271
+ async function enableTasksForSessions(projectRoot, sessionIds, now = Date.now(), options = {}) {
1272
+ if (sessionIds.length === 0) return;
1273
+ const targets = new Set(sessionIds);
1274
+ await updateCronTasks(
1275
+ projectRoot,
1276
+ (tasks) => {
1277
+ let changed = false;
1278
+ const next = tasks.map((task) => {
1279
+ if (isBoundTask(task) && targets.has(task.sessionId) && task.enabled === false && task.disabledByArchive === true) {
1280
+ changed = true;
1281
+ const resumed = { ...task, enabled: true };
1282
+ delete resumed.disabledByArchive;
1283
+ const minute = now - now % 6e4;
1284
+ if (resumed.recurring) {
1285
+ resumed.lastFiredAt = minute;
1286
+ } else {
1287
+ resumed.createdAt = now;
1288
+ resumed.lastFiredAt = minute;
1289
+ }
1290
+ return resumed;
1291
+ }
1292
+ return task;
1293
+ });
1294
+ return changed ? next : tasks;
1295
+ },
1296
+ options
1297
+ );
1298
+ }
1299
+ __name(enableTasksForSessions, "enableTasksForSessions");
1300
+ async function removeTasksForSessions(projectRoot, sessionIds, options = {}) {
1301
+ if (sessionIds.length === 0) return;
1302
+ const targets = new Set(sessionIds);
1303
+ await updateCronTasks(
1304
+ projectRoot,
1305
+ (tasks) => {
1306
+ const next = tasks.filter(
1307
+ (task) => !isBoundTask(task) || !targets.has(task.sessionId)
1308
+ );
1309
+ return next.length === tasks.length ? tasks : next;
1310
+ },
1311
+ options
1312
+ );
1313
+ }
1314
+ __name(removeTasksForSessions, "removeTasksForSessions");
1315
+
1316
+ // packages/cli/src/serve/server/session-archive.ts
1317
+ var DaemonDrainingError = class extends Error {
1318
+ static {
1319
+ __name(this, "DaemonDrainingError");
1320
+ }
1321
+ name = "DaemonDrainingError";
1322
+ code = "daemon_draining";
1323
+ constructor() {
1324
+ super("The daemon is draining and no longer accepts session maintenance.");
1325
+ }
1326
+ };
1327
+ var SessionArchiveCoordinator = class {
1328
+ static {
1329
+ __name(this, "SessionArchiveCoordinator");
1330
+ }
1331
+ exclusive = /* @__PURE__ */ new Set();
1332
+ shared = /* @__PURE__ */ new Map();
1333
+ sharedDrains = /* @__PURE__ */ new Map();
1334
+ maintenanceSealed = false;
1335
+ activeMaintenance = 0;
1336
+ maintenanceDrain;
1337
+ // Lock keys are canonicalized like every other session-id lookup: batch
1338
+ // delete/archive/unarchive lock raw caller spellings while restore locks
1339
+ // the request spelling, and on a case-insensitive filesystem both reach
1340
+ // the same transcript file — uncanonicalized keys would let a differently
1341
+ // cased caller id slip past a held guard and unlink it mid-restore.
1342
+ assertNotTransitioning(sessionId) {
1343
+ if (this.exclusive.has(normalizeSessionIdForLookup(sessionId))) {
1344
+ throw new SessionArchivingError(sessionId);
1345
+ }
1346
+ }
1347
+ async runExclusiveMany(sessionIds, fn) {
1348
+ if (this.maintenanceSealed) {
1349
+ throw new DaemonDrainingError();
1350
+ }
1351
+ const uniqueSessionIds = [
1352
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1353
+ ];
1354
+ for (const sessionId of uniqueSessionIds) {
1355
+ this.assertNotTransitioning(sessionId);
1356
+ if ((this.shared.get(sessionId) ?? 0) > 0) {
1357
+ throw new SessionArchivingError(sessionId, "shared");
1358
+ }
1359
+ }
1360
+ for (const sessionId of uniqueSessionIds) {
1361
+ this.exclusive.add(sessionId);
1362
+ }
1363
+ this.activeMaintenance++;
1364
+ try {
1365
+ return await fn();
1366
+ } finally {
1367
+ for (const sessionId of uniqueSessionIds) {
1368
+ this.exclusive.delete(sessionId);
1369
+ }
1370
+ this.activeMaintenance--;
1371
+ if (this.activeMaintenance === 0) {
1372
+ this.maintenanceDrain?.resolve();
1373
+ this.maintenanceDrain = void 0;
1374
+ }
1375
+ }
1376
+ }
1377
+ async runExclusiveAfterShared(rawSessionId, fn) {
1378
+ if (this.maintenanceSealed) {
1379
+ throw new DaemonDrainingError();
1380
+ }
1381
+ const sessionId = normalizeSessionIdForLookup(rawSessionId);
1382
+ this.assertNotTransitioning(sessionId);
1383
+ this.exclusive.add(sessionId);
1384
+ this.activeMaintenance++;
1385
+ try {
1386
+ const sharedCount = this.shared.get(sessionId) ?? 0;
1387
+ if (sharedCount > 0) {
1388
+ let drain = this.sharedDrains.get(sessionId);
1389
+ if (!drain) {
1390
+ let resolve;
1391
+ const promise = new Promise((done) => {
1392
+ resolve = done;
1393
+ });
1394
+ drain = { promise, resolve };
1395
+ this.sharedDrains.set(sessionId, drain);
1396
+ }
1397
+ await drain.promise;
1398
+ }
1399
+ return await fn();
1400
+ } finally {
1401
+ this.sharedDrains.delete(sessionId);
1402
+ this.exclusive.delete(sessionId);
1403
+ this.activeMaintenance--;
1404
+ if (this.activeMaintenance === 0) {
1405
+ this.maintenanceDrain?.resolve();
1406
+ this.maintenanceDrain = void 0;
1407
+ }
1408
+ }
1409
+ }
1410
+ sealMaintenanceAndWait() {
1411
+ this.maintenanceSealed = true;
1412
+ if (this.activeMaintenance === 0) {
1413
+ return Promise.resolve();
1414
+ }
1415
+ if (!this.maintenanceDrain) {
1416
+ let resolve;
1417
+ const promise = new Promise((done) => {
1418
+ resolve = done;
1419
+ });
1420
+ this.maintenanceDrain = { promise, resolve };
1421
+ }
1422
+ return this.maintenanceDrain.promise;
1423
+ }
1424
+ async runSharedMany(sessionIds, fn) {
1425
+ if (this.maintenanceSealed) {
1426
+ throw new DaemonDrainingError();
1427
+ }
1428
+ const uniqueSessionIds = [
1429
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1430
+ ];
1431
+ for (const sessionId of uniqueSessionIds) {
1432
+ this.assertNotTransitioning(sessionId);
1433
+ }
1434
+ for (const sessionId of uniqueSessionIds) {
1435
+ this.shared.set(sessionId, (this.shared.get(sessionId) ?? 0) + 1);
1436
+ }
1437
+ this.activeMaintenance++;
1438
+ try {
1439
+ return await fn();
1440
+ } finally {
1441
+ for (const sessionId of uniqueSessionIds) {
1442
+ const count = (this.shared.get(sessionId) ?? 1) - 1;
1443
+ if (count <= 0) {
1444
+ this.shared.delete(sessionId);
1445
+ this.sharedDrains.get(sessionId)?.resolve();
1446
+ this.sharedDrains.delete(sessionId);
1447
+ } else {
1448
+ this.shared.set(sessionId, count);
1449
+ }
1450
+ }
1451
+ this.activeMaintenance--;
1452
+ if (this.activeMaintenance === 0) {
1453
+ this.maintenanceDrain?.resolve();
1454
+ this.maintenanceDrain = void 0;
1455
+ }
1456
+ }
1457
+ }
1458
+ };
1459
+ async function runWithDaemonWriterLease(params) {
1460
+ const {
1461
+ action,
1462
+ sessionId,
1463
+ service,
1464
+ mutate,
1465
+ mutationAppliedAfterError,
1466
+ afterMutationApplied
1467
+ } = params;
1468
+ let lease;
1469
+ try {
1470
+ const leaseOptions = {
1471
+ processKind: "daemon",
1472
+ reclaimPolicy: "never",
1473
+ takeoverPolicy: "certified"
1474
+ };
1475
+ try {
1476
+ lease = await service.acquireSessionWriterLease(sessionId, leaseOptions);
1477
+ } catch (error) {
1478
+ if (!(error instanceof SessionWriterUnavailableError) && !(error instanceof SessionTranscriptChangedError)) {
1479
+ throw error;
1480
+ }
1481
+ lease = await service.acquireSessionMaintenanceLease(
1482
+ sessionId,
1483
+ leaseOptions
1484
+ );
1485
+ }
1486
+ } catch (error) {
1487
+ return { mutationApplied: false, error };
1488
+ }
1489
+ let value;
1490
+ let mutationApplied = false;
1491
+ let mutationError;
1492
+ try {
1493
+ const mutation = await mutate(() => lease.assertOwnedAndUnchanged());
1494
+ value = mutation.value;
1495
+ mutationApplied = mutation.mutationApplied;
1496
+ } catch (error) {
1497
+ mutationError = error;
1498
+ try {
1499
+ mutationApplied = await mutationAppliedAfterError();
1500
+ } catch {
1501
+ mutationApplied = false;
1502
+ }
1503
+ }
1504
+ let maintenanceError;
1505
+ if (mutationApplied) {
1506
+ try {
1507
+ await afterMutationApplied();
1508
+ } catch (error) {
1509
+ maintenanceError = error;
1510
+ logSessionArchiveWarning(
1511
+ `scheduled task lifecycle update failed action=${action} workspace=${safeLogValue(
1512
+ service.getProjectRoot()
1513
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1514
+ errorMessage(error)
1515
+ )}`
1516
+ );
1517
+ }
1518
+ }
1519
+ let releaseError;
1520
+ try {
1521
+ await lease.release();
1522
+ } catch (error) {
1523
+ releaseError = error;
1524
+ }
1525
+ if (releaseError !== void 0) {
1526
+ logMaintenanceLeaseReleaseFailure({
1527
+ action,
1528
+ workspace: service.getProjectRoot(),
1529
+ sessionId,
1530
+ error: releaseError,
1531
+ mutationApplied
1532
+ });
1533
+ if (mutationError !== void 0) {
1534
+ logSessionArchiveWarning(
1535
+ `session maintenance mutation also failed action=${action} workspace=${safeLogValue(
1536
+ service.getProjectRoot()
1537
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1538
+ errorMessage(mutationError)
1539
+ )}`
1540
+ );
1541
+ }
1542
+ return { mutationApplied, error: releaseError, maintenanceError };
1543
+ }
1544
+ if (mutationError !== void 0) {
1545
+ return { mutationApplied, error: mutationError, maintenanceError };
1546
+ }
1547
+ return { value, mutationApplied, maintenanceError };
1548
+ }
1549
+ __name(runWithDaemonWriterLease, "runWithDaemonWriterLease");
1550
+ function logMaintenanceLeaseReleaseFailure(params) {
1551
+ const errorKind = typeof params.error === "object" && params.error !== null && typeof params.error.errorKind === "string" ? params.error.errorKind : "unknown";
1552
+ logSessionArchiveWarning(
1553
+ `session maintenance lease release failed action=${params.action} workspace=${safeLogValue(
1554
+ params.workspace
1555
+ )} session=${safeLogValue(params.sessionId)} errorKind=${safeLogValue(
1556
+ errorKind
1557
+ )} mutationApplied=${params.mutationApplied}`
1558
+ );
1559
+ }
1560
+ __name(logMaintenanceLeaseReleaseFailure, "logMaintenanceLeaseReleaseFailure");
1561
+ async function classifySessionLocation(service, sessionId) {
1562
+ return service.getMaintainableSessionLocation(sessionId);
1563
+ }
1564
+ __name(classifySessionLocation, "classifySessionLocation");
1565
+ function sessionLocationError(sessionId) {
1566
+ const error = new SessionConflictError(sessionId);
1567
+ error.message = `Session "${sessionId}" exists in both active and archived directories. Retry with resolveConflicts: true to keep one copy.`;
1568
+ return error;
1569
+ }
1570
+ __name(sessionLocationError, "sessionLocationError");
1571
+ function updateScheduledTaskForMaintenance(service, sessionId, action, assertCanMutate) {
1572
+ if (action === "archive") {
1573
+ return disableTasksForSessions(service.getProjectRoot(), [sessionId], {
1574
+ assertCanCommit: assertCanMutate
1575
+ });
1576
+ }
1577
+ if (action === "unarchive") {
1578
+ return enableTasksForSessions(
1579
+ service.getProjectRoot(),
1580
+ [sessionId],
1581
+ Date.now(),
1582
+ { assertCanCommit: assertCanMutate }
1583
+ );
1584
+ }
1585
+ return removeTasksForSessions(service.getProjectRoot(), [sessionId], {
1586
+ assertCanCommit: assertCanMutate
1587
+ });
1588
+ }
1589
+ __name(updateScheduledTaskForMaintenance, "updateScheduledTaskForMaintenance");
1590
+ async function deletePersistedSessionWithLease(service, sessionId, assertCanMutate) {
1591
+ const initialLocation = await classifySessionLocation(service, sessionId);
1592
+ if (initialLocation === void 0) {
1593
+ let maintenanceError;
1594
+ try {
1595
+ assertCanMutate?.();
1596
+ await updateScheduledTaskForMaintenance(
1597
+ service,
1598
+ sessionId,
1599
+ "delete",
1600
+ assertCanMutate
1601
+ );
1602
+ } catch (error) {
1603
+ maintenanceError = error;
1604
+ logSessionArchiveWarning(
1605
+ `scheduled task lifecycle update failed action=delete workspace=${safeLogValue(
1606
+ service.getProjectRoot()
1607
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1608
+ errorMessage(error)
1609
+ )}`
1610
+ );
1611
+ }
1612
+ return {
1613
+ kind: "notFound",
1614
+ mutationApplied: false,
1615
+ maintenanceError
1616
+ };
1617
+ }
1618
+ const mutation = await runWithDaemonWriterLease({
1619
+ action: "delete",
1620
+ sessionId,
1621
+ service,
1622
+ mutate: /* @__PURE__ */ __name(async (assertOwnedAndUnchanged) => {
1623
+ const lockedLocation = await classifySessionLocation(service, sessionId);
1624
+ if (lockedLocation === void 0) {
1625
+ return {
1626
+ value: "notFound",
1627
+ mutationApplied: false
1628
+ };
1629
+ }
1630
+ const removed = await service.removeSession(sessionId, {
1631
+ assertStorageUnchanged: assertOwnedAndUnchanged,
1632
+ assertCanMutate
1633
+ });
1634
+ return {
1635
+ value: removed ? "removed" : "notFound",
1636
+ mutationApplied: removed
1637
+ };
1638
+ }, "mutate"),
1639
+ mutationAppliedAfterError: /* @__PURE__ */ __name(async () => await classifySessionLocation(service, sessionId) === void 0, "mutationAppliedAfterError"),
1640
+ afterMutationApplied: /* @__PURE__ */ __name(async () => {
1641
+ assertCanMutate?.();
1642
+ await updateScheduledTaskForMaintenance(
1643
+ service,
1644
+ sessionId,
1645
+ "delete",
1646
+ assertCanMutate
1647
+ );
1648
+ }, "afterMutationApplied")
1649
+ });
1650
+ if (mutation.error !== void 0) {
1651
+ return {
1652
+ kind: "error",
1653
+ error: mutation.error,
1654
+ mutationApplied: mutation.mutationApplied,
1655
+ maintenanceError: mutation.maintenanceError
1656
+ };
1657
+ }
1658
+ return {
1659
+ kind: mutation.value ?? "notFound",
1660
+ mutationApplied: mutation.mutationApplied,
1661
+ maintenanceError: mutation.maintenanceError
1662
+ };
1663
+ }
1664
+ __name(deletePersistedSessionWithLease, "deletePersistedSessionWithLease");
1665
+ async function deleteDaemonSessions(params) {
1666
+ const {
1667
+ sessionIds,
1668
+ service,
1669
+ bridge,
1670
+ coordinator,
1671
+ coordinatorLockHeld = false,
1672
+ assertCanMutate,
1673
+ onError
1674
+ } = params;
1675
+ const uniqueSessionIds = [
1676
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1677
+ ];
1678
+ if (!coordinatorLockHeld) {
1679
+ for (const sessionId of uniqueSessionIds) {
1680
+ coordinator.assertNotTransitioning(sessionId);
1681
+ }
1682
+ }
1683
+ const results = await Promise.all(
1684
+ uniqueSessionIds.map(async (sessionId) => {
1685
+ try {
1686
+ const mutateSession = /* @__PURE__ */ __name(async () => {
1687
+ assertCanMutate?.();
1688
+ const removePersistedSession = /* @__PURE__ */ __name(async () => {
1689
+ const result = await deletePersistedSessionWithLease(
1690
+ service,
1691
+ sessionId,
1692
+ assertCanMutate
1693
+ );
1694
+ if (result.kind === "error") {
1695
+ onError?.({
1696
+ phase: "remove",
1697
+ sessionId,
1698
+ error: errorMessage(result.error)
1699
+ });
1700
+ return result;
1701
+ }
1702
+ try {
1703
+ if (assertCanMutate) {
1704
+ await bridge.deleteSessionAttachments(sessionId, {
1705
+ assertCanCommit: assertCanMutate
1706
+ });
1707
+ } else {
1708
+ await bridge.deleteSessionAttachments(sessionId);
1709
+ }
1710
+ return result;
1711
+ } catch (error) {
1712
+ onError?.({
1713
+ phase: "delete",
1714
+ sessionId,
1715
+ error: errorMessage(error)
1716
+ });
1717
+ return {
1718
+ kind: "error",
1719
+ error,
1720
+ mutationApplied: result.mutationApplied,
1721
+ maintenanceError: result.maintenanceError
1722
+ };
1723
+ }
1724
+ }, "removePersistedSession");
1725
+ try {
1726
+ await bridge.closeSession(sessionId);
1727
+ } catch (error) {
1728
+ if (isSessionNotFoundError(error)) {
1729
+ return await removePersistedSession();
1730
+ }
1731
+ onError?.({
1732
+ phase: "close",
1733
+ sessionId,
1734
+ error: errorMessage(error)
1735
+ });
1736
+ return {
1737
+ kind: "error",
1738
+ error,
1739
+ mutationApplied: false
1740
+ };
1741
+ }
1742
+ return await removePersistedSession();
1743
+ }, "mutateSession");
1744
+ return await (coordinatorLockHeld ? mutateSession() : coordinator.runExclusiveMany([sessionId], mutateSession));
1745
+ } catch (error) {
1746
+ if (error instanceof DaemonDrainingError) {
1747
+ throw error;
1748
+ }
1749
+ onError?.({
1750
+ phase: "delete",
1751
+ sessionId,
1752
+ error: errorMessage(error)
1753
+ });
1754
+ return {
1755
+ kind: "error",
1756
+ error,
1757
+ mutationApplied: false
1758
+ };
1759
+ }
1760
+ })
1761
+ );
1762
+ const removed = [];
1763
+ const notFound = [];
1764
+ const errors = [];
1765
+ for (let i = 0; i < results.length; i++) {
1766
+ const sessionId = uniqueSessionIds[i];
1767
+ const result = results[i];
1768
+ if (result.kind === "removed") {
1769
+ removed.push(sessionId);
1770
+ } else if (result.kind === "notFound") {
1771
+ notFound.push(sessionId);
1772
+ } else {
1773
+ errors.push({ sessionId, error: errorMessage(result.error) });
1774
+ }
1775
+ if (result.maintenanceError !== void 0) {
1776
+ errors.push({
1777
+ sessionId,
1778
+ error: "Scheduled task lifecycle update failed."
1779
+ });
1780
+ }
1781
+ }
1782
+ return { removed, notFound, errors };
1783
+ }
1784
+ __name(deleteDaemonSessions, "deleteDaemonSessions");
1785
+ async function deleteDaemonSessionIfOrphan(params) {
1786
+ const { sessionId, service, bridge, coordinator } = params;
1787
+ coordinator.assertNotTransitioning(sessionId);
1788
+ const result = await coordinator.runExclusiveMany([sessionId], async () => {
1789
+ let killed = false;
1790
+ try {
1791
+ killed = await bridge.killSession(sessionId, {
1792
+ requireZeroAttaches: true
1793
+ });
1794
+ } catch (error) {
1795
+ if (!isSessionNotFoundError(error)) throw error;
1796
+ killed = true;
1797
+ }
1798
+ if (!killed) {
1799
+ return void 0;
1800
+ }
1801
+ return deletePersistedSessionWithLease(service, sessionId);
1802
+ });
1803
+ if (result === void 0) {
1804
+ return false;
1805
+ }
1806
+ if (result.kind === "error") {
1807
+ throw result.error;
1808
+ }
1809
+ bridge.markSessionCatalogChanged();
1810
+ return true;
1811
+ }
1812
+ __name(deleteDaemonSessionIfOrphan, "deleteDaemonSessionIfOrphan");
1813
+ async function assertSessionLoadable(workspaceCwd, sessionId, runtimeBaseDir, options = {}) {
1814
+ const service = new SessionService(workspaceCwd, {
1815
+ runtimeBaseDir
1816
+ });
1817
+ const location = await service.getSessionLocation(sessionId);
1818
+ if (location === "archived") {
1819
+ throw new SessionArchivedError(sessionId);
1820
+ }
1821
+ if (location === "conflict") {
1822
+ if (options.allowActiveConflict) {
1823
+ try {
1824
+ await service.findSessionIdIgnoringCase(sessionId);
1825
+ } catch (error) {
1826
+ if (error instanceof SessionIdCaseConflictError && error.reason === "case_conflict" && error.candidateSessionId === sessionId) {
1827
+ return "active";
1828
+ }
1829
+ if (!(error instanceof SessionIdCaseConflictError)) throw error;
1830
+ }
1831
+ }
1832
+ throw new SessionConflictError(sessionId);
1833
+ }
1834
+ return location;
1835
+ }
1836
+ __name(assertSessionLoadable, "assertSessionLoadable");
1837
+ async function resolveSessionIdForRestore(service, sessionId) {
1838
+ try {
1839
+ return await service.findSessionIdIgnoringCase(sessionId);
1840
+ } catch (error) {
1841
+ if (error instanceof SessionIdCaseConflictError) {
1842
+ if (error.candidateSessionId === sessionId) return sessionId;
1843
+ throw new SessionConflictError(sessionId);
1844
+ }
1845
+ throw error;
1846
+ }
1847
+ }
1848
+ __name(resolveSessionIdForRestore, "resolveSessionIdForRestore");
1849
+ async function assertSessionRestorable(workspaceCwd, sessionId, requestedSessionId, runtimeBaseDir) {
1850
+ const location = await new SessionService(workspaceCwd, {
1851
+ runtimeBaseDir
1852
+ }).getSessionLocation(sessionId);
1853
+ if (location === "archived") {
1854
+ throw new SessionArchivedError(sessionId);
1855
+ }
1856
+ if (location === "conflict") {
1857
+ if (sessionId !== requestedSessionId) {
1858
+ throw new SessionConflictError(requestedSessionId);
1859
+ }
1860
+ return "active";
1861
+ }
1862
+ return location;
1863
+ }
1864
+ __name(assertSessionRestorable, "assertSessionRestorable");
1865
+ async function assertSessionArchived(workspaceCwd, sessionId, runtimeBaseDir) {
1866
+ const location = await new SessionService(workspaceCwd, {
1867
+ runtimeBaseDir
1868
+ }).getSessionLocation(sessionId);
1869
+ if (location === "active") {
1870
+ throw new SessionNotArchivedError(sessionId);
1871
+ }
1872
+ if (location === "conflict") {
1873
+ throw new SessionConflictError(sessionId);
1874
+ }
1875
+ if (location === void 0) {
1876
+ throw new SessionNotFoundError(sessionId);
1877
+ }
1878
+ }
1879
+ __name(assertSessionArchived, "assertSessionArchived");
1880
+ function isSessionNotFoundError(err) {
1881
+ return err instanceof SessionNotFoundError || err instanceof Error && err.name === "SessionNotFoundError";
1882
+ }
1883
+ __name(isSessionNotFoundError, "isSessionNotFoundError");
1884
+ function logSessionArchiveResult(action, result) {
1885
+ const changedLabel = action === "archive" ? "archived" : "unarchived";
1886
+ const alreadyLabel = action === "archive" ? "alreadyArchived" : "alreadyActive";
1887
+ const details = [
1888
+ `requested=${result.requested.length} requestedIds=${formatSessionIds(result.requested)}`,
1889
+ `${changedLabel}=${result.changed.length} ${changedLabel}Ids=${formatSessionIds(result.changed)}`,
1890
+ `${alreadyLabel}=${result.already.length} ${alreadyLabel}Ids=${formatSessionIds(result.already)}`,
1891
+ `notFound=${result.notFound.length} notFoundIds=${formatSessionIds(result.notFound)}`,
1892
+ `errors=${result.errors.length} errorIds=${formatSessionErrors(result.errors)}`
1893
+ ].join(" ");
1894
+ writeStderrLine(`qwen serve: sessions ${action} result ${details}`);
1895
+ }
1896
+ __name(logSessionArchiveResult, "logSessionArchiveResult");
1897
+ function formatSessionIds(sessionIds) {
1898
+ return `[${sessionIds.map((sessionId) => safeLogValue(sessionId)).join(",")}]`;
1899
+ }
1900
+ __name(formatSessionIds, "formatSessionIds");
1901
+ function formatSessionErrors(errors) {
1902
+ return `[${errors.map(
1903
+ ({ sessionId, error }) => `${safeLogValue(sessionId)}:${safeLogValue(errorMessage(error))}`
1904
+ ).join(",")}]`;
1905
+ }
1906
+ __name(formatSessionErrors, "formatSessionErrors");
1907
+ function errorMessage(error) {
1908
+ return error instanceof Error ? error.message : String(error);
1909
+ }
1910
+ __name(errorMessage, "errorMessage");
1911
+ function logSessionArchiveWarning(message) {
1912
+ writeStderrLine(`qwen serve: ${sanitizeLogLine(message)}`);
1913
+ }
1914
+ __name(logSessionArchiveWarning, "logSessionArchiveWarning");
1915
+ var LOG_LINE_UNSAFE_RE = /[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]/g;
1916
+ function sanitizeLogLine(message) {
1917
+ return message.replace(LOG_LINE_UNSAFE_RE, " ").slice(0, 4096);
1918
+ }
1919
+ __name(sanitizeLogLine, "sanitizeLogLine");
1920
+ async function archiveDaemonSessions(params) {
1921
+ const {
1922
+ sessionIds,
1923
+ service,
1924
+ bridge,
1925
+ coordinator,
1926
+ coordinatorLockHeld = false,
1927
+ resolveConflicts = false,
1928
+ assertCanMutate
1929
+ } = params;
1930
+ const uniqueSessionIds = [
1931
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1932
+ ];
1933
+ if (!coordinatorLockHeld) {
1934
+ for (const sessionId of uniqueSessionIds) {
1935
+ coordinator.assertNotTransitioning(sessionId);
1936
+ }
1937
+ }
1938
+ const results = await Promise.all(
1939
+ uniqueSessionIds.map(async (sessionId) => {
1940
+ try {
1941
+ const mutateSession = /* @__PURE__ */ __name(async () => {
1942
+ assertCanMutate?.();
1943
+ try {
1944
+ await bridge.closeSession(sessionId, void 0, {
1945
+ requireAgentClose: true
1946
+ });
1947
+ } catch (error) {
1948
+ if (!isSessionNotFoundError(error)) {
1949
+ return {
1950
+ kind: "error",
1951
+ error,
1952
+ mutationApplied: false
1953
+ };
1954
+ }
1955
+ }
1956
+ const initialLocation = await classifySessionLocation(
1957
+ service,
1958
+ sessionId
1959
+ );
1960
+ if (initialLocation === void 0) {
1961
+ return { kind: "notFound", mutationApplied: false };
1962
+ }
1963
+ if (initialLocation === "archived") {
1964
+ let maintenanceError;
1965
+ try {
1966
+ await updateScheduledTaskForMaintenance(
1967
+ service,
1968
+ sessionId,
1969
+ "archive",
1970
+ assertCanMutate
1971
+ );
1972
+ } catch (error) {
1973
+ maintenanceError = error;
1974
+ logSessionArchiveWarning(
1975
+ `scheduled task lifecycle update failed action=archive workspace=${safeLogValue(
1976
+ service.getProjectRoot()
1977
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1978
+ errorMessage(error)
1979
+ )}`
1980
+ );
1981
+ }
1982
+ return {
1983
+ kind: "alreadyArchived",
1984
+ mutationApplied: false,
1985
+ maintenanceError
1986
+ };
1987
+ }
1988
+ if (initialLocation === "conflict" && !resolveConflicts) {
1989
+ return {
1990
+ kind: "error",
1991
+ error: sessionLocationError(sessionId),
1992
+ mutationApplied: false
1993
+ };
1994
+ }
1995
+ const mutation = await runWithDaemonWriterLease({
1996
+ action: "archive",
1997
+ sessionId,
1998
+ service,
1999
+ mutate: /* @__PURE__ */ __name(async (assertOwnedAndUnchanged) => {
2000
+ const lockedLocation = await classifySessionLocation(
2001
+ service,
2002
+ sessionId
2003
+ );
2004
+ if (lockedLocation === void 0) {
2005
+ return {
2006
+ value: "notFound",
2007
+ mutationApplied: false
2008
+ };
2009
+ }
2010
+ if (lockedLocation === "archived") {
2011
+ return {
2012
+ value: "alreadyArchived",
2013
+ mutationApplied: false
2014
+ };
2015
+ }
2016
+ if (lockedLocation === "conflict" && !resolveConflicts) {
2017
+ throw sessionLocationError(sessionId);
2018
+ }
2019
+ const result = await service.archiveSessions([sessionId], {
2020
+ resolveConflicts,
2021
+ assertStorageUnchanged: assertOwnedAndUnchanged,
2022
+ assertCanMutate
2023
+ });
2024
+ if (result.errors[0]) throw result.errors[0].error;
2025
+ if (result.archived.length > 0) {
2026
+ return {
2027
+ value: result.resolvedConflicts.length ? "resolvedConflict" : "archived",
2028
+ mutationApplied: true
2029
+ };
2030
+ }
2031
+ return {
2032
+ value: result.alreadyArchived.length > 0 ? "alreadyArchived" : "notFound",
2033
+ mutationApplied: false
2034
+ };
2035
+ }, "mutate"),
2036
+ mutationAppliedAfterError: /* @__PURE__ */ __name(async () => await classifySessionLocation(service, sessionId) === "archived", "mutationAppliedAfterError"),
2037
+ afterMutationApplied: /* @__PURE__ */ __name(async () => {
2038
+ assertCanMutate?.();
2039
+ await updateScheduledTaskForMaintenance(
2040
+ service,
2041
+ sessionId,
2042
+ "archive",
2043
+ assertCanMutate
2044
+ );
2045
+ }, "afterMutationApplied")
2046
+ });
2047
+ if (mutation.error !== void 0) {
2048
+ return {
2049
+ kind: "error",
2050
+ error: mutation.error,
2051
+ mutationApplied: mutation.mutationApplied,
2052
+ maintenanceError: mutation.maintenanceError
2053
+ };
2054
+ }
2055
+ return {
2056
+ kind: mutation.value ?? "notFound",
2057
+ mutationApplied: mutation.mutationApplied,
2058
+ maintenanceError: mutation.maintenanceError
2059
+ };
2060
+ }, "mutateSession");
2061
+ return await (coordinatorLockHeld ? mutateSession() : coordinator.runExclusiveMany([sessionId], mutateSession));
2062
+ } catch (error) {
2063
+ if (error instanceof DaemonDrainingError) {
2064
+ throw error;
2065
+ }
2066
+ return {
2067
+ kind: "error",
2068
+ error,
2069
+ mutationApplied: false,
2070
+ maintenanceError: void 0
2071
+ };
2072
+ }
2073
+ })
2074
+ );
2075
+ const archived = [];
2076
+ const alreadyArchived = [];
2077
+ const resolvedConflicts = [];
2078
+ const notFound = [];
2079
+ const errors = [];
2080
+ for (let i = 0; i < results.length; i++) {
2081
+ const sessionId = uniqueSessionIds[i];
2082
+ const result = results[i];
2083
+ if (result.kind === "archived") archived.push(sessionId);
2084
+ else if (result.kind === "resolvedConflict") {
2085
+ archived.push(sessionId);
2086
+ resolvedConflicts.push(sessionId);
2087
+ } else if (result.kind === "alreadyArchived") {
2088
+ alreadyArchived.push(sessionId);
2089
+ } else if (result.kind === "notFound") notFound.push(sessionId);
2090
+ else errors.push({ sessionId, error: result.error });
2091
+ if ("maintenanceError" in result && result.maintenanceError !== void 0) {
2092
+ errors.push({ sessionId, error: result.maintenanceError });
2093
+ }
2094
+ }
2095
+ logSessionArchiveResult("archive", {
2096
+ requested: uniqueSessionIds,
2097
+ changed: archived,
2098
+ already: alreadyArchived,
2099
+ notFound,
2100
+ errors
2101
+ });
2102
+ return {
2103
+ archived,
2104
+ alreadyArchived,
2105
+ resolvedConflicts,
2106
+ notFound,
2107
+ errors
2108
+ };
2109
+ }
2110
+ __name(archiveDaemonSessions, "archiveDaemonSessions");
2111
+ async function unarchiveDaemonSessions(params) {
2112
+ const {
2113
+ sessionIds,
2114
+ service,
2115
+ coordinator,
2116
+ coordinatorLockHeld = false,
2117
+ resolveConflicts = false,
2118
+ assertCanMutate
2119
+ } = params;
2120
+ const uniqueSessionIds = [
2121
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
2122
+ ];
2123
+ if (!coordinatorLockHeld) {
2124
+ for (const sessionId of uniqueSessionIds) {
2125
+ coordinator.assertNotTransitioning(sessionId);
2126
+ }
2127
+ }
2128
+ const results = await Promise.all(
2129
+ uniqueSessionIds.map(async (sessionId) => {
2130
+ try {
2131
+ const mutateSession = /* @__PURE__ */ __name(async () => {
2132
+ assertCanMutate?.();
2133
+ const initialLocation = await classifySessionLocation(
2134
+ service,
2135
+ sessionId
2136
+ );
2137
+ if (initialLocation === void 0) {
2138
+ return { kind: "notFound", mutationApplied: false };
2139
+ }
2140
+ if (initialLocation === "active") {
2141
+ let maintenanceError;
2142
+ try {
2143
+ await updateScheduledTaskForMaintenance(
2144
+ service,
2145
+ sessionId,
2146
+ "unarchive",
2147
+ assertCanMutate
2148
+ );
2149
+ } catch (error) {
2150
+ maintenanceError = error;
2151
+ logSessionArchiveWarning(
2152
+ `scheduled task lifecycle update failed action=unarchive workspace=${safeLogValue(
2153
+ service.getProjectRoot()
2154
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
2155
+ errorMessage(error)
2156
+ )}`
2157
+ );
2158
+ }
2159
+ return {
2160
+ kind: "alreadyActive",
2161
+ mutationApplied: false,
2162
+ maintenanceError
2163
+ };
2164
+ }
2165
+ if (initialLocation === "conflict" && !resolveConflicts) {
2166
+ return {
2167
+ kind: "error",
2168
+ error: sessionLocationError(sessionId),
2169
+ mutationApplied: false
2170
+ };
2171
+ }
2172
+ const mutation = await runWithDaemonWriterLease({
2173
+ action: "unarchive",
2174
+ sessionId,
2175
+ service,
2176
+ mutate: /* @__PURE__ */ __name(async (assertOwnedAndUnchanged) => {
2177
+ const lockedLocation = await classifySessionLocation(
2178
+ service,
2179
+ sessionId
2180
+ );
2181
+ if (lockedLocation === void 0) {
2182
+ return {
2183
+ value: "notFound",
2184
+ mutationApplied: false
2185
+ };
2186
+ }
2187
+ if (lockedLocation === "active") {
2188
+ return {
2189
+ value: "alreadyActive",
2190
+ mutationApplied: false
2191
+ };
2192
+ }
2193
+ if (lockedLocation === "conflict" && !resolveConflicts) {
2194
+ throw sessionLocationError(sessionId);
2195
+ }
2196
+ const result = await service.unarchiveSessions([sessionId], {
2197
+ resolveConflicts,
2198
+ assertStorageUnchanged: assertOwnedAndUnchanged,
2199
+ assertCanMutate
2200
+ });
2201
+ if (result.errors[0]) throw result.errors[0].error;
2202
+ if (result.unarchived.length > 0) {
2203
+ return {
2204
+ value: result.resolvedConflicts.length ? "resolvedConflict" : "unarchived",
2205
+ mutationApplied: true
2206
+ };
2207
+ }
2208
+ return {
2209
+ value: result.alreadyActive.length > 0 ? "alreadyActive" : "notFound",
2210
+ mutationApplied: false
2211
+ };
2212
+ }, "mutate"),
2213
+ mutationAppliedAfterError: /* @__PURE__ */ __name(async () => await classifySessionLocation(service, sessionId) === "active", "mutationAppliedAfterError"),
2214
+ afterMutationApplied: /* @__PURE__ */ __name(async () => {
2215
+ assertCanMutate?.();
2216
+ await updateScheduledTaskForMaintenance(
2217
+ service,
2218
+ sessionId,
2219
+ "unarchive",
2220
+ assertCanMutate
2221
+ );
2222
+ }, "afterMutationApplied")
2223
+ });
2224
+ if (mutation.error !== void 0) {
2225
+ return {
2226
+ kind: "error",
2227
+ error: mutation.error,
2228
+ mutationApplied: mutation.mutationApplied,
2229
+ maintenanceError: mutation.maintenanceError
2230
+ };
2231
+ }
2232
+ return {
2233
+ kind: mutation.value ?? "notFound",
2234
+ mutationApplied: mutation.mutationApplied,
2235
+ maintenanceError: mutation.maintenanceError
2236
+ };
2237
+ }, "mutateSession");
2238
+ return await (coordinatorLockHeld ? mutateSession() : coordinator.runExclusiveMany([sessionId], mutateSession));
2239
+ } catch (error) {
2240
+ if (error instanceof DaemonDrainingError) {
2241
+ throw error;
2242
+ }
2243
+ return {
2244
+ kind: "error",
2245
+ error,
2246
+ mutationApplied: false,
2247
+ maintenanceError: void 0
2248
+ };
2249
+ }
2250
+ })
2251
+ );
2252
+ const unarchived = [];
2253
+ const alreadyActive = [];
2254
+ const resolvedConflicts = [];
2255
+ const notFound = [];
2256
+ const errors = [];
2257
+ for (let i = 0; i < results.length; i++) {
2258
+ const sessionId = uniqueSessionIds[i];
2259
+ const result = results[i];
2260
+ if (result.kind === "unarchived") unarchived.push(sessionId);
2261
+ else if (result.kind === "resolvedConflict") {
2262
+ unarchived.push(sessionId);
2263
+ resolvedConflicts.push(sessionId);
2264
+ } else if (result.kind === "alreadyActive") alreadyActive.push(sessionId);
2265
+ else if (result.kind === "notFound") notFound.push(sessionId);
2266
+ else errors.push({ sessionId, error: result.error });
2267
+ if (result.maintenanceError !== void 0) {
2268
+ errors.push({ sessionId, error: result.maintenanceError });
2269
+ }
2270
+ }
2271
+ logSessionArchiveResult("unarchive", {
2272
+ requested: uniqueSessionIds,
2273
+ changed: unarchived,
2274
+ already: alreadyActive,
2275
+ notFound,
2276
+ errors
2277
+ });
2278
+ return {
2279
+ unarchived,
2280
+ alreadyActive,
2281
+ resolvedConflicts,
2282
+ notFound,
2283
+ errors
2284
+ };
2285
+ }
2286
+ __name(unarchiveDaemonSessions, "unarchiveDaemonSessions");
2287
+
2288
+ export {
2289
+ createSessionOrganizationService,
2290
+ laterActivityTimestamp,
2291
+ invalidateWorkspaceSessionListCache,
2292
+ InvalidCursorError,
2293
+ listWorkspaceSessionsForResponse,
2294
+ listLiveWorkspaceSessionsForResponse,
2295
+ getWorkspaceSessionInfoForResponse,
2296
+ parseSessionPageSizeQuery,
2297
+ runWithWorkspaceRuntimeStorage,
2298
+ createWorkspaceRuntimeSessionService,
2299
+ DaemonDrainingError,
2300
+ SessionArchiveCoordinator,
2301
+ deleteDaemonSessions,
2302
+ deleteDaemonSessionIfOrphan,
2303
+ assertSessionLoadable,
2304
+ resolveSessionIdForRestore,
2305
+ assertSessionRestorable,
2306
+ assertSessionArchived,
2307
+ logSessionArchiveWarning,
2308
+ archiveDaemonSessions,
2309
+ unarchiveDaemonSessions
2310
+ };
2311
+ /**
2312
+ * @license
2313
+ * Copyright 2025 Qwen Team
2314
+ * SPDX-License-Identifier: Apache-2.0
2315
+ */
2316
+ /**
2317
+ * @license
2318
+ * Copyright 2026 Qwen Team
2319
+ * SPDX-License-Identifier: Apache-2.0
2320
+ */