@qwen-code/qwen-code 0.19.3 → 0.19.4-nightly.20260702.46814e4f1

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 (308) hide show
  1. package/bundled/loop/SKILL.md +22 -3
  2. package/bundled/loop/SKILL.test.ts +20 -0
  3. package/bundled/loop/autonomous-loop.test.ts +59 -0
  4. package/bundled/loop/autonomous-loop.ts +102 -0
  5. package/bundled/loop/loop-task-file.test.ts +1064 -0
  6. package/bundled/loop/loop-task-file.ts +404 -0
  7. package/bundled/loop/loop-tick-resolver.test.ts +906 -0
  8. package/bundled/loop/loop-tick-resolver.ts +416 -0
  9. package/bundled/qc-helper/SKILL.md +12 -5
  10. package/bundled/qc-helper/docs/configuration/auth.md +1 -1
  11. package/bundled/qc-helper/docs/configuration/settings.md +62 -32
  12. package/bundled/qc-helper/docs/features/approval-mode.md +3 -0
  13. package/bundled/qc-helper/docs/features/auto-mode.md +40 -0
  14. package/bundled/qc-helper/docs/features/channels/overview.md +81 -18
  15. package/bundled/qc-helper/docs/features/channels/plugins.md +1 -1
  16. package/bundled/qc-helper/docs/features/code-review.md +17 -61
  17. package/bundled/qc-helper/docs/features/commands.md +42 -40
  18. package/bundled/qc-helper/docs/features/headless.md +19 -18
  19. package/bundled/qc-helper/docs/features/hooks.md +6 -1
  20. package/bundled/qc-helper/docs/features/mcp.md +3 -1
  21. package/bundled/qc-helper/docs/features/memory.md +1 -1
  22. package/bundled/qc-helper/docs/features/scheduled-tasks.md +10 -0
  23. package/bundled/qc-helper/docs/features/status-line.md +3 -3
  24. package/bundled/qc-helper/docs/ide-integration/ide-integration.md +4 -4
  25. package/bundled/qc-helper/docs/qwen-serve.md +53 -0
  26. package/bundled/qc-helper/docs/support/troubleshooting.md +11 -0
  27. package/bundled/review/DESIGN.md +21 -26
  28. package/bundled/review/SKILL.md +45 -129
  29. package/chunks/MaxSizedBox-GHGRQ2OS.js +69 -0
  30. package/chunks/{StandaloneSessionPicker-Z52JTYST.js → StandaloneSessionPicker-G7YTTM27.js} +49 -42
  31. package/chunks/{acpAgent-7RZUOWOM.js → acpAgent-SDOILBSU.js} +1325 -365
  32. package/chunks/{agent-4FG7WTHJ.js → agent-NTSXGV4L.js} +31 -25
  33. package/chunks/agent-headless-WYURMSAB.js +62 -0
  34. package/chunks/{anthropicContentGenerator-PFITVL7Y.js → anthropicContentGenerator-WL3LJOUB.js} +110 -31
  35. package/chunks/{artifact-tool-D2X7G3C3.js → artifact-tool-W76WC2JX.js} +3 -3
  36. package/chunks/{askUserQuestion-UGETICJQ.js → askUserQuestion-J3P6TH3V.js} +2 -2
  37. package/chunks/bridge-AMOL4W4P.js +73 -0
  38. package/chunks/{ca-IUFWESZL.js → ca-HCMB2I54.js} +10 -9
  39. package/chunks/channel-worker-supervisor-C3IB63V7.js +659 -0
  40. package/chunks/{chunk-STUWFKGD.js → chunk-26JIREA5.js} +466 -543
  41. package/chunks/{chunk-SLNKLLEO.js → chunk-2MRV62AU.js} +37 -8
  42. package/chunks/{chunk-ODLIHNOY.js → chunk-2U4HUMOL.js} +1 -1
  43. package/chunks/{chunk-CKQA6AWF.js → chunk-4D73HUOP.js} +1 -1
  44. package/chunks/{chunk-M2U5NM24.js → chunk-54YZOP7P.js} +309 -72
  45. package/chunks/{chunk-J7FA27RO.js → chunk-5LKL3PAU.js} +3 -3
  46. package/chunks/chunk-5P5XGNYH.js +93 -0
  47. package/chunks/{chunk-UFLGERMB.js → chunk-6JE32BRB.js} +178 -124
  48. package/chunks/{chunk-FKAVULLM.js → chunk-75AVTQJ2.js} +74 -10
  49. package/chunks/{chunk-I2LYBGNI.js → chunk-7IOMIYOE.js} +1 -1
  50. package/chunks/{chunk-4LUZAKMK.js → chunk-7KXAGQJ2.js} +1 -1
  51. package/chunks/{chunk-BXSHL2SF.js → chunk-7LUOQJ3D.js} +1 -1
  52. package/chunks/{chunk-YAINVQ3Q.js → chunk-A5OPLHFM.js} +18693 -17055
  53. package/chunks/chunk-AHNXYU4O.js +24 -0
  54. package/chunks/{chunk-UX4SGCGN.js → chunk-AVQDCKNF.js} +96 -22
  55. package/chunks/{chunk-HYCC3XM3.js → chunk-B236XPGF.js} +1 -1
  56. package/chunks/chunk-B6SZLQAZ.js +3523 -0
  57. package/chunks/{chunk-5DWXLGOM.js → chunk-BJBWRCSK.js} +1 -1
  58. package/chunks/chunk-BPFJQGY7.js +193 -0
  59. package/chunks/{chunk-SKQZZVAV.js → chunk-BZHLWC6T.js} +2 -2
  60. package/chunks/{chunk-U3KSMM7G.js → chunk-D5KISTLW.js} +339 -383
  61. package/chunks/{chunk-GT2FGICD.js → chunk-DE7YXUR7.js} +1 -1
  62. package/chunks/{chunk-BUUQ5HPX.js → chunk-DG573EOO.js} +1 -1
  63. package/chunks/{chunk-VVLOGDB6.js → chunk-DX3TKXNT.js} +2 -2
  64. package/chunks/chunk-E5A7LHNN.js +51 -0
  65. package/chunks/{chunk-3PJXIDKI.js → chunk-E6US47KI.js} +3 -27
  66. package/chunks/{chunk-QBZ22PQX.js → chunk-EWALXUAD.js} +3 -1
  67. package/chunks/{chunk-PDE7CSDS.js → chunk-FXKI7OW6.js} +2 -2
  68. package/chunks/{chunk-F3ZYSEY6.js → chunk-FY4TT4L4.js} +3 -3
  69. package/chunks/{chunk-QLDPRILK.js → chunk-G7OQ3RFJ.js} +3 -3
  70. package/chunks/{chunk-R2BXK7SX.js → chunk-GHOTR7HL.js} +6 -1
  71. package/chunks/{chunk-KMGMKW5Q.js → chunk-GLPV75ES.js} +9 -3
  72. package/chunks/{chunk-LD2XBG6Z.js → chunk-GO6LNQXT.js} +1 -39
  73. package/chunks/{chunk-CNLEDYE3.js → chunk-H6TNLOLM.js} +5 -5
  74. package/chunks/{chunk-JVHEVCAU.js → chunk-HLW4EGKR.js} +31 -6
  75. package/chunks/{chunk-I4H7PRWQ.js → chunk-HTWHAN44.js} +1 -1
  76. package/chunks/{chunk-QE6KJYLT.js → chunk-IPYE5BIS.js} +123 -25
  77. package/chunks/{chunk-EJYJYJZ2.js → chunk-IRJWHZWU.js} +3 -70
  78. package/chunks/{chunk-EDMZZFDU.js → chunk-J3YPTTNL.js} +930 -798
  79. package/chunks/{chunk-GGBIN5K7.js → chunk-JGAJMIJZ.js} +1 -1
  80. package/chunks/{chunk-N4EJFBN5.js → chunk-JVLP5US5.js} +427 -263
  81. package/chunks/{chunk-R5OP2ATH.js → chunk-JZG7VB6C.js} +11 -11
  82. package/chunks/{chunk-QI7GOGJR.js → chunk-KKQWC6WS.js} +1 -1
  83. package/chunks/{chunk-ADCIHOQZ.js → chunk-KX5QZRW2.js} +142 -30
  84. package/chunks/{chunk-SBBN4BWR.js → chunk-L7OJ3ZO3.js} +1 -1
  85. package/chunks/{chunk-NDOC6M5S.js → chunk-L7QPM2YD.js} +2 -2
  86. package/chunks/{chunk-BVSVIN45.js → chunk-LKWAVAB5.js} +3 -3
  87. package/chunks/{chunk-T4T2FNV4.js → chunk-LOW52WYZ.js} +2 -2
  88. package/chunks/{chunk-4QK3O43S.js → chunk-LU7BIVWC.js} +4 -4
  89. package/chunks/{chunk-ZP6UKOPB.js → chunk-LWGLBVWA.js} +1 -1
  90. package/chunks/{chunk-L7OKCI7T.js → chunk-M7BLWURA.js} +15 -1
  91. package/chunks/{chunk-PR32FRT6.js → chunk-MIM62IXS.js} +3 -3
  92. package/chunks/{chunk-RD6YJJJ6.js → chunk-MOUXUCXQ.js} +1 -1
  93. package/chunks/{chunk-VBZ452JT.js → chunk-MSNGFH6L.js} +494 -114
  94. package/chunks/{chunk-BX5YO7UW.js → chunk-MTNTVOJR.js} +542 -370
  95. package/chunks/chunk-MX2YXRER.js +44 -0
  96. package/chunks/chunk-NIOPRZNN.js +27 -0
  97. package/chunks/{chunk-SMYQZVZ3.js → chunk-NOGSPTLJ.js} +1 -1
  98. package/chunks/{chunk-DDMOU62Q.js → chunk-NPQWQYU6.js} +1 -1
  99. package/chunks/{chunk-MNF6S5PR.js → chunk-P5THQV6A.js} +4 -4
  100. package/chunks/{chunk-6V4NZFUS.js → chunk-PCYOT4PK.js} +5 -5
  101. package/chunks/{chunk-CF6BB3LT.js → chunk-PPFWEV7G.js} +10 -1
  102. package/chunks/{chunk-FXKVLFFY.js → chunk-PSFDB5FZ.js} +3 -3
  103. package/chunks/{chunk-XJYUPHRC.js → chunk-QOMAHFYI.js} +3 -3
  104. package/chunks/{chunk-J37FGIOA.js → chunk-QXPI7FEC.js} +38 -4
  105. package/chunks/{chunk-RRFZXMYP.js → chunk-QZDBHNMV.js} +691 -164
  106. package/chunks/{chunk-S7AKE7HL.js → chunk-R6RI2HIC.js} +63 -9
  107. package/chunks/{chunk-HZT4UCFB.js → chunk-RB7S52NJ.js} +4 -4
  108. package/chunks/{chunk-J33ZR6OJ.js → chunk-RK22ACPP.js} +16 -16
  109. package/chunks/chunk-RM3PGSGL.js +66 -0
  110. package/chunks/chunk-RNBYOUGV.js +42 -0
  111. package/chunks/chunk-S6RLAIUR.js +23 -0
  112. package/chunks/{chunk-3TV3HUWZ.js → chunk-SCYK2YLI.js} +81 -30
  113. package/chunks/{chunk-HPZTOP4I.js → chunk-SEKRT4SD.js} +133 -23
  114. package/chunks/chunk-SEZC2725.js +36 -0
  115. package/chunks/chunk-SIUQ3YYX.js +78 -0
  116. package/chunks/{chunk-O2VBQ3Y2.js → chunk-SJBIFVD2.js} +2 -2
  117. package/chunks/chunk-SYCJMSIJ.js +82 -0
  118. package/chunks/{chunk-JE5FVRPC.js → chunk-T22H4V4R.js} +48 -23
  119. package/chunks/{chunk-3227DZO4.js → chunk-T42ACHFI.js} +1 -1
  120. package/chunks/{chunk-UO5GVXQE.js → chunk-TENOUWY2.js} +3 -3
  121. package/chunks/{chunk-JOLIREYR.js → chunk-TOAUDIS7.js} +1 -1
  122. package/chunks/{chunk-QNKBEJO2.js → chunk-UA6XBZT7.js} +2776 -1289
  123. package/chunks/{chunk-O75BHFQW.js → chunk-UQTYK5SS.js} +2 -2
  124. package/chunks/{chunk-Y6YMRS3U.js → chunk-UY2TCIZS.js} +17 -3
  125. package/chunks/{chunk-FNJ7BDPH.js → chunk-UY7ZAYTY.js} +10 -7
  126. package/chunks/{chunk-UYT3MWEB.js → chunk-UYHWM24C.js} +30 -2
  127. package/chunks/{chunk-SMXULRAN.js → chunk-VXGPYF7U.js} +1 -1
  128. package/chunks/{chunk-BTLJ2MF5.js → chunk-W7CG5HPC.js} +3 -3
  129. package/chunks/{chunk-JJXWTVSK.js → chunk-XHZKDN7M.js} +34 -1
  130. package/chunks/{chunk-K5XU6E4T.js → chunk-XKSCTXPK.js} +2 -2
  131. package/chunks/chunk-Y4LITCRB.js +367 -0
  132. package/chunks/chunk-YHTNWGRR.js +239 -0
  133. package/chunks/{chunk-BKXBARJZ.js → chunk-YPCPZSZB.js} +1 -1
  134. package/chunks/{chunk-QWFNTRH4.js → chunk-YSM24SCE.js} +1 -1
  135. package/chunks/chunk-YTFBURQD.js +313 -0
  136. package/chunks/{chunk-NL4C3H6C.js → chunk-YXK4GPYO.js} +1 -1
  137. package/chunks/{chunk-RYLJU2DY.js → chunk-ZN5T4BHI.js} +1 -1
  138. package/chunks/{computer-use-JGB36FDW.js → computer-use-MTSVPLPY.js} +34 -28
  139. package/chunks/contextCommand-VGJ3BPTK.js +67 -0
  140. package/chunks/{cron-create-SKEY55RG.js → cron-create-6YTCOX6P.js} +4 -4
  141. package/chunks/{cron-delete-I3NAT32Z.js → cron-delete-E3NIFSUK.js} +4 -4
  142. package/chunks/{cron-list-6XRRL6TH.js → cron-list-Q64MNQNE.js} +4 -4
  143. package/chunks/daemon-EEB2RYOL.js +8453 -0
  144. package/chunks/daemon-status-provider-H5SNMK42.js +71 -0
  145. package/chunks/{de-EOW5PVHF.js → de-PLLFDERI.js} +10 -9
  146. package/chunks/{dist-NHEYYB2B.js → dist-ADMIQGHI.js} +2 -2
  147. package/chunks/{dist-J37VXPLD.js → dist-BCQ7INM7.js} +40 -15
  148. package/chunks/{dist-663NZ6MI.js → dist-KNZFCY5F.js} +116 -11
  149. package/chunks/{dist-LB6OGPVM.js → dist-LHUWC3K6.js} +26 -5
  150. package/chunks/{dist-PQPZ5Q4N.js → dist-WBBZ76JZ.js} +20 -9
  151. package/chunks/{earlyInputCapture-44RISVVJ.js → earlyInputCapture-U4ZIQSQU.js} +32 -26
  152. package/chunks/{edit-NN6GM5DT.js → edit-SYIQ2KBI.js} +41 -38
  153. package/chunks/{en-HPWEJBTR.js → en-M4EBUBNU.js} +32 -10
  154. package/chunks/{enter-worktree-PB3O2C7D.js → enter-worktree-HPPOO244.js} +31 -25
  155. package/chunks/{enterPlanMode-YQFNNSUA.js → enterPlanMode-56YYO52U.js} +41 -25
  156. package/chunks/{errors-LS7XU5DZ.js → errors-EO4SXCFP.js} +33 -27
  157. package/chunks/{exit-worktree-E2FTNSBK.js → exit-worktree-UDM7E6XH.js} +31 -25
  158. package/chunks/{exitPlanMode-GLYK2BUB.js → exitPlanMode-M6P3AWLJ.js} +149 -33
  159. package/chunks/{fast-path-WQ6M7LI7.js → fast-path-42P4QYWI.js} +33 -14
  160. package/chunks/{fast-path-settings-OAGU3X5H.js → fast-path-settings-UQLRFDQP.js} +2 -2
  161. package/chunks/{fr-BN5NKSAC.js → fr-MBMNQSQ6.js} +10 -9
  162. package/chunks/{gemini-2YFLVA2M.js → gemini-NRLXS5J7.js} +84 -70
  163. package/chunks/{geminiContentGenerator-XV6SV6CD.js → geminiContentGenerator-DLJPYYPA.js} +41 -5
  164. package/chunks/{glob-2H6CDDMK.js → glob-JPY3F74Y.js} +31 -25
  165. package/chunks/{grep-VXIUXM3C.js → grep-HW23YES5.js} +31 -25
  166. package/chunks/initializer-HWOZTC4A.js +67 -0
  167. package/chunks/{ja-7DEUB2TS.js → ja-HFV5QCHR.js} +10 -9
  168. package/chunks/{keychain-token-storage-YLMDLKXT.js → keychain-token-storage-GPAKRDKQ.js} +2 -2
  169. package/chunks/list-OZGAGRDG.js +71 -0
  170. package/chunks/loadedSettingsAdapter-RUTZVVIA.js +66 -0
  171. package/chunks/{loop-wakeup-CITGGQHA.js → loop-wakeup-G2EHBRGR.js} +5 -5
  172. package/chunks/{ls-R5WP4BGZ.js → ls-IDHUVSAG.js} +4 -4
  173. package/chunks/{lsp-GSICJMMW.js → lsp-FSRYXGFT.js} +2 -2
  174. package/chunks/{monitor-HKLRS2HQ.js → monitor-QVWEIXU3.js} +33 -26
  175. package/chunks/nonInteractiveCli-RV2WYPML.js +109 -0
  176. package/chunks/{notebook-edit-Y6SKSGTT.js → notebook-edit-B26W3FFH.js} +37 -34
  177. package/chunks/{openaiContentGenerator-J7G2FYJT.js → openaiContentGenerator-6TH7AZGQ.js} +15 -13
  178. package/chunks/pidfile-KW2QQJZI.js +73 -0
  179. package/chunks/{pt-TNZRNLQB.js → pt-2THT3YHA.js} +10 -9
  180. package/chunks/{qwenContentGenerator-5XIEM5GV.js → qwenContentGenerator-5IQAC7RN.js} +33 -27
  181. package/chunks/{qwenOAuth2-AG3PFFLZ.js → qwenOAuth2-LWLA6MQG.js} +5 -4
  182. package/chunks/{read-file-J7D552ZJ.js → read-file-CWFAHOI2.js} +11 -10
  183. package/chunks/{read-mcp-resource-DQQW7H7T.js → read-mcp-resource-PIJF24RO.js} +2 -2
  184. package/chunks/ripGrep-FTZGDKY4.js +60 -0
  185. package/chunks/{ru-NIAUBKCN.js → ru-Z67YJHBG.js} +10 -9
  186. package/chunks/{run-qwen-serve-SGEEVMXD.js → run-qwen-serve-FN2SW5ZI.js} +545 -97
  187. package/chunks/{scheduler-7CQI3S4Q.js → scheduler-BMS23O3I.js} +31 -25
  188. package/chunks/{send-message-EE4TWKVU.js → send-message-33PYFMCT.js} +20 -4
  189. package/chunks/serve-PXFYKL65.js +71 -0
  190. package/chunks/{server-4QMUWXPW.js → server-BRKALJ4F.js} +4132 -1175
  191. package/chunks/{session-NRO7UFOY.js → session-AQMISBP4.js} +205 -64
  192. package/chunks/{settings-SGWRDQSC.js → settings-JCPVUZMB.js} +35 -29
  193. package/chunks/{shell-62ANGIHL.js → shell-POHCRVN2.js} +31 -25
  194. package/chunks/{skill-VWAQAWW6.js → skill-QPEVHS6H.js} +13 -12
  195. package/chunks/spawnChannel-V3QT62TE.js +69 -0
  196. package/chunks/{src-KUV5J5Q2.js → src-IZSP7L6Y.js} +127 -32
  197. package/chunks/{startInteractiveUI-6EYJN3JV.js → startInteractiveUI-63KATISO.js} +16762 -16075
  198. package/chunks/{syntheticOutput-T5YHQ6S2.js → syntheticOutput-YOSWIHDJ.js} +3 -3
  199. package/chunks/{task-create-BLY7RHXX.js → task-create-NHS2NGB3.js} +9 -7
  200. package/chunks/{task-list-3QUYNVYR.js → task-list-5UIB564R.js} +7 -6
  201. package/chunks/{task-stop-U4RATK2V.js → task-stop-HGXZ2VZ3.js} +2 -2
  202. package/chunks/{task-update-U54O7KJX.js → task-update-IYYWUILG.js} +40 -7
  203. package/chunks/{team-create-LPOGCPM7.js → team-create-E5O2F3CA.js} +31 -25
  204. package/chunks/{team-delete-LKBYPASD.js → team-delete-FEKJCU4P.js} +7 -6
  205. package/chunks/team-plan-approval-2TU4YROB.js +202 -0
  206. package/chunks/theme-manager-37KOGPJL.js +64 -0
  207. package/chunks/{todoWrite-OYXKTVYN.js → todoWrite-TKMVZ2HT.js} +4 -4
  208. package/chunks/{tool-search-YPUFJ3ZQ.js → tool-search-4ZTGNSFI.js} +38 -11
  209. package/chunks/{trustedFolders-5B24TMEA.js → trustedFolders-RJ5WXJ6L.js} +32 -26
  210. package/chunks/{validateNonInterActiveAuth-BTDTYOVT.js → validateNonInterActiveAuth-ZWMHZAOK.js} +66 -55
  211. package/chunks/{web-fetch-EEB5LZYU.js → web-fetch-J4PIW36Q.js} +5 -4
  212. package/chunks/{workflow-LAWIW5LI.js → workflow-6PG2PC5M.js} +68 -39
  213. package/chunks/workspace-providers-status-4QIZN2W4.js +68 -0
  214. package/chunks/workspace-service-CYMCOEIO.js +78 -0
  215. package/chunks/{write-file-PCV226DJ.js → write-file-R354LGQF.js} +41 -40
  216. package/chunks/{zh-5EUYXASN.js → zh-SLZNSSZB.js} +32 -10
  217. package/chunks/{zh-TW-TR3XYGE5.js → zh-TW-P53C2SL5.js} +32 -10
  218. package/cli.js +6 -6
  219. package/locales/ca.js +15 -13
  220. package/locales/de.js +15 -13
  221. package/locales/en.js +52 -15
  222. package/locales/fr.js +15 -14
  223. package/locales/ja.js +15 -14
  224. package/locales/pt.js +15 -13
  225. package/locales/ru.js +15 -13
  226. package/locales/zh-TW.js +50 -14
  227. package/locales/zh.js +50 -14
  228. package/node_modules/@qwen-code/audio-capture/package.json +1 -1
  229. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
  230. package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
  231. package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
  232. package/package.json +15 -6
  233. package/patches/chrome-devtools-mcp+1.4.0.patch +31 -0
  234. package/postinstall.js +50 -0
  235. package/web-shell/assets/{arc-DA7r8Ueo.js → arc-Bd3048nX.js} +1 -1
  236. package/web-shell/assets/{architectureDiagram-3BPJPVTR-ZDUxPtZ2.js → architectureDiagram-3BPJPVTR-DyzbzABx.js} +1 -1
  237. package/web-shell/assets/{blockDiagram-GPEHLZMM-vrtOf1kJ.js → blockDiagram-GPEHLZMM-CTjxm9Sy.js} +1 -1
  238. package/web-shell/assets/{c4Diagram-AAUBKEIU-BHFjzIi4.js → c4Diagram-AAUBKEIU-DSOFWNU6.js} +1 -1
  239. package/web-shell/assets/channel-oVoup_Ci.js +1 -0
  240. package/web-shell/assets/{chunk-2J33WTMH-mdeQVz59.js → chunk-2J33WTMH-D_PFdjo2.js} +1 -1
  241. package/web-shell/assets/{chunk-4BX2VUAB-BkKMlwBX.js → chunk-4BX2VUAB-52eG6wOT.js} +1 -1
  242. package/web-shell/assets/{chunk-55IACEB6-B7bnXNfu.js → chunk-55IACEB6-CGTZfKkC.js} +1 -1
  243. package/web-shell/assets/{chunk-727SXJPM-DGz8Mm6i.js → chunk-727SXJPM-CZ-qfRUm.js} +1 -1
  244. package/web-shell/assets/{chunk-AQP2D5EJ-BQAydUNk.js → chunk-AQP2D5EJ-B2dSDcqM.js} +1 -1
  245. package/web-shell/assets/{chunk-FMBD7UC4-GHr2LN_p.js → chunk-FMBD7UC4-Cfy3tyA0.js} +1 -1
  246. package/web-shell/assets/{chunk-ND2GUHAM-7R91lnUx.js → chunk-ND2GUHAM-CApNUpUq.js} +1 -1
  247. package/web-shell/assets/{chunk-QZHKN3VN-aTJD3lSQ.js → chunk-QZHKN3VN-CVBG8kgg.js} +1 -1
  248. package/web-shell/assets/classDiagram-4FO5ZUOK-B8WsaT2G.js +1 -0
  249. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-B8WsaT2G.js +1 -0
  250. package/web-shell/assets/{cose-bilkent-S5V4N54A-BTf8t1RL.js → cose-bilkent-S5V4N54A-URd77-_-.js} +1 -1
  251. package/web-shell/assets/{dagre-BM42HDAG-_sgp3WuA.js → dagre-BM42HDAG-C07H4G9-.js} +1 -1
  252. package/web-shell/assets/{diagram-2AECGRRQ-CROtRy1w.js → diagram-2AECGRRQ-CYbpXrSn.js} +1 -1
  253. package/web-shell/assets/{diagram-5GNKFQAL-BqGRzwSc.js → diagram-5GNKFQAL-SI8s6fjX.js} +1 -1
  254. package/web-shell/assets/{diagram-KO2AKTUF-CMrcEtA7.js → diagram-KO2AKTUF-mBkC4RTW.js} +1 -1
  255. package/web-shell/assets/{diagram-LMA3HP47-BRydGNW5.js → diagram-LMA3HP47-CyBPDzWJ.js} +1 -1
  256. package/web-shell/assets/{diagram-OG6HWLK6-D0ilgNjV.js → diagram-OG6HWLK6-DwK7kBCu.js} +1 -1
  257. package/web-shell/assets/{erDiagram-TEJ5UH35-2lnQeJUM.js → erDiagram-TEJ5UH35-Ds1StEUd.js} +1 -1
  258. package/web-shell/assets/{flowDiagram-I6XJVG4X-C_ZMdQiC.js → flowDiagram-I6XJVG4X-BDC4-jHO.js} +1 -1
  259. package/web-shell/assets/{ganttDiagram-6RSMTGT7-Dw9V_Ny0.js → ganttDiagram-6RSMTGT7-CV2aHQqf.js} +1 -1
  260. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-HDXI-F1B.js → gitGraphDiagram-PVQCEYII-B8RcuV_L.js} +1 -1
  261. package/web-shell/assets/index-B5WZ0qP1.js +717 -0
  262. package/web-shell/assets/index-CYE1IMd1.css +5 -0
  263. package/web-shell/assets/{infoDiagram-5YYISTIA-CuB8Ebua.js → infoDiagram-5YYISTIA-DUPoTf50.js} +1 -1
  264. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-D_tyhVwh.js → ishikawaDiagram-YF4QCWOH-FDYOx9rf.js} +1 -1
  265. package/web-shell/assets/{journeyDiagram-JHISSGLW-CgCwJQNU.js → journeyDiagram-JHISSGLW-C5_ohMRp.js} +1 -1
  266. package/web-shell/assets/{kanban-definition-UN3LZRKU-PZUtcbPx.js → kanban-definition-UN3LZRKU-Bn4UnOMG.js} +1 -1
  267. package/web-shell/assets/{linear-CZqRdJIU.js → linear-Bl0pKQtY.js} +1 -1
  268. package/web-shell/assets/{mermaid.core-CPW_4UEF.js → mermaid.core-sevQFoji.js} +72 -72
  269. package/web-shell/assets/{mindmap-definition-RKZ34NQL-D_Y75ID7.js → mindmap-definition-RKZ34NQL-DSH4JZF9.js} +1 -1
  270. package/web-shell/assets/{pieDiagram-4H26LBE5-Q4dTyLeF.js → pieDiagram-4H26LBE5-acWvdQTD.js} +1 -1
  271. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-ckw329Ft.js → quadrantDiagram-W4KKPZXB-DlggX4Sm.js} +1 -1
  272. package/web-shell/assets/{requirementDiagram-4Y6WPE33-DbVDm4It.js → requirementDiagram-4Y6WPE33--mMqwmV8.js} +1 -1
  273. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-CHuZ_ecH.js → sankeyDiagram-5OEKKPKP-BtV9tZ77.js} +1 -1
  274. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DU2YSpq-.js → sequenceDiagram-3UESZ5HK-iDQzPFlj.js} +1 -1
  275. package/web-shell/assets/{stateDiagram-AJRCARHV-CA9PEBUo.js → stateDiagram-AJRCARHV-CsCyQLZ3.js} +1 -1
  276. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CPapECG9.js +1 -0
  277. package/web-shell/assets/{timeline-definition-PNZ67QCA-Bhlo4WVc.js → timeline-definition-PNZ67QCA-Dl0rnKvr.js} +1 -1
  278. package/web-shell/assets/{vennDiagram-CIIHVFJN-6xtPLsyl.js → vennDiagram-CIIHVFJN-qF7nTZzA.js} +1 -1
  279. package/web-shell/assets/{wardley-L42UT6IY-3eozmXPf.js → wardley-L42UT6IY-fWoK9i7F.js} +1 -1
  280. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BOn6hKss.js → wardleyDiagram-YWT4CUSO-pHGfkMnc.js} +1 -1
  281. package/web-shell/assets/{xychartDiagram-2RQKCTM6-BsP4-I_y.js → xychartDiagram-2RQKCTM6-3Doc4Trz.js} +1 -1
  282. package/web-shell/index.html +18 -2
  283. package/chunks/MaxSizedBox-QNF3EIGU.js +0 -63
  284. package/chunks/agent-headless-RQ5BTX3G.js +0 -56
  285. package/chunks/bridge-JL2PMCIW.js +0 -66
  286. package/chunks/chunk-5GOVVXEV.js +0 -73
  287. package/chunks/chunk-BC3C4F3Q.js +0 -40
  288. package/chunks/chunk-BW4KCQFD.js +0 -1103
  289. package/chunks/chunk-RKIZXJMB.js +0 -13
  290. package/chunks/contextCommand-WYU6OQ2F.js +0 -61
  291. package/chunks/daemon-status-provider-HH2EC5FI.js +0 -65
  292. package/chunks/headlessSafetyWarnings-TBE35GJ4.js +0 -55
  293. package/chunks/initializer-2Y7SLOKV.js +0 -61
  294. package/chunks/list-ZAFHZ7OS.js +0 -65
  295. package/chunks/loadedSettingsAdapter-6KJXD6M3.js +0 -60
  296. package/chunks/nonInteractiveCli-5W4GIZQM.js +0 -96
  297. package/chunks/ripGrep-IEIFIWP4.js +0 -54
  298. package/chunks/serve-V6GVZR6U.js +0 -65
  299. package/chunks/spawnChannel-3VHW5EPY.js +0 -63
  300. package/chunks/theme-manager-LYLGAERF.js +0 -58
  301. package/chunks/workspace-providers-status-PIAFVYHA.js +0 -62
  302. package/chunks/workspace-service-YAIOD4HG.js +0 -71
  303. package/web-shell/assets/channel-iRo68q4Q.js +0 -1
  304. package/web-shell/assets/classDiagram-4FO5ZUOK-iHF24a8X.js +0 -1
  305. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-iHF24a8X.js +0 -1
  306. package/web-shell/assets/index-CHmzAWys.css +0 -5
  307. package/web-shell/assets/index-w6GTOHh1.js +0 -713
  308. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-t1LRI0oY.js +0 -1
@@ -2,12 +2,15 @@
2
2
  "use strict";
3
3
  import {
4
4
  MID_TURN_QUEUE_DRAIN_METHOD
5
- } from "./chunk-QBZ22PQX.js";
5
+ } from "./chunk-EWALXUAD.js";
6
6
  import {
7
7
  DEFAULT_RING_SIZE,
8
8
  EVENT_SCHEMA_VERSION,
9
9
  EventBus
10
10
  } from "./chunk-ALX6BUYW.js";
11
+ import {
12
+ defaultSpawnChannelFactory
13
+ } from "./chunk-PSFDB5FZ.js";
11
14
  import {
12
15
  MCP_RESTART_SERVER_DEADLINE_MS
13
16
  } from "./chunk-P7M4GA57.js";
@@ -29,17 +32,11 @@ import {
29
32
  SessionShellClientRequiredError,
30
33
  SessionShellDisabledError,
31
34
  WorkspaceMismatchError,
32
- canonicalizeWorkspace,
33
35
  isNotCurrentlyGeneratingCancelError
34
- } from "./chunk-JE5FVRPC.js";
35
- import {
36
- defaultSpawnChannelFactory
37
- } from "./chunk-FXKVLFFY.js";
36
+ } from "./chunk-T22H4V4R.js";
38
37
  import {
39
- ClientSideConnection,
40
- PROTOCOL_VERSION,
41
- RequestError
42
- } from "./chunk-UFC57OYT.js";
38
+ canonicalizeWorkspace
39
+ } from "./chunk-SEZC2725.js";
43
40
  import {
44
41
  BridgeChannelClosedError,
45
42
  BridgeTimeoutError,
@@ -48,15 +45,20 @@ import {
48
45
  STATUS_SCHEMA_VERSION,
49
46
  createIdleWorkspaceExtensionsStatus,
50
47
  createIdleWorkspaceHooksStatus
51
- } from "./chunk-L7OKCI7T.js";
48
+ } from "./chunk-M7BLWURA.js";
49
+ import {
50
+ ClientSideConnection,
51
+ PROTOCOL_VERSION,
52
+ RequestError
53
+ } from "./chunk-UFC57OYT.js";
52
54
  import {
53
55
  ShellExecutionService,
54
56
  TrustGateError
55
- } from "./chunk-YAINVQ3Q.js";
57
+ } from "./chunk-A5OPLHFM.js";
56
58
  import {
57
59
  DAEMON_TRACEPARENT_META_KEY,
58
60
  DAEMON_TRACESTATE_META_KEY
59
- } from "./chunk-QNKBEJO2.js";
61
+ } from "./chunk-UA6XBZT7.js";
60
62
  import {
61
63
  init_esbuild_shims
62
64
  } from "./chunk-A4BMJM77.js";
@@ -1098,7 +1100,7 @@ function sliceLineRange(content, startLine, endLine) {
1098
1100
  }
1099
1101
  __name(sliceLineRange, "sliceLineRange");
1100
1102
  var BridgeClient = class {
1101
- constructor(resolveEntry, resolvePendingRestoreEvents, mediator, permissionTimeoutMs, maxPendingPerSession, fileSystem, onModelPromoted, onModePromoted) {
1103
+ constructor(resolveEntry, resolvePendingRestoreEvents, mediator, permissionTimeoutMs, maxPendingPerSession, fileSystem, onModelPromoted, onModePromoted, clientMcpSender) {
1102
1104
  this.resolveEntry = resolveEntry;
1103
1105
  this.resolvePendingRestoreEvents = resolvePendingRestoreEvents;
1104
1106
  this.mediator = mediator;
@@ -1107,6 +1109,7 @@ var BridgeClient = class {
1107
1109
  this.fileSystem = fileSystem;
1108
1110
  this.onModelPromoted = onModelPromoted;
1109
1111
  this.onModePromoted = onModePromoted;
1112
+ this.clientMcpSender = clientMcpSender;
1110
1113
  }
1111
1114
  static {
1112
1115
  __name(this, "BridgeClient");
@@ -1253,6 +1256,9 @@ var BridgeClient = class {
1253
1256
  * treats that as "drain unsupported" and stops asking.
1254
1257
  */
1255
1258
  async extMethod(method, params) {
1259
+ if (method === SERVE_CONTROL_EXT_METHODS.clientMcpMessage) {
1260
+ return this.handleClientMcpMessage(params);
1261
+ }
1256
1262
  if (method !== MID_TURN_QUEUE_DRAIN_METHOD) {
1257
1263
  throw RequestError.methodNotFound(method);
1258
1264
  }
@@ -1282,6 +1288,52 @@ var BridgeClient = class {
1282
1288
  }
1283
1289
  return { messages };
1284
1290
  }
1291
+ /**
1292
+ * Reverse tool channel (issue #5626, Phase 2) — answer the child's
1293
+ * `qwen/control/client_mcp/message` ext-method. The child's session
1294
+ * `McpClientManager` calls this when its agent drives a client-hosted
1295
+ * (extension) MCP server: `params` carries the advertised `server` name and
1296
+ * the JSON-RPC `payload` (initialize / tools/list / tools/call / a
1297
+ * notification). We resolve the per-WS-connection sender via the injected
1298
+ * `clientMcpSender` lookup, deliver the payload over the daemon WS, and
1299
+ * return the correlated response as `{ payload }`.
1300
+ *
1301
+ * Rejects with ACP `methodNotFound` when no `clientMcpSender` is wired (Mode
1302
+ * A / tests can't host a client MCP server), and `invalidParams` when the
1303
+ * frame is malformed or the named server is no longer hosted (e.g. the
1304
+ * extension disconnected mid-turn) — the agent's `SdkControlClientTransport`
1305
+ * surfaces that as a transport error rather than hanging.
1306
+ */
1307
+ async handleClientMcpMessage(params) {
1308
+ if (!this.clientMcpSender) {
1309
+ throw RequestError.methodNotFound(
1310
+ SERVE_CONTROL_EXT_METHODS.clientMcpMessage
1311
+ );
1312
+ }
1313
+ const server = params["server"];
1314
+ if (typeof server !== "string" || server.length === 0) {
1315
+ throw RequestError.invalidParams(
1316
+ void 0,
1317
+ "`server` must be a non-empty string"
1318
+ );
1319
+ }
1320
+ const payload = params["payload"];
1321
+ if (payload === null || typeof payload !== "object") {
1322
+ throw RequestError.invalidParams(
1323
+ void 0,
1324
+ "`payload` must be a JSON-RPC message object"
1325
+ );
1326
+ }
1327
+ const send = this.clientMcpSender(server);
1328
+ if (!send) {
1329
+ throw RequestError.invalidParams(
1330
+ void 0,
1331
+ `client-hosted MCP server '${server}' is not currently connected`
1332
+ );
1333
+ }
1334
+ const response = await send(payload);
1335
+ return { payload: response };
1336
+ }
1285
1337
  /**
1286
1338
  * Handle child->bridge ACP `extNotification` calls. Six methods are
1287
1339
  * recognized — `qwen/notify/session/model-update`,
@@ -1857,6 +1909,24 @@ function extractPermissionResponseMetadata(response) {
1857
1909
  return void 0;
1858
1910
  }
1859
1911
  __name(extractPermissionResponseMetadata, "extractPermissionResponseMetadata");
1912
+ function parseWorkspaceMemoryRememberResult(response) {
1913
+ if (response === null || typeof response !== "object" || Array.isArray(response)) {
1914
+ throw new Error("Malformed workspace memory remember response");
1915
+ }
1916
+ const record = response;
1917
+ const summary = record["summary"];
1918
+ const filesTouched = record["filesTouched"];
1919
+ const touchedScopes = record["touchedScopes"];
1920
+ if (summary !== void 0 && typeof summary !== "string" || !Array.isArray(filesTouched) || !filesTouched.every((file) => typeof file === "string") || !Array.isArray(touchedScopes) || !touchedScopes.every((scope) => scope === "user" || scope === "project")) {
1921
+ throw new Error("Malformed workspace memory remember response");
1922
+ }
1923
+ return {
1924
+ ...summary === void 0 ? {} : { summary },
1925
+ filesTouched,
1926
+ touchedScopes
1927
+ };
1928
+ }
1929
+ __name(parseWorkspaceMemoryRememberResult, "parseWorkspaceMemoryRememberResult");
1860
1930
  function echoPromptToSessionBus(entry, req, originatorClientId) {
1861
1931
  const prompt = req.prompt;
1862
1932
  if (!Array.isArray(prompt) || prompt.length === 0) return;
@@ -1911,15 +1981,18 @@ function broadcastPromptCancelledOnce(entry, sessionId, originatorClientId, reas
1911
1981
  }
1912
1982
  __name(broadcastPromptCancelledOnce, "broadcastPromptCancelledOnce");
1913
1983
  function broadcastTurnComplete(entry, sessionId, promptResult, promptId, originatorClientId) {
1914
- entry.events.publish({
1915
- type: "turn_complete",
1916
- data: {
1917
- sessionId,
1918
- stopReason: promptResult.stopReason ?? "end_turn",
1919
- ...promptId ? { promptId } : {}
1920
- },
1921
- ...originatorClientId ? { originatorClientId } : {}
1922
- });
1984
+ try {
1985
+ entry.events.publish({
1986
+ type: "turn_complete",
1987
+ data: {
1988
+ sessionId,
1989
+ stopReason: promptResult.stopReason ?? "end_turn",
1990
+ ...promptId ? { promptId } : {}
1991
+ },
1992
+ ...originatorClientId ? { originatorClientId } : {}
1993
+ });
1994
+ } catch {
1995
+ }
1923
1996
  }
1924
1997
  __name(broadcastTurnComplete, "broadcastTurnComplete");
1925
1998
  function extractErrorMessage(err) {
@@ -1962,16 +2035,19 @@ function broadcastTurnError(entry, sessionId, err, promptId, originatorClientId)
1962
2035
  const message = extractErrorMessage(err);
1963
2036
  const code = extractErrorCode(err);
1964
2037
  entry.retryAllowed = true;
1965
- entry.events.publish({
1966
- type: "turn_error",
1967
- data: {
1968
- sessionId,
1969
- message,
1970
- ...code ? { code } : {},
1971
- ...promptId ? { promptId } : {}
1972
- },
1973
- ...originatorClientId ? { originatorClientId } : {}
1974
- });
2038
+ try {
2039
+ entry.events.publish({
2040
+ type: "turn_error",
2041
+ data: {
2042
+ sessionId,
2043
+ message,
2044
+ ...code ? { code } : {},
2045
+ ...promptId ? { promptId } : {}
2046
+ },
2047
+ ...originatorClientId ? { originatorClientId } : {}
2048
+ });
2049
+ } catch {
2050
+ }
1975
2051
  }
1976
2052
  __name(broadcastTurnError, "broadcastTurnError");
1977
2053
  function hasControlCharacter(value) {
@@ -1984,11 +2060,27 @@ function hasControlCharacter(value) {
1984
2060
  return false;
1985
2061
  }
1986
2062
  __name(hasControlCharacter, "hasControlCharacter");
2063
+ function extractPromptText(prompt) {
2064
+ if (!Array.isArray(prompt)) return "";
2065
+ let hasImage = false;
2066
+ for (const block of prompt) {
2067
+ if (block["type"] === "image") {
2068
+ hasImage = true;
2069
+ }
2070
+ if (block["type"] === "text" && typeof block["text"] === "string" && block["text"].length > 0) {
2071
+ return block["text"];
2072
+ }
2073
+ }
2074
+ return hasImage ? "[image]" : "";
2075
+ }
2076
+ __name(extractPromptText, "extractPromptText");
1987
2077
  var DEFAULT_INIT_TIMEOUT_MS = 1e4;
1988
2078
  var PERSIST_TIMEOUT_MS = 5e3;
1989
2079
  var MCP_RESTART_TIMEOUT_MS = 3e5;
2080
+ var WORKSPACE_MEMORY_REMEMBER_TIMEOUT_MS = 3e5;
1990
2081
  var MCP_OAUTH_TIMEOUT_MS = 6e5;
1991
2082
  var DAEMON_RETRY_META_KEY = "qwen.daemon.retry";
2083
+ var DAEMON_CONTINUE_META_KEY = "qwen.daemon.continueLastTurn";
1992
2084
  var SESSION_RECAP_TIMEOUT_MS = 6e4;
1993
2085
  var SESSION_BTW_TIMEOUT_MS = 6e4;
1994
2086
  var SHELL_COMMAND_TIMEOUT_MS = 12e4;
@@ -2121,7 +2213,7 @@ function createAcpSessionBridge(opts) {
2121
2213
  cancelIdleTimer();
2122
2214
  idleTimer = setTimeout(() => {
2123
2215
  idleTimer = void 0;
2124
- if (ci.sessionIds.size === 0 && ci.pendingRestoreIds.size === 0) {
2216
+ if (hasNoChannelWork(ci)) {
2125
2217
  writeStderrLine(
2126
2218
  `qwen serve: idle timeout (${timeoutMs}ms) expired, killing channel`
2127
2219
  );
@@ -2131,6 +2223,33 @@ function createAcpSessionBridge(opts) {
2131
2223
  idleTimer.unref();
2132
2224
  }
2133
2225
  __name(startIdleTimer, "startIdleTimer");
2226
+ function hasNoChannelWork(ci, opts2) {
2227
+ const inFlightSpawnCount = ci.sessionSpawnsInFlight - (opts2?.ignoreCurrentSessionSpawn === true ? 1 : 0);
2228
+ const pendingRestoreCount = ci.pendingRestoreIds.size - (opts2?.ignoreRestoreId !== void 0 && ci.pendingRestoreIds.has(opts2.ignoreRestoreId) ? 1 : 0);
2229
+ return ci.sessionIds.size === 0 && pendingRestoreCount === 0 && ci.workspaceControlInFlight === 0 && inFlightSpawnCount === 0;
2230
+ }
2231
+ __name(hasNoChannelWork, "hasNoChannelWork");
2232
+ async function reapPendingEmptyChannel(ci) {
2233
+ if (!ci.emptyReapPending || !hasNoChannelWork(ci)) return;
2234
+ ci.emptyReapPending = false;
2235
+ ci.isDying = true;
2236
+ await ci.channel.kill().catch(() => {
2237
+ });
2238
+ }
2239
+ __name(reapPendingEmptyChannel, "reapPendingEmptyChannel");
2240
+ async function withWorkspaceControl(ci, fn) {
2241
+ ci.workspaceControlInFlight++;
2242
+ try {
2243
+ return await fn();
2244
+ } finally {
2245
+ ci.workspaceControlInFlight = Math.max(
2246
+ 0,
2247
+ ci.workspaceControlInFlight - 1
2248
+ );
2249
+ await reapPendingEmptyChannel(ci);
2250
+ }
2251
+ }
2252
+ __name(withWorkspaceControl, "withWorkspaceControl");
2134
2253
  function startSessionReaper() {
2135
2254
  if (sessionReapIntervalMs <= 0 || sessionIdleTimeoutMs <= 0) {
2136
2255
  writeStderrLine("qwen serve: session reaper disabled");
@@ -2301,7 +2420,14 @@ function createAcpSessionBridge(opts) {
2301
2420
  },
2302
2421
  originator
2303
2422
  );
2304
- }
2423
+ },
2424
+ // Reverse tool channel (issue #5626, Phase 2): forward the optional
2425
+ // client-hosted-MCP sender lookup so `BridgeClient.extMethod` can
2426
+ // answer `qwen/control/client_mcp/message` from the child by reaching
2427
+ // the per-WS-connection `ClientMcpRegistrar`. Omitted callers (tests,
2428
+ // Mode A) never host a client MCP server, so the method stays
2429
+ // unreachable.
2430
+ opts.clientMcpSender
2305
2431
  );
2306
2432
  const connection = new ClientSideConnection(() => client, channel.stream);
2307
2433
  const info = {
@@ -2310,6 +2436,9 @@ function createAcpSessionBridge(opts) {
2310
2436
  client,
2311
2437
  sessionIds: /* @__PURE__ */ new Set(),
2312
2438
  pendingRestoreIds: /* @__PURE__ */ new Set(),
2439
+ sessionSpawnsInFlight: 0,
2440
+ workspaceControlInFlight: 0,
2441
+ emptyReapPending: false,
2313
2442
  isDying: false,
2314
2443
  handshakeComplete: false
2315
2444
  };
@@ -2413,63 +2542,75 @@ function createAcpSessionBridge(opts) {
2413
2542
  __name(ensureChannel, "ensureChannel");
2414
2543
  async function doSpawn(modelServiceId, effectiveScope, requestedClientId) {
2415
2544
  const ci = await ensureChannel();
2545
+ ci.sessionSpawnsInFlight++;
2546
+ let sessionRegistered = false;
2416
2547
  let newSessionResp;
2417
2548
  try {
2418
- newSessionResp = await telemetry.withSpan(
2419
- "session.new",
2420
- {
2421
- "qwen-code.daemon.bridge.operation": "session.new",
2422
- "qwen-code.daemon.session_scope": effectiveScope
2423
- },
2424
- async () => await withTimeout(
2425
- ci.connection.newSession({
2426
- cwd: boundWorkspace,
2427
- mcpServers: []
2428
- }),
2429
- initTimeoutMs,
2430
- "newSession"
2431
- )
2549
+ try {
2550
+ newSessionResp = await telemetry.withSpan(
2551
+ "session.new",
2552
+ {
2553
+ "qwen-code.daemon.bridge.operation": "session.new",
2554
+ "qwen-code.daemon.session_scope": effectiveScope
2555
+ },
2556
+ async () => await withTimeout(
2557
+ ci.connection.newSession({
2558
+ cwd: boundWorkspace,
2559
+ mcpServers: []
2560
+ }),
2561
+ initTimeoutMs,
2562
+ "newSession"
2563
+ )
2564
+ );
2565
+ } catch (err) {
2566
+ if (hasNoChannelWork(ci, { ignoreCurrentSessionSpawn: true })) {
2567
+ ci.isDying = true;
2568
+ await ci.channel.kill().catch(() => {
2569
+ });
2570
+ } else {
2571
+ ci.emptyReapPending = true;
2572
+ }
2573
+ throw err;
2574
+ }
2575
+ if (shuttingDown) {
2576
+ throw new Error("AcpSessionBridge is shutting down");
2577
+ }
2578
+ const entry = createSessionEntry(
2579
+ ci,
2580
+ newSessionResp.sessionId,
2581
+ boundWorkspace
2432
2582
  );
2433
- } catch (err) {
2434
- if (ci.sessionIds.size === 0) {
2435
- ci.isDying = true;
2436
- await ci.channel.kill().catch(() => {
2583
+ sessionRegistered = true;
2584
+ seedSnapshotCaches(entry, newSessionResp);
2585
+ const clientId = registerClient(entry, requestedClientId);
2586
+ if (effectiveScope === "single" && !defaultEntry) defaultEntry = entry;
2587
+ if (modelServiceId) {
2588
+ await applyModelServiceId(
2589
+ entry,
2590
+ modelServiceId,
2591
+ initTimeoutMs,
2592
+ clientId
2593
+ ).catch(() => {
2437
2594
  });
2438
2595
  }
2439
- throw err;
2440
- }
2441
- if (shuttingDown) {
2442
- throw new Error("AcpSessionBridge is shutting down");
2443
- }
2444
- const entry = createSessionEntry(
2445
- ci,
2446
- newSessionResp.sessionId,
2447
- boundWorkspace
2448
- );
2449
- seedSnapshotCaches(entry, newSessionResp);
2450
- const clientId = registerClient(entry, requestedClientId);
2451
- if (effectiveScope === "single" && !defaultEntry) defaultEntry = entry;
2452
- if (modelServiceId) {
2453
- await applyModelServiceId(
2454
- entry,
2455
- modelServiceId,
2456
- initTimeoutMs,
2457
- clientId
2458
- ).catch(() => {
2459
- });
2460
- }
2461
- if (!byId.has(entry.sessionId)) {
2462
- throw new Error(
2463
- `Session ${entry.sessionId} died during model-switch initialization`
2464
- );
2596
+ if (!byId.has(entry.sessionId)) {
2597
+ throw new Error(
2598
+ `Session ${entry.sessionId} died during model-switch initialization`
2599
+ );
2600
+ }
2601
+ return {
2602
+ sessionId: entry.sessionId,
2603
+ workspaceCwd: entry.workspaceCwd,
2604
+ attached: false,
2605
+ clientId,
2606
+ createdAt: entry.createdAt
2607
+ };
2608
+ } finally {
2609
+ ci.sessionSpawnsInFlight = Math.max(0, ci.sessionSpawnsInFlight - 1);
2610
+ if (!sessionRegistered) {
2611
+ await reapPendingEmptyChannel(ci);
2612
+ }
2465
2613
  }
2466
- return {
2467
- sessionId: entry.sessionId,
2468
- workspaceCwd: entry.workspaceCwd,
2469
- attached: false,
2470
- clientId,
2471
- createdAt: entry.createdAt
2472
- };
2473
2614
  }
2474
2615
  __name(doSpawn, "doSpawn");
2475
2616
  async function applyModelServiceId(entry, modelId, timeoutMs, originatorClientId) {
@@ -2608,13 +2749,24 @@ function createAcpSessionBridge(opts) {
2608
2749
  ]);
2609
2750
  return response;
2610
2751
  }, "requestSessionStatus");
2611
- const notifyAgentSessionClose = /* @__PURE__ */ __name(async (entry, ci, label) => {
2612
- if (!ci || ci.channel !== entry.channel) return;
2752
+ const notifyAgentSessionClose = /* @__PURE__ */ __name(async (entry, ci, label, opts2) => {
2753
+ if (!ci || ci.channel !== entry.channel) {
2754
+ if (opts2?.throwOnFailure === true) {
2755
+ writeStderrLine(
2756
+ `qwen serve: ${label} ACP session close channel unavailable for session ${JSON.stringify(entry.sessionId)}; agent close skipped`
2757
+ );
2758
+ throw new Error(
2759
+ `ACP session close channel unavailable for ${entry.sessionId}`
2760
+ );
2761
+ }
2762
+ return;
2763
+ }
2613
2764
  try {
2614
2765
  await Promise.race([
2615
2766
  withTimeout(
2616
2767
  entry.connection.extMethod(SERVE_CONTROL_EXT_METHODS.sessionClose, {
2617
- sessionId: entry.sessionId
2768
+ sessionId: entry.sessionId,
2769
+ ...opts2?.requireFlush === true ? { requireFlush: true } : {}
2618
2770
  }),
2619
2771
  initTimeoutMs,
2620
2772
  SERVE_CONTROL_EXT_METHODS.sessionClose
@@ -2627,6 +2779,9 @@ function createAcpSessionBridge(opts) {
2627
2779
  err instanceof Error ? err.message : err
2628
2780
  )}`
2629
2781
  );
2782
+ if (opts2?.throwOnFailure === true) {
2783
+ throw err;
2784
+ }
2630
2785
  }
2631
2786
  }, "notifyAgentSessionClose");
2632
2787
  const broadcastWorkspaceEvent = /* @__PURE__ */ __name((envelope, skipSessionId) => {
@@ -2757,6 +2912,7 @@ function createAcpSessionBridge(opts) {
2757
2912
  events,
2758
2913
  promptQueue: Promise.resolve(),
2759
2914
  pendingPromptCount: 0,
2915
+ pendingPromptList: [],
2760
2916
  midTurnMessageQueue: [],
2761
2917
  modelChangeQueue: Promise.resolve(),
2762
2918
  approvalModeQueue: Promise.resolve(),
@@ -2928,10 +3084,11 @@ function createAcpSessionBridge(opts) {
2928
3084
  if (isAcpSessionResourceNotFound(err, req.sessionId)) {
2929
3085
  throw new SessionNotFoundError(req.sessionId);
2930
3086
  }
2931
- if (ci.sessionIds.size === 0 && ci.pendingRestoreIds.size === 1 && ci.pendingRestoreIds.has(req.sessionId)) {
3087
+ ci.emptyReapPending = hasNoChannelWork(ci, {
3088
+ ignoreRestoreId: req.sessionId
3089
+ });
3090
+ if (ci.emptyReapPending) {
2932
3091
  ci.isDying = true;
2933
- await ci.channel.kill().catch(() => {
2934
- });
2935
3092
  }
2936
3093
  throw err;
2937
3094
  }
@@ -2982,7 +3139,7 @@ function createAcpSessionBridge(opts) {
2982
3139
  hasActivePrompt: entry.promptActive,
2983
3140
  ...replayFieldsFor(entry, action)
2984
3141
  };
2985
- })().finally(() => {
3142
+ })().finally(async () => {
2986
3143
  ci?.pendingRestoreIds.delete(req.sessionId);
2987
3144
  ci?.client.clearRestoreInFlight(req.sessionId);
2988
3145
  pendingRestoreEvents.delete(req.sessionId);
@@ -2990,6 +3147,9 @@ function createAcpSessionBridge(opts) {
2990
3147
  restoreEvents.close();
2991
3148
  ci?.client.markSessionClosed(req.sessionId);
2992
3149
  }
3150
+ if (ci) {
3151
+ await reapPendingEmptyChannel(ci);
3152
+ }
2993
3153
  });
2994
3154
  inFlightRestores.set(req.sessionId, { action, promise, coalesceState });
2995
3155
  try {
@@ -3022,6 +3182,13 @@ function createAcpSessionBridge(opts) {
3022
3182
  `qwen serve: closeSession channelInfoForEntry returned undefined for session ${JSON.stringify(sessionId)} \u2014 channel cleanup skipped (entry's channel already torn down)`
3023
3183
  );
3024
3184
  }
3185
+ const requireAgentClose = closeOpts?.requireAgentClose === true;
3186
+ if (requireAgentClose) {
3187
+ await notifyAgentSessionClose(entry, ci, "closeSession", {
3188
+ throwOnFailure: true,
3189
+ requireFlush: true
3190
+ });
3191
+ }
3025
3192
  if (ci && ci.channel === entry.channel) {
3026
3193
  ci.sessionIds.delete(sessionId);
3027
3194
  }
@@ -3052,7 +3219,9 @@ function createAcpSessionBridge(opts) {
3052
3219
  } catch {
3053
3220
  }
3054
3221
  entry.events.close();
3055
- await notifyAgentSessionClose(entry, ci, "closeSession");
3222
+ if (!requireAgentClose) {
3223
+ await notifyAgentSessionClose(entry, ci, "closeSession");
3224
+ }
3056
3225
  try {
3057
3226
  await telemetry.withSpan(
3058
3227
  "session.close.cancel_active_prompt",
@@ -3064,13 +3233,16 @@ function createAcpSessionBridge(opts) {
3064
3233
  );
3065
3234
  } catch {
3066
3235
  }
3067
- if (ci && ci.sessionIds.size === 0 && ci.pendingRestoreIds.size === 0) {
3068
- await startIdleTimer(ci, `closeSession "${sessionId}"`);
3236
+ if (ci && hasNoChannelWork(ci)) {
3237
+ await reapPendingEmptyChannel(ci);
3238
+ if (!ci.isDying) {
3239
+ await startIdleTimer(ci, `closeSession "${sessionId}"`);
3240
+ }
3069
3241
  }
3070
3242
  }
3071
3243
  __name(closeSessionImpl, "closeSessionImpl");
3072
3244
  startSessionReaper();
3073
- return {
3245
+ const bridgeApi = {
3074
3246
  getDaemonStatusSnapshot() {
3075
3247
  return {
3076
3248
  limits: {
@@ -3234,10 +3406,60 @@ function createAcpSessionBridge(opts) {
3234
3406
  promptSlotReleased = true;
3235
3407
  entry.pendingPromptCount = Math.max(0, entry.pendingPromptCount - 1);
3236
3408
  }, "releasePromptSlot");
3409
+ const promptId = context?.promptId ?? randomUUID2();
3410
+ const isQueued = entry.pendingPromptCount > 1;
3411
+ const pendingAbort = new AbortController();
3412
+ if (signal) {
3413
+ if (signal.aborted) {
3414
+ pendingAbort.abort(signal.reason);
3415
+ } else {
3416
+ signal.addEventListener(
3417
+ "abort",
3418
+ () => pendingAbort.abort(signal.reason),
3419
+ { once: true }
3420
+ );
3421
+ }
3422
+ }
3423
+ const pendingEntry = {
3424
+ promptId,
3425
+ queuedAt,
3426
+ ...originatorClientId !== void 0 ? { originatorClientId } : {},
3427
+ text: extractPromptText(req.prompt),
3428
+ abortController: pendingAbort,
3429
+ state: isQueued ? "queued" : "running"
3430
+ };
3431
+ entry.pendingPromptList.push(pendingEntry);
3432
+ if (isQueued) {
3433
+ entry.events.publish({
3434
+ type: "pending_prompt_added",
3435
+ data: {
3436
+ sessionId,
3437
+ promptId: pendingEntry.promptId,
3438
+ text: pendingEntry.text,
3439
+ queuedAt: pendingEntry.queuedAt
3440
+ },
3441
+ ...originatorClientId ? { originatorClientId } : {}
3442
+ });
3443
+ }
3237
3444
  const result = entry.promptQueue.then(
3238
3445
  () => telemetry.runWithContext(capturedContext, async () => {
3239
3446
  const queueWaitMs = Date.now() - queuedAt;
3240
3447
  telemetry.metrics?.promptQueueWait(queueWaitMs);
3448
+ if (pendingAbort.signal.aborted) {
3449
+ throw new DOMException("Prompt aborted", "AbortError");
3450
+ }
3451
+ if (pendingEntry.state === "queued") {
3452
+ pendingEntry.state = "running";
3453
+ entry.events.publish({
3454
+ type: "pending_prompt_started",
3455
+ data: {
3456
+ sessionId,
3457
+ promptId: pendingEntry.promptId,
3458
+ text: pendingEntry.text
3459
+ },
3460
+ ...originatorClientId ? { originatorClientId } : {}
3461
+ });
3462
+ }
3241
3463
  const dispatchStartMs = Date.now();
3242
3464
  try {
3243
3465
  return await telemetry.withSpan(
@@ -3255,13 +3477,11 @@ function createAcpSessionBridge(opts) {
3255
3477
  sessionId
3256
3478
  }
3257
3479
  );
3258
- if (signal?.aborted) {
3259
- throw new DOMException("Prompt aborted", "AbortError");
3260
- }
3261
3480
  assertLivePromptEntry(sessionId, entry);
3262
3481
  const requestedRetry = req.retry === true;
3263
3482
  const isRetry = requestedRetry && entry.retryAllowed;
3264
3483
  entry.retryAllowed = false;
3484
+ const isContinue = context?.continue === true;
3265
3485
  const promptRequest = (() => {
3266
3486
  const copy = {
3267
3487
  ...normalized
@@ -3269,9 +3489,13 @@ function createAcpSessionBridge(opts) {
3269
3489
  delete copy.retry;
3270
3490
  const meta = copy._meta && typeof copy._meta === "object" ? { ...copy._meta } : {};
3271
3491
  delete meta[DAEMON_RETRY_META_KEY];
3492
+ delete meta[DAEMON_CONTINUE_META_KEY];
3272
3493
  if (isRetry) {
3273
3494
  meta[DAEMON_RETRY_META_KEY] = true;
3274
3495
  }
3496
+ if (isContinue) {
3497
+ meta[DAEMON_CONTINUE_META_KEY] = true;
3498
+ }
3275
3499
  if (Object.keys(meta).length > 0) {
3276
3500
  copy._meta = meta;
3277
3501
  } else {
@@ -3290,7 +3514,7 @@ function createAcpSessionBridge(opts) {
3290
3514
  }
3291
3515
  try {
3292
3516
  entry.cancelBroadcast = false;
3293
- if (!isRetry) {
3517
+ if (!isRetry && !isContinue) {
3294
3518
  echoPromptToSessionBus(
3295
3519
  entry,
3296
3520
  promptRequest,
@@ -3332,6 +3556,12 @@ function createAcpSessionBridge(opts) {
3332
3556
  () => {
3333
3557
  },
3334
3558
  (err) => {
3559
+ if (err instanceof DOMException && err.name === "AbortError" && pendingEntry.state === "queued") {
3560
+ writeStderrLine(
3561
+ `sendPrompt: queued prompt removed before agent forward for session ${sessionId}`
3562
+ );
3563
+ return;
3564
+ }
3335
3565
  writeStderrLine(
3336
3566
  `sendPrompt: forward failed for session ${sessionId}: ${extractErrorMessage(err)}`
3337
3567
  );
@@ -3342,12 +3572,15 @@ function createAcpSessionBridge(opts) {
3342
3572
  "forward_failed"
3343
3573
  );
3344
3574
  cancelPendingForSession(sessionId);
3345
- entry.connection.cancel({ sessionId }).catch(() => {
3575
+ entry.connection.cancel({ sessionId }).catch((err2) => {
3576
+ writeStderrLine(
3577
+ `[pending-prompt] cancel forward failed after prompt abort session=${sessionId}: ${extractErrorMessage(err2)}`
3578
+ );
3346
3579
  });
3347
3580
  }
3348
3581
  ).catch(() => {
3349
3582
  });
3350
- if (!signal) return racedPromise;
3583
+ const abortSignal = pendingAbort.signal;
3351
3584
  const onAbort = /* @__PURE__ */ __name(() => {
3352
3585
  broadcastPromptCancelledOnce(
3353
3586
  entry,
@@ -3355,15 +3588,22 @@ function createAcpSessionBridge(opts) {
3355
3588
  originatorClientId
3356
3589
  );
3357
3590
  cancelPendingForSession(sessionId);
3358
- entry.connection.cancel({ sessionId }).catch(() => {
3591
+ entry.connection.cancel({ sessionId }).catch((err) => {
3592
+ writeStderrLine(
3593
+ `[pending-prompt] cancel forward failed after removePendingPrompt session=${sessionId}: ${extractErrorMessage(err)}`
3594
+ );
3359
3595
  });
3360
3596
  }, "onAbort");
3361
- if (signal.aborted) {
3597
+ if (abortSignal.aborted) {
3362
3598
  onAbort();
3363
3599
  } else {
3364
- signal.addEventListener("abort", onAbort, { once: true });
3365
- if (signal.aborted) onAbort();
3366
- racedPromise.finally(() => signal.removeEventListener("abort", onAbort)).catch(() => {
3600
+ abortSignal.addEventListener("abort", onAbort, {
3601
+ once: true
3602
+ });
3603
+ if (abortSignal.aborted) onAbort();
3604
+ racedPromise.finally(
3605
+ () => abortSignal.removeEventListener("abort", onAbort)
3606
+ ).catch(() => {
3367
3607
  });
3368
3608
  }
3369
3609
  return racedPromise;
@@ -3374,14 +3614,13 @@ function createAcpSessionBridge(opts) {
3374
3614
  }
3375
3615
  })
3376
3616
  );
3377
- const promptId = context?.promptId;
3378
3617
  result.then(
3379
3618
  (promptResult) => {
3380
3619
  broadcastTurnComplete(
3381
3620
  entry,
3382
3621
  sessionId,
3383
3622
  promptResult,
3384
- promptId,
3623
+ pendingEntry.promptId,
3385
3624
  originatorClientId
3386
3625
  );
3387
3626
  },
@@ -3391,7 +3630,7 @@ function createAcpSessionBridge(opts) {
3391
3630
  entry,
3392
3631
  sessionId,
3393
3632
  err,
3394
- promptId,
3633
+ pendingEntry.promptId,
3395
3634
  originatorClientId
3396
3635
  );
3397
3636
  }
@@ -3401,6 +3640,24 @@ function createAcpSessionBridge(opts) {
3401
3640
  () => void 0
3402
3641
  );
3403
3642
  result.finally(() => {
3643
+ const listIdx = entry.pendingPromptList.indexOf(pendingEntry);
3644
+ if (listIdx !== -1) {
3645
+ entry.pendingPromptList.splice(listIdx, 1);
3646
+ if (isQueued) {
3647
+ try {
3648
+ entry.events.publish({
3649
+ type: "pending_prompt_completed",
3650
+ data: {
3651
+ sessionId,
3652
+ promptId: pendingEntry.promptId,
3653
+ state: "completed"
3654
+ },
3655
+ ...originatorClientId ? { originatorClientId } : {}
3656
+ });
3657
+ } catch {
3658
+ }
3659
+ }
3660
+ }
3404
3661
  releasePromptSlot();
3405
3662
  if (entry.pendingPromptCount === 0 && entry.midTurnMessageQueue.length > 0) {
3406
3663
  writeStderrLine(
@@ -3837,6 +4094,54 @@ function createAcpSessionBridge(opts) {
3837
4094
  );
3838
4095
  return response;
3839
4096
  },
4097
+ async isWorkspaceMemoryRememberAvailable() {
4098
+ const info = await ensureChannel();
4099
+ try {
4100
+ const response = await withWorkspaceControl(
4101
+ info,
4102
+ () => withTimeout(
4103
+ Promise.race([
4104
+ info.connection.extMethod(
4105
+ SERVE_CONTROL_EXT_METHODS.workspaceMemoryRememberAvailability,
4106
+ { cwd: boundWorkspace }
4107
+ ),
4108
+ getChannelClosedReject(info)
4109
+ ]),
4110
+ initTimeoutMs,
4111
+ SERVE_CONTROL_EXT_METHODS.workspaceMemoryRememberAvailability
4112
+ )
4113
+ );
4114
+ return response !== null && typeof response === "object" && response["available"] === true;
4115
+ } finally {
4116
+ if (hasNoChannelWork(info)) {
4117
+ await startIdleTimer(info, "workspace memory remember availability");
4118
+ }
4119
+ }
4120
+ },
4121
+ async runWorkspaceMemoryRemember(request) {
4122
+ const info = await ensureChannel();
4123
+ try {
4124
+ const response = await withWorkspaceControl(
4125
+ info,
4126
+ () => withTimeout(
4127
+ Promise.race([
4128
+ info.connection.extMethod(
4129
+ SERVE_CONTROL_EXT_METHODS.workspaceMemoryRemember,
4130
+ { ...request, cwd: boundWorkspace }
4131
+ ),
4132
+ getChannelClosedReject(info)
4133
+ ]),
4134
+ WORKSPACE_MEMORY_REMEMBER_TIMEOUT_MS,
4135
+ SERVE_CONTROL_EXT_METHODS.workspaceMemoryRemember
4136
+ )
4137
+ );
4138
+ return parseWorkspaceMemoryRememberResult(response);
4139
+ } finally {
4140
+ if (hasNoChannelWork(info)) {
4141
+ await startIdleTimer(info, "workspace memory remember");
4142
+ }
4143
+ }
4144
+ },
3840
4145
  async getWorkspaceMcpToolsStatus(serverName) {
3841
4146
  return requestWorkspaceStatus(
3842
4147
  SERVE_STATUS_EXT_METHODS.workspaceMcpTools,
@@ -3942,6 +4247,39 @@ function createAcpSessionBridge(opts) {
3942
4247
  SERVE_CONTROL_EXT_METHODS.sessionGoalClear
3943
4248
  );
3944
4249
  },
4250
+ async continueSession(sessionId, context) {
4251
+ const entry = byId.get(sessionId);
4252
+ if (!entry) throw new SessionNotFoundError(sessionId);
4253
+ resolveTrustedClientId(entry, context?.clientId);
4254
+ const decision = await requestSessionStatus(sessionId, SERVE_CONTROL_EXT_METHODS.sessionContinue);
4255
+ if (!decision.accepted) {
4256
+ return decision;
4257
+ }
4258
+ const liveEntry = byId.get(sessionId);
4259
+ if (!liveEntry) throw new SessionNotFoundError(sessionId);
4260
+ const lastEventId = liveEntry.events.lastEventId;
4261
+ const promptId = context?.promptId;
4262
+ const promptPromise = bridgeApi.sendPrompt(
4263
+ sessionId,
4264
+ { sessionId, prompt: [] },
4265
+ void 0,
4266
+ {
4267
+ ...context?.clientId !== void 0 ? { clientId: context.clientId } : {},
4268
+ ...promptId !== void 0 ? { promptId } : {},
4269
+ continue: true
4270
+ }
4271
+ );
4272
+ promptPromise.catch((err) => {
4273
+ teeServeDebugLine(
4274
+ `continueSession: continuation turn failed for ${sessionId}: ${err instanceof Error ? err.message : String(err)}`
4275
+ );
4276
+ });
4277
+ return {
4278
+ ...decision,
4279
+ ...promptId !== void 0 ? { promptId } : {},
4280
+ lastEventId
4281
+ };
4282
+ },
3945
4283
  async getSessionStatsStatus(sessionId) {
3946
4284
  return requestSessionStatus(
3947
4285
  sessionId,
@@ -4266,6 +4604,44 @@ function createAcpSessionBridge(opts) {
4266
4604
  recap: response.recap ?? null
4267
4605
  };
4268
4606
  },
4607
+ getPendingPrompts(sessionId, context) {
4608
+ const entry = byId.get(sessionId);
4609
+ if (!entry) throw new SessionNotFoundError(sessionId);
4610
+ resolveTrustedClientId(entry, context?.clientId);
4611
+ return entry.pendingPromptList.map((p) => ({
4612
+ promptId: p.promptId,
4613
+ text: p.text,
4614
+ queuedAt: p.queuedAt,
4615
+ state: p.state,
4616
+ ...p.originatorClientId !== void 0 ? { originatorClientId: p.originatorClientId } : {}
4617
+ }));
4618
+ },
4619
+ removePendingPrompt(sessionId, promptId, context) {
4620
+ const entry = byId.get(sessionId);
4621
+ if (!entry) throw new SessionNotFoundError(sessionId);
4622
+ resolveTrustedClientId(entry, context?.clientId);
4623
+ const idx = entry.pendingPromptList.findIndex(
4624
+ (p) => p.promptId === promptId
4625
+ );
4626
+ if (idx === -1) return { removed: false };
4627
+ const target = entry.pendingPromptList[idx];
4628
+ writeStderrLine(
4629
+ `[pending-prompt] session=${sessionId} removing promptId=${promptId} state=${target.state}`
4630
+ );
4631
+ target.abortController.abort(
4632
+ new DOMException("Prompt removed by user", "AbortError")
4633
+ );
4634
+ entry.pendingPromptList.splice(idx, 1);
4635
+ try {
4636
+ entry.events.publish({
4637
+ type: "pending_prompt_completed",
4638
+ data: { sessionId, promptId, state: "removed" },
4639
+ ...target.originatorClientId ? { originatorClientId: target.originatorClientId } : {}
4640
+ });
4641
+ } catch {
4642
+ }
4643
+ return { removed: true };
4644
+ },
4269
4645
  enqueueMidTurnMessage(sessionId, message, context) {
4270
4646
  const entry = byId.get(sessionId);
4271
4647
  if (!entry) throw new SessionNotFoundError(sessionId);
@@ -4724,8 +5100,11 @@ function createAcpSessionBridge(opts) {
4724
5100
  } catch {
4725
5101
  }
4726
5102
  entry.events.close();
4727
- if (ci && ci.sessionIds.size === 0 && ci.pendingRestoreIds.size === 0) {
4728
- await startIdleTimer(ci, `killSession "${sessionId}"`);
5103
+ if (ci && hasNoChannelWork(ci)) {
5104
+ await reapPendingEmptyChannel(ci);
5105
+ if (!ci.isDying) {
5106
+ await startIdleTimer(ci, `killSession "${sessionId}"`);
5107
+ }
4729
5108
  }
4730
5109
  },
4731
5110
  async detachClient(sessionId, clientId) {
@@ -4812,11 +5191,12 @@ function createAcpSessionBridge(opts) {
4812
5191
  if (shuttingDown) return;
4813
5192
  const ci = await ensureChannel();
4814
5193
  const idleMs = resolvedChannelIdleTimeoutMs();
4815
- if (idleMs > 0 && ci.sessionIds.size === 0 && ci.pendingRestoreIds.size === 0) {
5194
+ if (idleMs > 0 && hasNoChannelWork(ci)) {
4816
5195
  await startIdleTimer(ci);
4817
5196
  }
4818
5197
  }
4819
5198
  };
5199
+ return bridgeApi;
4820
5200
  }
4821
5201
  __name(createAcpSessionBridge, "createAcpSessionBridge");
4822
5202
  async function withTimeout(p, ms, label) {