@qwen-code/qwen-code 0.19.11 → 0.19.12-preview.0

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 (304) hide show
  1. package/bundled/batch/SKILL.md +6 -0
  2. package/bundled/qc-helper/docs/configuration/model-providers.md +11 -0
  3. package/bundled/qc-helper/docs/configuration/settings.md +11 -10
  4. package/bundled/qc-helper/docs/features/channels/overview.md +66 -11
  5. package/bundled/qc-helper/docs/features/sub-agents.md +8 -8
  6. package/bundled/qc-helper/docs/features/worktree.md +2 -2
  7. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +42 -7
  8. package/bundled/qc-helper/docs/qwen-serve.md +102 -40
  9. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +1 -1
  10. package/bundled/review/SKILL.md +60 -49
  11. package/bundled/simplify/SKILL.md +1 -1
  12. package/chunks/{MaxSizedBox-L6TGYDM3.js → MaxSizedBox-3KIWAU6Z.js} +31 -32
  13. package/chunks/{StandaloneSessionPicker-AKEQHU5P.js → StandaloneSessionPicker-TF626NO7.js} +45 -46
  14. package/chunks/acp-startup-profiler-N3RHHXJ3.js +25 -0
  15. package/chunks/{acpAgent-PTNBGJDN.js → acpAgent-JDVJXVBO.js} +1863 -507
  16. package/chunks/{agent-AJOMOZPJ.js → agent-BONWC4VY.js} +26 -27
  17. package/chunks/{agent-headless-CYKOMAXS.js → agent-headless-H7HKMGLZ.js} +26 -27
  18. package/chunks/{anthropicContentGenerator-HBRXJSP4.js → anthropicContentGenerator-ZZRGFEES.js} +35 -12
  19. package/chunks/{artifact-tool-MIZLXBLF.js → artifact-tool-PHO5XEGZ.js} +5 -5
  20. package/chunks/{askUserQuestion-XMJVPNWM.js → askUserQuestion-CEPBT47X.js} +2 -47
  21. package/chunks/{bridge-QKISWPCI.js → bridge-ATN2TLWJ.js} +31 -32
  22. package/chunks/{ca-CODEN7TD.js → ca-2SL2BXTK.js} +3 -2
  23. package/chunks/{channel-worker-group-SOUWTFHC.js → channel-worker-group-S3H5QHTI.js} +4 -4
  24. package/chunks/{channel-worker-manager-LOVSV3WW.js → channel-worker-manager-ZJ4HTMO2.js} +4 -4
  25. package/chunks/{channel-worker-supervisor-XW6MHJBQ.js → channel-worker-supervisor-JA6VZ5V5.js} +3 -3
  26. package/chunks/{chunk-ZIXOTAPZ.js → chunk-2DZ7E27L.js} +92 -3
  27. package/chunks/{chunk-L5U3ELZX.js → chunk-335ECZTA.js} +1 -1
  28. package/chunks/{chunk-2FO5GFKZ.js → chunk-3DJY4IFO.js} +1 -1
  29. package/chunks/{chunk-4AGTGMCQ.js → chunk-3PE7OY2G.js} +12 -12
  30. package/chunks/{chunk-QOTQH4CB.js → chunk-4AGBO6RB.js} +27 -10
  31. package/chunks/{chunk-Y66VOBRP.js → chunk-4CA4WUMS.js} +2 -2
  32. package/chunks/{chunk-LQIDP6K5.js → chunk-4CHDYDG3.js} +1 -1
  33. package/chunks/{chunk-574PTLMU.js → chunk-4OVECYBM.js} +407 -92
  34. package/chunks/{chunk-TV6K2FB4.js → chunk-4RPARQ5D.js} +2 -2
  35. package/chunks/{chunk-TL4R5TRK.js → chunk-4W55BHOC.js} +2 -2
  36. package/chunks/{chunk-RCEEXIOO.js → chunk-4XCVGEEX.js} +3 -3
  37. package/chunks/{chunk-3DWIFU7L.js → chunk-53UMEONK.js} +1 -1
  38. package/chunks/{chunk-AU3MFJPL.js → chunk-54KPEDM2.js} +8 -8
  39. package/chunks/{chunk-T76DGHGG.js → chunk-66F4IJ4L.js} +5 -5
  40. package/chunks/{chunk-YLSSEUAM.js → chunk-675SVDMD.js} +354 -278
  41. package/chunks/{chunk-NVTQZXR7.js → chunk-6QGZVKOO.js} +91 -52
  42. package/chunks/{chunk-NJOFRXTM.js → chunk-6TDA4EVC.js} +4200 -3450
  43. package/chunks/{chunk-BYH2JRK3.js → chunk-6WZZHJSZ.js} +5 -5
  44. package/chunks/{chunk-7X7TEQNX.js → chunk-76BFY7AF.js} +13 -0
  45. package/chunks/chunk-7KS72E2N.js +883 -0
  46. package/chunks/{chunk-CF5VJRGC.js → chunk-7LMAKIWE.js} +1 -1
  47. package/chunks/{chunk-WMNXXRGL.js → chunk-7O7WZH7N.js} +31 -31
  48. package/chunks/{chunk-7ZYHLN67.js → chunk-7OZGMFHC.js} +26 -75
  49. package/chunks/{chunk-6WPJRYLZ.js → chunk-7SX6WZNO.js} +3 -3
  50. package/chunks/{chunk-JGUT3LWZ.js → chunk-ANRANWVE.js} +4 -1
  51. package/chunks/{chunk-JD44PNGJ.js → chunk-AWOU24F6.js} +10 -5
  52. package/chunks/{chunk-6WGZDD67.js → chunk-BEFQGC6H.js} +2 -2
  53. package/chunks/{chunk-KXYJPRT5.js → chunk-BEZPRKD3.js} +28 -6
  54. package/chunks/{chunk-FYQ22K62.js → chunk-CHVH4DVN.js} +6 -5
  55. package/chunks/{chunk-LS56TX3M.js → chunk-CMHJEUVB.js} +1 -1
  56. package/chunks/{chunk-FXKOAEXP.js → chunk-CXWUXRD5.js} +14 -14
  57. package/chunks/{chunk-CAHY5ABC.js → chunk-DULSE2SH.js} +1 -1
  58. package/chunks/{chunk-SQ5BK3GO.js → chunk-DYUPBU7H.js} +1 -1
  59. package/chunks/{chunk-FNX3LGAK.js → chunk-E655RDRL.js} +1 -1
  60. package/chunks/{chunk-N5VIZTND.js → chunk-EWPLL4OT.js} +1 -1
  61. package/chunks/{chunk-FSA7ERJ2.js → chunk-F2RR4HO2.js} +1 -1
  62. package/chunks/{chunk-S63Z5V42.js → chunk-F2YCCUXI.js} +4 -4
  63. package/chunks/{chunk-3AYLDB6B.js → chunk-FEZXQXW2.js} +1 -1
  64. package/chunks/{chunk-OWT2CAEQ.js → chunk-GEHSF7MS.js} +105 -12
  65. package/chunks/{chunk-LXLTBIDP.js → chunk-HCCR43AY.js} +1 -1
  66. package/chunks/{chunk-7NMU22Q3.js → chunk-HQ7MDVBO.js} +18 -7
  67. package/chunks/{chunk-KSZKSE23.js → chunk-HVWPSGDY.js} +1 -1
  68. package/chunks/{chunk-YFVO2HOR.js → chunk-HZXU6YZW.js} +5 -5
  69. package/chunks/{chunk-HASK4LMI.js → chunk-IKLWU6YS.js} +13 -6
  70. package/chunks/{chunk-GNBBAQ6J.js → chunk-ILQ42UG6.js} +111 -40
  71. package/chunks/{chunk-THXDQSTA.js → chunk-IQRQVPGN.js} +49 -154
  72. package/chunks/{chunk-SPJQO2CE.js → chunk-J2MKYJKZ.js} +2 -2
  73. package/chunks/{chunk-SUARMD4Q.js → chunk-J6NT5YTN.js} +28 -2
  74. package/chunks/{chunk-TYLOFD2U.js → chunk-JCJPZMJV.js} +1 -1
  75. package/chunks/{chunk-BYB3GF2T.js → chunk-JCYMQU5F.js} +133 -6
  76. package/chunks/{chunk-6EDDYPI3.js → chunk-JUNVFQVY.js} +4 -4
  77. package/chunks/{chunk-CH2XVB47.js → chunk-K7P34F2J.js} +3 -3
  78. package/chunks/{chunk-5VWYKIMW.js → chunk-KANTXY7B.js} +2 -2
  79. package/chunks/{chunk-K7VD4XLT.js → chunk-LHEQDKAR.js} +1 -1
  80. package/chunks/{chunk-A2HWMJVO.js → chunk-LKR7QQ63.js} +3 -3
  81. package/chunks/{chunk-4HUDDSO5.js → chunk-LLIGYAQU.js} +4 -4
  82. package/chunks/{chunk-5Z452MMD.js → chunk-LODZMRXC.js} +154 -83
  83. package/chunks/{chunk-FBU7WRZI.js → chunk-LPHGXXZX.js} +6 -1
  84. package/chunks/{chunk-CPFIQVZJ.js → chunk-LYFDJTXE.js} +1 -1
  85. package/chunks/{chunk-TIOE2OPE.js → chunk-MCYZTKBV.js} +2 -2
  86. package/chunks/{chunk-ZQIYGQCG.js → chunk-MHEZV3OY.js} +506 -143
  87. package/chunks/{chunk-JWICTOXS.js → chunk-NGTQA57Y.js} +2 -2
  88. package/chunks/{chunk-5CNYZ7TN.js → chunk-NJQPQ4IO.js} +7 -7
  89. package/chunks/chunk-NSZJQACR.js +45 -0
  90. package/chunks/{chunk-DOPUYNXO.js → chunk-NUHSLBJZ.js} +7 -7
  91. package/chunks/{chunk-CITWNIXJ.js → chunk-NVUGS23Y.js} +5 -5
  92. package/chunks/{chunk-2Z5UX4KI.js → chunk-OSSDHJDU.js} +1 -1
  93. package/chunks/{chunk-YUZI3WAC.js → chunk-OWAK7LMW.js} +7 -0
  94. package/chunks/{chunk-Y3KFTWVX.js → chunk-OZWJAFFE.js} +6 -6
  95. package/chunks/{chunk-YGYSMY2R.js → chunk-PSISZNIT.js} +1629 -1142
  96. package/chunks/{chunk-4ROQY23C.js → chunk-PTXVHS2O.js} +7 -7
  97. package/chunks/{chunk-OKAIGAYW.js → chunk-QGONRHUS.js} +3 -3
  98. package/chunks/{chunk-PZL23GTM.js → chunk-QR6U5QPP.js} +8 -0
  99. package/chunks/chunk-QSG4ZFG4.js +257 -0
  100. package/chunks/{chunk-BXBDC476.js → chunk-R32BTEZY.js} +5 -5
  101. package/chunks/{chunk-AVEOWVOM.js → chunk-R3VWUU2E.js} +1 -1
  102. package/chunks/{chunk-RP5R7MB6.js → chunk-R4RIMOJL.js} +12 -12
  103. package/chunks/{chunk-ARKANCNX.js → chunk-SGPFJMRP.js} +1 -1
  104. package/chunks/{chunk-3M75MSVA.js → chunk-SMASS3CY.js} +1 -1
  105. package/chunks/{chunk-4IJMTYCB.js → chunk-SNONG66P.js} +818 -29
  106. package/chunks/chunk-TDKQP3M6.js +201 -0
  107. package/chunks/{chunk-VFX7EZIR.js → chunk-TFV3XVAZ.js} +8 -1
  108. package/chunks/{chunk-4LD5APFL.js → chunk-TYQMGACW.js} +1 -0
  109. package/chunks/{chunk-7NFB7LBQ.js → chunk-UE5TZ55T.js} +8 -0
  110. package/chunks/{chunk-F333XEAU.js → chunk-UOA2IHRI.js} +4 -3
  111. package/chunks/{chunk-VRR65QYW.js → chunk-V4PCIS25.js} +5 -1
  112. package/chunks/{chunk-WIEO4CWB.js → chunk-VAJS2E2D.js} +1 -1
  113. package/chunks/{chunk-GLNHPRZT.js → chunk-W4DFAUAO.js} +1 -1
  114. package/chunks/{chunk-STZQCNN3.js → chunk-W7H223ZZ.js} +1 -1
  115. package/chunks/{chunk-6Y6ORE2G.js → chunk-WACI4VES.js} +288 -20
  116. package/chunks/{chunk-WTNZ6DXB.js → chunk-WEPXQKGP.js} +1 -1
  117. package/chunks/{chunk-4BJVSIS3.js → chunk-WHQNBBWW.js} +2 -2
  118. package/chunks/{chunk-QDJ2R4CM.js → chunk-WTHRMVKB.js} +3 -3
  119. package/chunks/{chunk-L4Y55KIS.js → chunk-X6YQWCIJ.js} +1 -1
  120. package/chunks/{chunk-Q6TUALBE.js → chunk-XAAEDML2.js} +1 -1
  121. package/chunks/{chunk-BUAXJVNP.js → chunk-XACBIZJB.js} +3 -3
  122. package/chunks/{chunk-2OG646IN.js → chunk-XFJU7SVP.js} +4 -4
  123. package/chunks/{chunk-KKRTYONM.js → chunk-XSPFQQRE.js} +3 -3
  124. package/chunks/{chunk-V2DXTLUE.js → chunk-Y5UDBQYF.js} +3 -3
  125. package/chunks/{chunk-MQOVXZAF.js → chunk-YN2I5I42.js} +529 -61
  126. package/chunks/{chunk-FMNYGWOD.js → chunk-Z4ZCVYJ5.js} +14 -8
  127. package/chunks/{chunk-SY7NEYX4.js → chunk-ZFHHBRRA.js} +2 -2
  128. package/chunks/{chunk-QYG4BY6Q.js → chunk-ZPVGEMVC.js} +1 -1
  129. package/chunks/{computer-use-VZZMJEQ7.js → computer-use-UY4A72X7.js} +26 -27
  130. package/chunks/{config-utils-IQQT3GCI.js → config-utils-KWTRFP7D.js} +3 -3
  131. package/chunks/{contextCommand-PORKIZSY.js → contextCommand-3DZ2SVH6.js} +30 -31
  132. package/chunks/{create-sub-session-EAB2U5XW.js → create-sub-session-DIJOV6HV.js} +2 -2
  133. package/chunks/{create-sub-session-XVFKHAFW.js → create-sub-session-OT7WXLDO.js} +27 -28
  134. package/chunks/{cron-create-GMVKSXZT.js → cron-create-X462ERYA.js} +4 -4
  135. package/chunks/{cron-delete-VDZKUAVK.js → cron-delete-SL5UJUM3.js} +4 -4
  136. package/chunks/{cron-list-UG7C7RAR.js → cron-list-3MD6SVXI.js} +4 -4
  137. package/chunks/{daemon-IHR6WSPB.js → daemon-ZW6LHOXT.js} +91 -14
  138. package/chunks/{daemon-status-provider-ABLBA3UJ.js → daemon-status-provider-GTZOYSBO.js} +35 -36
  139. package/chunks/{de-NOXPCSYN.js → de-I7ZIYXZC.js} +3 -2
  140. package/chunks/{dist-PX2ERZ6I.js → dist-HCUUS6IH.js} +2 -2
  141. package/chunks/{dist-VYWUKURL.js → dist-O2IP3G5D.js} +1 -1
  142. package/chunks/{dist-GXJVCOS7.js → dist-RZBJT5O2.js} +2 -1
  143. package/chunks/{dist-V2YVLYOW.js → dist-Y54RURGT.js} +3 -1
  144. package/chunks/{dist-DOPL5LSQ.js → dist-YTPTCUAD.js} +1 -1
  145. package/chunks/{dist-4WCQEZIN.js → dist-ZJHKKWUD.js} +1 -1
  146. package/chunks/{earlyInputCapture-DJCU5SPU.js → earlyInputCapture-GGWVGBZ7.js} +27 -28
  147. package/chunks/{edit-O4VV5AO6.js → edit-JN467GIR.js} +27 -28
  148. package/chunks/{en-JFVULHTB.js → en-XE34GKAA.js} +7 -3
  149. package/chunks/{enter-worktree-XQYDDI2I.js → enter-worktree-MMO4VBQE.js} +26 -27
  150. package/chunks/{enterPlanMode-CESVMQBV.js → enterPlanMode-BRZOG4DB.js} +27 -30
  151. package/chunks/{environment-5KXOLZNR.js → environment-LOCDCWMZ.js} +29 -30
  152. package/chunks/{errors-EBUTCBAQ.js → errors-XXSL5HGG.js} +29 -30
  153. package/chunks/{exit-worktree-MWGNSPNX.js → exit-worktree-UD7PI5H5.js} +26 -27
  154. package/chunks/exitPlanMode-EIUETQI6.js +389 -0
  155. package/chunks/{fast-path-6V73F2T2.js → fast-path-ULGAEUVK.js} +2 -2
  156. package/chunks/{fr-HVFNU42H.js → fr-X7KDVZIY.js} +3 -2
  157. package/chunks/{gemini-TEFJZCIZ.js → gemini-KW3APZ4P.js} +133 -80
  158. package/chunks/{geminiContentGenerator-M56BEXWI.js → geminiContentGenerator-4BQ5QHPR.js} +5 -5
  159. package/chunks/{glob-DMYFEEAZ.js → glob-FPKAMR6B.js} +32 -28
  160. package/chunks/{grep-GYE47MD4.js → grep-MOGRCYB4.js} +32 -28
  161. package/chunks/{handleAutoUpdate-OLUY4L7L.js → handleAutoUpdate-QUMRZZOS.js} +33 -34
  162. package/chunks/{i18n-462JC7IY.js → i18n-F3W6YUYP.js} +28 -29
  163. package/chunks/{initializer-Y7WD4D2I.js → initializer-KLU2KAIZ.js} +33 -34
  164. package/chunks/{installationInfo-I2Z3BKCE.js → installationInfo-P3ZP2SIZ.js} +27 -28
  165. package/chunks/{ja-PY5AF544.js → ja-2ICT3KXF.js} +3 -2
  166. package/chunks/{keychain-token-storage-AU22CQI6.js → keychain-token-storage-K23CFKGN.js} +2 -2
  167. package/chunks/{list-XQ5MSAXP.js → list-4X6D5JD2.js} +35 -36
  168. package/chunks/{loadedSettingsAdapter-TQOWYE7C.js → loadedSettingsAdapter-446B6WKA.js} +32 -33
  169. package/chunks/{loop-wakeup-QXWZSCYM.js → loop-wakeup-6H7OENTB.js} +5 -5
  170. package/chunks/{ls-2OUTG3IZ.js → ls-APTSOOS5.js} +4 -4
  171. package/chunks/{lsp-4VMNXZW6.js → lsp-HPACPJAN.js} +2 -2
  172. package/chunks/{mcp-22LLEEVM.js → mcp-JYVOJZOD.js} +32 -33
  173. package/chunks/{monitor-VKG324X3.js → monitor-KY7YH7TL.js} +26 -27
  174. package/chunks/nonInteractiveCli-EK35TLVJ.js +129 -0
  175. package/chunks/{notebook-edit-FJJRBQ3S.js → notebook-edit-IHGW42QK.js} +27 -28
  176. package/chunks/{openaiContentGenerator-4T2OGTR5.js → openaiContentGenerator-FURUCKQJ.js} +13 -14
  177. package/chunks/{pidfile-XL3MDCBM.js → pidfile-WKUVXDMR.js} +27 -28
  178. package/chunks/{processUtils-7UCFN34D.js → processUtils-LHSRN76X.js} +2 -2
  179. package/chunks/{pt-A3PRQXMU.js → pt-JJ4XPIBP.js} +3 -2
  180. package/chunks/{qwenContentGenerator-PQUXJDIZ.js → qwenContentGenerator-NRLM7R36.js} +30 -31
  181. package/chunks/{qwenOAuth2-LEYOU7RU.js → qwenOAuth2-5FNX3AWH.js} +22 -5
  182. package/chunks/{read-file-3EYQML7E.js → read-file-VLEAEXFP.js} +9 -10
  183. package/chunks/{read-mcp-resource-JUFHCKSC.js → read-mcp-resource-C6NT52T6.js} +2 -2
  184. package/chunks/{record-artifact-DWSMBXYY.js → record-artifact-ENCU7QCL.js} +2 -2
  185. package/chunks/{ripGrep-S6WPGQNA.js → ripGrep-MT23EIDD.js} +26 -27
  186. package/chunks/{ru-IBCWUTOC.js → ru-STR4KTW7.js} +3 -2
  187. package/chunks/{run-qwen-serve-NSKBT3HU.js → run-qwen-serve-5HWOQFLI.js} +63 -47
  188. package/chunks/{runtime-LG5ZZ3VH.js → runtime-6IVKJSLW.js} +38 -37
  189. package/chunks/{scheduler-PLX3VVTB.js → scheduler-63GJG75U.js} +26 -27
  190. package/chunks/{send-message-JZ752NWD.js → send-message-5GZ4FX2V.js} +3 -3
  191. package/chunks/{serve-S2ZLRZZR.js → serve-3LL7RRDP.js} +32 -33
  192. package/chunks/{server-5ECMV4TM.js → server-AA24QLPA.js} +1672 -615
  193. package/chunks/{session-ILSONWG4.js → session-LRVCFQQQ.js} +102 -75
  194. package/chunks/{settings-BOE7WWSA.js → settings-ZX3OKUT4.js} +36 -37
  195. package/chunks/{shell-VW664JIZ.js → shell-KR3IMYH6.js} +26 -27
  196. package/chunks/{skill-COHV6625.js → skill-QLM2LSF7.js} +11 -12
  197. package/chunks/{spawnChannel-5UUR5XOZ.js → spawnChannel-6WFOK3SA.js} +28 -29
  198. package/chunks/{src-XPKFZ3RN.js → src-ADLNIPHD.js} +101 -72
  199. package/chunks/{standalone-update-IOOJ2NZQ.js → standalone-update-C54OTJWJ.js} +29 -30
  200. package/chunks/{startInteractiveUI-3NGJGXXS.js → startInteractiveUI-KFAOS6HC.js} +2342 -1796
  201. package/chunks/{stdioHelpers-UMY72QRP.js → stdioHelpers-HGIYTWAY.js} +3 -1
  202. package/chunks/{syntheticOutput-LELY6HAI.js → syntheticOutput-ULOVVLY4.js} +3 -3
  203. package/chunks/{task-create-QY3BIMNM.js → task-create-DUE2PMNI.js} +7 -7
  204. package/chunks/{task-list-D2U47WBJ.js → task-list-WVPNX7BZ.js} +5 -5
  205. package/chunks/{task-stop-N6E5IYLH.js → task-stop-CPEQWOT6.js} +2 -2
  206. package/chunks/{task-update-HJCQILLB.js → task-update-HY2LNFFB.js} +7 -7
  207. package/chunks/{team-create-UPLVZQFX.js → team-create-Q5B5M7UD.js} +26 -27
  208. package/chunks/{team-delete-RCWYDRF4.js → team-delete-JJV6IUOA.js} +5 -5
  209. package/chunks/{team-plan-approval-F5F432RO.js → team-plan-approval-J55PXNY2.js} +26 -27
  210. package/chunks/{theme-manager-JJE4BJ67.js → theme-manager-QWTDRPHV.js} +27 -28
  211. package/chunks/todoWrite-JHHIDOIV.js +358 -0
  212. package/chunks/{tool-search-LRXI4JLZ.js → tool-search-LSSKWZKH.js} +10 -11
  213. package/chunks/{total-session-admission-I4DHN6UP.js → total-session-admission-S6ATY5HY.js} +32 -33
  214. package/chunks/{trustedFolders-SEH7LNX2.js → trustedFolders-CY4TUPDJ.js} +28 -29
  215. package/chunks/turndown.cjs-FZHGMUTY.js +17670 -0
  216. package/chunks/{update-relaunch-T6ZKBUA6.js → update-relaunch-IOKOUV3K.js} +6 -6
  217. package/chunks/{updateCheck-FWLXZPRO.js → updateCheck-YNRFE4V7.js} +30 -31
  218. package/chunks/{validateNonInterActiveAuth-X6K2VWYT.js → validateNonInterActiveAuth-OXTECS4B.js} +68 -68
  219. package/chunks/{version-LIFSOGSE.js → version-2CZQQDL5.js} +1 -1
  220. package/chunks/web-fetch-7QTEGJI5.js +938 -0
  221. package/chunks/{workflow-NX2DFWGD.js → workflow-G3CZU256.js} +29 -30
  222. package/chunks/{workspace-providers-status-VYD6M2NE.js → workspace-providers-status-UHQOIPAZ.js} +35 -36
  223. package/chunks/{workspace-registration-store-2Y6PWOEL.js → workspace-registration-store-5WPCMX4F.js} +1 -1
  224. package/chunks/{workspace-registry-PKBDBWCA.js → workspace-registry-LAQCRQTH.js} +32 -33
  225. package/chunks/{workspace-service-HHORUHTS.js → workspace-service-6ZEUJY2Z.js} +38 -39
  226. package/chunks/{workspace-skills-status-O5Q26LIY.js → workspace-skills-status-YG6OITSM.js} +33 -34
  227. package/chunks/{write-file-NVAEZ3J2.js → write-file-E7T3PU3B.js} +60 -28
  228. package/chunks/{zh-PAUNIMHQ.js → zh-6ANG2HTL.js} +7 -3
  229. package/chunks/{zh-TW-GNEUIUFF.js → zh-TW-4RR3YHNN.js} +7 -3
  230. package/cli-entry.js +37 -2
  231. package/cli.js +17 -11
  232. package/locales/ca.js +3 -2
  233. package/locales/de.js +3 -2
  234. package/locales/en.js +10 -5
  235. package/locales/fr.js +3 -2
  236. package/locales/ja.js +3 -2
  237. package/locales/pt.js +3 -2
  238. package/locales/ru.js +3 -2
  239. package/locales/zh-TW.js +9 -3
  240. package/locales/zh.js +9 -3
  241. package/package.json +3 -3
  242. package/web-shell/assets/{arc-H74fE8UR.js → arc-_dVIKMdB.js} +1 -1
  243. package/web-shell/assets/{architectureDiagram-3BPJPVTR-DN3kEq-I.js → architectureDiagram-3BPJPVTR-MuN3nKpL.js} +1 -1
  244. package/web-shell/assets/{blockDiagram-GPEHLZMM-BrqbsFUF.js → blockDiagram-GPEHLZMM-BtmvJjzx.js} +1 -1
  245. package/web-shell/assets/{c4Diagram-AAUBKEIU-ClFhU1P-.js → c4Diagram-AAUBKEIU-Dvi58_BU.js} +1 -1
  246. package/web-shell/assets/channel-Bi5TehaT.js +1 -0
  247. package/web-shell/assets/{chunk-2J33WTMH-jCIcG0_M.js → chunk-2J33WTMH-YqxOVhS1.js} +1 -1
  248. package/web-shell/assets/{chunk-4BX2VUAB-DSkGe62-.js → chunk-4BX2VUAB-DoBgbC9z.js} +1 -1
  249. package/web-shell/assets/{chunk-55IACEB6-BxBHOGTd.js → chunk-55IACEB6-3NEQrBAr.js} +1 -1
  250. package/web-shell/assets/{chunk-727SXJPM-v_DS7dH7.js → chunk-727SXJPM-DrCZQxp0.js} +1 -1
  251. package/web-shell/assets/{chunk-AQP2D5EJ-1RzEKRPq.js → chunk-AQP2D5EJ-m_g3zjgv.js} +1 -1
  252. package/web-shell/assets/{chunk-FMBD7UC4-DyrSbLOX.js → chunk-FMBD7UC4-D1_crABJ.js} +1 -1
  253. package/web-shell/assets/{chunk-ND2GUHAM-BCmdsZiy.js → chunk-ND2GUHAM-BdhgVtBx.js} +1 -1
  254. package/web-shell/assets/{chunk-QZHKN3VN-CphHGW2D.js → chunk-QZHKN3VN-BlmThhm-.js} +1 -1
  255. package/web-shell/assets/classDiagram-4FO5ZUOK-BKhhRdd1.js +1 -0
  256. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BKhhRdd1.js +1 -0
  257. package/web-shell/assets/{cose-bilkent-S5V4N54A-D5kRC7Fi.js → cose-bilkent-S5V4N54A-Cbjm_00Z.js} +1 -1
  258. package/web-shell/assets/{dagre-BM42HDAG-DIiyJJ0U.js → dagre-BM42HDAG-C39QNVgC.js} +1 -1
  259. package/web-shell/assets/{diagram-2AECGRRQ-BOcuB8xU.js → diagram-2AECGRRQ-DNXSAixC.js} +1 -1
  260. package/web-shell/assets/{diagram-5GNKFQAL-CMgiZ4d3.js → diagram-5GNKFQAL-BCbGUPEA.js} +1 -1
  261. package/web-shell/assets/{diagram-KO2AKTUF-Ctx8pfN0.js → diagram-KO2AKTUF-1eujKSDC.js} +1 -1
  262. package/web-shell/assets/{diagram-LMA3HP47-BT5REAWC.js → diagram-LMA3HP47-DUMKXgql.js} +1 -1
  263. package/web-shell/assets/{diagram-OG6HWLK6-CJkUqXcp.js → diagram-OG6HWLK6-BFktU3_u.js} +1 -1
  264. package/web-shell/assets/{erDiagram-TEJ5UH35-DyvNNX6v.js → erDiagram-TEJ5UH35-BvJC7DLk.js} +1 -1
  265. package/web-shell/assets/{flowDiagram-I6XJVG4X-VBf8_My8.js → flowDiagram-I6XJVG4X-Cgu3PlOt.js} +1 -1
  266. package/web-shell/assets/{ganttDiagram-6RSMTGT7-CviJnR7B.js → ganttDiagram-6RSMTGT7-DLNXN5Xh.js} +1 -1
  267. package/web-shell/assets/{gitGraphDiagram-PVQCEYII-BY66_Oze.js → gitGraphDiagram-PVQCEYII-BQFRDv6R.js} +1 -1
  268. package/web-shell/assets/index-C_ouplMQ.js +1187 -0
  269. package/web-shell/assets/{index-DhYuvi3j.js → index-CdC3pjP3.js} +1 -1
  270. package/web-shell/assets/index-XGDFJE-X.css +5 -0
  271. package/web-shell/assets/{infoDiagram-5YYISTIA-D2jaewWZ.js → infoDiagram-5YYISTIA-DT2mOSvp.js} +1 -1
  272. package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-BpnNTyi5.js → ishikawaDiagram-YF4QCWOH-9fy_K4bd.js} +1 -1
  273. package/web-shell/assets/{journeyDiagram-JHISSGLW-CA55GNZF.js → journeyDiagram-JHISSGLW-CoGSEuhE.js} +1 -1
  274. package/web-shell/assets/{kanban-definition-UN3LZRKU-DyiSl_Ts.js → kanban-definition-UN3LZRKU-BP9hHYIj.js} +1 -1
  275. package/web-shell/assets/{linear-B-sN3dkV.js → linear-uIroDsmp.js} +1 -1
  276. package/web-shell/assets/{mermaid.core-xf9SXDdb.js → mermaid.core-BUwoStsA.js} +5 -5
  277. package/web-shell/assets/{mindmap-definition-RKZ34NQL-DXhr2kRk.js → mindmap-definition-RKZ34NQL-DZB-FWim.js} +1 -1
  278. package/web-shell/assets/{pieDiagram-4H26LBE5-DUXpbfGQ.js → pieDiagram-4H26LBE5-YPptloKl.js} +1 -1
  279. package/web-shell/assets/{quadrantDiagram-W4KKPZXB-NeDQYeWw.js → quadrantDiagram-W4KKPZXB-dgk3DSzm.js} +1 -1
  280. package/web-shell/assets/{requirementDiagram-4Y6WPE33-BSbFRL1A.js → requirementDiagram-4Y6WPE33-BH2En2i9.js} +1 -1
  281. package/web-shell/assets/{sankeyDiagram-5OEKKPKP-gg27cAaN.js → sankeyDiagram-5OEKKPKP-BB98feeI.js} +1 -1
  282. package/web-shell/assets/{sequenceDiagram-3UESZ5HK-Bi_1TSs4.js → sequenceDiagram-3UESZ5HK-CunAIGh8.js} +1 -1
  283. package/web-shell/assets/{stateDiagram-AJRCARHV-CboCCRaf.js → stateDiagram-AJRCARHV-DTJs_-I2.js} +1 -1
  284. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-DrfFMYta.js +1 -0
  285. package/web-shell/assets/{timeline-definition-PNZ67QCA-DrGpF_jn.js → timeline-definition-PNZ67QCA-Cd4AN7O0.js} +1 -1
  286. package/web-shell/assets/{vennDiagram-CIIHVFJN-DCaJU67x.js → vennDiagram-CIIHVFJN-xIG-rUU9.js} +1 -1
  287. package/web-shell/assets/{wardley-L42UT6IY-p0QcW1aP.js → wardley-L42UT6IY-D1UyjIcG.js} +1 -1
  288. package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DiEVxj1W.js → wardleyDiagram-YWT4CUSO-BVM0Mb99.js} +1 -1
  289. package/web-shell/assets/{xychartDiagram-2RQKCTM6-iQB8nSlA.js → xychartDiagram-2RQKCTM6-BX31JDSz.js} +1 -1
  290. package/web-shell/index.html +2 -2
  291. package/chunks/chunk-2HRYPZT5.js +0 -25
  292. package/chunks/chunk-QAW7PIHT.js +0 -168
  293. package/chunks/chunk-RTV5TUYB.js +0 -143
  294. package/chunks/chunk-ZPAHLFZU.js +0 -172
  295. package/chunks/exitPlanMode-HYQL4XMB.js +0 -909
  296. package/chunks/nonInteractiveCli-UMYUT643.js +0 -129
  297. package/chunks/todoWrite-FKCGATPJ.js +0 -531
  298. package/chunks/web-fetch-CFCWTCAP.js +0 -5673
  299. package/web-shell/assets/channel-NFC5ADAa.js +0 -1
  300. package/web-shell/assets/classDiagram-4FO5ZUOK-DHgwjz3X.js +0 -1
  301. package/web-shell/assets/classDiagram-v2-Q7XG4LA2-DHgwjz3X.js +0 -1
  302. package/web-shell/assets/index-8xIBbHV3.js +0 -1143
  303. package/web-shell/assets/index-DLyhlZZO.css +0 -5
  304. package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CXRqms6P.js +0 -1
@@ -14,12 +14,12 @@ import {
14
14
  shouldSuppressRememberErrorDetails,
15
15
  workspaceMemoryFailureCode,
16
16
  workspaceMemoryFailureDiagnostics
17
- } from "./chunk-QOTQH4CB.js";
17
+ } from "./chunk-4AGBO6RB.js";
18
18
  import {
19
19
  openQwenAsrRealtimeStream,
20
20
  openVoiceStream,
21
21
  openVoiceStreamWithRetry
22
- } from "./chunk-5VWYKIMW.js";
22
+ } from "./chunk-KANTXY7B.js";
23
23
  import {
24
24
  SetupGithubError,
25
25
  collectSessionData,
@@ -30,11 +30,21 @@ import {
30
30
  toJson,
31
31
  toJsonl,
32
32
  toMarkdown
33
- } from "./chunk-6Y6ORE2G.js";
34
- import "./chunk-CF5VJRGC.js";
35
- import "./chunk-SUARMD4Q.js";
33
+ } from "./chunk-WACI4VES.js";
34
+ import {
35
+ OBSERVED_CONTACT_MAX_FRESH_WITHIN_SECONDS,
36
+ ObservedChannelContactStore
37
+ } from "./chunk-QSG4ZFG4.js";
38
+ import "./chunk-7LMAKIWE.js";
39
+ import "./chunk-J6NT5YTN.js";
36
40
  import "./chunk-QHTIBUWB.js";
41
+ import "./chunk-76BFY7AF.js";
42
+ import "./chunk-HTHUX2T5.js";
37
43
  import "./chunk-L573Z2QZ.js";
44
+ import {
45
+ createSingleWorkspaceRegistry,
46
+ createWorkspaceSessionOwnerIndex
47
+ } from "./chunk-W7H223ZZ.js";
38
48
  import {
39
49
  CAPABILITIES_SCHEMA_VERSION,
40
50
  CLIENT_ID_HEADER,
@@ -44,7 +54,6 @@ import {
44
54
  MAX_CLIENT_ID_LENGTH,
45
55
  MAX_CONCURRENT_VOICE_SESSIONS,
46
56
  MAX_SERVER_NAME_LENGTH,
47
- MAX_SKILL_NAME_LENGTH,
48
57
  MAX_TOOL_NAME_LENGTH,
49
58
  PathMutexRegistry,
50
59
  QWEN_CDP_MCP_COMMAND_ENV,
@@ -65,6 +74,7 @@ import {
65
74
  denyBrowserOriginCors,
66
75
  detectFromLoopback,
67
76
  getAdvertisedServeFeatures,
77
+ getDeferredRuntimeRequestTiming,
68
78
  getServeProtocolVersions,
69
79
  hostAllowlist,
70
80
  isBrowserAutomationMcpAvailable,
@@ -89,48 +99,51 @@ import {
89
99
  setRateLimiter,
90
100
  unsafeRevealSecret,
91
101
  validateMcpRuntimeServerName
92
- } from "./chunk-KXYJPRT5.js";
102
+ } from "./chunk-BEZPRKD3.js";
93
103
  import {
94
104
  isLoopbackBind
95
105
  } from "./chunk-RXFQM6FQ.js";
96
106
  import {
97
107
  createDaemonStatusProvider
98
- } from "./chunk-6EDDYPI3.js";
108
+ } from "./chunk-JUNVFQVY.js";
99
109
  import "./chunk-LXXMOYPL.js";
100
- import "./chunk-S63Z5V42.js";
110
+ import "./chunk-F2YCCUXI.js";
101
111
  import "./chunk-E5Z2AVNV.js";
102
112
  import {
103
113
  createWorkspaceProvidersStatusProvider
104
- } from "./chunk-7ZYHLN67.js";
114
+ } from "./chunk-7OZGMFHC.js";
105
115
  import {
106
116
  getAuthTypeFromEnv,
107
117
  resolveCliGenerationConfig
108
- } from "./chunk-ZIXOTAPZ.js";
118
+ } from "./chunk-2DZ7E27L.js";
109
119
  import {
110
120
  snapshotProcessEnv
111
- } from "./chunk-SY7NEYX4.js";
121
+ } from "./chunk-ZFHHBRRA.js";
112
122
  import {
113
123
  createWorkspaceSkillsStatusProvider
114
- } from "./chunk-JD44PNGJ.js";
124
+ } from "./chunk-AWOU24F6.js";
115
125
  import "./chunk-2W3OOD4W.js";
116
126
  import {
117
127
  EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
128
+ MAX_WORKSPACE_SKILL_NAME_LENGTH,
129
+ WorkspaceSkillManagementError,
118
130
  WorkspaceVoiceError,
119
131
  buildWorkspaceVoiceSettingsWrites,
120
132
  buildWorkspaceVoiceStatus,
121
133
  createDaemonWorkspaceService,
122
134
  hasConfiguredBatchVoiceTranscriptionModel,
123
135
  transcribeWorkspaceVoiceAudio,
136
+ validateWorkspaceSkillName,
124
137
  validateWorkspaceVoiceState,
125
138
  voiceSettingsScopeToWire
126
- } from "./chunk-4IJMTYCB.js";
139
+ } from "./chunk-SNONG66P.js";
127
140
  import {
128
141
  PermissionRulesValidationError,
129
142
  buildPermissionSettings,
130
143
  isPermissionRuleType,
131
144
  normalizePermissionRules,
132
145
  readPermissionRuleSet
133
- } from "./chunk-K7VD4XLT.js";
146
+ } from "./chunk-LHEQDKAR.js";
134
147
  import {
135
148
  assertVoiceBaseUrlNetworkAllowed,
136
149
  isStreamingVoiceModel,
@@ -138,13 +151,13 @@ import {
138
151
  resolveVoiceTranscriptionConfig,
139
152
  sanitizeVoiceErrorMessage,
140
153
  transcribeVoiceAudio
141
- } from "./chunk-BUAXJVNP.js";
154
+ } from "./chunk-XACBIZJB.js";
142
155
  import {
143
156
  isVoiceEnabled,
144
157
  isVoiceMode,
145
158
  readVoiceModel
146
- } from "./chunk-3M75MSVA.js";
147
- import "./chunk-FSA7ERJ2.js";
159
+ } from "./chunk-SMASS3CY.js";
160
+ import "./chunk-F2RR4HO2.js";
148
161
  import {
149
162
  WorkspacePermissionRulesSessionRequiredError,
150
163
  WorkspaceSettingsPartialPersistError,
@@ -153,24 +166,21 @@ import {
153
166
  } from "./chunk-OA4JVLSA.js";
154
167
  import {
155
168
  createTotalSessionAdmissionController
156
- } from "./chunk-AVEOWVOM.js";
157
- import {
158
- createSingleWorkspaceRegistry,
159
- createWorkspaceSessionOwnerIndex
160
- } from "./chunk-STZQCNN3.js";
169
+ } from "./chunk-R3VWUU2E.js";
161
170
  import "./chunk-GRC5HGPI.js";
162
171
  import {
163
172
  SessionArtifactAuthorizationError,
164
173
  SessionArtifactValidationError,
165
174
  createAcpSessionBridge,
166
175
  parseSessionSource
167
- } from "./chunk-574PTLMU.js";
168
- import "./chunk-PZL23GTM.js";
176
+ } from "./chunk-4OVECYBM.js";
169
177
  import {
170
178
  EVENT_SCHEMA_VERSION,
171
179
  SubscriberLimitExceededError
172
180
  } from "./chunk-6RLROE6G.js";
173
181
  import "./chunk-COH43MRJ.js";
182
+ import "./chunk-QR6U5QPP.js";
183
+ import "./chunk-FEZXQXW2.js";
174
184
  import {
175
185
  BranchWhilePromptActiveError,
176
186
  CancelSentinelCollisionError,
@@ -202,30 +212,30 @@ import {
202
212
  WorkspaceInitRaceError,
203
213
  WorkspaceInitSymlinkError,
204
214
  WorkspaceMismatchError
205
- } from "./chunk-L4Y55KIS.js";
215
+ } from "./chunk-X6YQWCIJ.js";
216
+ import {
217
+ STATUS_SCHEMA_VERSION,
218
+ createIdleWorkspaceMemoryStatus,
219
+ mapDomainErrorToErrorKind
220
+ } from "./chunk-TFV3XVAZ.js";
206
221
  import "./chunk-WBL3FJEU.js";
207
222
  import {
223
+ daemonObservedContactsPath,
208
224
  loadChannelsConfig
209
- } from "./chunk-7NMU22Q3.js";
210
- import "./chunk-YFVO2HOR.js";
225
+ } from "./chunk-HQ7MDVBO.js";
226
+ import "./chunk-HZXU6YZW.js";
211
227
  import "./chunk-57OAHC2Y.js";
212
228
  import {
213
229
  parseChannelWebhookConfigLenient
214
- } from "./chunk-5CNYZ7TN.js";
215
- import "./chunk-FNX3LGAK.js";
230
+ } from "./chunk-NJQPQ4IO.js";
231
+ import "./chunk-E655RDRL.js";
216
232
  import "./chunk-V6WHFGST.js";
217
- import "./chunk-3AYLDB6B.js";
218
- import {
219
- STATUS_SCHEMA_VERSION,
220
- createIdleWorkspaceMemoryStatus,
221
- mapDomainErrorToErrorKind
222
- } from "./chunk-VFX7EZIR.js";
223
233
  import {
224
234
  MAX_REGISTERED_WORKSPACES,
225
235
  WorkspaceRegistrationStoreCommittedError,
226
236
  WorkspaceRegistrationStoreLimitError,
227
237
  workspaceRegistrationId
228
- } from "./chunk-N5VIZTND.js";
238
+ } from "./chunk-EWPLL4OT.js";
229
239
  import {
230
240
  MAX_WORKSPACE_PATH_LENGTH,
231
241
  canonicalizeWorkspace,
@@ -239,7 +249,7 @@ import {
239
249
  QWEN_SERVER_TOKEN_ENV,
240
250
  isChannelWebhookEnqueueError,
241
251
  normalizeWorkerDiagnostic
242
- } from "./chunk-KSZKSE23.js";
252
+ } from "./chunk-HVWPSGDY.js";
243
253
  import {
244
254
  normalizeServeChannelSelection
245
255
  } from "./chunk-TJTKSVIV.js";
@@ -250,7 +260,7 @@ import "./chunk-5HBA2Z7V.js";
250
260
  import "./chunk-T2NCM2ET.js";
251
261
  import {
252
262
  sanitizeLogText
253
- } from "./chunk-ZQIYGQCG.js";
263
+ } from "./chunk-MHEZV3OY.js";
254
264
  import "./chunk-UDXSXLER.js";
255
265
  import {
256
266
  getDialogSettingKeys,
@@ -261,27 +271,27 @@ import {
261
271
  getWritableScopes,
262
272
  loadSettings,
263
273
  validateSettingValue
264
- } from "./chunk-GNBBAQ6J.js";
274
+ } from "./chunk-ILQ42UG6.js";
265
275
  import "./chunk-RKUWKYED.js";
266
- import {
267
- SUPPORTED_LANGUAGES
268
- } from "./chunk-4AGTGMCQ.js";
269
- import "./chunk-JWICTOXS.js";
270
276
  import "./chunk-GOXKNSDZ.js";
271
277
  import "./chunk-IDS7MSUP.js";
278
+ import {
279
+ SUPPORTED_LANGUAGES
280
+ } from "./chunk-3PE7OY2G.js";
281
+ import "./chunk-NGTQA57Y.js";
272
282
  import "./chunk-QRUIS3DN.js";
283
+ import "./chunk-W4DFAUAO.js";
284
+ import "./chunk-VJNBRRZG.js";
273
285
  import {
274
286
  getWorkspaceTrustStatus
275
- } from "./chunk-2OG646IN.js";
287
+ } from "./chunk-XFJU7SVP.js";
276
288
  import "./chunk-ALGGS7UH.js";
277
289
  import {
278
290
  isWithinRoot as isWithinRoot2
279
291
  } from "./chunk-MR3PXB6E.js";
280
292
  import {
281
293
  writeStderrLine
282
- } from "./chunk-YUZI3WAC.js";
283
- import "./chunk-GLNHPRZT.js";
284
- import "./chunk-VJNBRRZG.js";
294
+ } from "./chunk-OWAK7LMW.js";
285
295
  import {
286
296
  ALL_PROVIDERS,
287
297
  BTW_MAX_INPUT_LENGTH,
@@ -296,6 +306,7 @@ import {
296
306
  RUNTIME_MCP_IF_ABSENT_CONFIG_FLAG,
297
307
  SESSION_TRANSCRIPT_MAX_INDEX_BYTES,
298
308
  SESSION_TRANSCRIPT_MAX_LIMIT,
309
+ SESSION_TRANSCRIPT_MAX_PAGE_BYTES,
299
310
  SessionOrganizationError,
300
311
  SessionOrganizationService,
301
312
  SessionService,
@@ -314,6 +325,9 @@ import {
314
325
  buildUsageDashboard,
315
326
  detectLineEnding,
316
327
  encodeTextFileContent,
328
+ fetchGitDiff,
329
+ fetchGitDiffHunksForFile,
330
+ getGitWorkingTreeStatus,
317
331
  glob,
318
332
  loadIgnoreRules,
319
333
  loadUsageHistoryWithLive,
@@ -326,17 +340,17 @@ import {
326
340
  stripTerminalControlSequences,
327
341
  watchRepoBranch,
328
342
  writeWorkspaceContextFile
329
- } from "./chunk-NJOFRXTM.js";
343
+ } from "./chunk-6TDA4EVC.js";
344
+ import "./chunk-5M6IDOMF.js";
330
345
  import "./chunk-T4TZQJ7W.js";
331
346
  import "./chunk-H6XPXXMH.js";
332
- import "./chunk-5M6IDOMF.js";
333
347
  import {
334
348
  MAX_JOBS,
335
349
  nextDurableFireMs
336
- } from "./chunk-A2HWMJVO.js";
337
- import "./chunk-RCEEXIOO.js";
338
- import "./chunk-KKRTYONM.js";
339
- import "./chunk-TV6K2FB4.js";
350
+ } from "./chunk-LKR7QQ63.js";
351
+ import "./chunk-4XCVGEEX.js";
352
+ import "./chunk-XSPFQQRE.js";
353
+ import "./chunk-4RPARQ5D.js";
340
354
  import "./chunk-E2UVIFI2.js";
341
355
  import {
342
356
  nextFireTime,
@@ -350,7 +364,7 @@ import {
350
364
  readCronTasks,
351
365
  taskHasLegacyCondition,
352
366
  updateCronTasks
353
- } from "./chunk-SPJQO2CE.js";
367
+ } from "./chunk-J2MKYJKZ.js";
354
368
  import "./chunk-SZRN75WQ.js";
355
369
  import "./chunk-HTO4JFDZ.js";
356
370
  import "./chunk-CPBF7KYF.js";
@@ -358,12 +372,23 @@ import {
358
372
  APPROVAL_MODES,
359
373
  SubagentError,
360
374
  SubagentErrorCode
361
- } from "./chunk-F333XEAU.js";
375
+ } from "./chunk-UOA2IHRI.js";
362
376
  import "./chunk-6AM5D4ME.js";
363
- import "./chunk-2Z5UX4KI.js";
364
- import "./chunk-ARKANCNX.js";
365
- import "./chunk-L5U3ELZX.js";
366
- import "./chunk-TYLOFD2U.js";
377
+ import "./chunk-OSSDHJDU.js";
378
+ import "./chunk-SGPFJMRP.js";
379
+ import "./chunk-335ECZTA.js";
380
+ import "./chunk-JCJPZMJV.js";
381
+ import {
382
+ QwenOAuth2Client,
383
+ QwenOAuthPollError,
384
+ cacheQwenCredentials,
385
+ generatePKCEPair,
386
+ isDeviceAuthorizationSuccess,
387
+ isDeviceTokenPending,
388
+ isDeviceTokenSuccess
389
+ } from "./chunk-QGONRHUS.js";
390
+ import "./chunk-7KS72E2N.js";
391
+ import "./chunk-JESCGQM3.js";
367
392
  import {
368
393
  addDaemonRequestAttribute,
369
394
  decodeBufferWithEncodingInfo,
@@ -377,45 +402,33 @@ import {
377
402
  recordDaemonHttpRequest,
378
403
  recordDaemonHttpResponse,
379
404
  withDaemonRequestSpan
380
- } from "./chunk-MQOVXZAF.js";
405
+ } from "./chunk-YN2I5I42.js";
381
406
  import "./chunk-4WKAA4KS.js";
382
407
  import "./chunk-CR3C7WXL.js";
383
- import "./chunk-RTV5TUYB.js";
384
408
  import "./chunk-VGC4I5JJ.js";
385
- import "./chunk-FBU7WRZI.js";
386
- import "./chunk-Y66VOBRP.js";
387
- import "./chunk-WTNZ6DXB.js";
388
- import "./chunk-JGUT3LWZ.js";
389
- import {
390
- QwenOAuth2Client,
391
- QwenOAuthPollError,
392
- cacheQwenCredentials,
393
- generatePKCEPair,
394
- isDeviceAuthorizationSuccess,
395
- isDeviceTokenPending,
396
- isDeviceTokenSuccess
397
- } from "./chunk-OKAIGAYW.js";
398
- import "./chunk-ZPAHLFZU.js";
399
- import "./chunk-JESCGQM3.js";
400
- import "./chunk-WIEO4CWB.js";
409
+ import "./chunk-LPHGXXZX.js";
410
+ import "./chunk-4CA4WUMS.js";
411
+ import "./chunk-VAJS2E2D.js";
412
+ import "./chunk-WEPXQKGP.js";
413
+ import "./chunk-ANRANWVE.js";
401
414
  import "./chunk-XVNQMZ2I.js";
402
415
  import "./chunk-FEOZBUMT.js";
403
- import "./chunk-VRR65QYW.js";
416
+ import "./chunk-DJ2GSRLV.js";
417
+ import "./chunk-4CHDYDG3.js";
418
+ import "./chunk-V4PCIS25.js";
404
419
  import "./chunk-A4UCTEB5.js";
405
420
  import "./chunk-XWRJCPHC.js";
406
- import "./chunk-4LD5APFL.js";
421
+ import "./chunk-TYQMGACW.js";
407
422
  import {
408
423
  import_websocket_server
409
424
  } from "./chunk-TYAMGABM.js";
410
425
  import "./chunk-FCMNKVXT.js";
411
- import "./chunk-DJ2GSRLV.js";
412
- import "./chunk-LQIDP6K5.js";
413
426
  import {
414
427
  FatalConfigError,
415
428
  Storage,
416
429
  createDebugLogger,
417
430
  runWithoutDebugLogSession
418
- } from "./chunk-7NFB7LBQ.js";
431
+ } from "./chunk-UE5TZ55T.js";
419
432
  import "./chunk-75DOP5OR.js";
420
433
  import "./chunk-DMTGGOSA.js";
421
434
  import "./chunk-YQ3U5MUC.js";
@@ -2911,7 +2924,7 @@ async function handleSetupGithub(req, res, deps) {
2911
2924
  const result = await setupGithub({
2912
2925
  cwd: deps.boundWorkspace,
2913
2926
  workspaceRoot: deps.boundWorkspace,
2914
- proxy: resolveSetupGithubProxy(deps.boundWorkspace),
2927
+ proxy: resolveSetupGithubProxy(deps.boundWorkspace, deps.env),
2915
2928
  abortSignal: requestAbortSignal(req, res),
2916
2929
  fileOps: createSetupGithubFileOps(factory, ROUTE, originatorClientId)
2917
2930
  });
@@ -3129,14 +3142,14 @@ function setupGithubEventData(result) {
3129
3142
  };
3130
3143
  }
3131
3144
  __name(setupGithubEventData, "setupGithubEventData");
3132
- function resolveSetupGithubProxy(boundWorkspace) {
3145
+ function resolveSetupGithubProxy(boundWorkspace, env) {
3133
3146
  const settings = loadSettings(boundWorkspace, { skipLoadEnvironment: true });
3134
3147
  const trustState = getWorkspaceTrustStatus(
3135
3148
  settingsForSetupGithubTrust(settings),
3136
3149
  boundWorkspace
3137
3150
  ).effective.state;
3138
3151
  const settingsProxy = trustState === "trusted" ? settings.merged.proxy : settings.user.settings.proxy || settings.system.settings.proxy || settings.systemDefaults.settings.proxy;
3139
- return settingsProxy || process.env["HTTPS_PROXY"] || process.env["https_proxy"] || process.env["HTTP_PROXY"] || process.env["http_proxy"];
3152
+ return settingsProxy || env["HTTPS_PROXY"] || env["https_proxy"] || env["HTTP_PROXY"] || env["http_proxy"];
3140
3153
  }
3141
3154
  __name(resolveSetupGithubProxy, "resolveSetupGithubProxy");
3142
3155
  function settingsForSetupGithubTrust(settings) {
@@ -6954,9 +6967,10 @@ function rpcErrorFrame(id, err) {
6954
6967
  __name(rpcErrorFrame, "rpcErrorFrame");
6955
6968
  var ACP_PROTOCOL_VERSION = 1;
6956
6969
  var AcpDispatcher = class {
6957
- constructor(bridge, boundWorkspace, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator()) {
6970
+ constructor(bridge, boundWorkspace, env, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator()) {
6958
6971
  this.bridge = bridge;
6959
6972
  this.boundWorkspace = boundWorkspace;
6973
+ this.env = env;
6960
6974
  this.workspace = workspace;
6961
6975
  this.workspaceRememberLane = workspaceRememberLane;
6962
6976
  this.fsFactory = fsFactory;
@@ -8333,7 +8347,7 @@ var AcpDispatcher = class {
8333
8347
  const result = await setupGithub({
8334
8348
  cwd: this.boundWorkspace,
8335
8349
  workspaceRoot: this.boundWorkspace,
8336
- proxy: resolveSetupGithubProxy(this.boundWorkspace),
8350
+ proxy: resolveSetupGithubProxy(this.boundWorkspace, this.env),
8337
8351
  abortSignal: conn.abortSignal,
8338
8352
  fileOps: createSetupGithubFileOps(
8339
8353
  this.fsFactory,
@@ -11804,11 +11818,11 @@ function delay(ms) {
11804
11818
  return new Promise((resolve5) => setTimeout(resolve5, ms));
11805
11819
  }
11806
11820
  __name(delay, "delay");
11807
- function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname) {
11821
+ function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname, env) {
11808
11822
  if (localPort === void 0 || !Number.isInteger(localPort) || localPort <= 0) {
11809
11823
  return void 0;
11810
11824
  }
11811
- const command = resolveCdpMcpCommand(process.env);
11825
+ const command = resolveCdpMcpCommand(env);
11812
11826
  if (!command) {
11813
11827
  writeStderrLine(
11814
11828
  `qwen serve: set ${QWEN_CDP_MCP_COMMAND_ENV} to enable browser automation MCP (no adapter is bundled)`
@@ -11914,9 +11928,18 @@ function workspaceRateLimitKey(mount, clientKey) {
11914
11928
  return JSON.stringify([clientKey, mount.rateLimitScope]);
11915
11929
  }
11916
11930
  __name(workspaceRateLimitKey, "workspaceRateLimitKey");
11931
+ function runtimeEffectiveEnv(runtime, daemonEnv) {
11932
+ if (runtime.env.mode === "runtime-overlay") {
11933
+ return runtime.env.effectiveEnv ?? {};
11934
+ }
11935
+ return runtime.env.effectiveEnv ?? daemonEnv;
11936
+ }
11937
+ __name(runtimeEffectiveEnv, "runtimeEffectiveEnv");
11917
11938
  function mountAcpHttp(app, bridge, opts) {
11918
11939
  const enabled = opts.enabled ?? resolveAcpHttpEnabled();
11919
11940
  if (!enabled) return void 0;
11941
+ const daemonEnv = opts.daemonEnv ?? process.env;
11942
+ const primaryEnv = opts.workspaceRegistry ? runtimeEffectiveEnv(opts.workspaceRegistry.primary, daemonEnv) : daemonEnv;
11920
11943
  const path15 = opts.path ?? "/acp";
11921
11944
  const dispatcherRef = {};
11922
11945
  let disposed = false;
@@ -12006,7 +12029,8 @@ function mountAcpHttp(app, bridge, opts) {
12006
12029
  }
12007
12030
  const runtimeConfig = buildChromeDevToolsMcpRuntimeConfig(
12008
12031
  localPort,
12009
- opts.hostname
12032
+ opts.hostname,
12033
+ daemonEnv
12010
12034
  );
12011
12035
  if (!runtimeConfig) {
12012
12036
  cdpMcpTerminalSkipLogged = true;
@@ -12065,6 +12089,7 @@ function mountAcpHttp(app, bridge, opts) {
12065
12089
  const dispatcher = new AcpDispatcher(
12066
12090
  bridge,
12067
12091
  opts.boundWorkspace,
12092
+ primaryEnv,
12068
12093
  opts.workspace,
12069
12094
  opts.workspaceRememberLane,
12070
12095
  opts.fsFactory,
@@ -12353,6 +12378,7 @@ function mountAcpHttp(app, bridge, opts) {
12353
12378
  const secondaryDispatcher = new AcpDispatcher(
12354
12379
  rt.bridge,
12355
12380
  rt.workspaceCwd,
12381
+ runtimeEffectiveEnv(rt, daemonEnv),
12356
12382
  rt.workspaceService,
12357
12383
  workspaceRememberLane,
12358
12384
  rt.routeFileSystemFactory,
@@ -17714,157 +17740,772 @@ init_esbuild_shims();
17714
17740
 
17715
17741
  // packages/cli/src/serve/routes/session-runtime.ts
17716
17742
  init_esbuild_shims();
17717
- function requireSessionRuntime(opts) {
17718
- const {
17719
- sessionId,
17720
- route,
17721
- res,
17722
- workspaceRegistry,
17723
- daemonLog,
17724
- details = {}
17725
- } = opts;
17726
- if (workspaceRegistry.list().length === 1) {
17727
- return workspaceRegistry.primary;
17743
+
17744
+ // packages/cli/src/serve/server/telemetry.ts
17745
+ init_esbuild_shims();
17746
+ var legacySessionTelemetryRoutes = [
17747
+ {
17748
+ method: "POST",
17749
+ path: "/session",
17750
+ attribution: "handler_resolved",
17751
+ route: "POST /session"
17752
+ },
17753
+ {
17754
+ method: "POST",
17755
+ path: "/session/:id/load",
17756
+ attribution: "handler_resolved",
17757
+ route: "POST /session/:id/load"
17758
+ },
17759
+ {
17760
+ method: "POST",
17761
+ path: "/session/:id/resume",
17762
+ attribution: "handler_resolved",
17763
+ route: "POST /session/:id/resume"
17764
+ },
17765
+ {
17766
+ method: "POST",
17767
+ path: "/session/:id/branch",
17768
+ attribution: "handler_resolved",
17769
+ route: "POST /session/:id/branch"
17770
+ },
17771
+ {
17772
+ method: "POST",
17773
+ path: "/session/:id/fork",
17774
+ attribution: "handler_resolved",
17775
+ route: "POST /session/:id/fork"
17776
+ },
17777
+ {
17778
+ method: "POST",
17779
+ path: "/session/:id/cd",
17780
+ attribution: "handler_resolved",
17781
+ route: "POST /session/:id/cd"
17782
+ },
17783
+ {
17784
+ method: "GET",
17785
+ path: "/session/:id/status",
17786
+ attribution: "handler_resolved",
17787
+ route: "GET /session/:id/status"
17788
+ },
17789
+ {
17790
+ method: "GET",
17791
+ path: "/session/:id/export",
17792
+ attribution: "pre_resolved",
17793
+ route: "GET /session/:id/export"
17794
+ },
17795
+ {
17796
+ method: "GET",
17797
+ path: "/session/:id/transcript",
17798
+ attribution: "handler_resolved",
17799
+ route: "GET /session/:id/transcript"
17800
+ },
17801
+ {
17802
+ method: "GET",
17803
+ path: "/session/:id/context",
17804
+ attribution: "handler_resolved",
17805
+ route: "GET /session/:id/context"
17806
+ },
17807
+ {
17808
+ method: "GET",
17809
+ path: "/session/:id/context-usage",
17810
+ attribution: "handler_resolved",
17811
+ route: "GET /session/:id/context-usage"
17812
+ },
17813
+ {
17814
+ method: "GET",
17815
+ path: "/session/:id/stats",
17816
+ attribution: "handler_resolved",
17817
+ route: "GET /session/:id/stats"
17818
+ },
17819
+ {
17820
+ method: "GET",
17821
+ path: "/session/:id/supported-commands",
17822
+ attribution: "handler_resolved",
17823
+ route: "GET /session/:id/supported-commands"
17824
+ },
17825
+ {
17826
+ method: "GET",
17827
+ path: "/session/:id/tasks",
17828
+ attribution: "handler_resolved",
17829
+ route: "GET /session/:id/tasks"
17830
+ },
17831
+ {
17832
+ method: "GET",
17833
+ path: "/session/:id/lsp",
17834
+ attribution: "handler_resolved",
17835
+ route: "GET /session/:id/lsp"
17836
+ },
17837
+ {
17838
+ method: "GET",
17839
+ path: "/session/:id/hooks",
17840
+ attribution: "handler_resolved",
17841
+ route: "GET /session/:id/hooks"
17842
+ },
17843
+ {
17844
+ method: "GET",
17845
+ path: "/session/:id/artifacts",
17846
+ attribution: "handler_resolved",
17847
+ route: "GET /session/:id/artifacts"
17848
+ },
17849
+ {
17850
+ method: "POST",
17851
+ path: "/session/:id/artifacts",
17852
+ attribution: "handler_resolved",
17853
+ route: "POST /session/:id/artifacts"
17854
+ },
17855
+ {
17856
+ method: "DELETE",
17857
+ path: "/session/:id/artifacts/:artifactId",
17858
+ attribution: "handler_resolved",
17859
+ route: "DELETE /session/:id/artifacts/:artifactId"
17860
+ },
17861
+ {
17862
+ method: "POST",
17863
+ path: "/session/:id/tasks/:taskId/cancel",
17864
+ attribution: "handler_resolved",
17865
+ route: "POST /session/:id/tasks/:taskId/cancel"
17866
+ },
17867
+ {
17868
+ method: "POST",
17869
+ path: "/session/:id/goal/clear",
17870
+ attribution: "handler_resolved",
17871
+ route: "POST /session/:id/goal/clear"
17872
+ },
17873
+ {
17874
+ method: "POST",
17875
+ path: "/session/:id/continue",
17876
+ attribution: "handler_resolved",
17877
+ route: "POST /session/:id/continue"
17878
+ },
17879
+ {
17880
+ method: "POST",
17881
+ path: "/session/:id/prompt",
17882
+ attribution: "handler_resolved",
17883
+ route: "POST /session/:id/prompt"
17884
+ },
17885
+ {
17886
+ method: "POST",
17887
+ path: "/session/:id/generate",
17888
+ attribution: "handler_resolved",
17889
+ route: "POST /session/:id/generate"
17890
+ },
17891
+ {
17892
+ method: "POST",
17893
+ path: "/session/:id/heartbeat",
17894
+ attribution: "handler_resolved",
17895
+ route: "POST /session/:id/heartbeat"
17896
+ },
17897
+ {
17898
+ method: "POST",
17899
+ path: "/session/:id/detach",
17900
+ attribution: "handler_resolved",
17901
+ route: "POST /session/:id/detach"
17902
+ },
17903
+ {
17904
+ method: "POST",
17905
+ path: "/session/:id/cancel",
17906
+ attribution: "handler_resolved",
17907
+ route: "POST /session/:id/cancel"
17908
+ },
17909
+ {
17910
+ method: "DELETE",
17911
+ path: "/session/:id",
17912
+ attribution: "handler_resolved",
17913
+ route: "DELETE /session/:id"
17914
+ },
17915
+ {
17916
+ method: "POST",
17917
+ path: "/sessions/delete",
17918
+ attribution: "pre_resolved",
17919
+ route: "POST /sessions/delete"
17920
+ },
17921
+ {
17922
+ method: "POST",
17923
+ path: "/sessions/archive",
17924
+ attribution: "pre_resolved",
17925
+ route: "POST /sessions/archive"
17926
+ },
17927
+ {
17928
+ method: "POST",
17929
+ path: "/sessions/unarchive",
17930
+ attribution: "pre_resolved",
17931
+ route: "POST /sessions/unarchive"
17932
+ },
17933
+ {
17934
+ method: "PATCH",
17935
+ path: "/session/:id/metadata",
17936
+ attribution: "handler_resolved",
17937
+ route: "PATCH /session/:id/metadata"
17938
+ },
17939
+ {
17940
+ method: "PATCH",
17941
+ path: "/session/:id/organization",
17942
+ attribution: "pre_resolved",
17943
+ route: "PATCH /session/:id/organization"
17944
+ },
17945
+ {
17946
+ method: "POST",
17947
+ path: "/session/:id/model",
17948
+ attribution: "handler_resolved",
17949
+ route: "POST /session/:id/model"
17950
+ },
17951
+ {
17952
+ method: "POST",
17953
+ path: "/session/:id/recap",
17954
+ attribution: "handler_resolved",
17955
+ route: "POST /session/:id/recap"
17956
+ },
17957
+ {
17958
+ method: "POST",
17959
+ path: "/session/:id/btw",
17960
+ attribution: "handler_resolved",
17961
+ route: "POST /session/:id/btw"
17962
+ },
17963
+ {
17964
+ method: "POST",
17965
+ path: "/session/:id/mid-turn-message",
17966
+ attribution: "handler_resolved",
17967
+ route: "POST /session/:id/mid-turn-message"
17968
+ },
17969
+ {
17970
+ method: "GET",
17971
+ path: "/session/:id/pending-prompts",
17972
+ attribution: "handler_resolved",
17973
+ route: "GET /session/:id/pending-prompts"
17974
+ },
17975
+ {
17976
+ method: "DELETE",
17977
+ path: "/session/:id/pending-prompts/:promptId",
17978
+ attribution: "handler_resolved",
17979
+ route: "DELETE /session/:id/pending-prompts/:promptId"
17980
+ },
17981
+ {
17982
+ method: "POST",
17983
+ path: "/session/:id/shell",
17984
+ attribution: "handler_resolved",
17985
+ route: "POST /session/:id/shell"
17986
+ },
17987
+ {
17988
+ method: "GET",
17989
+ path: "/session/:id/rewind/snapshots",
17990
+ attribution: "handler_resolved",
17991
+ route: "GET /session/:id/rewind/snapshots"
17992
+ },
17993
+ {
17994
+ method: "POST",
17995
+ path: "/session/:id/rewind",
17996
+ attribution: "handler_resolved",
17997
+ route: "POST /session/:id/rewind"
17998
+ },
17999
+ {
18000
+ method: "POST",
18001
+ path: "/session/:id/approval-mode",
18002
+ attribution: "handler_resolved",
18003
+ route: "POST /session/:id/approval-mode"
18004
+ },
18005
+ {
18006
+ method: "POST",
18007
+ path: "/session/:id/language",
18008
+ attribution: "handler_resolved",
18009
+ route: "POST /session/:id/language"
18010
+ },
18011
+ {
18012
+ method: "POST",
18013
+ path: "/session/:id/permission/:requestId",
18014
+ attribution: "handler_resolved",
18015
+ route: "POST /session/:id/permission/:requestId"
18016
+ },
18017
+ {
18018
+ method: "POST",
18019
+ path: "/permission/:requestId",
18020
+ attribution: "pre_resolved",
18021
+ route: "POST /permission/:requestId"
18022
+ },
18023
+ {
18024
+ method: "GET",
18025
+ path: "/session/:id/events",
18026
+ attribution: "handler_resolved",
18027
+ route: "GET /session/:id/events"
18028
+ },
18029
+ {
18030
+ method: "POST",
18031
+ path: "/session/:id/a2ui-action",
18032
+ attribution: "pre_resolved",
18033
+ route: "POST /session/:id/a2ui-action"
17728
18034
  }
17729
- const resolution = workspaceRegistry.resolveLiveSessionOwner(sessionId);
17730
- if (resolution.kind === "found") {
17731
- const runtime = resolution.runtime;
17732
- if (!runtime.primary && !runtime.trusted) {
17733
- daemonLog?.warn("session routing failed", {
17734
- route,
17735
- resolutionKind: "untrusted_workspace",
17736
- sessionId,
17737
- workspaceId: runtime.workspaceId,
17738
- workspaceCwd: runtime.workspaceCwd,
17739
- ...details
17740
- });
17741
- sendUntrustedWorkspaceResponse(res, {
17742
- sessionId,
17743
- workspaceCwd: runtime.workspaceCwd,
17744
- workspaceId: runtime.workspaceId
17745
- });
17746
- return void 0;
17747
- }
17748
- return runtime;
18035
+ ];
18036
+ var daemonTelemetryResponseContext = Symbol("daemonTelemetryResponseContext");
18037
+ function decodePathSegment(value) {
18038
+ try {
18039
+ return decodeURIComponent(value);
18040
+ } catch {
18041
+ return value;
17749
18042
  }
17750
- if (resolution.kind === "not_found") {
17751
- daemonLog?.warn("session routing failed", {
17752
- route,
17753
- resolutionKind: "not_found",
17754
- sessionId,
17755
- ...details
17756
- });
17757
- res.status(404).json({
17758
- error: `No session with id "${sessionId}"`,
17759
- code: "session_not_found",
17760
- sessionId
17761
- });
18043
+ }
18044
+ __name(decodePathSegment, "decodePathSegment");
18045
+ function matchLegacySessionTelemetryRoute(method, requestPath) {
18046
+ const path15 = requestPath.length > 1 && requestPath.endsWith("/") ? requestPath.slice(0, -1) : requestPath;
18047
+ const requestSegments = path15.split("/").slice(1);
18048
+ const prefix = requestSegments[0]?.toLowerCase();
18049
+ if (prefix !== "session" && prefix !== "sessions" && prefix !== "permission") {
17762
18050
  return void 0;
17763
18051
  }
17764
- const workspaceIds = resolution.runtimes.map(
17765
- (runtime) => runtime.workspaceId
17766
- );
17767
- daemonLog?.warn("session routing failed", {
17768
- route,
17769
- resolutionKind: "ambiguous",
17770
- sessionId,
17771
- workspaceIds,
17772
- ...details
17773
- });
17774
- res.status(500).json({
17775
- error: `Session owner is ambiguous for "${sessionId}"`,
17776
- code: "ambiguous_session_owner",
17777
- sessionId,
17778
- route,
17779
- workspaceIds
17780
- });
17781
- return void 0;
17782
- }
17783
- __name(requireSessionRuntime, "requireSessionRuntime");
17784
-
17785
- // packages/cli/src/serve/routes/permission.ts
17786
- function registerPermissionRoutes(app, deps) {
17787
- const {
17788
- bridge,
17789
- workspaceRegistry,
17790
- daemonLog,
17791
- mutate,
17792
- sendPermissionVoteError: sendPermissionVoteError2
17793
- } = deps;
17794
- app.post("/session/:id/permission/:requestId", mutate(), (req, res) => {
17795
- const sessionId = req.params["id"];
17796
- const requestId = req.params["requestId"];
17797
- const response = parsePermissionVoteBody(req, res);
17798
- if (response === void 0) return;
17799
- const clientId = parseClientIdHeader(req, res);
17800
- if (clientId === null) return;
17801
- const fromLoopback = detectFromLoopback(req);
17802
- const context = {
17803
- ...clientId !== void 0 ? { clientId } : {},
17804
- fromLoopback
17805
- };
17806
- let accepted;
17807
- try {
17808
- const runtime = requireSessionRuntime({
17809
- sessionId,
17810
- route: "POST /session/:id/permission/:requestId",
17811
- res,
17812
- workspaceRegistry,
17813
- daemonLog,
17814
- details: { requestId }
17815
- });
17816
- if (!runtime) return;
17817
- accepted = runtime.bridge.respondToSessionPermission(
17818
- sessionId,
17819
- requestId,
17820
- response,
17821
- context
17822
- );
17823
- } catch (err) {
17824
- sendPermissionVoteError2(res, err, {
17825
- route: "POST /session/:id/permission/:requestId",
17826
- sessionId
17827
- });
17828
- return;
17829
- }
17830
- if (!accepted) {
17831
- res.status(404).json({
17832
- error: "No pending permission request for session",
17833
- sessionId,
17834
- requestId
17835
- });
17836
- return;
18052
+ for (const entry of legacySessionTelemetryRoutes) {
18053
+ if (entry.method !== method) continue;
18054
+ const templateSegments = entry.path.split("/").slice(1);
18055
+ if (templateSegments.length !== requestSegments.length) continue;
18056
+ const params = /* @__PURE__ */ new Map();
18057
+ let matched = true;
18058
+ for (let index = 0; index < templateSegments.length; index += 1) {
18059
+ const templateSegment = templateSegments[index];
18060
+ const requestSegment = requestSegments[index];
18061
+ if (templateSegment.startsWith(":")) {
18062
+ if (requestSegment === "") {
18063
+ matched = false;
18064
+ break;
18065
+ }
18066
+ params.set(templateSegment.slice(1), requestSegment);
18067
+ } else if (templateSegment.toLowerCase() !== requestSegment.toLowerCase()) {
18068
+ matched = false;
18069
+ break;
18070
+ }
17837
18071
  }
17838
- res.status(200).json({});
17839
- });
17840
- app.post("/permission/:requestId", mutate(), (req, res) => {
17841
- const requestId = req.params["requestId"];
17842
- const response = parsePermissionVoteBody(req, res);
17843
- if (response === void 0) return;
17844
- const clientId = parseClientIdHeader(req, res);
17845
- if (clientId === null) return;
17846
- const fromLoopback = detectFromLoopback(req);
17847
- const context = {
17848
- ...clientId !== void 0 ? { clientId } : {},
17849
- fromLoopback
18072
+ if (!matched) continue;
18073
+ const rawSessionId = params.get("id");
18074
+ const rawRequestId = params.get("requestId");
18075
+ const requestId = rawRequestId !== void 0 ? decodePathSegment(rawRequestId) : void 0;
18076
+ return {
18077
+ route: entry.route,
18078
+ attribution: entry.attribution,
18079
+ ...rawSessionId ? { sessionId: decodePathSegment(rawSessionId) } : {},
18080
+ ...requestId !== void 0 && requestId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(requestId) ? { permissionRequestId: requestId } : {}
17850
18081
  };
17851
- let accepted;
17852
- try {
17853
- accepted = bridge.respondToPermission(requestId, response, context);
17854
- } catch (err) {
17855
- sendPermissionVoteError2(res, err, {
17856
- route: "POST /permission/:requestId"
17857
- });
17858
- return;
17859
- }
17860
- if (!accepted) {
17861
- res.status(404).json({ error: "No pending permission request", requestId });
17862
- return;
18082
+ }
18083
+ return void 0;
18084
+ }
18085
+ __name(matchLegacySessionTelemetryRoute, "matchLegacySessionTelemetryRoute");
18086
+ function setDaemonTelemetryWorkspace(res, workspaceCwd) {
18087
+ try {
18088
+ const context = res[daemonTelemetryResponseContext];
18089
+ if (context && context.workspaceCwd === void 0) {
18090
+ context.workspaceCwd = workspaceCwd;
17863
18091
  }
17864
- res.status(200).json({});
17865
- });
18092
+ } catch {
18093
+ }
17866
18094
  }
17867
- __name(registerPermissionRoutes, "registerPermissionRoutes");
18095
+ __name(setDaemonTelemetryWorkspace, "setDaemonTelemetryWorkspace");
18096
+ function resolveDaemonTelemetryRoute(req) {
18097
+ const legacyRoute = matchLegacySessionTelemetryRoute(req.method, req.path);
18098
+ if (legacyRoute) return legacyRoute;
18099
+ const path15 = req.path.replace(/\/$/, "") || "/";
18100
+ if (req.method === "GET" && path15 === "/daemon/status") {
18101
+ return { route: "GET /daemon/status" };
18102
+ }
18103
+ if (req.method === "GET" && /^\/workspace\/[^/]+\/sessions$/.test(path15)) {
18104
+ return { route: "GET /workspace/:id/sessions" };
18105
+ }
18106
+ if (req.method === "GET" && /^\/workspaces\/[^/]+\/sessions$/.test(path15)) {
18107
+ return { route: "GET /workspace/:id/sessions" };
18108
+ }
18109
+ if (req.method === "GET" && /^\/workspace\/[^/]+\/session-info$/.test(path15)) {
18110
+ return { route: "GET /workspace/:id/session-info" };
18111
+ }
18112
+ if (req.method === "GET" && /^\/workspaces\/[^/]+\/session-info$/.test(path15)) {
18113
+ return { route: "GET /workspace/:id/session-info" };
18114
+ }
18115
+ const workspaceTranscript = path15.match(
18116
+ /^\/workspaces\/[^/]+\/session\/([^/]+)\/transcript$/
18117
+ );
18118
+ if (workspaceTranscript?.[1] && req.method === "GET") {
18119
+ return {
18120
+ route: "GET /workspaces/:workspace/session/:id/transcript",
18121
+ sessionId: decodePathSegment(workspaceTranscript[1])
18122
+ };
18123
+ }
18124
+ const workspaceExport = path15.match(
18125
+ /^\/workspaces\/[^/]+\/session\/([^/]+)\/export$/
18126
+ );
18127
+ if (workspaceExport?.[1] && req.method === "GET") {
18128
+ return {
18129
+ route: "GET /workspaces/:workspace/session/:id/export",
18130
+ sessionId: decodePathSegment(workspaceExport[1])
18131
+ };
18132
+ }
18133
+ const workspaceArchivedExport = path15.match(
18134
+ /^\/workspaces\/[^/]+\/session\/([^/]+)\/archive\/export$/
18135
+ );
18136
+ if (workspaceArchivedExport?.[1] && req.method === "GET") {
18137
+ return {
18138
+ route: "GET /workspaces/:workspace/session/:id/archive/export",
18139
+ sessionId: decodePathSegment(workspaceArchivedExport[1])
18140
+ };
18141
+ }
18142
+ const pluralWorkspacePrefix = /^\/workspaces\/[^/]+/;
18143
+ if (pluralWorkspacePrefix.test(path15)) {
18144
+ const suffix = path15.replace(pluralWorkspacePrefix, "/workspace");
18145
+ if (req.method === "GET") {
18146
+ if (suffix === "/workspace/mcp" || suffix === "/workspace/skills" || suffix === "/workspace/tools" || suffix === "/workspace/providers" || suffix === "/workspace/env" || suffix === "/workspace/preflight" || suffix === "/workspace/hooks" || suffix === "/workspace/settings" || suffix === "/workspace/voice" || suffix === "/workspace/permissions" || suffix === "/workspace/trust" || suffix === "/workspace/memory" || suffix === "/workspace/agents") {
18147
+ return { route: `GET ${suffix}` };
18148
+ }
18149
+ if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
18150
+ return { route: "GET /workspace/agents/:agentType" };
18151
+ }
18152
+ if (suffix === "/workspace/file") return { route: "GET /file" };
18153
+ if (suffix === "/workspace/file/bytes") {
18154
+ return { route: "GET /file/bytes" };
18155
+ }
18156
+ if (suffix === "/workspace/stat") return { route: "GET /stat" };
18157
+ if (suffix === "/workspace/list") return { route: "GET /list" };
18158
+ if (suffix === "/workspace/glob") return { route: "GET /glob" };
18159
+ if (/^\/workspace\/mcp\/[^/]+\/tools$/.test(suffix)) {
18160
+ return { route: "GET /workspace/mcp/:server/tools" };
18161
+ }
18162
+ if (/^\/workspace\/mcp\/[^/]+\/resources$/.test(suffix)) {
18163
+ return { route: "GET /workspace/mcp/:server/resources" };
18164
+ }
18165
+ }
18166
+ if (req.method === "POST") {
18167
+ if (suffix === "/workspace/settings" || suffix === "/workspace/voice" || suffix === "/workspace/voice/transcribe" || suffix === "/workspace/permissions" || suffix === "/workspace/trust/request" || suffix === "/workspace/init" || suffix === "/workspace/reload" || suffix === "/workspace/file/write" || suffix === "/workspace/file/edit" || suffix === "/workspace/mcp/servers" || suffix === "/workspace/memory" || suffix === "/workspace/agents" || suffix === "/workspace/sessions/delete" || suffix === "/workspace/sessions/archive" || suffix === "/workspace/sessions/unarchive" || suffix === "/workspace/session-groups") {
18168
+ return { route: `POST ${suffix}` };
18169
+ }
18170
+ if (/^\/workspace\/tools\/[^/]+\/enable$/.test(suffix)) {
18171
+ return { route: "POST /workspace/tools/:name/enable" };
18172
+ }
18173
+ if (/^\/workspace\/mcp\/[^/]+\/restart$/.test(suffix)) {
18174
+ return { route: "POST /workspace/mcp/:server/restart" };
18175
+ }
18176
+ if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
18177
+ return { route: "POST /workspace/agents/:agentType" };
18178
+ }
18179
+ if (/^\/workspace\/mcp\/[^/]+\/(approve|enable|disable|authenticate|clear-auth)$/.test(
18180
+ suffix
18181
+ )) {
18182
+ return {
18183
+ route: `POST /workspace/mcp/:server/${suffix.split("/").at(-1)}`
18184
+ };
18185
+ }
18186
+ }
18187
+ if (req.method === "DELETE" && /^\/workspace\/mcp\/servers\/[^/]+$/.test(suffix)) {
18188
+ return { route: "DELETE /workspace/mcp/servers/:name" };
18189
+ }
18190
+ if (req.method === "DELETE" && /^\/workspace\/agents\/[^/]+$/.test(suffix)) {
18191
+ return { route: "DELETE /workspace/agents/:agentType" };
18192
+ }
18193
+ if (suffix === "/workspace/session-groups" && req.method === "GET") {
18194
+ return { route: "GET /workspace/session-groups" };
18195
+ }
18196
+ if (/^\/workspace\/session-groups\/[^/]+$/.test(suffix) && req.method === "PATCH") {
18197
+ return { route: "PATCH /workspace/session-groups/:groupId" };
18198
+ }
18199
+ if (/^\/workspace\/session-groups\/[^/]+$/.test(suffix) && req.method === "DELETE") {
18200
+ return { route: "DELETE /workspace/session-groups/:groupId" };
18201
+ }
18202
+ }
18203
+ if (req.method === "POST" && path15 === "/workspace/init") {
18204
+ return { route: "POST /workspace/init" };
18205
+ }
18206
+ if (req.method === "POST" && path15 === "/workspace/setup-github") {
18207
+ return { route: "POST /workspace/setup-github" };
18208
+ }
18209
+ if (req.method === "POST" && path15 === "/workspace/reload") {
18210
+ return { route: "POST /workspace/reload" };
18211
+ }
18212
+ const mcpRestart = path15.match(/^\/workspace\/mcp\/([^/]+)\/restart$/);
18213
+ if (mcpRestart?.[1] && req.method === "POST") {
18214
+ return { route: "POST /workspace/mcp/:server/restart" };
18215
+ }
18216
+ if (req.method === "POST" && path15 === "/workspace/mcp/servers") {
18217
+ return { route: "POST /workspace/mcp/servers" };
18218
+ }
18219
+ const mcpDelete = path15.match(/^\/workspace\/mcp\/servers\/([^/]+)$/);
18220
+ if (mcpDelete?.[1] && req.method === "DELETE") {
18221
+ return { route: "DELETE /workspace/mcp/servers/:name" };
18222
+ }
18223
+ if (req.method === "POST" && path15 === "/workspace/auth/device-flow") {
18224
+ return { route: "POST /workspace/auth/device-flow" };
18225
+ }
18226
+ const deviceFlowDelete = path15.match(
18227
+ /^\/workspace\/auth\/device-flow\/([^/]+)$/
18228
+ );
18229
+ if (deviceFlowDelete?.[1] && req.method === "DELETE") {
18230
+ return { route: "DELETE /workspace/auth/device-flow/:id" };
18231
+ }
18232
+ const toolEnable = path15.match(/^\/workspace\/tools\/([^/]+)\/enable$/);
18233
+ if (toolEnable?.[1] && req.method === "POST") {
18234
+ return { route: "POST /workspace/tools/:name/enable" };
18235
+ }
18236
+ if (path15 === "/workspace/settings") {
18237
+ if (req.method === "GET") return { route: "GET /workspace/settings" };
18238
+ if (req.method === "POST") return { route: "POST /workspace/settings" };
18239
+ }
18240
+ if (path15 === "/workspace/permissions") {
18241
+ if (req.method === "GET") return { route: "GET /workspace/permissions" };
18242
+ if (req.method === "POST") return { route: "POST /workspace/permissions" };
18243
+ }
18244
+ if (path15 === "/workspace/trust") {
18245
+ if (req.method === "GET") return { route: "GET /workspace/trust" };
18246
+ }
18247
+ if (req.method === "POST" && path15 === "/workspace/trust/request") {
18248
+ return { route: "POST /workspace/trust/request" };
18249
+ }
18250
+ if (path15 === "/workspace/voice") {
18251
+ if (req.method === "GET") return { route: "GET /workspace/voice" };
18252
+ if (req.method === "POST") return { route: "POST /workspace/voice" };
18253
+ }
18254
+ if (req.method === "POST" && path15 === "/workspace/voice/transcribe") {
18255
+ return { route: "POST /workspace/voice/transcribe" };
18256
+ }
18257
+ return void 0;
18258
+ }
18259
+ __name(resolveDaemonTelemetryRoute, "resolveDaemonTelemetryRoute");
18260
+ function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest) {
18261
+ const workspaceHashByCwd = /* @__PURE__ */ new Map();
18262
+ const resolveWorkspaceHash = /* @__PURE__ */ __name((workspaceCwd) => {
18263
+ const existing = workspaceHashByCwd.get(workspaceCwd);
18264
+ if (existing !== void 0) return existing;
18265
+ const workspaceHash = hashDaemonWorkspace(workspaceCwd);
18266
+ workspaceHashByCwd.set(workspaceCwd, workspaceHash);
18267
+ return workspaceHash;
18268
+ }, "resolveWorkspaceHash");
18269
+ return (req, res, next) => {
18270
+ const route = resolveDaemonTelemetryRoute(req);
18271
+ if (!route) {
18272
+ next();
18273
+ return;
18274
+ }
18275
+ const sessionId = route.sessionId;
18276
+ let workspaceHash;
18277
+ if (route.attribution !== "handler_resolved") {
18278
+ try {
18279
+ workspaceHash = resolveWorkspaceHash(resolveWorkspaceCwd(req));
18280
+ } catch {
18281
+ }
18282
+ }
18283
+ const rawClientId = req.get(CLIENT_ID_HEADER);
18284
+ const clientId = rawClientId !== void 0 && rawClientId !== "" && rawClientId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawClientId) ? rawClientId : void 0;
18285
+ const deferredRuntime = getDeferredRuntimeRequestTiming(req);
18286
+ const startMs = deferredRuntime?.startedAt.getTime() ?? Date.now();
18287
+ const telemetryRes = res;
18288
+ if (route.attribution === "handler_resolved") {
18289
+ try {
18290
+ telemetryRes[daemonTelemetryResponseContext] = {};
18291
+ } catch {
18292
+ }
18293
+ }
18294
+ void withDaemonRequestSpan(
18295
+ {
18296
+ method: req.method,
18297
+ route: route.route,
18298
+ ...workspaceHash !== void 0 ? { workspaceHash } : {},
18299
+ ...sessionId ? { sessionId } : {},
18300
+ ...route.permissionRequestId ? { permissionRequestId: route.permissionRequestId } : {},
18301
+ ...clientId ? { clientId } : {},
18302
+ ...deferredRuntime?.waitMs !== void 0 ? {
18303
+ startTime: deferredRuntime.startedAt,
18304
+ deferredRuntimeWaitMs: deferredRuntime.waitMs,
18305
+ deferredRuntimePath: deferredRuntime.path
18306
+ } : {}
18307
+ },
18308
+ async (span) => await new Promise((resolve5, reject) => {
18309
+ let done = false;
18310
+ const finish = /* @__PURE__ */ __name(() => {
18311
+ if (done) return;
18312
+ done = true;
18313
+ try {
18314
+ const context = telemetryRes[daemonTelemetryResponseContext];
18315
+ delete telemetryRes[daemonTelemetryResponseContext];
18316
+ if (context?.workspaceCwd !== void 0) {
18317
+ span?.setAttribute(
18318
+ "qwen-code.workspace.hash",
18319
+ resolveWorkspaceHash(context.workspaceCwd)
18320
+ );
18321
+ }
18322
+ } catch {
18323
+ }
18324
+ recordDaemonHttpResponse(span, res.statusCode);
18325
+ const durationMs = Date.now() - startMs;
18326
+ const successfulSse = route.route === "GET /session/:id/events" && res.statusCode === 200 && res.headersSent;
18327
+ if (!successfulSse) {
18328
+ recordDaemonHttpRequest(
18329
+ durationMs,
18330
+ route.route,
18331
+ res.statusCode,
18332
+ deferredRuntime?.path
18333
+ );
18334
+ }
18335
+ if (!successfulSse && route.route !== "GET /daemon/status" && route.route !== "POST /session/:id/heartbeat") {
18336
+ recordRequest?.(durationMs, res.statusCode);
18337
+ }
18338
+ resolve5();
18339
+ }, "finish");
18340
+ res.once("finish", finish);
18341
+ res.once("close", finish);
18342
+ try {
18343
+ next();
18344
+ } catch (error2) {
18345
+ recordDaemonError(span, error2);
18346
+ reject(error2);
18347
+ }
18348
+ })
18349
+ ).catch(next);
18350
+ };
18351
+ }
18352
+ __name(daemonTelemetryMiddleware, "daemonTelemetryMiddleware");
18353
+
18354
+ // packages/cli/src/serve/routes/session-runtime.ts
18355
+ function requireSessionRuntime(opts) {
18356
+ const {
18357
+ sessionId,
18358
+ route,
18359
+ res,
18360
+ workspaceRegistry,
18361
+ daemonLog,
18362
+ details = {}
18363
+ } = opts;
18364
+ if (workspaceRegistry.list().length === 1) {
18365
+ const runtime = workspaceRegistry.primary;
18366
+ setDaemonTelemetryWorkspace(res, runtime.workspaceCwd);
18367
+ return runtime;
18368
+ }
18369
+ const resolution = workspaceRegistry.resolveLiveSessionOwner(sessionId);
18370
+ if (resolution.kind === "found") {
18371
+ const runtime = resolution.runtime;
18372
+ setDaemonTelemetryWorkspace(res, runtime.workspaceCwd);
18373
+ if (!runtime.primary && !runtime.trusted) {
18374
+ daemonLog?.warn("session routing failed", {
18375
+ route,
18376
+ resolutionKind: "untrusted_workspace",
18377
+ sessionId,
18378
+ workspaceId: runtime.workspaceId,
18379
+ workspaceCwd: runtime.workspaceCwd,
18380
+ ...details
18381
+ });
18382
+ sendUntrustedWorkspaceResponse(res, {
18383
+ sessionId,
18384
+ workspaceCwd: runtime.workspaceCwd,
18385
+ workspaceId: runtime.workspaceId
18386
+ });
18387
+ return void 0;
18388
+ }
18389
+ return runtime;
18390
+ }
18391
+ if (resolution.kind === "not_found") {
18392
+ daemonLog?.warn("session routing failed", {
18393
+ route,
18394
+ resolutionKind: "not_found",
18395
+ sessionId,
18396
+ ...details
18397
+ });
18398
+ res.status(404).json({
18399
+ error: `No session with id "${sessionId}"`,
18400
+ code: "session_not_found",
18401
+ sessionId
18402
+ });
18403
+ return void 0;
18404
+ }
18405
+ const workspaceIds = resolution.runtimes.map(
18406
+ (runtime) => runtime.workspaceId
18407
+ );
18408
+ daemonLog?.warn("session routing failed", {
18409
+ route,
18410
+ resolutionKind: "ambiguous",
18411
+ sessionId,
18412
+ workspaceIds,
18413
+ ...details
18414
+ });
18415
+ res.status(500).json({
18416
+ error: `Session owner is ambiguous for "${sessionId}"`,
18417
+ code: "ambiguous_session_owner",
18418
+ sessionId,
18419
+ route,
18420
+ workspaceIds
18421
+ });
18422
+ return void 0;
18423
+ }
18424
+ __name(requireSessionRuntime, "requireSessionRuntime");
18425
+
18426
+ // packages/cli/src/serve/routes/permission.ts
18427
+ function registerPermissionRoutes(app, deps) {
18428
+ const {
18429
+ bridge,
18430
+ workspaceRegistry,
18431
+ daemonLog,
18432
+ mutate,
18433
+ sendPermissionVoteError: sendPermissionVoteError2
18434
+ } = deps;
18435
+ app.post("/session/:id/permission/:requestId", mutate(), (req, res) => {
18436
+ const sessionId = req.params["id"];
18437
+ const requestId = req.params["requestId"];
18438
+ const response = parsePermissionVoteBody(req, res);
18439
+ if (response === void 0) return;
18440
+ const clientId = parseClientIdHeader(req, res);
18441
+ if (clientId === null) return;
18442
+ const fromLoopback = detectFromLoopback(req);
18443
+ const context = {
18444
+ ...clientId !== void 0 ? { clientId } : {},
18445
+ fromLoopback
18446
+ };
18447
+ let accepted;
18448
+ try {
18449
+ const runtime = requireSessionRuntime({
18450
+ sessionId,
18451
+ route: "POST /session/:id/permission/:requestId",
18452
+ res,
18453
+ workspaceRegistry,
18454
+ daemonLog,
18455
+ details: { requestId }
18456
+ });
18457
+ if (!runtime) return;
18458
+ accepted = runtime.bridge.respondToSessionPermission(
18459
+ sessionId,
18460
+ requestId,
18461
+ response,
18462
+ context
18463
+ );
18464
+ } catch (err) {
18465
+ sendPermissionVoteError2(res, err, {
18466
+ route: "POST /session/:id/permission/:requestId",
18467
+ sessionId
18468
+ });
18469
+ return;
18470
+ }
18471
+ if (!accepted) {
18472
+ res.status(404).json({
18473
+ error: "No pending permission request for session",
18474
+ sessionId,
18475
+ requestId
18476
+ });
18477
+ return;
18478
+ }
18479
+ res.status(200).json({});
18480
+ });
18481
+ app.post("/permission/:requestId", mutate(), (req, res) => {
18482
+ const requestId = req.params["requestId"];
18483
+ const response = parsePermissionVoteBody(req, res);
18484
+ if (response === void 0) return;
18485
+ const clientId = parseClientIdHeader(req, res);
18486
+ if (clientId === null) return;
18487
+ const fromLoopback = detectFromLoopback(req);
18488
+ const context = {
18489
+ ...clientId !== void 0 ? { clientId } : {},
18490
+ fromLoopback
18491
+ };
18492
+ let accepted;
18493
+ try {
18494
+ accepted = bridge.respondToPermission(requestId, response, context);
18495
+ } catch (err) {
18496
+ sendPermissionVoteError2(res, err, {
18497
+ route: "POST /permission/:requestId"
18498
+ });
18499
+ return;
18500
+ }
18501
+ if (!accepted) {
18502
+ res.status(404).json({ error: "No pending permission request", requestId });
18503
+ return;
18504
+ }
18505
+ res.status(200).json({});
18506
+ });
18507
+ }
18508
+ __name(registerPermissionRoutes, "registerPermissionRoutes");
17868
18509
 
17869
18510
  // packages/cli/src/serve/routes/session.ts
17870
18511
  init_esbuild_shims();
@@ -18379,6 +19020,19 @@ function listLiveWorkspaceSessionsForResponse(bridge, workspaceCwd, options) {
18379
19020
  };
18380
19021
  }
18381
19022
  __name(listLiveWorkspaceSessionsForResponse, "listLiveWorkspaceSessionsForResponse");
19023
+ async function getWorkspaceSessionInfoForResponse(bridge, workspaceCwd, options = {}) {
19024
+ const counts = await new SessionService(workspaceCwd).getSessionInfoCounts();
19025
+ return {
19026
+ active: counts.active,
19027
+ archived: counts.archived,
19028
+ total: counts.total,
19029
+ ...options.includeLive === false ? {} : { live: bridge.listWorkspaceSessions(workspaceCwd).length },
19030
+ expensive: true,
19031
+ cost: "disk_scan",
19032
+ ...counts.truncated ? { truncated: true } : {}
19033
+ };
19034
+ }
19035
+ __name(getWorkspaceSessionInfoForResponse, "getWorkspaceSessionInfoForResponse");
18382
19036
  function parseSessionPageSizeQuery(raw) {
18383
19037
  if (typeof raw !== "string") return void 0;
18384
19038
  const trimmed = raw.trim();
@@ -18451,11 +19105,21 @@ async function exportSessionTranscript(params) {
18451
19105
  __name(exportSessionTranscript, "exportSessionTranscript");
18452
19106
 
18453
19107
  // packages/cli/src/serve/routes/session.ts
18454
- var WORKSPACE_TRANSCRIPT_PAGE_SOURCE_MAX_BYTES = 4 * 1024 * 1024;
18455
19108
  var WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES = 32 * 1024 * 1024;
18456
19109
  var WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES = 64 * 1024;
18457
19110
  var TRANSCRIPT_CURSOR_TOO_LARGE_REPLAY_ERROR = "Transcript pagination state exceeds the safe limit";
18458
19111
  var GENERATION_HEARTBEAT_MS = 15e3;
19112
+ var PRIMARY_ONLY_LIVE_SESSION_ROUTES = [
19113
+ "POST /session/:id/branch",
19114
+ "POST /session/:id/fork",
19115
+ "POST /session/:id/cd"
19116
+ ];
19117
+ function isPrimaryOnlyLiveSessionRoute(route) {
19118
+ return PRIMARY_ONLY_LIVE_SESSION_ROUTES.includes(
19119
+ route
19120
+ );
19121
+ }
19122
+ __name(isPrimaryOnlyLiveSessionRoute, "isPrimaryOnlyLiveSessionRoute");
18459
19123
  function formatGenerationSse(event, data) {
18460
19124
  return `event: ${event}
18461
19125
  data: ${JSON.stringify({ v: 1, ...data })}
@@ -18584,6 +19248,32 @@ function parseTranscriptCursorQuery(rawCursor, res) {
18584
19248
  return rawCursor;
18585
19249
  }
18586
19250
  __name(parseTranscriptCursorQuery, "parseTranscriptCursorQuery");
19251
+ function parseTranscriptRecordBoundaryQuery(rawBoundary, res) {
19252
+ if (rawBoundary === void 0) return void 0;
19253
+ if (typeof rawBoundary !== "string" || rawBoundary.trim() === "" || rawBoundary.length > 200) {
19254
+ res.status(400).json({
19255
+ error: "`beforeRecordId` must be a non-empty record id",
19256
+ code: "invalid_transcript_cursor"
19257
+ });
19258
+ return null;
19259
+ }
19260
+ return rawBoundary;
19261
+ }
19262
+ __name(parseTranscriptRecordBoundaryQuery, "parseTranscriptRecordBoundaryQuery");
19263
+ function parseHistoryPageSize(body, res) {
19264
+ const value = body["historyPageSize"];
19265
+ if (value === void 0) return void 0;
19266
+ if (!Number.isSafeInteger(value) || value < 1 || value > SESSION_TRANSCRIPT_MAX_LIMIT) {
19267
+ res.status(400).json({
19268
+ error: `\`historyPageSize\` must be between 1 and ${SESSION_TRANSCRIPT_MAX_LIMIT}`,
19269
+ code: "invalid_transcript_limit",
19270
+ maxLimit: SESSION_TRANSCRIPT_MAX_LIMIT
19271
+ });
19272
+ return null;
19273
+ }
19274
+ return value;
19275
+ }
19276
+ __name(parseHistoryPageSize, "parseHistoryPageSize");
18587
19277
  function workspaceTranscriptCursorExceedsLimit(cursor, maxBytes = WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES) {
18588
19278
  return Buffer.byteLength(cursor) > maxBytes;
18589
19279
  }
@@ -18705,6 +19395,7 @@ function registerSessionRoutes(app, deps) {
18705
19395
  return void 0;
18706
19396
  }
18707
19397
  if (workspaceRegistry.list().length === 1) {
19398
+ setDaemonTelemetryWorkspace(res, workspaceRegistry.primary.workspaceCwd);
18708
19399
  return {
18709
19400
  runtime: workspaceRegistry.primary,
18710
19401
  workspaceCwd: "cwd" in body ? key : workspaceRegistry.primary.workspaceCwd
@@ -18720,6 +19411,7 @@ function registerSessionRoutes(app, deps) {
18720
19411
  sendWorkspaceMismatch2(res, key);
18721
19412
  return void 0;
18722
19413
  }
19414
+ setDaemonTelemetryWorkspace(res, runtime.workspaceCwd);
18723
19415
  if (!runtime.primary && !runtime.trusted) {
18724
19416
  logSessionRoutingFailure("POST /session", "untrusted_workspace", {
18725
19417
  workspaceId: runtime.workspaceId,
@@ -18972,6 +19664,7 @@ function registerSessionRoutes(app, deps) {
18972
19664
  sendWorkspaceMismatch2(res, key);
18973
19665
  return void 0;
18974
19666
  }
19667
+ setDaemonTelemetryWorkspace(res, runtime.workspaceCwd);
18975
19668
  if (!runtime.primary && !runtime.trusted) {
18976
19669
  logSessionRoutingFailure(route, "untrusted_workspace", {
18977
19670
  workspaceId: runtime.workspaceId,
@@ -19009,7 +19702,7 @@ function registerSessionRoutes(app, deps) {
19009
19702
  }), "resolveLiveSessionRuntime");
19010
19703
  const sendNonPrimarySessionRouteUnsupported = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
19011
19704
  res.status(400).json({
19012
- error: `Route "${route}" is primary-only for non-primary workspace sessions in Phase 2a.`,
19705
+ error: `Route "${route}" is only available for primary workspace sessions.`,
19013
19706
  code: "non_primary_session_route_not_supported",
19014
19707
  sessionId,
19015
19708
  workspaceId: runtime.workspaceId,
@@ -19057,6 +19750,7 @@ function registerSessionRoutes(app, deps) {
19057
19750
  }, "throwMissingActiveTranscript");
19058
19751
  if (workspaceRegistry.list().length === 1) {
19059
19752
  const runtime = workspaceRegistry.primary;
19753
+ setDaemonTelemetryWorkspace(res, runtime.workspaceCwd);
19060
19754
  if (await activeInRuntime(runtime)) {
19061
19755
  return runtime;
19062
19756
  }
@@ -19068,6 +19762,7 @@ function registerSessionRoutes(app, deps) {
19068
19762
  return void 0;
19069
19763
  }
19070
19764
  if (liveOwner.kind === "found") {
19765
+ setDaemonTelemetryWorkspace(res, liveOwner.runtime.workspaceCwd);
19071
19766
  if (!assertTrustedSessionOwner(res, route, sessionId, liveOwner.runtime)) {
19072
19767
  return void 0;
19073
19768
  }
@@ -19102,6 +19797,7 @@ function registerSessionRoutes(app, deps) {
19102
19797
  }
19103
19798
  if (activeRuntimes.length === 1) {
19104
19799
  const runtime = activeRuntimes[0];
19800
+ setDaemonTelemetryWorkspace(res, runtime.workspaceCwd);
19105
19801
  if (!assertTrustedSessionOwner(res, route, sessionId, runtime)) {
19106
19802
  return void 0;
19107
19803
  }
@@ -19158,23 +19854,37 @@ function registerSessionRoutes(app, deps) {
19158
19854
  }
19159
19855
  return key;
19160
19856
  }, "resolveWorkspaceParam");
19161
- const withMutableSession = /* @__PURE__ */ __name((route, handler) => async (req, res) => {
19162
- const sessionId = requireSessionId(req, res);
19163
- if (sessionId === null) return;
19164
- const runtime = resolveLiveSessionRuntime(sessionId, res, route);
19165
- if (!runtime) return;
19166
- if (!runtime.primary) {
19167
- sendNonPrimarySessionRouteUnsupported(res, route, sessionId, runtime);
19168
- return;
19169
- }
19170
- try {
19171
- await archiveCoordinator.runSharedMany([sessionId], async () => {
19172
- await handler(req, res, sessionId);
19173
- });
19174
- } catch (err) {
19175
- sendBridgeError2(res, err, { route, sessionId });
19857
+ const withPrimaryOnlyMutableSession = /* @__PURE__ */ __name((route, handler) => {
19858
+ if (!isPrimaryOnlyLiveSessionRoute(route)) {
19859
+ throw new Error(`Unregistered primary-only session route: ${route}`);
19176
19860
  }
19177
- }, "withMutableSession");
19861
+ return async (req, res) => {
19862
+ const sessionId = requireSessionId(req, res);
19863
+ if (sessionId === null) return;
19864
+ const runtime = resolveLiveSessionRuntime(sessionId, res, route);
19865
+ if (!runtime) return;
19866
+ if (!runtime.primary) {
19867
+ logSessionRoutingFailure(
19868
+ route,
19869
+ "non_primary_session_route_not_supported",
19870
+ {
19871
+ sessionId,
19872
+ workspaceId: runtime.workspaceId,
19873
+ workspaceCwd: runtime.workspaceCwd
19874
+ }
19875
+ );
19876
+ sendNonPrimarySessionRouteUnsupported(res, route, sessionId, runtime);
19877
+ return;
19878
+ }
19879
+ try {
19880
+ await archiveCoordinator.runSharedMany([sessionId], async () => {
19881
+ await handler(req, res, sessionId);
19882
+ });
19883
+ } catch (err) {
19884
+ sendBridgeError2(res, err, { route, sessionId });
19885
+ }
19886
+ };
19887
+ }, "withPrimaryOnlyMutableSession");
19178
19888
  app.post("/session", mutate(), async (req, res) => {
19179
19889
  const body = safeBody(req);
19180
19890
  const resolvedRuntime = resolveRuntimeForSessionCreation(body, res);
@@ -19285,6 +19995,11 @@ function registerSessionRoutes(app, deps) {
19285
19995
  releaseRestoreOwner();
19286
19996
  return;
19287
19997
  }
19998
+ const historyPageSize = action === "load" ? parseHistoryPageSize(body ?? {}, res) : void 0;
19999
+ if (historyPageSize === null) {
20000
+ releaseRestoreOwner();
20001
+ return;
20002
+ }
19288
20003
  const clientId = parseClientIdHeader(req, res);
19289
20004
  if (clientId === null) {
19290
20005
  releaseRestoreOwner();
@@ -19302,6 +20017,7 @@ function registerSessionRoutes(app, deps) {
19302
20017
  sessionId,
19303
20018
  workspaceCwd,
19304
20019
  historyReplay: "response",
20020
+ ...historyPageSize !== void 0 ? { historyPageSize } : {},
19305
20021
  ...clientId !== void 0 ? { clientId } : {},
19306
20022
  ...approvalMode !== void 0 ? { approvalMode } : {},
19307
20023
  ...metadata
@@ -19345,7 +20061,7 @@ function registerSessionRoutes(app, deps) {
19345
20061
  app.post(
19346
20062
  "/session/:id/branch",
19347
20063
  mutate(),
19348
- withMutableSession(
20064
+ withPrimaryOnlyMutableSession(
19349
20065
  "POST /session/:id/branch",
19350
20066
  async (req, res, sessionId) => {
19351
20067
  const body = safeBody(req);
@@ -19380,7 +20096,7 @@ function registerSessionRoutes(app, deps) {
19380
20096
  app.post(
19381
20097
  "/session/:id/fork",
19382
20098
  mutate(),
19383
- withMutableSession(
20099
+ withPrimaryOnlyMutableSession(
19384
20100
  "POST /session/:id/fork",
19385
20101
  async (req, res, sessionId) => {
19386
20102
  const body = safeBody(req);
@@ -19406,25 +20122,28 @@ function registerSessionRoutes(app, deps) {
19406
20122
  app.post(
19407
20123
  "/session/:id/cd",
19408
20124
  mutate(),
19409
- withMutableSession("POST /session/:id/cd", async (req, res, sessionId) => {
19410
- const body = safeBody(req);
19411
- const targetPath = body["path"];
19412
- if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
19413
- res.status(400).json({
19414
- error: "`path` is required and must be an absolute path",
19415
- code: "invalid_path"
19416
- });
19417
- return;
20125
+ withPrimaryOnlyMutableSession(
20126
+ "POST /session/:id/cd",
20127
+ async (req, res, sessionId) => {
20128
+ const body = safeBody(req);
20129
+ const targetPath = body["path"];
20130
+ if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
20131
+ res.status(400).json({
20132
+ error: "`path` is required and must be an absolute path",
20133
+ code: "invalid_path"
20134
+ });
20135
+ return;
20136
+ }
20137
+ const clientId = parseClientIdHeader(req, res);
20138
+ if (clientId === null) return;
20139
+ const result = await bridge.changeSessionCwd(
20140
+ sessionId,
20141
+ { path: targetPath },
20142
+ clientId !== void 0 ? { clientId } : void 0
20143
+ );
20144
+ res.status(200).json(result);
19418
20145
  }
19419
- const clientId = parseClientIdHeader(req, res);
19420
- if (clientId === null) return;
19421
- const result = await bridge.changeSessionCwd(
19422
- sessionId,
19423
- { path: targetPath },
19424
- clientId !== void 0 ? { clientId } : void 0
19425
- );
19426
- res.status(200).json(result);
19427
- })
20146
+ )
19428
20147
  );
19429
20148
  app.get("/session/:id/status", (req, res) => {
19430
20149
  const sessionId = requireSessionId(req, res);
@@ -19482,6 +20201,18 @@ function registerSessionRoutes(app, deps) {
19482
20201
  if (limit === null) return;
19483
20202
  const cursor = parseTranscriptCursorQuery(req.query["cursor"], res);
19484
20203
  if (cursor === null) return;
20204
+ const beforeRecordId = parseTranscriptRecordBoundaryQuery(
20205
+ req.query["beforeRecordId"],
20206
+ res
20207
+ );
20208
+ if (beforeRecordId === null) return;
20209
+ if (cursor !== void 0 && beforeRecordId !== void 0) {
20210
+ res.status(400).json({
20211
+ error: "`cursor` and `beforeRecordId` are mutually exclusive",
20212
+ code: "invalid_transcript_cursor"
20213
+ });
20214
+ return;
20215
+ }
19485
20216
  try {
19486
20217
  const result = await archiveCoordinator.runSharedMany(
19487
20218
  [sessionId],
@@ -19496,7 +20227,8 @@ function registerSessionRoutes(app, deps) {
19496
20227
  return runtime.bridge.getSessionTranscriptPage({
19497
20228
  sessionId,
19498
20229
  ...limit !== void 0 ? { limit } : {},
19499
- ...cursor !== void 0 ? { cursor } : {}
20230
+ ...cursor !== void 0 ? { cursor } : {},
20231
+ ...beforeRecordId !== void 0 ? { beforeRecordId } : {}
19500
20232
  });
19501
20233
  }
19502
20234
  );
@@ -19531,6 +20263,18 @@ function registerSessionRoutes(app, deps) {
19531
20263
  if (limit === null) return;
19532
20264
  const cursor = parseTranscriptCursorQuery(req.query["cursor"], res);
19533
20265
  if (cursor === null) return;
20266
+ const beforeRecordId = parseTranscriptRecordBoundaryQuery(
20267
+ req.query["beforeRecordId"],
20268
+ res
20269
+ );
20270
+ if (beforeRecordId === null) return;
20271
+ if (cursor !== void 0 && beforeRecordId !== void 0) {
20272
+ res.status(400).json({
20273
+ error: "`cursor` and `beforeRecordId` are mutually exclusive",
20274
+ code: "invalid_transcript_cursor"
20275
+ });
20276
+ return;
20277
+ }
19534
20278
  if (cursor !== void 0 && workspaceTranscriptCursorExceedsLimit(cursor)) {
19535
20279
  res.status(400).json({
19536
20280
  error: "`cursor` exceeds the maximum size",
@@ -19555,7 +20299,8 @@ function registerSessionRoutes(app, deps) {
19555
20299
  page = await reader.readPage(sessionId, {
19556
20300
  ...limit !== void 0 ? { limit } : {},
19557
20301
  ...cursor !== void 0 ? { cursor } : {},
19558
- maxBytes: WORKSPACE_TRANSCRIPT_PAGE_SOURCE_MAX_BYTES
20302
+ ...beforeRecordId !== void 0 ? { beforeRecordId } : {},
20303
+ maxBytes: SESSION_TRANSCRIPT_MAX_PAGE_BYTES
19559
20304
  });
19560
20305
  } catch (error2) {
19561
20306
  if (error2.code !== "ENOENT") {
@@ -20686,6 +21431,36 @@ function registerSessionRoutes(app, deps) {
20686
21431
  "/workspaces/:workspace/sessions",
20687
21432
  listWorkspaceSessionsHandler("workspace")
20688
21433
  );
21434
+ const workspaceSessionInfoHandler = /* @__PURE__ */ __name((paramName) => async (req, res) => {
21435
+ const route = paramName === "workspace" ? "GET /workspaces/:workspace/session-info" : "GET /workspace/:id/session-info";
21436
+ const runtime = resolveRuntimeForCatalogRoute(req, res, paramName, route);
21437
+ if (runtime === null) return;
21438
+ const key = runtime.workspaceCwd;
21439
+ try {
21440
+ const info = await runWorkspaceInspectionWithLogPolicy(
21441
+ runtime,
21442
+ () => getWorkspaceSessionInfoForResponse(runtime.bridge, key, {
21443
+ includeLive: !isReadOnlyWorkspaceInspection(runtime)
21444
+ })
21445
+ );
21446
+ res.status(200).json(info);
21447
+ } catch (err) {
21448
+ writeStderrLine(
21449
+ `qwen serve: failed to read session-info for workspace ${safeLogValue(
21450
+ key
21451
+ )}: ${safeLogValue(err instanceof Error ? err.message : String(err))}`
21452
+ );
21453
+ res.status(500).json({
21454
+ error: "Failed to read session info",
21455
+ code: "session_info_failed"
21456
+ });
21457
+ }
21458
+ }, "workspaceSessionInfoHandler");
21459
+ app.get("/workspace/:id/session-info", workspaceSessionInfoHandler("id"));
21460
+ app.get(
21461
+ "/workspaces/:workspace/session-info",
21462
+ workspaceSessionInfoHandler("workspace")
21463
+ );
20689
21464
  app.post(
20690
21465
  "/session/:id/model",
20691
21466
  mutate(),
@@ -21663,6 +22438,81 @@ function parseNameField(raw) {
21663
22438
  }
21664
22439
  __name(parseNameField, "parseNameField");
21665
22440
 
22441
+ // packages/cli/src/serve/routes/goals.ts
22442
+ init_esbuild_shims();
22443
+ var PROBE_CONCURRENCY = 10;
22444
+ async function allSettledWithLimit(items, limit, fn) {
22445
+ const results = new Array(items.length);
22446
+ let next = 0;
22447
+ const worker = /* @__PURE__ */ __name(async () => {
22448
+ while (next < items.length) {
22449
+ const index = next++;
22450
+ try {
22451
+ results[index] = { status: "fulfilled", value: await fn(items[index]) };
22452
+ } catch (reason) {
22453
+ results[index] = { status: "rejected", reason };
22454
+ }
22455
+ }
22456
+ }, "worker");
22457
+ const workers = Math.min(Math.max(1, limit), items.length);
22458
+ await Promise.all(Array.from({ length: workers }, worker));
22459
+ return results;
22460
+ }
22461
+ __name(allSettledWithLimit, "allSettledWithLimit");
22462
+ function registerGoalsRoutes(app, deps) {
22463
+ const { boundWorkspace, bridge } = deps;
22464
+ app.get("/goals", async (_req, res) => {
22465
+ try {
22466
+ const sessions = bridge.listWorkspaceSessions(boundWorkspace);
22467
+ const settled = await allSettledWithLimit(
22468
+ sessions,
22469
+ PROBE_CONCURRENCY,
22470
+ async (session) => ({
22471
+ session,
22472
+ goal: await bridge.getSessionGoal(session.sessionId)
22473
+ })
22474
+ );
22475
+ const goals = [];
22476
+ const dropped = [];
22477
+ for (const [index, outcome] of settled.entries()) {
22478
+ if (outcome.status !== "fulfilled") {
22479
+ const sessionId = sessions[index]?.sessionId ?? "(unknown)";
22480
+ const reason = outcome.reason instanceof Error ? outcome.reason.message : String(outcome.reason);
22481
+ dropped.push(`${sessionId}: ${reason}`);
22482
+ continue;
22483
+ }
22484
+ const { session, goal } = outcome.value;
22485
+ if (!goal.active) continue;
22486
+ goals.push({
22487
+ sessionId: session.sessionId,
22488
+ displayName: session.displayName ?? null,
22489
+ condition: goal.active.condition,
22490
+ iterations: goal.active.iterations,
22491
+ setAt: goal.active.setAt,
22492
+ ...goal.active.lastReason !== void 0 ? { lastReason: goal.active.lastReason } : {},
22493
+ hasActivePrompt: session.hasActivePrompt
22494
+ });
22495
+ }
22496
+ if (dropped.length > 0) {
22497
+ writeStderrLine(
22498
+ `qwen serve: GET /goals could not probe ${dropped.length} of ${sessions.length} session(s): ${dropped.join("; ")}`
22499
+ );
22500
+ }
22501
+ goals.sort((a, b) => b.setAt - a.setAt);
22502
+ res.status(200).json({ v: 1, goals, droppedCount: dropped.length });
22503
+ } catch (err) {
22504
+ writeStderrLine(
22505
+ `qwen serve: GET /goals failed: ${err instanceof Error ? err.message : String(err)}`
22506
+ );
22507
+ res.status(500).json({
22508
+ error: "Failed to list active goals",
22509
+ code: "goals_read_failed"
22510
+ });
22511
+ }
22512
+ });
22513
+ }
22514
+ __name(registerGoalsRoutes, "registerGoalsRoutes");
22515
+
21666
22516
  // packages/cli/src/serve/routes/usage-stats.ts
21667
22517
  init_esbuild_shims();
21668
22518
  var DEFAULT_HEATMAP_DAYS = 183;
@@ -23188,7 +24038,7 @@ function sendBridgeError(res, err, ctx, daemonLog) {
23188
24038
  if (err instanceof WorkspaceSkillNotToggleableError) {
23189
24039
  res.status(409).json({
23190
24040
  error: err.message,
23191
- code: "skill_not_toggleable",
24041
+ code: err.reason === "inactive_extension" ? "skill_inactive_extension" : "skill_not_toggleable",
23192
24042
  skillName: err.skillName,
23193
24043
  reason: err.reason,
23194
24044
  ...err.lockedScope ? { lockedScope: err.lockedScope } : {}
@@ -23391,7 +24241,7 @@ function sendBridgeError(res, err, ctx, daemonLog) {
23391
24241
  }
23392
24242
  if (err instanceof WorkspaceMismatchError) {
23393
24243
  writeStderrLine(
23394
- `qwen serve: workspace_mismatch (POST /session): daemon bound to ${JSON.stringify(err.bound)}, rejected ${JSON.stringify(err.requested)}`
24244
+ `qwen serve: workspace_mismatch (POST /session): runtime bound to ${JSON.stringify(err.bound)}, rejected ${JSON.stringify(err.requested)}`
23395
24245
  );
23396
24246
  res.status(400).json({
23397
24247
  error: err.message,
@@ -23575,13 +24425,24 @@ function sendBridgeError(res, err, ctx, daemonLog) {
23575
24425
  });
23576
24426
  return;
23577
24427
  }
23578
- if (kind === "transcript_too_large") {
24428
+ if (kind === "transcript_too_large") {
24429
+ const d = data;
24430
+ res.status(413).json({
24431
+ error: errorMessage2(err),
24432
+ code: "transcript_too_large",
24433
+ ...d.sessionId ? { sessionId: d.sessionId } : {},
24434
+ ...typeof d.snapshotSize === "number" ? { snapshotSize: d.snapshotSize } : {},
24435
+ ...typeof d.maxBytes === "number" ? { maxBytes: d.maxBytes } : {}
24436
+ });
24437
+ return;
24438
+ }
24439
+ if (kind === "transcript_page_too_large") {
23579
24440
  const d = data;
23580
24441
  res.status(413).json({
23581
24442
  error: errorMessage2(err),
23582
- code: "transcript_too_large",
24443
+ code: "transcript_page_too_large",
23583
24444
  ...d.sessionId ? { sessionId: d.sessionId } : {},
23584
- ...typeof d.snapshotSize === "number" ? { snapshotSize: d.snapshotSize } : {},
24445
+ ...typeof d.pageBytes === "number" ? { pageBytes: d.pageBytes } : {},
23585
24446
  ...typeof d.maxBytes === "number" ? { maxBytes: d.maxBytes } : {}
23586
24447
  });
23587
24448
  return;
@@ -24373,309 +25234,6 @@ function dropNestedWorkspacesPreservingPrimary(workspaces) {
24373
25234
  }
24374
25235
  __name(dropNestedWorkspacesPreservingPrimary, "dropNestedWorkspacesPreservingPrimary");
24375
25236
 
24376
- // packages/cli/src/serve/server/telemetry.ts
24377
- init_esbuild_shims();
24378
- function decodePathSegment(value) {
24379
- try {
24380
- return decodeURIComponent(value);
24381
- } catch {
24382
- return value;
24383
- }
24384
- }
24385
- __name(decodePathSegment, "decodePathSegment");
24386
- function resolveDaemonTelemetryRoute(req) {
24387
- const path15 = req.path.replace(/\/$/, "") || "/";
24388
- if (req.method === "POST" && path15 === "/session") {
24389
- return { route: "POST /session" };
24390
- }
24391
- if (req.method === "POST" && path15 === "/sessions/delete") {
24392
- return { route: "POST /sessions/delete" };
24393
- }
24394
- if (req.method === "GET" && path15 === "/daemon/status") {
24395
- return { route: "GET /daemon/status" };
24396
- }
24397
- const rewindSnapshots = path15.match(/^\/session\/([^/]+)\/rewind\/snapshots$/);
24398
- if (rewindSnapshots?.[1] && req.method === "GET") {
24399
- return {
24400
- route: "GET /session/:id/rewind/snapshots",
24401
- sessionId: rewindSnapshots[1]
24402
- };
24403
- }
24404
- const sessionAction = path15.match(
24405
- /^\/session\/([^/]+)\/(load|resume|prompt|cancel|recap|btw|mid-turn-message|model|shell|detach|rewind|approval-mode|language|a2ui-action)$/
24406
- );
24407
- const sessionActionId = sessionAction?.[1];
24408
- const sessionActionName = sessionAction?.[2];
24409
- if (sessionActionId && sessionActionName && req.method === "POST") {
24410
- return {
24411
- route: `POST /session/:id/${sessionActionName}`,
24412
- sessionId: sessionActionId
24413
- };
24414
- }
24415
- const sessionMetadata = path15.match(/^\/session\/([^/]+)\/metadata$/);
24416
- if (sessionMetadata?.[1] && req.method === "PATCH") {
24417
- return {
24418
- route: "PATCH /session/:id/metadata",
24419
- sessionId: sessionMetadata[1]
24420
- };
24421
- }
24422
- const sessionArtifacts = path15.match(/^\/session\/([^/]+)\/artifacts$/);
24423
- if (sessionArtifacts?.[1]) {
24424
- if (req.method === "GET") {
24425
- return {
24426
- route: "GET /session/:id/artifacts",
24427
- sessionId: sessionArtifacts[1]
24428
- };
24429
- }
24430
- if (req.method === "POST") {
24431
- return {
24432
- route: "POST /session/:id/artifacts",
24433
- sessionId: sessionArtifacts[1]
24434
- };
24435
- }
24436
- }
24437
- const sessionArtifact = path15.match(
24438
- /^\/session\/([^/]+)\/artifacts\/([^/]+)$/
24439
- );
24440
- if (sessionArtifact?.[1] && req.method === "DELETE") {
24441
- return {
24442
- route: "DELETE /session/:id/artifacts/:artifactId",
24443
- sessionId: sessionArtifact[1]
24444
- };
24445
- }
24446
- const sessionPermission = path15.match(
24447
- /^\/session\/([^/]+)\/permission\/([^/]+)$/
24448
- );
24449
- if (sessionPermission?.[1] && sessionPermission?.[2] && req.method === "POST") {
24450
- const rawRequestId = sessionPermission[2];
24451
- return {
24452
- route: "POST /session/:id/permission/:requestId",
24453
- sessionId: sessionPermission[1],
24454
- ...rawRequestId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawRequestId) ? { permissionRequestId: rawRequestId } : {}
24455
- };
24456
- }
24457
- const globalPermission = path15.match(/^\/permission\/([^/]+)$/);
24458
- if (globalPermission?.[1] && req.method === "POST") {
24459
- const rawRequestId = globalPermission[1];
24460
- return {
24461
- route: "POST /permission/:requestId",
24462
- ...rawRequestId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawRequestId) ? { permissionRequestId: rawRequestId } : {}
24463
- };
24464
- }
24465
- const deleteSession = path15.match(/^\/session\/([^/]+)$/);
24466
- const deleteSessionId = deleteSession?.[1];
24467
- if (deleteSessionId && req.method === "DELETE") {
24468
- return { route: "DELETE /session/:id", sessionId: deleteSessionId };
24469
- }
24470
- if (req.method === "GET" && /^\/workspace\/[^/]+\/sessions$/.test(path15)) {
24471
- return { route: "GET /workspace/:id/sessions" };
24472
- }
24473
- if (req.method === "GET" && /^\/workspaces\/[^/]+\/sessions$/.test(path15)) {
24474
- return { route: "GET /workspace/:id/sessions" };
24475
- }
24476
- const workspaceTranscript = path15.match(
24477
- /^\/workspaces\/[^/]+\/session\/([^/]+)\/transcript$/
24478
- );
24479
- if (workspaceTranscript?.[1] && req.method === "GET") {
24480
- return {
24481
- route: "GET /workspaces/:workspace/session/:id/transcript",
24482
- sessionId: workspaceTranscript[1]
24483
- };
24484
- }
24485
- const workspaceExport = path15.match(
24486
- /^\/workspaces\/[^/]+\/session\/([^/]+)\/export$/
24487
- );
24488
- if (workspaceExport?.[1] && req.method === "GET") {
24489
- return {
24490
- route: "GET /workspaces/:workspace/session/:id/export",
24491
- sessionId: workspaceExport[1]
24492
- };
24493
- }
24494
- const workspaceArchivedExport = path15.match(
24495
- /^\/workspaces\/[^/]+\/session\/([^/]+)\/archive\/export$/
24496
- );
24497
- if (workspaceArchivedExport?.[1] && req.method === "GET") {
24498
- return {
24499
- route: "GET /workspaces/:workspace/session/:id/archive/export",
24500
- sessionId: workspaceArchivedExport[1]
24501
- };
24502
- }
24503
- const pluralWorkspacePrefix = /^\/workspaces\/[^/]+/;
24504
- if (pluralWorkspacePrefix.test(path15)) {
24505
- const suffix = path15.replace(pluralWorkspacePrefix, "/workspace");
24506
- if (req.method === "GET") {
24507
- if (suffix === "/workspace/mcp" || suffix === "/workspace/skills" || suffix === "/workspace/tools" || suffix === "/workspace/providers" || suffix === "/workspace/env" || suffix === "/workspace/preflight" || suffix === "/workspace/hooks" || suffix === "/workspace/settings" || suffix === "/workspace/voice" || suffix === "/workspace/permissions" || suffix === "/workspace/trust" || suffix === "/workspace/memory" || suffix === "/workspace/agents") {
24508
- return { route: `GET ${suffix}` };
24509
- }
24510
- if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
24511
- return { route: "GET /workspace/agents/:agentType" };
24512
- }
24513
- if (suffix === "/workspace/file") return { route: "GET /file" };
24514
- if (suffix === "/workspace/file/bytes") {
24515
- return { route: "GET /file/bytes" };
24516
- }
24517
- if (suffix === "/workspace/stat") return { route: "GET /stat" };
24518
- if (suffix === "/workspace/list") return { route: "GET /list" };
24519
- if (suffix === "/workspace/glob") return { route: "GET /glob" };
24520
- if (/^\/workspace\/mcp\/[^/]+\/tools$/.test(suffix)) {
24521
- return { route: "GET /workspace/mcp/:server/tools" };
24522
- }
24523
- if (/^\/workspace\/mcp\/[^/]+\/resources$/.test(suffix)) {
24524
- return { route: "GET /workspace/mcp/:server/resources" };
24525
- }
24526
- }
24527
- if (req.method === "POST") {
24528
- if (suffix === "/workspace/settings" || suffix === "/workspace/voice" || suffix === "/workspace/voice/transcribe" || suffix === "/workspace/permissions" || suffix === "/workspace/trust/request" || suffix === "/workspace/init" || suffix === "/workspace/reload" || suffix === "/workspace/file/write" || suffix === "/workspace/file/edit" || suffix === "/workspace/mcp/servers" || suffix === "/workspace/memory" || suffix === "/workspace/agents" || suffix === "/workspace/sessions/delete" || suffix === "/workspace/sessions/archive" || suffix === "/workspace/sessions/unarchive" || suffix === "/workspace/session-groups") {
24529
- return { route: `POST ${suffix}` };
24530
- }
24531
- if (/^\/workspace\/tools\/[^/]+\/enable$/.test(suffix)) {
24532
- return { route: "POST /workspace/tools/:name/enable" };
24533
- }
24534
- if (/^\/workspace\/mcp\/[^/]+\/restart$/.test(suffix)) {
24535
- return { route: "POST /workspace/mcp/:server/restart" };
24536
- }
24537
- if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
24538
- return { route: "POST /workspace/agents/:agentType" };
24539
- }
24540
- if (/^\/workspace\/mcp\/[^/]+\/(approve|enable|disable|authenticate|clear-auth)$/.test(
24541
- suffix
24542
- )) {
24543
- return {
24544
- route: `POST /workspace/mcp/:server/${suffix.split("/").at(-1)}`
24545
- };
24546
- }
24547
- }
24548
- if (req.method === "DELETE" && /^\/workspace\/mcp\/servers\/[^/]+$/.test(suffix)) {
24549
- return { route: "DELETE /workspace/mcp/servers/:name" };
24550
- }
24551
- if (req.method === "DELETE" && /^\/workspace\/agents\/[^/]+$/.test(suffix)) {
24552
- return { route: "DELETE /workspace/agents/:agentType" };
24553
- }
24554
- if (suffix === "/workspace/session-groups" && req.method === "GET") {
24555
- return { route: "GET /workspace/session-groups" };
24556
- }
24557
- if (/^\/workspace\/session-groups\/[^/]+$/.test(suffix) && req.method === "PATCH") {
24558
- return { route: "PATCH /workspace/session-groups/:groupId" };
24559
- }
24560
- if (/^\/workspace\/session-groups\/[^/]+$/.test(suffix) && req.method === "DELETE") {
24561
- return { route: "DELETE /workspace/session-groups/:groupId" };
24562
- }
24563
- }
24564
- if (req.method === "POST" && path15 === "/workspace/init") {
24565
- return { route: "POST /workspace/init" };
24566
- }
24567
- if (req.method === "POST" && path15 === "/workspace/setup-github") {
24568
- return { route: "POST /workspace/setup-github" };
24569
- }
24570
- if (req.method === "POST" && path15 === "/workspace/reload") {
24571
- return { route: "POST /workspace/reload" };
24572
- }
24573
- const mcpRestart = path15.match(/^\/workspace\/mcp\/([^/]+)\/restart$/);
24574
- if (mcpRestart?.[1] && req.method === "POST") {
24575
- return { route: "POST /workspace/mcp/:server/restart" };
24576
- }
24577
- if (req.method === "POST" && path15 === "/workspace/mcp/servers") {
24578
- return { route: "POST /workspace/mcp/servers" };
24579
- }
24580
- const mcpDelete = path15.match(/^\/workspace\/mcp\/servers\/([^/]+)$/);
24581
- if (mcpDelete?.[1] && req.method === "DELETE") {
24582
- return { route: "DELETE /workspace/mcp/servers/:name" };
24583
- }
24584
- if (req.method === "POST" && path15 === "/workspace/auth/device-flow") {
24585
- return { route: "POST /workspace/auth/device-flow" };
24586
- }
24587
- const deviceFlowDelete = path15.match(
24588
- /^\/workspace\/auth\/device-flow\/([^/]+)$/
24589
- );
24590
- if (deviceFlowDelete?.[1] && req.method === "DELETE") {
24591
- return { route: "DELETE /workspace/auth/device-flow/:id" };
24592
- }
24593
- const toolEnable = path15.match(/^\/workspace\/tools\/([^/]+)\/enable$/);
24594
- if (toolEnable?.[1] && req.method === "POST") {
24595
- return { route: "POST /workspace/tools/:name/enable" };
24596
- }
24597
- if (path15 === "/workspace/settings") {
24598
- if (req.method === "GET") return { route: "GET /workspace/settings" };
24599
- if (req.method === "POST") return { route: "POST /workspace/settings" };
24600
- }
24601
- if (path15 === "/workspace/permissions") {
24602
- if (req.method === "GET") return { route: "GET /workspace/permissions" };
24603
- if (req.method === "POST") return { route: "POST /workspace/permissions" };
24604
- }
24605
- if (path15 === "/workspace/trust") {
24606
- if (req.method === "GET") return { route: "GET /workspace/trust" };
24607
- }
24608
- if (req.method === "POST" && path15 === "/workspace/trust/request") {
24609
- return { route: "POST /workspace/trust/request" };
24610
- }
24611
- if (path15 === "/workspace/voice") {
24612
- if (req.method === "GET") return { route: "GET /workspace/voice" };
24613
- if (req.method === "POST") return { route: "POST /workspace/voice" };
24614
- }
24615
- if (req.method === "POST" && path15 === "/workspace/voice/transcribe") {
24616
- return { route: "POST /workspace/voice/transcribe" };
24617
- }
24618
- return void 0;
24619
- }
24620
- __name(resolveDaemonTelemetryRoute, "resolveDaemonTelemetryRoute");
24621
- function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSessionWorkspaceCwd) {
24622
- const workspaceHashByCwd = /* @__PURE__ */ new Map();
24623
- const resolveWorkspaceHash = /* @__PURE__ */ __name((workspaceCwd) => {
24624
- const existing = workspaceHashByCwd.get(workspaceCwd);
24625
- if (existing !== void 0) return existing;
24626
- const workspaceHash = hashDaemonWorkspace(workspaceCwd);
24627
- workspaceHashByCwd.set(workspaceCwd, workspaceHash);
24628
- return workspaceHash;
24629
- }, "resolveWorkspaceHash");
24630
- return (req, res, next) => {
24631
- const route = resolveDaemonTelemetryRoute(req);
24632
- if (!route) {
24633
- next();
24634
- return;
24635
- }
24636
- const resolveOwnerWorkspace = route.route === "GET /session/:id/rewind/snapshots" || route.route === "POST /session/:id/rewind" || route.route === "POST /session/:id/shell";
24637
- const sessionId = route.sessionId ? decodePathSegment(route.sessionId) : void 0;
24638
- const workspaceCwd = (resolveOwnerWorkspace && sessionId ? resolveSessionWorkspaceCwd?.(sessionId) : void 0) ?? resolveWorkspaceCwd(req);
24639
- const workspaceHash = resolveWorkspaceHash(workspaceCwd);
24640
- const rawClientId = req.get(CLIENT_ID_HEADER);
24641
- const clientId = rawClientId !== void 0 && rawClientId !== "" && rawClientId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawClientId) ? rawClientId : void 0;
24642
- const startMs = Date.now();
24643
- void withDaemonRequestSpan(
24644
- {
24645
- method: req.method,
24646
- route: route.route,
24647
- workspaceHash,
24648
- ...sessionId ? { sessionId } : {},
24649
- ...route.permissionRequestId ? { permissionRequestId: route.permissionRequestId } : {},
24650
- ...clientId ? { clientId } : {}
24651
- },
24652
- async (span) => await new Promise((resolve5, reject) => {
24653
- let done = false;
24654
- const finish = /* @__PURE__ */ __name(() => {
24655
- if (done) return;
24656
- done = true;
24657
- recordDaemonHttpResponse(span, res.statusCode);
24658
- const durationMs = Date.now() - startMs;
24659
- recordDaemonHttpRequest(durationMs, route.route, res.statusCode);
24660
- if (route.route !== "GET /daemon/status") {
24661
- recordRequest?.(durationMs, res.statusCode);
24662
- }
24663
- resolve5();
24664
- }, "finish");
24665
- res.once("finish", finish);
24666
- res.once("close", finish);
24667
- try {
24668
- next();
24669
- } catch (error2) {
24670
- recordDaemonError(span, error2);
24671
- reject(error2);
24672
- }
24673
- })
24674
- ).catch(next);
24675
- };
24676
- }
24677
- __name(daemonTelemetryMiddleware, "daemonTelemetryMiddleware");
24678
-
24679
25237
  // packages/cli/src/serve/server/access-log.ts
24680
25238
  init_esbuild_shims();
24681
25239
  var SESSION_ID_RE = /\/session\/([^/]+)/;
@@ -25199,9 +25757,10 @@ __name(registerWorkspaceQualifiedLifecycleRoutes, "registerWorkspaceQualifiedLif
25199
25757
 
25200
25758
  // packages/cli/src/serve/routes/workspace-management.ts
25201
25759
  init_esbuild_shims();
25202
- import { stat } from "node:fs/promises";
25760
+ import { readdir, stat } from "node:fs/promises";
25203
25761
  import { realpathSync } from "node:fs";
25204
- import { isAbsolute as isAbsolute7, resolve as resolve4 } from "node:path";
25762
+ import { basename as basename4, dirname as dirname4, isAbsolute as isAbsolute7, join as join7, resolve as resolve4, sep as sep3 } from "node:path";
25763
+ var MAX_PATH_SUGGESTIONS = 50;
25205
25764
  function registerWorkspaceManagementRoutes(app, deps) {
25206
25765
  const {
25207
25766
  workspaceRegistry,
@@ -25231,6 +25790,72 @@ function registerWorkspaceManagementRoutes(app, deps) {
25231
25790
  code: "daemon_shutting_down"
25232
25791
  });
25233
25792
  }, "sendSealed");
25793
+ app.get(
25794
+ "/workspace-path-suggestions",
25795
+ async (req, res) => {
25796
+ const prefixRaw = req.query["prefix"];
25797
+ if (typeof prefixRaw !== "string" || prefixRaw.trim().length === 0) {
25798
+ res.status(400).json({
25799
+ error: "`prefix` must be a non-empty string",
25800
+ code: "invalid_prefix"
25801
+ });
25802
+ return;
25803
+ }
25804
+ const prefix = prefixRaw;
25805
+ if (prefix.length > MAX_WORKSPACE_PATH_LENGTH) {
25806
+ res.status(400).json({
25807
+ error: `\`prefix\` exceeds the ${MAX_WORKSPACE_PATH_LENGTH}-character limit`,
25808
+ code: "invalid_prefix"
25809
+ });
25810
+ return;
25811
+ }
25812
+ if (!isAbsolute7(prefix)) {
25813
+ res.status(400).json({
25814
+ error: "`prefix` must be an absolute path",
25815
+ code: "invalid_prefix"
25816
+ });
25817
+ return;
25818
+ }
25819
+ const endsWithSep = prefix.endsWith("/") || process.platform === "win32" && prefix.endsWith("\\");
25820
+ const dir = endsWithSep ? join7(prefix, ".") : dirname4(prefix);
25821
+ const filter = endsWithSep ? "" : basename4(prefix);
25822
+ const filterLower = filter.toLowerCase();
25823
+ const suggestions = [];
25824
+ let truncated = false;
25825
+ try {
25826
+ const entries = await readdir(dir, { withFileTypes: true });
25827
+ entries.sort((a, b) => a.name.localeCompare(b.name));
25828
+ for (const entry of entries) {
25829
+ if (entry.name.startsWith(".") && !filter.startsWith(".")) continue;
25830
+ if (filter && !entry.name.toLowerCase().startsWith(filterLower)) {
25831
+ continue;
25832
+ }
25833
+ let isDir = entry.isDirectory();
25834
+ if (!isDir && entry.isSymbolicLink()) {
25835
+ try {
25836
+ isDir = (await stat(join7(dir, entry.name))).isDirectory();
25837
+ } catch {
25838
+ continue;
25839
+ }
25840
+ }
25841
+ if (!isDir) continue;
25842
+ if (suggestions.length >= MAX_PATH_SUGGESTIONS) {
25843
+ truncated = true;
25844
+ break;
25845
+ }
25846
+ suggestions.push({ name: entry.name, path: join7(dir, entry.name) });
25847
+ }
25848
+ } catch {
25849
+ }
25850
+ res.status(200).json({
25851
+ kind: "workspace-path-suggestions",
25852
+ dir,
25853
+ sep: sep3,
25854
+ suggestions,
25855
+ truncated
25856
+ });
25857
+ }
25858
+ );
25234
25859
  app.post(
25235
25860
  "/workspaces",
25236
25861
  mutate({ strict: true }),
@@ -25983,6 +26608,151 @@ function registerWorkspaceQualifiedGitRoutes(app, deps) {
25983
26608
  }
25984
26609
  __name(registerWorkspaceQualifiedGitRoutes, "registerWorkspaceQualifiedGitRoutes");
25985
26610
 
26611
+ // packages/cli/src/serve/routes/workspace-git-diff.ts
26612
+ init_esbuild_shims();
26613
+ function buildDiffList(workspaceCwd, result) {
26614
+ if (!result) {
26615
+ return {
26616
+ v: 1,
26617
+ workspaceCwd,
26618
+ available: false,
26619
+ filesCount: 0,
26620
+ linesAdded: 0,
26621
+ linesRemoved: 0,
26622
+ files: [],
26623
+ hiddenCount: 0
26624
+ };
26625
+ }
26626
+ const files = [...result.perFileStats.entries()].map(([path15, s]) => ({
26627
+ path: path15,
26628
+ oldPath: s.oldPath,
26629
+ added: s.added,
26630
+ removed: s.removed,
26631
+ isBinary: s.isBinary,
26632
+ isUntracked: s.isUntracked ?? false,
26633
+ isDeleted: s.isDeleted ?? false,
26634
+ truncated: s.truncated ?? false
26635
+ }));
26636
+ return {
26637
+ v: 1,
26638
+ workspaceCwd,
26639
+ available: true,
26640
+ filesCount: result.stats.filesCount,
26641
+ linesAdded: result.stats.linesAdded,
26642
+ linesRemoved: result.stats.linesRemoved,
26643
+ files,
26644
+ hiddenCount: Math.max(
26645
+ 0,
26646
+ result.stats.filesCount - result.perFileStats.size
26647
+ )
26648
+ };
26649
+ }
26650
+ __name(buildDiffList, "buildDiffList");
26651
+ function buildFileHunks(workspaceCwd, queryPath, result) {
26652
+ return {
26653
+ v: 1,
26654
+ workspaceCwd,
26655
+ path: queryPath,
26656
+ available: result !== null && result.hunks.length > 0,
26657
+ hunks: (result?.hunks ?? []).map((h) => ({
26658
+ oldStart: h.oldStart,
26659
+ oldLines: h.oldLines,
26660
+ newStart: h.newStart,
26661
+ newLines: h.newLines,
26662
+ lines: h.lines
26663
+ })),
26664
+ // Only present when the per-file caps actually cut content, so the client
26665
+ // can label the diff incomplete; absent otherwise (additive to v=1).
26666
+ ...result?.truncated ? { truncated: true } : {}
26667
+ };
26668
+ }
26669
+ __name(buildFileHunks, "buildFileHunks");
26670
+ async function handleDiffList(res, workspaceCwd, sendBridgeError2, route) {
26671
+ try {
26672
+ applyReadHeaders(res);
26673
+ res.status(200).json(buildDiffList(workspaceCwd, await fetchGitDiff(workspaceCwd)));
26674
+ } catch (err) {
26675
+ sendBridgeError2(res, err, { route });
26676
+ }
26677
+ }
26678
+ __name(handleDiffList, "handleDiffList");
26679
+ async function handleDiffFile(req, res, workspaceCwd, sendBridgeError2, route) {
26680
+ const queryPath = req.query["path"];
26681
+ if (typeof queryPath !== "string" || queryPath.length === 0) {
26682
+ applyReadHeaders(res);
26683
+ res.status(400).json({
26684
+ errorKind: "parse_error",
26685
+ error: "path query parameter is required",
26686
+ status: 400
26687
+ });
26688
+ return;
26689
+ }
26690
+ const queryOldPath = req.query["oldPath"];
26691
+ const oldPath = typeof queryOldPath === "string" && queryOldPath.length > 0 ? queryOldPath : void 0;
26692
+ try {
26693
+ applyReadHeaders(res);
26694
+ const result = await fetchGitDiffHunksForFile(
26695
+ workspaceCwd,
26696
+ queryPath,
26697
+ oldPath
26698
+ );
26699
+ res.status(200).json(buildFileHunks(workspaceCwd, queryPath, result));
26700
+ } catch (err) {
26701
+ sendBridgeError2(res, err, { route });
26702
+ }
26703
+ }
26704
+ __name(handleDiffFile, "handleDiffFile");
26705
+ function registerWorkspaceGitDiffRoutes(app, deps) {
26706
+ app.get("/workspace/git/diff", (_req, res) => {
26707
+ void handleDiffList(
26708
+ res,
26709
+ deps.boundWorkspace,
26710
+ deps.sendBridgeError,
26711
+ "GET /workspace/git/diff"
26712
+ );
26713
+ });
26714
+ app.get("/workspace/git/diff/file", (req, res) => {
26715
+ void handleDiffFile(
26716
+ req,
26717
+ res,
26718
+ deps.boundWorkspace,
26719
+ deps.sendBridgeError,
26720
+ "GET /workspace/git/diff/file"
26721
+ );
26722
+ });
26723
+ }
26724
+ __name(registerWorkspaceGitDiffRoutes, "registerWorkspaceGitDiffRoutes");
26725
+ function resolveTrustedRuntime3(registry, req, res) {
26726
+ const runtime = resolveWorkspaceRuntimeFromParam(registry, req, res);
26727
+ if (!runtime) return null;
26728
+ return requireTrustedWorkspaceRuntime(runtime, res) ? runtime : null;
26729
+ }
26730
+ __name(resolveTrustedRuntime3, "resolveTrustedRuntime");
26731
+ function registerWorkspaceQualifiedGitDiffRoutes(app, deps) {
26732
+ app.get("/workspaces/:workspace/git/diff", (req, res) => {
26733
+ const runtime = resolveTrustedRuntime3(deps.workspaceRegistry, req, res);
26734
+ if (!runtime) return;
26735
+ void handleDiffList(
26736
+ res,
26737
+ runtime.workspaceCwd,
26738
+ deps.sendBridgeError,
26739
+ "GET /workspaces/:workspace/git/diff"
26740
+ );
26741
+ });
26742
+ app.get("/workspaces/:workspace/git/diff/file", (req, res) => {
26743
+ const runtime = resolveTrustedRuntime3(deps.workspaceRegistry, req, res);
26744
+ if (!runtime) return;
26745
+ void handleDiffFile(
26746
+ req,
26747
+ res,
26748
+ runtime.workspaceCwd,
26749
+ deps.sendBridgeError,
26750
+ "GET /workspaces/:workspace/git/diff/file"
26751
+ );
26752
+ });
26753
+ }
26754
+ __name(registerWorkspaceQualifiedGitDiffRoutes, "registerWorkspaceQualifiedGitDiffRoutes");
26755
+
25986
26756
  // packages/cli/src/serve/workspace-git-state.ts
25987
26757
  init_esbuild_shims();
25988
26758
  var WorkspaceGitState = class {
@@ -25992,7 +26762,28 @@ var WorkspaceGitState = class {
25992
26762
  entries = /* @__PURE__ */ new Map();
25993
26763
  async getStatus(workspaceCwd, bridge) {
25994
26764
  const entry = await this.getOrCreateEntry(workspaceCwd, bridge);
25995
- return { v: 1, workspaceCwd, branch: entry.branch ?? null };
26765
+ const status = await getGitWorkingTreeStatus(workspaceCwd).catch(
26766
+ () => null
26767
+ );
26768
+ if (!status) {
26769
+ return { v: 2, workspaceCwd, branch: entry.branch ?? null };
26770
+ }
26771
+ return {
26772
+ v: 2,
26773
+ workspaceCwd,
26774
+ branch: entry.branch ?? status.branch ?? null,
26775
+ detached: status.detached,
26776
+ staged: status.staged,
26777
+ unstaged: status.unstaged,
26778
+ untracked: status.untracked,
26779
+ conflicted: status.conflicted,
26780
+ hasUpstream: status.hasUpstream,
26781
+ ahead: status.ahead,
26782
+ behind: status.behind,
26783
+ stashCount: status.stashCount,
26784
+ ...status.operation ? { operation: status.operation } : {},
26785
+ computedAt: Date.now()
26786
+ };
25996
26787
  }
25997
26788
  dispose() {
25998
26789
  for (const pending of this.entries.values()) {
@@ -26764,6 +27555,63 @@ function registerWorkspaceChannelControlRoutes(app, deps) {
26764
27555
  }
26765
27556
  __name(registerWorkspaceChannelControlRoutes, "registerWorkspaceChannelControlRoutes");
26766
27557
 
27558
+ // packages/cli/src/serve/routes/workspace-channel-observed-contacts.ts
27559
+ init_esbuild_shims();
27560
+ var DEFAULT_FRESH_WITHIN_SECONDS = 7 * 24 * 60 * 60;
27561
+ function parseFreshWithinSeconds(req) {
27562
+ const raw = req.query["freshWithinSeconds"];
27563
+ if (raw === void 0) return DEFAULT_FRESH_WITHIN_SECONDS;
27564
+ if (typeof raw !== "string" || !/^\d+$/u.test(raw)) return void 0;
27565
+ const value = Number(raw);
27566
+ if (!Number.isSafeInteger(value) || value < 1 || value > OBSERVED_CONTACT_MAX_FRESH_WITHIN_SECONDS) {
27567
+ return void 0;
27568
+ }
27569
+ return value;
27570
+ }
27571
+ __name(parseFreshWithinSeconds, "parseFreshWithinSeconds");
27572
+ function sendContacts(req, res, workspaceCwd) {
27573
+ res.setHeader("Cache-Control", "no-store");
27574
+ res.setHeader("X-Content-Type-Options", "nosniff");
27575
+ const freshWithinSeconds = parseFreshWithinSeconds(req);
27576
+ if (freshWithinSeconds === void 0) {
27577
+ res.status(400).json({
27578
+ error: `freshWithinSeconds must be an integer from 1 to ${OBSERVED_CONTACT_MAX_FRESH_WITHIN_SECONDS}.`,
27579
+ code: "invalid_freshness"
27580
+ });
27581
+ return;
27582
+ }
27583
+ try {
27584
+ const store = new ObservedChannelContactStore(
27585
+ daemonObservedContactsPath(workspaceCwd)
27586
+ );
27587
+ res.status(200).json(store.list({ freshWithinSeconds }));
27588
+ } catch {
27589
+ process.stderr.write(
27590
+ "qwen serve: observed channel contacts unavailable.\n"
27591
+ );
27592
+ res.status(500).json({
27593
+ error: "Observed channel contacts are unavailable.",
27594
+ code: "channel_observed_contacts_unavailable"
27595
+ });
27596
+ }
27597
+ }
27598
+ __name(sendContacts, "sendContacts");
27599
+ function registerWorkspaceChannelObservedContactRoutes(app, deps) {
27600
+ app.get("/workspace/channel/observed-contacts", (req, res) => {
27601
+ sendContacts(req, res, deps.primaryWorkspace);
27602
+ });
27603
+ app.get("/workspaces/:workspace/channel/observed-contacts", (req, res) => {
27604
+ const runtime = resolveWorkspaceRuntimeFromParam(
27605
+ deps.workspaceRegistry,
27606
+ req,
27607
+ res
27608
+ );
27609
+ if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
27610
+ sendContacts(req, res, runtime.workspaceCwd);
27611
+ });
27612
+ }
27613
+ __name(registerWorkspaceChannelObservedContactRoutes, "registerWorkspaceChannelObservedContactRoutes");
27614
+
26767
27615
  // packages/cli/src/serve/routes/workspace-tools.ts
26768
27616
  init_esbuild_shims();
26769
27617
  function registerWorkspaceToolsRoutes(app, deps) {
@@ -26922,9 +27770,9 @@ function parseSkillToggleRequest(req, res, safeBody2) {
26922
27770
  });
26923
27771
  return void 0;
26924
27772
  }
26925
- if (skillName.length > MAX_SKILL_NAME_LENGTH) {
27773
+ if (skillName.length > MAX_WORKSPACE_SKILL_NAME_LENGTH) {
26926
27774
  res.status(400).json({
26927
- error: `Skill name exceeds ${MAX_SKILL_NAME_LENGTH}-character limit`,
27775
+ error: `Skill name exceeds ${MAX_WORKSPACE_SKILL_NAME_LENGTH}-character limit`,
26928
27776
  code: "invalid_skill_name"
26929
27777
  });
26930
27778
  return void 0;
@@ -26940,11 +27788,138 @@ function parseSkillToggleRequest(req, res, safeBody2) {
26940
27788
  return { skillName, enabled };
26941
27789
  }
26942
27790
  __name(parseSkillToggleRequest, "parseSkillToggleRequest");
27791
+ function parseSkillScope(value, res) {
27792
+ if (value === "workspace" || value === "global") return value;
27793
+ res.status(400).json({
27794
+ error: '`scope` must be "workspace" or "global"',
27795
+ code: "invalid_skill_scope"
27796
+ });
27797
+ return void 0;
27798
+ }
27799
+ __name(parseSkillScope, "parseSkillScope");
27800
+ function parseSkillInstallRequest(req, res, safeBody2) {
27801
+ const body = safeBody2(req);
27802
+ const name = body["name"];
27803
+ if (typeof name !== "string" || !name.trim()) {
27804
+ res.status(400).json({
27805
+ error: "`name` is required and must be a string",
27806
+ code: "invalid_skill_name"
27807
+ });
27808
+ return void 0;
27809
+ }
27810
+ if (name.trim().length > MAX_WORKSPACE_SKILL_NAME_LENGTH) {
27811
+ res.status(400).json({
27812
+ error: `Skill name exceeds ${MAX_WORKSPACE_SKILL_NAME_LENGTH}-character limit`,
27813
+ code: "invalid_skill_name"
27814
+ });
27815
+ return void 0;
27816
+ }
27817
+ const scope = parseSkillScope(body["scope"], res);
27818
+ if (!scope) return void 0;
27819
+ const rawSource = body["source"];
27820
+ if (!rawSource || typeof rawSource !== "object" || Array.isArray(rawSource)) {
27821
+ res.status(400).json({
27822
+ error: "`source` is required",
27823
+ code: "invalid_skill_source"
27824
+ });
27825
+ return void 0;
27826
+ }
27827
+ const source = rawSource;
27828
+ if (source["type"] === "github" && typeof source["url"] === "string") {
27829
+ return { name, scope, source: { type: "github", url: source["url"] } };
27830
+ }
27831
+ if (source["type"] === "zip" && typeof source["contentBase64"] === "string") {
27832
+ return {
27833
+ name,
27834
+ scope,
27835
+ source: { type: "zip", contentBase64: source["contentBase64"] }
27836
+ };
27837
+ }
27838
+ if (source["type"] === "folder" && typeof source["path"] === "string") {
27839
+ return {
27840
+ name,
27841
+ scope,
27842
+ source: { type: "folder", path: source["path"] }
27843
+ };
27844
+ }
27845
+ res.status(400).json({
27846
+ error: "Invalid Skill install source",
27847
+ code: "invalid_skill_source"
27848
+ });
27849
+ return void 0;
27850
+ }
27851
+ __name(parseSkillInstallRequest, "parseSkillInstallRequest");
27852
+ function parseDeleteScope(req, res) {
27853
+ return parseSkillScope(req.query["scope"], res);
27854
+ }
27855
+ __name(parseDeleteScope, "parseDeleteScope");
27856
+ function sendSkillManagementError(res, error2) {
27857
+ if (!(error2 instanceof WorkspaceSkillManagementError)) return false;
27858
+ res.status(error2.statusCode).json({
27859
+ error: error2.message,
27860
+ code: error2.code
27861
+ });
27862
+ return true;
27863
+ }
27864
+ __name(sendSkillManagementError, "sendSkillManagementError");
26943
27865
  function registerWorkspaceSkillsRoutes(app, deps) {
26944
27866
  const buildWorkspaceCtx = createBuildWorkspaceCtx(
26945
27867
  deps.workspaceRuntime.workspaceCwd
26946
27868
  );
26947
27869
  const route = "POST /workspace/skills/:name/enable";
27870
+ app.post(
27871
+ "/workspace/skills/install",
27872
+ deps.mutate({ strict: true }),
27873
+ async (req, res) => {
27874
+ if (!requireTrustedWorkspaceRuntime(deps.workspaceRuntime, res)) return;
27875
+ const input = parseSkillInstallRequest(req, res, deps.safeBody);
27876
+ if (!input) return;
27877
+ const clientId = deps.parseAndValidateClientId(req, res);
27878
+ if (clientId === null) return;
27879
+ const installRoute = "POST /workspace/skills/install";
27880
+ try {
27881
+ const result = await deps.workspaceRuntime.workspaceService.installWorkspaceSkill(
27882
+ buildWorkspaceCtx(installRoute, clientId),
27883
+ input
27884
+ );
27885
+ res.status(200).json(result);
27886
+ } catch (err) {
27887
+ if (!sendSkillManagementError(res, err))
27888
+ deps.sendBridgeError(res, err, { route: installRoute });
27889
+ }
27890
+ }
27891
+ );
27892
+ app.delete(
27893
+ "/workspace/skills/:name",
27894
+ deps.mutate({ strict: true }),
27895
+ async (req, res) => {
27896
+ if (!requireTrustedWorkspaceRuntime(deps.workspaceRuntime, res)) return;
27897
+ const rawSkillName = req.params["name"];
27898
+ const scope = parseDeleteScope(req, res);
27899
+ if (!rawSkillName || !scope) return;
27900
+ let skillName;
27901
+ try {
27902
+ skillName = validateWorkspaceSkillName(rawSkillName);
27903
+ } catch (error2) {
27904
+ sendSkillManagementError(res, error2);
27905
+ return;
27906
+ }
27907
+ const clientId = deps.parseAndValidateClientId(req, res);
27908
+ if (clientId === null) return;
27909
+ const deleteRoute = "DELETE /workspace/skills/:name";
27910
+ try {
27911
+ const result = await deps.workspaceRuntime.workspaceService.deleteWorkspaceSkill(
27912
+ buildWorkspaceCtx(deleteRoute, clientId),
27913
+ skillName,
27914
+ scope
27915
+ );
27916
+ res.status(200).json(result);
27917
+ } catch (err) {
27918
+ if (!sendSkillManagementError(res, err))
27919
+ deps.sendBridgeError(res, err, { route: deleteRoute });
27920
+ }
27921
+ }
27922
+ );
26948
27923
  app.post(
26949
27924
  "/workspace/skills/:name/enable",
26950
27925
  deps.mutate({ strict: true }),
@@ -26970,6 +27945,77 @@ function registerWorkspaceSkillsRoutes(app, deps) {
26970
27945
  __name(registerWorkspaceSkillsRoutes, "registerWorkspaceSkillsRoutes");
26971
27946
  function registerWorkspaceQualifiedSkillsRoutes(app, deps) {
26972
27947
  const route = "POST /workspaces/:workspace/skills/:name/enable";
27948
+ app.post(
27949
+ "/workspaces/:workspace/skills/install",
27950
+ deps.mutate({ strict: true }),
27951
+ async (req, res) => {
27952
+ const runtime = resolveWorkspaceRuntimeFromParam(
27953
+ deps.workspaceRegistry,
27954
+ req,
27955
+ res
27956
+ );
27957
+ if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
27958
+ const input = parseSkillInstallRequest(req, res, deps.safeBody);
27959
+ if (!input) return;
27960
+ const clientId = parseAndValidateWorkspaceClientId(
27961
+ req,
27962
+ res,
27963
+ runtime.bridge
27964
+ );
27965
+ if (clientId === null) return;
27966
+ const installRoute = "POST /workspaces/:workspace/skills/install";
27967
+ try {
27968
+ const result = await runtime.workspaceService.installWorkspaceSkill(
27969
+ createBuildWorkspaceCtx(runtime.workspaceCwd)(installRoute, clientId),
27970
+ input
27971
+ );
27972
+ res.status(200).json(result);
27973
+ } catch (err) {
27974
+ if (!sendSkillManagementError(res, err))
27975
+ deps.sendBridgeError(res, err, { route: installRoute });
27976
+ }
27977
+ }
27978
+ );
27979
+ app.delete(
27980
+ "/workspaces/:workspace/skills/:name",
27981
+ deps.mutate({ strict: true }),
27982
+ async (req, res) => {
27983
+ const runtime = resolveWorkspaceRuntimeFromParam(
27984
+ deps.workspaceRegistry,
27985
+ req,
27986
+ res
27987
+ );
27988
+ if (!runtime || !requireTrustedWorkspaceRuntime(runtime, res)) return;
27989
+ const rawSkillName = req.params["name"];
27990
+ const scope = parseDeleteScope(req, res);
27991
+ if (!rawSkillName || !scope) return;
27992
+ let skillName;
27993
+ try {
27994
+ skillName = validateWorkspaceSkillName(rawSkillName);
27995
+ } catch (error2) {
27996
+ sendSkillManagementError(res, error2);
27997
+ return;
27998
+ }
27999
+ const clientId = parseAndValidateWorkspaceClientId(
28000
+ req,
28001
+ res,
28002
+ runtime.bridge
28003
+ );
28004
+ if (clientId === null) return;
28005
+ const deleteRoute = "DELETE /workspaces/:workspace/skills/:name";
28006
+ try {
28007
+ const result = await runtime.workspaceService.deleteWorkspaceSkill(
28008
+ createBuildWorkspaceCtx(runtime.workspaceCwd)(deleteRoute, clientId),
28009
+ skillName,
28010
+ scope
28011
+ );
28012
+ res.status(200).json(result);
28013
+ } catch (err) {
28014
+ if (!sendSkillManagementError(res, err))
28015
+ deps.sendBridgeError(res, err, { route: deleteRoute });
28016
+ }
28017
+ }
28018
+ );
26973
28019
  app.post(
26974
28020
  "/workspaces/:workspace/skills/:name/enable",
26975
28021
  deps.mutate({ strict: true }),
@@ -27484,6 +28530,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
27484
28530
  primaryEffectiveEnv ? { env: primaryEffectiveEnv } : {}
27485
28531
  ),
27486
28532
  workspaceSkillsStatusProvider: createWorkspaceSkillsStatusProvider(),
28533
+ ...primaryEffectiveEnv ? { skillInstallEnv: primaryEffectiveEnv } : {},
27487
28534
  ...primaryEffectiveEnv ? { voiceEnv: primaryEffectiveEnv } : {},
27488
28535
  isChannelLive: /* @__PURE__ */ __name(() => bridge.isChannelLive(), "isChannelLive"),
27489
28536
  persistDisabledTools: deps.persistDisabledTools ?? (async () => {
@@ -27528,6 +28575,8 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
27528
28575
  );
27529
28576
  app.locals.workspaceRegistry = workspaceRegistry;
27530
28577
  const primaryRuntime = workspaceRegistry.primary;
28578
+ const daemonEnv = deps.daemonEnv ?? process.env;
28579
+ const primaryRuntimeEffectiveEnv = getRuntimeEffectiveEnv(primaryRuntime.env) ?? daemonEnv;
27531
28580
  const voiceCoordinator = deps.voiceCoordinator ?? new WorkspaceVoiceCoordinator();
27532
28581
  const primaryBoundWorkspace = primaryRuntime.workspaceCwd;
27533
28582
  const primaryBridge = primaryRuntime.bridge;
@@ -27617,38 +28666,27 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
27617
28666
  requireAuth: opts.requireAuth === true
27618
28667
  });
27619
28668
  app.use(
27620
- daemonTelemetryMiddleware(
27621
- (req) => {
27622
- const match = req.path.match(/^\/workspaces\/([^/]+)/);
27623
- const rawSelector = match?.[1];
27624
- if (rawSelector) {
27625
- try {
27626
- const selector = decodeURIComponent(rawSelector);
27627
- const byId = workspaceRegistry.getByWorkspaceId(selector);
27628
- if (byId) return byId.workspaceCwd;
27629
- if (isPortableAbsolutePath(selector)) {
27630
- const runtime = resolveRegisteredWorkspaceRuntimeByPathSelector(
27631
- workspaceRegistry,
27632
- selector
27633
- );
27634
- if (runtime) return runtime.workspaceCwd;
27635
- }
27636
- } catch {
27637
- return primaryBoundWorkspace;
27638
- }
27639
- }
27640
- return primaryBoundWorkspace;
27641
- },
27642
- deps.recordDaemonRequest,
27643
- (sessionId) => {
28669
+ daemonTelemetryMiddleware((req) => {
28670
+ const match = req.path.match(/^\/workspaces\/([^/]+)/);
28671
+ const rawSelector = match?.[1];
28672
+ if (rawSelector) {
27644
28673
  try {
27645
- const owner = workspaceRegistry.resolveLiveSessionOwner(sessionId);
27646
- return owner.kind === "found" ? owner.runtime.workspaceCwd : void 0;
28674
+ const selector = decodeURIComponent(rawSelector);
28675
+ const byId = workspaceRegistry.getByWorkspaceId(selector);
28676
+ if (byId) return byId.workspaceCwd;
28677
+ if (isPortableAbsolutePath(selector)) {
28678
+ const runtime = resolveRegisteredWorkspaceRuntimeByPathSelector(
28679
+ workspaceRegistry,
28680
+ selector
28681
+ );
28682
+ if (runtime) return runtime.workspaceCwd;
28683
+ }
27647
28684
  } catch {
27648
- return void 0;
28685
+ return primaryBoundWorkspace;
27649
28686
  }
27650
28687
  }
27651
- )
28688
+ return primaryBoundWorkspace;
28689
+ }, deps.recordDaemonRequest)
27652
28690
  );
27653
28691
  const buildWorkspaceCtx = createBuildWorkspaceCtx(primaryBoundWorkspace);
27654
28692
  const acpHandleRef = {};
@@ -27713,6 +28751,14 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
27713
28751
  gitState: workspaceGitState,
27714
28752
  sendBridgeError: sendBridgeError2
27715
28753
  });
28754
+ registerWorkspaceGitDiffRoutes(app, {
28755
+ boundWorkspace: primaryBoundWorkspace,
28756
+ sendBridgeError: sendBridgeError2
28757
+ });
28758
+ registerWorkspaceQualifiedGitDiffRoutes(app, {
28759
+ workspaceRegistry,
28760
+ sendBridgeError: sendBridgeError2
28761
+ });
27716
28762
  mountWorkspaceMemoryRoutes(app, {
27717
28763
  bridge: primaryBridge,
27718
28764
  boundWorkspace: primaryBoundWorkspace,
@@ -27790,6 +28836,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
27790
28836
  registerWorkspaceSetupGithubRoutes(app, {
27791
28837
  boundWorkspace: primaryBoundWorkspace,
27792
28838
  bridge: primaryBridge,
28839
+ env: primaryRuntimeEffectiveEnv,
27793
28840
  mutate,
27794
28841
  parseClientId: parseClientIdHeader,
27795
28842
  safeBody
@@ -27965,6 +29012,10 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
27965
29012
  parseAndValidateClientId: /* @__PURE__ */ __name((req, res) => parseAndValidateWorkspaceClientId(req, res, primaryBridge), "parseAndValidateClientId")
27966
29013
  });
27967
29014
  }
29015
+ registerWorkspaceChannelObservedContactRoutes(app, {
29016
+ primaryWorkspace: primaryBoundWorkspace,
29017
+ workspaceRegistry
29018
+ });
27968
29019
  registerWorkspaceLifecycleRoutes(app, {
27969
29020
  boundWorkspace: primaryBoundWorkspace,
27970
29021
  workspace: primaryWorkspace,
@@ -28014,6 +29065,10 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
28014
29065
  safeBody,
28015
29066
  bridge: deps.manageScheduledTaskSessions ? bridge : void 0
28016
29067
  });
29068
+ registerGoalsRoutes(app, {
29069
+ boundWorkspace: primaryBoundWorkspace,
29070
+ bridge: primaryBridge
29071
+ });
28017
29072
  registerWorkspaceQualifiedScheduledTasksRoutes(app, {
28018
29073
  workspaceRegistry,
28019
29074
  mutate,
@@ -28086,6 +29141,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
28086
29141
  });
28087
29142
  acpHandleRef.current = mountAcpHttp(app, primaryBridge, {
28088
29143
  boundWorkspace: primaryBoundWorkspace,
29144
+ daemonEnv,
28089
29145
  // Phase 4 (issue #6378): pass the registry so `/workspaces/:workspace/acp`
28090
29146
  // mounts a per-runtime ACP dispatcher for each registered workspace.
28091
29147
  workspaceRegistry,
@@ -28157,6 +29213,7 @@ export {
28157
29213
  createServeApp,
28158
29214
  detectFromLoopback,
28159
29215
  getActiveSseCount,
29216
+ getWorkspaceSessionInfoForResponse,
28160
29217
  listWorkspaceSessionsForResponse,
28161
29218
  resolveBoundWorkspacesFromIdeEnv,
28162
29219
  resolveBridgeFsFactory,