@qwen-code/qwen-code 0.19.10 → 0.19.11-nightly.20260717.f8e6e8931
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.
- package/bundled/qc-helper/docs/configuration/settings.md +7 -6
- package/bundled/qc-helper/docs/features/approval-mode.md +2 -2
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +30 -0
- package/bundled/qc-helper/docs/features/channels/overview.md +53 -17
- package/bundled/qc-helper/docs/features/channels/wecom.md +8 -7
- package/bundled/qc-helper/docs/features/sandbox.md +2 -0
- package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +42 -7
- package/bundled/qc-helper/docs/qwen-serve.md +53 -46
- package/bundled/review/SKILL.md +163 -403
- package/chunks/{MaxSizedBox-67ODZ4SZ.js → MaxSizedBox-JGTP7YJQ.js} +13 -13
- package/chunks/{StandaloneSessionPicker-SIPBQT5Z.js → StandaloneSessionPicker-2XQDOYZ5.js} +27 -27
- package/chunks/{acpAgent-VPZJXLFX.js → acpAgent-RXRJA7GD.js} +1135 -373
- package/chunks/{agent-Z7NWL6XL.js → agent-UQP53UWQ.js} +10 -10
- package/chunks/{agent-headless-73HZ6ROQ.js → agent-headless-I52OXDCK.js} +10 -10
- package/chunks/{anthropicContentGenerator-56U3YCP2.js → anthropicContentGenerator-HBRXJSP4.js} +76 -14
- package/chunks/{artifact-tool-BWZZJ42H.js → artifact-tool-MIZLXBLF.js} +1 -1
- package/chunks/{askUserQuestion-WU3S5A5T.js → askUserQuestion-XMJVPNWM.js} +1 -1
- package/chunks/{bridge-XFKW6S7Q.js → bridge-3DVRNBSF.js} +14 -16
- package/chunks/{ca-C2JTT2N5.js → ca-CODEN7TD.js} +5 -0
- package/chunks/channel-worker-group-SOUWTFHC.js +21 -0
- package/chunks/{channel-worker-manager-5RWKSGEU.js → channel-worker-manager-LOVSV3WW.js} +34 -10
- package/chunks/{channel-worker-supervisor-PCDAZN4D.js → channel-worker-supervisor-XW6MHJBQ.js} +6 -4
- package/chunks/{chunk-BBNVFRGD.js → chunk-3DWIFU7L.js} +1 -1
- package/chunks/{chunk-ZQTZXVHP.js → chunk-3KSHYS4T.js} +4 -18
- package/chunks/{chunk-ZKMGAFYV.js → chunk-3LS57JZI.js} +1 -1
- package/chunks/{chunk-B5I2IIWY.js → chunk-46Y6SSQ7.js} +5 -5
- package/chunks/{chunk-GDQQRV43.js → chunk-4BJVSIS3.js} +2 -2
- package/chunks/{chunk-L37RC7MQ.js → chunk-4HTHLSIH.js} +1 -1
- package/chunks/{chunk-DPFBNG72.js → chunk-4UBEB74N.js} +1 -1
- package/chunks/{chunk-AAR5SGMD.js → chunk-4YR7FSAM.js} +7 -5
- package/chunks/{chunk-OATTJGPJ.js → chunk-5CNYZ7TN.js} +7 -7
- package/chunks/{chunk-JSJFKYWT.js → chunk-5VWYKIMW.js} +1 -1
- package/chunks/{chunk-6GETGQWP.js → chunk-5WWYHNAH.js} +39 -10
- package/chunks/{chunk-65N2J6V2.js → chunk-6ANLV27M.js} +2 -2
- package/chunks/{chunk-L62SEJWY.js → chunk-6RV42SFP.js} +4 -4
- package/chunks/{chunk-XXJKGHZV.js → chunk-6VMOP2Z7.js} +4 -4
- package/chunks/{chunk-URU5UEK6.js → chunk-6WGZDD67.js} +135 -68
- package/chunks/{chunk-7NAWTFVY.js → chunk-6WPJRYLZ.js} +2 -2
- package/chunks/chunk-6WVLHULT.js +59 -0
- package/chunks/{chunk-N6FXRR6P.js → chunk-7ZFXHKKZ.js} +1 -1
- package/chunks/{chunk-E67NFMF4.js → chunk-A2HWMJVO.js} +35 -1
- package/chunks/{chunk-4FMG7EDJ.js → chunk-AEKHQ3E5.js} +77 -11
- package/chunks/{chunk-WIASPMLX.js → chunk-AH3YAJU6.js} +22 -33
- package/chunks/{chunk-6GKMJPOC.js → chunk-AHAH5H6D.js} +3 -3
- package/chunks/{chunk-3XJFUTNM.js → chunk-AVAU67KP.js} +57 -10
- package/chunks/{chunk-LNUXFLLJ.js → chunk-BDHYJ2MM.js} +53 -5
- package/chunks/{chunk-P6LART6G.js → chunk-BTSE2DUP.js} +957 -122
- package/chunks/{chunk-7MJAZMXK.js → chunk-BZ5D7OVV.js} +28 -77
- package/chunks/{chunk-WDWJ4OQJ.js → chunk-CC2UASQ4.js} +3 -3
- package/chunks/{chunk-WLXYAKV7.js → chunk-D7KYA6EY.js} +3 -3
- package/chunks/{chunk-5LROA5W4.js → chunk-DD45XVOQ.js} +3 -3
- package/chunks/{chunk-H3FQOPPS.js → chunk-DOPUYNXO.js} +2 -2
- package/chunks/{chunk-SPUYQB4T.js → chunk-DPXB3XRN.js} +1 -1
- package/chunks/{chunk-XLIRF7IK.js → chunk-E7ECGLZW.js} +1 -1
- package/chunks/{chunk-RDRVMDWV.js → chunk-EMJJBXS7.js} +10 -10
- package/chunks/{chunk-TXY2C3D2.js → chunk-F333XEAU.js} +1 -1
- package/chunks/chunk-FEOZBUMT.js +77 -0
- package/chunks/{chunk-YYPXHMWO.js → chunk-FEYHXPZG.js} +4 -4
- package/chunks/{chunk-ZRKBI3DP.js → chunk-FNX3LGAK.js} +1 -1
- package/chunks/chunk-FXK3QMRD.js +140 -0
- package/chunks/{chunk-422XAKCK.js → chunk-G5ZKRK2E.js} +2 -2
- package/chunks/{chunk-DK33QJ3V.js → chunk-GCRFH57X.js} +732 -13
- package/chunks/{chunk-EQY6POVO.js → chunk-GLEJW7T2.js} +1 -1
- package/chunks/{chunk-FXMC7SL2.js → chunk-I6NOSIVF.js} +1 -1
- package/chunks/{chunk-VBRRNQB7.js → chunk-IHJRUIWN.js} +109 -22
- package/chunks/{chunk-F7NXQH4Y.js → chunk-IIXEI2VE.js} +1 -1
- package/chunks/{chunk-2UUAIFQO.js → chunk-JGUT3LWZ.js} +5 -0
- package/chunks/{chunk-5EBKKSBX.js → chunk-JY74T7PW.js} +1 -1
- package/chunks/chunk-KSZKSE23.js +226 -0
- package/chunks/{chunk-MO7O5722.js → chunk-KW46DBFM.js} +35 -2
- package/chunks/{chunk-TISZXPAX.js → chunk-L263ROM6.js} +1 -1
- package/chunks/chunk-LXXMOYPL.js +22 -0
- package/chunks/{chunk-YX4LLZ3D.js → chunk-NABT4VOY.js} +109 -35
- package/chunks/{chunk-W34A5MJH.js → chunk-NROLDLP4.js} +1 -1
- package/chunks/{chunk-V7EQTZYR.js → chunk-O3WCEZEN.js} +191 -44
- package/chunks/{chunk-K4PZ5F5T.js → chunk-OWT2CAEQ.js} +1 -1
- package/chunks/{chunk-4YWLED2A.js → chunk-PNCWEDF6.js} +7 -4
- package/chunks/{chunk-WDW64OW3.js → chunk-PSDTLRAV.js} +5 -5
- package/chunks/{chunk-7R4DPSRA.js → chunk-R3VWUU2E.js} +1 -1
- package/chunks/{chunk-K7CRWKOE.js → chunk-R6AO7HBQ.js} +4617 -4012
- package/chunks/{chunk-6OATMEYN.js → chunk-RTV5TUYB.js} +12 -4
- package/chunks/{chunk-6W6DI34P.js → chunk-SE6GSFAO.js} +159 -2
- package/chunks/{chunk-WTSXKLG5.js → chunk-SUARMD4Q.js} +1 -1
- package/chunks/chunk-T4TZQJ7W.js +48 -0
- package/chunks/{chunk-LTNI523B.js → chunk-T7CZYIAU.js} +28 -5
- package/chunks/{chunk-3MX7D6QN.js → chunk-TIOE2OPE.js} +32 -4
- package/chunks/{chunk-TTUO4DNG.js → chunk-UF6ZTWU5.js} +75 -710
- package/chunks/{chunk-Q5GLXH5Q.js → chunk-UJG4VV2O.js} +5 -5
- package/chunks/{chunk-CJFNEBYB.js → chunk-VFEZWI6F.js} +1 -1
- package/chunks/{chunk-UFOKA4PR.js → chunk-VHCSIMTF.js} +114 -4
- package/chunks/{chunk-TQBODCFD.js → chunk-VRR65QYW.js} +250 -2
- package/chunks/{chunk-CUUXANEQ.js → chunk-W6J7RSCK.js} +6 -1
- package/chunks/{chunk-YHN5SUIJ.js → chunk-W7H223ZZ.js} +1 -1
- package/chunks/{chunk-WX6SD4IQ.js → chunk-WTNZ6DXB.js} +1 -1
- package/chunks/{chunk-GGJII3FM.js → chunk-WZJELXEU.js} +92 -3
- package/chunks/{chunk-OFEVHGVU.js → chunk-X5HZX4EP.js} +9 -11
- package/chunks/{chunk-KSO42X3Z.js → chunk-X6YQWCIJ.js} +21 -2
- package/chunks/{chunk-7L4XBYVW.js → chunk-XK42MWWO.js} +9 -2
- package/chunks/{chunk-X362TMXZ.js → chunk-XQDPCQ3A.js} +7 -5
- package/chunks/{chunk-YU56QGXX.js → chunk-Y3TNSHKF.js} +1 -1
- package/chunks/{chunk-HHEFI4RP.js → chunk-YOJGIRTD.js} +714 -109
- package/chunks/{chunk-CEW4HDPK.js → chunk-ZK4AMPKI.js} +2459 -350
- package/chunks/{chunk-SXU3KKNI.js → chunk-ZQIYGQCG.js} +251 -54
- package/chunks/{computer-use-IYTX45WA.js → computer-use-LTW3VB6L.js} +10 -10
- package/chunks/{config-utils-CFT33LTP.js → config-utils-IQQT3GCI.js} +3 -3
- package/chunks/{contextCommand-272V77WU.js → contextCommand-GLMC6CTP.js} +12 -12
- package/chunks/{create-sub-session-WNX2OQVX.js → create-sub-session-EAB2U5XW.js} +1 -1
- package/chunks/{create-sub-session-CBJMQLYP.js → create-sub-session-YMWQAWSN.js} +10 -10
- package/chunks/{cron-create-36TIFKRT.js → cron-create-GMVKSXZT.js} +1 -1
- package/chunks/{cron-delete-OQD3WULU.js → cron-delete-VDZKUAVK.js} +1 -1
- package/chunks/{cron-list-4533T2FH.js → cron-list-UG7C7RAR.js} +1 -1
- package/chunks/{daemon-RNGFPMAB.js → daemon-PRB64RP5.js} +303 -71
- package/chunks/{daemon-status-provider-L4STG5VO.js → daemon-status-provider-5OMM5JHF.js} +19 -20
- package/chunks/{de-2VCDRDGU.js → de-NOXPCSYN.js} +5 -0
- package/chunks/{dist-ERCPDVA6.js → dist-4WCQEZIN.js} +4 -51
- package/chunks/{dist-MOEC47TR.js → dist-DOPL5LSQ.js} +1 -1
- package/chunks/{dist-JZE7F6YR.js → dist-GXJVCOS7.js} +1 -1
- package/chunks/{dist-PHEPJLXD.js → dist-PX2ERZ6I.js} +2 -2
- package/chunks/{dist-HNN7DR2L.js → dist-V2YVLYOW.js} +58 -30
- package/chunks/{dist-3V3ZV6ML.js → dist-VYWUKURL.js} +1 -1
- package/chunks/{earlyInputCapture-EN4BRREQ.js → earlyInputCapture-A3WSRN4T.js} +10 -10
- package/chunks/{edit-OMAF2QDR.js → edit-7PG4AH27.js} +10 -10
- package/chunks/{en-NJCA3TAA.js → en-JFVULHTB.js} +6 -0
- package/chunks/{enter-worktree-BBZX52HG.js → enter-worktree-QUSB44RE.js} +10 -10
- package/chunks/{enterPlanMode-5NNFMBUY.js → enterPlanMode-NVSIEL7X.js} +10 -10
- package/chunks/{environment-7TEWMJYN.js → environment-AHHXHQTI.js} +12 -12
- package/chunks/{errors-I4VKVX3F.js → errors-NSWSRXC7.js} +12 -12
- package/chunks/{exit-worktree-FUWRJI33.js → exit-worktree-FXYEYHPL.js} +10 -10
- package/chunks/{exitPlanMode-IHCJ5EEI.js → exitPlanMode-JI5GK3F6.js} +10 -10
- package/chunks/{fast-path-ZA57TOH4.js → fast-path-X7EVDLKZ.js} +2 -2
- package/chunks/{fr-5F3E7WKD.js → fr-HVFNU42H.js} +5 -0
- package/chunks/{gemini-UOAKVXBG.js → gemini-YRLHY5KS.js} +162 -206
- package/chunks/{geminiContentGenerator-G6UCE6MW.js → geminiContentGenerator-SPLFPV5E.js} +1 -1
- package/chunks/{glob-4GJQ2UFF.js → glob-WASUBCSA.js} +10 -10
- package/chunks/{grep-5QSYXF2E.js → grep-DUVG3NGA.js} +10 -10
- package/chunks/{handleAutoUpdate-ULHNWL6R.js → handleAutoUpdate-NGE5AQ2N.js} +14 -14
- package/chunks/{i18n-CYDUTF6F.js → i18n-QNVR36NB.js} +11 -11
- package/chunks/{initializer-NRFKUGIO.js → initializer-ZY7ORPMH.js} +15 -15
- package/chunks/{installationInfo-WELKRHHE.js → installationInfo-4R75MFTB.js} +11 -11
- package/chunks/{ja-66J6B53L.js → ja-PY5AF544.js} +5 -0
- package/chunks/{list-JVDXEG2E.js → list-36JCMZRS.js} +18 -18
- package/chunks/{loadedSettingsAdapter-WAM4VUTG.js → loadedSettingsAdapter-PQIOJUSJ.js} +15 -15
- package/chunks/{loop-wakeup-MVUKDVCP.js → loop-wakeup-QXWZSCYM.js} +2 -2
- package/chunks/{ls-RXNIAQDE.js → ls-2OUTG3IZ.js} +1 -1
- package/chunks/{lsp-HB5LM5IL.js → lsp-4VMNXZW6.js} +1 -1
- package/chunks/{mcp-YHOZN3ZM.js → mcp-QXY6XA6H.js} +15 -15
- package/chunks/{monitor-R7XZPJHQ.js → monitor-AVEKRSY3.js} +12 -11
- package/chunks/{nonInteractiveCli-NSOB6D74.js → nonInteractiveCli-YWIBKX4M.js} +50 -50
- package/chunks/{notebook-edit-6RNKE2L2.js → notebook-edit-4SBTJX72.js} +10 -10
- package/chunks/{openaiContentGenerator-XNS5S64I.js → openaiContentGenerator-4EBAO7LR.js} +8 -8
- package/chunks/{pidfile-XE4RRR2P.js → pidfile-JMIUPXSU.js} +10 -10
- package/chunks/processUtils-EOINMEIH.js +29 -0
- package/chunks/{pt-TFZO5Y6T.js → pt-A3PRQXMU.js} +5 -0
- package/chunks/{qwenContentGenerator-APDPJ3VN.js → qwenContentGenerator-M7UBL3JS.js} +12 -12
- package/chunks/{read-file-XSUWXSR7.js → read-file-DXSEFHCV.js} +5 -5
- package/chunks/{read-mcp-resource-6LRTZKXI.js → read-mcp-resource-JUFHCKSC.js} +1 -1
- package/chunks/{record-artifact-PMDTY4OS.js → record-artifact-DWSMBXYY.js} +1 -1
- package/chunks/{ripGrep-APB3CDMU.js → ripGrep-VTRVFMDJ.js} +10 -10
- package/chunks/{ru-4L4LFHIT.js → ru-IBCWUTOC.js} +5 -0
- package/chunks/{run-qwen-serve-NWTGPERT.js → run-qwen-serve-P7WQDZAS.js} +59 -38
- package/chunks/{runtime-EIO3NQKR.js → runtime-UHYO6JGN.js} +19 -19
- package/chunks/{scheduler-JJDZBDRN.js → scheduler-WTK7ZLV5.js} +10 -10
- package/chunks/{send-message-SR4WSXP2.js → send-message-JZ752NWD.js} +2 -2
- package/chunks/{serve-WTIPB3EI.js → serve-AG2AOG56.js} +15 -15
- package/chunks/{server-NJPHQHLH.js → server-G5MM2BRI.js} +1157 -225
- package/chunks/{session-O4AO7FTS.js → session-NUAGEMVS.js} +51 -51
- package/chunks/{settings-HQNDK7TG.js → settings-VQA5PR2M.js} +14 -14
- package/chunks/{shell-UIXM6PWG.js → shell-X33RWGLP.js} +12 -10
- package/chunks/{skill-3XMB4ULV.js → skill-PHSU2OPP.js} +5 -5
- package/chunks/{spawnChannel-3R632QRM.js → spawnChannel-D6TZN4W7.js} +12 -13
- package/chunks/{src-USZKPUOC.js → src-6OJFUPTL.js} +95 -34
- package/chunks/{standalone-update-L5XW3D7K.js → standalone-update-ZARRW44Y.js} +12 -12
- package/chunks/{startInteractiveUI-CPZOL2WB.js → startInteractiveUI-C6IZRTF3.js} +176 -158
- package/chunks/{syntheticOutput-YKFNUQZD.js → syntheticOutput-LELY6HAI.js} +2 -2
- package/chunks/{task-create-NUFOHU53.js → task-create-QY3BIMNM.js} +3 -3
- package/chunks/{task-list-Z2IKQY3S.js → task-list-D2U47WBJ.js} +1 -1
- package/chunks/{task-stop-KQFIVQTJ.js → task-stop-N6E5IYLH.js} +1 -1
- package/chunks/{task-update-HKADXSTD.js → task-update-HJCQILLB.js} +3 -3
- package/chunks/{team-create-XXPRF3IQ.js → team-create-H434NQP2.js} +10 -10
- package/chunks/{team-delete-SDNTGZLG.js → team-delete-RCWYDRF4.js} +1 -1
- package/chunks/{team-plan-approval-EOTTKHDW.js → team-plan-approval-IIOHXZU6.js} +10 -10
- package/chunks/{theme-manager-P6UITO2L.js → theme-manager-IEOPHMX6.js} +10 -10
- package/chunks/{todoWrite-YNXB27GB.js → todoWrite-FKCGATPJ.js} +1 -1
- package/chunks/{tool-search-DDNGK2LR.js → tool-search-WIIEDALL.js} +6 -6
- package/chunks/{total-session-admission-PL5N7DNY.js → total-session-admission-WU3DORRW.js} +15 -17
- package/chunks/{trustedFolders-C5LMF3UR.js → trustedFolders-JVUTUAJ3.js} +11 -11
- package/chunks/update-relaunch-X5EQKCH5.js +87 -0
- package/chunks/{updateCheck-QTVVISH7.js → updateCheck-TGO2X735.js} +14 -12
- package/chunks/{validateNonInterActiveAuth-RY4RKBQG.js → validateNonInterActiveAuth-2MEUL2ME.js} +46 -46
- package/chunks/{version-U45RYOSD.js → version-KBGQKZWV.js} +1 -1
- package/chunks/{web-fetch-ZSPR3PRR.js → web-fetch-CFCWTCAP.js} +2 -3
- package/chunks/{workflow-TCIAQYOA.js → workflow-PAOSF4CG.js} +11 -11
- package/chunks/{workspace-providers-status-I3G2HYLY.js → workspace-providers-status-AYHJYSVO.js} +18 -18
- package/chunks/{workspace-registration-store-IH5GLZ6Y.js → workspace-registration-store-GZMR53QL.js} +1 -1
- package/chunks/{workspace-registry-QEKBELIX.js → workspace-registry-C2IXZWPF.js} +15 -17
- package/chunks/{workspace-service-ORKHGLP3.js → workspace-service-KDDAW33F.js} +20 -21
- package/chunks/{workspace-skills-status-D7QCNDYY.js → workspace-skills-status-WWEZBZXY.js} +16 -16
- package/chunks/{write-file-JGRQR5VM.js → write-file-ACN3TAIX.js} +10 -10
- package/chunks/{zh-FSAH32JB.js → zh-PAUNIMHQ.js} +6 -0
- package/chunks/{zh-TW-D2YIE2LO.js → zh-TW-GNEUIUFF.js} +6 -0
- package/cli-entry.js +92 -8
- package/cli.js +11 -11
- package/locales/ca.js +10 -0
- package/locales/de.js +10 -0
- package/locales/en.js +11 -0
- package/locales/fr.js +10 -0
- package/locales/ja.js +10 -0
- package/locales/pt.js +10 -0
- package/locales/ru.js +10 -0
- package/locales/zh-TW.js +11 -0
- package/locales/zh.js +11 -0
- package/package.json +3 -3
- package/web-shell/assets/{arc-CUeDlxvE.js → arc-Blc5_CnD.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-PiUszkQA.js → architectureDiagram-3BPJPVTR-Dyv1BvGP.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-s2wYSO7e.js → blockDiagram-GPEHLZMM-CVAb8DyB.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-DyLxZoz9.js → c4Diagram-AAUBKEIU-ClHPb_6S.js} +1 -1
- package/web-shell/assets/channel-DkPTtnGS.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-Dsdai7Tk.js → chunk-2J33WTMH-Dad9g3ZA.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-DEosOjV7.js → chunk-4BX2VUAB-IJJSSdDs.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-sNsRLTXf.js → chunk-55IACEB6-DRcc-Hl9.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-DkRNZzmh.js → chunk-727SXJPM-DOCFB-6a.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-BrsRNpzd.js → chunk-AQP2D5EJ-CRZnSjHp.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-CI039lpl.js → chunk-FMBD7UC4-BwUI4Yes.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-M-pkeIfu.js → chunk-ND2GUHAM-DLy8doxd.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-C4ckGNbH.js → chunk-QZHKN3VN-Bhz7iysj.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-DBdPU8ix.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-DBdPU8ix.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-BciKUAFq.js → cose-bilkent-S5V4N54A-jT1e8KzN.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-C1nTSgU6.js → dagre-BM42HDAG-C1veApQk.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-BDPNWr1m.js → diagram-2AECGRRQ-C_NOwKeT.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-CNFhTszL.js → diagram-5GNKFQAL-Bigfuz1r.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-CjPa4p5a.js → diagram-KO2AKTUF-CpXltPpU.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-ZzPykSyG.js → diagram-LMA3HP47-DYawbYbH.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-0UVtZ9A4.js → diagram-OG6HWLK6-D2t-ttd1.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-CajDZCat.js → erDiagram-TEJ5UH35-Buc53PB5.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-BRuFBIvL.js → flowDiagram-I6XJVG4X-DwdFsCN7.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-BevGmJqG.js → ganttDiagram-6RSMTGT7-XhiEKGoP.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-DvPMpBMb.js → gitGraphDiagram-PVQCEYII-D6We014a.js} +1 -1
- package/web-shell/assets/index-BctAmeF3.js +1143 -0
- package/web-shell/assets/{index-DzHwQkQq.js → index-CAWqS-bZ.js} +1 -1
- package/web-shell/assets/index-DLyhlZZO.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-Oixn7tA9.js → infoDiagram-5YYISTIA-C_iugRHQ.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-BgKpeg-j.js → ishikawaDiagram-YF4QCWOH-CAn9Kaix.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-74mwxIaA.js → journeyDiagram-JHISSGLW-BjDYOkEB.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-D4D6cEqA.js → kanban-definition-UN3LZRKU-Br_oI3Ob.js} +1 -1
- package/web-shell/assets/{linear-atZRE_L2.js → linear-BqnWHE9E.js} +1 -1
- package/web-shell/assets/{mermaid.core-KKudX-JC.js → mermaid.core-CT-sofSb.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-CMCej9yG.js → mindmap-definition-RKZ34NQL-BbvrZR4B.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-nhx40X7q.js → pieDiagram-4H26LBE5-gAwi3h_Q.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-CUmVcN3M.js → quadrantDiagram-W4KKPZXB-CONvBIuO.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-C_vyEwyy.js → requirementDiagram-4Y6WPE33-lpkrcy1e.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-DU6G4VWR.js → sankeyDiagram-5OEKKPKP-Bk6FJHqb.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DdeRR_KJ.js → sequenceDiagram-3UESZ5HK-B9b9bBzt.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-C6iCI8ps.js → stateDiagram-AJRCARHV-JqBGC-S3.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-B_w4fDnm.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-B_Ea8Cb7.js → timeline-definition-PNZ67QCA-CCCceXDP.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-BPUVZEJA.js → vennDiagram-CIIHVFJN-EHRnmZ09.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-BWEj0lKY.js → wardley-L42UT6IY-CYIcHx3_.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-BvDsdIQw.js → wardleyDiagram-YWT4CUSO-B81AuYRl.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-crz0QhF_.js → xychartDiagram-2RQKCTM6-DOQ6E3z7.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/channel-worker-group-K7QKH6IG.js +0 -13
- package/chunks/chunk-B7NUUEXC.js +0 -311
- package/chunks/chunk-CARU2RR2.js +0 -24
- package/chunks/chunk-GYTKQYDB.js +0 -23
- package/chunks/chunk-LQU7EVFA.js +0 -30
- package/chunks/chunk-OCPBI7J5.js +0 -18
- package/chunks/chunk-OJAMDVF5.js +0 -66
- package/chunks/chunk-TEGEBB2I.js +0 -122
- package/web-shell/assets/channel-DkuJJ0qd.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CwqHc0TB.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CwqHc0TB.js +0 -1
- package/web-shell/assets/index-Cnvv4VcI.css +0 -5
- package/web-shell/assets/index-D1Uyklxa.js +0 -1088
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-C0_6nR6C.js +0 -1
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
openVoiceStream,
|
|
6
|
-
openVoiceStreamWithRetry
|
|
7
|
-
} from "./chunk-JSJFKYWT.js";
|
|
8
|
-
import {
|
|
4
|
+
GENERATION_MAX_PROMPT_BYTES,
|
|
9
5
|
MAX_REMEMBER_CONTENT_BYTES,
|
|
10
6
|
createWorkspaceMemoryExtractionErrorLogger,
|
|
11
7
|
extractRememberErrorCode,
|
|
12
8
|
formatWorkspaceMemoryDreamSummary,
|
|
13
9
|
formatWorkspaceMemoryForgetSummary,
|
|
14
10
|
isValidServerName,
|
|
11
|
+
redactMcpServersSetting,
|
|
15
12
|
replayTranscriptRecordPage,
|
|
13
|
+
restoreRedactedMcpServersSetting,
|
|
16
14
|
shouldSuppressRememberErrorDetails,
|
|
17
15
|
workspaceMemoryFailureCode,
|
|
18
16
|
workspaceMemoryFailureDiagnostics
|
|
19
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-SE6GSFAO.js";
|
|
18
|
+
import {
|
|
19
|
+
openQwenAsrRealtimeStream,
|
|
20
|
+
openVoiceStream,
|
|
21
|
+
openVoiceStreamWithRetry
|
|
22
|
+
} from "./chunk-5VWYKIMW.js";
|
|
20
23
|
import {
|
|
21
24
|
SetupGithubError,
|
|
22
25
|
collectSessionData,
|
|
@@ -27,9 +30,9 @@ import {
|
|
|
27
30
|
toJson,
|
|
28
31
|
toJsonl,
|
|
29
32
|
toMarkdown
|
|
30
|
-
} from "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
+
} from "./chunk-AEKHQ3E5.js";
|
|
34
|
+
import "./chunk-DPXB3XRN.js";
|
|
35
|
+
import "./chunk-SUARMD4Q.js";
|
|
33
36
|
import "./chunk-QHTIBUWB.js";
|
|
34
37
|
import "./chunk-L573Z2QZ.js";
|
|
35
38
|
import {
|
|
@@ -62,9 +65,11 @@ import {
|
|
|
62
65
|
denyBrowserOriginCors,
|
|
63
66
|
detectFromLoopback,
|
|
64
67
|
getAdvertisedServeFeatures,
|
|
68
|
+
getDeferredRuntimeRequestTiming,
|
|
65
69
|
getServeProtocolVersions,
|
|
66
70
|
hostAllowlist,
|
|
67
71
|
isBrowserAutomationMcpAvailable,
|
|
72
|
+
isDeepHealthQuery,
|
|
68
73
|
parseAllowOriginPatterns,
|
|
69
74
|
parseAndValidateWorkspaceClientId,
|
|
70
75
|
parseClientIdHeader,
|
|
@@ -85,28 +90,29 @@ import {
|
|
|
85
90
|
setRateLimiter,
|
|
86
91
|
unsafeRevealSecret,
|
|
87
92
|
validateMcpRuntimeServerName
|
|
88
|
-
} from "./chunk-
|
|
93
|
+
} from "./chunk-KW46DBFM.js";
|
|
89
94
|
import {
|
|
90
95
|
isLoopbackBind
|
|
91
96
|
} from "./chunk-RXFQM6FQ.js";
|
|
92
97
|
import {
|
|
93
98
|
createDaemonStatusProvider
|
|
94
|
-
} from "./chunk-
|
|
95
|
-
import "./chunk-
|
|
99
|
+
} from "./chunk-3KSHYS4T.js";
|
|
100
|
+
import "./chunk-LXXMOYPL.js";
|
|
101
|
+
import "./chunk-CC2UASQ4.js";
|
|
96
102
|
import "./chunk-E5Z2AVNV.js";
|
|
97
103
|
import {
|
|
98
104
|
createWorkspaceProvidersStatusProvider
|
|
99
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-BZ5D7OVV.js";
|
|
100
106
|
import {
|
|
101
107
|
getAuthTypeFromEnv,
|
|
102
108
|
resolveCliGenerationConfig
|
|
103
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-WZJELXEU.js";
|
|
104
110
|
import {
|
|
105
111
|
snapshotProcessEnv
|
|
106
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-3LS57JZI.js";
|
|
107
113
|
import {
|
|
108
114
|
createWorkspaceSkillsStatusProvider
|
|
109
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-D7KYA6EY.js";
|
|
110
116
|
import "./chunk-2W3OOD4W.js";
|
|
111
117
|
import {
|
|
112
118
|
EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
|
|
@@ -118,14 +124,14 @@ import {
|
|
|
118
124
|
transcribeWorkspaceVoiceAudio,
|
|
119
125
|
validateWorkspaceVoiceState,
|
|
120
126
|
voiceSettingsScopeToWire
|
|
121
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-X5HZX4EP.js";
|
|
122
128
|
import {
|
|
123
129
|
PermissionRulesValidationError,
|
|
124
130
|
buildPermissionSettings,
|
|
125
131
|
isPermissionRuleType,
|
|
126
132
|
normalizePermissionRules,
|
|
127
133
|
readPermissionRuleSet
|
|
128
|
-
} from "./chunk-
|
|
134
|
+
} from "./chunk-7ZFXHKKZ.js";
|
|
129
135
|
import {
|
|
130
136
|
assertVoiceBaseUrlNetworkAllowed,
|
|
131
137
|
isStreamingVoiceModel,
|
|
@@ -133,12 +139,12 @@ import {
|
|
|
133
139
|
resolveVoiceTranscriptionConfig,
|
|
134
140
|
sanitizeVoiceErrorMessage,
|
|
135
141
|
transcribeVoiceAudio
|
|
136
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-I6NOSIVF.js";
|
|
137
143
|
import {
|
|
138
144
|
isVoiceEnabled,
|
|
139
145
|
isVoiceMode,
|
|
140
146
|
readVoiceModel
|
|
141
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-4UBEB74N.js";
|
|
142
148
|
import "./chunk-FSA7ERJ2.js";
|
|
143
149
|
import {
|
|
144
150
|
WorkspacePermissionRulesSessionRequiredError,
|
|
@@ -148,24 +154,24 @@ import {
|
|
|
148
154
|
} from "./chunk-OA4JVLSA.js";
|
|
149
155
|
import {
|
|
150
156
|
createTotalSessionAdmissionController
|
|
151
|
-
} from "./chunk-
|
|
157
|
+
} from "./chunk-R3VWUU2E.js";
|
|
152
158
|
import {
|
|
153
159
|
createSingleWorkspaceRegistry,
|
|
154
160
|
createWorkspaceSessionOwnerIndex
|
|
155
|
-
} from "./chunk-
|
|
161
|
+
} from "./chunk-W7H223ZZ.js";
|
|
156
162
|
import "./chunk-GRC5HGPI.js";
|
|
157
163
|
import {
|
|
158
164
|
SessionArtifactAuthorizationError,
|
|
159
165
|
SessionArtifactValidationError,
|
|
160
|
-
createAcpSessionBridge
|
|
161
|
-
|
|
166
|
+
createAcpSessionBridge,
|
|
167
|
+
parseSessionSource
|
|
168
|
+
} from "./chunk-YOJGIRTD.js";
|
|
162
169
|
import "./chunk-PZL23GTM.js";
|
|
163
170
|
import {
|
|
164
171
|
EVENT_SCHEMA_VERSION,
|
|
165
172
|
SubscriberLimitExceededError
|
|
166
173
|
} from "./chunk-6RLROE6G.js";
|
|
167
174
|
import "./chunk-COH43MRJ.js";
|
|
168
|
-
import "./chunk-OCPBI7J5.js";
|
|
169
175
|
import {
|
|
170
176
|
BranchWhilePromptActiveError,
|
|
171
177
|
CancelSentinelCollisionError,
|
|
@@ -186,6 +192,7 @@ import {
|
|
|
186
192
|
SessionBusyError,
|
|
187
193
|
SessionConflictError,
|
|
188
194
|
SessionLimitExceededError,
|
|
195
|
+
SessionNotArchivedError,
|
|
189
196
|
SessionNotFoundError,
|
|
190
197
|
SessionShellClientRequiredError,
|
|
191
198
|
SessionShellDisabledError,
|
|
@@ -196,39 +203,44 @@ import {
|
|
|
196
203
|
WorkspaceInitRaceError,
|
|
197
204
|
WorkspaceInitSymlinkError,
|
|
198
205
|
WorkspaceMismatchError
|
|
199
|
-
} from "./chunk-
|
|
206
|
+
} from "./chunk-X6YQWCIJ.js";
|
|
200
207
|
import "./chunk-WBL3FJEU.js";
|
|
201
208
|
import {
|
|
202
209
|
loadChannelsConfig
|
|
203
|
-
} from "./chunk-
|
|
204
|
-
import "./chunk-
|
|
210
|
+
} from "./chunk-UJG4VV2O.js";
|
|
211
|
+
import "./chunk-4YR7FSAM.js";
|
|
205
212
|
import "./chunk-57OAHC2Y.js";
|
|
206
213
|
import {
|
|
207
214
|
parseChannelWebhookConfigLenient
|
|
208
|
-
} from "./chunk-
|
|
209
|
-
import "./chunk-
|
|
215
|
+
} from "./chunk-5CNYZ7TN.js";
|
|
216
|
+
import "./chunk-FNX3LGAK.js";
|
|
210
217
|
import "./chunk-V6WHFGST.js";
|
|
211
|
-
import "./chunk-
|
|
212
|
-
import "./chunk-TEGEBB2I.js";
|
|
218
|
+
import "./chunk-VHCSIMTF.js";
|
|
213
219
|
import {
|
|
214
220
|
STATUS_SCHEMA_VERSION,
|
|
215
221
|
createIdleWorkspaceMemoryStatus,
|
|
216
222
|
mapDomainErrorToErrorKind
|
|
217
|
-
} from "./chunk-
|
|
223
|
+
} from "./chunk-W6J7RSCK.js";
|
|
218
224
|
import {
|
|
219
225
|
MAX_REGISTERED_WORKSPACES,
|
|
220
226
|
WorkspaceRegistrationStoreCommittedError,
|
|
221
227
|
WorkspaceRegistrationStoreLimitError,
|
|
222
228
|
workspaceRegistrationId
|
|
223
|
-
} from "./chunk-
|
|
229
|
+
} from "./chunk-4HTHLSIH.js";
|
|
224
230
|
import {
|
|
225
231
|
MAX_WORKSPACE_PATH_LENGTH,
|
|
226
232
|
canonicalizeWorkspace,
|
|
227
233
|
canonicalizeWorkspaces
|
|
228
234
|
} from "./chunk-W7FJ3N32.js";
|
|
229
235
|
import {
|
|
230
|
-
|
|
231
|
-
|
|
236
|
+
MAX_CHANNEL_STARTUP_FAILURES,
|
|
237
|
+
MAX_CHANNEL_STARTUP_FAILURE_CHANNEL_LENGTH,
|
|
238
|
+
MAX_CHANNEL_STARTUP_FAILURE_CODE_LENGTH,
|
|
239
|
+
MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH,
|
|
240
|
+
QWEN_SERVER_TOKEN_ENV,
|
|
241
|
+
isChannelWebhookEnqueueError,
|
|
242
|
+
normalizeWorkerDiagnostic
|
|
243
|
+
} from "./chunk-KSZKSE23.js";
|
|
232
244
|
import {
|
|
233
245
|
normalizeServeChannelSelection
|
|
234
246
|
} from "./chunk-TJTKSVIV.js";
|
|
@@ -236,11 +248,10 @@ import {
|
|
|
236
248
|
redactLogCredentials
|
|
237
249
|
} from "./chunk-M5GB774H.js";
|
|
238
250
|
import "./chunk-5HBA2Z7V.js";
|
|
239
|
-
import {
|
|
240
|
-
isChannelWebhookEnqueueError
|
|
241
|
-
} from "./chunk-OJAMDVF5.js";
|
|
242
251
|
import "./chunk-T2NCM2ET.js";
|
|
243
|
-
import
|
|
252
|
+
import {
|
|
253
|
+
sanitizeLogText
|
|
254
|
+
} from "./chunk-ZQIYGQCG.js";
|
|
244
255
|
import "./chunk-UDXSXLER.js";
|
|
245
256
|
import {
|
|
246
257
|
getDialogSettingKeys,
|
|
@@ -251,18 +262,18 @@ import {
|
|
|
251
262
|
getWritableScopes,
|
|
252
263
|
loadSettings,
|
|
253
264
|
validateSettingValue
|
|
254
|
-
} from "./chunk-
|
|
265
|
+
} from "./chunk-5WWYHNAH.js";
|
|
255
266
|
import "./chunk-RKUWKYED.js";
|
|
256
267
|
import {
|
|
257
268
|
SUPPORTED_LANGUAGES
|
|
258
|
-
} from "./chunk-
|
|
259
|
-
import "./chunk-
|
|
269
|
+
} from "./chunk-EMJJBXS7.js";
|
|
270
|
+
import "./chunk-JY74T7PW.js";
|
|
260
271
|
import "./chunk-GOXKNSDZ.js";
|
|
261
272
|
import "./chunk-IDS7MSUP.js";
|
|
262
273
|
import "./chunk-QRUIS3DN.js";
|
|
263
274
|
import {
|
|
264
275
|
getWorkspaceTrustStatus
|
|
265
|
-
} from "./chunk-
|
|
276
|
+
} from "./chunk-PNCWEDF6.js";
|
|
266
277
|
import "./chunk-ALGGS7UH.js";
|
|
267
278
|
import {
|
|
268
279
|
isWithinRoot as isWithinRoot2
|
|
@@ -270,7 +281,7 @@ import {
|
|
|
270
281
|
import {
|
|
271
282
|
writeStderrLine
|
|
272
283
|
} from "./chunk-YUZI3WAC.js";
|
|
273
|
-
import "./chunk-
|
|
284
|
+
import "./chunk-Y3TNSHKF.js";
|
|
274
285
|
import "./chunk-VJNBRRZG.js";
|
|
275
286
|
import {
|
|
276
287
|
ALL_PROVIDERS,
|
|
@@ -284,6 +295,7 @@ import {
|
|
|
284
295
|
InvalidSessionTranscriptCursorError,
|
|
285
296
|
ModelsConfig,
|
|
286
297
|
RUNTIME_MCP_IF_ABSENT_CONFIG_FLAG,
|
|
298
|
+
SESSION_TRANSCRIPT_MAX_INDEX_BYTES,
|
|
287
299
|
SESSION_TRANSCRIPT_MAX_LIMIT,
|
|
288
300
|
SessionOrganizationError,
|
|
289
301
|
SessionOrganizationService,
|
|
@@ -315,18 +327,18 @@ import {
|
|
|
315
327
|
stripTerminalControlSequences,
|
|
316
328
|
watchRepoBranch,
|
|
317
329
|
writeWorkspaceContextFile
|
|
318
|
-
} from "./chunk-
|
|
330
|
+
} from "./chunk-R6AO7HBQ.js";
|
|
331
|
+
import "./chunk-T4TZQJ7W.js";
|
|
319
332
|
import "./chunk-H6XPXXMH.js";
|
|
320
333
|
import "./chunk-5M6IDOMF.js";
|
|
321
334
|
import {
|
|
322
335
|
MAX_JOBS,
|
|
323
336
|
nextDurableFireMs
|
|
324
|
-
} from "./chunk-
|
|
337
|
+
} from "./chunk-A2HWMJVO.js";
|
|
325
338
|
import "./chunk-RCEEXIOO.js";
|
|
326
339
|
import "./chunk-KKRTYONM.js";
|
|
327
340
|
import "./chunk-TV6K2FB4.js";
|
|
328
341
|
import "./chunk-E2UVIFI2.js";
|
|
329
|
-
import "./chunk-6OATMEYN.js";
|
|
330
342
|
import {
|
|
331
343
|
nextFireTime,
|
|
332
344
|
parseCron
|
|
@@ -347,7 +359,7 @@ import {
|
|
|
347
359
|
APPROVAL_MODES,
|
|
348
360
|
SubagentError,
|
|
349
361
|
SubagentErrorCode
|
|
350
|
-
} from "./chunk-
|
|
362
|
+
} from "./chunk-F333XEAU.js";
|
|
351
363
|
import "./chunk-6AM5D4ME.js";
|
|
352
364
|
import "./chunk-2Z5UX4KI.js";
|
|
353
365
|
import "./chunk-ARKANCNX.js";
|
|
@@ -366,15 +378,15 @@ import {
|
|
|
366
378
|
recordDaemonHttpRequest,
|
|
367
379
|
recordDaemonHttpResponse,
|
|
368
380
|
withDaemonRequestSpan
|
|
369
|
-
} from "./chunk-
|
|
381
|
+
} from "./chunk-BTSE2DUP.js";
|
|
370
382
|
import "./chunk-4WKAA4KS.js";
|
|
371
383
|
import "./chunk-CR3C7WXL.js";
|
|
372
|
-
import "./chunk-
|
|
384
|
+
import "./chunk-RTV5TUYB.js";
|
|
373
385
|
import "./chunk-VGC4I5JJ.js";
|
|
374
386
|
import "./chunk-FBU7WRZI.js";
|
|
375
387
|
import "./chunk-Y66VOBRP.js";
|
|
376
|
-
import "./chunk-
|
|
377
|
-
import "./chunk-
|
|
388
|
+
import "./chunk-WTNZ6DXB.js";
|
|
389
|
+
import "./chunk-JGUT3LWZ.js";
|
|
378
390
|
import {
|
|
379
391
|
QwenOAuth2Client,
|
|
380
392
|
QwenOAuthPollError,
|
|
@@ -388,8 +400,8 @@ import "./chunk-ZPAHLFZU.js";
|
|
|
388
400
|
import "./chunk-JESCGQM3.js";
|
|
389
401
|
import "./chunk-WIEO4CWB.js";
|
|
390
402
|
import "./chunk-XVNQMZ2I.js";
|
|
391
|
-
import "./chunk-
|
|
392
|
-
import "./chunk-
|
|
403
|
+
import "./chunk-FEOZBUMT.js";
|
|
404
|
+
import "./chunk-VRR65QYW.js";
|
|
393
405
|
import "./chunk-A4UCTEB5.js";
|
|
394
406
|
import "./chunk-XWRJCPHC.js";
|
|
395
407
|
import "./chunk-4LD5APFL.js";
|
|
@@ -2900,7 +2912,7 @@ async function handleSetupGithub(req, res, deps) {
|
|
|
2900
2912
|
const result = await setupGithub({
|
|
2901
2913
|
cwd: deps.boundWorkspace,
|
|
2902
2914
|
workspaceRoot: deps.boundWorkspace,
|
|
2903
|
-
proxy: resolveSetupGithubProxy(deps.boundWorkspace),
|
|
2915
|
+
proxy: resolveSetupGithubProxy(deps.boundWorkspace, deps.env),
|
|
2904
2916
|
abortSignal: requestAbortSignal(req, res),
|
|
2905
2917
|
fileOps: createSetupGithubFileOps(factory, ROUTE, originatorClientId)
|
|
2906
2918
|
});
|
|
@@ -3118,14 +3130,14 @@ function setupGithubEventData(result) {
|
|
|
3118
3130
|
};
|
|
3119
3131
|
}
|
|
3120
3132
|
__name(setupGithubEventData, "setupGithubEventData");
|
|
3121
|
-
function resolveSetupGithubProxy(boundWorkspace) {
|
|
3133
|
+
function resolveSetupGithubProxy(boundWorkspace, env) {
|
|
3122
3134
|
const settings = loadSettings(boundWorkspace, { skipLoadEnvironment: true });
|
|
3123
3135
|
const trustState = getWorkspaceTrustStatus(
|
|
3124
3136
|
settingsForSetupGithubTrust(settings),
|
|
3125
3137
|
boundWorkspace
|
|
3126
3138
|
).effective.state;
|
|
3127
3139
|
const settingsProxy = trustState === "trusted" ? settings.merged.proxy : settings.user.settings.proxy || settings.system.settings.proxy || settings.systemDefaults.settings.proxy;
|
|
3128
|
-
return settingsProxy ||
|
|
3140
|
+
return settingsProxy || env["HTTPS_PROXY"] || env["https_proxy"] || env["HTTP_PROXY"] || env["http_proxy"];
|
|
3129
3141
|
}
|
|
3130
3142
|
__name(resolveSetupGithubProxy, "resolveSetupGithubProxy");
|
|
3131
3143
|
function settingsForSetupGithubTrust(settings) {
|
|
@@ -6226,6 +6238,21 @@ async function assertSessionLoadable(workspaceCwd, sessionId) {
|
|
|
6226
6238
|
return location;
|
|
6227
6239
|
}
|
|
6228
6240
|
__name(assertSessionLoadable, "assertSessionLoadable");
|
|
6241
|
+
async function assertSessionArchived(workspaceCwd, sessionId) {
|
|
6242
|
+
const location = await new SessionService(workspaceCwd).getSessionLocation(
|
|
6243
|
+
sessionId
|
|
6244
|
+
);
|
|
6245
|
+
if (location === "active") {
|
|
6246
|
+
throw new SessionNotArchivedError(sessionId);
|
|
6247
|
+
}
|
|
6248
|
+
if (location === "conflict") {
|
|
6249
|
+
throw new SessionConflictError(sessionId);
|
|
6250
|
+
}
|
|
6251
|
+
if (location === void 0) {
|
|
6252
|
+
throw new SessionNotFoundError(sessionId);
|
|
6253
|
+
}
|
|
6254
|
+
}
|
|
6255
|
+
__name(assertSessionArchived, "assertSessionArchived");
|
|
6229
6256
|
function isSessionNotFoundError(err) {
|
|
6230
6257
|
return err instanceof SessionNotFoundError || err instanceof Error && err.name === "SessionNotFoundError";
|
|
6231
6258
|
}
|
|
@@ -6928,9 +6955,10 @@ function rpcErrorFrame(id, err) {
|
|
|
6928
6955
|
__name(rpcErrorFrame, "rpcErrorFrame");
|
|
6929
6956
|
var ACP_PROTOCOL_VERSION = 1;
|
|
6930
6957
|
var AcpDispatcher = class {
|
|
6931
|
-
constructor(bridge, boundWorkspace, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator()) {
|
|
6958
|
+
constructor(bridge, boundWorkspace, env, workspace, workspaceRememberLane, fsFactory, deviceFlowRegistry, sessionShellCommandEnabled = false, registry, archiveCoordinator = new SessionArchiveCoordinator()) {
|
|
6932
6959
|
this.bridge = bridge;
|
|
6933
6960
|
this.boundWorkspace = boundWorkspace;
|
|
6961
|
+
this.env = env;
|
|
6934
6962
|
this.workspace = workspace;
|
|
6935
6963
|
this.workspaceRememberLane = workspaceRememberLane;
|
|
6936
6964
|
this.fsFactory = fsFactory;
|
|
@@ -6944,8 +6972,14 @@ var AcpDispatcher = class {
|
|
|
6944
6972
|
__name(this, "AcpDispatcher");
|
|
6945
6973
|
}
|
|
6946
6974
|
agentManager;
|
|
6947
|
-
killOrphanSession(sessionId) {
|
|
6948
|
-
void this.bridge.killSession(sessionId, { requireZeroAttaches: true }).
|
|
6975
|
+
killOrphanSession(sessionId, removePersistedSession = false) {
|
|
6976
|
+
void this.bridge.killSession(sessionId, { requireZeroAttaches: true }).then(async (killed) => {
|
|
6977
|
+
if (killed && removePersistedSession) {
|
|
6978
|
+
await new SessionService(this.boundWorkspace).removeSession(
|
|
6979
|
+
sessionId
|
|
6980
|
+
);
|
|
6981
|
+
}
|
|
6982
|
+
}).catch(
|
|
6949
6983
|
(err) => writeStderrLine(
|
|
6950
6984
|
`qwen serve: /acp orphan killSession(${logSafe(sessionId)}) failed: ${logSafe(errMsg(err))}`
|
|
6951
6985
|
)
|
|
@@ -7229,26 +7263,40 @@ var AcpDispatcher = class {
|
|
|
7229
7263
|
return;
|
|
7230
7264
|
case "session/new": {
|
|
7231
7265
|
const cwd = parseOptionalWorkspaceCwd2(params, this.boundWorkspace);
|
|
7266
|
+
const source = parseSessionSource(
|
|
7267
|
+
params["sourceType"],
|
|
7268
|
+
params["sourceId"]
|
|
7269
|
+
);
|
|
7270
|
+
if ("error" in source) {
|
|
7271
|
+
if (id !== void 0) {
|
|
7272
|
+
conn.sendConn(error(id, RPC.INVALID_PARAMS, source.error));
|
|
7273
|
+
}
|
|
7274
|
+
return;
|
|
7275
|
+
}
|
|
7232
7276
|
const session = await this.bridge.spawnOrAttach({
|
|
7233
7277
|
workspaceCwd: cwd,
|
|
7234
7278
|
clientId: conn.clientId,
|
|
7235
|
-
sessionScope: "thread"
|
|
7279
|
+
sessionScope: "thread",
|
|
7280
|
+
...source
|
|
7236
7281
|
});
|
|
7237
7282
|
if (conn.destroyed) {
|
|
7238
|
-
this.killOrphanSession(session.sessionId);
|
|
7283
|
+
this.killOrphanSession(session.sessionId, true);
|
|
7239
7284
|
return;
|
|
7240
7285
|
}
|
|
7241
7286
|
conn.getOrCreateSession(session.sessionId).clientId = session.clientId;
|
|
7242
7287
|
conn.ownSession(session.sessionId);
|
|
7243
7288
|
const configOptions = await this.configOptionsFor(session.sessionId);
|
|
7244
7289
|
if (conn.destroyed) {
|
|
7245
|
-
this.killOrphanSession(session.sessionId);
|
|
7290
|
+
this.killOrphanSession(session.sessionId, true);
|
|
7246
7291
|
return;
|
|
7247
7292
|
}
|
|
7248
7293
|
const models = this.extractModelState(configOptions);
|
|
7249
7294
|
const modes = this.extractModeState(configOptions);
|
|
7250
7295
|
this.replyConn(conn, id, {
|
|
7251
7296
|
sessionId: session.sessionId,
|
|
7297
|
+
...session.sourceType ? { sourceType: session.sourceType } : {},
|
|
7298
|
+
...session.sourceId !== void 0 ? { sourceId: session.sourceId } : {},
|
|
7299
|
+
...session.sourcePersisted !== void 0 ? { sourcePersisted: session.sourcePersisted } : {},
|
|
7252
7300
|
...configOptions ? { configOptions } : {},
|
|
7253
7301
|
...models ? { models } : {},
|
|
7254
7302
|
...modes ? { modes } : {}
|
|
@@ -7283,20 +7331,20 @@ var AcpDispatcher = class {
|
|
|
7283
7331
|
[sessionId],
|
|
7284
7332
|
async () => {
|
|
7285
7333
|
await assertSessionLoadable(cwd, sessionId);
|
|
7286
|
-
const
|
|
7334
|
+
const metadata = await new SessionService(
|
|
7287
7335
|
cwd
|
|
7288
|
-
).
|
|
7336
|
+
).readCreationMetadata(sessionId);
|
|
7289
7337
|
return method === "session/load" ? await this.bridge.loadSession({
|
|
7290
7338
|
sessionId,
|
|
7291
7339
|
workspaceCwd: cwd,
|
|
7292
7340
|
clientId: conn.clientId,
|
|
7293
7341
|
historyReplay: "response",
|
|
7294
|
-
...
|
|
7342
|
+
...metadata
|
|
7295
7343
|
}) : await this.bridge.resumeSession({
|
|
7296
7344
|
sessionId,
|
|
7297
7345
|
workspaceCwd: cwd,
|
|
7298
7346
|
clientId: conn.clientId,
|
|
7299
|
-
...
|
|
7347
|
+
...metadata
|
|
7300
7348
|
});
|
|
7301
7349
|
}
|
|
7302
7350
|
);
|
|
@@ -7395,6 +7443,13 @@ var AcpDispatcher = class {
|
|
|
7395
7443
|
);
|
|
7396
7444
|
}
|
|
7397
7445
|
}
|
|
7446
|
+
const parsedSource = parseSessionSource(
|
|
7447
|
+
params["sourceType"],
|
|
7448
|
+
params["sourceId"]
|
|
7449
|
+
);
|
|
7450
|
+
if ("error" in parsedSource) {
|
|
7451
|
+
throw new AcpParamError(parsedSource.error);
|
|
7452
|
+
}
|
|
7398
7453
|
const result = await listWorkspaceSessionsForResponse(
|
|
7399
7454
|
this.bridge,
|
|
7400
7455
|
workspaceCwd,
|
|
@@ -7404,7 +7459,8 @@ var AcpDispatcher = class {
|
|
|
7404
7459
|
archiveState,
|
|
7405
7460
|
view,
|
|
7406
7461
|
group,
|
|
7407
|
-
parentSessionId
|
|
7462
|
+
parentSessionId,
|
|
7463
|
+
...parsedSource
|
|
7408
7464
|
}
|
|
7409
7465
|
);
|
|
7410
7466
|
this.replyConn(conn, id, {
|
|
@@ -7417,6 +7473,8 @@ var AcpDispatcher = class {
|
|
|
7417
7473
|
displayName: s.displayName,
|
|
7418
7474
|
title: s.displayName,
|
|
7419
7475
|
...s.parentSessionId !== void 0 ? { parentSessionId: s.parentSessionId } : {},
|
|
7476
|
+
...s.sourceType !== void 0 ? { sourceType: s.sourceType } : {},
|
|
7477
|
+
...s.sourceId !== void 0 ? { sourceId: s.sourceId } : {},
|
|
7420
7478
|
clientCount: s.clientCount,
|
|
7421
7479
|
hasActivePrompt: s.hasActivePrompt,
|
|
7422
7480
|
isArchived: s.isArchived === true,
|
|
@@ -8277,7 +8335,7 @@ var AcpDispatcher = class {
|
|
|
8277
8335
|
const result = await setupGithub({
|
|
8278
8336
|
cwd: this.boundWorkspace,
|
|
8279
8337
|
workspaceRoot: this.boundWorkspace,
|
|
8280
|
-
proxy: resolveSetupGithubProxy(this.boundWorkspace),
|
|
8338
|
+
proxy: resolveSetupGithubProxy(this.boundWorkspace, this.env),
|
|
8281
8339
|
abortSignal: conn.abortSignal,
|
|
8282
8340
|
fileOps: createSetupGithubFileOps(
|
|
8283
8341
|
this.fsFactory,
|
|
@@ -11748,11 +11806,11 @@ function delay(ms) {
|
|
|
11748
11806
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
11749
11807
|
}
|
|
11750
11808
|
__name(delay, "delay");
|
|
11751
|
-
function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname) {
|
|
11809
|
+
function buildChromeDevToolsMcpRuntimeConfig(localPort, hostname, env) {
|
|
11752
11810
|
if (localPort === void 0 || !Number.isInteger(localPort) || localPort <= 0) {
|
|
11753
11811
|
return void 0;
|
|
11754
11812
|
}
|
|
11755
|
-
const command = resolveCdpMcpCommand(
|
|
11813
|
+
const command = resolveCdpMcpCommand(env);
|
|
11756
11814
|
if (!command) {
|
|
11757
11815
|
writeStderrLine(
|
|
11758
11816
|
`qwen serve: set ${QWEN_CDP_MCP_COMMAND_ENV} to enable browser automation MCP (no adapter is bundled)`
|
|
@@ -11858,9 +11916,18 @@ function workspaceRateLimitKey(mount, clientKey) {
|
|
|
11858
11916
|
return JSON.stringify([clientKey, mount.rateLimitScope]);
|
|
11859
11917
|
}
|
|
11860
11918
|
__name(workspaceRateLimitKey, "workspaceRateLimitKey");
|
|
11919
|
+
function runtimeEffectiveEnv(runtime, daemonEnv) {
|
|
11920
|
+
if (runtime.env.mode === "runtime-overlay") {
|
|
11921
|
+
return runtime.env.effectiveEnv ?? {};
|
|
11922
|
+
}
|
|
11923
|
+
return runtime.env.effectiveEnv ?? daemonEnv;
|
|
11924
|
+
}
|
|
11925
|
+
__name(runtimeEffectiveEnv, "runtimeEffectiveEnv");
|
|
11861
11926
|
function mountAcpHttp(app, bridge, opts) {
|
|
11862
11927
|
const enabled = opts.enabled ?? resolveAcpHttpEnabled();
|
|
11863
11928
|
if (!enabled) return void 0;
|
|
11929
|
+
const daemonEnv = opts.daemonEnv ?? process.env;
|
|
11930
|
+
const primaryEnv = opts.workspaceRegistry ? runtimeEffectiveEnv(opts.workspaceRegistry.primary, daemonEnv) : daemonEnv;
|
|
11864
11931
|
const path15 = opts.path ?? "/acp";
|
|
11865
11932
|
const dispatcherRef = {};
|
|
11866
11933
|
let disposed = false;
|
|
@@ -11950,7 +12017,8 @@ function mountAcpHttp(app, bridge, opts) {
|
|
|
11950
12017
|
}
|
|
11951
12018
|
const runtimeConfig = buildChromeDevToolsMcpRuntimeConfig(
|
|
11952
12019
|
localPort,
|
|
11953
|
-
opts.hostname
|
|
12020
|
+
opts.hostname,
|
|
12021
|
+
daemonEnv
|
|
11954
12022
|
);
|
|
11955
12023
|
if (!runtimeConfig) {
|
|
11956
12024
|
cdpMcpTerminalSkipLogged = true;
|
|
@@ -12009,6 +12077,7 @@ function mountAcpHttp(app, bridge, opts) {
|
|
|
12009
12077
|
const dispatcher = new AcpDispatcher(
|
|
12010
12078
|
bridge,
|
|
12011
12079
|
opts.boundWorkspace,
|
|
12080
|
+
primaryEnv,
|
|
12012
12081
|
opts.workspace,
|
|
12013
12082
|
opts.workspaceRememberLane,
|
|
12014
12083
|
opts.fsFactory,
|
|
@@ -12297,6 +12366,7 @@ function mountAcpHttp(app, bridge, opts) {
|
|
|
12297
12366
|
const secondaryDispatcher = new AcpDispatcher(
|
|
12298
12367
|
rt.bridge,
|
|
12299
12368
|
rt.workspaceCwd,
|
|
12369
|
+
runtimeEffectiveEnv(rt, daemonEnv),
|
|
12300
12370
|
rt.workspaceService,
|
|
12301
12371
|
workspaceRememberLane,
|
|
12302
12372
|
rt.routeFileSystemFactory,
|
|
@@ -14402,7 +14472,13 @@ __name(getDemoHtml, "getDemoHtml");
|
|
|
14402
14472
|
|
|
14403
14473
|
// packages/cli/src/serve/routes/health-demo.ts
|
|
14404
14474
|
function createHealthDemoRoutes(deps) {
|
|
14405
|
-
const {
|
|
14475
|
+
const {
|
|
14476
|
+
opts,
|
|
14477
|
+
getPort,
|
|
14478
|
+
workspaceRegistry,
|
|
14479
|
+
getActiveSseCount: getActiveSseCount2,
|
|
14480
|
+
getRateLimiter
|
|
14481
|
+
} = deps;
|
|
14406
14482
|
const demoHandler = /* @__PURE__ */ __name((_req, res) => {
|
|
14407
14483
|
try {
|
|
14408
14484
|
res.type("html").set("X-Frame-Options", "DENY").set(
|
|
@@ -14417,32 +14493,55 @@ function createHealthDemoRoutes(deps) {
|
|
|
14417
14493
|
}
|
|
14418
14494
|
}, "demoHandler");
|
|
14419
14495
|
const healthHandler = /* @__PURE__ */ __name((req, res) => {
|
|
14420
|
-
|
|
14421
|
-
const deep = deepQuery === "1" || deepQuery === "true" || deepQuery === "";
|
|
14422
|
-
if (!deep) {
|
|
14496
|
+
if (!isDeepHealthQuery(req.query["deep"])) {
|
|
14423
14497
|
res.status(200).json({ status: "ok" });
|
|
14424
14498
|
return;
|
|
14425
14499
|
}
|
|
14500
|
+
let failedWorkspaceId;
|
|
14426
14501
|
try {
|
|
14427
|
-
const
|
|
14502
|
+
const runtimes = workspaceRegistry.listManaged();
|
|
14503
|
+
let sessions = 0;
|
|
14504
|
+
let pendingPermissions = 0;
|
|
14505
|
+
let activePrompts = 0;
|
|
14506
|
+
let channelAlive = false;
|
|
14507
|
+
let lastActivity = null;
|
|
14508
|
+
for (const runtime of runtimes) {
|
|
14509
|
+
failedWorkspaceId = runtime.workspaceId;
|
|
14510
|
+
const bridge = runtime.bridge;
|
|
14511
|
+
const runtimeSessions = bridge.sessionCount;
|
|
14512
|
+
const runtimePendingPermissions = bridge.pendingPermissionCount;
|
|
14513
|
+
const runtimeActivePrompts = bridge.activePromptCount;
|
|
14514
|
+
const runtimeChannelAlive = bridge.isChannelLive();
|
|
14515
|
+
const runtimeLastActivity = bridge.lastActivityAt;
|
|
14516
|
+
sessions += runtimeSessions;
|
|
14517
|
+
pendingPermissions += runtimePendingPermissions;
|
|
14518
|
+
activePrompts += runtimeActivePrompts;
|
|
14519
|
+
channelAlive = channelAlive || runtimeChannelAlive;
|
|
14520
|
+
if (runtimeLastActivity !== null && (lastActivity === null || runtimeLastActivity > lastActivity)) {
|
|
14521
|
+
lastActivity = runtimeLastActivity;
|
|
14522
|
+
}
|
|
14523
|
+
failedWorkspaceId = void 0;
|
|
14524
|
+
}
|
|
14428
14525
|
const now = Date.now();
|
|
14429
14526
|
const rateLimiter = getRateLimiter();
|
|
14430
14527
|
res.status(200).json({
|
|
14431
14528
|
status: "ok",
|
|
14432
|
-
|
|
14433
|
-
|
|
14434
|
-
|
|
14529
|
+
workspaceCount: runtimes.length,
|
|
14530
|
+
sessions,
|
|
14531
|
+
pendingPermissions,
|
|
14532
|
+
activePrompts,
|
|
14435
14533
|
connectedClients: getActiveSseCount2(),
|
|
14436
|
-
channelAlive
|
|
14534
|
+
channelAlive,
|
|
14437
14535
|
lastActivityAt: lastActivity !== null ? new Date(lastActivity).toISOString() : null,
|
|
14438
14536
|
idleSinceMs: lastActivity !== null ? now - lastActivity : null,
|
|
14439
14537
|
...rateLimiter ? { rateLimitHits: rateLimiter.getHitCounts() } : {}
|
|
14440
14538
|
});
|
|
14441
14539
|
} catch (err) {
|
|
14540
|
+
const workspaceContext = failedWorkspaceId !== void 0 ? ` for workspace ${JSON.stringify(failedWorkspaceId)}` : "";
|
|
14442
14541
|
writeStderrLine(
|
|
14443
|
-
`qwen serve: /health deep probe failed: ${err instanceof Error ? err.message : String(err)}`
|
|
14542
|
+
`qwen serve: /health deep probe failed${workspaceContext}: ${err instanceof Error ? err.message : String(err)}`
|
|
14444
14543
|
);
|
|
14445
|
-
res.status(503).json({ status: "degraded" });
|
|
14544
|
+
res.status(503).json({ status: "degraded", reason: "aggregation_failed" });
|
|
14446
14545
|
}
|
|
14447
14546
|
}, "healthHandler");
|
|
14448
14547
|
const loopback = isLoopbackBind(opts.hostname);
|
|
@@ -14950,6 +15049,7 @@ __name(registerWorkspaceAuthRoutes, "registerWorkspaceAuthRoutes");
|
|
|
14950
15049
|
|
|
14951
15050
|
// packages/cli/src/serve/routes/workspace-extensions.ts
|
|
14952
15051
|
init_esbuild_shims();
|
|
15052
|
+
import * as crypto2 from "node:crypto";
|
|
14953
15053
|
|
|
14954
15054
|
// packages/cli/src/serve/extension-operation-scheduler.ts
|
|
14955
15055
|
init_esbuild_shims();
|
|
@@ -15029,6 +15129,18 @@ init_esbuild_shims();
|
|
|
15029
15129
|
import * as crypto from "node:crypto";
|
|
15030
15130
|
var MAX_UNFINISHED_EXTENSION_OPERATIONS = 10;
|
|
15031
15131
|
var sanitizeDaemonMessage = /* @__PURE__ */ __name((message) => redactUrlCredentials(stripAnsiAndControl(message)), "sanitizeDaemonMessage");
|
|
15132
|
+
var redactExtensionDisplaySource = /* @__PURE__ */ __name((source) => {
|
|
15133
|
+
const redacted = redactUrlCredentials(source);
|
|
15134
|
+
if (/^[A-Za-z]:[\\/]/.test(redacted)) return redacted;
|
|
15135
|
+
try {
|
|
15136
|
+
const url = new URL(redacted);
|
|
15137
|
+
url.search = "";
|
|
15138
|
+
url.hash = "";
|
|
15139
|
+
return url.toString();
|
|
15140
|
+
} catch {
|
|
15141
|
+
return redacted;
|
|
15142
|
+
}
|
|
15143
|
+
}, "redactExtensionDisplaySource");
|
|
15032
15144
|
var EXTENSION_PREPARATION_CONCURRENCY = 2;
|
|
15033
15145
|
var EXTENSION_REFRESH_TIMEOUT_MS = 3e4;
|
|
15034
15146
|
var RECONCILE_SLOW_MS = 3e4;
|
|
@@ -15057,21 +15169,21 @@ function createExtensionsController(deps) {
|
|
|
15057
15169
|
unfinishedOperationCount -= 1;
|
|
15058
15170
|
};
|
|
15059
15171
|
}, "acquireOperationSlot");
|
|
15060
|
-
const createExtensionManager = /* @__PURE__ */ __name((workspaceDir = boundWorkspace, trustedOverride) => new ExtensionManager({
|
|
15172
|
+
const createExtensionManager = /* @__PURE__ */ __name((workspaceDir = boundWorkspace, trustedOverride, interactions) => new ExtensionManager({
|
|
15061
15173
|
workspaceDir,
|
|
15062
15174
|
isWorkspaceTrusted: trustedOverride ?? getWorkspaceTrustStatus(loadSettings(workspaceDir).merged, workspaceDir).effective.state === "trusted",
|
|
15063
15175
|
requestConsent: /* @__PURE__ */ __name(() => Promise.resolve(), "requestConsent"),
|
|
15064
15176
|
networkPolicy: "public",
|
|
15065
|
-
requestSetting:
|
|
15177
|
+
requestSetting: interactions?.requestSetting ?? (async (setting) => {
|
|
15066
15178
|
throw new Error(
|
|
15067
15179
|
`Extension setting "${setting.envVar}" requires interactive configuration and is not supported over the daemon install endpoint.`
|
|
15068
15180
|
);
|
|
15069
|
-
}
|
|
15070
|
-
requestChoicePlugin:
|
|
15181
|
+
}),
|
|
15182
|
+
requestChoicePlugin: interactions?.requestChoicePlugin ?? (async () => {
|
|
15071
15183
|
throw new Error(
|
|
15072
15184
|
"Marketplace plugin selection is not supported over the daemon install endpoint. Specify a plugin name in the source."
|
|
15073
15185
|
);
|
|
15074
|
-
}
|
|
15186
|
+
})
|
|
15075
15187
|
}), "createExtensionManager");
|
|
15076
15188
|
const validateExtensionMutationClient = /* @__PURE__ */ __name((req, res, opts = {}) => {
|
|
15077
15189
|
const clientId = parseAndValidateWorkspaceClientId(
|
|
@@ -15090,10 +15202,10 @@ function createExtensionsController(deps) {
|
|
|
15090
15202
|
return true;
|
|
15091
15203
|
}, "validateExtensionMutationClient");
|
|
15092
15204
|
const extensionOperations = /* @__PURE__ */ new Map();
|
|
15093
|
-
const isTerminalExtensionOperation = /* @__PURE__ */ __name((operation) => operation.status !== "queued" && operation.status !== "running", "isTerminalExtensionOperation");
|
|
15205
|
+
const isTerminalExtensionOperation = /* @__PURE__ */ __name((operation) => operation.status !== "queued" && operation.status !== "running" && operation.status !== "waiting_for_input", "isTerminalExtensionOperation");
|
|
15094
15206
|
const redactExtensionOperationResult = /* @__PURE__ */ __name((event) => ({
|
|
15095
15207
|
...event,
|
|
15096
|
-
...event.source ? { source:
|
|
15208
|
+
...event.source ? { source: redactExtensionDisplaySource(event.source) } : {}
|
|
15097
15209
|
}), "redactExtensionOperationResult");
|
|
15098
15210
|
const bridgeMutationEvent = /* @__PURE__ */ __name((event) => {
|
|
15099
15211
|
const redacted = redactExtensionOperationResult(event);
|
|
@@ -15174,7 +15286,7 @@ function createExtensionsController(deps) {
|
|
|
15174
15286
|
status: "queued",
|
|
15175
15287
|
createdAt: now,
|
|
15176
15288
|
updatedAt: now,
|
|
15177
|
-
...failureContext.source ? { source:
|
|
15289
|
+
...failureContext.source ? { source: redactExtensionDisplaySource(failureContext.source) } : {},
|
|
15178
15290
|
...failureContext.name ? { name: failureContext.name } : {}
|
|
15179
15291
|
});
|
|
15180
15292
|
const operationBasePath = options.operationBasePath ?? "/workspace/extensions/operations";
|
|
@@ -15201,7 +15313,7 @@ function createExtensionsController(deps) {
|
|
|
15201
15313
|
status: "running",
|
|
15202
15314
|
phase: "preparing"
|
|
15203
15315
|
});
|
|
15204
|
-
const extensionManager = options.manager ?? createExtensionManager();
|
|
15316
|
+
const extensionManager = options.manager ?? options.createManager?.(operationId) ?? createExtensionManager();
|
|
15205
15317
|
const deadlineController = new AbortController();
|
|
15206
15318
|
let deadlineStarted = false;
|
|
15207
15319
|
const startDeadline = /* @__PURE__ */ __name(() => {
|
|
@@ -15302,7 +15414,8 @@ function createExtensionsController(deps) {
|
|
|
15302
15414
|
const event = await run(
|
|
15303
15415
|
extensionManager,
|
|
15304
15416
|
deadlineController.signal,
|
|
15305
|
-
context
|
|
15417
|
+
context,
|
|
15418
|
+
operationId
|
|
15306
15419
|
);
|
|
15307
15420
|
mutationEvent = event;
|
|
15308
15421
|
if (deadline) clearTimeout(deadline);
|
|
@@ -15527,7 +15640,9 @@ function createExtensionsController(deps) {
|
|
|
15527
15640
|
bridge.broadcastExtensionsChanged({
|
|
15528
15641
|
...mutationEvent ? bridgeMutationEvent(mutationEvent) : {
|
|
15529
15642
|
...failureContext.source ? {
|
|
15530
|
-
source:
|
|
15643
|
+
source: redactExtensionDisplaySource(
|
|
15644
|
+
failureContext.source
|
|
15645
|
+
)
|
|
15531
15646
|
} : {},
|
|
15532
15647
|
...failureContext.name ? { name: failureContext.name } : {}
|
|
15533
15648
|
},
|
|
@@ -15548,13 +15663,14 @@ function createExtensionsController(deps) {
|
|
|
15548
15663
|
updateExtensionOperation(operationId, {
|
|
15549
15664
|
status: "failed",
|
|
15550
15665
|
phase: void 0,
|
|
15666
|
+
interaction: void 0,
|
|
15551
15667
|
error: message.slice(0, 500),
|
|
15552
15668
|
...code ? { code } : {}
|
|
15553
15669
|
});
|
|
15554
15670
|
try {
|
|
15555
15671
|
bridge.broadcastExtensionsChanged({
|
|
15556
15672
|
status: "failed",
|
|
15557
|
-
...failureContext.source ? { source:
|
|
15673
|
+
...failureContext.source ? { source: redactExtensionDisplaySource(failureContext.source) } : {},
|
|
15558
15674
|
...failureContext.name ? { name: failureContext.name } : {},
|
|
15559
15675
|
refreshed: 0,
|
|
15560
15676
|
failed: 0,
|
|
@@ -15576,6 +15692,7 @@ function createExtensionsController(deps) {
|
|
|
15576
15692
|
} finally {
|
|
15577
15693
|
if (deadline) clearTimeout(deadline);
|
|
15578
15694
|
reconciliationReservation?.release();
|
|
15695
|
+
options.onSettled?.(operationId);
|
|
15579
15696
|
releaseOperationSlot();
|
|
15580
15697
|
}
|
|
15581
15698
|
})();
|
|
@@ -15610,7 +15727,11 @@ function createExtensionsController(deps) {
|
|
|
15610
15727
|
version: ext.version,
|
|
15611
15728
|
isActive: ext.isActive,
|
|
15612
15729
|
path: ext.path,
|
|
15613
|
-
...ext.installMetadata?.source ? {
|
|
15730
|
+
...ext.installMetadata?.source ? {
|
|
15731
|
+
source: redactExtensionDisplaySource(
|
|
15732
|
+
ext.installMetadata.source
|
|
15733
|
+
)
|
|
15734
|
+
} : {},
|
|
15614
15735
|
...ext.installMetadata?.type ? { installType: ext.installMetadata.type } : {},
|
|
15615
15736
|
...ext.installMetadata?.originSource ? { originSource: ext.installMetadata.originSource } : {},
|
|
15616
15737
|
...ext.installMetadata?.ref ? { ref: ext.installMetadata.ref } : {},
|
|
@@ -15646,6 +15767,10 @@ function createExtensionsController(deps) {
|
|
|
15646
15767
|
buildLocalExtensionsStatus,
|
|
15647
15768
|
refreshExtensionsForAllSessions,
|
|
15648
15769
|
getOperation: /* @__PURE__ */ __name((operationId) => extensionOperations.get(operationId), "getOperation"),
|
|
15770
|
+
getActiveOperations: /* @__PURE__ */ __name(() => [...extensionOperations.values()].filter(
|
|
15771
|
+
(operation) => !isTerminalExtensionOperation(operation)
|
|
15772
|
+
), "getActiveOperations"),
|
|
15773
|
+
updateOperation: updateExtensionOperation,
|
|
15649
15774
|
preparationQueue,
|
|
15650
15775
|
acquireOperationSlot,
|
|
15651
15776
|
validateExtensionMutationClient,
|
|
@@ -15656,6 +15781,8 @@ __name(createExtensionsController, "createExtensionsController");
|
|
|
15656
15781
|
|
|
15657
15782
|
// packages/cli/src/serve/routes/workspace-extensions.ts
|
|
15658
15783
|
var EXTENSION_PREPARE_DEADLINE_MS = 10 * 6e4;
|
|
15784
|
+
var EXTENSION_INTERACTION_DEADLINE_MS = 10 * 6e4;
|
|
15785
|
+
var EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS = EXTENSION_PREPARE_DEADLINE_MS + EXTENSION_INTERACTION_DEADLINE_MS;
|
|
15659
15786
|
var EXTENSION_UPDATE_CHECK_DEADLINE_MS = 2 * 6e4;
|
|
15660
15787
|
var parseExtensionScope = /* @__PURE__ */ __name((body, res) => {
|
|
15661
15788
|
const scope = body["scope"];
|
|
@@ -15761,6 +15888,96 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
15761
15888
|
const primaryController = createExtensionsController(
|
|
15762
15889
|
controllerDeps(boundWorkspace, bridge, workspace)
|
|
15763
15890
|
);
|
|
15891
|
+
const pendingExtensionInteractions = /* @__PURE__ */ new Map();
|
|
15892
|
+
const supersededInstallOperations = /* @__PURE__ */ new Set();
|
|
15893
|
+
const cancelPendingExtensionInteraction = /* @__PURE__ */ __name((operationId, reason) => {
|
|
15894
|
+
const pending = pendingExtensionInteractions.get(operationId);
|
|
15895
|
+
if (!pending) return;
|
|
15896
|
+
clearTimeout(pending.timeout);
|
|
15897
|
+
pendingExtensionInteractions.delete(operationId);
|
|
15898
|
+
pending.reject(new Error(reason));
|
|
15899
|
+
}, "cancelPendingExtensionInteraction");
|
|
15900
|
+
const supersedeActiveInstallOperations = /* @__PURE__ */ __name((controller, currentOperationId) => {
|
|
15901
|
+
for (const operation of controller.getActiveOperations()) {
|
|
15902
|
+
if (operation.operation !== "install" || operation.operationId === currentOperationId) {
|
|
15903
|
+
continue;
|
|
15904
|
+
}
|
|
15905
|
+
supersededInstallOperations.add(operation.operationId);
|
|
15906
|
+
cancelPendingExtensionInteraction(
|
|
15907
|
+
operation.operationId,
|
|
15908
|
+
"Extension installation cancelled by a new install request"
|
|
15909
|
+
);
|
|
15910
|
+
}
|
|
15911
|
+
}, "supersedeActiveInstallOperations");
|
|
15912
|
+
const waitForExtensionInteraction = /* @__PURE__ */ __name((controller, operationId, interaction) => {
|
|
15913
|
+
if (supersededInstallOperations.delete(operationId)) {
|
|
15914
|
+
return Promise.reject(
|
|
15915
|
+
new Error("Extension installation superseded by a new install request")
|
|
15916
|
+
);
|
|
15917
|
+
}
|
|
15918
|
+
const operation = controller.getOperation(operationId);
|
|
15919
|
+
if (operation && operation.status !== "queued" && operation.status !== "running" && operation.status !== "waiting_for_input") {
|
|
15920
|
+
return Promise.reject(new Error("Extension operation already completed"));
|
|
15921
|
+
}
|
|
15922
|
+
const pendingInteraction = {
|
|
15923
|
+
...interaction,
|
|
15924
|
+
id: crypto2.randomUUID()
|
|
15925
|
+
};
|
|
15926
|
+
return new Promise((resolve5, reject) => {
|
|
15927
|
+
const timeout = setTimeout(() => {
|
|
15928
|
+
pendingExtensionInteractions.delete(operationId);
|
|
15929
|
+
controller.updateOperation(operationId, {
|
|
15930
|
+
status: "failed",
|
|
15931
|
+
phase: void 0,
|
|
15932
|
+
interaction: void 0,
|
|
15933
|
+
error: "Extension interaction timed out"
|
|
15934
|
+
});
|
|
15935
|
+
reject(new Error("Extension interaction timed out"));
|
|
15936
|
+
}, EXTENSION_INTERACTION_DEADLINE_MS);
|
|
15937
|
+
timeout.unref?.();
|
|
15938
|
+
pendingExtensionInteractions.set(operationId, {
|
|
15939
|
+
interaction: pendingInteraction,
|
|
15940
|
+
resolve: resolve5,
|
|
15941
|
+
reject,
|
|
15942
|
+
timeout
|
|
15943
|
+
});
|
|
15944
|
+
controller.updateOperation(operationId, {
|
|
15945
|
+
status: "waiting_for_input",
|
|
15946
|
+
phase: void 0,
|
|
15947
|
+
interaction: pendingInteraction
|
|
15948
|
+
});
|
|
15949
|
+
});
|
|
15950
|
+
}, "waitForExtensionInteraction");
|
|
15951
|
+
const extensionInteractionHandlers = /* @__PURE__ */ __name((controller, operationId) => ({
|
|
15952
|
+
requestSetting: /* @__PURE__ */ __name((setting) => waitForExtensionInteraction(controller, operationId, {
|
|
15953
|
+
kind: "setting",
|
|
15954
|
+
setting: {
|
|
15955
|
+
name: setting.name,
|
|
15956
|
+
description: setting.description,
|
|
15957
|
+
sensitive: setting.sensitive === true
|
|
15958
|
+
}
|
|
15959
|
+
}), "requestSetting"),
|
|
15960
|
+
requestChoicePlugin: /* @__PURE__ */ __name((marketplace) => {
|
|
15961
|
+
if (marketplace.plugins.length === 0) {
|
|
15962
|
+
return Promise.reject(
|
|
15963
|
+
new Error(`Marketplace "${marketplace.name}" has no plugins`)
|
|
15964
|
+
);
|
|
15965
|
+
}
|
|
15966
|
+
return waitForExtensionInteraction(controller, operationId, {
|
|
15967
|
+
kind: "marketplace_plugin",
|
|
15968
|
+
marketplace: { name: marketplace.name },
|
|
15969
|
+
plugins: marketplace.plugins.map((plugin) => ({
|
|
15970
|
+
name: plugin.name,
|
|
15971
|
+
...plugin.description ? { description: plugin.description } : {},
|
|
15972
|
+
source: redactExtensionDisplaySource(
|
|
15973
|
+
typeof plugin.source === "string" ? plugin.source : plugin.source.source === "github" ? plugin.source.repo : plugin.source.url
|
|
15974
|
+
),
|
|
15975
|
+
...plugin.category ? { category: plugin.category } : {},
|
|
15976
|
+
...plugin.tags ? { tags: plugin.tags } : {}
|
|
15977
|
+
}))
|
|
15978
|
+
});
|
|
15979
|
+
}, "requestChoicePlugin")
|
|
15980
|
+
}), "extensionInteractionHandlers");
|
|
15764
15981
|
const runtimeReconciliationQueue = createFifoTaskQueue(1);
|
|
15765
15982
|
const reserveRuntimeReconciliation = /* @__PURE__ */ __name(() => {
|
|
15766
15983
|
let provideTask;
|
|
@@ -15877,6 +16094,11 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
15877
16094
|
sendBridgeError2(res, err, { route: `GET ${base}` });
|
|
15878
16095
|
}
|
|
15879
16096
|
});
|
|
16097
|
+
app.get(`${base}/operations`, async (req, res) => {
|
|
16098
|
+
const ctrl = resolve5(req, res, false);
|
|
16099
|
+
if (!ctrl) return;
|
|
16100
|
+
res.status(200).json({ v: 1, operations: ctrl.getActiveOperations() });
|
|
16101
|
+
});
|
|
15880
16102
|
app.get(`${base}/operations/:operationId`, async (req, res) => {
|
|
15881
16103
|
const ctrl = resolve5(req, res, false);
|
|
15882
16104
|
if (!ctrl) return;
|
|
@@ -15918,11 +16140,85 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
15918
16140
|
});
|
|
15919
16141
|
}
|
|
15920
16142
|
});
|
|
16143
|
+
app.post(
|
|
16144
|
+
`${base}/operations/:operationId/interactions/:interactionId`,
|
|
16145
|
+
mutate({ strict: true }),
|
|
16146
|
+
async (req, res) => {
|
|
16147
|
+
const ctrl = resolve5(req, res, false);
|
|
16148
|
+
if (!ctrl) return;
|
|
16149
|
+
try {
|
|
16150
|
+
if (!ctrl.validateExtensionMutationClient(req, res, {
|
|
16151
|
+
requireClientId: false
|
|
16152
|
+
})) {
|
|
16153
|
+
return;
|
|
16154
|
+
}
|
|
16155
|
+
const operationId = req.params["operationId"];
|
|
16156
|
+
const interactionId = req.params["interactionId"];
|
|
16157
|
+
const pending = operationId ? pendingExtensionInteractions.get(operationId) : void 0;
|
|
16158
|
+
if (!operationId || !interactionId || !pending) {
|
|
16159
|
+
res.status(404).json({ error: "Extension interaction not found" });
|
|
16160
|
+
return;
|
|
16161
|
+
}
|
|
16162
|
+
if (pending.interaction.id !== interactionId) {
|
|
16163
|
+
res.status(404).json({ error: "Extension interaction not found" });
|
|
16164
|
+
return;
|
|
16165
|
+
}
|
|
16166
|
+
const body = safeBody2(req);
|
|
16167
|
+
let value;
|
|
16168
|
+
if (body["cancelled"] === true) {
|
|
16169
|
+
clearTimeout(pending.timeout);
|
|
16170
|
+
pendingExtensionInteractions.delete(operationId);
|
|
16171
|
+
ctrl.updateOperation(operationId, {
|
|
16172
|
+
status: "failed",
|
|
16173
|
+
phase: void 0,
|
|
16174
|
+
interaction: void 0,
|
|
16175
|
+
error: "Extension operation cancelled"
|
|
16176
|
+
});
|
|
16177
|
+
pending.reject(new Error("Extension operation cancelled"));
|
|
16178
|
+
res.status(200).json({ accepted: true });
|
|
16179
|
+
return;
|
|
16180
|
+
}
|
|
16181
|
+
if (pending.interaction.kind === "marketplace_plugin") {
|
|
16182
|
+
const pluginName = body["pluginName"];
|
|
16183
|
+
if (typeof pluginName !== "string" || !pending.interaction.plugins.some(
|
|
16184
|
+
(plugin) => plugin.name === pluginName
|
|
16185
|
+
)) {
|
|
16186
|
+
res.status(400).json({ error: "Invalid marketplace plugin name" });
|
|
16187
|
+
return;
|
|
16188
|
+
}
|
|
16189
|
+
value = pluginName;
|
|
16190
|
+
} else {
|
|
16191
|
+
const settingValue = body["value"];
|
|
16192
|
+
if (typeof settingValue !== "string") {
|
|
16193
|
+
res.status(400).json({ error: "Extension setting value must be a string" });
|
|
16194
|
+
return;
|
|
16195
|
+
}
|
|
16196
|
+
value = settingValue;
|
|
16197
|
+
}
|
|
16198
|
+
clearTimeout(pending.timeout);
|
|
16199
|
+
pendingExtensionInteractions.delete(operationId);
|
|
16200
|
+
ctrl.updateOperation(operationId, {
|
|
16201
|
+
status: "running",
|
|
16202
|
+
phase: "preparing",
|
|
16203
|
+
interaction: void 0,
|
|
16204
|
+
error: void 0
|
|
16205
|
+
});
|
|
16206
|
+
pending.resolve(value);
|
|
16207
|
+
res.status(200).json({ accepted: true });
|
|
16208
|
+
} catch (err) {
|
|
16209
|
+
sendBridgeError2(res, err, {
|
|
16210
|
+
route: `POST ${base}/operations/:operationId/interactions/:interactionId`
|
|
16211
|
+
});
|
|
16212
|
+
}
|
|
16213
|
+
}
|
|
16214
|
+
);
|
|
15921
16215
|
app.post(`${base}/install`, mutate({ strict: true }), async (req, res) => {
|
|
15922
16216
|
const ctrl = resolve5(req, res, true);
|
|
15923
16217
|
if (!ctrl) return;
|
|
15924
16218
|
try {
|
|
15925
|
-
if (!ctrl.validateExtensionMutationClient(req, res
|
|
16219
|
+
if (!ctrl.validateExtensionMutationClient(req, res, {
|
|
16220
|
+
requireClientId: false
|
|
16221
|
+
})) {
|
|
15926
16222
|
return;
|
|
15927
16223
|
}
|
|
15928
16224
|
const body = safeBody2(req);
|
|
@@ -15972,11 +16268,56 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
15972
16268
|
if (!validateExtensionSourceHost(sourceValue, res)) {
|
|
15973
16269
|
return;
|
|
15974
16270
|
}
|
|
16271
|
+
const localSource = /^[A-Za-z]:[\\/]/.test(sourceValue) || sourceValue.startsWith("/") || sourceValue.startsWith(".");
|
|
16272
|
+
if (localSource) {
|
|
16273
|
+
try {
|
|
16274
|
+
const metadata = await parseInstallSource(sourceValue, {
|
|
16275
|
+
networkPolicy: "public"
|
|
16276
|
+
});
|
|
16277
|
+
if (metadata.type !== "git" && metadata.type !== "github-release" && metadata.type !== "npm") {
|
|
16278
|
+
res.status(400).json({
|
|
16279
|
+
error: "Only GitHub, Git, and npm extension installs are supported over the daemon endpoint."
|
|
16280
|
+
});
|
|
16281
|
+
return;
|
|
16282
|
+
}
|
|
16283
|
+
} catch (error2) {
|
|
16284
|
+
const message = error2 instanceof Error ? error2.message : "Invalid install source";
|
|
16285
|
+
res.status(400).json({
|
|
16286
|
+
error: redactUrlCredentials(
|
|
16287
|
+
message.replaceAll(
|
|
16288
|
+
sourceValue,
|
|
16289
|
+
redactExtensionDisplaySource(sourceValue)
|
|
16290
|
+
)
|
|
16291
|
+
)
|
|
16292
|
+
});
|
|
16293
|
+
return;
|
|
16294
|
+
}
|
|
16295
|
+
}
|
|
16296
|
+
const npmSource = sourceValue.startsWith("@");
|
|
16297
|
+
const remoteSource = npmSource || sourceValue.startsWith("https://") || /^[^/\s]+\/[^/\s]+/.test(sourceValue);
|
|
16298
|
+
if (!localSource && !remoteSource) {
|
|
16299
|
+
res.status(400).json({
|
|
16300
|
+
error: `Install source not found: ${redactExtensionDisplaySource(
|
|
16301
|
+
sourceValue
|
|
16302
|
+
)}`
|
|
16303
|
+
});
|
|
16304
|
+
return;
|
|
16305
|
+
}
|
|
16306
|
+
if (npmSource && refValue) {
|
|
16307
|
+
res.status(400).json({ error: "--ref is not applicable for npm extensions." });
|
|
16308
|
+
return;
|
|
16309
|
+
}
|
|
16310
|
+
if (!npmSource && registryValue) {
|
|
16311
|
+
res.status(400).json({
|
|
16312
|
+
error: "--registry is only applicable for npm extensions."
|
|
16313
|
+
});
|
|
16314
|
+
return;
|
|
16315
|
+
}
|
|
15975
16316
|
ctrl.runQueuedExtensionMutation(
|
|
15976
16317
|
"install",
|
|
15977
16318
|
{ source: sourceValue },
|
|
15978
16319
|
res,
|
|
15979
|
-
async (extensionManager, _signal, context) => {
|
|
16320
|
+
async (extensionManager, _signal, context, operationId) => {
|
|
15980
16321
|
const prepared = await context.prepare(async (signal) => {
|
|
15981
16322
|
const installMetadata = await parseInstallSource(sourceValue, {
|
|
15982
16323
|
networkPolicy: "public"
|
|
@@ -16000,6 +16341,7 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
16000
16341
|
if (installMetadata.type === "npm" && registryUrl) {
|
|
16001
16342
|
installMetadata.registryUrl = registryUrl;
|
|
16002
16343
|
}
|
|
16344
|
+
supersedeActiveInstallOperations(ctrl, operationId);
|
|
16003
16345
|
return await extensionManager.prepareExtensionInstall({
|
|
16004
16346
|
installMetadata: {
|
|
16005
16347
|
...installMetadata,
|
|
@@ -16030,7 +16372,19 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
16030
16372
|
}
|
|
16031
16373
|
},
|
|
16032
16374
|
{
|
|
16033
|
-
|
|
16375
|
+
createManager: /* @__PURE__ */ __name((operationId) => ctrl.createExtensionManager(
|
|
16376
|
+
void 0,
|
|
16377
|
+
void 0,
|
|
16378
|
+
extensionInteractionHandlers(ctrl, operationId)
|
|
16379
|
+
), "createManager"),
|
|
16380
|
+
onSettled: /* @__PURE__ */ __name((operationId) => {
|
|
16381
|
+
supersededInstallOperations.delete(operationId);
|
|
16382
|
+
cancelPendingExtensionInteraction(
|
|
16383
|
+
operationId,
|
|
16384
|
+
"Extension operation ended"
|
|
16385
|
+
);
|
|
16386
|
+
}, "onSettled"),
|
|
16387
|
+
deadlineMs: EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS,
|
|
16034
16388
|
...globalReconciliationOptions()
|
|
16035
16389
|
}
|
|
16036
16390
|
);
|
|
@@ -16047,7 +16401,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
16047
16401
|
let timer;
|
|
16048
16402
|
let releaseOperationSlot;
|
|
16049
16403
|
try {
|
|
16050
|
-
if (!ctrl.validateExtensionMutationClient(req, res
|
|
16404
|
+
if (!ctrl.validateExtensionMutationClient(req, res, {
|
|
16405
|
+
requireClientId: false
|
|
16406
|
+
})) {
|
|
16051
16407
|
return;
|
|
16052
16408
|
}
|
|
16053
16409
|
releaseOperationSlot = ctrl.acquireOperationSlot(res);
|
|
@@ -16107,7 +16463,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
16107
16463
|
const ctrl = resolve5(req, res, true);
|
|
16108
16464
|
if (!ctrl) return;
|
|
16109
16465
|
try {
|
|
16110
|
-
if (!ctrl.validateExtensionMutationClient(req, res
|
|
16466
|
+
if (!ctrl.validateExtensionMutationClient(req, res, {
|
|
16467
|
+
requireClientId: false
|
|
16468
|
+
})) {
|
|
16111
16469
|
return;
|
|
16112
16470
|
}
|
|
16113
16471
|
const releaseOperationSlot = ctrl.acquireOperationSlot(res);
|
|
@@ -16223,7 +16581,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
16223
16581
|
const ctrl = resolve5(req, res, true);
|
|
16224
16582
|
if (!ctrl) return;
|
|
16225
16583
|
try {
|
|
16226
|
-
if (!ctrl.validateExtensionMutationClient(req, res
|
|
16584
|
+
if (!ctrl.validateExtensionMutationClient(req, res, {
|
|
16585
|
+
requireClientId: false
|
|
16586
|
+
})) {
|
|
16227
16587
|
return;
|
|
16228
16588
|
}
|
|
16229
16589
|
const name = req.params["name"];
|
|
@@ -16280,7 +16640,18 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
16280
16640
|
}
|
|
16281
16641
|
},
|
|
16282
16642
|
{
|
|
16283
|
-
|
|
16643
|
+
createManager: /* @__PURE__ */ __name((operationId) => ctrl.createExtensionManager(
|
|
16644
|
+
void 0,
|
|
16645
|
+
void 0,
|
|
16646
|
+
extensionInteractionHandlers(ctrl, operationId)
|
|
16647
|
+
), "createManager"),
|
|
16648
|
+
onSettled: /* @__PURE__ */ __name((operationId) => {
|
|
16649
|
+
cancelPendingExtensionInteraction(
|
|
16650
|
+
operationId,
|
|
16651
|
+
"Extension operation ended"
|
|
16652
|
+
);
|
|
16653
|
+
}, "onSettled"),
|
|
16654
|
+
deadlineMs: EXTENSION_INTERACTIVE_PREPARE_DEADLINE_MS,
|
|
16284
16655
|
...globalReconciliationOptions()
|
|
16285
16656
|
}
|
|
16286
16657
|
);
|
|
@@ -16293,7 +16664,9 @@ function registerWorkspaceExtensionRoutes(app, deps) {
|
|
|
16293
16664
|
const ctrl = resolve5(req, res, true);
|
|
16294
16665
|
if (!ctrl) return;
|
|
16295
16666
|
try {
|
|
16296
|
-
if (!ctrl.validateExtensionMutationClient(req, res
|
|
16667
|
+
if (!ctrl.validateExtensionMutationClient(req, res, {
|
|
16668
|
+
requireClientId: false
|
|
16669
|
+
})) {
|
|
16297
16670
|
return;
|
|
16298
16671
|
}
|
|
16299
16672
|
const name = req.params["name"];
|
|
@@ -17509,7 +17882,7 @@ __name(registerPermissionRoutes, "registerPermissionRoutes");
|
|
|
17509
17882
|
|
|
17510
17883
|
// packages/cli/src/serve/routes/session.ts
|
|
17511
17884
|
init_esbuild_shims();
|
|
17512
|
-
import * as
|
|
17885
|
+
import * as crypto3 from "node:crypto";
|
|
17513
17886
|
import * as path11 from "node:path";
|
|
17514
17887
|
|
|
17515
17888
|
// packages/cli/src/serve/server/prompt-deadline.ts
|
|
@@ -17566,7 +17939,7 @@ function parseOrganizedCursor(cursor, expected) {
|
|
|
17566
17939
|
const decoded = Buffer.from(cursor, "base64url").toString("utf8");
|
|
17567
17940
|
const parsed = JSON.parse(decoded);
|
|
17568
17941
|
const last = parsed.last;
|
|
17569
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.isPinned !== "boolean" || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.group !== expected.group || parsed.archiveState !== expected.archiveState) {
|
|
17942
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.isPinned !== "boolean" || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.group !== expected.group || parsed.archiveState !== expected.archiveState || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId) {
|
|
17570
17943
|
throw new Error("invalid organized cursor");
|
|
17571
17944
|
}
|
|
17572
17945
|
return last;
|
|
@@ -17575,9 +17948,9 @@ function parseOrganizedCursor(cursor, expected) {
|
|
|
17575
17948
|
}
|
|
17576
17949
|
}
|
|
17577
17950
|
__name(parseOrganizedCursor, "parseOrganizedCursor");
|
|
17578
|
-
function encodeOrganizedCursor(last, group, archiveState) {
|
|
17951
|
+
function encodeOrganizedCursor(last, group, archiveState, sourceType, sourceId) {
|
|
17579
17952
|
return Buffer.from(
|
|
17580
|
-
JSON.stringify({ group, archiveState, last }),
|
|
17953
|
+
JSON.stringify({ group, archiveState, sourceType, sourceId, last }),
|
|
17581
17954
|
"utf8"
|
|
17582
17955
|
).toString("base64url");
|
|
17583
17956
|
}
|
|
@@ -17601,29 +17974,39 @@ function encodeLiveSessionCursor(last) {
|
|
|
17601
17974
|
return Buffer.from(JSON.stringify(last), "utf8").toString("base64url");
|
|
17602
17975
|
}
|
|
17603
17976
|
__name(encodeLiveSessionCursor, "encodeLiveSessionCursor");
|
|
17604
|
-
function
|
|
17977
|
+
function matchesSessionMetadataSource(session, filter) {
|
|
17978
|
+
const sourceTypeMatches = filter.sourceType === void 0 || session.sourceType === filter.sourceType || // Legacy sessions without source metadata belong to the default catalog.
|
|
17979
|
+
filter.sourceType === "default" && session.sourceType === void 0;
|
|
17980
|
+
return sourceTypeMatches && // sourceId remains exact; only the default source type has legacy fallback.
|
|
17981
|
+
(filter.sourceId === void 0 || session.sourceId === filter.sourceId);
|
|
17982
|
+
}
|
|
17983
|
+
__name(matchesSessionMetadataSource, "matchesSessionMetadataSource");
|
|
17984
|
+
function parseMetadataSessionCursor(cursor, expected) {
|
|
17605
17985
|
if (cursor === "") return void 0;
|
|
17606
17986
|
try {
|
|
17607
17987
|
const parsed = JSON.parse(
|
|
17608
17988
|
Buffer.from(cursor, "base64url").toString("utf8")
|
|
17609
17989
|
);
|
|
17610
17990
|
const last = parsed.last;
|
|
17611
|
-
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.parentSessionId !== expected.parentSessionId || parsed.archiveState !== expected.archiveState) {
|
|
17612
|
-
throw new Error("invalid
|
|
17991
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof last !== "object" || last === null || Array.isArray(last) || typeof last.activityTime !== "number" || !Number.isFinite(last.activityTime) || typeof last.sessionId !== "string" || last.sessionId.length === 0 || parsed.parentSessionId !== expected.parentSessionId || parsed.sourceType !== expected.sourceType || parsed.sourceId !== expected.sourceId || parsed.archiveState !== expected.archiveState) {
|
|
17992
|
+
throw new Error("invalid metadata cursor");
|
|
17613
17993
|
}
|
|
17614
17994
|
return { activityTime: last.activityTime, sessionId: last.sessionId };
|
|
17615
17995
|
} catch {
|
|
17616
|
-
throw new InvalidCursorError(
|
|
17996
|
+
throw new InvalidCursorError(
|
|
17997
|
+
cursor,
|
|
17998
|
+
expected.sourceType === void 0 ? "parent" : "metadata"
|
|
17999
|
+
);
|
|
17617
18000
|
}
|
|
17618
18001
|
}
|
|
17619
|
-
__name(
|
|
17620
|
-
function
|
|
18002
|
+
__name(parseMetadataSessionCursor, "parseMetadataSessionCursor");
|
|
18003
|
+
function encodeMetadataSessionCursor(last, filter, archiveState) {
|
|
17621
18004
|
return Buffer.from(
|
|
17622
|
-
JSON.stringify({
|
|
18005
|
+
JSON.stringify({ ...filter, archiveState, last }),
|
|
17623
18006
|
"utf8"
|
|
17624
18007
|
).toString("base64url");
|
|
17625
18008
|
}
|
|
17626
|
-
__name(
|
|
18009
|
+
__name(encodeMetadataSessionCursor, "encodeMetadataSessionCursor");
|
|
17627
18010
|
function toSummary2(item) {
|
|
17628
18011
|
return {
|
|
17629
18012
|
sessionId: item.sessionId,
|
|
@@ -17632,6 +18015,8 @@ function toSummary2(item) {
|
|
|
17632
18015
|
updatedAt: new Date(item.mtime).toISOString(),
|
|
17633
18016
|
displayName: item.customTitle || item.prompt,
|
|
17634
18017
|
...item.parentSessionId ? { parentSessionId: item.parentSessionId } : {},
|
|
18018
|
+
...item.sourceType ? { sourceType: item.sourceType } : {},
|
|
18019
|
+
...item.sourceId !== void 0 ? { sourceId: item.sourceId } : {},
|
|
17635
18020
|
clientCount: 0,
|
|
17636
18021
|
hasActivePrompt: false,
|
|
17637
18022
|
isArchived: item.isArchived === true
|
|
@@ -17647,6 +18032,8 @@ function mergeLiveSessionSummary(existing, live) {
|
|
|
17647
18032
|
// Immutable lineage; the persisted transcript is authoritative, and a live
|
|
17648
18033
|
// entry only carries it when spawned this run.
|
|
17649
18034
|
parentSessionId: existing.parentSessionId ?? live.parentSessionId,
|
|
18035
|
+
sourceType: existing.sourceType ?? live.sourceType,
|
|
18036
|
+
sourceId: existing.sourceType !== void 0 ? existing.sourceId : live.sourceId,
|
|
17650
18037
|
updatedAt: live.updatedAt ?? existing.updatedAt,
|
|
17651
18038
|
clientCount: live.clientCount,
|
|
17652
18039
|
hasActivePrompt: live.hasActivePrompt,
|
|
@@ -17746,7 +18133,12 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
|
|
|
17746
18133
|
"group"
|
|
17747
18134
|
);
|
|
17748
18135
|
}
|
|
17749
|
-
const cursorKey = options.cursor !== void 0 ? parseOrganizedCursor(options.cursor, {
|
|
18136
|
+
const cursorKey = options.cursor !== void 0 ? parseOrganizedCursor(options.cursor, {
|
|
18137
|
+
group,
|
|
18138
|
+
archiveState,
|
|
18139
|
+
sourceType: options.sourceType,
|
|
18140
|
+
sourceId: options.sourceId
|
|
18141
|
+
}) : void 0;
|
|
17750
18142
|
const isFirstPage = cursorKey === void 0;
|
|
17751
18143
|
let liveMergeFailed = false;
|
|
17752
18144
|
const bySessionId = /* @__PURE__ */ new Map();
|
|
@@ -17798,6 +18190,7 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
|
|
|
17798
18190
|
}
|
|
17799
18191
|
}
|
|
17800
18192
|
const filtered = [...bySessionId.values()].filter((session) => {
|
|
18193
|
+
if (!matchesSessionMetadataSource(session, options)) return false;
|
|
17801
18194
|
if (group === "all") return true;
|
|
17802
18195
|
if (group === "pinned") return session.isPinned === true;
|
|
17803
18196
|
if (group === "ungrouped")
|
|
@@ -17821,7 +18214,9 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
|
|
|
17821
18214
|
const nextCursor = page.length < afterCursor.length ? encodeOrganizedCursor(
|
|
17822
18215
|
getOrganizedCursorKey(activityTimeById, page[page.length - 1]),
|
|
17823
18216
|
group,
|
|
17824
|
-
archiveState
|
|
18217
|
+
archiveState,
|
|
18218
|
+
options.sourceType,
|
|
18219
|
+
options.sourceId
|
|
17825
18220
|
) : void 0;
|
|
17826
18221
|
return {
|
|
17827
18222
|
sessions: page,
|
|
@@ -17831,7 +18226,7 @@ async function listOrganizedWorkspaceSessionsForResponse(bridge, workspaceCwd, o
|
|
|
17831
18226
|
};
|
|
17832
18227
|
}
|
|
17833
18228
|
__name(listOrganizedWorkspaceSessionsForResponse, "listOrganizedWorkspaceSessionsForResponse");
|
|
17834
|
-
async function
|
|
18229
|
+
async function listWorkspaceSessionsByMetadataForResponse(bridge, workspaceCwd, options, pageSize, filter, readOptions) {
|
|
17835
18230
|
const archiveState = options.archiveState ?? "active";
|
|
17836
18231
|
const sessionService = new SessionService(workspaceCwd);
|
|
17837
18232
|
const bySessionId = /* @__PURE__ */ new Map();
|
|
@@ -17865,18 +18260,20 @@ async function listWorkspaceSessionsByParentForResponse(bridge, workspaceCwd, op
|
|
|
17865
18260
|
} catch (error2) {
|
|
17866
18261
|
liveMergeFailed = true;
|
|
17867
18262
|
writeStderrLine(
|
|
17868
|
-
`qwen serve: session
|
|
18263
|
+
`qwen serve: session metadata filter live merge failed; using persisted sessions only: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
17869
18264
|
);
|
|
17870
18265
|
}
|
|
17871
18266
|
}
|
|
17872
|
-
const matches = [...bySessionId.values()].filter(
|
|
18267
|
+
const matches = [...bySessionId.values()].filter(
|
|
18268
|
+
(session) => (filter.parentSessionId === void 0 || session.parentSessionId === filter.parentSessionId) && matchesSessionMetadataSource(session, filter)
|
|
18269
|
+
).sort(
|
|
17873
18270
|
(a, b) => compareLiveSessionCursorKeys(
|
|
17874
18271
|
getLiveSessionCursorKey(a),
|
|
17875
18272
|
getLiveSessionCursorKey(b)
|
|
17876
18273
|
)
|
|
17877
18274
|
);
|
|
17878
|
-
const cursorKey = options.cursor !== void 0 && options.cursor !== "" ?
|
|
17879
|
-
|
|
18275
|
+
const cursorKey = options.cursor !== void 0 && options.cursor !== "" ? parseMetadataSessionCursor(options.cursor, {
|
|
18276
|
+
...filter,
|
|
17880
18277
|
archiveState
|
|
17881
18278
|
}) : void 0;
|
|
17882
18279
|
const afterCursor = cursorKey === void 0 ? matches : matches.filter(
|
|
@@ -17886,9 +18283,9 @@ async function listWorkspaceSessionsByParentForResponse(bridge, workspaceCwd, op
|
|
|
17886
18283
|
) < 0
|
|
17887
18284
|
);
|
|
17888
18285
|
const page = afterCursor.slice(0, pageSize);
|
|
17889
|
-
const nextCursor = page.length < afterCursor.length ?
|
|
18286
|
+
const nextCursor = page.length < afterCursor.length ? encodeMetadataSessionCursor(
|
|
17890
18287
|
getLiveSessionCursorKey(page[page.length - 1]),
|
|
17891
|
-
|
|
18288
|
+
filter,
|
|
17892
18289
|
archiveState
|
|
17893
18290
|
) : void 0;
|
|
17894
18291
|
return {
|
|
@@ -17898,7 +18295,7 @@ async function listWorkspaceSessionsByParentForResponse(bridge, workspaceCwd, op
|
|
|
17898
18295
|
...persisted.truncated ? { truncated: true } : {}
|
|
17899
18296
|
};
|
|
17900
18297
|
}
|
|
17901
|
-
__name(
|
|
18298
|
+
__name(listWorkspaceSessionsByMetadataForResponse, "listWorkspaceSessionsByMetadataForResponse");
|
|
17902
18299
|
async function listWorkspaceSessionsForResponse(bridge, workspaceCwd, options, readOptions = {}) {
|
|
17903
18300
|
const rawSize = options?.size;
|
|
17904
18301
|
const requestedSize = typeof rawSize === "number" && Number.isSafeInteger(rawSize) ? rawSize : DEFAULT_SESSION_PAGE_SIZE;
|
|
@@ -17912,13 +18309,17 @@ async function listWorkspaceSessionsForResponse(bridge, workspaceCwd, options, r
|
|
|
17912
18309
|
readOptions
|
|
17913
18310
|
);
|
|
17914
18311
|
}
|
|
17915
|
-
if (options?.parentSessionId !== void 0) {
|
|
17916
|
-
return
|
|
18312
|
+
if (options?.parentSessionId !== void 0 || options?.sourceType !== void 0) {
|
|
18313
|
+
return listWorkspaceSessionsByMetadataForResponse(
|
|
17917
18314
|
bridge,
|
|
17918
18315
|
workspaceCwd,
|
|
17919
18316
|
options,
|
|
17920
18317
|
pageSize,
|
|
17921
|
-
|
|
18318
|
+
{
|
|
18319
|
+
...options.parentSessionId !== void 0 ? { parentSessionId: options.parentSessionId } : {},
|
|
18320
|
+
...options.sourceType !== void 0 ? { sourceType: options.sourceType } : {},
|
|
18321
|
+
...options.sourceId !== void 0 ? { sourceId: options.sourceId } : {}
|
|
18322
|
+
},
|
|
17922
18323
|
readOptions
|
|
17923
18324
|
);
|
|
17924
18325
|
}
|
|
@@ -18036,9 +18437,10 @@ function sessionExportFormatValues() {
|
|
|
18036
18437
|
__name(sessionExportFormatValues, "sessionExportFormatValues");
|
|
18037
18438
|
async function exportSessionTranscript(params) {
|
|
18038
18439
|
const { workspaceCwd, sessionId, format } = params;
|
|
18039
|
-
const
|
|
18040
|
-
|
|
18041
|
-
|
|
18440
|
+
const service = new SessionService(workspaceCwd);
|
|
18441
|
+
const sessionData = params.archiveState === "archived" ? await service.loadArchivedSession(sessionId, {
|
|
18442
|
+
maxBytes: SESSION_TRANSCRIPT_MAX_INDEX_BYTES
|
|
18443
|
+
}) : await service.loadSession(sessionId);
|
|
18042
18444
|
if (!sessionData) {
|
|
18043
18445
|
throw new SessionNotFoundError(sessionId);
|
|
18044
18446
|
}
|
|
@@ -18067,6 +18469,60 @@ var WORKSPACE_TRANSCRIPT_PAGE_SOURCE_MAX_BYTES = 4 * 1024 * 1024;
|
|
|
18067
18469
|
var WORKSPACE_TRANSCRIPT_RESPONSE_MAX_BYTES = 32 * 1024 * 1024;
|
|
18068
18470
|
var WORKSPACE_TRANSCRIPT_CURSOR_MAX_BYTES = 64 * 1024;
|
|
18069
18471
|
var TRANSCRIPT_CURSOR_TOO_LARGE_REPLAY_ERROR = "Transcript pagination state exceeds the safe limit";
|
|
18472
|
+
var GENERATION_HEARTBEAT_MS = 15e3;
|
|
18473
|
+
var PRIMARY_ONLY_LIVE_SESSION_ROUTES = [
|
|
18474
|
+
"POST /session/:id/branch",
|
|
18475
|
+
"POST /session/:id/fork",
|
|
18476
|
+
"POST /session/:id/cd"
|
|
18477
|
+
];
|
|
18478
|
+
function isPrimaryOnlyLiveSessionRoute(route) {
|
|
18479
|
+
return PRIMARY_ONLY_LIVE_SESSION_ROUTES.includes(
|
|
18480
|
+
route
|
|
18481
|
+
);
|
|
18482
|
+
}
|
|
18483
|
+
__name(isPrimaryOnlyLiveSessionRoute, "isPrimaryOnlyLiveSessionRoute");
|
|
18484
|
+
function formatGenerationSse(event, data) {
|
|
18485
|
+
return `event: ${event}
|
|
18486
|
+
data: ${JSON.stringify({ v: 1, ...data })}
|
|
18487
|
+
|
|
18488
|
+
`;
|
|
18489
|
+
}
|
|
18490
|
+
__name(formatGenerationSse, "formatGenerationSse");
|
|
18491
|
+
function writeGenerationSseChunk(res, chunk) {
|
|
18492
|
+
if (res.destroyed) {
|
|
18493
|
+
return Promise.reject(new Error("Generation SSE connection destroyed"));
|
|
18494
|
+
}
|
|
18495
|
+
const writable = res.write(chunk);
|
|
18496
|
+
const flush = res.flush;
|
|
18497
|
+
flush?.call(res);
|
|
18498
|
+
if (writable) {
|
|
18499
|
+
return res.destroyed ? Promise.reject(new Error("Generation SSE connection destroyed")) : Promise.resolve();
|
|
18500
|
+
}
|
|
18501
|
+
return new Promise((resolve5, reject) => {
|
|
18502
|
+
const cleanup = /* @__PURE__ */ __name(() => {
|
|
18503
|
+
res.off("drain", onDrain);
|
|
18504
|
+
res.off("close", onClose);
|
|
18505
|
+
res.off("error", onError);
|
|
18506
|
+
}, "cleanup");
|
|
18507
|
+
const onDrain = /* @__PURE__ */ __name(() => {
|
|
18508
|
+
cleanup();
|
|
18509
|
+
resolve5();
|
|
18510
|
+
}, "onDrain");
|
|
18511
|
+
const onClose = /* @__PURE__ */ __name(() => {
|
|
18512
|
+
cleanup();
|
|
18513
|
+
reject(new Error("Generation SSE connection closed"));
|
|
18514
|
+
}, "onClose");
|
|
18515
|
+
const onError = /* @__PURE__ */ __name((error2) => {
|
|
18516
|
+
cleanup();
|
|
18517
|
+
reject(error2);
|
|
18518
|
+
}, "onError");
|
|
18519
|
+
res.once("drain", onDrain);
|
|
18520
|
+
res.once("close", onClose);
|
|
18521
|
+
res.once("error", onError);
|
|
18522
|
+
if (res.destroyed) onClose();
|
|
18523
|
+
});
|
|
18524
|
+
}
|
|
18525
|
+
__name(writeGenerationSseChunk, "writeGenerationSseChunk");
|
|
18070
18526
|
function isReadOnlyWorkspaceInspection(runtime) {
|
|
18071
18527
|
return !runtime.primary && !runtime.trusted;
|
|
18072
18528
|
}
|
|
@@ -18212,14 +18668,14 @@ function registerSessionRoutes(app, deps) {
|
|
|
18212
18668
|
sessionShellCommandEnabled
|
|
18213
18669
|
} = deps;
|
|
18214
18670
|
const LANGUAGE_CODES = deps.languageCodes;
|
|
18215
|
-
const transcriptCursorMasterKey =
|
|
18671
|
+
const transcriptCursorMasterKey = crypto3.randomBytes(32);
|
|
18216
18672
|
const transcriptCursorCodecs = /* @__PURE__ */ new Map();
|
|
18217
18673
|
const getTranscriptCursorCodec = /* @__PURE__ */ __name((runtime) => {
|
|
18218
18674
|
const canonicalCwd = canonicalizeWorkspace(runtime.workspaceCwd);
|
|
18219
18675
|
const cacheKey = `${runtime.workspaceId}\0${canonicalCwd}`;
|
|
18220
18676
|
const cached = transcriptCursorCodecs.get(cacheKey);
|
|
18221
18677
|
if (cached) return cached;
|
|
18222
|
-
const derivedKey =
|
|
18678
|
+
const derivedKey = crypto3.hkdfSync(
|
|
18223
18679
|
"sha256",
|
|
18224
18680
|
transcriptCursorMasterKey,
|
|
18225
18681
|
Buffer.alloc(0),
|
|
@@ -18397,11 +18853,16 @@ function registerSessionRoutes(app, deps) {
|
|
|
18397
18853
|
const result = await archiveCoordinator.runSharedMany(
|
|
18398
18854
|
[sessionId],
|
|
18399
18855
|
async () => {
|
|
18400
|
-
|
|
18856
|
+
if (target.archiveState === "archived") {
|
|
18857
|
+
await assertSessionArchived(target.workspaceCwd, sessionId);
|
|
18858
|
+
} else {
|
|
18859
|
+
await assertSessionLoadable(target.workspaceCwd, sessionId);
|
|
18860
|
+
}
|
|
18401
18861
|
return exportSessionTranscript({
|
|
18402
18862
|
workspaceCwd: target.workspaceCwd,
|
|
18403
18863
|
sessionId,
|
|
18404
18864
|
format,
|
|
18865
|
+
archiveState: target.archiveState,
|
|
18405
18866
|
config: { getChannel: /* @__PURE__ */ __name(() => "daemon", "getChannel") }
|
|
18406
18867
|
});
|
|
18407
18868
|
}
|
|
@@ -18573,7 +19034,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
18573
19034
|
}), "resolveLiveSessionRuntime");
|
|
18574
19035
|
const sendNonPrimarySessionRouteUnsupported = /* @__PURE__ */ __name((res, route, sessionId, runtime) => {
|
|
18575
19036
|
res.status(400).json({
|
|
18576
|
-
error: `Route "${route}" is
|
|
19037
|
+
error: `Route "${route}" is only available for primary workspace sessions.`,
|
|
18577
19038
|
code: "non_primary_session_route_not_supported",
|
|
18578
19039
|
sessionId,
|
|
18579
19040
|
workspaceId: runtime.workspaceId,
|
|
@@ -18722,23 +19183,37 @@ function registerSessionRoutes(app, deps) {
|
|
|
18722
19183
|
}
|
|
18723
19184
|
return key;
|
|
18724
19185
|
}, "resolveWorkspaceParam");
|
|
18725
|
-
const
|
|
18726
|
-
|
|
18727
|
-
|
|
18728
|
-
const runtime = resolveLiveSessionRuntime(sessionId, res, route);
|
|
18729
|
-
if (!runtime) return;
|
|
18730
|
-
if (!runtime.primary) {
|
|
18731
|
-
sendNonPrimarySessionRouteUnsupported(res, route, sessionId, runtime);
|
|
18732
|
-
return;
|
|
19186
|
+
const withPrimaryOnlyMutableSession = /* @__PURE__ */ __name((route, handler) => {
|
|
19187
|
+
if (!isPrimaryOnlyLiveSessionRoute(route)) {
|
|
19188
|
+
throw new Error(`Unregistered primary-only session route: ${route}`);
|
|
18733
19189
|
}
|
|
18734
|
-
|
|
18735
|
-
|
|
18736
|
-
|
|
18737
|
-
|
|
18738
|
-
|
|
18739
|
-
|
|
18740
|
-
|
|
18741
|
-
|
|
19190
|
+
return async (req, res) => {
|
|
19191
|
+
const sessionId = requireSessionId(req, res);
|
|
19192
|
+
if (sessionId === null) return;
|
|
19193
|
+
const runtime = resolveLiveSessionRuntime(sessionId, res, route);
|
|
19194
|
+
if (!runtime) return;
|
|
19195
|
+
if (!runtime.primary) {
|
|
19196
|
+
logSessionRoutingFailure(
|
|
19197
|
+
route,
|
|
19198
|
+
"non_primary_session_route_not_supported",
|
|
19199
|
+
{
|
|
19200
|
+
sessionId,
|
|
19201
|
+
workspaceId: runtime.workspaceId,
|
|
19202
|
+
workspaceCwd: runtime.workspaceCwd
|
|
19203
|
+
}
|
|
19204
|
+
);
|
|
19205
|
+
sendNonPrimarySessionRouteUnsupported(res, route, sessionId, runtime);
|
|
19206
|
+
return;
|
|
19207
|
+
}
|
|
19208
|
+
try {
|
|
19209
|
+
await archiveCoordinator.runSharedMany([sessionId], async () => {
|
|
19210
|
+
await handler(req, res, sessionId);
|
|
19211
|
+
});
|
|
19212
|
+
} catch (err) {
|
|
19213
|
+
sendBridgeError2(res, err, { route, sessionId });
|
|
19214
|
+
}
|
|
19215
|
+
};
|
|
19216
|
+
}, "withPrimaryOnlyMutableSession");
|
|
18742
19217
|
app.post("/session", mutate(), async (req, res) => {
|
|
18743
19218
|
const body = safeBody(req);
|
|
18744
19219
|
const resolvedRuntime = resolveRuntimeForSessionCreation(body, res);
|
|
@@ -18759,6 +19234,14 @@ function registerSessionRoutes(app, deps) {
|
|
|
18759
19234
|
}
|
|
18760
19235
|
const approvalMode = parseOptionalApprovalMode(body, res);
|
|
18761
19236
|
if (approvalMode === null) return;
|
|
19237
|
+
const source = parseSessionSource(body["sourceType"], body["sourceId"]);
|
|
19238
|
+
if ("error" in source) {
|
|
19239
|
+
res.status(400).json({
|
|
19240
|
+
error: source.error,
|
|
19241
|
+
code: "invalid_session_source"
|
|
19242
|
+
});
|
|
19243
|
+
return;
|
|
19244
|
+
}
|
|
18762
19245
|
const clientId = parseClientIdHeader(req, res);
|
|
18763
19246
|
if (clientId === null) return;
|
|
18764
19247
|
try {
|
|
@@ -18767,7 +19250,9 @@ function registerSessionRoutes(app, deps) {
|
|
|
18767
19250
|
modelServiceId,
|
|
18768
19251
|
...clientId !== void 0 ? { clientId } : {},
|
|
18769
19252
|
...sessionScope !== void 0 ? { sessionScope } : {},
|
|
18770
|
-
...approvalMode !== void 0 ? { approvalMode } : {}
|
|
19253
|
+
...approvalMode !== void 0 ? { approvalMode } : {},
|
|
19254
|
+
...source.sourceType !== void 0 ? { sourceType: source.sourceType } : {},
|
|
19255
|
+
...source.sourceId !== void 0 ? { sourceId: source.sourceId } : {}
|
|
18771
19256
|
});
|
|
18772
19257
|
if (daemonLog) {
|
|
18773
19258
|
daemonLog.info(
|
|
@@ -18786,8 +19271,17 @@ function registerSessionRoutes(app, deps) {
|
|
|
18786
19271
|
);
|
|
18787
19272
|
}
|
|
18788
19273
|
if (!session.attached) {
|
|
18789
|
-
|
|
18790
|
-
|
|
19274
|
+
try {
|
|
19275
|
+
const killed = await runtime.bridge.killSession(session.sessionId, {
|
|
19276
|
+
requireZeroAttaches: true
|
|
19277
|
+
});
|
|
19278
|
+
if (killed) {
|
|
19279
|
+
await new SessionService(runtime.workspaceCwd).removeSession(
|
|
19280
|
+
session.sessionId
|
|
19281
|
+
);
|
|
19282
|
+
}
|
|
19283
|
+
} catch {
|
|
19284
|
+
}
|
|
18791
19285
|
} else {
|
|
18792
19286
|
runtime.bridge.detachClient(session.sessionId, session.clientId).catch(() => {
|
|
18793
19287
|
});
|
|
@@ -18840,22 +19334,22 @@ function registerSessionRoutes(app, deps) {
|
|
|
18840
19334
|
[sessionId],
|
|
18841
19335
|
async () => {
|
|
18842
19336
|
await assertSessionLoadable(workspaceCwd, sessionId);
|
|
18843
|
-
const
|
|
19337
|
+
const metadata = await new SessionService(
|
|
18844
19338
|
workspaceCwd
|
|
18845
|
-
).
|
|
19339
|
+
).readCreationMetadata(sessionId);
|
|
18846
19340
|
return action === "load" ? await runtime.bridge.loadSession({
|
|
18847
19341
|
sessionId,
|
|
18848
19342
|
workspaceCwd,
|
|
18849
19343
|
historyReplay: "response",
|
|
18850
19344
|
...clientId !== void 0 ? { clientId } : {},
|
|
18851
19345
|
...approvalMode !== void 0 ? { approvalMode } : {},
|
|
18852
|
-
...
|
|
19346
|
+
...metadata
|
|
18853
19347
|
}) : await runtime.bridge.resumeSession({
|
|
18854
19348
|
sessionId,
|
|
18855
19349
|
workspaceCwd,
|
|
18856
19350
|
...clientId !== void 0 ? { clientId } : {},
|
|
18857
19351
|
...approvalMode !== void 0 ? { approvalMode } : {},
|
|
18858
|
-
...
|
|
19352
|
+
...metadata
|
|
18859
19353
|
});
|
|
18860
19354
|
}
|
|
18861
19355
|
);
|
|
@@ -18890,7 +19384,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
18890
19384
|
app.post(
|
|
18891
19385
|
"/session/:id/branch",
|
|
18892
19386
|
mutate(),
|
|
18893
|
-
|
|
19387
|
+
withPrimaryOnlyMutableSession(
|
|
18894
19388
|
"POST /session/:id/branch",
|
|
18895
19389
|
async (req, res, sessionId) => {
|
|
18896
19390
|
const body = safeBody(req);
|
|
@@ -18925,7 +19419,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
18925
19419
|
app.post(
|
|
18926
19420
|
"/session/:id/fork",
|
|
18927
19421
|
mutate(),
|
|
18928
|
-
|
|
19422
|
+
withPrimaryOnlyMutableSession(
|
|
18929
19423
|
"POST /session/:id/fork",
|
|
18930
19424
|
async (req, res, sessionId) => {
|
|
18931
19425
|
const body = safeBody(req);
|
|
@@ -18951,25 +19445,28 @@ function registerSessionRoutes(app, deps) {
|
|
|
18951
19445
|
app.post(
|
|
18952
19446
|
"/session/:id/cd",
|
|
18953
19447
|
mutate(),
|
|
18954
|
-
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
19448
|
+
withPrimaryOnlyMutableSession(
|
|
19449
|
+
"POST /session/:id/cd",
|
|
19450
|
+
async (req, res, sessionId) => {
|
|
19451
|
+
const body = safeBody(req);
|
|
19452
|
+
const targetPath = body["path"];
|
|
19453
|
+
if (typeof targetPath !== "string" || targetPath.length === 0 || !path11.isAbsolute(targetPath)) {
|
|
19454
|
+
res.status(400).json({
|
|
19455
|
+
error: "`path` is required and must be an absolute path",
|
|
19456
|
+
code: "invalid_path"
|
|
19457
|
+
});
|
|
19458
|
+
return;
|
|
19459
|
+
}
|
|
19460
|
+
const clientId = parseClientIdHeader(req, res);
|
|
19461
|
+
if (clientId === null) return;
|
|
19462
|
+
const result = await bridge.changeSessionCwd(
|
|
19463
|
+
sessionId,
|
|
19464
|
+
{ path: targetPath },
|
|
19465
|
+
clientId !== void 0 ? { clientId } : void 0
|
|
19466
|
+
);
|
|
19467
|
+
res.status(200).json(result);
|
|
18963
19468
|
}
|
|
18964
|
-
|
|
18965
|
-
if (clientId === null) return;
|
|
18966
|
-
const result = await bridge.changeSessionCwd(
|
|
18967
|
-
sessionId,
|
|
18968
|
-
{ path: targetPath },
|
|
18969
|
-
clientId !== void 0 ? { clientId } : void 0
|
|
18970
|
-
);
|
|
18971
|
-
res.status(200).json(result);
|
|
18972
|
-
})
|
|
19469
|
+
)
|
|
18973
19470
|
);
|
|
18974
19471
|
app.get("/session/:id/status", (req, res) => {
|
|
18975
19472
|
const sessionId = requireSessionId(req, res);
|
|
@@ -19005,6 +19502,20 @@ function registerSessionRoutes(app, deps) {
|
|
|
19005
19502
|
workspaceQualified: true
|
|
19006
19503
|
});
|
|
19007
19504
|
});
|
|
19505
|
+
app.get(
|
|
19506
|
+
"/workspaces/:workspace/session/:id/archive/export",
|
|
19507
|
+
async (req, res) => {
|
|
19508
|
+
const route = "GET /workspaces/:workspace/session/:id/archive/export";
|
|
19509
|
+
const runtime = requireTrustedRuntimeForWorkspaceRoute(req, res, route);
|
|
19510
|
+
if (!runtime) return;
|
|
19511
|
+
await handleSessionExport(req, res, {
|
|
19512
|
+
route,
|
|
19513
|
+
workspaceCwd: runtime.workspaceCwd,
|
|
19514
|
+
workspaceQualified: true,
|
|
19515
|
+
archiveState: "archived"
|
|
19516
|
+
});
|
|
19517
|
+
}
|
|
19518
|
+
);
|
|
19008
19519
|
app.get("/session/:id/transcript", async (req, res) => {
|
|
19009
19520
|
const route = "GET /session/:id/transcript";
|
|
19010
19521
|
const sessionId = requireSessionId(req, res);
|
|
@@ -19348,7 +19859,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
19348
19859
|
async (req, res, sessionId, runtime) => {
|
|
19349
19860
|
const clientId = parseClientIdHeader(req, res);
|
|
19350
19861
|
if (clientId === null) return;
|
|
19351
|
-
const promptId =
|
|
19862
|
+
const promptId = crypto3.randomUUID();
|
|
19352
19863
|
res.status(200).json(
|
|
19353
19864
|
await runtime.bridge.continueSession(sessionId, {
|
|
19354
19865
|
...clientId !== void 0 ? { clientId } : {},
|
|
@@ -19395,7 +19906,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
19395
19906
|
}
|
|
19396
19907
|
const clientId = parseClientIdHeader(req, res);
|
|
19397
19908
|
if (clientId === null) return;
|
|
19398
|
-
const promptId =
|
|
19909
|
+
const promptId = crypto3.randomUUID();
|
|
19399
19910
|
const forwardedBody = { ...body };
|
|
19400
19911
|
delete forwardedBody["deadlineMs"];
|
|
19401
19912
|
const lastEventId = ownerBridge.getSessionLastEventId(sessionId);
|
|
@@ -19496,6 +20007,88 @@ function registerSessionRoutes(app, deps) {
|
|
|
19496
20007
|
}
|
|
19497
20008
|
)
|
|
19498
20009
|
);
|
|
20010
|
+
app.post(
|
|
20011
|
+
"/session/:id/generate",
|
|
20012
|
+
mutate(),
|
|
20013
|
+
withOwnerReadSession(
|
|
20014
|
+
"POST /session/:id/generate",
|
|
20015
|
+
async (req, res, sessionId, runtime) => {
|
|
20016
|
+
const body = safeBody(req);
|
|
20017
|
+
const prompt = body["prompt"];
|
|
20018
|
+
if (typeof prompt !== "string" || prompt.trim().length === 0 || Buffer.byteLength(prompt, "utf8") > GENERATION_MAX_PROMPT_BYTES) {
|
|
20019
|
+
res.status(400).json({
|
|
20020
|
+
error: `\`prompt\` must be a non-empty string no larger than ${GENERATION_MAX_PROMPT_BYTES} UTF-8 bytes`,
|
|
20021
|
+
code: "invalid_prompt"
|
|
20022
|
+
});
|
|
20023
|
+
return;
|
|
20024
|
+
}
|
|
20025
|
+
const clientId = parseClientIdHeader(req, res);
|
|
20026
|
+
if (clientId === null) return;
|
|
20027
|
+
if (!runtime.bridge.generateSessionContent) {
|
|
20028
|
+
res.status(501).json({
|
|
20029
|
+
error: "Stateless generation is not supported by this bridge",
|
|
20030
|
+
code: "generation_not_supported"
|
|
20031
|
+
});
|
|
20032
|
+
return;
|
|
20033
|
+
}
|
|
20034
|
+
const abort = new AbortController();
|
|
20035
|
+
let completed = false;
|
|
20036
|
+
const onClose = /* @__PURE__ */ __name(() => {
|
|
20037
|
+
if (!completed) abort.abort();
|
|
20038
|
+
}, "onClose");
|
|
20039
|
+
res.once("close", onClose);
|
|
20040
|
+
const stream = runtime.bridge.generateSessionContent(
|
|
20041
|
+
sessionId,
|
|
20042
|
+
prompt,
|
|
20043
|
+
abort.signal,
|
|
20044
|
+
clientId !== void 0 ? { clientId } : void 0
|
|
20045
|
+
);
|
|
20046
|
+
res.status(200);
|
|
20047
|
+
res.setHeader("Content-Type", "text/event-stream");
|
|
20048
|
+
res.setHeader("Cache-Control", "no-cache, no-transform");
|
|
20049
|
+
res.setHeader("Connection", "keep-alive");
|
|
20050
|
+
res.setHeader("X-Accel-Buffering", "no");
|
|
20051
|
+
res.flushHeaders();
|
|
20052
|
+
let writeChain = Promise.resolve();
|
|
20053
|
+
const write = /* @__PURE__ */ __name((chunk) => {
|
|
20054
|
+
writeChain = writeChain.then(
|
|
20055
|
+
() => writeGenerationSseChunk(res, chunk)
|
|
20056
|
+
);
|
|
20057
|
+
return writeChain;
|
|
20058
|
+
}, "write");
|
|
20059
|
+
await write(": connected\n\n");
|
|
20060
|
+
const heartbeat = setInterval(() => {
|
|
20061
|
+
void write(": heartbeat\n\n").catch(() => abort.abort());
|
|
20062
|
+
}, GENERATION_HEARTBEAT_MS);
|
|
20063
|
+
heartbeat.unref();
|
|
20064
|
+
try {
|
|
20065
|
+
for await (const event of stream) {
|
|
20066
|
+
await write(formatGenerationSse(event.type, event));
|
|
20067
|
+
}
|
|
20068
|
+
} catch (err) {
|
|
20069
|
+
if (!abort.signal.aborted && !res.destroyed) {
|
|
20070
|
+
daemonLog?.error(
|
|
20071
|
+
"session generation failed",
|
|
20072
|
+
err instanceof Error ? err : new Error(String(err)),
|
|
20073
|
+
{ sessionId, clientId }
|
|
20074
|
+
);
|
|
20075
|
+
await write(
|
|
20076
|
+
formatGenerationSse("error", {
|
|
20077
|
+
type: "error",
|
|
20078
|
+
code: "generation_failed",
|
|
20079
|
+
message: "Generation failed"
|
|
20080
|
+
})
|
|
20081
|
+
).catch(() => void 0);
|
|
20082
|
+
}
|
|
20083
|
+
} finally {
|
|
20084
|
+
completed = true;
|
|
20085
|
+
clearInterval(heartbeat);
|
|
20086
|
+
res.off("close", onClose);
|
|
20087
|
+
if (!res.destroyed) res.end();
|
|
20088
|
+
}
|
|
20089
|
+
}
|
|
20090
|
+
)
|
|
20091
|
+
);
|
|
19499
20092
|
app.post(
|
|
19500
20093
|
"/session/:id/heartbeat",
|
|
19501
20094
|
mutate(),
|
|
@@ -20064,16 +20657,28 @@ function registerSessionRoutes(app, deps) {
|
|
|
20064
20657
|
}
|
|
20065
20658
|
parentSessionId = rawParentSessionId;
|
|
20066
20659
|
}
|
|
20660
|
+
const parsedSource = parseSessionSource(
|
|
20661
|
+
req.query["sourceType"],
|
|
20662
|
+
req.query["sourceId"]
|
|
20663
|
+
);
|
|
20664
|
+
if ("error" in parsedSource) {
|
|
20665
|
+
res.status(400).json({
|
|
20666
|
+
error: parsedSource.error,
|
|
20667
|
+
code: "invalid_session_source"
|
|
20668
|
+
});
|
|
20669
|
+
return;
|
|
20670
|
+
}
|
|
20067
20671
|
const options = {
|
|
20068
20672
|
...cursor !== void 0 ? { cursor } : {},
|
|
20069
20673
|
...size !== void 0 ? { size } : {},
|
|
20070
20674
|
...archiveState !== void 0 ? { archiveState } : {},
|
|
20071
20675
|
...view !== void 0 ? { view } : {},
|
|
20072
20676
|
...group !== void 0 ? { group } : {},
|
|
20073
|
-
...parentSessionId !== void 0 ? { parentSessionId } : {}
|
|
20677
|
+
...parentSessionId !== void 0 ? { parentSessionId } : {},
|
|
20678
|
+
...parsedSource
|
|
20074
20679
|
};
|
|
20075
|
-
const usePersisted = readOnlySecondary || runtime.primary || view === "organized" || archiveState === "archived" || parentSessionId !== void 0 || (cursor !== void 0 && cursor !== "" ? isNumericSessionCursor(cursor) : await hasActivePersistedSessions(key));
|
|
20076
|
-
if (!usePersisted && (view !== void 0 || archiveState === "archived")) {
|
|
20680
|
+
const usePersisted = readOnlySecondary || runtime.primary || view === "organized" || archiveState === "archived" || parentSessionId !== void 0 || parsedSource.sourceType !== void 0 || (cursor !== void 0 && cursor !== "" ? isNumericSessionCursor(cursor) : await hasActivePersistedSessions(key));
|
|
20681
|
+
if (!usePersisted && (view !== void 0 || archiveState === "archived" || parentSessionId !== void 0 || parsedSource.sourceType !== void 0)) {
|
|
20077
20682
|
throw new Error(
|
|
20078
20683
|
"session list live path received persisted-only options"
|
|
20079
20684
|
);
|
|
@@ -20672,6 +21277,7 @@ function registerScheduledTaskCrudRoutes(app, deps) {
|
|
|
20672
21277
|
}
|
|
20673
21278
|
const recurring = body["recurring"] !== false;
|
|
20674
21279
|
const enabled = body["enabled"] !== false;
|
|
21280
|
+
const taskId = generateCronTaskId();
|
|
20675
21281
|
let boundSessionId;
|
|
20676
21282
|
if (bridge) {
|
|
20677
21283
|
try {
|
|
@@ -20687,7 +21293,9 @@ function registerScheduledTaskCrudRoutes(app, deps) {
|
|
|
20687
21293
|
try {
|
|
20688
21294
|
const session = await bridge.spawnOrAttach({
|
|
20689
21295
|
workspaceCwd,
|
|
20690
|
-
sessionScope: "thread"
|
|
21296
|
+
sessionScope: "thread",
|
|
21297
|
+
sourceType: "scheduled_task",
|
|
21298
|
+
sourceId: taskId
|
|
20691
21299
|
});
|
|
20692
21300
|
boundSessionId = session.sessionId;
|
|
20693
21301
|
try {
|
|
@@ -20709,7 +21317,7 @@ function registerScheduledTaskCrudRoutes(app, deps) {
|
|
|
20709
21317
|
}
|
|
20710
21318
|
const now = Date.now();
|
|
20711
21319
|
const task = {
|
|
20712
|
-
id:
|
|
21320
|
+
id: taskId,
|
|
20713
21321
|
cron,
|
|
20714
21322
|
prompt,
|
|
20715
21323
|
recurring,
|
|
@@ -21192,7 +21800,9 @@ async function bindAndNameSessions(bridge, boundWorkspace, tasks, renamed, spawn
|
|
|
21192
21800
|
binding.add(task.id);
|
|
21193
21801
|
const rawSpawn = bridge.spawnOrAttach({
|
|
21194
21802
|
workspaceCwd: boundWorkspace,
|
|
21195
|
-
sessionScope: "thread"
|
|
21803
|
+
sessionScope: "thread",
|
|
21804
|
+
sourceType: "scheduled_task",
|
|
21805
|
+
sourceId: task.id
|
|
21196
21806
|
});
|
|
21197
21807
|
let timedOut = false;
|
|
21198
21808
|
rawSpawn.then(({ sessionId: sessionId2 }) => {
|
|
@@ -21301,12 +21911,16 @@ function startScheduledTaskKeepalive(opts) {
|
|
|
21301
21911
|
continue;
|
|
21302
21912
|
}
|
|
21303
21913
|
log.debug("keepalive: recordHeartbeat failed for", sessionId, err);
|
|
21914
|
+
reviving.add(sessionId);
|
|
21915
|
+
const metadata = await new SessionService(
|
|
21916
|
+
boundWorkspace
|
|
21917
|
+
).readCreationMetadata(sessionId);
|
|
21304
21918
|
const load = bridge.loadSession({
|
|
21305
21919
|
sessionId,
|
|
21306
21920
|
workspaceCwd: boundWorkspace,
|
|
21307
|
-
historyReplay: "response"
|
|
21921
|
+
historyReplay: "response",
|
|
21922
|
+
...metadata
|
|
21308
21923
|
});
|
|
21309
|
-
reviving.add(sessionId);
|
|
21310
21924
|
void load.catch(() => {
|
|
21311
21925
|
}).finally(() => {
|
|
21312
21926
|
reviving.delete(sessionId);
|
|
@@ -21417,10 +22031,14 @@ async function rehydrateScheduledTaskSessions(deps) {
|
|
|
21417
22031
|
const loaded = [];
|
|
21418
22032
|
const failed = [];
|
|
21419
22033
|
const loadOne = /* @__PURE__ */ __name(async (sessionId) => {
|
|
22034
|
+
const metadata = await new SessionService(
|
|
22035
|
+
boundWorkspace
|
|
22036
|
+
).readCreationMetadata(sessionId);
|
|
21420
22037
|
const load = bridge.loadSession({
|
|
21421
22038
|
sessionId,
|
|
21422
22039
|
workspaceCwd: boundWorkspace,
|
|
21423
|
-
historyReplay: "response"
|
|
22040
|
+
historyReplay: "response",
|
|
22041
|
+
...metadata
|
|
21424
22042
|
});
|
|
21425
22043
|
void load.catch(() => {
|
|
21426
22044
|
});
|
|
@@ -21767,6 +22385,7 @@ function createServeFeatures(deps) {
|
|
|
21767
22385
|
boundWorkspace,
|
|
21768
22386
|
persistSettingAvailable,
|
|
21769
22387
|
sessionArtifactsPersistenceAvailable,
|
|
22388
|
+
sessionGenerationAvailable,
|
|
21770
22389
|
reloadAvailable,
|
|
21771
22390
|
channelReloadAvailable,
|
|
21772
22391
|
channelControlAvailable,
|
|
@@ -21800,6 +22419,7 @@ function createServeFeatures(deps) {
|
|
|
21800
22419
|
persistSettingAvailable,
|
|
21801
22420
|
sessionShellCommandEnabled,
|
|
21802
22421
|
sessionArtifactsPersistenceAvailable,
|
|
22422
|
+
sessionGenerationAvailable: sessionGenerationAvailable(),
|
|
21803
22423
|
rateLimit: opts.rateLimit === true,
|
|
21804
22424
|
reloadAvailable,
|
|
21805
22425
|
channelReloadAvailable: channelReloadAvailable(),
|
|
@@ -22089,6 +22709,7 @@ init_esbuild_shims();
|
|
|
22089
22709
|
var TUI_ONLY_SETTINGS = /* @__PURE__ */ new Set([
|
|
22090
22710
|
"general.vimMode",
|
|
22091
22711
|
"general.terminalBell",
|
|
22712
|
+
"general.notificationMode",
|
|
22092
22713
|
"general.preferredEditor",
|
|
22093
22714
|
"general.outputLanguage",
|
|
22094
22715
|
"ide.enabled",
|
|
@@ -22099,9 +22720,14 @@ var TUI_ONLY_SETTINGS = /* @__PURE__ */ new Set([
|
|
|
22099
22720
|
"ui.accessibility.enableLoadingPhrases",
|
|
22100
22721
|
"ui.enableWelcomeBack"
|
|
22101
22722
|
]);
|
|
22102
|
-
var WEB_SHELL_SETTINGS = /* @__PURE__ */ new Set([
|
|
22723
|
+
var WEB_SHELL_SETTINGS = /* @__PURE__ */ new Set([
|
|
22724
|
+
"ui.compactMode",
|
|
22725
|
+
"voiceModel",
|
|
22726
|
+
"mcpServers"
|
|
22727
|
+
]);
|
|
22103
22728
|
var VALID_WRITE_SCOPES = /* @__PURE__ */ new Set(["workspace", "user"]);
|
|
22104
22729
|
var QUALIFIED_WRITE_SCOPES = /* @__PURE__ */ new Set(["workspace"]);
|
|
22730
|
+
var mcpServerMutationQueues = /* @__PURE__ */ new Map();
|
|
22105
22731
|
var SECURITY_SENSITIVE_SETTINGS = /* @__PURE__ */ new Set(["tools.approvalMode"]);
|
|
22106
22732
|
function getAllowedKeys() {
|
|
22107
22733
|
const keys = new Set(
|
|
@@ -22133,11 +22759,12 @@ function buildSettingsResponse(boundWorkspace, keys) {
|
|
|
22133
22759
|
loaded.workspace.settings,
|
|
22134
22760
|
key
|
|
22135
22761
|
);
|
|
22762
|
+
const publicValue = /* @__PURE__ */ __name((value) => key === "mcpServers" ? redactMcpServersSetting(value) : value, "publicValue");
|
|
22136
22763
|
const values = {
|
|
22137
|
-
effective: effective !== void 0 ? effective : def.default
|
|
22764
|
+
effective: publicValue(effective !== void 0 ? effective : def.default)
|
|
22138
22765
|
};
|
|
22139
|
-
if (userVal !== void 0) values.user = userVal;
|
|
22140
|
-
if (wsVal !== void 0) values.workspace = wsVal;
|
|
22766
|
+
if (userVal !== void 0) values.user = publicValue(userVal);
|
|
22767
|
+
if (wsVal !== void 0) values.workspace = publicValue(wsVal);
|
|
22141
22768
|
settings.push({
|
|
22142
22769
|
key,
|
|
22143
22770
|
type: def.type,
|
|
@@ -22165,9 +22792,62 @@ function buildSettingsResponse(boundWorkspace, keys) {
|
|
|
22165
22792
|
}
|
|
22166
22793
|
__name(buildSettingsResponse, "buildSettingsResponse");
|
|
22167
22794
|
var SCOPE_MAP = {
|
|
22168
|
-
|
|
22169
|
-
|
|
22795
|
+
user: "User" /* User */,
|
|
22796
|
+
workspace: "Workspace" /* Workspace */
|
|
22170
22797
|
};
|
|
22798
|
+
function prepareSettingWrite(workspace, scope, key, value, mcpServerMutation) {
|
|
22799
|
+
if (key !== "mcpServers") {
|
|
22800
|
+
return { persistedValue: value, publicValue: value };
|
|
22801
|
+
}
|
|
22802
|
+
const existing = loadSettings(workspace).forScope(scope).settings.mcpServers ?? {};
|
|
22803
|
+
let nextValue = value;
|
|
22804
|
+
if (mcpServerMutation) {
|
|
22805
|
+
const servers = { ...existing };
|
|
22806
|
+
if (mcpServerMutation.operation === "set") {
|
|
22807
|
+
servers[mcpServerMutation.name] = value;
|
|
22808
|
+
} else {
|
|
22809
|
+
delete servers[mcpServerMutation.name];
|
|
22810
|
+
}
|
|
22811
|
+
nextValue = servers;
|
|
22812
|
+
}
|
|
22813
|
+
const persistedValue = restoreRedactedMcpServersSetting(nextValue, existing);
|
|
22814
|
+
return {
|
|
22815
|
+
persistedValue,
|
|
22816
|
+
publicValue: redactMcpServersSetting(persistedValue)
|
|
22817
|
+
};
|
|
22818
|
+
}
|
|
22819
|
+
__name(prepareSettingWrite, "prepareSettingWrite");
|
|
22820
|
+
function parseMcpServerMutation(key, value) {
|
|
22821
|
+
if (value === void 0) return void 0;
|
|
22822
|
+
if (key !== "mcpServers" || typeof value !== "object" || value === null) {
|
|
22823
|
+
throw new Error("mcpServerMutation is only valid for mcpServers");
|
|
22824
|
+
}
|
|
22825
|
+
const operation = value["operation"];
|
|
22826
|
+
const name = value["name"];
|
|
22827
|
+
if (operation !== "set" && operation !== "remove" || typeof name !== "string" || !name.trim()) {
|
|
22828
|
+
throw new Error("mcpServerMutation requires a valid operation and name");
|
|
22829
|
+
}
|
|
22830
|
+
return { operation, name };
|
|
22831
|
+
}
|
|
22832
|
+
__name(parseMcpServerMutation, "parseMcpServerMutation");
|
|
22833
|
+
async function withMcpServerMutationLock(workspace, scope, operation) {
|
|
22834
|
+
const key = `${workspace}\0${scope}`;
|
|
22835
|
+
const previous = mcpServerMutationQueues.get(key) ?? Promise.resolve();
|
|
22836
|
+
const run = previous.catch(() => void 0).then(operation);
|
|
22837
|
+
const tail = run.then(
|
|
22838
|
+
() => void 0,
|
|
22839
|
+
() => void 0
|
|
22840
|
+
);
|
|
22841
|
+
mcpServerMutationQueues.set(key, tail);
|
|
22842
|
+
try {
|
|
22843
|
+
return await run;
|
|
22844
|
+
} finally {
|
|
22845
|
+
if (mcpServerMutationQueues.get(key) === tail) {
|
|
22846
|
+
mcpServerMutationQueues.delete(key);
|
|
22847
|
+
}
|
|
22848
|
+
}
|
|
22849
|
+
}
|
|
22850
|
+
__name(withMcpServerMutationLock, "withMcpServerMutationLock");
|
|
22171
22851
|
function registerWorkspaceSettingsRoutes(app, deps) {
|
|
22172
22852
|
const {
|
|
22173
22853
|
boundWorkspace,
|
|
@@ -22200,6 +22880,19 @@ function registerWorkspaceSettingsRoutes(app, deps) {
|
|
|
22200
22880
|
const scope = body["scope"];
|
|
22201
22881
|
const key = body["key"];
|
|
22202
22882
|
const value = body["value"];
|
|
22883
|
+
let mcpServerMutation;
|
|
22884
|
+
try {
|
|
22885
|
+
mcpServerMutation = parseMcpServerMutation(
|
|
22886
|
+
typeof key === "string" ? key : "",
|
|
22887
|
+
body["mcpServerMutation"]
|
|
22888
|
+
);
|
|
22889
|
+
} catch (error2) {
|
|
22890
|
+
res.status(400).json({
|
|
22891
|
+
error: error2 instanceof Error ? error2.message : String(error2),
|
|
22892
|
+
code: "invalid_mcp_server_mutation"
|
|
22893
|
+
});
|
|
22894
|
+
return;
|
|
22895
|
+
}
|
|
22203
22896
|
if (typeof scope !== "string" || !VALID_WRITE_SCOPES.has(scope)) {
|
|
22204
22897
|
res.status(400).json({
|
|
22205
22898
|
error: `scope must be one of: ${[...VALID_WRITE_SCOPES].join(", ")}`,
|
|
@@ -22246,16 +22939,41 @@ function registerWorkspaceSettingsRoutes(app, deps) {
|
|
|
22246
22939
|
}
|
|
22247
22940
|
const clientId = parseAndValidateClientId(req, res);
|
|
22248
22941
|
if (clientId === null) return;
|
|
22942
|
+
const settingScope = SCOPE_MAP[scope];
|
|
22943
|
+
if (!settingScope) {
|
|
22944
|
+
res.status(400).json({
|
|
22945
|
+
error: `scope must be one of: ${[...VALID_WRITE_SCOPES].join(", ")}`,
|
|
22946
|
+
code: "invalid_scope"
|
|
22947
|
+
});
|
|
22948
|
+
return;
|
|
22949
|
+
}
|
|
22950
|
+
let publicValue = value;
|
|
22249
22951
|
try {
|
|
22250
|
-
const
|
|
22251
|
-
|
|
22252
|
-
|
|
22253
|
-
|
|
22254
|
-
|
|
22255
|
-
|
|
22256
|
-
|
|
22952
|
+
const persist = /* @__PURE__ */ __name(async () => {
|
|
22953
|
+
const prepared = prepareSettingWrite(
|
|
22954
|
+
boundWorkspace,
|
|
22955
|
+
settingScope,
|
|
22956
|
+
key,
|
|
22957
|
+
value,
|
|
22958
|
+
mcpServerMutation
|
|
22959
|
+
);
|
|
22960
|
+
publicValue = prepared.publicValue;
|
|
22961
|
+
await persistSetting(
|
|
22962
|
+
boundWorkspace,
|
|
22963
|
+
settingScope,
|
|
22964
|
+
key,
|
|
22965
|
+
prepared.persistedValue
|
|
22966
|
+
);
|
|
22967
|
+
}, "persist");
|
|
22968
|
+
if (mcpServerMutation) {
|
|
22969
|
+
await withMcpServerMutationLock(
|
|
22970
|
+
boundWorkspace,
|
|
22971
|
+
settingScope,
|
|
22972
|
+
persist
|
|
22973
|
+
);
|
|
22974
|
+
} else {
|
|
22975
|
+
await persist();
|
|
22257
22976
|
}
|
|
22258
|
-
await persistSetting(boundWorkspace, settingScope, key, value);
|
|
22259
22977
|
} catch (err) {
|
|
22260
22978
|
writeStderrLine(
|
|
22261
22979
|
`qwen serve: POST /workspace/settings persist error (key=${key}, scope=${scope}, workspace=${boundWorkspace}): ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -22267,7 +22985,7 @@ function registerWorkspaceSettingsRoutes(app, deps) {
|
|
|
22267
22985
|
return;
|
|
22268
22986
|
}
|
|
22269
22987
|
try {
|
|
22270
|
-
broadcastSettingsChanged(key,
|
|
22988
|
+
broadcastSettingsChanged(key, publicValue, scope, clientId);
|
|
22271
22989
|
} catch (err) {
|
|
22272
22990
|
writeStderrLine(
|
|
22273
22991
|
`qwen serve: POST /workspace/settings broadcast error (key=${key}, scope=${scope}): ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -22276,7 +22994,7 @@ function registerWorkspaceSettingsRoutes(app, deps) {
|
|
|
22276
22994
|
res.status(200).json({
|
|
22277
22995
|
key,
|
|
22278
22996
|
scope,
|
|
22279
|
-
value,
|
|
22997
|
+
value: publicValue,
|
|
22280
22998
|
requiresRestart: def.requiresRestart
|
|
22281
22999
|
});
|
|
22282
23000
|
}
|
|
@@ -22319,6 +23037,19 @@ function registerWorkspaceQualifiedSettingsRoutes(app, deps) {
|
|
|
22319
23037
|
const scope = body["scope"];
|
|
22320
23038
|
const key = body["key"];
|
|
22321
23039
|
const value = body["value"];
|
|
23040
|
+
let mcpServerMutation;
|
|
23041
|
+
try {
|
|
23042
|
+
mcpServerMutation = parseMcpServerMutation(
|
|
23043
|
+
typeof key === "string" ? key : "",
|
|
23044
|
+
body["mcpServerMutation"]
|
|
23045
|
+
);
|
|
23046
|
+
} catch (error2) {
|
|
23047
|
+
res.status(400).json({
|
|
23048
|
+
error: error2 instanceof Error ? error2.message : String(error2),
|
|
23049
|
+
code: "invalid_mcp_server_mutation"
|
|
23050
|
+
});
|
|
23051
|
+
return;
|
|
23052
|
+
}
|
|
22322
23053
|
if (typeof scope !== "string" || !QUALIFIED_WRITE_SCOPES.has(scope)) {
|
|
22323
23054
|
res.status(400).json({
|
|
22324
23055
|
error: `scope must be one of: ${[...QUALIFIED_WRITE_SCOPES].join(", ")}`,
|
|
@@ -22377,13 +23108,33 @@ function registerWorkspaceQualifiedSettingsRoutes(app, deps) {
|
|
|
22377
23108
|
});
|
|
22378
23109
|
return;
|
|
22379
23110
|
}
|
|
23111
|
+
let publicValue = value;
|
|
22380
23112
|
try {
|
|
22381
|
-
|
|
22382
|
-
|
|
22383
|
-
|
|
22384
|
-
|
|
22385
|
-
|
|
22386
|
-
|
|
23113
|
+
const persist = /* @__PURE__ */ __name(async () => {
|
|
23114
|
+
const prepared = prepareSettingWrite(
|
|
23115
|
+
runtime.workspaceCwd,
|
|
23116
|
+
settingScope,
|
|
23117
|
+
key,
|
|
23118
|
+
value,
|
|
23119
|
+
mcpServerMutation
|
|
23120
|
+
);
|
|
23121
|
+
publicValue = prepared.publicValue;
|
|
23122
|
+
await deps.persistSetting(
|
|
23123
|
+
runtime.workspaceCwd,
|
|
23124
|
+
settingScope,
|
|
23125
|
+
key,
|
|
23126
|
+
prepared.persistedValue
|
|
23127
|
+
);
|
|
23128
|
+
}, "persist");
|
|
23129
|
+
if (mcpServerMutation) {
|
|
23130
|
+
await withMcpServerMutationLock(
|
|
23131
|
+
runtime.workspaceCwd,
|
|
23132
|
+
settingScope,
|
|
23133
|
+
persist
|
|
23134
|
+
);
|
|
23135
|
+
} else {
|
|
23136
|
+
await persist();
|
|
23137
|
+
}
|
|
22387
23138
|
} catch (err) {
|
|
22388
23139
|
writeStderrLine(
|
|
22389
23140
|
`qwen serve: POST /workspaces/:workspace/settings persist error (key=${key}, scope=${scope}, workspace=${runtime.workspaceCwd}): ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -22397,13 +23148,13 @@ function registerWorkspaceQualifiedSettingsRoutes(app, deps) {
|
|
|
22397
23148
|
deps.invalidateServeFeaturesCache();
|
|
22398
23149
|
runtime.bridge.publishWorkspaceEvent({
|
|
22399
23150
|
type: "settings_changed",
|
|
22400
|
-
data: { key, value, scope },
|
|
23151
|
+
data: { key, value: publicValue, scope },
|
|
22401
23152
|
...clientId ? { originatorClientId: clientId } : {}
|
|
22402
23153
|
});
|
|
22403
23154
|
res.status(200).json({
|
|
22404
23155
|
key,
|
|
22405
23156
|
scope,
|
|
22406
|
-
value,
|
|
23157
|
+
value: publicValue,
|
|
22407
23158
|
requiresRestart: def.requiresRestart
|
|
22408
23159
|
});
|
|
22409
23160
|
}
|
|
@@ -22621,6 +23372,14 @@ function sendBridgeError(res, err, ctx, daemonLog) {
|
|
|
22621
23372
|
});
|
|
22622
23373
|
return;
|
|
22623
23374
|
}
|
|
23375
|
+
if (err instanceof SessionNotArchivedError) {
|
|
23376
|
+
res.status(409).json({
|
|
23377
|
+
error: err.message,
|
|
23378
|
+
code: "session_not_archived",
|
|
23379
|
+
sessionId: err.sessionId
|
|
23380
|
+
});
|
|
23381
|
+
return;
|
|
23382
|
+
}
|
|
22624
23383
|
if (err instanceof SessionConflictError) {
|
|
22625
23384
|
res.status(409).json({
|
|
22626
23385
|
error: err.message,
|
|
@@ -22674,7 +23433,7 @@ function sendBridgeError(res, err, ctx, daemonLog) {
|
|
|
22674
23433
|
}
|
|
22675
23434
|
if (err instanceof WorkspaceMismatchError) {
|
|
22676
23435
|
writeStderrLine(
|
|
22677
|
-
`qwen serve: workspace_mismatch (POST /session):
|
|
23436
|
+
`qwen serve: workspace_mismatch (POST /session): runtime bound to ${JSON.stringify(err.bound)}, rejected ${JSON.stringify(err.requested)}`
|
|
22678
23437
|
);
|
|
22679
23438
|
res.status(400).json({
|
|
22680
23439
|
error: err.message,
|
|
@@ -23774,6 +24533,15 @@ function resolveDaemonTelemetryRoute(req) {
|
|
|
23774
24533
|
sessionId: workspaceExport[1]
|
|
23775
24534
|
};
|
|
23776
24535
|
}
|
|
24536
|
+
const workspaceArchivedExport = path15.match(
|
|
24537
|
+
/^\/workspaces\/[^/]+\/session\/([^/]+)\/archive\/export$/
|
|
24538
|
+
);
|
|
24539
|
+
if (workspaceArchivedExport?.[1] && req.method === "GET") {
|
|
24540
|
+
return {
|
|
24541
|
+
route: "GET /workspaces/:workspace/session/:id/archive/export",
|
|
24542
|
+
sessionId: workspaceArchivedExport[1]
|
|
24543
|
+
};
|
|
24544
|
+
}
|
|
23777
24545
|
const pluralWorkspacePrefix = /^\/workspaces\/[^/]+/;
|
|
23778
24546
|
if (pluralWorkspacePrefix.test(path15)) {
|
|
23779
24547
|
const suffix = path15.replace(pluralWorkspacePrefix, "/workspace");
|
|
@@ -23811,7 +24579,7 @@ function resolveDaemonTelemetryRoute(req) {
|
|
|
23811
24579
|
if (/^\/workspace\/agents\/[^/]+$/.test(suffix)) {
|
|
23812
24580
|
return { route: "POST /workspace/agents/:agentType" };
|
|
23813
24581
|
}
|
|
23814
|
-
if (/^\/workspace\/mcp\/[^/]+\/(enable|disable|authenticate|clear-auth)$/.test(
|
|
24582
|
+
if (/^\/workspace\/mcp\/[^/]+\/(approve|enable|disable|authenticate|clear-auth)$/.test(
|
|
23815
24583
|
suffix
|
|
23816
24584
|
)) {
|
|
23817
24585
|
return {
|
|
@@ -23913,7 +24681,8 @@ function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSe
|
|
|
23913
24681
|
const workspaceHash = resolveWorkspaceHash(workspaceCwd);
|
|
23914
24682
|
const rawClientId = req.get(CLIENT_ID_HEADER);
|
|
23915
24683
|
const clientId = rawClientId !== void 0 && rawClientId !== "" && rawClientId.length <= MAX_CLIENT_ID_LENGTH && CLIENT_ID_RE.test(rawClientId) ? rawClientId : void 0;
|
|
23916
|
-
const
|
|
24684
|
+
const deferredRuntime = getDeferredRuntimeRequestTiming(req);
|
|
24685
|
+
const startMs = deferredRuntime?.startedAt.getTime() ?? Date.now();
|
|
23917
24686
|
void withDaemonRequestSpan(
|
|
23918
24687
|
{
|
|
23919
24688
|
method: req.method,
|
|
@@ -23921,7 +24690,12 @@ function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSe
|
|
|
23921
24690
|
workspaceHash,
|
|
23922
24691
|
...sessionId ? { sessionId } : {},
|
|
23923
24692
|
...route.permissionRequestId ? { permissionRequestId: route.permissionRequestId } : {},
|
|
23924
|
-
...clientId ? { clientId } : {}
|
|
24693
|
+
...clientId ? { clientId } : {},
|
|
24694
|
+
...deferredRuntime?.waitMs !== void 0 ? {
|
|
24695
|
+
startTime: deferredRuntime.startedAt,
|
|
24696
|
+
deferredRuntimeWaitMs: deferredRuntime.waitMs,
|
|
24697
|
+
deferredRuntimePath: deferredRuntime.path
|
|
24698
|
+
} : {}
|
|
23925
24699
|
},
|
|
23926
24700
|
async (span) => await new Promise((resolve5, reject) => {
|
|
23927
24701
|
let done = false;
|
|
@@ -23930,7 +24704,12 @@ function daemonTelemetryMiddleware(resolveWorkspaceCwd, recordRequest, resolveSe
|
|
|
23930
24704
|
done = true;
|
|
23931
24705
|
recordDaemonHttpResponse(span, res.statusCode);
|
|
23932
24706
|
const durationMs = Date.now() - startMs;
|
|
23933
|
-
recordDaemonHttpRequest(
|
|
24707
|
+
recordDaemonHttpRequest(
|
|
24708
|
+
durationMs,
|
|
24709
|
+
route.route,
|
|
24710
|
+
res.statusCode,
|
|
24711
|
+
deferredRuntime?.path
|
|
24712
|
+
);
|
|
23934
24713
|
if (route.route !== "GET /daemon/status") {
|
|
23935
24714
|
recordRequest?.(durationMs, res.statusCode);
|
|
23936
24715
|
}
|
|
@@ -25330,6 +26109,30 @@ function registerWorkspaceMcpControlRoutes(app, deps) {
|
|
|
25330
26109
|
parseAndValidateClientId
|
|
25331
26110
|
} = deps;
|
|
25332
26111
|
const buildWorkspaceCtx = createBuildWorkspaceCtx(boundWorkspace);
|
|
26112
|
+
app.post(
|
|
26113
|
+
"/workspace/mcp/initialize",
|
|
26114
|
+
mutate({ strict: true }),
|
|
26115
|
+
async (_req, res) => {
|
|
26116
|
+
try {
|
|
26117
|
+
const result = await bridge.initializeWorkspaceMcp();
|
|
26118
|
+
res.status(202).json(result);
|
|
26119
|
+
} catch (err) {
|
|
26120
|
+
sendBridgeError2(res, err, { route: "POST /workspace/mcp/initialize" });
|
|
26121
|
+
}
|
|
26122
|
+
}
|
|
26123
|
+
);
|
|
26124
|
+
app.post(
|
|
26125
|
+
"/workspace/mcp/reload",
|
|
26126
|
+
mutate({ strict: true }),
|
|
26127
|
+
async (_req, res) => {
|
|
26128
|
+
try {
|
|
26129
|
+
const result = await bridge.reloadWorkspaceMcp();
|
|
26130
|
+
res.status(202).json(result);
|
|
26131
|
+
} catch (err) {
|
|
26132
|
+
sendBridgeError2(res, err, { route: "POST /workspace/mcp/reload" });
|
|
26133
|
+
}
|
|
26134
|
+
}
|
|
26135
|
+
);
|
|
25333
26136
|
app.post(
|
|
25334
26137
|
"/workspace/mcp/:server/restart",
|
|
25335
26138
|
mutate({ strict: true }),
|
|
@@ -25384,6 +26187,7 @@ function registerWorkspaceMcpControlRoutes(app, deps) {
|
|
|
25384
26187
|
}
|
|
25385
26188
|
);
|
|
25386
26189
|
for (const [routeAction, bridgeAction] of [
|
|
26190
|
+
["approve", "approve"],
|
|
25387
26191
|
["enable", "enable"],
|
|
25388
26192
|
["disable", "disable"],
|
|
25389
26193
|
["authenticate", "authenticate"],
|
|
@@ -25498,6 +26302,44 @@ function resolveTrustedMcpRuntime(registry, req, res) {
|
|
|
25498
26302
|
}
|
|
25499
26303
|
__name(resolveTrustedMcpRuntime, "resolveTrustedMcpRuntime");
|
|
25500
26304
|
function registerWorkspaceQualifiedMcpControlRoutes(app, deps) {
|
|
26305
|
+
app.post(
|
|
26306
|
+
"/workspaces/:workspace/mcp/initialize",
|
|
26307
|
+
deps.mutate({ strict: true }),
|
|
26308
|
+
async (req, res) => {
|
|
26309
|
+
const runtime = resolveTrustedMcpRuntime(
|
|
26310
|
+
deps.workspaceRegistry,
|
|
26311
|
+
req,
|
|
26312
|
+
res
|
|
26313
|
+
);
|
|
26314
|
+
if (!runtime) return;
|
|
26315
|
+
const route = "POST /workspaces/:workspace/mcp/initialize";
|
|
26316
|
+
try {
|
|
26317
|
+
const result = await runtime.bridge.initializeWorkspaceMcp();
|
|
26318
|
+
res.status(202).json(result);
|
|
26319
|
+
} catch (err) {
|
|
26320
|
+
deps.sendBridgeError(res, err, { route });
|
|
26321
|
+
}
|
|
26322
|
+
}
|
|
26323
|
+
);
|
|
26324
|
+
app.post(
|
|
26325
|
+
"/workspaces/:workspace/mcp/reload",
|
|
26326
|
+
deps.mutate({ strict: true }),
|
|
26327
|
+
async (req, res) => {
|
|
26328
|
+
const runtime = resolveTrustedMcpRuntime(
|
|
26329
|
+
deps.workspaceRegistry,
|
|
26330
|
+
req,
|
|
26331
|
+
res
|
|
26332
|
+
);
|
|
26333
|
+
if (!runtime) return;
|
|
26334
|
+
const route = "POST /workspaces/:workspace/mcp/reload";
|
|
26335
|
+
try {
|
|
26336
|
+
const result = await runtime.bridge.reloadWorkspaceMcp();
|
|
26337
|
+
res.status(202).json(result);
|
|
26338
|
+
} catch (err) {
|
|
26339
|
+
deps.sendBridgeError(res, err, { route });
|
|
26340
|
+
}
|
|
26341
|
+
}
|
|
26342
|
+
);
|
|
25501
26343
|
app.post(
|
|
25502
26344
|
"/workspaces/:workspace/mcp/:server/restart",
|
|
25503
26345
|
deps.mutate({ strict: true }),
|
|
@@ -25561,6 +26403,7 @@ function registerWorkspaceQualifiedMcpControlRoutes(app, deps) {
|
|
|
25561
26403
|
}
|
|
25562
26404
|
);
|
|
25563
26405
|
for (const [routeAction, bridgeAction] of [
|
|
26406
|
+
["approve", "approve"],
|
|
25564
26407
|
["enable", "enable"],
|
|
25565
26408
|
["disable", "disable"],
|
|
25566
26409
|
["authenticate", "authenticate"],
|
|
@@ -25752,11 +26595,84 @@ function parseSelection(body, res) {
|
|
|
25752
26595
|
}
|
|
25753
26596
|
}
|
|
25754
26597
|
__name(parseSelection, "parseSelection");
|
|
26598
|
+
function sanitizeControlDiagnostic(value, maxLength) {
|
|
26599
|
+
return sanitizeLogText(
|
|
26600
|
+
redactLogCredentials(normalizeWorkerDiagnostic(value)),
|
|
26601
|
+
maxLength
|
|
26602
|
+
);
|
|
26603
|
+
}
|
|
26604
|
+
__name(sanitizeControlDiagnostic, "sanitizeControlDiagnostic");
|
|
26605
|
+
function startupFailureResponseFields(error2) {
|
|
26606
|
+
if (!error2 || typeof error2 !== "object") return {};
|
|
26607
|
+
let rawFailures;
|
|
26608
|
+
let rawTruncated;
|
|
26609
|
+
try {
|
|
26610
|
+
rawFailures = Reflect.get(error2, "startupFailures");
|
|
26611
|
+
rawTruncated = Reflect.get(error2, "startupFailuresTruncated");
|
|
26612
|
+
} catch {
|
|
26613
|
+
return {};
|
|
26614
|
+
}
|
|
26615
|
+
if (!Array.isArray(rawFailures)) return {};
|
|
26616
|
+
let limitedFailures;
|
|
26617
|
+
let rawFailureCount;
|
|
26618
|
+
try {
|
|
26619
|
+
limitedFailures = rawFailures.slice(0, MAX_CHANNEL_STARTUP_FAILURES);
|
|
26620
|
+
rawFailureCount = rawFailures.length;
|
|
26621
|
+
} catch {
|
|
26622
|
+
return {};
|
|
26623
|
+
}
|
|
26624
|
+
const startupFailures = limitedFailures.flatMap((raw) => {
|
|
26625
|
+
try {
|
|
26626
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return [];
|
|
26627
|
+
const failure = raw;
|
|
26628
|
+
if (typeof failure["workspaceCwd"] !== "string" || failure["workspaceCwd"].length === 0 || typeof failure["channel"] !== "string" || failure["channel"].length === 0 || failure["phase"] !== "connect" || typeof failure["message"] !== "string" || failure["message"].length === 0 || failure["code"] !== void 0 && (typeof failure["code"] !== "string" || failure["code"].length === 0)) {
|
|
26629
|
+
return [];
|
|
26630
|
+
}
|
|
26631
|
+
const workspaceCwd = sanitizeControlDiagnostic(
|
|
26632
|
+
failure["workspaceCwd"],
|
|
26633
|
+
MAX_WORKSPACE_PATH_LENGTH
|
|
26634
|
+
);
|
|
26635
|
+
const channel = sanitizeControlDiagnostic(
|
|
26636
|
+
failure["channel"],
|
|
26637
|
+
MAX_CHANNEL_STARTUP_FAILURE_CHANNEL_LENGTH
|
|
26638
|
+
);
|
|
26639
|
+
const message = sanitizeControlDiagnostic(
|
|
26640
|
+
failure["message"],
|
|
26641
|
+
MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH
|
|
26642
|
+
);
|
|
26643
|
+
const code = typeof failure["code"] === "string" ? sanitizeControlDiagnostic(
|
|
26644
|
+
failure["code"],
|
|
26645
|
+
MAX_CHANNEL_STARTUP_FAILURE_CODE_LENGTH
|
|
26646
|
+
) : void 0;
|
|
26647
|
+
if (!workspaceCwd || !channel || !message) return [];
|
|
26648
|
+
return [
|
|
26649
|
+
{
|
|
26650
|
+
workspaceCwd,
|
|
26651
|
+
channel,
|
|
26652
|
+
phase: "connect",
|
|
26653
|
+
...code ? { code } : {},
|
|
26654
|
+
message
|
|
26655
|
+
}
|
|
26656
|
+
];
|
|
26657
|
+
} catch {
|
|
26658
|
+
return [];
|
|
26659
|
+
}
|
|
26660
|
+
});
|
|
26661
|
+
if (startupFailures.length === 0) return {};
|
|
26662
|
+
const truncated = rawTruncated === true || rawFailureCount > MAX_CHANNEL_STARTUP_FAILURES;
|
|
26663
|
+
return {
|
|
26664
|
+
startupFailures,
|
|
26665
|
+
...truncated ? { startupFailuresTruncated: true } : {}
|
|
26666
|
+
};
|
|
26667
|
+
}
|
|
26668
|
+
__name(startupFailureResponseFields, "startupFailureResponseFields");
|
|
25755
26669
|
function sendChannelControlError(res, error2, getState) {
|
|
25756
26670
|
const code = error2 && typeof error2 === "object" && "code" in error2 ? error2.code : void 0;
|
|
25757
|
-
const
|
|
25758
|
-
|
|
25759
|
-
|
|
26671
|
+
const rawMessage = error2 instanceof Error ? error2.message : String(error2);
|
|
26672
|
+
const message = code === "channel_worker_start_failed" ? sanitizeControlDiagnostic(
|
|
26673
|
+
rawMessage,
|
|
26674
|
+
MAX_CHANNEL_STARTUP_FAILURE_MESSAGE_LENGTH
|
|
26675
|
+
) : redactLogCredentials(rawMessage);
|
|
25760
26676
|
if (code === "channel_workspace_mismatch" || code === "ambiguous_channel_workspace") {
|
|
25761
26677
|
res.status(400).json({ error: message, code });
|
|
25762
26678
|
return true;
|
|
@@ -25792,7 +26708,13 @@ function sendChannelControlError(res, error2, getState) {
|
|
|
25792
26708
|
error: message,
|
|
25793
26709
|
code,
|
|
25794
26710
|
...typeof controlError.rolledBack === "boolean" ? { rolledBack: controlError.rolledBack } : {},
|
|
25795
|
-
...typeof controlError.rollbackError === "string" && controlError.rollbackError ? {
|
|
26711
|
+
...typeof controlError.rollbackError === "string" && controlError.rollbackError ? {
|
|
26712
|
+
rollbackError: sanitizeControlDiagnostic(
|
|
26713
|
+
controlError.rollbackError,
|
|
26714
|
+
512
|
|
26715
|
+
)
|
|
26716
|
+
} : {},
|
|
26717
|
+
...code === "channel_worker_start_failed" ? startupFailureResponseFields(error2) : {},
|
|
25796
26718
|
state: getState()
|
|
25797
26719
|
});
|
|
25798
26720
|
return true;
|
|
@@ -26525,6 +27447,12 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
26525
27447
|
boundWorkspace,
|
|
26526
27448
|
persistSettingAvailable: deps.persistSetting !== void 0,
|
|
26527
27449
|
sessionArtifactsPersistenceAvailable: deps.sessionArtifactsPersistenceAvailable !== false,
|
|
27450
|
+
sessionGenerationAvailable: /* @__PURE__ */ __name(() => {
|
|
27451
|
+
const runtimes = workspaceRegistry.list();
|
|
27452
|
+
return runtimes.length > 0 && runtimes.every(
|
|
27453
|
+
(runtime) => runtime.bridge.generateSessionContent !== void 0
|
|
27454
|
+
);
|
|
27455
|
+
}, "sessionGenerationAvailable"),
|
|
26528
27456
|
// Registry injection supplies the primary workspace service through the
|
|
26529
27457
|
// runtime, so it has the same reload surface as legacy deps.workspace.
|
|
26530
27458
|
reloadAvailable: deps.workspace !== void 0 || injectedWorkspaceRegistry !== void 0,
|
|
@@ -26653,6 +27581,8 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
26653
27581
|
);
|
|
26654
27582
|
app.locals.workspaceRegistry = workspaceRegistry;
|
|
26655
27583
|
const primaryRuntime = workspaceRegistry.primary;
|
|
27584
|
+
const daemonEnv = deps.daemonEnv ?? process.env;
|
|
27585
|
+
const primaryRuntimeEffectiveEnv = getRuntimeEffectiveEnv(primaryRuntime.env) ?? daemonEnv;
|
|
26656
27586
|
const voiceCoordinator = deps.voiceCoordinator ?? new WorkspaceVoiceCoordinator();
|
|
26657
27587
|
const primaryBoundWorkspace = primaryRuntime.workspaceCwd;
|
|
26658
27588
|
const primaryBridge = primaryRuntime.bridge;
|
|
@@ -26681,7 +27611,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
26681
27611
|
const healthDemoRoutes = createHealthDemoRoutes({
|
|
26682
27612
|
opts,
|
|
26683
27613
|
getPort,
|
|
26684
|
-
|
|
27614
|
+
workspaceRegistry,
|
|
26685
27615
|
getActiveSseCount,
|
|
26686
27616
|
getRateLimiter: /* @__PURE__ */ __name(() => rateLimiter, "getRateLimiter")
|
|
26687
27617
|
});
|
|
@@ -26915,6 +27845,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
26915
27845
|
registerWorkspaceSetupGithubRoutes(app, {
|
|
26916
27846
|
boundWorkspace: primaryBoundWorkspace,
|
|
26917
27847
|
bridge: primaryBridge,
|
|
27848
|
+
env: primaryRuntimeEffectiveEnv,
|
|
26918
27849
|
mutate,
|
|
26919
27850
|
parseClientId: parseClientIdHeader,
|
|
26920
27851
|
safeBody
|
|
@@ -27211,6 +28142,7 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
27211
28142
|
});
|
|
27212
28143
|
acpHandleRef.current = mountAcpHttp(app, primaryBridge, {
|
|
27213
28144
|
boundWorkspace: primaryBoundWorkspace,
|
|
28145
|
+
daemonEnv,
|
|
27214
28146
|
// Phase 4 (issue #6378): pass the registry so `/workspaces/:workspace/acp`
|
|
27215
28147
|
// mounts a per-runtime ACP dispatcher for each registered workspace.
|
|
27216
28148
|
workspaceRegistry,
|