@qwen-code/qwen-code 0.22.2-preview.1 → 0.22.3

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 (437) hide show
  1. package/bundled/computer-use/SKILL.md +3 -3
  2. package/bundled/goal-draft/SKILL.md +109 -0
  3. package/bundled/qc-helper/docs/configuration/settings.md +37 -36
  4. package/bundled/qc-helper/docs/features/_meta.ts +1 -0
  5. package/bundled/qc-helper/docs/features/channels/dws.md +2 -0
  6. package/bundled/qc-helper/docs/features/channels/overview.md +34 -3
  7. package/bundled/qc-helper/docs/features/code-review.md +3 -3
  8. package/bundled/qc-helper/docs/features/commands.md +2 -1
  9. package/bundled/qc-helper/docs/features/computer-use.md +2 -2
  10. package/bundled/qc-helper/docs/features/goals.md +58 -0
  11. package/bundled/qc-helper/docs/features/headless.md +13 -11
  12. package/bundled/qc-helper/docs/features/status-line.md +3 -3
  13. package/bundled/qc-helper/docs/features/tool-use-summaries.md +1 -1
  14. package/bundled/qc-helper/docs/qwen-serve.md +1 -1
  15. package/bundled/review/SKILL.md +81 -31
  16. package/bundled/review/references/persistence.md +7 -3
  17. package/bundled/review/references/posting.md +10 -4
  18. package/chunks/MaxSizedBox-X42SXBJH.js +110 -0
  19. package/chunks/{StandaloneSessionPicker-5D2L22SF.js → StandaloneSessionPicker-2FJAOLGG.js} +81 -83
  20. package/chunks/{acpAgent-4DCKLA32.js → acpAgent-2ZMIJAFV.js} +1153 -357
  21. package/chunks/{agent-B4AFZL6H.js → agent-X5WX3L2I.js} +44 -46
  22. package/chunks/agent-headless-IZM25LJA.js +85 -0
  23. package/chunks/{anthropicContentGenerator-U76GTVB6.js → anthropicContentGenerator-YVTB6QX7.js} +46 -50
  24. package/chunks/{artifact-tool-XDJCZZCF.js → artifact-tool-XSMPHZBT.js} +11 -3
  25. package/chunks/{askUserQuestion-ZXXERLEV.js → askUserQuestion-4SWJY65V.js} +2 -2
  26. package/chunks/bridge-ME6QXZNA.js +119 -0
  27. package/chunks/{channel-management-service-HXXS3HOZ.js → channel-management-service-HQ6KDS7C.js} +6 -6
  28. package/chunks/channel-settings-store-PEOI7XCG.js +120 -0
  29. package/chunks/{channel-worker-group-EVDC2P4K.js → channel-worker-group-6NA6BBZV.js} +8 -7
  30. package/chunks/{channel-worker-manager-IJJZHGEI.js → channel-worker-manager-NEZ2J6RK.js} +10 -8
  31. package/chunks/{channel-worker-supervisor-YSKB5GVB.js → channel-worker-supervisor-FKU7DIHJ.js} +6 -5
  32. package/chunks/{chunk-7QGEJI7M.js → chunk-23RFD54N.js} +1 -1
  33. package/chunks/{chunk-JLU3FPQR.js → chunk-2HYKTO7V.js} +5 -5
  34. package/chunks/chunk-2LNNVAUV.js +1584 -0
  35. package/chunks/{chunk-FJAITR4L.js → chunk-2OBKDPZZ.js} +2 -2
  36. package/chunks/{chunk-JSY43GMI.js → chunk-2OUD5T67.js} +185 -174
  37. package/chunks/{chunk-LJP2BBMK.js → chunk-2SXSLSQE.js} +4 -4
  38. package/chunks/chunk-2TNL5KPM.js +49 -0
  39. package/chunks/{chunk-XMSMTU6H.js → chunk-2YOHKHYR.js} +4 -4
  40. package/chunks/{chunk-MCKJTBZN.js → chunk-36GSQ3MM.js} +2 -2
  41. package/chunks/chunk-36LGBEM6.js +130 -0
  42. package/chunks/{chunk-ZWKGZB2K.js → chunk-3JXM2CVW.js} +3 -3
  43. package/chunks/{chunk-X3XGCJ32.js → chunk-3SZC4VP4.js} +28 -111
  44. package/chunks/{chunk-ILPXSKGQ.js → chunk-3WK3QDNV.js} +2 -2
  45. package/chunks/{chunk-IKN3IUJP.js → chunk-3XKLXHGK.js} +17 -9
  46. package/chunks/{chunk-ZLTEQYNC.js → chunk-42IDLQWS.js} +26 -20
  47. package/chunks/chunk-4CMJKUND.js +95 -0
  48. package/chunks/{chunk-77TOMRBG.js → chunk-4K7KNVWH.js} +3 -3
  49. package/chunks/{chunk-SQPOJ4ZI.js → chunk-4NDLQAY2.js} +27 -270
  50. package/chunks/{chunk-V3GINY6K.js → chunk-4QHPPXK2.js} +16 -8
  51. package/chunks/{chunk-VBF4KZRQ.js → chunk-4TT3IVGA.js} +1 -1
  52. package/chunks/{chunk-IOGKXPL3.js → chunk-4VPCTGH6.js} +6 -6
  53. package/chunks/chunk-4VQBQLIZ.js +293 -0
  54. package/chunks/{chunk-UCSV2IZW.js → chunk-62GQFYID.js} +3 -3
  55. package/chunks/{chunk-SLEWBQWM.js → chunk-6DIGWMGT.js} +2 -2
  56. package/chunks/{chunk-BRVWYMKV.js → chunk-6MBXY6WM.js} +1 -1
  57. package/chunks/{chunk-PVBT5QPD.js → chunk-6PJOTWAN.js} +1 -1
  58. package/chunks/{chunk-WZ3QKPMQ.js → chunk-6X7EU5TI.js} +19 -31
  59. package/chunks/{chunk-KQYW2GB5.js → chunk-6ZPDLGHN.js} +6 -6
  60. package/chunks/{chunk-AKQA3WCH.js → chunk-734C6JGI.js} +723 -3399
  61. package/chunks/{chunk-F7M6ZFGU.js → chunk-73RM4POK.js} +8 -8
  62. package/chunks/{chunk-ELY4QVIB.js → chunk-7EQQR46F.js} +1 -1
  63. package/chunks/{chunk-KGJGEEVR.js → chunk-7FA2II6K.js} +10 -1
  64. package/chunks/chunk-7J6OTNGO.js +424 -0
  65. package/chunks/{chunk-LWLEPXKK.js → chunk-7LOELM2I.js} +19 -2
  66. package/chunks/{chunk-DIMEPKCW.js → chunk-7S226YTK.js} +1 -1
  67. package/chunks/{chunk-AWFZDYSD.js → chunk-7T52W4SW.js} +1 -1
  68. package/chunks/{chunk-3JKUX4PB.js → chunk-7VMIMAVB.js} +9 -9
  69. package/chunks/{chunk-2MHGD7EE.js → chunk-A3LWD5MK.js} +1 -1
  70. package/chunks/{chunk-E4I5MVBR.js → chunk-ABS25QER.js} +1 -1
  71. package/chunks/{chunk-TDQBVEPK.js → chunk-AIAOIFY4.js} +10 -8
  72. package/chunks/{chunk-NEZZHGEI.js → chunk-AYFA7MZV.js} +6 -6
  73. package/chunks/{chunk-FVDQ5E67.js → chunk-B466ZSHZ.js} +3 -3
  74. package/chunks/{chunk-6US7BF3G.js → chunk-B5PHIJGI.js} +183 -5
  75. package/chunks/{chunk-4TPAG3O7.js → chunk-BFPESSTR.js} +1 -1
  76. package/chunks/{chunk-WBT3STGU.js → chunk-BKWNKLZB.js} +20 -20
  77. package/chunks/{chunk-T45CL2NT.js → chunk-BOWFGCEU.js} +3 -3
  78. package/chunks/{chunk-IPQA4SR5.js → chunk-BWORX6FA.js} +1 -1
  79. package/chunks/{chunk-BKDAF7ES.js → chunk-BXDAPVQU.js} +2 -2
  80. package/chunks/{chunk-ZEADBZLO.js → chunk-C2X7KY45.js} +3 -3
  81. package/chunks/{chunk-PTQF7WRA.js → chunk-C3PEFRKD.js} +6 -6
  82. package/chunks/{chunk-7OBH4AM2.js → chunk-CAJTKR6W.js} +5 -5
  83. package/chunks/{chunk-2FN2HNTI.js → chunk-CFJY4DGX.js} +2 -2
  84. package/chunks/{chunk-SUE2ZMUH.js → chunk-CIZCL2MW.js} +49 -31
  85. package/chunks/{chunk-W2WRNJKX.js → chunk-CLWO3B77.js} +6 -6
  86. package/chunks/{chunk-U45D46O5.js → chunk-CMHFCLBU.js} +1 -1
  87. package/chunks/{chunk-LRKMQPMD.js → chunk-CQH5KTKC.js} +1 -1
  88. package/chunks/{chunk-JECO75XD.js → chunk-D5LUXLUH.js} +2 -2
  89. package/chunks/chunk-DJBQCO2E.js +842 -0
  90. package/chunks/{chunk-BQBUZDDH.js → chunk-DJECZIJX.js} +42 -42
  91. package/chunks/{chunk-GTUZ3R6I.js → chunk-DJEZ55D4.js} +351 -113
  92. package/chunks/{chunk-HPECDZ6X.js → chunk-DJPASAUV.js} +3866 -1077
  93. package/chunks/{chunk-VYWCFWI5.js → chunk-DMLVSW7L.js} +542 -654
  94. package/chunks/{chunk-EB4VDXNI.js → chunk-DYXFD5RO.js} +182 -3
  95. package/chunks/{chunk-ZKAZP2ZG.js → chunk-EB6QRGHM.js} +3 -3
  96. package/chunks/{chunk-UWICO5KN.js → chunk-EFWRMA2I.js} +3 -3
  97. package/chunks/{chunk-3UZCLCXR.js → chunk-EKSCLBBF.js} +3 -3
  98. package/chunks/{chunk-ALTQLFEG.js → chunk-EQSBPBZ3.js} +5 -194
  99. package/chunks/{chunk-624NHDGB.js → chunk-ERFDKH32.js} +11 -0
  100. package/chunks/{chunk-4K44OMLI.js → chunk-FROAFEFB.js} +3 -3
  101. package/chunks/{chunk-MZS7GEC7.js → chunk-FTF2YIZ5.js} +1 -1
  102. package/chunks/{chunk-Z7VOMGDC.js → chunk-FTJMWDND.js} +0 -24
  103. package/chunks/{chunk-ZJG323IA.js → chunk-G6FECKTJ.js} +7 -5
  104. package/chunks/{chunk-TMGAS5TO.js → chunk-GBJBJ4HX.js} +26 -4
  105. package/chunks/{chunk-UCQOSV6A.js → chunk-GPGU4S2N.js} +3 -3
  106. package/chunks/{chunk-BHTJAO36.js → chunk-GVIVASYK.js} +7 -7
  107. package/chunks/chunk-H72BQNM3.js +645 -0
  108. package/chunks/{chunk-Z4X5MTRT.js → chunk-HCOBAG2L.js} +2 -4
  109. package/chunks/{chunk-FCSWZAS3.js → chunk-HP5LR5HL.js} +5 -5
  110. package/chunks/{chunk-7JPW6IYH.js → chunk-HVC3PNVC.js} +1 -1
  111. package/chunks/{chunk-OI2DR6QB.js → chunk-I6LYRJPB.js} +3 -3
  112. package/chunks/{chunk-E55H6BZ7.js → chunk-ICURCKIU.js} +1335 -119
  113. package/chunks/{chunk-PAJGKZAA.js → chunk-ISKH4QX3.js} +14 -12
  114. package/chunks/{chunk-AYVIGUUK.js → chunk-JB4JIVTJ.js} +1 -1
  115. package/chunks/{chunk-FN5C6C7G.js → chunk-JHYH6PYQ.js} +192 -478
  116. package/chunks/{chunk-T6OODF2U.js → chunk-JWALNCLT.js} +1 -1
  117. package/chunks/{chunk-SKNVVYIJ.js → chunk-K5KXUXWC.js} +3 -3
  118. package/chunks/{chunk-XUX6O2ZT.js → chunk-KID24ZFN.js} +4 -1
  119. package/chunks/{chunk-I6DY753S.js → chunk-KJO2LBUK.js} +944 -18
  120. package/chunks/{chunk-5T4LWWNX.js → chunk-KYWTPLBJ.js} +18 -21
  121. package/chunks/{chunk-CZFQ62RM.js → chunk-LHBUKJG2.js} +4 -4
  122. package/chunks/{chunk-TOF4UZHH.js → chunk-LUEHOUHM.js} +3 -3
  123. package/chunks/{chunk-2YDYDDE2.js → chunk-M3QRM3DE.js} +3 -3
  124. package/chunks/{chunk-GNMJNDZE.js → chunk-M6FOJXW3.js} +1 -1
  125. package/chunks/{chunk-ZGWDHSUM.js → chunk-MF7HCQWZ.js} +4 -4
  126. package/chunks/{chunk-66GIFJ63.js → chunk-MK2GIB46.js} +1 -1
  127. package/chunks/{chunk-TFV4RXPU.js → chunk-MO3FC2WT.js} +1 -1
  128. package/chunks/{chunk-TR7G7XFQ.js → chunk-MPNBVAEU.js} +5 -5
  129. package/chunks/{chunk-K3LPAED5.js → chunk-MQM5PJML.js} +24 -4
  130. package/chunks/{chunk-3WBMPR3S.js → chunk-MSBO7X2W.js} +1 -1
  131. package/chunks/{chunk-5PA6UEYA.js → chunk-MZCJWS5Y.js} +1 -1
  132. package/chunks/{chunk-BGXZBI5B.js → chunk-N4X7G4J2.js} +2 -1
  133. package/chunks/{chunk-27ONXAFY.js → chunk-NIFYWDYN.js} +1 -1
  134. package/chunks/{chunk-AP7WZONS.js → chunk-NMOD2FXQ.js} +19 -9
  135. package/chunks/{chunk-IJVDHPKD.js → chunk-NU7RKEZR.js} +2 -2
  136. package/chunks/{chunk-5URK47RN.js → chunk-NV55WWD6.js} +11595 -10375
  137. package/chunks/{chunk-HABT2Z7R.js → chunk-OU5APVWO.js} +4 -4
  138. package/chunks/{chunk-QR4AHMGQ.js → chunk-P2G476QN.js} +13 -13
  139. package/chunks/{chunk-5SM2AK65.js → chunk-PADPMMYM.js} +5 -5
  140. package/chunks/{chunk-RRKNX553.js → chunk-PDQGMSZK.js} +1 -1
  141. package/chunks/{chunk-GTUKW3I6.js → chunk-PPKZ7JOE.js} +1 -1
  142. package/chunks/{chunk-SAH4BD2J.js → chunk-PQEISIKS.js} +67 -0
  143. package/chunks/{chunk-XIRDDFRS.js → chunk-PZ66FRIC.js} +2644 -2296
  144. package/chunks/{chunk-H3HZ4AWW.js → chunk-Q2MSPKIJ.js} +1 -1
  145. package/chunks/{chunk-WEGXPP5E.js → chunk-QFCDF5PL.js} +1 -1
  146. package/chunks/{chunk-OF2DPXUS.js → chunk-QYMAKPY5.js} +119 -24
  147. package/chunks/{chunk-JVPFTDBK.js → chunk-RFIDDFAL.js} +1 -1
  148. package/chunks/chunk-RKFGE7JH.js +93 -0
  149. package/chunks/{chunk-CPPYZHBN.js → chunk-RU7BK6B3.js} +1 -1
  150. package/chunks/chunk-SEONHUS3.js +275 -0
  151. package/chunks/{chunk-DEYPMJPD.js → chunk-SMPR7SPO.js} +1 -1
  152. package/chunks/chunk-SS4MRMKE.js +3525 -0
  153. package/chunks/{chunk-BPMVPWBT.js → chunk-SS5SDCD3.js} +6 -6
  154. package/chunks/{chunk-J3CBIEDS.js → chunk-ST5MDGH3.js} +32 -15
  155. package/chunks/{chunk-J5352S3S.js → chunk-ST5V3ZOC.js} +3 -3
  156. package/chunks/{chunk-7CWEZQ6T.js → chunk-STUJ7IMZ.js} +0 -77
  157. package/chunks/{chunk-4K7NQDCG.js → chunk-T4EFG2P5.js} +18 -9
  158. package/chunks/{chunk-TWSKM647.js → chunk-T7KMERIX.js} +1 -1
  159. package/chunks/{chunk-5CMWFBML.js → chunk-TEBDFQBZ.js} +1 -1
  160. package/chunks/{chunk-EC5BONC3.js → chunk-TPI7O7HR.js} +1 -1
  161. package/chunks/{chunk-T2CRBIDJ.js → chunk-TTX2JUE6.js} +1 -1
  162. package/chunks/{chunk-VOEMVOM4.js → chunk-TVC6HQ2U.js} +2 -2
  163. package/chunks/{chunk-WXDZZFH3.js → chunk-TZBSGJ6C.js} +6 -6
  164. package/chunks/chunk-U54AYGEC.js +337 -0
  165. package/chunks/{chunk-2NNTE2ED.js → chunk-UHQFIS7N.js} +15 -0
  166. package/chunks/{chunk-76WGY6LW.js → chunk-URE3QBBB.js} +3 -3
  167. package/chunks/{chunk-KOJ6MHD5.js → chunk-UTLCH2FK.js} +1 -1
  168. package/chunks/{chunk-7DPKPBOQ.js → chunk-V2NDP3I4.js} +2 -2
  169. package/chunks/{chunk-FJWICLG7.js → chunk-V4264FEG.js} +9 -9
  170. package/chunks/{chunk-XR7OIAQF.js → chunk-V5J4J5TP.js} +2 -2
  171. package/chunks/{chunk-7UJTY5V3.js → chunk-V7EESTJV.js} +1 -1
  172. package/chunks/{chunk-Z6L3C4VF.js → chunk-VBCPNIQD.js} +39 -39
  173. package/chunks/{chunk-ATLGYSYH.js → chunk-VGIFXISB.js} +4 -4
  174. package/chunks/{chunk-X2UOOG5V.js → chunk-VQUGEVGR.js} +1 -1
  175. package/chunks/{chunk-XJS54K4A.js → chunk-VTHREBQM.js} +2 -2
  176. package/chunks/{chunk-AA7VBRBG.js → chunk-W3JH33JE.js} +8 -8
  177. package/chunks/{chunk-FPH6TXD3.js → chunk-WAOIHTJS.js} +1 -1
  178. package/chunks/{chunk-CDUN63IN.js → chunk-WGY3AVGM.js} +3 -3
  179. package/chunks/{chunk-JLGFGPZJ.js → chunk-WNPDGUJO.js} +22 -3
  180. package/chunks/{chunk-O3BUXIPM.js → chunk-WXEA74YB.js} +3 -3
  181. package/chunks/{chunk-YRLW2MSX.js → chunk-XBVNNDPK.js} +11 -4
  182. package/chunks/{chunk-VL4YX3FH.js → chunk-XF63PKEN.js} +1 -1
  183. package/chunks/{chunk-R7G7GKOX.js → chunk-XHF7WQ6B.js} +3 -3
  184. package/chunks/{chunk-3FSBMAYD.js → chunk-XQFT3QUF.js} +1 -1
  185. package/chunks/{chunk-3D6PDLNJ.js → chunk-XSG6G3G6.js} +49 -32
  186. package/chunks/{chunk-5JCZ3UKB.js → chunk-Y5S7LBOZ.js} +44 -7
  187. package/chunks/{chunk-OLS3MAXQ.js → chunk-YLSQLSH7.js} +15 -9
  188. package/chunks/{chunk-2SERYG4T.js → chunk-YTDVNSUQ.js} +1 -1
  189. package/chunks/{chunk-KPF2K55D.js → chunk-ZEYFMJQA.js} +39 -8
  190. package/chunks/{chunk-OT4YKUUV.js → chunk-ZU4UDIWX.js} +2 -2
  191. package/chunks/chunk-ZWJDJ6RU.js +2597 -0
  192. package/chunks/{chunk-R3T33BG5.js → chunk-ZYMLPEZQ.js} +3 -3
  193. package/chunks/{chunk-DID6IRGC.js → chunk-ZZMSC3RG.js} +56 -39
  194. package/chunks/{chunk-L436XFLJ.js → chunk-ZZUKP7HV.js} +1 -1
  195. package/chunks/config-utils-R6M3TA34.js +113 -0
  196. package/chunks/contextCommand-ZCAP23J6.js +106 -0
  197. package/chunks/{core-runtime-CEJRHCRF.js → core-runtime-AXB6SK5D.js} +59 -61
  198. package/chunks/{create-sub-session-RVHSWVAP.js → create-sub-session-23ITIELI.js} +3 -3
  199. package/chunks/{create-sub-session-DFZVIG56.js → create-sub-session-4QNE64MR.js} +164 -85
  200. package/chunks/{cron-create-IJGVR5R2.js → cron-create-KJ4IY6PP.js} +57 -10
  201. package/chunks/{cron-delete-4N5BI6GL.js → cron-delete-MBLQCAYY.js} +4 -4
  202. package/chunks/{cron-list-2CATIPUX.js → cron-list-DWH2PQ47.js} +4 -4
  203. package/chunks/{daemon-NAYK4XXU.js → daemon-3GNHB3M2.js} +523 -8
  204. package/chunks/{daemon-git-worktree-guard-L6ZUFKF7.js → daemon-git-worktree-guard-IVAJJWYK.js} +56 -58
  205. package/chunks/daemon-status-provider-K3SJ5C2U.js +117 -0
  206. package/chunks/daemon-trust-policy-DOR3YG62.js +112 -0
  207. package/chunks/{daemon-trust-policy-monitor-2G3EKQEU.js → daemon-trust-policy-monitor-KGGROSIV.js} +64 -66
  208. package/chunks/deferred-core-runtime-WOYLUQQ7.js +114 -0
  209. package/chunks/{display-image-6KHQNEAE.js → display-image-BE7I6ZB6.js} +5 -5
  210. package/chunks/{dist-DJBNNPLN.js → dist-4WXLCBDR.js} +1 -1
  211. package/chunks/{dist-TJUDJTCB.js → dist-5VXFRTWU.js} +280 -48
  212. package/chunks/{dist-6H6RZ5H6.js → dist-6BPYWHVD.js} +89 -65
  213. package/chunks/{dist-ZBVOXSKF.js → dist-GFN5DCBX.js} +74 -65
  214. package/chunks/{dist-SATKXKUR.js → dist-HZNT6GQS.js} +1 -1
  215. package/chunks/{dist-FVJZSIO4.js → dist-LVZCXVPF.js} +72 -20
  216. package/chunks/{dist-7CKN54NL.js → dist-N6W6E753.js} +71 -64
  217. package/chunks/{dist-4Q7NTUNB.js → dist-NSV4NBPK.js} +31 -14
  218. package/chunks/{dist-UQUFZDIY.js → dist-SWQMYP2Q.js} +18 -16
  219. package/chunks/earlyInputCapture-OHBEVO4K.js +107 -0
  220. package/chunks/{edit-ZERGX3RV.js → edit-LEQLAGPZ.js} +45 -47
  221. package/chunks/{en-6MDBWMTG.js → en-YLXBXM4Z.js} +2 -1
  222. package/chunks/{enter-worktree-UOZ6ZTP7.js → enter-worktree-35QCAAFP.js} +7 -7
  223. package/chunks/{enterPlanMode-W2RP3P5B.js → enterPlanMode-ONQN3WHE.js} +47 -49
  224. package/chunks/{environment-ZBJ23YVR.js → environment-UANTR7A4.js} +60 -62
  225. package/chunks/errors-WAK6KFBC.js +113 -0
  226. package/chunks/{exit-worktree-G2QATUCV.js → exit-worktree-XQD6D543.js} +7 -7
  227. package/chunks/exitPlanMode-UEYBG6P5.js +83 -0
  228. package/chunks/{fast-path-4MWBCEUF.js → fast-path-WUL7UZ6H.js} +7 -7
  229. package/chunks/{fast-path-settings-XMFBYFUH.js → fast-path-settings-XH426LUU.js} +3 -3
  230. package/chunks/{glob-DKTNG32L.js → glob-Y54QUWDY.js} +44 -46
  231. package/chunks/{goal-tools-CNVXMSZD.js → goal-tools-PTD3MBA7.js} +10 -8
  232. package/chunks/{grep-3NLSS32D.js → grep-5GPICQBU.js} +6 -6
  233. package/chunks/handleAutoUpdate-FP3NWNSG.js +109 -0
  234. package/chunks/i18n-INIU5X7A.js +124 -0
  235. package/chunks/{image-gen-63NN2H5N.js → image-gen-J6FDGUZP.js} +8 -10
  236. package/chunks/initializer-TYODV6GE.js +113 -0
  237. package/chunks/installationInfo-AAPKYDSZ.js +107 -0
  238. package/chunks/{keychain-token-storage-3MGFRYGM.js → keychain-token-storage-37XPR34V.js} +2 -2
  239. package/chunks/list-TUODDN6J.js +116 -0
  240. package/chunks/{list-agents-EXRSHIDJ.js → list-agents-DI3YFTDT.js} +2 -2
  241. package/chunks/{gemini-X5GQHQYF.js → llm-NSAVK5V3.js} +117 -114
  242. package/chunks/{geminiContentGenerator-UDSWXZXL.js → llm-content-generator-AY2QKXHE.js} +29 -29
  243. package/chunks/loadedSettingsAdapter-KJCLZ3C4.js +110 -0
  244. package/chunks/{loggingContentGenerator-73C7TKDK.js → loggingContentGenerator-DSFQHXIF.js} +328 -37
  245. package/chunks/{loop-wakeup-XBPB2BRO.js → loop-wakeup-XJFONSQ7.js} +5 -5
  246. package/chunks/{ls-WFONAND2.js → ls-3VAT2J7A.js} +4 -4
  247. package/chunks/{lsp-DUKPDUXN.js → lsp-5W7IRUBH.js} +2 -2
  248. package/chunks/{managed-npm-update-H2KOLQZU.js → managed-npm-update-TSWENTK5.js} +57 -59
  249. package/chunks/mcp-MWSAPFOL.js +110 -0
  250. package/chunks/{monitor-TGCMNJJH.js → monitor-RW4GWJHB.js} +44 -46
  251. package/chunks/nonInteractiveCli-JXKL343Q.js +185 -0
  252. package/chunks/{notebook-edit-YEUNZYDX.js → notebook-edit-CQNYS5OR.js} +45 -47
  253. package/chunks/{open-with-auth-4UI3KHUR.js → open-with-auth-YN3QZHVM.js} +1 -1
  254. package/chunks/{openaiContentGenerator-J7LD4VSL.js → openaiContentGenerator-J6QIF7EX.js} +26 -28
  255. package/chunks/pidfile-QOIQZFT2.js +111 -0
  256. package/chunks/process-registry-OAEG6WGC.js +662 -0
  257. package/chunks/{processUtils-ZHFC7CSL.js → processUtils-GPHNANKZ.js} +2 -2
  258. package/chunks/prompt-terminal-ledger-FOMFTYOM.js +105 -0
  259. package/chunks/{qwenContentGenerator-YEWWK3JQ.js → qwenContentGenerator-WWDXPYQI.js} +49 -51
  260. package/chunks/{qwenOAuth2-JIYAWXTW.js → qwenOAuth2-OF5WRBQT.js} +7 -9
  261. package/chunks/{read-file-ZQI3WPVK.js → read-file-FQUQHC6N.js} +13 -13
  262. package/chunks/{read-mcp-resource-7A7NFSFL.js → read-mcp-resource-XD257PGJ.js} +2 -2
  263. package/chunks/{record-artifact-CPJ4IJSD.js → record-artifact-VW23GS4F.js} +4 -4
  264. package/chunks/{report-findings-VFM5DENC.js → report-findings-AO5VYFLR.js} +9 -5
  265. package/chunks/{request-shutdown-6IW46GD7.js → request-shutdown-BCLA3JV2.js} +7 -7
  266. package/chunks/resumeHistoryUtils-NSGF3UCB.js +118 -0
  267. package/chunks/ripGrep-4CAT6SKV.js +39 -0
  268. package/chunks/{run-qwen-serve-WHWU7NZ6.js → run-qwen-serve-5X6IDZER.js} +371 -357
  269. package/chunks/{runtime-E7BSPWQP.js → runtime-HK27GMPF.js} +69 -71
  270. package/chunks/scheduled-tasks-MN2ZZ5P6.js +127 -0
  271. package/chunks/{scheduler-TJPATFOM.js → scheduler-WD4MHMO5.js} +58 -60
  272. package/chunks/{sdk-exporters-http-XXSKBD2C.js → sdk-exporters-http-TTU2CHBU.js} +2 -2
  273. package/chunks/{sdk-impl-VPNBLV7I.js → sdk-impl-UUMVYMAL.js} +11 -5
  274. package/chunks/{send-message-OXZK6USO.js → send-message-AJ4OCUBV.js} +25 -9
  275. package/chunks/serve-2XCHPPGG.js +118 -0
  276. package/chunks/{server-AXCN7QBJ.js → server-GO2N5DH7.js} +6080 -4964
  277. package/chunks/{session-HO4US3AG.js → session-IFNHTUBT.js} +112 -112
  278. package/chunks/session-pr-refresh-I3UBWMVP.js +364 -0
  279. package/chunks/{settings-B2PFJJN4.js → settings-L6N54CU6.js} +63 -65
  280. package/chunks/{shell-7XMSANI3.js → shell-4Y5LLW6N.js} +44 -46
  281. package/chunks/{skill-NL3VH562.js → skill-YOWTRAKQ.js} +68 -24
  282. package/chunks/skill-settings-ZL4JY5UE.js +118 -0
  283. package/chunks/spawnChannel-ZST6XJVJ.js +112 -0
  284. package/chunks/standalone-update-THVU3OKY.js +118 -0
  285. package/chunks/{startInteractiveUI-G2XKSCQ7.js → startInteractiveUI-XDFSHBZD.js} +3076 -2475
  286. package/chunks/{stdioHelpers-7A2EE64Z.js → stdioHelpers-AY6XCDY2.js} +3 -1
  287. package/chunks/{syntheticOutput-5AJ444QT.js → syntheticOutput-ML43GEFN.js} +3 -3
  288. package/chunks/{task-create-TY7P6UHG.js → task-create-QN4LYRSE.js} +11 -11
  289. package/chunks/{task-list-BELMPA75.js → task-list-JPLGK45U.js} +5 -5
  290. package/chunks/{task-stop-U3S3KZG2.js → task-stop-CXEH5L2D.js} +2 -2
  291. package/chunks/{task-update-O4IGDPCK.js → task-update-IWEOJFV2.js} +11 -11
  292. package/chunks/{team-create-IYBUOORE.js → team-create-OOPXCDBA.js} +44 -46
  293. package/chunks/{team-delete-YWFXX77L.js → team-delete-RZVVSGCY.js} +5 -5
  294. package/chunks/{team-plan-approval-YKU57LBM.js → team-plan-approval-DSX5EWAT.js} +44 -46
  295. package/chunks/terminal-image-renderer-KS25G33E.js +114 -0
  296. package/chunks/theme-manager-YMZNG45F.js +102 -0
  297. package/chunks/{todoWrite-435EO2CS.js → todoWrite-WDJNQEMW.js} +43 -25
  298. package/chunks/{tool-search-4Q3KASIQ.js → tool-search-J5Q6U7DN.js} +22 -22
  299. package/chunks/total-session-admission-PVN64JVV.js +114 -0
  300. package/chunks/trustedFolders-FATSC4YI.js +122 -0
  301. package/chunks/{types-WYCFCEHR.js → types-HKLPXZB3.js} +1 -3
  302. package/chunks/{update-relaunch-4DC2KKFS.js → update-relaunch-SIKHLHVR.js} +6 -6
  303. package/chunks/updateCheck-D3YG2WCD.js +118 -0
  304. package/chunks/useAutoAcceptIndicator-ILINOSAS.js +120 -0
  305. package/chunks/{validateNonInterActiveAuth-YAE4YPO3.js → validateNonInterActiveAuth-JUDQP6V4.js} +105 -105
  306. package/chunks/{version-QFP7OGWX.js → version-C63GDDWN.js} +1 -1
  307. package/chunks/{web-fetch-6T23IK6Q.js → web-fetch-FOQZMNSC.js} +16 -18
  308. package/chunks/{web-search-WBWTCZK2.js → web-search-PUJTBFUC.js} +9 -11
  309. package/chunks/{web-shell-static-A6QMUNNV.js → web-shell-static-HNB4FDOE.js} +2 -2
  310. package/chunks/{workflow-FMAA3D4R.js → workflow-Y5IPINVH.js} +128 -94
  311. package/chunks/workspace-providers-status-IJ4VHFMB.js +114 -0
  312. package/chunks/{workspace-registration-store-CMMX7EPX.js → workspace-registration-store-SMJWI2AI.js} +1 -1
  313. package/chunks/workspace-registry-BTGZIMPK.js +123 -0
  314. package/chunks/workspace-service-SIN67ITC.js +126 -0
  315. package/chunks/workspace-skills-status-F3RKCUIX.js +113 -0
  316. package/chunks/{workspace-trust-reconciler-PJDQUTJL.js → workspace-trust-reconciler-PLIDLJZX.js} +72 -72
  317. package/chunks/write-file-PAIGB33C.js +88 -0
  318. package/chunks/{zh-TW-MV4FWFB6.js → zh-TW-RPTMRTHG.js} +2 -1
  319. package/chunks/{zh-X3WGU6SI.js → zh-UNY63FR3.js} +2 -1
  320. package/chunks/{zoom-image-WVYVFRXF.js → zoom-image-LYQD7BQA.js} +13 -13
  321. package/cli.js +16 -16
  322. package/locales/en.js +2 -0
  323. package/locales/zh-TW.js +2 -0
  324. package/locales/zh.js +2 -0
  325. package/package.json +3 -3
  326. package/web-shell/assets/{abnfDiagram-VCTEODGH-d-8xa8uz.js → abnfDiagram-VCTEODGH-TRCMSA_6.js} +1 -1
  327. package/web-shell/assets/{arc-BhB7CrGK.js → arc-D9Uls5b3.js} +1 -1
  328. package/web-shell/assets/{architectureDiagram-5GKGNRK7-BDCd_IcJ.js → architectureDiagram-5GKGNRK7-Bwb8jPXg.js} +1 -1
  329. package/web-shell/assets/{blockDiagram-NRAW4CY4-C-AHu6mi.js → blockDiagram-NRAW4CY4-DHj71TSX.js} +1 -1
  330. package/web-shell/assets/{c4Diagram-UCG6FXSJ-CFjQt0vl.js → c4Diagram-UCG6FXSJ-uKBBdbyr.js} +1 -1
  331. package/web-shell/assets/channel-CXjVLaBa.js +1 -0
  332. package/web-shell/assets/{chunk-2Q5K7J3B-DRjwqaDq.js → chunk-2Q5K7J3B-BZd0Phrl.js} +1 -1
  333. package/web-shell/assets/{chunk-5VM5RSS4-eHM9noJE.js → chunk-5VM5RSS4-7KNeNBqN.js} +1 -1
  334. package/web-shell/assets/{chunk-F27PBJKO-CcSWUYn1.js → chunk-F27PBJKO-BeboS7Fi.js} +1 -1
  335. package/web-shell/assets/{chunk-G27WJ6UU-DNr-RF5S.js → chunk-G27WJ6UU-RV3JONoj.js} +1 -1
  336. package/web-shell/assets/{chunk-JWPE2WC7-rVJHoNF8.js → chunk-JWPE2WC7-Yw9FCFsP.js} +1 -1
  337. package/web-shell/assets/{chunk-LCL6LL3I-B2aX0Gzy.js → chunk-LCL6LL3I-GIMnydDe.js} +1 -1
  338. package/web-shell/assets/{chunk-POPQ4Y6H-DVp07n32.js → chunk-POPQ4Y6H-Cfrux7bL.js} +1 -1
  339. package/web-shell/assets/{chunk-SVP7TREG-C6QB_KUr.js → chunk-SVP7TREG-BlvIN0CO.js} +1 -1
  340. package/web-shell/assets/{chunk-XXDRQBXY-CLVxDNCy.js → chunk-XXDRQBXY-DMs7Rr4t.js} +1 -1
  341. package/web-shell/assets/classDiagram-DTDB5LWJ-DANEijO3.js +1 -0
  342. package/web-shell/assets/classDiagram-v2-JRS7N3AN-DANEijO3.js +1 -0
  343. package/web-shell/assets/{cose-bilkent-JH36ORCC-B_aKX3A3.js → cose-bilkent-JH36ORCC-DNGqTNwI.js} +1 -1
  344. package/web-shell/assets/{cynefin-OW5HDTMX-BBw2pPUa.js → cynefin-OW5HDTMX-CojMpaoH.js} +1 -1
  345. package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-WWPiBTwk.js → cynefinDiagram-5FMLGOSQ-DF07YXGo.js} +1 -1
  346. package/web-shell/assets/{dagre-3AP2YEHR-CPtIdka-.js → dagre-3AP2YEHR-17-4WtCH.js} +1 -1
  347. package/web-shell/assets/{diagram-S7CK7UJ4-Dj5og1Xi.js → diagram-S7CK7UJ4-G3Wuyz9m.js} +1 -1
  348. package/web-shell/assets/{diagram-UQ7AKVKN-CC_x70YC.js → diagram-UQ7AKVKN-nyWIKZ8P.js} +1 -1
  349. package/web-shell/assets/{diagram-VSXAHHWV-rXMfsO4n.js → diagram-VSXAHHWV-tKHhmYSC.js} +1 -1
  350. package/web-shell/assets/{diagram-VX7I27RA-DEmLYQbh.js → diagram-VX7I27RA-CpDf1hYk.js} +1 -1
  351. package/web-shell/assets/{diagram-Z3DM3KII-B0ys6Vxx.js → diagram-Z3DM3KII-Cah2IFXG.js} +1 -1
  352. package/web-shell/assets/{ebnfDiagram-PWID7BFC-Bq6y6lKH.js → ebnfDiagram-PWID7BFC-DNaCkgxy.js} +1 -1
  353. package/web-shell/assets/{erDiagram-SSCWMZ5O-l69JeBZ4.js → erDiagram-SSCWMZ5O-CAdRgcf1.js} +1 -1
  354. package/web-shell/assets/{flowDiagram-A5DVABFB-Cm-EzGY4.js → flowDiagram-A5DVABFB-CMUJAShL.js} +1 -1
  355. package/web-shell/assets/{ganttDiagram-EL5Y4UJY-BRS9ZOp7.js → ganttDiagram-EL5Y4UJY-o-_MUNey.js} +1 -1
  356. package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-DAMRKgLk.js → gitGraphDiagram-WWUBYQGX-_aG-2Z7O.js} +1 -1
  357. package/web-shell/assets/{index-Bncx8E8M.js → index-BK_NKxiJ.js} +1 -1
  358. package/web-shell/assets/index-Ci-z4zWY.js +1913 -0
  359. package/web-shell/assets/index-LDlXZRHA.css +36 -0
  360. package/web-shell/assets/{infoDiagram-RXCK75RN-DasffaZp.js → infoDiagram-RXCK75RN-qJPeZbGP.js} +1 -1
  361. package/web-shell/assets/{ishikawaDiagram-5VMMS53U-CmRUt3C-.js → ishikawaDiagram-5VMMS53U-7Om4vNo1.js} +1 -1
  362. package/web-shell/assets/{journeyDiagram-EYS64GPL-DzhE_c1Z.js → journeyDiagram-EYS64GPL-BNtXqmBW.js} +1 -1
  363. package/web-shell/assets/{kanban-definition-3QL26DDD-BH5b6nn3.js → kanban-definition-3QL26DDD-COgFec8P.js} +1 -1
  364. package/web-shell/assets/{layout-BxoLK-LY.js → layout-B9n81PC9.js} +1 -1
  365. package/web-shell/assets/{linear-CqDPvVI7.js → linear-Bb6nXZQq.js} +1 -1
  366. package/web-shell/assets/{mermaid.core-DBoN4plo.js → mermaid.core-Cgrm3JVT.js} +6 -6
  367. package/web-shell/assets/{mindmap-definition-FBJOCRG2-DJJtXPEM.js → mindmap-definition-FBJOCRG2-TKwLTjnG.js} +1 -1
  368. package/web-shell/assets/{pegDiagram-XKGWAZYB-DmgPXP5l.js → pegDiagram-XKGWAZYB-BJPuvlpi.js} +1 -1
  369. package/web-shell/assets/{pieDiagram-E7YTZNPT-1ezjzcI5.js → pieDiagram-E7YTZNPT-D01VkNsW.js} +1 -1
  370. package/web-shell/assets/{quadrantDiagram-AXDQQJYC-ChKARz3k.js → quadrantDiagram-AXDQQJYC-C4hHsiv-.js} +1 -1
  371. package/web-shell/assets/{railroadDiagram-O6MQD6OU-k7mNB_QT.js → railroadDiagram-O6MQD6OU-CuEO4xK2.js} +1 -1
  372. package/web-shell/assets/{requirementDiagram-EFPCY7ZU-B0XFsii0.js → requirementDiagram-EFPCY7ZU-D5J_vIo5.js} +1 -1
  373. package/web-shell/assets/{sankeyDiagram-P5KCCOFB-repJ2Ukk.js → sankeyDiagram-P5KCCOFB-DQKY223V.js} +1 -1
  374. package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-D0gUSKGu.js → sequenceDiagram-WJ2MYXX4-D27YV_cm.js} +1 -1
  375. package/web-shell/assets/{sizeCapture-X5ZJPWSS-CE463F74.js → sizeCapture-X5ZJPWSS-TJg8UcwV.js} +1 -1
  376. package/web-shell/assets/{stateDiagram-HBIQ2CUA-003zYtJa.js → stateDiagram-HBIQ2CUA-CmnPzUIx.js} +1 -1
  377. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-DNKPyrDc.js +1 -0
  378. package/web-shell/assets/{swimlanes-XN3QIQJK-DBj8MFpu.js → swimlanes-XN3QIQJK-ByeP3_Nu.js} +1 -1
  379. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-ZL1HPC6w.js +8 -0
  380. package/web-shell/assets/{timeline-definition-24CTP7MA-D2aCh4a9.js → timeline-definition-24CTP7MA-BsFA5juR.js} +1 -1
  381. package/web-shell/assets/{vennDiagram-4TSXK5OY-BHMfWBpl.js → vennDiagram-4TSXK5OY-DREP2ECo.js} +1 -1
  382. package/web-shell/assets/{wardleyDiagram-VM6X3IG4-RdHAj66j.js → wardleyDiagram-VM6X3IG4-iyd9lKi2.js} +1 -1
  383. package/web-shell/assets/{xychartDiagram-S5SC5T6Z-BgJWOvq0.js → xychartDiagram-S5SC5T6Z-CVr1_j9q.js} +1 -1
  384. package/web-shell/index.html +3 -3
  385. package/chunks/MaxSizedBox-BFVLZP2E.js +0 -112
  386. package/chunks/agent-headless-UCBCS4V4.js +0 -87
  387. package/chunks/bridge-FRNYLYY7.js +0 -119
  388. package/chunks/channel-settings-store-IV4KDL7N.js +0 -117
  389. package/chunks/chunk-I6VVOZDK.js +0 -202
  390. package/chunks/chunk-JS73NNWF.js +0 -30
  391. package/chunks/chunk-K2OJUPOE.js +0 -78
  392. package/chunks/chunk-P3QQPMQA.js +0 -19
  393. package/chunks/chunk-SDVF6A42.js +0 -945
  394. package/chunks/chunk-VGHZT6JR.js +0 -51
  395. package/chunks/config-utils-PMX4QZ5Y.js +0 -113
  396. package/chunks/contextCommand-NZRLVAFC.js +0 -108
  397. package/chunks/daemon-status-provider-FTTYZEKN.js +0 -118
  398. package/chunks/daemon-trust-policy-WMGFPA3Z.js +0 -114
  399. package/chunks/deferred-core-runtime-BUFEFYNA.js +0 -116
  400. package/chunks/earlyInputCapture-ROPLMXA7.js +0 -109
  401. package/chunks/errors-U5KNAADB.js +0 -115
  402. package/chunks/exitPlanMode-VFJ5R5DD.js +0 -85
  403. package/chunks/handleAutoUpdate-W4BUYFT7.js +0 -111
  404. package/chunks/i18n-KX7FEKJJ.js +0 -126
  405. package/chunks/initializer-SNVVLS7Y.js +0 -115
  406. package/chunks/installationInfo-D4XGQNHJ.js +0 -109
  407. package/chunks/list-WYECMLXZ.js +0 -118
  408. package/chunks/loadedSettingsAdapter-5WZBXBCR.js +0 -112
  409. package/chunks/mcp-CBWAROY3.js +0 -112
  410. package/chunks/nonInteractiveCli-O232UUV7.js +0 -185
  411. package/chunks/pidfile-MSPQ255Y.js +0 -113
  412. package/chunks/process-registry-PMJOA5CO.js +0 -172
  413. package/chunks/prompt-terminal-ledger-YPGMNDXT.js +0 -107
  414. package/chunks/resumeHistoryUtils-35D4KAVT.js +0 -120
  415. package/chunks/ripGrep-46N4FLOS.js +0 -39
  416. package/chunks/serve-WQ54UIYG.js +0 -120
  417. package/chunks/skill-settings-SKMN5YXC.js +0 -120
  418. package/chunks/spawnChannel-NE43EEO3.js +0 -113
  419. package/chunks/standalone-update-XOCWGXAH.js +0 -120
  420. package/chunks/terminal-image-renderer-NREKYTAD.js +0 -116
  421. package/chunks/theme-manager-IJS6OICX.js +0 -104
  422. package/chunks/total-session-admission-L5RPEFZ2.js +0 -114
  423. package/chunks/trustedFolders-OILZCHRD.js +0 -124
  424. package/chunks/updateCheck-AK4COHNK.js +0 -120
  425. package/chunks/useAutoAcceptIndicator-O2N2Q6KG.js +0 -122
  426. package/chunks/workspace-providers-status-OCFEWIPQ.js +0 -116
  427. package/chunks/workspace-registry-WJLZPRTG.js +0 -123
  428. package/chunks/workspace-service-5ZOBMMIB.js +0 -131
  429. package/chunks/workspace-skills-status-B6NJZD4B.js +0 -115
  430. package/chunks/write-file-B2RNX6SU.js +0 -90
  431. package/web-shell/assets/channel-CU-Zyv0r.js +0 -1
  432. package/web-shell/assets/classDiagram-DTDB5LWJ-C0J2_LKs.js +0 -1
  433. package/web-shell/assets/classDiagram-v2-JRS7N3AN-C0J2_LKs.js +0 -1
  434. package/web-shell/assets/index-C-XlQn24.css +0 -5
  435. package/web-shell/assets/index-gdvMN4J1.js +0 -1860
  436. package/web-shell/assets/stateDiagram-v2-4QOOHH4V-2uACDdJN.js +0 -1
  437. package/web-shell/assets/swimlanesDiagram-VK2B7HYN-C4JJkavU.js +0 -8
@@ -0,0 +1,2597 @@
1
+ // Force strict mode and setup for ESM
2
+ "use strict";
3
+ import {
4
+ classifyTopLevelConversationSource
5
+ } from "./chunk-36LGBEM6.js";
6
+ import {
7
+ A1_MIN_VERSION,
8
+ a1VersionAtLeast,
9
+ isAoneCanonicalHost,
10
+ parseA1Version,
11
+ parseRemoteUrl
12
+ } from "./chunk-4VQBQLIZ.js";
13
+ import {
14
+ safeLogValue
15
+ } from "./chunk-SEONHUS3.js";
16
+ import {
17
+ normalizeSessionIdForLookup,
18
+ parseCallerSuppliedSessionId
19
+ } from "./chunk-ZEZKIS2K.js";
20
+ import {
21
+ SessionArchivedError,
22
+ SessionArchivingError,
23
+ SessionConflictError,
24
+ SessionNotArchivedError,
25
+ SessionNotFoundError
26
+ } from "./chunk-ERFDKH32.js";
27
+ import {
28
+ gitEnv
29
+ } from "./chunk-NV55WWD6.js";
30
+ import {
31
+ readWorktreeSession
32
+ } from "./chunk-62GQFYID.js";
33
+ import {
34
+ SESSION_PR_URL_MAX_LENGTH,
35
+ SessionIdCaseConflictError,
36
+ SessionOrganizationError,
37
+ SessionOrganizationService,
38
+ SessionService,
39
+ SessionTranscriptChangedError,
40
+ SessionWriterUnavailableError,
41
+ canonicalSessionPrUrl,
42
+ readSessionPrs
43
+ } from "./chunk-PZ66FRIC.js";
44
+ import {
45
+ updateCronTasks
46
+ } from "./chunk-D5LUXLUH.js";
47
+ import {
48
+ findGitRoot
49
+ } from "./chunk-SMPR7SPO.js";
50
+ import {
51
+ addDaemonRequestAttribute
52
+ } from "./chunk-3WK3QDNV.js";
53
+ import {
54
+ Storage
55
+ } from "./chunk-UHQFIS7N.js";
56
+ import {
57
+ writeStderrLine
58
+ } from "./chunk-7FA2II6K.js";
59
+ import {
60
+ init_esbuild_shims
61
+ } from "./chunk-5O2XNYP6.js";
62
+ import {
63
+ __name
64
+ } from "./chunk-J2S4EL5Y.js";
65
+
66
+ // packages/cli/src/serve/server/session-list.ts
67
+ init_esbuild_shims();
68
+
69
+ // packages/cli/src/serve/session-organization-helpers.ts
70
+ init_esbuild_shims();
71
+ function createSessionOrganizationService(workspaceCwd) {
72
+ return new SessionOrganizationService(workspaceCwd, (message) => {
73
+ writeStderrLine(`qwen serve: session-org: ${message}`);
74
+ });
75
+ }
76
+ __name(createSessionOrganizationService, "createSessionOrganizationService");
77
+
78
+ // packages/cli/src/serve/server/persisted-session-list-cache.ts
79
+ init_esbuild_shims();
80
+ import path from "node:path";
81
+ var PersistedSessionListCache = class {
82
+ constructor(ttlMs, maxRetainedSummaries) {
83
+ this.ttlMs = ttlMs;
84
+ this.maxRetainedSummaries = maxRetainedSummaries;
85
+ }
86
+ static {
87
+ __name(this, "PersistedSessionListCache");
88
+ }
89
+ slots = /* @__PURE__ */ new Map();
90
+ retainedSummaries = 0;
91
+ lookup(scope, loader, options = {}) {
92
+ options.signal?.throwIfAborted();
93
+ const key = this.key(scope);
94
+ let slot = this.slots.get(key);
95
+ if (!slot) {
96
+ slot = { generation: 0 };
97
+ this.slots.set(key, slot);
98
+ }
99
+ const now = Date.now();
100
+ if (slot.value) {
101
+ const cacheAgeMs = Math.max(0, now - slot.value.completedAt);
102
+ if (cacheAgeMs < this.ttlMs) {
103
+ const snapshot = slot.value.snapshot;
104
+ return {
105
+ status: "cache_hit",
106
+ promise: Promise.resolve().then(() => {
107
+ options.signal?.throwIfAborted();
108
+ return snapshot;
109
+ }),
110
+ cacheAgeMs
111
+ };
112
+ }
113
+ this.removeValue(slot);
114
+ }
115
+ if (slot.inFlight !== void 0 && slot.inFlight.generation === slot.generation && !slot.inFlight.controller.signal.aborted) {
116
+ return {
117
+ status: "single_flight",
118
+ promise: this.attachWaiter(key, slot, slot.inFlight, options.signal)
119
+ };
120
+ }
121
+ const generation = slot.generation;
122
+ const controller = new AbortController();
123
+ const load = {
124
+ generation,
125
+ controller,
126
+ promise: void 0,
127
+ waiterCount: 0,
128
+ settled: false
129
+ };
130
+ const managed = Promise.resolve().then(() => {
131
+ controller.signal.throwIfAborted();
132
+ return loader(controller.signal);
133
+ }).then(
134
+ (snapshot) => {
135
+ load.settled = true;
136
+ const current = this.slots.get(key);
137
+ if (current === slot && current.inFlight === load) {
138
+ current.inFlight = void 0;
139
+ if (current.generation === generation && !controller.signal.aborted && snapshot.sessions.length <= this.maxRetainedSummaries) {
140
+ this.installValue(key, current, snapshot);
141
+ } else if (current.value === void 0) {
142
+ this.slots.delete(key);
143
+ }
144
+ }
145
+ return snapshot;
146
+ },
147
+ (error) => {
148
+ load.settled = true;
149
+ const current = this.slots.get(key);
150
+ if (current === slot && current.inFlight === load) {
151
+ current.inFlight = void 0;
152
+ if (current.value === void 0) this.slots.delete(key);
153
+ }
154
+ throw error;
155
+ }
156
+ );
157
+ load.promise = managed;
158
+ slot.inFlight = load;
159
+ return {
160
+ status: "scan",
161
+ promise: this.attachWaiter(key, slot, load, options.signal)
162
+ };
163
+ }
164
+ invalidate(scope) {
165
+ const key = this.key(scope);
166
+ const slot = this.slots.get(key);
167
+ if (!slot) return;
168
+ slot.generation += 1;
169
+ this.removeValue(slot);
170
+ if (slot.inFlight === void 0) this.slots.delete(key);
171
+ }
172
+ clear() {
173
+ for (const slot of this.slots.values()) {
174
+ if (slot.value) clearTimeout(slot.value.expiryTimer);
175
+ }
176
+ this.slots.clear();
177
+ this.retainedSummaries = 0;
178
+ }
179
+ installValue(key, slot, snapshot) {
180
+ const completedAt = Date.now();
181
+ this.evictFor(snapshot.sessions.length);
182
+ const remainingTtlMs = Math.max(0, this.ttlMs - (Date.now() - completedAt));
183
+ const expiryTimer = setTimeout(() => {
184
+ const current = this.slots.get(key);
185
+ if (current !== slot || current.value?.expiryTimer !== expiryTimer) {
186
+ return;
187
+ }
188
+ this.removeValue(current);
189
+ if (current.inFlight === void 0) this.slots.delete(key);
190
+ }, remainingTtlMs);
191
+ if (typeof expiryTimer.unref === "function") expiryTimer.unref();
192
+ const value = { snapshot, completedAt, expiryTimer };
193
+ slot.value = value;
194
+ this.retainedSummaries += snapshot.sessions.length;
195
+ }
196
+ evictFor(incomingSummaries) {
197
+ while (this.retainedSummaries + incomingSummaries > this.maxRetainedSummaries) {
198
+ let oldest;
199
+ for (const [key, slot] of this.slots) {
200
+ if (slot.value && (oldest === void 0 || slot.value.completedAt < oldest.completedAt)) {
201
+ oldest = { key, slot, completedAt: slot.value.completedAt };
202
+ }
203
+ }
204
+ if (!oldest) return;
205
+ this.removeValue(oldest.slot);
206
+ if (oldest.slot.inFlight === void 0) this.slots.delete(oldest.key);
207
+ }
208
+ }
209
+ removeValue(slot) {
210
+ const value = slot.value;
211
+ if (!value) return;
212
+ clearTimeout(value.expiryTimer);
213
+ this.retainedSummaries -= value.snapshot.sessions.length;
214
+ slot.value = void 0;
215
+ }
216
+ attachWaiter(key, slot, load, signal) {
217
+ load.waiterCount += 1;
218
+ return new Promise((resolve, reject) => {
219
+ let settled = false;
220
+ const settle = /* @__PURE__ */ __name((finish) => {
221
+ if (settled) return;
222
+ settled = true;
223
+ signal?.removeEventListener("abort", onAbort);
224
+ load.waiterCount -= 1;
225
+ if (load.waiterCount === 0 && !load.settled) {
226
+ load.controller.abort(
227
+ new DOMException("No active session list waiters", "AbortError")
228
+ );
229
+ const current = this.slots.get(key);
230
+ if (current === slot && current.inFlight === load) {
231
+ current.inFlight = void 0;
232
+ if (current.value === void 0) this.slots.delete(key);
233
+ }
234
+ }
235
+ finish();
236
+ }, "settle");
237
+ const onAbort = /* @__PURE__ */ __name(() => {
238
+ if (load.settled) return;
239
+ settle(() => reject(signal?.reason));
240
+ }, "onAbort");
241
+ signal?.addEventListener("abort", onAbort, { once: true });
242
+ if (signal?.aborted) onAbort();
243
+ void load.promise.then(
244
+ (snapshot) => settle(() => resolve(snapshot)),
245
+ (error) => settle(() => reject(error))
246
+ );
247
+ });
248
+ }
249
+ key(scope) {
250
+ return JSON.stringify([
251
+ path.resolve(scope.runtimeBaseDir),
252
+ scope.workspaceCwd,
253
+ scope.archiveState
254
+ ]);
255
+ }
256
+ };
257
+
258
+ // packages/cli/src/serve/server/activity-timestamp.ts
259
+ init_esbuild_shims();
260
+ function laterActivityTimestamp(live, persisted) {
261
+ const liveTime = live === void 0 ? Number.NaN : Date.parse(live);
262
+ const persistedTime = persisted === void 0 ? Number.NaN : Date.parse(persisted);
263
+ const liveValid = Number.isFinite(liveTime);
264
+ const persistedValid = Number.isFinite(persistedTime);
265
+ if (liveValid && persistedValid) {
266
+ return liveTime >= persistedTime ? live : persisted;
267
+ }
268
+ if (liveValid) return live;
269
+ if (persistedValid) return persisted;
270
+ return live ?? persisted;
271
+ }
272
+ __name(laterActivityTimestamp, "laterActivityTimestamp");
273
+
274
+ // packages/cli/src/serve/server/session-list.ts
275
+ var DEFAULT_SESSION_PAGE_SIZE = 20;
276
+ var MAX_SESSION_PAGE_SIZE = 100;
277
+ var MAX_ORGANIZED_SESSIONS = 5e4;
278
+ var MAX_EMITTED_CURSOR_SESSION_IDS = 64;
279
+ var PERSISTED_SESSION_LIST_CACHE_TTL_MS = 2e3;
280
+ var persistedSessionListCache = new PersistedSessionListCache(
281
+ PERSISTED_SESSION_LIST_CACHE_TTL_MS,
282
+ MAX_ORGANIZED_SESSIONS
283
+ );
284
+ function invalidateWorkspaceSessionListCache(options) {
285
+ for (const archiveState of options.archiveStates) {
286
+ persistedSessionListCache.invalidate({
287
+ runtimeBaseDir: options.runtimeBaseDir,
288
+ workspaceCwd: options.workspaceCwd,
289
+ archiveState
290
+ });
291
+ }
292
+ }
293
+ __name(invalidateWorkspaceSessionListCache, "invalidateWorkspaceSessionListCache");
294
+ var InvalidCursorError = class extends Error {
295
+ static {
296
+ __name(this, "InvalidCursorError");
297
+ }
298
+ constructor(cursor, kind = "numeric") {
299
+ super(`Invalid cursor: "${cursor}" is not a valid ${kind} cursor`);
300
+ this.name = "InvalidCursorError";
301
+ }
302
+ };
303
+ function parseSessionCursor(cursor) {
304
+ if (cursor === "") return void 0;
305
+ const trimmed = cursor.trim();
306
+ const parsed = Number(trimmed);
307
+ if (trimmed === "" || !Number.isFinite(parsed) || parsed < 0 || parsed > Number.MAX_SAFE_INTEGER) {
308
+ throw new InvalidCursorError(cursor);
309
+ }
310
+ return parsed;
311
+ }
312
+ __name(parseSessionCursor, "parseSessionCursor");
313
+ function parseEmittedSessionIds(value) {
314
+ if (value === void 0) return [];
315
+ if (!Array.isArray(value) || value.some((id) => typeof id !== "string" || id.length === 0)) {
316
+ return void 0;
317
+ }
318
+ return value;
319
+ }
320
+ __name(parseEmittedSessionIds, "parseEmittedSessionIds");
321
+ function parseOrganizedCursor(cursor, expected) {
322
+ if (cursor === "") return void 0;
323
+ try {
324
+ const decoded = Buffer.from(cursor, "base64url").toString("utf8");
325
+ const parsed = JSON.parse(decoded);
326
+ const last = parsed.last;
327
+ 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) {
328
+ throw new Error("invalid organized cursor");
329
+ }
330
+ const emitted = parseEmittedSessionIds(parsed.emitted);
331
+ if (emitted === void 0) {
332
+ throw new Error("invalid organized cursor");
333
+ }
334
+ return { last, emitted };
335
+ } catch {
336
+ throw new InvalidCursorError(cursor, "organized");
337
+ }
338
+ }
339
+ __name(parseOrganizedCursor, "parseOrganizedCursor");
340
+ function encodeOrganizedCursor(last, group, archiveState, sourceType, sourceId, conversationKind, emitted = []) {
341
+ return Buffer.from(
342
+ JSON.stringify({
343
+ group,
344
+ archiveState,
345
+ sourceType,
346
+ sourceId,
347
+ conversationKind,
348
+ last,
349
+ ...emitted.length > 0 ? { emitted } : {}
350
+ }),
351
+ "utf8"
352
+ ).toString("base64url");
353
+ }
354
+ __name(encodeOrganizedCursor, "encodeOrganizedCursor");
355
+ function parseLiveSessionCursor(cursor) {
356
+ if (cursor === "") return void 0;
357
+ try {
358
+ const parsed = JSON.parse(
359
+ Buffer.from(cursor, "base64url").toString("utf8")
360
+ );
361
+ 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) {
362
+ throw new Error("invalid live cursor");
363
+ }
364
+ return parsed;
365
+ } catch {
366
+ throw new InvalidCursorError(cursor, "live");
367
+ }
368
+ }
369
+ __name(parseLiveSessionCursor, "parseLiveSessionCursor");
370
+ function encodeLiveSessionCursor(last) {
371
+ return Buffer.from(JSON.stringify(last), "utf8").toString("base64url");
372
+ }
373
+ __name(encodeLiveSessionCursor, "encodeLiveSessionCursor");
374
+ function matchesSessionMetadataSource(session, filter) {
375
+ if (filter.conversationKind === "standalone-top-level" && classifyTopLevelConversationSource(session)?.kind !== "standalone") {
376
+ return false;
377
+ }
378
+ const sourceTypeMatches = filter.sourceType === void 0 || session.sourceType === filter.sourceType || // Legacy sessions without source metadata belong to the default catalog.
379
+ filter.sourceType === "default" && session.sourceType === void 0;
380
+ return sourceTypeMatches && // sourceId remains exact; only the default source type has legacy fallback.
381
+ (filter.sourceId === void 0 || session.sourceId === filter.sourceId);
382
+ }
383
+ __name(matchesSessionMetadataSource, "matchesSessionMetadataSource");
384
+ function parseMetadataSessionCursor(cursor, expected) {
385
+ if (cursor === "") return void 0;
386
+ try {
387
+ const parsed = JSON.parse(
388
+ Buffer.from(cursor, "base64url").toString("utf8")
389
+ );
390
+ const last = parsed.last;
391
+ 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) {
392
+ throw new Error("invalid metadata cursor");
393
+ }
394
+ const emitted = parseEmittedSessionIds(
395
+ parsed.emitted
396
+ );
397
+ if (emitted === void 0) {
398
+ throw new Error("invalid metadata cursor");
399
+ }
400
+ return {
401
+ last: { activityTime: last.activityTime, sessionId: last.sessionId },
402
+ emitted
403
+ };
404
+ } catch {
405
+ throw new InvalidCursorError(
406
+ cursor,
407
+ expected.sourceType === void 0 ? "parent" : "metadata"
408
+ );
409
+ }
410
+ }
411
+ __name(parseMetadataSessionCursor, "parseMetadataSessionCursor");
412
+ function encodeMetadataSessionCursor(last, filter, archiveState, emitted = []) {
413
+ return Buffer.from(
414
+ JSON.stringify({
415
+ ...filter,
416
+ archiveState,
417
+ last,
418
+ ...emitted.length > 0 ? { emitted } : {}
419
+ }),
420
+ "utf8"
421
+ ).toString("base64url");
422
+ }
423
+ __name(encodeMetadataSessionCursor, "encodeMetadataSessionCursor");
424
+ async function enrichWorktreeSidecars(bySessionId, sessionService, archiveState = "active", signal) {
425
+ for (const [sessionId, summary] of bySessionId) {
426
+ signal?.throwIfAborted();
427
+ if (summary.worktree) continue;
428
+ let sidecar;
429
+ try {
430
+ const sidecarPath = sessionService.getWorktreeSessionPathForArchiveState(
431
+ sessionId,
432
+ archiveState
433
+ );
434
+ sidecar = signal ? await readWorktreeSession(sidecarPath, { signal }) : await readWorktreeSession(sidecarPath);
435
+ } catch {
436
+ signal?.throwIfAborted();
437
+ sidecar = null;
438
+ }
439
+ if (sidecar) {
440
+ bySessionId.set(sessionId, {
441
+ ...summary,
442
+ worktree: {
443
+ slug: sidecar.slug,
444
+ path: sidecar.worktreePath,
445
+ branch: sidecar.worktreeBranch
446
+ }
447
+ });
448
+ }
449
+ }
450
+ }
451
+ __name(enrichWorktreeSidecars, "enrichWorktreeSidecars");
452
+ async function enrichPrSidecars(bySessionId, sessionService, archiveState, signal) {
453
+ for (const [sessionId, summary] of bySessionId) {
454
+ signal?.throwIfAborted();
455
+ let sidecar;
456
+ try {
457
+ const sidecarPath = sessionService.getPrSessionPathForArchiveState(
458
+ sessionId,
459
+ archiveState
460
+ );
461
+ sidecar = signal ? await readSessionPrs(sidecarPath, { signal }) : await readSessionPrs(sidecarPath);
462
+ } catch {
463
+ signal?.throwIfAborted();
464
+ sidecar = null;
465
+ }
466
+ if (sidecar) {
467
+ bySessionId.set(sessionId, {
468
+ ...summary,
469
+ prs: sidecarToPrInfos(sidecar)
470
+ });
471
+ }
472
+ }
473
+ }
474
+ __name(enrichPrSidecars, "enrichPrSidecars");
475
+ function toSummary(item) {
476
+ return {
477
+ sessionId: item.sessionId,
478
+ workspaceCwd: item.cwd,
479
+ createdAt: item.startTime,
480
+ updatedAt: new Date(item.mtime).toISOString(),
481
+ displayName: item.customTitle || item.prompt,
482
+ ...item.parentSessionId ? { parentSessionId: item.parentSessionId } : {},
483
+ ...item.sourceType ? { sourceType: item.sourceType } : {},
484
+ ...item.sourceId !== void 0 ? { sourceId: item.sourceId } : {},
485
+ clientCount: 0,
486
+ hasActivePrompt: false,
487
+ isArchived: item.isArchived === true
488
+ };
489
+ }
490
+ __name(toSummary, "toSummary");
491
+ function mergeLiveSessionSummary(existing, live) {
492
+ const merged = {
493
+ ...existing,
494
+ ...live,
495
+ createdAt: existing.createdAt,
496
+ displayName: live.displayName ?? existing.displayName,
497
+ // Immutable lineage; the persisted transcript is authoritative, and a live
498
+ // entry only carries it when spawned this run.
499
+ parentSessionId: existing.parentSessionId ?? live.parentSessionId,
500
+ sourceType: existing.sourceType ?? live.sourceType,
501
+ sourceId: existing.sourceType !== void 0 ? existing.sourceId : live.sourceId,
502
+ updatedAt: laterActivityTimestamp(live.updatedAt, existing.updatedAt),
503
+ clientCount: live.clientCount,
504
+ hasActivePrompt: live.hasActivePrompt,
505
+ isArchived: false
506
+ };
507
+ if (existing.prs || live.prs) {
508
+ merged.prs = mergeSummaryPrs(existing.prs, live.prs);
509
+ }
510
+ return merged;
511
+ }
512
+ __name(mergeLiveSessionSummary, "mergeLiveSessionSummary");
513
+ function sidecarToPrInfos(sidecar) {
514
+ return sidecar.map(({ number, url, state }) => ({
515
+ number,
516
+ url,
517
+ ...state ? { state } : {}
518
+ }));
519
+ }
520
+ __name(sidecarToPrInfos, "sidecarToPrInfos");
521
+ function mergeSummaryPrs(persistedPrs, livePrs) {
522
+ const live = livePrs ?? [];
523
+ const persistedByNumber = new Map(
524
+ (persistedPrs ?? []).map((p) => [p.number, p])
525
+ );
526
+ return [
527
+ ...(persistedPrs ?? []).filter(
528
+ (p) => !live.some((l) => l.number === p.number)
529
+ ),
530
+ ...live.map((l) => {
531
+ const persisted = persistedByNumber.get(l.number);
532
+ return persisted?.state !== void 0 && persisted.state !== l.state ? { ...l, state: persisted.state } : l;
533
+ })
534
+ ];
535
+ }
536
+ __name(mergeSummaryPrs, "mergeSummaryPrs");
537
+ async function liveOnlySummary(live, sessionService, signal) {
538
+ const summary = {
539
+ ...live,
540
+ createdAt: live.createdAt,
541
+ clientCount: live.clientCount,
542
+ hasActivePrompt: live.hasActivePrompt,
543
+ isArchived: false
544
+ };
545
+ let sidecar;
546
+ try {
547
+ const sidecarPath = sessionService.getPrSessionPathForArchiveState(
548
+ live.sessionId,
549
+ "active"
550
+ );
551
+ sidecar = signal ? await readSessionPrs(sidecarPath, { signal }) : await readSessionPrs(sidecarPath);
552
+ } catch {
553
+ signal?.throwIfAborted();
554
+ sidecar = null;
555
+ }
556
+ if (sidecar) {
557
+ summary.prs = mergeSummaryPrs(sidecarToPrInfos(sidecar), live.prs);
558
+ }
559
+ return summary;
560
+ }
561
+ __name(liveOnlySummary, "liveOnlySummary");
562
+ function clonePersistedSummary(session) {
563
+ return {
564
+ ...session,
565
+ ...session.worktree ? { worktree: { ...session.worktree } } : {}
566
+ };
567
+ }
568
+ __name(clonePersistedSummary, "clonePersistedSummary");
569
+ async function loadAllPersistedSummaries(sessionService, archiveState, signal) {
570
+ const scanStartedAt = performance.now();
571
+ signal.throwIfAborted();
572
+ const sessions = [];
573
+ let truncated = false;
574
+ let scanPages = 0;
575
+ let cursor;
576
+ do {
577
+ scanPages += 1;
578
+ const page = await sessionService.listSessions({
579
+ cursor,
580
+ size: 1e4,
581
+ archiveState,
582
+ signal
583
+ });
584
+ signal.throwIfAborted();
585
+ const remaining = MAX_ORGANIZED_SESSIONS - sessions.length;
586
+ sessions.push(...page.items.slice(0, remaining).map(toSummary));
587
+ cursor = page.nextCursor;
588
+ if (page.items.length === 0) {
589
+ break;
590
+ }
591
+ if (page.items.length > remaining || sessions.length >= MAX_ORGANIZED_SESSIONS && cursor !== void 0) {
592
+ writeStderrLine(
593
+ `qwen serve: organized session list truncated at ${MAX_ORGANIZED_SESSIONS} sessions`
594
+ );
595
+ truncated = true;
596
+ break;
597
+ }
598
+ } while (cursor !== void 0);
599
+ const bySessionId = new Map(
600
+ sessions.map((session) => [session.sessionId, session])
601
+ );
602
+ await enrichWorktreeSidecars(
603
+ bySessionId,
604
+ sessionService,
605
+ archiveState,
606
+ signal
607
+ );
608
+ await enrichPrSidecars(bySessionId, sessionService, archiveState, signal);
609
+ signal.throwIfAborted();
610
+ return {
611
+ sessions: [...bySessionId.values()],
612
+ truncated,
613
+ scanPages,
614
+ scanDurationMs: Math.max(0, performance.now() - scanStartedAt)
615
+ };
616
+ }
617
+ __name(loadAllPersistedSummaries, "loadAllPersistedSummaries");
618
+ async function listAllPersistedSummaries(sessionService, workspaceCwd, archiveState, runtimeBaseDir, queryKind, signal) {
619
+ const lookup = persistedSessionListCache.lookup(
620
+ { runtimeBaseDir, workspaceCwd, archiveState },
621
+ (loadSignal) => loadAllPersistedSummaries(sessionService, archiveState, loadSignal),
622
+ { signal }
623
+ );
624
+ addDaemonRequestAttribute(
625
+ "qwen-code.daemon.session_list.cache_status",
626
+ lookup.status
627
+ );
628
+ addDaemonRequestAttribute(
629
+ "qwen-code.daemon.session_list.archive_state",
630
+ archiveState
631
+ );
632
+ addDaemonRequestAttribute(
633
+ "qwen-code.daemon.session_list.query_kind",
634
+ queryKind
635
+ );
636
+ if (lookup.cacheAgeMs !== void 0) {
637
+ addDaemonRequestAttribute(
638
+ "qwen-code.daemon.session_list.cache_age_ms",
639
+ lookup.cacheAgeMs
640
+ );
641
+ }
642
+ const snapshot = await lookup.promise;
643
+ signal?.throwIfAborted();
644
+ addDaemonRequestAttribute(
645
+ "qwen-code.daemon.session_list.persisted_sessions",
646
+ snapshot.sessions.length
647
+ );
648
+ addDaemonRequestAttribute(
649
+ "qwen-code.daemon.session_list.scan_pages",
650
+ snapshot.scanPages
651
+ );
652
+ addDaemonRequestAttribute(
653
+ "qwen-code.daemon.session_list.truncated",
654
+ snapshot.truncated
655
+ );
656
+ if (lookup.status !== "cache_hit") {
657
+ addDaemonRequestAttribute(
658
+ "qwen-code.daemon.session_list.scan_duration_ms",
659
+ snapshot.scanDurationMs
660
+ );
661
+ }
662
+ return snapshot;
663
+ }
664
+ __name(listAllPersistedSummaries, "listAllPersistedSummaries");
665
+ function getSummaryActivityTime(session) {
666
+ const time = Date.parse(session.updatedAt ?? session.createdAt);
667
+ return Number.isFinite(time) ? time : 0;
668
+ }
669
+ __name(getSummaryActivityTime, "getSummaryActivityTime");
670
+ function getLiveSessionCursorKey(session) {
671
+ return {
672
+ activityTime: getSummaryActivityTime(session),
673
+ sessionId: session.sessionId
674
+ };
675
+ }
676
+ __name(getLiveSessionCursorKey, "getLiveSessionCursorKey");
677
+ function compareLiveSessionCursorKeys(a, b) {
678
+ const byTime = b.activityTime - a.activityTime;
679
+ if (byTime !== 0) return byTime;
680
+ return a.sessionId.localeCompare(b.sessionId);
681
+ }
682
+ __name(compareLiveSessionCursorKeys, "compareLiveSessionCursorKeys");
683
+ function compareOrganizedSessions(activityTimeById, a, b) {
684
+ return compareOrganizedCursorKeys(
685
+ getOrganizedCursorKey(activityTimeById, a),
686
+ getOrganizedCursorKey(activityTimeById, b)
687
+ );
688
+ }
689
+ __name(compareOrganizedSessions, "compareOrganizedSessions");
690
+ function getOrganizedCursorKey(activityTimeById, session) {
691
+ return {
692
+ isPinned: session.isPinned === true,
693
+ activityTime: activityTimeById.get(session.sessionId) ?? 0,
694
+ sessionId: session.sessionId
695
+ };
696
+ }
697
+ __name(getOrganizedCursorKey, "getOrganizedCursorKey");
698
+ function compareOrganizedCursorKeys(a, b) {
699
+ const byPinned = Number(b.isPinned) - Number(a.isPinned);
700
+ if (byPinned !== 0) return byPinned;
701
+ const byTime = b.activityTime - a.activityTime;
702
+ if (byTime !== 0) return byTime;
703
+ return a.sessionId.localeCompare(b.sessionId);
704
+ }
705
+ __name(compareOrganizedCursorKeys, "compareOrganizedCursorKeys");
706
+ function nextEmittedSessionIds(options) {
707
+ const candidates = new Set(options.carried);
708
+ for (const row of options.page) {
709
+ if (options.liveSessionIds.has(row.sessionId)) {
710
+ candidates.add(row.sessionId);
711
+ }
712
+ }
713
+ const kept = [];
714
+ for (const sessionId of candidates) {
715
+ const row = options.listedById.get(sessionId);
716
+ if (!row) {
717
+ kept.push({ sessionId, persistedTime: Number.NEGATIVE_INFINITY });
718
+ continue;
719
+ }
720
+ const persistedTime = options.persistedTimeById.get(sessionId);
721
+ if (persistedTime === void 0) {
722
+ kept.push({ sessionId, persistedTime: Number.NEGATIVE_INFINITY });
723
+ continue;
724
+ }
725
+ if (options.reenters(row, persistedTime)) {
726
+ kept.push({ sessionId, persistedTime });
727
+ }
728
+ }
729
+ if (kept.length > MAX_EMITTED_CURSOR_SESSION_IDS) {
730
+ kept.sort((a, b) => a.persistedTime - b.persistedTime);
731
+ kept.length = MAX_EMITTED_CURSOR_SESSION_IDS;
732
+ }
733
+ return kept.map((entry) => entry.sessionId);
734
+ }
735
+ __name(nextEmittedSessionIds, "nextEmittedSessionIds");
736
+ function applyOrganization(session, organization) {
737
+ return {
738
+ ...session,
739
+ groupId: organization?.groupId ?? null,
740
+ color: organization?.color ?? null,
741
+ isPinned: organization?.isPinned === true,
742
+ ...organization?.pinnedAt !== void 0 ? { pinnedAt: organization.pinnedAt } : {}
743
+ };
744
+ }
745
+ __name(applyOrganization, "applyOrganization");
746
+ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, options, pageSize, readOptions) {
747
+ const archiveState = options.archiveState ?? "active";
748
+ const sessionService = new SessionService(workspaceCwd);
749
+ const organizationService = createSessionOrganizationService(workspaceCwd);
750
+ readOptions.signal?.throwIfAborted();
751
+ const snapshot = await organizationService.readSnapshot();
752
+ readOptions.signal?.throwIfAborted();
753
+ const knownGroupIds = new Set(snapshot.groups.map((group2) => group2.id));
754
+ const group = options.group ?? "all";
755
+ if (group !== "all" && group !== "pinned" && group !== "ungrouped" && !knownGroupIds.has(group)) {
756
+ throw new SessionOrganizationError(
757
+ `Group not found: ${group}`,
758
+ "group_not_found",
759
+ "group"
760
+ );
761
+ }
762
+ const cursor = options.cursor !== void 0 ? parseOrganizedCursor(options.cursor, {
763
+ group,
764
+ archiveState,
765
+ sourceType: options.sourceType,
766
+ sourceId: options.sourceId,
767
+ conversationKind: options.conversationKind
768
+ }) : void 0;
769
+ const cursorKey = cursor?.last;
770
+ const emittedBeforePage = new Set(cursor?.emitted ?? []);
771
+ const isFirstPage = cursorKey === void 0;
772
+ let liveMergeFailed = false;
773
+ const bySessionId = /* @__PURE__ */ new Map();
774
+ const persisted = await listAllPersistedSummaries(
775
+ sessionService,
776
+ workspaceCwd,
777
+ archiveState,
778
+ readOptions.runtimeBaseDir,
779
+ "organized",
780
+ readOptions.signal
781
+ );
782
+ readOptions.signal?.throwIfAborted();
783
+ for (const session of persisted.sessions) {
784
+ bySessionId.set(
785
+ session.sessionId,
786
+ applyOrganization(
787
+ clonePersistedSummary(session),
788
+ snapshot.sessions.get(session.sessionId)
789
+ )
790
+ );
791
+ }
792
+ const persistedTimeById = new Map(
793
+ persisted.sessions.map((session) => [
794
+ session.sessionId,
795
+ getSummaryActivityTime(session)
796
+ ])
797
+ );
798
+ const liveSessionIds = /* @__PURE__ */ new Set();
799
+ if (readOptions.mergeLive !== false && archiveState !== "archived") {
800
+ try {
801
+ const liveSessions = bridge.listWorkspaceSessions(workspaceCwd);
802
+ for (const live of liveSessions) {
803
+ liveSessionIds.add(live.sessionId);
804
+ const existing = bySessionId.get(live.sessionId);
805
+ const organization = snapshot.sessions.get(live.sessionId);
806
+ if (existing) {
807
+ bySessionId.set(
808
+ live.sessionId,
809
+ applyOrganization(
810
+ mergeLiveSessionSummary(existing, live),
811
+ organization
812
+ )
813
+ );
814
+ } else if (
815
+ // A live-only row has no persisted key to page by, so it stays a
816
+ // first-page-only insertion as before.
817
+ isFirstPage && // `listAllPersistedSummaries` already scanned every persisted
818
+ // session when the scan wasn't truncated, so a `sessionId` missing
819
+ // from `bySessionId` is definitively new — no disk re-check
820
+ // needed. Re-checking here raced a session that persists its
821
+ // first write (e.g. a `displayName` update) between the scan
822
+ // above and this point: `existing` stayed undefined but
823
+ // `sessionExists` flipped to true, silently dropping the live
824
+ // session from the response instead of merging it.
825
+ (!persisted.truncated || !await (readOptions.signal ? sessionService.sessionExists(live.sessionId, {
826
+ signal: readOptions.signal
827
+ }) : sessionService.sessionExists(live.sessionId)))
828
+ ) {
829
+ bySessionId.set(
830
+ live.sessionId,
831
+ applyOrganization(
832
+ await liveOnlySummary(live, sessionService, readOptions.signal),
833
+ organization
834
+ )
835
+ );
836
+ }
837
+ }
838
+ } catch (error) {
839
+ readOptions.signal?.throwIfAborted();
840
+ liveMergeFailed = true;
841
+ writeStderrLine(
842
+ `qwen serve: organized session list live merge failed; using persisted sessions only: ${error instanceof Error ? error.message : String(error)}`
843
+ );
844
+ }
845
+ }
846
+ const filtered = [...bySessionId.values()].filter((session) => {
847
+ if (!matchesSessionMetadataSource(session, options)) return false;
848
+ if (group === "all") return true;
849
+ if (group === "pinned") return session.isPinned === true;
850
+ if (group === "ungrouped")
851
+ return session.groupId == null && session.color == null;
852
+ return session.color == null && session.groupId === group;
853
+ });
854
+ readOptions.signal?.throwIfAborted();
855
+ const activityTimeById = new Map(
856
+ filtered.map((session) => [
857
+ session.sessionId,
858
+ getSummaryActivityTime(session)
859
+ ])
860
+ );
861
+ filtered.sort((a, b) => compareOrganizedSessions(activityTimeById, a, b));
862
+ readOptions.signal?.throwIfAborted();
863
+ const afterCursor = cursorKey === void 0 ? filtered : filtered.filter(
864
+ (session) => (
865
+ // A row already emitted at a live-derived key stays excluded even
866
+ // if its key regressed behind the cursor (live retirement, or a
867
+ // live-only row that persisted mid-pass).
868
+ !emittedBeforePage.has(session.sessionId) && compareOrganizedCursorKeys(
869
+ cursorKey,
870
+ getOrganizedCursorKey(activityTimeById, session)
871
+ ) < 0
872
+ )
873
+ );
874
+ const page = afterCursor.slice(0, pageSize);
875
+ let nextCursor;
876
+ if (page.length < afterCursor.length) {
877
+ const boundary = getOrganizedCursorKey(
878
+ activityTimeById,
879
+ page[page.length - 1]
880
+ );
881
+ const emitted = nextEmittedSessionIds({
882
+ carried: emittedBeforePage,
883
+ page,
884
+ liveSessionIds,
885
+ listedById: new Map(
886
+ filtered.map((session) => [session.sessionId, session])
887
+ ),
888
+ persistedTimeById,
889
+ // `isPinned` is re-read from the organization snapshot on every page
890
+ // request, so a pin flip between fetches can move the persisted key
891
+ // across the pinned/unpinned blocks. Keep the identity while the key
892
+ // could re-enter under either state.
893
+ reenters: /* @__PURE__ */ __name((row, persistedTime) => [true, false].some(
894
+ (isPinned) => compareOrganizedCursorKeys(boundary, {
895
+ isPinned,
896
+ activityTime: persistedTime,
897
+ sessionId: row.sessionId
898
+ }) < 0
899
+ ), "reenters")
900
+ });
901
+ nextCursor = encodeOrganizedCursor(
902
+ boundary,
903
+ group,
904
+ archiveState,
905
+ options.sourceType,
906
+ options.sourceId,
907
+ options.conversationKind,
908
+ emitted
909
+ );
910
+ }
911
+ return {
912
+ sessions: page,
913
+ ...nextCursor !== void 0 ? { nextCursor } : {},
914
+ ...liveMergeFailed ? { liveMergeFailed: true } : {},
915
+ ...persisted.truncated ? { truncated: true } : {}
916
+ };
917
+ }
918
+ __name(listOrganizedWorkspaceSessionsForResponse, "listOrganizedWorkspaceSessionsForResponse");
919
+ async function listWorkspaceSessionsByMetadataForResponse(bridge, workspaceCwd, options, pageSize, filter, readOptions) {
920
+ const archiveState = options.archiveState ?? "active";
921
+ const sessionService = new SessionService(workspaceCwd);
922
+ const bySessionId = /* @__PURE__ */ new Map();
923
+ const persisted = await listAllPersistedSummaries(
924
+ sessionService,
925
+ workspaceCwd,
926
+ archiveState,
927
+ readOptions.runtimeBaseDir,
928
+ "metadata",
929
+ readOptions.signal
930
+ );
931
+ readOptions.signal?.throwIfAborted();
932
+ const canonicalizeStandaloneIds = filter.conversationKind === "standalone-top-level";
933
+ const conflictedStandaloneIds = /* @__PURE__ */ new Set();
934
+ const persistedTimeById = /* @__PURE__ */ new Map();
935
+ for (const session of persisted.sessions) {
936
+ let sessionId = session.sessionId;
937
+ if (canonicalizeStandaloneIds) {
938
+ const parsed = parseCallerSuppliedSessionId(sessionId);
939
+ if (parsed.kind !== "valid") continue;
940
+ sessionId = parsed.sessionId;
941
+ if (conflictedStandaloneIds.has(sessionId)) continue;
942
+ if (bySessionId.has(sessionId)) {
943
+ bySessionId.delete(sessionId);
944
+ persistedTimeById.delete(sessionId);
945
+ conflictedStandaloneIds.add(sessionId);
946
+ continue;
947
+ }
948
+ }
949
+ bySessionId.set(sessionId, {
950
+ ...clonePersistedSummary(session),
951
+ sessionId
952
+ });
953
+ persistedTimeById.set(sessionId, getSummaryActivityTime(session));
954
+ }
955
+ const liveSessionIds = /* @__PURE__ */ new Set();
956
+ let liveMergeFailed = false;
957
+ if (readOptions.mergeLive !== false && archiveState !== "archived") {
958
+ try {
959
+ for (const live of bridge.listWorkspaceSessions(workspaceCwd)) {
960
+ let sessionId = live.sessionId;
961
+ if (canonicalizeStandaloneIds) {
962
+ const parsed = parseCallerSuppliedSessionId(sessionId);
963
+ if (parsed.kind !== "valid" || conflictedStandaloneIds.has(parsed.sessionId)) {
964
+ continue;
965
+ }
966
+ sessionId = parsed.sessionId;
967
+ }
968
+ const canonicalLive = sessionId === live.sessionId ? live : { ...live, sessionId };
969
+ liveSessionIds.add(sessionId);
970
+ const existing = bySessionId.get(sessionId);
971
+ if (existing) {
972
+ bySessionId.set(
973
+ sessionId,
974
+ mergeLiveSessionSummary(existing, canonicalLive)
975
+ );
976
+ } else if (
977
+ // See the matching comment in
978
+ // `listOrganizedWorkspaceSessionsForResponse`: an untruncated scan
979
+ // already covers every persisted session, so skip the racy
980
+ // re-check when nothing was truncated.
981
+ !persisted.truncated || !await (readOptions.signal ? sessionService.sessionExists(sessionId, {
982
+ signal: readOptions.signal
983
+ }) : sessionService.sessionExists(sessionId))
984
+ ) {
985
+ bySessionId.set(
986
+ sessionId,
987
+ await liveOnlySummary(
988
+ canonicalLive,
989
+ sessionService,
990
+ readOptions.signal
991
+ )
992
+ );
993
+ }
994
+ }
995
+ } catch (error) {
996
+ readOptions.signal?.throwIfAborted();
997
+ liveMergeFailed = true;
998
+ writeStderrLine(
999
+ `qwen serve: session metadata filter live merge failed; using persisted sessions only: ${error instanceof Error ? error.message : String(error)}`
1000
+ );
1001
+ }
1002
+ }
1003
+ const matches = [...bySessionId.values()].filter(
1004
+ (session) => (filter.parentSessionId === void 0 || session.parentSessionId === filter.parentSessionId) && matchesSessionMetadataSource(session, filter)
1005
+ ).sort(
1006
+ (a, b) => compareLiveSessionCursorKeys(
1007
+ getLiveSessionCursorKey(a),
1008
+ getLiveSessionCursorKey(b)
1009
+ )
1010
+ );
1011
+ readOptions.signal?.throwIfAborted();
1012
+ const cursor = options.cursor !== void 0 && options.cursor !== "" ? parseMetadataSessionCursor(options.cursor, {
1013
+ ...filter,
1014
+ archiveState
1015
+ }) : void 0;
1016
+ const cursorKey = cursor?.last;
1017
+ const emittedBeforePage = new Set(cursor?.emitted ?? []);
1018
+ const afterCursor = cursorKey === void 0 ? matches : matches.filter(
1019
+ (session) => (
1020
+ // See the organized path: exclude rows already emitted at a
1021
+ // live-derived key whose key regressed behind the cursor.
1022
+ !emittedBeforePage.has(session.sessionId) && compareLiveSessionCursorKeys(
1023
+ cursorKey,
1024
+ getLiveSessionCursorKey(session)
1025
+ ) < 0
1026
+ )
1027
+ );
1028
+ const page = afterCursor.slice(0, pageSize);
1029
+ let nextCursor;
1030
+ if (page.length < afterCursor.length) {
1031
+ const boundary = getLiveSessionCursorKey(page[page.length - 1]);
1032
+ const emitted = nextEmittedSessionIds({
1033
+ carried: emittedBeforePage,
1034
+ page,
1035
+ liveSessionIds,
1036
+ listedById: new Map(
1037
+ matches.map((session) => [session.sessionId, session])
1038
+ ),
1039
+ persistedTimeById,
1040
+ reenters: /* @__PURE__ */ __name((row, persistedTime) => compareLiveSessionCursorKeys(boundary, {
1041
+ activityTime: persistedTime,
1042
+ sessionId: row.sessionId
1043
+ }) < 0, "reenters")
1044
+ });
1045
+ nextCursor = encodeMetadataSessionCursor(
1046
+ boundary,
1047
+ filter,
1048
+ archiveState,
1049
+ emitted
1050
+ );
1051
+ }
1052
+ return {
1053
+ sessions: page,
1054
+ ...nextCursor !== void 0 ? { nextCursor } : {},
1055
+ ...liveMergeFailed ? { liveMergeFailed: true } : {},
1056
+ ...persisted.truncated ? { truncated: true } : {}
1057
+ };
1058
+ }
1059
+ __name(listWorkspaceSessionsByMetadataForResponse, "listWorkspaceSessionsByMetadataForResponse");
1060
+ async function listWorkspaceSessionsForResponse(bridge, workspaceCwd, options, readOptions = {}) {
1061
+ readOptions.signal?.throwIfAborted();
1062
+ const runtimeBaseDir = new Storage(
1063
+ workspaceCwd,
1064
+ readOptions.runtimeBaseDir
1065
+ ).getRuntimeBaseDir();
1066
+ const result = await Storage.runWithResolvedRuntimeBaseDir(
1067
+ runtimeBaseDir,
1068
+ () => listWorkspaceSessionsForResponseInRuntime(bridge, workspaceCwd, options, {
1069
+ ...readOptions.mergeLive !== void 0 ? { mergeLive: readOptions.mergeLive } : {},
1070
+ ...readOptions.signal !== void 0 ? { signal: readOptions.signal } : {},
1071
+ runtimeBaseDir
1072
+ })
1073
+ );
1074
+ readOptions.signal?.throwIfAborted();
1075
+ return result;
1076
+ }
1077
+ __name(listWorkspaceSessionsForResponse, "listWorkspaceSessionsForResponse");
1078
+ async function listWorkspaceSessionsForResponseInRuntime(bridge, workspaceCwd, options, readOptions) {
1079
+ readOptions.signal?.throwIfAborted();
1080
+ const rawSize = options?.size;
1081
+ const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
1082
+ const pageSize = Math.min(Math.max(requestedSize, 1), MAX_SESSION_PAGE_SIZE);
1083
+ if (options?.view === "organized") {
1084
+ return listOrganizedWorkspaceSessionsForResponse(
1085
+ bridge,
1086
+ workspaceCwd,
1087
+ options,
1088
+ pageSize,
1089
+ readOptions
1090
+ );
1091
+ }
1092
+ if (options?.parentSessionId !== void 0 || options?.sourceType !== void 0 || options?.conversationKind !== void 0) {
1093
+ return listWorkspaceSessionsByMetadataForResponse(
1094
+ bridge,
1095
+ workspaceCwd,
1096
+ options,
1097
+ pageSize,
1098
+ {
1099
+ ...options.parentSessionId !== void 0 ? { parentSessionId: options.parentSessionId } : {},
1100
+ ...options.sourceType !== void 0 ? { sourceType: options.sourceType } : {},
1101
+ ...options.sourceId !== void 0 ? { sourceId: options.sourceId } : {},
1102
+ ...options.conversationKind !== void 0 ? { conversationKind: options.conversationKind } : {}
1103
+ },
1104
+ readOptions
1105
+ );
1106
+ }
1107
+ let numericCursor;
1108
+ if (options?.cursor != null) {
1109
+ numericCursor = parseSessionCursor(options.cursor);
1110
+ }
1111
+ const isFirstPage = numericCursor === void 0;
1112
+ const sessionService = new SessionService(workspaceCwd);
1113
+ const archiveState = options?.archiveState ?? "active";
1114
+ const persisted = await sessionService.listSessions({
1115
+ cursor: numericCursor,
1116
+ size: pageSize,
1117
+ archiveState,
1118
+ ...readOptions.signal ? { signal: readOptions.signal } : {}
1119
+ });
1120
+ readOptions.signal?.throwIfAborted();
1121
+ const bySessionId = /* @__PURE__ */ new Map();
1122
+ for (const item of persisted.items) {
1123
+ bySessionId.set(item.sessionId, toSummary(item));
1124
+ }
1125
+ await enrichWorktreeSidecars(
1126
+ bySessionId,
1127
+ sessionService,
1128
+ archiveState,
1129
+ readOptions.signal
1130
+ );
1131
+ await enrichPrSidecars(
1132
+ bySessionId,
1133
+ sessionService,
1134
+ archiveState,
1135
+ readOptions.signal
1136
+ );
1137
+ readOptions.signal?.throwIfAborted();
1138
+ if (archiveState === "archived" || readOptions.mergeLive === false) {
1139
+ const sessions2 = [...bySessionId.values()];
1140
+ const nextCursor2 = persisted.nextCursor != null ? String(persisted.nextCursor) : void 0;
1141
+ return { sessions: sessions2, nextCursor: nextCursor2 };
1142
+ }
1143
+ const liveSessions = bridge.listWorkspaceSessions(workspaceCwd);
1144
+ for (const live of liveSessions) {
1145
+ const existing = bySessionId.get(live.sessionId);
1146
+ if (existing) {
1147
+ bySessionId.set(live.sessionId, mergeLiveSessionSummary(existing, live));
1148
+ } else if (isFirstPage && // If this is a complete scan (no further pages), a missing
1149
+ // `sessionId` here is definitively new — no disk re-check needed.
1150
+ // Re-checking raced a session that persists its first write (e.g. a
1151
+ // `displayName` update) between the scan above and this point:
1152
+ // `existing` stayed undefined but `sessionExists` flipped to true,
1153
+ // silently dropping the live session from the response instead of
1154
+ // merging it.
1155
+ (persisted.nextCursor == null || !await (readOptions.signal ? sessionService.sessionExists(live.sessionId, {
1156
+ signal: readOptions.signal
1157
+ }) : sessionService.sessionExists(live.sessionId)))) {
1158
+ bySessionId.set(
1159
+ live.sessionId,
1160
+ await liveOnlySummary(live, sessionService, readOptions.signal)
1161
+ );
1162
+ }
1163
+ }
1164
+ const sessions = [...bySessionId.values()].sort((a, b) => {
1165
+ const aTime = Date.parse(a.updatedAt ?? a.createdAt);
1166
+ const bTime = Date.parse(b.updatedAt ?? b.createdAt);
1167
+ return bTime - aTime;
1168
+ });
1169
+ readOptions.signal?.throwIfAborted();
1170
+ const nextCursor = persisted.nextCursor != null ? String(persisted.nextCursor) : void 0;
1171
+ return { sessions, nextCursor };
1172
+ }
1173
+ __name(listWorkspaceSessionsForResponseInRuntime, "listWorkspaceSessionsForResponseInRuntime");
1174
+ async function listLiveWorkspaceSessionsForResponse(bridge, workspaceCwd, options, readOptions = {}) {
1175
+ const runtimeBaseDir = new Storage(
1176
+ workspaceCwd,
1177
+ readOptions.runtimeBaseDir
1178
+ ).getRuntimeBaseDir();
1179
+ return Storage.runWithResolvedRuntimeBaseDir(runtimeBaseDir, async () => {
1180
+ const rawSize = options?.size;
1181
+ const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
1182
+ const pageSize = Math.min(
1183
+ Math.max(requestedSize, 1),
1184
+ MAX_SESSION_PAGE_SIZE
1185
+ );
1186
+ const cursorKey = options?.cursor !== void 0 ? parseLiveSessionCursor(options.cursor) : void 0;
1187
+ const sessions = bridge.listWorkspaceSessions(workspaceCwd).sort(
1188
+ (a, b) => compareLiveSessionCursorKeys(
1189
+ getLiveSessionCursorKey(a),
1190
+ getLiveSessionCursorKey(b)
1191
+ )
1192
+ );
1193
+ const afterCursor = cursorKey === void 0 ? sessions : sessions.filter(
1194
+ (session) => compareLiveSessionCursorKeys(
1195
+ cursorKey,
1196
+ getLiveSessionCursorKey(session)
1197
+ ) < 0
1198
+ );
1199
+ const page = afterCursor.slice(0, pageSize);
1200
+ const sessionService = new SessionService(workspaceCwd);
1201
+ const enriched = await Promise.all(
1202
+ page.map(
1203
+ (summary) => liveOnlySummary(summary, sessionService, readOptions.signal)
1204
+ )
1205
+ );
1206
+ const nextCursor = page.length < afterCursor.length ? encodeLiveSessionCursor(
1207
+ getLiveSessionCursorKey(page[page.length - 1])
1208
+ ) : void 0;
1209
+ return {
1210
+ sessions: enriched,
1211
+ ...nextCursor !== void 0 ? { nextCursor } : {}
1212
+ };
1213
+ });
1214
+ }
1215
+ __name(listLiveWorkspaceSessionsForResponse, "listLiveWorkspaceSessionsForResponse");
1216
+ async function getWorkspaceSessionInfoForResponse(bridge, workspaceCwd, options = {}) {
1217
+ const counts = await new SessionService(workspaceCwd).getSessionInfoCounts();
1218
+ return {
1219
+ active: counts.active,
1220
+ archived: counts.archived,
1221
+ total: counts.total,
1222
+ ...options.includeLive === false ? {} : { live: bridge.listWorkspaceSessions(workspaceCwd).length },
1223
+ expensive: true,
1224
+ cost: "disk_scan",
1225
+ ...counts.truncated ? { truncated: true } : {}
1226
+ };
1227
+ }
1228
+ __name(getWorkspaceSessionInfoForResponse, "getWorkspaceSessionInfoForResponse");
1229
+ function parseSessionPageSizeQuery(raw) {
1230
+ if (typeof raw !== "string") return void 0;
1231
+ const trimmed = raw.trim();
1232
+ if (!/^[+-]?\d+$/.test(trimmed)) return void 0;
1233
+ const parsed = Number.parseInt(trimmed, 10);
1234
+ if (!Number.isFinite(parsed)) return void 0;
1235
+ if (Number.isSafeInteger(parsed)) return parsed;
1236
+ return trimmed.startsWith("-") ? 1 : MAX_SESSION_PAGE_SIZE;
1237
+ }
1238
+ __name(parseSessionPageSizeQuery, "parseSessionPageSizeQuery");
1239
+
1240
+ // packages/cli/src/serve/workspace-runtime-storage.ts
1241
+ init_esbuild_shims();
1242
+ function runWithWorkspaceRuntimeStorage(runtime, fn) {
1243
+ return Storage.runWithResolvedRuntimeBaseDir(
1244
+ runtime.sessionRuntimeBaseDir,
1245
+ fn
1246
+ );
1247
+ }
1248
+ __name(runWithWorkspaceRuntimeStorage, "runWithWorkspaceRuntimeStorage");
1249
+ function createWorkspaceRuntimeSessionService(runtime, options = {}) {
1250
+ return new SessionService(runtime.workspaceCwd, {
1251
+ ...options,
1252
+ runtimeBaseDir: runtime.sessionRuntimeBaseDir
1253
+ });
1254
+ }
1255
+ __name(createWorkspaceRuntimeSessionService, "createWorkspaceRuntimeSessionService");
1256
+
1257
+ // packages/cli/src/serve/server/session-archive.ts
1258
+ init_esbuild_shims();
1259
+
1260
+ // packages/cli/src/serve/scheduled-task-session-lifecycle.ts
1261
+ init_esbuild_shims();
1262
+ function isBoundTask(task) {
1263
+ return typeof task.sessionId === "string" && task.sessionId.length > 0;
1264
+ }
1265
+ __name(isBoundTask, "isBoundTask");
1266
+ async function disableTasksForSessions(projectRoot, sessionIds, options = {}) {
1267
+ if (sessionIds.length === 0) return;
1268
+ const targets = new Set(sessionIds);
1269
+ await updateCronTasks(
1270
+ projectRoot,
1271
+ (tasks) => {
1272
+ let changed = false;
1273
+ const next = tasks.map((task) => {
1274
+ if (isBoundTask(task) && targets.has(task.sessionId) && task.enabled !== false) {
1275
+ changed = true;
1276
+ return { ...task, enabled: false, disabledByArchive: true };
1277
+ }
1278
+ return task;
1279
+ });
1280
+ return changed ? next : tasks;
1281
+ },
1282
+ options
1283
+ );
1284
+ }
1285
+ __name(disableTasksForSessions, "disableTasksForSessions");
1286
+ async function enableTasksForSessions(projectRoot, sessionIds, now = Date.now(), options = {}) {
1287
+ if (sessionIds.length === 0) return;
1288
+ const targets = new Set(sessionIds);
1289
+ await updateCronTasks(
1290
+ projectRoot,
1291
+ (tasks) => {
1292
+ let changed = false;
1293
+ const next = tasks.map((task) => {
1294
+ if (isBoundTask(task) && targets.has(task.sessionId) && task.enabled === false && task.disabledByArchive === true) {
1295
+ changed = true;
1296
+ const resumed = { ...task, enabled: true };
1297
+ delete resumed.disabledByArchive;
1298
+ const minute = now - now % 6e4;
1299
+ if (resumed.recurring) {
1300
+ resumed.lastFiredAt = minute;
1301
+ } else {
1302
+ resumed.createdAt = now;
1303
+ resumed.lastFiredAt = minute;
1304
+ }
1305
+ return resumed;
1306
+ }
1307
+ return task;
1308
+ });
1309
+ return changed ? next : tasks;
1310
+ },
1311
+ options
1312
+ );
1313
+ }
1314
+ __name(enableTasksForSessions, "enableTasksForSessions");
1315
+ async function removeTasksForSessions(projectRoot, sessionIds, options = {}) {
1316
+ if (sessionIds.length === 0) return;
1317
+ const targets = new Set(sessionIds);
1318
+ await updateCronTasks(
1319
+ projectRoot,
1320
+ (tasks) => {
1321
+ const next = tasks.filter(
1322
+ (task) => !isBoundTask(task) || !targets.has(task.sessionId)
1323
+ );
1324
+ return next.length === tasks.length ? tasks : next;
1325
+ },
1326
+ options
1327
+ );
1328
+ }
1329
+ __name(removeTasksForSessions, "removeTasksForSessions");
1330
+
1331
+ // packages/cli/src/serve/server/session-archive.ts
1332
+ var DaemonDrainingError = class extends Error {
1333
+ static {
1334
+ __name(this, "DaemonDrainingError");
1335
+ }
1336
+ name = "DaemonDrainingError";
1337
+ code = "daemon_draining";
1338
+ constructor() {
1339
+ super("The daemon is draining and no longer accepts session maintenance.");
1340
+ }
1341
+ };
1342
+ var SessionArchiveCoordinator = class {
1343
+ static {
1344
+ __name(this, "SessionArchiveCoordinator");
1345
+ }
1346
+ exclusive = /* @__PURE__ */ new Set();
1347
+ shared = /* @__PURE__ */ new Map();
1348
+ sharedDrains = /* @__PURE__ */ new Map();
1349
+ maintenanceSealed = false;
1350
+ activeMaintenance = 0;
1351
+ maintenanceDrain;
1352
+ // Lock keys are canonicalized like every other session-id lookup: batch
1353
+ // delete/archive/unarchive lock raw caller spellings while restore locks
1354
+ // the request spelling, and on a case-insensitive filesystem both reach
1355
+ // the same transcript file — uncanonicalized keys would let a differently
1356
+ // cased caller id slip past a held guard and unlink it mid-restore.
1357
+ assertNotTransitioning(sessionId) {
1358
+ if (this.exclusive.has(normalizeSessionIdForLookup(sessionId))) {
1359
+ throw new SessionArchivingError(sessionId);
1360
+ }
1361
+ }
1362
+ async runExclusiveMany(sessionIds, fn) {
1363
+ if (this.maintenanceSealed) {
1364
+ throw new DaemonDrainingError();
1365
+ }
1366
+ const uniqueSessionIds = [
1367
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1368
+ ];
1369
+ for (const sessionId of uniqueSessionIds) {
1370
+ this.assertNotTransitioning(sessionId);
1371
+ if ((this.shared.get(sessionId) ?? 0) > 0) {
1372
+ throw new SessionArchivingError(sessionId, "shared");
1373
+ }
1374
+ }
1375
+ for (const sessionId of uniqueSessionIds) {
1376
+ this.exclusive.add(sessionId);
1377
+ }
1378
+ this.activeMaintenance++;
1379
+ try {
1380
+ return await fn();
1381
+ } finally {
1382
+ for (const sessionId of uniqueSessionIds) {
1383
+ this.exclusive.delete(sessionId);
1384
+ }
1385
+ this.activeMaintenance--;
1386
+ if (this.activeMaintenance === 0) {
1387
+ this.maintenanceDrain?.resolve();
1388
+ this.maintenanceDrain = void 0;
1389
+ }
1390
+ }
1391
+ }
1392
+ async runExclusiveAfterShared(rawSessionId, fn) {
1393
+ if (this.maintenanceSealed) {
1394
+ throw new DaemonDrainingError();
1395
+ }
1396
+ const sessionId = normalizeSessionIdForLookup(rawSessionId);
1397
+ this.assertNotTransitioning(sessionId);
1398
+ this.exclusive.add(sessionId);
1399
+ this.activeMaintenance++;
1400
+ try {
1401
+ const sharedCount = this.shared.get(sessionId) ?? 0;
1402
+ if (sharedCount > 0) {
1403
+ let drain = this.sharedDrains.get(sessionId);
1404
+ if (!drain) {
1405
+ let resolve;
1406
+ const promise = new Promise((done) => {
1407
+ resolve = done;
1408
+ });
1409
+ drain = { promise, resolve };
1410
+ this.sharedDrains.set(sessionId, drain);
1411
+ }
1412
+ await drain.promise;
1413
+ }
1414
+ return await fn();
1415
+ } finally {
1416
+ this.sharedDrains.delete(sessionId);
1417
+ this.exclusive.delete(sessionId);
1418
+ this.activeMaintenance--;
1419
+ if (this.activeMaintenance === 0) {
1420
+ this.maintenanceDrain?.resolve();
1421
+ this.maintenanceDrain = void 0;
1422
+ }
1423
+ }
1424
+ }
1425
+ sealMaintenanceAndWait() {
1426
+ this.maintenanceSealed = true;
1427
+ if (this.activeMaintenance === 0) {
1428
+ return Promise.resolve();
1429
+ }
1430
+ if (!this.maintenanceDrain) {
1431
+ let resolve;
1432
+ const promise = new Promise((done) => {
1433
+ resolve = done;
1434
+ });
1435
+ this.maintenanceDrain = { promise, resolve };
1436
+ }
1437
+ return this.maintenanceDrain.promise;
1438
+ }
1439
+ async runSharedMany(sessionIds, fn) {
1440
+ if (this.maintenanceSealed) {
1441
+ throw new DaemonDrainingError();
1442
+ }
1443
+ const uniqueSessionIds = [
1444
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1445
+ ];
1446
+ for (const sessionId of uniqueSessionIds) {
1447
+ this.assertNotTransitioning(sessionId);
1448
+ }
1449
+ for (const sessionId of uniqueSessionIds) {
1450
+ this.shared.set(sessionId, (this.shared.get(sessionId) ?? 0) + 1);
1451
+ }
1452
+ this.activeMaintenance++;
1453
+ try {
1454
+ return await fn();
1455
+ } finally {
1456
+ for (const sessionId of uniqueSessionIds) {
1457
+ const count = (this.shared.get(sessionId) ?? 1) - 1;
1458
+ if (count <= 0) {
1459
+ this.shared.delete(sessionId);
1460
+ this.sharedDrains.get(sessionId)?.resolve();
1461
+ this.sharedDrains.delete(sessionId);
1462
+ } else {
1463
+ this.shared.set(sessionId, count);
1464
+ }
1465
+ }
1466
+ this.activeMaintenance--;
1467
+ if (this.activeMaintenance === 0) {
1468
+ this.maintenanceDrain?.resolve();
1469
+ this.maintenanceDrain = void 0;
1470
+ }
1471
+ }
1472
+ }
1473
+ };
1474
+ async function runWithDaemonWriterLease(params) {
1475
+ const {
1476
+ action,
1477
+ sessionId,
1478
+ service,
1479
+ mutate,
1480
+ mutationAppliedAfterError,
1481
+ afterMutationApplied
1482
+ } = params;
1483
+ let lease;
1484
+ try {
1485
+ const leaseOptions = {
1486
+ processKind: "daemon",
1487
+ reclaimPolicy: "never",
1488
+ takeoverPolicy: "certified"
1489
+ };
1490
+ try {
1491
+ lease = await service.acquireSessionWriterLease(sessionId, leaseOptions);
1492
+ } catch (error) {
1493
+ if (!(error instanceof SessionWriterUnavailableError) && !(error instanceof SessionTranscriptChangedError)) {
1494
+ throw error;
1495
+ }
1496
+ lease = await service.acquireSessionMaintenanceLease(
1497
+ sessionId,
1498
+ leaseOptions
1499
+ );
1500
+ }
1501
+ } catch (error) {
1502
+ return { mutationApplied: false, error };
1503
+ }
1504
+ let value;
1505
+ let mutationApplied = false;
1506
+ let mutationError;
1507
+ try {
1508
+ const mutation = await mutate(() => lease.assertOwnedAndUnchanged());
1509
+ value = mutation.value;
1510
+ mutationApplied = mutation.mutationApplied;
1511
+ } catch (error) {
1512
+ mutationError = error;
1513
+ try {
1514
+ mutationApplied = await mutationAppliedAfterError();
1515
+ } catch {
1516
+ mutationApplied = false;
1517
+ }
1518
+ }
1519
+ let maintenanceError;
1520
+ if (mutationApplied) {
1521
+ try {
1522
+ await afterMutationApplied();
1523
+ } catch (error) {
1524
+ maintenanceError = error;
1525
+ logSessionArchiveWarning(
1526
+ `scheduled task lifecycle update failed action=${action} workspace=${safeLogValue(
1527
+ service.getProjectRoot()
1528
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1529
+ errorMessage(error)
1530
+ )}`
1531
+ );
1532
+ }
1533
+ }
1534
+ let releaseError;
1535
+ try {
1536
+ await lease.release();
1537
+ } catch (error) {
1538
+ releaseError = error;
1539
+ }
1540
+ if (releaseError !== void 0) {
1541
+ logMaintenanceLeaseReleaseFailure({
1542
+ action,
1543
+ workspace: service.getProjectRoot(),
1544
+ sessionId,
1545
+ error: releaseError,
1546
+ mutationApplied
1547
+ });
1548
+ if (mutationError !== void 0) {
1549
+ logSessionArchiveWarning(
1550
+ `session maintenance mutation also failed action=${action} workspace=${safeLogValue(
1551
+ service.getProjectRoot()
1552
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1553
+ errorMessage(mutationError)
1554
+ )}`
1555
+ );
1556
+ }
1557
+ return { mutationApplied, error: releaseError, maintenanceError };
1558
+ }
1559
+ if (mutationError !== void 0) {
1560
+ return { mutationApplied, error: mutationError, maintenanceError };
1561
+ }
1562
+ return { value, mutationApplied, maintenanceError };
1563
+ }
1564
+ __name(runWithDaemonWriterLease, "runWithDaemonWriterLease");
1565
+ function logMaintenanceLeaseReleaseFailure(params) {
1566
+ const errorKind = typeof params.error === "object" && params.error !== null && typeof params.error.errorKind === "string" ? params.error.errorKind : "unknown";
1567
+ logSessionArchiveWarning(
1568
+ `session maintenance lease release failed action=${params.action} workspace=${safeLogValue(
1569
+ params.workspace
1570
+ )} session=${safeLogValue(params.sessionId)} errorKind=${safeLogValue(
1571
+ errorKind
1572
+ )} mutationApplied=${params.mutationApplied}`
1573
+ );
1574
+ }
1575
+ __name(logMaintenanceLeaseReleaseFailure, "logMaintenanceLeaseReleaseFailure");
1576
+ async function classifySessionLocation(service, sessionId) {
1577
+ return service.getMaintainableSessionLocation(sessionId);
1578
+ }
1579
+ __name(classifySessionLocation, "classifySessionLocation");
1580
+ function sessionLocationError(sessionId) {
1581
+ const error = new SessionConflictError(sessionId);
1582
+ error.message = `Session "${sessionId}" exists in both active and archived directories. Retry with resolveConflicts: true to keep one copy.`;
1583
+ return error;
1584
+ }
1585
+ __name(sessionLocationError, "sessionLocationError");
1586
+ function updateScheduledTaskForMaintenance(service, sessionId, action, assertCanMutate) {
1587
+ if (action === "archive") {
1588
+ return disableTasksForSessions(service.getProjectRoot(), [sessionId], {
1589
+ assertCanCommit: assertCanMutate
1590
+ });
1591
+ }
1592
+ if (action === "unarchive") {
1593
+ return enableTasksForSessions(
1594
+ service.getProjectRoot(),
1595
+ [sessionId],
1596
+ Date.now(),
1597
+ { assertCanCommit: assertCanMutate }
1598
+ );
1599
+ }
1600
+ return removeTasksForSessions(service.getProjectRoot(), [sessionId], {
1601
+ assertCanCommit: assertCanMutate
1602
+ });
1603
+ }
1604
+ __name(updateScheduledTaskForMaintenance, "updateScheduledTaskForMaintenance");
1605
+ async function deletePersistedSessionWithLease(service, sessionId, assertCanMutate) {
1606
+ const initialLocation = await classifySessionLocation(service, sessionId);
1607
+ if (initialLocation === void 0) {
1608
+ let maintenanceError;
1609
+ try {
1610
+ assertCanMutate?.();
1611
+ await updateScheduledTaskForMaintenance(
1612
+ service,
1613
+ sessionId,
1614
+ "delete",
1615
+ assertCanMutate
1616
+ );
1617
+ } catch (error) {
1618
+ maintenanceError = error;
1619
+ logSessionArchiveWarning(
1620
+ `scheduled task lifecycle update failed action=delete workspace=${safeLogValue(
1621
+ service.getProjectRoot()
1622
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1623
+ errorMessage(error)
1624
+ )}`
1625
+ );
1626
+ }
1627
+ return {
1628
+ kind: "notFound",
1629
+ mutationApplied: false,
1630
+ maintenanceError
1631
+ };
1632
+ }
1633
+ const mutation = await runWithDaemonWriterLease({
1634
+ action: "delete",
1635
+ sessionId,
1636
+ service,
1637
+ mutate: /* @__PURE__ */ __name(async (assertOwnedAndUnchanged) => {
1638
+ const lockedLocation = await classifySessionLocation(service, sessionId);
1639
+ if (lockedLocation === void 0) {
1640
+ return {
1641
+ value: "notFound",
1642
+ mutationApplied: false
1643
+ };
1644
+ }
1645
+ const removed = await service.removeSession(sessionId, {
1646
+ assertStorageUnchanged: assertOwnedAndUnchanged,
1647
+ assertCanMutate
1648
+ });
1649
+ return {
1650
+ value: removed ? "removed" : "notFound",
1651
+ mutationApplied: removed
1652
+ };
1653
+ }, "mutate"),
1654
+ mutationAppliedAfterError: /* @__PURE__ */ __name(async () => await classifySessionLocation(service, sessionId) === void 0, "mutationAppliedAfterError"),
1655
+ afterMutationApplied: /* @__PURE__ */ __name(async () => {
1656
+ assertCanMutate?.();
1657
+ await updateScheduledTaskForMaintenance(
1658
+ service,
1659
+ sessionId,
1660
+ "delete",
1661
+ assertCanMutate
1662
+ );
1663
+ }, "afterMutationApplied")
1664
+ });
1665
+ if (mutation.error !== void 0) {
1666
+ return {
1667
+ kind: "error",
1668
+ error: mutation.error,
1669
+ mutationApplied: mutation.mutationApplied,
1670
+ maintenanceError: mutation.maintenanceError
1671
+ };
1672
+ }
1673
+ return {
1674
+ kind: mutation.value ?? "notFound",
1675
+ mutationApplied: mutation.mutationApplied,
1676
+ maintenanceError: mutation.maintenanceError
1677
+ };
1678
+ }
1679
+ __name(deletePersistedSessionWithLease, "deletePersistedSessionWithLease");
1680
+ async function deleteDaemonSessions(params) {
1681
+ const {
1682
+ sessionIds,
1683
+ service,
1684
+ bridge,
1685
+ coordinator,
1686
+ coordinatorLockHeld = false,
1687
+ assertCanMutate,
1688
+ onError
1689
+ } = params;
1690
+ const uniqueSessionIds = [
1691
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1692
+ ];
1693
+ if (!coordinatorLockHeld) {
1694
+ for (const sessionId of uniqueSessionIds) {
1695
+ coordinator.assertNotTransitioning(sessionId);
1696
+ }
1697
+ }
1698
+ const results = await Promise.all(
1699
+ uniqueSessionIds.map(async (sessionId) => {
1700
+ try {
1701
+ const mutateSession = /* @__PURE__ */ __name(async () => {
1702
+ assertCanMutate?.();
1703
+ const removePersistedSession = /* @__PURE__ */ __name(async () => {
1704
+ const result = await deletePersistedSessionWithLease(
1705
+ service,
1706
+ sessionId,
1707
+ assertCanMutate
1708
+ );
1709
+ if (result.kind === "error") {
1710
+ onError?.({
1711
+ phase: "remove",
1712
+ sessionId,
1713
+ error: errorMessage(result.error)
1714
+ });
1715
+ return result;
1716
+ }
1717
+ try {
1718
+ if (assertCanMutate) {
1719
+ await bridge.deleteSessionAttachments(sessionId, {
1720
+ assertCanCommit: assertCanMutate
1721
+ });
1722
+ } else {
1723
+ await bridge.deleteSessionAttachments(sessionId);
1724
+ }
1725
+ return result;
1726
+ } catch (error) {
1727
+ onError?.({
1728
+ phase: "delete",
1729
+ sessionId,
1730
+ error: errorMessage(error)
1731
+ });
1732
+ return {
1733
+ kind: "error",
1734
+ error,
1735
+ mutationApplied: result.mutationApplied,
1736
+ maintenanceError: result.maintenanceError
1737
+ };
1738
+ }
1739
+ }, "removePersistedSession");
1740
+ try {
1741
+ await bridge.closeSession(sessionId);
1742
+ } catch (error) {
1743
+ if (isSessionNotFoundError(error)) {
1744
+ return await removePersistedSession();
1745
+ }
1746
+ onError?.({
1747
+ phase: "close",
1748
+ sessionId,
1749
+ error: errorMessage(error)
1750
+ });
1751
+ return {
1752
+ kind: "error",
1753
+ error,
1754
+ mutationApplied: false
1755
+ };
1756
+ }
1757
+ return await removePersistedSession();
1758
+ }, "mutateSession");
1759
+ return await (coordinatorLockHeld ? mutateSession() : coordinator.runExclusiveMany([sessionId], mutateSession));
1760
+ } catch (error) {
1761
+ if (error instanceof DaemonDrainingError) {
1762
+ throw error;
1763
+ }
1764
+ onError?.({
1765
+ phase: "delete",
1766
+ sessionId,
1767
+ error: errorMessage(error)
1768
+ });
1769
+ return {
1770
+ kind: "error",
1771
+ error,
1772
+ mutationApplied: false
1773
+ };
1774
+ }
1775
+ })
1776
+ );
1777
+ const removed = [];
1778
+ const notFound = [];
1779
+ const errors = [];
1780
+ for (let i = 0; i < results.length; i++) {
1781
+ const sessionId = uniqueSessionIds[i];
1782
+ const result = results[i];
1783
+ if (result.kind === "removed") {
1784
+ removed.push(sessionId);
1785
+ } else if (result.kind === "notFound") {
1786
+ notFound.push(sessionId);
1787
+ } else {
1788
+ errors.push({ sessionId, error: errorMessage(result.error) });
1789
+ }
1790
+ if (result.maintenanceError !== void 0) {
1791
+ errors.push({
1792
+ sessionId,
1793
+ error: "Scheduled task lifecycle update failed."
1794
+ });
1795
+ }
1796
+ }
1797
+ return { removed, notFound, errors };
1798
+ }
1799
+ __name(deleteDaemonSessions, "deleteDaemonSessions");
1800
+ async function deleteDaemonSessionIfOrphan(params) {
1801
+ const { sessionId, service, bridge, coordinator } = params;
1802
+ coordinator.assertNotTransitioning(sessionId);
1803
+ const result = await coordinator.runExclusiveMany([sessionId], async () => {
1804
+ let killed = false;
1805
+ try {
1806
+ killed = await bridge.killSession(sessionId, {
1807
+ requireZeroAttaches: true
1808
+ });
1809
+ } catch (error) {
1810
+ if (!isSessionNotFoundError(error)) throw error;
1811
+ killed = true;
1812
+ }
1813
+ if (!killed) {
1814
+ return void 0;
1815
+ }
1816
+ return deletePersistedSessionWithLease(service, sessionId);
1817
+ });
1818
+ if (result === void 0) {
1819
+ return false;
1820
+ }
1821
+ if (result.kind === "error") {
1822
+ throw result.error;
1823
+ }
1824
+ bridge.markSessionCatalogChanged();
1825
+ return true;
1826
+ }
1827
+ __name(deleteDaemonSessionIfOrphan, "deleteDaemonSessionIfOrphan");
1828
+ async function assertSessionLoadable(workspaceCwd, sessionId, runtimeBaseDir, options = {}) {
1829
+ const service = new SessionService(workspaceCwd, {
1830
+ runtimeBaseDir
1831
+ });
1832
+ const location = await service.getSessionLocation(sessionId);
1833
+ if (location === "archived") {
1834
+ throw new SessionArchivedError(sessionId);
1835
+ }
1836
+ if (location === "conflict") {
1837
+ if (options.allowActiveConflict) {
1838
+ try {
1839
+ await service.findSessionIdIgnoringCase(sessionId);
1840
+ } catch (error) {
1841
+ if (error instanceof SessionIdCaseConflictError && error.reason === "case_conflict" && error.candidateSessionId === sessionId) {
1842
+ return "active";
1843
+ }
1844
+ if (!(error instanceof SessionIdCaseConflictError)) throw error;
1845
+ }
1846
+ }
1847
+ throw new SessionConflictError(sessionId);
1848
+ }
1849
+ return location;
1850
+ }
1851
+ __name(assertSessionLoadable, "assertSessionLoadable");
1852
+ async function resolveSessionIdForRestore(service, sessionId) {
1853
+ try {
1854
+ return await service.findSessionIdIgnoringCase(sessionId);
1855
+ } catch (error) {
1856
+ if (error instanceof SessionIdCaseConflictError) {
1857
+ if (error.candidateSessionId === sessionId) return sessionId;
1858
+ throw new SessionConflictError(sessionId);
1859
+ }
1860
+ throw error;
1861
+ }
1862
+ }
1863
+ __name(resolveSessionIdForRestore, "resolveSessionIdForRestore");
1864
+ async function assertSessionRestorable(workspaceCwd, sessionId, requestedSessionId, runtimeBaseDir) {
1865
+ const location = await new SessionService(workspaceCwd, {
1866
+ runtimeBaseDir
1867
+ }).getSessionLocation(sessionId);
1868
+ if (location === "archived") {
1869
+ throw new SessionArchivedError(sessionId);
1870
+ }
1871
+ if (location === "conflict") {
1872
+ if (sessionId !== requestedSessionId) {
1873
+ throw new SessionConflictError(requestedSessionId);
1874
+ }
1875
+ return "active";
1876
+ }
1877
+ return location;
1878
+ }
1879
+ __name(assertSessionRestorable, "assertSessionRestorable");
1880
+ async function assertSessionArchived(workspaceCwd, sessionId, runtimeBaseDir) {
1881
+ const location = await new SessionService(workspaceCwd, {
1882
+ runtimeBaseDir
1883
+ }).getSessionLocation(sessionId);
1884
+ if (location === "active") {
1885
+ throw new SessionNotArchivedError(sessionId);
1886
+ }
1887
+ if (location === "conflict") {
1888
+ throw new SessionConflictError(sessionId);
1889
+ }
1890
+ if (location === void 0) {
1891
+ throw new SessionNotFoundError(sessionId);
1892
+ }
1893
+ }
1894
+ __name(assertSessionArchived, "assertSessionArchived");
1895
+ function isSessionNotFoundError(err) {
1896
+ return err instanceof SessionNotFoundError || err instanceof Error && err.name === "SessionNotFoundError";
1897
+ }
1898
+ __name(isSessionNotFoundError, "isSessionNotFoundError");
1899
+ function logSessionArchiveResult(action, result) {
1900
+ const changedLabel = action === "archive" ? "archived" : "unarchived";
1901
+ const alreadyLabel = action === "archive" ? "alreadyArchived" : "alreadyActive";
1902
+ const details = [
1903
+ `requested=${result.requested.length} requestedIds=${formatSessionIds(result.requested)}`,
1904
+ `${changedLabel}=${result.changed.length} ${changedLabel}Ids=${formatSessionIds(result.changed)}`,
1905
+ `${alreadyLabel}=${result.already.length} ${alreadyLabel}Ids=${formatSessionIds(result.already)}`,
1906
+ `notFound=${result.notFound.length} notFoundIds=${formatSessionIds(result.notFound)}`,
1907
+ `errors=${result.errors.length} errorIds=${formatSessionErrors(result.errors)}`
1908
+ ].join(" ");
1909
+ writeStderrLine(`qwen serve: sessions ${action} result ${details}`);
1910
+ }
1911
+ __name(logSessionArchiveResult, "logSessionArchiveResult");
1912
+ function formatSessionIds(sessionIds) {
1913
+ return `[${sessionIds.map((sessionId) => safeLogValue(sessionId)).join(",")}]`;
1914
+ }
1915
+ __name(formatSessionIds, "formatSessionIds");
1916
+ function formatSessionErrors(errors) {
1917
+ return `[${errors.map(
1918
+ ({ sessionId, error }) => `${safeLogValue(sessionId)}:${safeLogValue(errorMessage(error))}`
1919
+ ).join(",")}]`;
1920
+ }
1921
+ __name(formatSessionErrors, "formatSessionErrors");
1922
+ function errorMessage(error) {
1923
+ return error instanceof Error ? error.message : String(error);
1924
+ }
1925
+ __name(errorMessage, "errorMessage");
1926
+ function logSessionArchiveWarning(message) {
1927
+ writeStderrLine(`qwen serve: ${sanitizeLogLine(message)}`);
1928
+ }
1929
+ __name(logSessionArchiveWarning, "logSessionArchiveWarning");
1930
+ var LOG_LINE_UNSAFE_RE = /[\x00-\x1f\x7f-\x9f\u200b-\u200f\u2028-\u202e\u2066-\u2069\ufeff]/g;
1931
+ function sanitizeLogLine(message) {
1932
+ return message.replace(LOG_LINE_UNSAFE_RE, " ").slice(0, 4096);
1933
+ }
1934
+ __name(sanitizeLogLine, "sanitizeLogLine");
1935
+ async function archiveDaemonSessions(params) {
1936
+ const {
1937
+ sessionIds,
1938
+ service,
1939
+ bridge,
1940
+ coordinator,
1941
+ coordinatorLockHeld = false,
1942
+ resolveConflicts = false,
1943
+ assertCanMutate
1944
+ } = params;
1945
+ const uniqueSessionIds = [
1946
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
1947
+ ];
1948
+ if (!coordinatorLockHeld) {
1949
+ for (const sessionId of uniqueSessionIds) {
1950
+ coordinator.assertNotTransitioning(sessionId);
1951
+ }
1952
+ }
1953
+ const results = await Promise.all(
1954
+ uniqueSessionIds.map(async (sessionId) => {
1955
+ try {
1956
+ const mutateSession = /* @__PURE__ */ __name(async () => {
1957
+ assertCanMutate?.();
1958
+ try {
1959
+ await bridge.closeSession(sessionId, void 0, {
1960
+ requireAgentClose: true
1961
+ });
1962
+ } catch (error) {
1963
+ if (!isSessionNotFoundError(error)) {
1964
+ return {
1965
+ kind: "error",
1966
+ error,
1967
+ mutationApplied: false
1968
+ };
1969
+ }
1970
+ }
1971
+ const initialLocation = await classifySessionLocation(
1972
+ service,
1973
+ sessionId
1974
+ );
1975
+ if (initialLocation === void 0) {
1976
+ return { kind: "notFound", mutationApplied: false };
1977
+ }
1978
+ if (initialLocation === "archived") {
1979
+ let maintenanceError;
1980
+ try {
1981
+ await updateScheduledTaskForMaintenance(
1982
+ service,
1983
+ sessionId,
1984
+ "archive",
1985
+ assertCanMutate
1986
+ );
1987
+ } catch (error) {
1988
+ maintenanceError = error;
1989
+ logSessionArchiveWarning(
1990
+ `scheduled task lifecycle update failed action=archive workspace=${safeLogValue(
1991
+ service.getProjectRoot()
1992
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
1993
+ errorMessage(error)
1994
+ )}`
1995
+ );
1996
+ }
1997
+ return {
1998
+ kind: "alreadyArchived",
1999
+ mutationApplied: false,
2000
+ maintenanceError
2001
+ };
2002
+ }
2003
+ if (initialLocation === "conflict" && !resolveConflicts) {
2004
+ return {
2005
+ kind: "error",
2006
+ error: sessionLocationError(sessionId),
2007
+ mutationApplied: false
2008
+ };
2009
+ }
2010
+ const mutation = await runWithDaemonWriterLease({
2011
+ action: "archive",
2012
+ sessionId,
2013
+ service,
2014
+ mutate: /* @__PURE__ */ __name(async (assertOwnedAndUnchanged) => {
2015
+ const lockedLocation = await classifySessionLocation(
2016
+ service,
2017
+ sessionId
2018
+ );
2019
+ if (lockedLocation === void 0) {
2020
+ return {
2021
+ value: "notFound",
2022
+ mutationApplied: false
2023
+ };
2024
+ }
2025
+ if (lockedLocation === "archived") {
2026
+ return {
2027
+ value: "alreadyArchived",
2028
+ mutationApplied: false
2029
+ };
2030
+ }
2031
+ if (lockedLocation === "conflict" && !resolveConflicts) {
2032
+ throw sessionLocationError(sessionId);
2033
+ }
2034
+ const result = await service.archiveSessions([sessionId], {
2035
+ resolveConflicts,
2036
+ assertStorageUnchanged: assertOwnedAndUnchanged,
2037
+ assertCanMutate
2038
+ });
2039
+ if (result.errors[0]) throw result.errors[0].error;
2040
+ if (result.archived.length > 0) {
2041
+ return {
2042
+ value: result.resolvedConflicts.length ? "resolvedConflict" : "archived",
2043
+ mutationApplied: true
2044
+ };
2045
+ }
2046
+ return {
2047
+ value: result.alreadyArchived.length > 0 ? "alreadyArchived" : "notFound",
2048
+ mutationApplied: false
2049
+ };
2050
+ }, "mutate"),
2051
+ mutationAppliedAfterError: /* @__PURE__ */ __name(async () => await classifySessionLocation(service, sessionId) === "archived", "mutationAppliedAfterError"),
2052
+ afterMutationApplied: /* @__PURE__ */ __name(async () => {
2053
+ assertCanMutate?.();
2054
+ await updateScheduledTaskForMaintenance(
2055
+ service,
2056
+ sessionId,
2057
+ "archive",
2058
+ assertCanMutate
2059
+ );
2060
+ }, "afterMutationApplied")
2061
+ });
2062
+ if (mutation.error !== void 0) {
2063
+ return {
2064
+ kind: "error",
2065
+ error: mutation.error,
2066
+ mutationApplied: mutation.mutationApplied,
2067
+ maintenanceError: mutation.maintenanceError
2068
+ };
2069
+ }
2070
+ return {
2071
+ kind: mutation.value ?? "notFound",
2072
+ mutationApplied: mutation.mutationApplied,
2073
+ maintenanceError: mutation.maintenanceError
2074
+ };
2075
+ }, "mutateSession");
2076
+ return await (coordinatorLockHeld ? mutateSession() : coordinator.runExclusiveMany([sessionId], mutateSession));
2077
+ } catch (error) {
2078
+ if (error instanceof DaemonDrainingError) {
2079
+ throw error;
2080
+ }
2081
+ return {
2082
+ kind: "error",
2083
+ error,
2084
+ mutationApplied: false,
2085
+ maintenanceError: void 0
2086
+ };
2087
+ }
2088
+ })
2089
+ );
2090
+ const archived = [];
2091
+ const alreadyArchived = [];
2092
+ const resolvedConflicts = [];
2093
+ const notFound = [];
2094
+ const errors = [];
2095
+ for (let i = 0; i < results.length; i++) {
2096
+ const sessionId = uniqueSessionIds[i];
2097
+ const result = results[i];
2098
+ if (result.kind === "archived") archived.push(sessionId);
2099
+ else if (result.kind === "resolvedConflict") {
2100
+ archived.push(sessionId);
2101
+ resolvedConflicts.push(sessionId);
2102
+ } else if (result.kind === "alreadyArchived") {
2103
+ alreadyArchived.push(sessionId);
2104
+ } else if (result.kind === "notFound") notFound.push(sessionId);
2105
+ else errors.push({ sessionId, error: result.error });
2106
+ if ("maintenanceError" in result && result.maintenanceError !== void 0) {
2107
+ errors.push({ sessionId, error: result.maintenanceError });
2108
+ }
2109
+ }
2110
+ logSessionArchiveResult("archive", {
2111
+ requested: uniqueSessionIds,
2112
+ changed: archived,
2113
+ already: alreadyArchived,
2114
+ notFound,
2115
+ errors
2116
+ });
2117
+ return {
2118
+ archived,
2119
+ alreadyArchived,
2120
+ resolvedConflicts,
2121
+ notFound,
2122
+ errors
2123
+ };
2124
+ }
2125
+ __name(archiveDaemonSessions, "archiveDaemonSessions");
2126
+ async function unarchiveDaemonSessions(params) {
2127
+ const {
2128
+ sessionIds,
2129
+ service,
2130
+ coordinator,
2131
+ coordinatorLockHeld = false,
2132
+ resolveConflicts = false,
2133
+ assertCanMutate
2134
+ } = params;
2135
+ const uniqueSessionIds = [
2136
+ ...new Set(sessionIds.map(normalizeSessionIdForLookup))
2137
+ ];
2138
+ if (!coordinatorLockHeld) {
2139
+ for (const sessionId of uniqueSessionIds) {
2140
+ coordinator.assertNotTransitioning(sessionId);
2141
+ }
2142
+ }
2143
+ const results = await Promise.all(
2144
+ uniqueSessionIds.map(async (sessionId) => {
2145
+ try {
2146
+ const mutateSession = /* @__PURE__ */ __name(async () => {
2147
+ assertCanMutate?.();
2148
+ const initialLocation = await classifySessionLocation(
2149
+ service,
2150
+ sessionId
2151
+ );
2152
+ if (initialLocation === void 0) {
2153
+ return { kind: "notFound", mutationApplied: false };
2154
+ }
2155
+ if (initialLocation === "active") {
2156
+ let maintenanceError;
2157
+ try {
2158
+ await updateScheduledTaskForMaintenance(
2159
+ service,
2160
+ sessionId,
2161
+ "unarchive",
2162
+ assertCanMutate
2163
+ );
2164
+ } catch (error) {
2165
+ maintenanceError = error;
2166
+ logSessionArchiveWarning(
2167
+ `scheduled task lifecycle update failed action=unarchive workspace=${safeLogValue(
2168
+ service.getProjectRoot()
2169
+ )} session=${safeLogValue(sessionId)} error=${safeLogValue(
2170
+ errorMessage(error)
2171
+ )}`
2172
+ );
2173
+ }
2174
+ return {
2175
+ kind: "alreadyActive",
2176
+ mutationApplied: false,
2177
+ maintenanceError
2178
+ };
2179
+ }
2180
+ if (initialLocation === "conflict" && !resolveConflicts) {
2181
+ return {
2182
+ kind: "error",
2183
+ error: sessionLocationError(sessionId),
2184
+ mutationApplied: false
2185
+ };
2186
+ }
2187
+ const mutation = await runWithDaemonWriterLease({
2188
+ action: "unarchive",
2189
+ sessionId,
2190
+ service,
2191
+ mutate: /* @__PURE__ */ __name(async (assertOwnedAndUnchanged) => {
2192
+ const lockedLocation = await classifySessionLocation(
2193
+ service,
2194
+ sessionId
2195
+ );
2196
+ if (lockedLocation === void 0) {
2197
+ return {
2198
+ value: "notFound",
2199
+ mutationApplied: false
2200
+ };
2201
+ }
2202
+ if (lockedLocation === "active") {
2203
+ return {
2204
+ value: "alreadyActive",
2205
+ mutationApplied: false
2206
+ };
2207
+ }
2208
+ if (lockedLocation === "conflict" && !resolveConflicts) {
2209
+ throw sessionLocationError(sessionId);
2210
+ }
2211
+ const result = await service.unarchiveSessions([sessionId], {
2212
+ resolveConflicts,
2213
+ assertStorageUnchanged: assertOwnedAndUnchanged,
2214
+ assertCanMutate
2215
+ });
2216
+ if (result.errors[0]) throw result.errors[0].error;
2217
+ if (result.unarchived.length > 0) {
2218
+ return {
2219
+ value: result.resolvedConflicts.length ? "resolvedConflict" : "unarchived",
2220
+ mutationApplied: true
2221
+ };
2222
+ }
2223
+ return {
2224
+ value: result.alreadyActive.length > 0 ? "alreadyActive" : "notFound",
2225
+ mutationApplied: false
2226
+ };
2227
+ }, "mutate"),
2228
+ mutationAppliedAfterError: /* @__PURE__ */ __name(async () => await classifySessionLocation(service, sessionId) === "active", "mutationAppliedAfterError"),
2229
+ afterMutationApplied: /* @__PURE__ */ __name(async () => {
2230
+ assertCanMutate?.();
2231
+ await updateScheduledTaskForMaintenance(
2232
+ service,
2233
+ sessionId,
2234
+ "unarchive",
2235
+ assertCanMutate
2236
+ );
2237
+ }, "afterMutationApplied")
2238
+ });
2239
+ if (mutation.error !== void 0) {
2240
+ return {
2241
+ kind: "error",
2242
+ error: mutation.error,
2243
+ mutationApplied: mutation.mutationApplied,
2244
+ maintenanceError: mutation.maintenanceError
2245
+ };
2246
+ }
2247
+ return {
2248
+ kind: mutation.value ?? "notFound",
2249
+ mutationApplied: mutation.mutationApplied,
2250
+ maintenanceError: mutation.maintenanceError
2251
+ };
2252
+ }, "mutateSession");
2253
+ return await (coordinatorLockHeld ? mutateSession() : coordinator.runExclusiveMany([sessionId], mutateSession));
2254
+ } catch (error) {
2255
+ if (error instanceof DaemonDrainingError) {
2256
+ throw error;
2257
+ }
2258
+ return {
2259
+ kind: "error",
2260
+ error,
2261
+ mutationApplied: false,
2262
+ maintenanceError: void 0
2263
+ };
2264
+ }
2265
+ })
2266
+ );
2267
+ const unarchived = [];
2268
+ const alreadyActive = [];
2269
+ const resolvedConflicts = [];
2270
+ const notFound = [];
2271
+ const errors = [];
2272
+ for (let i = 0; i < results.length; i++) {
2273
+ const sessionId = uniqueSessionIds[i];
2274
+ const result = results[i];
2275
+ if (result.kind === "unarchived") unarchived.push(sessionId);
2276
+ else if (result.kind === "resolvedConflict") {
2277
+ unarchived.push(sessionId);
2278
+ resolvedConflicts.push(sessionId);
2279
+ } else if (result.kind === "alreadyActive") alreadyActive.push(sessionId);
2280
+ else if (result.kind === "notFound") notFound.push(sessionId);
2281
+ else errors.push({ sessionId, error: result.error });
2282
+ if (result.maintenanceError !== void 0) {
2283
+ errors.push({ sessionId, error: result.maintenanceError });
2284
+ }
2285
+ }
2286
+ logSessionArchiveResult("unarchive", {
2287
+ requested: uniqueSessionIds,
2288
+ changed: unarchived,
2289
+ already: alreadyActive,
2290
+ notFound,
2291
+ errors
2292
+ });
2293
+ return {
2294
+ unarchived,
2295
+ alreadyActive,
2296
+ resolvedConflicts,
2297
+ notFound,
2298
+ errors
2299
+ };
2300
+ }
2301
+ __name(unarchiveDaemonSessions, "unarchiveDaemonSessions");
2302
+
2303
+ // packages/cli/src/serve/server/aone-mrs.ts
2304
+ init_esbuild_shims();
2305
+ import { execFile } from "node:child_process";
2306
+ import { promisify } from "node:util";
2307
+ var execFileAsync = promisify(execFile);
2308
+ var a1AvailabilityVerified = false;
2309
+ var defaultA1Exec = /* @__PURE__ */ __name(async (args, options) => {
2310
+ const { stdout } = await execFileAsync("a1", [...args], {
2311
+ ...options,
2312
+ encoding: "utf8",
2313
+ windowsHide: true
2314
+ // No env override: a1 authenticates through its own `a1 auth login`
2315
+ // config (review precedent); there is no A1_* token convention.
2316
+ });
2317
+ return { stdout };
2318
+ }, "defaultA1Exec");
2319
+ var a1Exec = defaultA1Exec;
2320
+ var A1_TIMEOUT_MS = 2e4;
2321
+ var A1_MAX_BUFFER = 16 * 1024 * 1024;
2322
+ var GIT_ORIGIN_TIMEOUT_MS = 5e3;
2323
+ var A1_VERSION_TIMEOUT_MS = 1e4;
2324
+ var A1_ERROR_MESSAGE_MAX = 512;
2325
+ var AONE_DETAIL_URL_HOST = "code.alibaba-inc.com";
2326
+ var AONE_MR_LIST_PAGE_SIZE = 20;
2327
+ var AONE_BACKFILL_PAGES_PER_STATE = 3;
2328
+ var AONE_MAX_MR_VIEW_CALLS_PER_RUN = 25;
2329
+ var AoneCliUnavailableError = class extends Error {
2330
+ static {
2331
+ __name(this, "AoneCliUnavailableError");
2332
+ }
2333
+ };
2334
+ var AoneCommandError = class extends Error {
2335
+ static {
2336
+ __name(this, "AoneCommandError");
2337
+ }
2338
+ };
2339
+ function mapAoneMrState(raw) {
2340
+ switch (raw?.toLowerCase()) {
2341
+ case "merged":
2342
+ return "merged";
2343
+ case "closed":
2344
+ return "closed";
2345
+ default:
2346
+ return "open";
2347
+ }
2348
+ }
2349
+ __name(mapAoneMrState, "mapAoneMrState");
2350
+ async function resolveAoneWorkspaceRepo(workspaceCwd, env) {
2351
+ const gitRoot = findGitRoot(workspaceCwd);
2352
+ if (!gitRoot) return void 0;
2353
+ let origin;
2354
+ try {
2355
+ ({ stdout: origin } = await execFileAsync(
2356
+ "git",
2357
+ ["remote", "get-url", "origin"],
2358
+ {
2359
+ cwd: gitRoot,
2360
+ timeout: GIT_ORIGIN_TIMEOUT_MS,
2361
+ encoding: "utf8",
2362
+ windowsHide: true,
2363
+ // Same sanitization as every sibling git spawn in these paths —
2364
+ // an inherited GIT_DIR/GIT_CONFIG_* would resolve origin against
2365
+ // a different repository despite the cwd.
2366
+ env: gitEnv(env)
2367
+ }
2368
+ ));
2369
+ } catch {
2370
+ return void 0;
2371
+ }
2372
+ const identity = parseRemoteUrl(origin.trim());
2373
+ if (!identity || !isAoneCanonicalHost(identity.host)) return void 0;
2374
+ return { gitRoot, repoPath: identity.groupPath };
2375
+ }
2376
+ __name(resolveAoneWorkspaceRepo, "resolveAoneWorkspaceRepo");
2377
+ function isAoneDetailUrlForRepo(repoPath, number, url) {
2378
+ return canonicalSessionPrUrl(url) === canonicalSessionPrUrl(
2379
+ `https://${AONE_DETAIL_URL_HOST}/${repoPath}/codereview/${number}`
2380
+ );
2381
+ }
2382
+ __name(isAoneDetailUrlForRepo, "isAoneDetailUrlForRepo");
2383
+ function isA1ErrorObject(value) {
2384
+ return typeof value === "object" && value !== null && value["schemaVersion"] === "a1.error/v1";
2385
+ }
2386
+ __name(isA1ErrorObject, "isA1ErrorObject");
2387
+ function a1ErrorMessage(error) {
2388
+ if (error?.killed === true) {
2389
+ return `a1 timed out after ${A1_TIMEOUT_MS / 1e3}s`;
2390
+ }
2391
+ const stderr = error?.stderr;
2392
+ const raw = typeof stderr === "string" && stderr.trim() ? stderr : error instanceof Error ? error.message : String(error);
2393
+ return raw.replace(/\s+/g, " ").trim().slice(0, A1_ERROR_MESSAGE_MAX);
2394
+ }
2395
+ __name(a1ErrorMessage, "a1ErrorMessage");
2396
+ function assertA1Version(stdout) {
2397
+ const triple = parseA1Version(stdout);
2398
+ const floor = parseA1Version(A1_MIN_VERSION);
2399
+ if (triple && floor && !a1VersionAtLeast(triple, floor)) {
2400
+ throw new AoneCliUnavailableError(
2401
+ `a1 ${A1_MIN_VERSION}+ is required (found ${stdout.trim().split("\n")[0]}); upgrade from https://code.alibaba-inc.com/aone/a1`
2402
+ );
2403
+ }
2404
+ }
2405
+ __name(assertA1Version, "assertA1Version");
2406
+ async function runA1Json(args) {
2407
+ let stdout;
2408
+ try {
2409
+ ({ stdout } = await a1Exec([...args, "--format", "json"], {
2410
+ timeout: A1_TIMEOUT_MS,
2411
+ maxBuffer: A1_MAX_BUFFER
2412
+ }));
2413
+ } catch (error) {
2414
+ if (error.code === "ENOENT") {
2415
+ throw new AoneCliUnavailableError(
2416
+ "a1 CLI not installed; install it and run `a1 auth login`"
2417
+ );
2418
+ }
2419
+ const errorStdout = error?.stdout;
2420
+ if (typeof errorStdout === "string" && errorStdout.trim()) {
2421
+ try {
2422
+ const parsed2 = JSON.parse(errorStdout);
2423
+ if (isA1ErrorObject(parsed2)) {
2424
+ throw new AoneCommandError(parsed2.message || "a1 command failed");
2425
+ }
2426
+ } catch (parseError) {
2427
+ if (parseError instanceof AoneCommandError) throw parseError;
2428
+ }
2429
+ }
2430
+ throw new AoneCommandError(a1ErrorMessage(error));
2431
+ }
2432
+ let parsed;
2433
+ try {
2434
+ parsed = JSON.parse(stdout);
2435
+ } catch {
2436
+ throw new AoneCommandError("a1 returned non-JSON output");
2437
+ }
2438
+ if (isA1ErrorObject(parsed)) {
2439
+ throw new AoneCommandError(parsed.message || "a1 command failed");
2440
+ }
2441
+ return parsed;
2442
+ }
2443
+ __name(runA1Json, "runA1Json");
2444
+ async function checkA1Available() {
2445
+ if (a1AvailabilityVerified) return;
2446
+ let stdout;
2447
+ try {
2448
+ ({ stdout } = await a1Exec(["--version"], {
2449
+ timeout: A1_VERSION_TIMEOUT_MS
2450
+ }));
2451
+ } catch (error) {
2452
+ if (error.code === "ENOENT") {
2453
+ throw new AoneCliUnavailableError(
2454
+ "a1 CLI not installed; install it and run `a1 auth login`"
2455
+ );
2456
+ }
2457
+ return;
2458
+ }
2459
+ assertA1Version(stdout);
2460
+ a1AvailabilityVerified = true;
2461
+ }
2462
+ __name(checkA1Available, "checkA1Available");
2463
+ function parseAoneMrListPage(raw) {
2464
+ if (!Array.isArray(raw)) {
2465
+ throw new AoneCommandError("unexpected a1 mr list output");
2466
+ }
2467
+ const entries = [];
2468
+ for (const item of raw) {
2469
+ if (item === null || typeof item !== "object") continue;
2470
+ const v = item;
2471
+ if (typeof v["id"] !== "number" || !Number.isInteger(v["id"]) || v["id"] <= 0) {
2472
+ continue;
2473
+ }
2474
+ entries.push({
2475
+ number: v["id"],
2476
+ headRefName: typeof v["sourceBranch"] === "string" ? v["sourceBranch"] : "",
2477
+ state: mapAoneMrState(
2478
+ typeof v["state"] === "string" ? v["state"] : void 0
2479
+ )
2480
+ });
2481
+ }
2482
+ return entries;
2483
+ }
2484
+ __name(parseAoneMrListPage, "parseAoneMrListPage");
2485
+ async function listAoneMergeRequests(repoPath, options) {
2486
+ await checkA1Available();
2487
+ const entries = [];
2488
+ const pages = Math.max(options.pages, 1);
2489
+ for (let page = 1; page <= pages; page++) {
2490
+ const parsed = await runA1Json([
2491
+ "repo",
2492
+ "mr",
2493
+ "list",
2494
+ "--repo",
2495
+ repoPath,
2496
+ "--state",
2497
+ options.state,
2498
+ "--page",
2499
+ String(page)
2500
+ ]);
2501
+ const pageEntries = parseAoneMrListPage(parsed);
2502
+ entries.push(...pageEntries);
2503
+ if (Array.isArray(parsed) && parsed.length < AONE_MR_LIST_PAGE_SIZE) {
2504
+ break;
2505
+ }
2506
+ }
2507
+ return entries;
2508
+ }
2509
+ __name(listAoneMergeRequests, "listAoneMergeRequests");
2510
+ function hasControlCharacter(value) {
2511
+ return Array.from(value).some((character) => {
2512
+ const code = character.charCodeAt(0);
2513
+ return code <= 31 || code === 127;
2514
+ });
2515
+ }
2516
+ __name(hasControlCharacter, "hasControlCharacter");
2517
+ function parseAoneMrView(raw, id) {
2518
+ const mr = raw !== null && typeof raw === "object" ? raw["mergeRequest"] : void 0;
2519
+ if (mr === null || typeof mr !== "object") {
2520
+ throw new AoneCommandError("unexpected a1 mr view output");
2521
+ }
2522
+ const v = mr;
2523
+ const url = typeof v["detailUrl"] === "string" ? v["detailUrl"] : "";
2524
+ if (!/^https?:\/\//i.test(url)) {
2525
+ throw new AoneCommandError("a1 mr view returned no detailUrl");
2526
+ }
2527
+ if (url.length > SESSION_PR_URL_MAX_LENGTH) {
2528
+ throw new AoneCommandError("a1 mr view returned an oversized detailUrl");
2529
+ }
2530
+ if (hasControlCharacter(url)) {
2531
+ throw new AoneCommandError("a1 mr view returned a malformed detailUrl");
2532
+ }
2533
+ return {
2534
+ number: id,
2535
+ url,
2536
+ state: mapAoneMrState(
2537
+ typeof v["state"] === "string" ? v["state"] : void 0
2538
+ )
2539
+ };
2540
+ }
2541
+ __name(parseAoneMrView, "parseAoneMrView");
2542
+ async function viewAoneMergeRequest(repoPath, id) {
2543
+ await checkA1Available();
2544
+ const parsed = await runA1Json([
2545
+ "repo",
2546
+ "mr",
2547
+ "view",
2548
+ String(id),
2549
+ "--repo",
2550
+ repoPath
2551
+ ]);
2552
+ return parseAoneMrView(parsed, id);
2553
+ }
2554
+ __name(viewAoneMergeRequest, "viewAoneMergeRequest");
2555
+ var defaultAoneMrBackend = {
2556
+ list: /* @__PURE__ */ __name((repoPath, state, pages) => listAoneMergeRequests(repoPath, { state, pages }), "list"),
2557
+ view: viewAoneMergeRequest
2558
+ };
2559
+
2560
+ export {
2561
+ createSessionOrganizationService,
2562
+ laterActivityTimestamp,
2563
+ invalidateWorkspaceSessionListCache,
2564
+ InvalidCursorError,
2565
+ listWorkspaceSessionsForResponse,
2566
+ listLiveWorkspaceSessionsForResponse,
2567
+ getWorkspaceSessionInfoForResponse,
2568
+ parseSessionPageSizeQuery,
2569
+ runWithWorkspaceRuntimeStorage,
2570
+ createWorkspaceRuntimeSessionService,
2571
+ DaemonDrainingError,
2572
+ SessionArchiveCoordinator,
2573
+ deleteDaemonSessions,
2574
+ deleteDaemonSessionIfOrphan,
2575
+ assertSessionLoadable,
2576
+ resolveSessionIdForRestore,
2577
+ assertSessionRestorable,
2578
+ assertSessionArchived,
2579
+ logSessionArchiveWarning,
2580
+ archiveDaemonSessions,
2581
+ unarchiveDaemonSessions,
2582
+ AONE_BACKFILL_PAGES_PER_STATE,
2583
+ AONE_MAX_MR_VIEW_CALLS_PER_RUN,
2584
+ resolveAoneWorkspaceRepo,
2585
+ isAoneDetailUrlForRepo,
2586
+ defaultAoneMrBackend
2587
+ };
2588
+ /**
2589
+ * @license
2590
+ * Copyright 2025 Qwen Team
2591
+ * SPDX-License-Identifier: Apache-2.0
2592
+ */
2593
+ /**
2594
+ * @license
2595
+ * Copyright 2026 Qwen Team
2596
+ * SPDX-License-Identifier: Apache-2.0
2597
+ */