@qwen-code/qwen-code 0.19.7-nightly.20260708.394c1a289 → 0.19.8
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/features/channels/overview.md +6 -3
- package/bundled/qc-helper/docs/features/channels/plugins.md +1 -0
- package/bundled/qc-helper/docs/features/hooks.md +36 -34
- package/bundled/qc-helper/docs/features/memory.md +1 -1
- package/bundled/qc-helper/docs/qwen-serve.md +17 -10
- package/bundled/review/SKILL.md +6 -2
- package/chunks/{MaxSizedBox-XS37LWTD.js → MaxSizedBox-5DT2SD7B.js} +7 -7
- package/chunks/{StandaloneSessionPicker-LPALJTKN.js → StandaloneSessionPicker-EYRGH6PJ.js} +23 -21
- package/chunks/{acpAgent-4VE3FGJX.js → acpAgent-GRFTTRHW.js} +74 -69
- package/chunks/{agent-CCHERW6L.js → agent-H2DGKS77.js} +4 -4
- package/chunks/{agent-headless-55N6UBUU.js → agent-headless-KFMFIT6J.js} +4 -4
- package/chunks/{anthropicContentGenerator-AKYPSZIV.js → anthropicContentGenerator-CPF22MA7.js} +28 -1
- package/chunks/{bridge-U6HXOHE7.js → bridge-NA3ZQQKJ.js} +11 -10
- package/chunks/{ca-HCMB2I54.js → ca-MKD32FQL.js} +26 -1
- package/chunks/{channel-worker-supervisor-CRCVYQIE.js → channel-worker-supervisor-NZQUOEFJ.js} +3 -3
- package/chunks/{chunk-J43WPR6U.js → chunk-27BHARDE.js} +8 -8
- package/chunks/{chunk-KKWO4IX2.js → chunk-2EM7ECZD.js} +251 -71
- package/chunks/{chunk-E7HM76PR.js → chunk-3GNOQZDC.js} +1562 -1025
- package/chunks/{chunk-G7ZG7CA6.js → chunk-3UP777ZS.js} +8 -7
- package/chunks/{chunk-VEB3NYSO.js → chunk-5MBO76SL.js} +5 -0
- package/chunks/{chunk-N74BA4VP.js → chunk-6VK6FIMQ.js} +1 -1
- package/chunks/{chunk-2FHWCKWA.js → chunk-A5JOJ77H.js} +35 -14
- package/chunks/{chunk-PLGONYEL.js → chunk-AYNCLGTW.js} +5 -5
- package/chunks/{chunk-K34DD7FH.js → chunk-BOBOCR5H.js} +4 -3
- package/chunks/chunk-BOBRZZKD.js +468 -0
- package/chunks/{chunk-7I4MGFBN.js → chunk-BUZ6HGL4.js} +5 -5
- package/chunks/{chunk-FK77ILF5.js → chunk-BVYU3ZTI.js} +2 -2
- package/chunks/{chunk-TBAZMRW3.js → chunk-CD6USWHZ.js} +1 -1
- package/chunks/{chunk-PVXPDMGP.js → chunk-CHB5SLZZ.js} +2 -2
- package/chunks/{chunk-SJHAUELE.js → chunk-DCZWC4PF.js} +2 -2
- package/chunks/{chunk-YYU6H66M.js → chunk-DHOLNQLC.js} +11 -11
- package/chunks/{chunk-MOQOAH7N.js → chunk-DICGXFAI.js} +1 -1
- package/chunks/{chunk-KT3SI3CQ.js → chunk-DIWVZ3VM.js} +8 -8
- package/chunks/{chunk-2DYY5XUZ.js → chunk-E7EMCSUG.js} +1 -1
- package/chunks/{chunk-XQ2GVLNJ.js → chunk-EEN2TKST.js} +1 -1
- package/chunks/{chunk-DNV4FSN5.js → chunk-FBET5XZ2.js} +6 -4
- package/chunks/{chunk-GIY6JTTC.js → chunk-FQNC62B2.js} +4 -4
- package/chunks/{chunk-B34OV7K2.js → chunk-GGQQA4JW.js} +13 -0
- package/chunks/chunk-GLE2YUPU.js +34 -0
- package/chunks/{chunk-X265R5C6.js → chunk-GN3F6PIU.js} +1 -1
- package/chunks/{chunk-LC4SMGYY.js → chunk-GSHQYYIV.js} +45 -9
- package/chunks/{chunk-BGL43SJ3.js → chunk-HDOH3QYE.js} +1 -1
- package/chunks/{chunk-4AFOWB47.js → chunk-I6WGFJJ3.js} +63 -4
- package/chunks/{chunk-2NPS2UDH.js → chunk-IBY3Q3HG.js} +390 -9
- package/chunks/{chunk-AXTPFMRS.js → chunk-J7RCB6N5.js} +1 -1
- package/chunks/{chunk-QCSLZO6J.js → chunk-JCH35JB3.js} +1 -1
- package/chunks/{chunk-JYOWO2F7.js → chunk-JPALE3PA.js} +3 -3
- package/chunks/{chunk-5FL2K3ZB.js → chunk-JRQ7EVGE.js} +1 -1
- package/chunks/{chunk-BHRU4SDF.js → chunk-JZHIQJOE.js} +3 -3
- package/chunks/{chunk-FB2ULV4M.js → chunk-L46XKEGM.js} +14 -153
- package/chunks/{chunk-LKXDC3AW.js → chunk-L4AMBVQG.js} +9 -9
- package/chunks/{chunk-ME344634.js → chunk-LAXNEOBG.js} +1 -1
- package/chunks/{chunk-QHT5USLK.js → chunk-M7S4GK5Z.js} +66 -445
- package/chunks/{chunk-4RQIB5UZ.js → chunk-O2YT7VB4.js} +0 -34
- package/chunks/{chunk-TBLJNMI7.js → chunk-O33TBKDC.js} +10 -10
- package/chunks/chunk-O7FIRWJV.js +168 -0
- package/chunks/{chunk-4KJ2BPIT.js → chunk-OACJLMLD.js} +2 -38
- package/chunks/{chunk-CR5IU2RX.js → chunk-ON3JA3RU.js} +2 -2
- package/chunks/{chunk-VTCPREC7.js → chunk-OQXDAMKY.js} +3 -3
- package/chunks/{chunk-ELMPRVCB.js → chunk-P3XEEI3X.js} +1 -1
- package/chunks/{chunk-OU6FPTJZ.js → chunk-PMFULMLX.js} +296 -81
- package/chunks/{chunk-2YELHTUE.js → chunk-PUVCVELY.js} +1 -1
- package/chunks/{chunk-5OSSOBZC.js → chunk-RMLZAUWH.js} +4 -4
- package/chunks/{chunk-B6WUEODT.js → chunk-SQ2UATK7.js} +14 -8
- package/chunks/{chunk-TEYGKLIZ.js → chunk-TI3BWD4D.js} +1 -1
- package/chunks/{chunk-T2EJHSE3.js → chunk-TSPB77TG.js} +57 -35
- package/chunks/{chunk-L7IWK7JY.js → chunk-UX6OTBVD.js} +1 -1
- package/chunks/{chunk-XUSONNJ4.js → chunk-UXEW557D.js} +1 -1
- package/chunks/chunk-V35MD7KN.js +13 -0
- package/chunks/{chunk-B5FOCTEZ.js → chunk-VGGOPZUL.js} +6 -5
- package/chunks/{chunk-MYZWWRVW.js → chunk-WF4FAXDL.js} +2 -2
- package/chunks/{chunk-2SWMCXVR.js → chunk-WHJQ3JUS.js} +20 -8
- package/chunks/{chunk-VQJ64BIQ.js → chunk-WQTHLB5T.js} +3 -3
- package/chunks/chunk-XNXVCNAT.js +88 -0
- package/chunks/{chunk-TDGF35EN.js → chunk-XOHNA2S6.js} +1 -1
- package/chunks/{chunk-ZK5EI6NR.js → chunk-XYR5RUA5.js} +14 -5
- package/chunks/{chunk-YMWIKAEE.js → chunk-YDOXPLYL.js} +244 -47
- package/chunks/{chunk-UZCT5OLN.js → chunk-YHKAK72D.js} +11 -11
- package/chunks/{chunk-RFIL6REB.js → chunk-YKZIAK7C.js} +119 -29
- package/chunks/chunk-Z3I3QJK3.js +47 -0
- package/chunks/{chunk-3QDZDAJG.js → chunk-ZE6E424U.js} +1 -1
- package/chunks/chunk-ZL5HN75Q.js +61 -0
- package/chunks/{computer-use-4CTF6WS3.js → computer-use-WMY3UOBX.js} +4 -4
- package/chunks/{contextCommand-Z3XWQCY6.js → contextCommand-LXFZRP4L.js} +6 -6
- package/chunks/{daemon-F3I2RXP6.js → daemon-WPAENEBW.js} +48 -0
- package/chunks/{daemon-status-provider-6A4QCG6Q.js → daemon-status-provider-GJRXY5EN.js} +15 -13
- package/chunks/{de-PLLFDERI.js → de-ZFPPQVSF.js} +26 -1
- package/chunks/{dist-IMFFBMAT.js → dist-BEXOZXLQ.js} +1 -1
- package/chunks/{dist-OT7G2WNM.js → dist-E6UANPIM.js} +1 -1
- package/chunks/{dist-FQ5WRJPL.js → dist-H2AEJCZ5.js} +2 -2
- package/chunks/{dist-YTRKAVUB.js → dist-O2IRTRPP.js} +1 -1
- package/chunks/{dist-573HNSVO.js → dist-SCFLLYMK.js} +1 -1
- package/chunks/{dist-PKFTNUHO.js → dist-Z34QPAQW.js} +1 -1
- package/chunks/{earlyInputCapture-7O47HW62.js → earlyInputCapture-KNOYZ4MJ.js} +4 -4
- package/chunks/{edit-E32KWLF2.js → edit-OTYWAXGP.js} +5 -5
- package/chunks/{en-GA2RMXY5.js → en-N4EPZAQI.js} +26 -1
- package/chunks/{enter-worktree-ZKFFMHUD.js → enter-worktree-HNYBDVCX.js} +4 -4
- package/chunks/{enterPlanMode-HLDC6NGX.js → enterPlanMode-CJCNGT63.js} +4 -4
- package/chunks/environment-ATFTYMLZ.js +88 -0
- package/chunks/{errors-MTIDDXX7.js → errors-A54HAADA.js} +6 -6
- package/chunks/{exit-worktree-YHY72XA2.js → exit-worktree-DUUKOE3X.js} +4 -4
- package/chunks/{exitPlanMode-JNXKBZ2C.js → exitPlanMode-AMMSXOAJ.js} +4 -4
- package/chunks/{fast-path-DVAGBROV.js → fast-path-OV6NIP3K.js} +12 -3
- package/chunks/{fast-path-settings-RCRXH2JG.js → fast-path-settings-7RIFI3PK.js} +3 -2
- package/chunks/{fr-GWNQG4XH.js → fr-5WWMY53B.js} +26 -1
- package/chunks/{gemini-2TMHJVRC.js → gemini-NQ3WWBKB.js} +431 -135
- package/chunks/{geminiContentGenerator-WCH4GWD3.js → geminiContentGenerator-CDUNEJQE.js} +1 -1
- package/chunks/{glob-I6Y4AGKO.js → glob-ROV3YS4R.js} +4 -4
- package/chunks/{grep-3P2J3LU5.js → grep-NRITKDCD.js} +4 -4
- package/chunks/{handleAutoUpdate-4IVRMRG4.js → handleAutoUpdate-CEZJAARW.js} +6 -6
- package/chunks/{initializer-DVNCPVTC.js → initializer-BRFJKRRX.js} +11 -9
- package/chunks/{ja-2HOTA47X.js → ja-CUHZOLEJ.js} +26 -1
- package/chunks/{list-4D6QK2KZ.js → list-KVHF7O4X.js} +13 -11
- package/chunks/{loadedSettingsAdapter-GNGELH6Q.js → loadedSettingsAdapter-LL5PSFKX.js} +11 -9
- package/chunks/{ls-L654WOAT.js → ls-7MFU2QYW.js} +1 -1
- package/chunks/{lsp-M35KE54Y.js → lsp-XHDTPTGV.js} +2 -4
- package/chunks/{mcp-2IL72YJP.js → mcp-3GCXRTOQ.js} +11 -9
- package/chunks/{monitor-BLVCZAVX.js → monitor-FL2ZO33W.js} +4 -4
- package/chunks/{nonInteractiveCli-UD3V7UOO.js → nonInteractiveCli-PTQI3DV6.js} +44 -41
- package/chunks/{notebook-edit-5TVMWIWY.js → notebook-edit-6PULTHL5.js} +5 -5
- package/chunks/{openaiContentGenerator-5LJ5A7YY.js → openaiContentGenerator-YE42PKCY.js} +3 -3
- package/chunks/{pidfile-AN5JQJ2T.js → pidfile-NZYSCFRK.js} +4 -4
- package/chunks/{pt-2THT3YHA.js → pt-OLYN42DS.js} +26 -1
- package/chunks/{qwenContentGenerator-E2JSB4FJ.js → qwenContentGenerator-NX2E7PB7.js} +5 -5
- package/chunks/{read-file-N5DEFUDU.js → read-file-33XGP5HF.js} +2 -2
- package/chunks/{record-artifact-PP3LKHTS.js → record-artifact-SQ2OKRJW.js} +3 -3
- package/chunks/{ripGrep-BLJHTHKE.js → ripGrep-QWZLGTAN.js} +4 -4
- package/chunks/{ru-Z67YJHBG.js → ru-LDM3GWVQ.js} +26 -1
- package/chunks/{run-qwen-serve-4JDO64RN.js → run-qwen-serve-JK2DL7PI.js} +596 -143
- package/chunks/{scheduler-FQR4XA7J.js → scheduler-O4IGVZKK.js} +4 -4
- package/chunks/{send-message-OA6MV4EU.js → send-message-76GT3JMC.js} +1 -1
- package/chunks/{serve-ZOCFC7YM.js → serve-JTMIGANH.js} +13 -10
- package/chunks/{server-GEOYEPYT.js → server-SGNPKX2O.js} +667 -243
- package/chunks/{session-NJCONHGX.js → session-5BNM25EZ.js} +45 -42
- package/chunks/{settings-QBGGXANI.js → settings-3MI4XXP6.js} +20 -16
- package/chunks/{shell-2DVPSEKT.js → shell-YJKBE67T.js} +4 -4
- package/chunks/{skill-HIPXUHV7.js → skill-I22QK5XS.js} +2 -2
- package/chunks/{spawnChannel-3JYXY52G.js → spawnChannel-UNV6W4DU.js} +6 -6
- package/chunks/{src-NLEX4CUC.js → src-BBQSM46M.js} +8 -4
- package/chunks/{startInteractiveUI-TYGZIU27.js → startInteractiveUI-JII36UGN.js} +619 -288
- package/chunks/{task-create-RPFZNB4B.js → task-create-WCHTB435.js} +2 -2
- package/chunks/{task-update-5WUG5MVQ.js → task-update-XYWMHJGJ.js} +2 -2
- package/chunks/{team-create-MGX57SZJ.js → team-create-A7NUU5AQ.js} +4 -4
- package/chunks/{team-plan-approval-BO2N7J3E.js → team-plan-approval-TOQRJ2KI.js} +4 -4
- package/chunks/{theme-manager-WU7LOA64.js → theme-manager-WZ4RRMMB.js} +4 -4
- package/chunks/{tool-search-CLBKVEVK.js → tool-search-SZ4EFS2T.js} +3 -3
- package/chunks/total-session-admission-ULXJWXFV.js +72 -0
- package/chunks/{trustedFolders-GAQM2GHB.js → trustedFolders-LAZZPZ3D.js} +5 -5
- package/chunks/{updateCheck-RIK2YIQE.js → updateCheck-KONLM73X.js} +5 -5
- package/chunks/{validateNonInterActiveAuth-NS3GBIJZ.js → validateNonInterActiveAuth-MPKSRCXD.js} +41 -38
- package/chunks/{version-B3RSLP54.js → version-NO2XSNNP.js} +1 -1
- package/chunks/{workflow-7APPIGND.js → workflow-WO2H6NRI.js} +5 -5
- package/chunks/{workspace-providers-status-SC67GLMY.js → workspace-providers-status-3W7E7DFW.js} +14 -11
- package/chunks/workspace-registry-SXJZNN3O.js +74 -0
- package/chunks/{workspace-service-ZJHF22WA.js → workspace-service-CZRQZ4Q4.js} +17 -15
- package/chunks/{workspace-skills-status-NJEK6P6Y.js → workspace-skills-status-K7WFREPD.js} +12 -10
- package/chunks/{write-file-R6Z3VLRY.js → write-file-PX2Z7IBE.js} +5 -5
- package/chunks/{zh-7XVVRTDH.js → zh-J4F6QWQV.js} +26 -1
- package/chunks/{zh-TW-DPH554OG.js → zh-TW-XVDWOLSW.js} +26 -1
- package/cli.js +11 -11
- package/locales/ca.js +30 -0
- package/locales/de.js +30 -0
- package/locales/en.js +30 -0
- package/locales/fr.js +30 -0
- package/locales/ja.js +30 -0
- package/locales/pt.js +30 -0
- package/locales/ru.js +30 -0
- package/locales/zh-TW.js +30 -0
- package/locales/zh.js +30 -0
- package/node_modules/@qwen-code/audio-capture/package.json +1 -1
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
- package/package.json +3 -3
- package/web-shell/assets/{arc-C7hjaa7g.js → arc-BWyoJpY2.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-pm9KtMZY.js → architectureDiagram-3BPJPVTR-BT0mGrz2.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-CApElKsU.js → blockDiagram-GPEHLZMM-BLgUWvyf.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-BeDe0-9N.js → c4Diagram-AAUBKEIU-DYx9M7oU.js} +1 -1
- package/web-shell/assets/channel-wmPUGHtg.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-DJEkmLdl.js → chunk-2J33WTMH-CfMHWbuZ.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-DXX8gdpe.js → chunk-4BX2VUAB-B1URoqEV.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-DORmk1kQ.js → chunk-55IACEB6-DAIaM4QF.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-DWmO4mCZ.js → chunk-727SXJPM-B2X34knw.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-C7LRaYw2.js → chunk-AQP2D5EJ-Cif-zLTQ.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-CCdXgyC5.js → chunk-FMBD7UC4-H18WCXdY.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-SyL_xvWc.js → chunk-ND2GUHAM-YFtetHi0.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-BzOuCKxa.js → chunk-QZHKN3VN-By2hiH3r.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-BA2ljEjW.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BA2ljEjW.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-BMPWyDKc.js → cose-bilkent-S5V4N54A-VrcnnLZu.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-B_GnPWik.js → dagre-BM42HDAG-CGo-IaVV.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-fJqMc3S_.js → diagram-2AECGRRQ-Dl4QjzIB.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-ximV3O9D.js → diagram-5GNKFQAL-qMLmsO0u.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-2vVyjzqw.js → diagram-KO2AKTUF-CHlmuxPI.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-Dckcx1sT.js → diagram-LMA3HP47-BUwU3GwT.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-BAVv47ga.js → diagram-OG6HWLK6-HEhwPDUM.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-Bn3nf5J0.js → erDiagram-TEJ5UH35-1n0llBmM.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-BIbGF9JT.js → flowDiagram-I6XJVG4X-BN74uMnt.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-CDbhb3AH.js → ganttDiagram-6RSMTGT7-BoOq78i3.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CbKG1a_w.js → gitGraphDiagram-PVQCEYII-CN8b00c8.js} +1 -1
- package/web-shell/assets/index-CNwoO1Cn.js +783 -0
- package/web-shell/assets/index-CWQ0z6kZ.css +5 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-DUFxTy8m.js → infoDiagram-5YYISTIA-CCurnIna.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-D69hrBG8.js → ishikawaDiagram-YF4QCWOH-AwuRqdUP.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-DsvEw51Y.js → journeyDiagram-JHISSGLW-B7IICk-E.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-lFFjZEYd.js → kanban-definition-UN3LZRKU-BYF0OKhx.js} +1 -1
- package/web-shell/assets/{linear-Bo5bWzvo.js → linear-GWWguGfD.js} +1 -1
- package/web-shell/assets/{mermaid.core-C_HKMJx5.js → mermaid.core-JqtkxvCl.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-DlV-NUTs.js → mindmap-definition-RKZ34NQL-B0MmHsZ6.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-B2e6FH2a.js → pieDiagram-4H26LBE5-DhImUZLQ.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-D75kSk-b.js → quadrantDiagram-W4KKPZXB-DGeSC3DT.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-CQ6xakhM.js → requirementDiagram-4Y6WPE33-DkspY6Re.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-J_XTKrcY.js → sankeyDiagram-5OEKKPKP-CaOofS2x.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-D7jTcBtf.js → sequenceDiagram-3UESZ5HK-DFQ_kFnN.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-CrlM_OT3.js → stateDiagram-AJRCARHV-D3snw0Tz.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BbSm_9d0.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-5oZi76Ef.js → timeline-definition-PNZ67QCA-l4zH8nLM.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-DO5YptPK.js → vennDiagram-CIIHVFJN-BnRlA98M.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-4t1eJDvM.js → wardley-L42UT6IY-BS0xUdmd.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DKZc661S.js → wardleyDiagram-YWT4CUSO-DKGBUWyQ.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-su9hp08G.js → xychartDiagram-2RQKCTM6-DVb2HuOB.js} +1 -1
- package/web-shell/index.html +2 -2
- package/web-shell/assets/channel-BNf1dW-j.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-uOIGlzgi.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-uOIGlzgi.js +0 -1
- package/web-shell/assets/index-CnE2ur2L.js +0 -779
- package/web-shell/assets/index-hSKXrlSE.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Bs4TK_84.js +0 -1
|
@@ -7,9 +7,6 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
findCliEntryPath
|
|
9
9
|
} from "./chunk-AHNXYU4O.js";
|
|
10
|
-
import {
|
|
11
|
-
RUNTIME_STARTUP_CANCELLED_MESSAGE
|
|
12
|
-
} from "./chunk-GHOTR7HL.js";
|
|
13
10
|
import {
|
|
14
11
|
CAPABILITIES_SCHEMA_VERSION,
|
|
15
12
|
ClientMcpSenderRegistry,
|
|
@@ -31,16 +28,29 @@ import {
|
|
|
31
28
|
positiveFiniteOrNull,
|
|
32
29
|
require_express,
|
|
33
30
|
resolveWebShellDir
|
|
34
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-YKZIAK7C.js";
|
|
35
32
|
import {
|
|
36
33
|
isLoopbackBind
|
|
37
34
|
} from "./chunk-RNBYOUGV.js";
|
|
38
35
|
import "./chunk-3HX5LZ6R.js";
|
|
39
36
|
import "./chunk-7RYW5LQV.js";
|
|
37
|
+
import {
|
|
38
|
+
RUNTIME_STARTUP_CANCELLED_MESSAGE
|
|
39
|
+
} from "./chunk-GHOTR7HL.js";
|
|
40
|
+
import {
|
|
41
|
+
LOAD_REPLAY_META_KEY
|
|
42
|
+
} from "./chunk-AGHU5VRK.js";
|
|
43
|
+
import {
|
|
44
|
+
DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
|
|
45
|
+
normalizeCompactedReplayMaxBytes
|
|
46
|
+
} from "./chunk-GLE2YUPU.js";
|
|
47
|
+
import {
|
|
48
|
+
canonicalizeWorkspace
|
|
49
|
+
} from "./chunk-ER3BKOLB.js";
|
|
40
50
|
import {
|
|
41
51
|
loadServeFastPathSettings,
|
|
42
52
|
preResolveServeFastPathHomeEnvOverrides
|
|
43
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-FBET5XZ2.js";
|
|
44
54
|
import {
|
|
45
55
|
QWEN_SERVER_TOKEN_ENV
|
|
46
56
|
} from "./chunk-S6RLAIUR.js";
|
|
@@ -50,16 +60,11 @@ import {
|
|
|
50
60
|
import {
|
|
51
61
|
getGlobalQwenDirLite,
|
|
52
62
|
resolveConfigPathLite
|
|
53
|
-
} from "./chunk-
|
|
54
|
-
import
|
|
55
|
-
LOAD_REPLAY_META_KEY
|
|
56
|
-
} from "./chunk-AGHU5VRK.js";
|
|
57
|
-
import {
|
|
58
|
-
canonicalizeWorkspace
|
|
59
|
-
} from "./chunk-ER3BKOLB.js";
|
|
63
|
+
} from "./chunk-O2YT7VB4.js";
|
|
64
|
+
import "./chunk-Z3I3QJK3.js";
|
|
60
65
|
import {
|
|
61
66
|
getCliVersion
|
|
62
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-UXEW557D.js";
|
|
63
68
|
import "./chunk-43W4YSO6.js";
|
|
64
69
|
import {
|
|
65
70
|
writeStderrLine,
|
|
@@ -105,7 +110,7 @@ var DuplicateWorkspaceInputError = class extends Error {
|
|
|
105
110
|
}
|
|
106
111
|
constructor(workspace) {
|
|
107
112
|
super(
|
|
108
|
-
`Duplicate --workspace value resolves to ${JSON.stringify(workspace)}.
|
|
113
|
+
`Duplicate --workspace value resolves to ${JSON.stringify(workspace)}. Pass distinct --workspace values.`
|
|
109
114
|
);
|
|
110
115
|
this.name = "DuplicateWorkspaceInputError";
|
|
111
116
|
}
|
|
@@ -116,22 +121,11 @@ var NestedWorkspaceInputError = class extends Error {
|
|
|
116
121
|
}
|
|
117
122
|
constructor(parent, child) {
|
|
118
123
|
super(
|
|
119
|
-
`Nested --workspace values are not supported yet: ${JSON.stringify(child)} is inside ${JSON.stringify(parent)}.
|
|
124
|
+
`Nested --workspace values are not supported yet: ${JSON.stringify(child)} is inside ${JSON.stringify(parent)}. Pass non-nested --workspace values.`
|
|
120
125
|
);
|
|
121
126
|
this.name = "NestedWorkspaceInputError";
|
|
122
127
|
}
|
|
123
128
|
};
|
|
124
|
-
var MultipleWorkspaceInputError = class extends Error {
|
|
125
|
-
static {
|
|
126
|
-
__name(this, "MultipleWorkspaceInputError");
|
|
127
|
-
}
|
|
128
|
-
constructor() {
|
|
129
|
-
super(
|
|
130
|
-
"Multiple --workspace values are not supported yet. Multi-workspace serve is not enabled; pass one --workspace."
|
|
131
|
-
);
|
|
132
|
-
this.name = "MultipleWorkspaceInputError";
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
129
|
var MissingWorkspaceInputError = class extends Error {
|
|
136
130
|
static {
|
|
137
131
|
__name(this, "MissingWorkspaceInputError");
|
|
@@ -156,7 +150,7 @@ function isNestedWorkspace(parent, child) {
|
|
|
156
150
|
return parent !== child && isWithinRoot(child, parent);
|
|
157
151
|
}
|
|
158
152
|
__name(isNestedWorkspace, "isNestedWorkspace");
|
|
159
|
-
function
|
|
153
|
+
function rejectDuplicateOrNestedWorkspaceInputs(workspaces) {
|
|
160
154
|
if (workspaces.length <= 1) return;
|
|
161
155
|
let canonicalWorkspaces;
|
|
162
156
|
try {
|
|
@@ -164,7 +158,7 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
|
|
|
164
158
|
(workspace) => canonicalizeWorkspace(workspace)
|
|
165
159
|
);
|
|
166
160
|
} catch {
|
|
167
|
-
|
|
161
|
+
return;
|
|
168
162
|
}
|
|
169
163
|
const seen = /* @__PURE__ */ new Set();
|
|
170
164
|
for (const workspace of canonicalWorkspaces) {
|
|
@@ -185,15 +179,14 @@ function rejectUnsupportedMultiWorkspaceInputs(workspaces) {
|
|
|
185
179
|
}
|
|
186
180
|
}
|
|
187
181
|
}
|
|
188
|
-
throw new MultipleWorkspaceInputError();
|
|
189
182
|
}
|
|
190
|
-
__name(
|
|
191
|
-
function
|
|
183
|
+
__name(rejectDuplicateOrNestedWorkspaceInputs, "rejectDuplicateOrNestedWorkspaceInputs");
|
|
184
|
+
function resolveWorkspaceInputs(workspace) {
|
|
192
185
|
const workspaces = normalizeWorkspaceInputs(workspace);
|
|
193
|
-
|
|
194
|
-
return workspaces
|
|
186
|
+
rejectDuplicateOrNestedWorkspaceInputs(workspaces);
|
|
187
|
+
return workspaces;
|
|
195
188
|
}
|
|
196
|
-
__name(
|
|
189
|
+
__name(resolveWorkspaceInputs, "resolveWorkspaceInputs");
|
|
197
190
|
|
|
198
191
|
// packages/cli/src/serve/permission-audit.ts
|
|
199
192
|
init_esbuild_shims();
|
|
@@ -939,11 +932,21 @@ function isNonNegativeIntegerOrInfinity(value) {
|
|
|
939
932
|
return value === Number.POSITIVE_INFINITY || Number.isFinite(value) && Number.isInteger(value) && value >= 0;
|
|
940
933
|
}
|
|
941
934
|
__name(isNonNegativeIntegerOrInfinity, "isNonNegativeIntegerOrInfinity");
|
|
935
|
+
function deriveDefaultMaxTotalSessions(maxSessionsPerWorkspace, workspaceCount) {
|
|
936
|
+
if (workspaceCount <= 1) return void 0;
|
|
937
|
+
const perWorkspace = maxSessionsPerWorkspace ?? DEFAULT_MAX_SESSIONS;
|
|
938
|
+
if (perWorkspace === 0 || perWorkspace === Number.POSITIVE_INFINITY) {
|
|
939
|
+
return void 0;
|
|
940
|
+
}
|
|
941
|
+
return perWorkspace * workspaceCount;
|
|
942
|
+
}
|
|
943
|
+
__name(deriveDefaultMaxTotalSessions, "deriveDefaultMaxTotalSessions");
|
|
942
944
|
function isNonNegativeIntegerMs(value) {
|
|
943
945
|
return Number.isFinite(value) && Number.isInteger(value) && value >= 0;
|
|
944
946
|
}
|
|
945
947
|
__name(isNonNegativeIntegerMs, "isNonNegativeIntegerMs");
|
|
946
948
|
var MAX_TIMEOUT_MS = 2147483647;
|
|
949
|
+
var MAX_PORT_ATTEMPTS = 10;
|
|
947
950
|
function assertTimerDelayInRange(name, value) {
|
|
948
951
|
if (value > MAX_TIMEOUT_MS) {
|
|
949
952
|
throw new TypeError(
|
|
@@ -1082,8 +1085,8 @@ __name(withSettingsLock, "withSettingsLock");
|
|
|
1082
1085
|
var channelWorkerRuntimePromise;
|
|
1083
1086
|
async function loadChannelWorkerRuntime() {
|
|
1084
1087
|
channelWorkerRuntimePromise ??= Promise.all([
|
|
1085
|
-
import("./channel-worker-supervisor-
|
|
1086
|
-
import("./pidfile-
|
|
1088
|
+
import("./channel-worker-supervisor-NZQUOEFJ.js"),
|
|
1089
|
+
import("./pidfile-NZYSCFRK.js")
|
|
1087
1090
|
]).then(([supervisor, pidfile]) => ({
|
|
1088
1091
|
createChannelWorkerSupervisor: supervisor.createChannelWorkerSupervisor,
|
|
1089
1092
|
channelServicePidfile: pidfile
|
|
@@ -1154,7 +1157,7 @@ function shouldPreheatBridge(deps) {
|
|
|
1154
1157
|
__name(shouldPreheatBridge, "shouldPreheatBridge");
|
|
1155
1158
|
var coreRuntimePromise;
|
|
1156
1159
|
function loadCoreRuntime() {
|
|
1157
|
-
coreRuntimePromise ??= import("./src-
|
|
1160
|
+
coreRuntimePromise ??= import("./src-BBQSM46M.js");
|
|
1158
1161
|
return coreRuntimePromise;
|
|
1159
1162
|
}
|
|
1160
1163
|
__name(loadCoreRuntime, "loadCoreRuntime");
|
|
@@ -1184,11 +1187,13 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
|
|
|
1184
1187
|
var settingsRuntimePromise;
|
|
1185
1188
|
function loadSettingsRuntimeModules() {
|
|
1186
1189
|
settingsRuntimePromise ??= Promise.all([
|
|
1187
|
-
import("./settings-
|
|
1188
|
-
import("./
|
|
1189
|
-
import("./
|
|
1190
|
-
|
|
1190
|
+
import("./settings-3MI4XXP6.js"),
|
|
1191
|
+
import("./environment-ATFTYMLZ.js"),
|
|
1192
|
+
import("./loadedSettingsAdapter-LL5PSFKX.js"),
|
|
1193
|
+
import("./trustedFolders-LAZZPZ3D.js")
|
|
1194
|
+
]).then(([settings, environment, loadedSettingsAdapter, trustedFolders]) => ({
|
|
1191
1195
|
settings,
|
|
1196
|
+
environment,
|
|
1192
1197
|
loadedSettingsAdapter,
|
|
1193
1198
|
trustedFolders
|
|
1194
1199
|
}));
|
|
@@ -1204,16 +1209,20 @@ async function loadServeRuntimeModules() {
|
|
|
1204
1209
|
workspaceTypesModule,
|
|
1205
1210
|
daemonStatusProviderModule,
|
|
1206
1211
|
workspaceProvidersStatusModule,
|
|
1207
|
-
workspaceSkillsStatusModule
|
|
1212
|
+
workspaceSkillsStatusModule,
|
|
1213
|
+
totalSessionAdmissionModule,
|
|
1214
|
+
workspaceRegistryModule
|
|
1208
1215
|
] = await Promise.all([
|
|
1209
|
-
import("./server-
|
|
1210
|
-
import("./bridge-
|
|
1211
|
-
import("./spawnChannel-
|
|
1212
|
-
import("./workspace-service-
|
|
1216
|
+
import("./server-SGNPKX2O.js"),
|
|
1217
|
+
import("./bridge-NA3ZQQKJ.js"),
|
|
1218
|
+
import("./spawnChannel-UNV6W4DU.js"),
|
|
1219
|
+
import("./workspace-service-CZRQZ4Q4.js"),
|
|
1213
1220
|
import("./types-QX5C3CHJ.js"),
|
|
1214
|
-
import("./daemon-status-provider-
|
|
1215
|
-
import("./workspace-providers-status-
|
|
1216
|
-
import("./workspace-skills-status-
|
|
1221
|
+
import("./daemon-status-provider-GJRXY5EN.js"),
|
|
1222
|
+
import("./workspace-providers-status-3W7E7DFW.js"),
|
|
1223
|
+
import("./workspace-skills-status-K7WFREPD.js"),
|
|
1224
|
+
import("./total-session-admission-ULXJWXFV.js"),
|
|
1225
|
+
import("./workspace-registry-SXJZNN3O.js")
|
|
1217
1226
|
]);
|
|
1218
1227
|
return {
|
|
1219
1228
|
createServeApp: serverModule.createServeApp,
|
|
@@ -1226,7 +1235,9 @@ async function loadServeRuntimeModules() {
|
|
|
1226
1235
|
WorkspaceSettingsPartialPersistError: workspaceTypesModule.WorkspaceSettingsPartialPersistError,
|
|
1227
1236
|
createDaemonStatusProvider: daemonStatusProviderModule.createDaemonStatusProvider,
|
|
1228
1237
|
createWorkspaceProvidersStatusProvider: workspaceProvidersStatusModule.createWorkspaceProvidersStatusProvider,
|
|
1229
|
-
createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider
|
|
1238
|
+
createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider,
|
|
1239
|
+
createTotalSessionAdmissionController: totalSessionAdmissionModule.createTotalSessionAdmissionController,
|
|
1240
|
+
createWorkspaceRegistry: workspaceRegistryModule.createWorkspaceRegistry
|
|
1230
1241
|
};
|
|
1231
1242
|
}
|
|
1232
1243
|
__name(loadServeRuntimeModules, "loadServeRuntimeModules");
|
|
@@ -1422,6 +1433,7 @@ function createBootstrapServeApp(input) {
|
|
|
1422
1433
|
qwenCodeVersion,
|
|
1423
1434
|
sessionShellCommandEnabled,
|
|
1424
1435
|
permissionPolicy,
|
|
1436
|
+
multiWorkspaceCapabilitiesRequireRuntime,
|
|
1425
1437
|
getRuntimeError,
|
|
1426
1438
|
getChannelWorkerSnapshot,
|
|
1427
1439
|
onHealthServed
|
|
@@ -1458,6 +1470,17 @@ function createBootstrapServeApp(input) {
|
|
|
1458
1470
|
app.get(BOOTSTRAP_HEALTH_PATH, healthHandler);
|
|
1459
1471
|
}
|
|
1460
1472
|
app.get(BOOTSTRAP_CAPABILITIES_PATH, (_req, res) => {
|
|
1473
|
+
if (multiWorkspaceCapabilitiesRequireRuntime) {
|
|
1474
|
+
const runtimeError = getRuntimeError();
|
|
1475
|
+
if (runtimeError === void 0) {
|
|
1476
|
+
res.setHeader("Retry-After", "1");
|
|
1477
|
+
}
|
|
1478
|
+
res.status(503).json({
|
|
1479
|
+
error: runtimeError ? "Daemon runtime failed to start" : "Daemon runtime is still starting",
|
|
1480
|
+
code: runtimeError ? "daemon_runtime_failed" : "daemon_runtime_starting"
|
|
1481
|
+
});
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1461
1484
|
res.status(200).json(
|
|
1462
1485
|
createBootstrapCapabilities({
|
|
1463
1486
|
opts,
|
|
@@ -1518,11 +1541,13 @@ function createBootstrapServeApp(input) {
|
|
|
1518
1541
|
},
|
|
1519
1542
|
limits: {
|
|
1520
1543
|
maxSessions: advertisedMaxSessions(opts.maxSessions),
|
|
1544
|
+
maxTotalSessions: positiveFiniteOrNull(opts.maxTotalSessions),
|
|
1521
1545
|
maxPendingPromptsPerSession: advertisedMaxPendingPromptsPerSession(
|
|
1522
1546
|
opts.maxPendingPromptsPerSession
|
|
1523
1547
|
),
|
|
1524
1548
|
listenerMaxConnections: listenerMaxConnections(opts.maxConnections),
|
|
1525
1549
|
eventRingSize: opts.eventRingSize ?? DEFAULT_EVENT_RING_SIZE,
|
|
1550
|
+
compactedReplayMaxBytes: opts.compactedReplayMaxBytes ?? DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
|
|
1526
1551
|
promptDeadlineMs: positiveFiniteOrNull(opts.promptDeadlineMs),
|
|
1527
1552
|
writerIdleTimeoutMs: positiveFiniteOrNull(opts.writerIdleTimeoutMs),
|
|
1528
1553
|
channelIdleTimeoutMs: channelIdleTimeoutMs(opts.channelIdleTimeoutMs),
|
|
@@ -1663,6 +1688,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1663
1688
|
}
|
|
1664
1689
|
};
|
|
1665
1690
|
preResolveServeFastPathHomeEnvOverrides();
|
|
1691
|
+
const daemonRuntimeBaseEnv = Object.freeze({
|
|
1692
|
+
...process.env
|
|
1693
|
+
});
|
|
1666
1694
|
const rawToken = optsIn.token ?? process.env[QWEN_SERVER_TOKEN_ENV];
|
|
1667
1695
|
const token = typeof rawToken === "string" && rawToken.trim().length > 0 ? rawToken.trim() : void 0;
|
|
1668
1696
|
const sessionShellCommandEnabled = optsIn.enableSessionShell === true && token !== void 0;
|
|
@@ -1684,7 +1712,8 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1684
1712
|
const chromeExtensionOriginAllowed = hasChromeExtensionOrigin(
|
|
1685
1713
|
optsIn.allowOrigins
|
|
1686
1714
|
);
|
|
1687
|
-
const
|
|
1715
|
+
const rawWorkspaces = resolveWorkspaceInputs(optsIn.workspace);
|
|
1716
|
+
const rawWorkspace = rawWorkspaces[0];
|
|
1688
1717
|
const opts = {
|
|
1689
1718
|
...optsIn,
|
|
1690
1719
|
token,
|
|
@@ -1830,35 +1859,76 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1830
1859
|
"qwen serve: --allow-private-auth-base-url enabled; /workspace/auth/provider may install localhost/private-network model endpoints. Use only for local development with trusted clients."
|
|
1831
1860
|
);
|
|
1832
1861
|
}
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
`Invalid --workspace "${rawWorkspace}": must be an absolute path.`
|
|
1836
|
-
);
|
|
1837
|
-
}
|
|
1838
|
-
try {
|
|
1839
|
-
const stats = fs.statSync(rawWorkspace);
|
|
1840
|
-
if (!stats.isDirectory()) {
|
|
1862
|
+
const validateAndCanonicalizeWorkspace = /* @__PURE__ */ __name((workspace) => {
|
|
1863
|
+
if (!path.isAbsolute(workspace)) {
|
|
1841
1864
|
throw new Error(
|
|
1842
|
-
`Invalid --workspace "${
|
|
1865
|
+
`Invalid --workspace "${workspace}": must be an absolute path.`
|
|
1843
1866
|
);
|
|
1844
1867
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
if (code === "ENOENT") {
|
|
1868
|
+
try {
|
|
1869
|
+
const stats = fs.statSync(workspace);
|
|
1870
|
+
if (!stats.isDirectory()) {
|
|
1849
1871
|
throw new Error(
|
|
1850
|
-
`Invalid --workspace "${
|
|
1872
|
+
`Invalid --workspace "${workspace}": exists but is not a directory.`
|
|
1851
1873
|
);
|
|
1852
1874
|
}
|
|
1853
|
-
|
|
1875
|
+
} catch (err) {
|
|
1876
|
+
if (err && typeof err === "object" && "code" in err) {
|
|
1877
|
+
const code = err.code;
|
|
1878
|
+
if (code === "ENOENT") {
|
|
1879
|
+
throw new Error(
|
|
1880
|
+
`Invalid --workspace "${workspace}": directory does not exist.`
|
|
1881
|
+
);
|
|
1882
|
+
}
|
|
1883
|
+
if (code === "EACCES" || code === "EPERM") {
|
|
1884
|
+
throw new Error(
|
|
1885
|
+
`Invalid --workspace "${workspace}": permission denied (${String(code)}). The path exists but cannot be stat'd by the current user.`
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
throw err;
|
|
1890
|
+
}
|
|
1891
|
+
return canonicalizeWorkspace(workspace);
|
|
1892
|
+
}, "validateAndCanonicalizeWorkspace");
|
|
1893
|
+
const workspaceInputs = rawWorkspaces.map((workspace) => ({
|
|
1894
|
+
raw: workspace,
|
|
1895
|
+
cwd: validateAndCanonicalizeWorkspace(workspace)
|
|
1896
|
+
}));
|
|
1897
|
+
const boundWorkspace = workspaceInputs[0].cwd;
|
|
1898
|
+
const seenCanonicalWorkspaces = /* @__PURE__ */ new Set();
|
|
1899
|
+
for (const workspace of workspaceInputs) {
|
|
1900
|
+
if (seenCanonicalWorkspaces.has(workspace.cwd)) {
|
|
1901
|
+
throw new Error(
|
|
1902
|
+
`Duplicate --workspace value resolves to ${JSON.stringify(
|
|
1903
|
+
workspace.cwd
|
|
1904
|
+
)}.`
|
|
1905
|
+
);
|
|
1906
|
+
}
|
|
1907
|
+
seenCanonicalWorkspaces.add(workspace.cwd);
|
|
1908
|
+
}
|
|
1909
|
+
for (let i = 0; i < workspaceInputs.length; i++) {
|
|
1910
|
+
for (let j = i + 1; j < workspaceInputs.length; j++) {
|
|
1911
|
+
const first = workspaceInputs[i].cwd;
|
|
1912
|
+
const second = workspaceInputs[j].cwd;
|
|
1913
|
+
const firstRel = path.relative(first, second);
|
|
1914
|
+
const secondRel = path.relative(second, first);
|
|
1915
|
+
if (firstRel && !firstRel.startsWith("..") && !path.isAbsolute(firstRel)) {
|
|
1854
1916
|
throw new Error(
|
|
1855
|
-
`
|
|
1917
|
+
`Nested --workspace values are not supported: ${JSON.stringify(second)} is inside ${JSON.stringify(first)}.`
|
|
1918
|
+
);
|
|
1919
|
+
}
|
|
1920
|
+
if (secondRel && !secondRel.startsWith("..") && !path.isAbsolute(secondRel)) {
|
|
1921
|
+
throw new Error(
|
|
1922
|
+
`Nested --workspace values are not supported: ${JSON.stringify(first)} is inside ${JSON.stringify(second)}.`
|
|
1856
1923
|
);
|
|
1857
1924
|
}
|
|
1858
1925
|
}
|
|
1859
|
-
throw err;
|
|
1860
1926
|
}
|
|
1861
|
-
|
|
1927
|
+
if (workspaceInputs.length > 1 && deps.bridge) {
|
|
1928
|
+
throw new Error(
|
|
1929
|
+
"Injected bridge dependencies are only supported with a single workspace; multiple --workspace values require runQwenServe to construct one bridge per workspace."
|
|
1930
|
+
);
|
|
1931
|
+
}
|
|
1862
1932
|
let contextFilenameForInit;
|
|
1863
1933
|
let permissionPolicy;
|
|
1864
1934
|
let permissionConsensusQuorum;
|
|
@@ -1919,6 +1989,13 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1919
1989
|
);
|
|
1920
1990
|
}
|
|
1921
1991
|
}
|
|
1992
|
+
if (opts.maxTotalSessions !== void 0) {
|
|
1993
|
+
if (!isNonNegativeIntegerOrInfinity(opts.maxTotalSessions)) {
|
|
1994
|
+
throw new TypeError(
|
|
1995
|
+
`Invalid maxTotalSessions: ${opts.maxTotalSessions}. Must be a non-negative integer (0 / Infinity = unlimited).`
|
|
1996
|
+
);
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1922
1999
|
if (opts.maxPendingPromptsPerSession !== void 0) {
|
|
1923
2000
|
if (!isNonNegativeIntegerOrInfinity(opts.maxPendingPromptsPerSession)) {
|
|
1924
2001
|
throw new TypeError(
|
|
@@ -1933,6 +2010,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1933
2010
|
);
|
|
1934
2011
|
}
|
|
1935
2012
|
}
|
|
2013
|
+
if (opts.compactedReplayMaxBytes !== void 0) {
|
|
2014
|
+
normalizeCompactedReplayMaxBytes(opts.compactedReplayMaxBytes);
|
|
2015
|
+
}
|
|
1936
2016
|
if (opts.writerIdleTimeoutMs !== void 0) {
|
|
1937
2017
|
if (!isPositiveIntegerMs(opts.writerIdleTimeoutMs)) {
|
|
1938
2018
|
throw new TypeError(
|
|
@@ -1968,6 +2048,10 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1968
2048
|
);
|
|
1969
2049
|
}
|
|
1970
2050
|
}
|
|
2051
|
+
opts.maxTotalSessions ??= deriveDefaultMaxTotalSessions(
|
|
2052
|
+
opts.maxSessions,
|
|
2053
|
+
workspaceInputs.length
|
|
2054
|
+
);
|
|
1971
2055
|
const inheritedNoPool = process.env["QWEN_SERVE_NO_MCP_POOL"] === "1";
|
|
1972
2056
|
if (opts.mcpPoolActive === void 0 && inheritedNoPool) {
|
|
1973
2057
|
opts.mcpPoolActive = false;
|
|
@@ -2005,6 +2089,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2005
2089
|
let runtimeApp;
|
|
2006
2090
|
let runtimeAppForCleanup;
|
|
2007
2091
|
let bridgeRef = deps.bridge;
|
|
2092
|
+
const internalRuntimeBridgesForCleanup = [];
|
|
2008
2093
|
let daemonEventLoopMonitor;
|
|
2009
2094
|
let daemonMetricsSampler;
|
|
2010
2095
|
let runtimeStartupError;
|
|
@@ -2047,6 +2132,17 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2047
2132
|
() => bridgeRef,
|
|
2048
2133
|
() => runtimeStartupError
|
|
2049
2134
|
);
|
|
2135
|
+
const shutdownBridges = /* @__PURE__ */ new WeakSet();
|
|
2136
|
+
const getRuntimeBridgesForCleanup = /* @__PURE__ */ __name(() => {
|
|
2137
|
+
const appForCleanup = runtimeApp ?? runtimeAppForCleanup;
|
|
2138
|
+
const registry = appForCleanup?.locals?.["workspaceRegistry"];
|
|
2139
|
+
const bridges = [
|
|
2140
|
+
...registry ? registry.list().map((runtime) => runtime.bridge) : [],
|
|
2141
|
+
...bridgeRef ? [bridgeRef] : [],
|
|
2142
|
+
...internalRuntimeBridgesForCleanup
|
|
2143
|
+
];
|
|
2144
|
+
return [...new Set(bridges)];
|
|
2145
|
+
}, "getRuntimeBridgesForCleanup");
|
|
2050
2146
|
const buildRuntime = /* @__PURE__ */ __name(async () => {
|
|
2051
2147
|
const [runtime, core, settingsRuntime, resolvedCliVersion] = await Promise.all([
|
|
2052
2148
|
loadServeRuntimeModules(),
|
|
@@ -2073,6 +2169,43 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2073
2169
|
{ workspace: boundWorkspace }
|
|
2074
2170
|
);
|
|
2075
2171
|
}
|
|
2172
|
+
const runtimeEnvSnapshot = runtimeBootSettings ? settingsRuntime.environment.buildRuntimeEnvironment(
|
|
2173
|
+
runtimeBootSettings.merged,
|
|
2174
|
+
boundWorkspace,
|
|
2175
|
+
daemonRuntimeBaseEnv
|
|
2176
|
+
) : {
|
|
2177
|
+
effectiveEnv: { ...daemonRuntimeBaseEnv },
|
|
2178
|
+
overlayKeys: Object.freeze([]),
|
|
2179
|
+
envFilePaths: Object.freeze([]),
|
|
2180
|
+
envFileReadFailed: false,
|
|
2181
|
+
envFileReadFailures: Object.freeze([])
|
|
2182
|
+
};
|
|
2183
|
+
const logRuntimeEnvFileReadFailures = /* @__PURE__ */ __name((workspace, snapshot) => {
|
|
2184
|
+
if (!snapshot.envFileReadFailed) return;
|
|
2185
|
+
const failedFiles = snapshot.envFileReadFailures ?? [];
|
|
2186
|
+
daemonLog.warn("one or more runtime env files could not be read", {
|
|
2187
|
+
workspace,
|
|
2188
|
+
...failedFiles.length > 0 ? { failedFiles } : {}
|
|
2189
|
+
});
|
|
2190
|
+
}, "logRuntimeEnvFileReadFailures");
|
|
2191
|
+
logRuntimeEnvFileReadFailures(boundWorkspace, runtimeEnvSnapshot);
|
|
2192
|
+
const runtimeEffectiveEnv = {
|
|
2193
|
+
...runtimeEnvSnapshot.effectiveEnv
|
|
2194
|
+
};
|
|
2195
|
+
const replaceRuntimeEffectiveEnv = /* @__PURE__ */ __name((nextEnv) => {
|
|
2196
|
+
for (const key of Object.keys(runtimeEffectiveEnv)) {
|
|
2197
|
+
delete runtimeEffectiveEnv[key];
|
|
2198
|
+
}
|
|
2199
|
+
Object.assign(runtimeEffectiveEnv, nextEnv);
|
|
2200
|
+
}, "replaceRuntimeEffectiveEnv");
|
|
2201
|
+
const primaryRuntimeEnv = {
|
|
2202
|
+
mode: "runtime-overlay",
|
|
2203
|
+
overlayKeys: [...runtimeEnvSnapshot.overlayKeys],
|
|
2204
|
+
effectiveEnv: runtimeEffectiveEnv,
|
|
2205
|
+
envFilePaths: [...runtimeEnvSnapshot.envFilePaths],
|
|
2206
|
+
envFileReadFailed: runtimeEnvSnapshot.envFileReadFailed,
|
|
2207
|
+
envFileReadFailures: [...runtimeEnvSnapshot.envFileReadFailures]
|
|
2208
|
+
};
|
|
2076
2209
|
const daemonWorkspaceHash = core.hashDaemonWorkspace(boundWorkspace);
|
|
2077
2210
|
let daemonTelemetrySettings;
|
|
2078
2211
|
try {
|
|
@@ -2145,54 +2278,58 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2145
2278
|
promptQueueWaitStats.lastMs = durationMs;
|
|
2146
2279
|
core.recordDaemonPromptQueueWait(durationMs);
|
|
2147
2280
|
}, "recordPromptQueueWait");
|
|
2148
|
-
const
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2281
|
+
const createRuntimeBridgeTelemetry = /* @__PURE__ */ __name((workspaceHash) => {
|
|
2282
|
+
const telemetry = core.createDaemonBridgeTelemetry();
|
|
2283
|
+
telemetry.metrics = {
|
|
2284
|
+
sessionLifecycle(action) {
|
|
2285
|
+
core.recordDaemonSessionLifecycle(action);
|
|
2286
|
+
core.emitDaemonLog(
|
|
2287
|
+
`Session ${action}.`,
|
|
2288
|
+
{
|
|
2289
|
+
"qwen-code.workspace.hash": workspaceHash
|
|
2290
|
+
},
|
|
2291
|
+
{
|
|
2292
|
+
eventName: `qwen-code.daemon.session.${action}`
|
|
2293
|
+
}
|
|
2294
|
+
);
|
|
2295
|
+
},
|
|
2296
|
+
channelLifecycle(action, expected) {
|
|
2297
|
+
core.recordDaemonChannelLifecycle(action, expected);
|
|
2298
|
+
core.emitDaemonLog(
|
|
2299
|
+
action === "spawn" ? "ACP channel spawned." : `ACP channel exited (expected=${expected ?? true}).`,
|
|
2300
|
+
{
|
|
2301
|
+
...action === "exit" ? { "qwen-code.daemon.channel.expected": expected ?? true } : {}
|
|
2302
|
+
},
|
|
2303
|
+
{
|
|
2304
|
+
eventName: `qwen-code.daemon.channel.${action}`,
|
|
2305
|
+
...expected === false && action === "exit" ? { severityNumber: 13 } : {}
|
|
2306
|
+
}
|
|
2307
|
+
);
|
|
2308
|
+
},
|
|
2309
|
+
promptQueueWait(durationMs) {
|
|
2310
|
+
recordPromptQueueWait(durationMs);
|
|
2311
|
+
metricsRing.recordPromptQueueWait(durationMs);
|
|
2312
|
+
},
|
|
2313
|
+
promptDuration(durationMs) {
|
|
2314
|
+
core.recordDaemonPromptDuration(durationMs);
|
|
2315
|
+
metricsRing.recordPromptDuration(durationMs);
|
|
2316
|
+
},
|
|
2317
|
+
cancelled: core.recordDaemonCancel,
|
|
2318
|
+
// Per-round model token usage + LLM round-trip time sniffed off
|
|
2319
|
+
// `agent_message_chunk._meta` (`usage` + `durationMs`) at the bridge's
|
|
2320
|
+
// single session/update fan-in. Increments (not cumulative), so the ring
|
|
2321
|
+
// sums tokens per window (token-burn chart) and pools the round-trip times
|
|
2322
|
+
// for the LLM-latency percentiles.
|
|
2323
|
+
tokenUsage(inputTokens, outputTokens, durationMs) {
|
|
2324
|
+
metricsRing.recordTokens(inputTokens, outputTokens);
|
|
2325
|
+
if (typeof durationMs === "number") {
|
|
2326
|
+
metricsRing.recordLlmDuration(durationMs);
|
|
2172
2327
|
}
|
|
2173
|
-
);
|
|
2174
|
-
},
|
|
2175
|
-
promptQueueWait(durationMs) {
|
|
2176
|
-
recordPromptQueueWait(durationMs);
|
|
2177
|
-
metricsRing.recordPromptQueueWait(durationMs);
|
|
2178
|
-
},
|
|
2179
|
-
promptDuration(durationMs) {
|
|
2180
|
-
core.recordDaemonPromptDuration(durationMs);
|
|
2181
|
-
metricsRing.recordPromptDuration(durationMs);
|
|
2182
|
-
},
|
|
2183
|
-
cancelled: core.recordDaemonCancel,
|
|
2184
|
-
// Per-round model token usage + LLM round-trip time sniffed off
|
|
2185
|
-
// `agent_message_chunk._meta` (`usage` + `durationMs`) at the bridge's
|
|
2186
|
-
// single session/update fan-in. Increments (not cumulative), so the ring
|
|
2187
|
-
// sums tokens per window (token-burn chart) and pools the round-trip times
|
|
2188
|
-
// for the LLM-latency percentiles.
|
|
2189
|
-
tokenUsage(inputTokens, outputTokens, durationMs) {
|
|
2190
|
-
metricsRing.recordTokens(inputTokens, outputTokens);
|
|
2191
|
-
if (typeof durationMs === "number") {
|
|
2192
|
-
metricsRing.recordLlmDuration(durationMs);
|
|
2193
2328
|
}
|
|
2194
|
-
}
|
|
2195
|
-
|
|
2329
|
+
};
|
|
2330
|
+
return telemetry;
|
|
2331
|
+
}, "createRuntimeBridgeTelemetry");
|
|
2332
|
+
const daemonTelemetry = createRuntimeBridgeTelemetry(daemonWorkspaceHash);
|
|
2196
2333
|
const permissionAuditRing = new PermissionAuditRing();
|
|
2197
2334
|
const permissionAuditPublisher = createPermissionAuditPublisher({
|
|
2198
2335
|
ring: permissionAuditRing
|
|
@@ -2239,7 +2376,17 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2239
2376
|
pathLocks: sharedPathLocks,
|
|
2240
2377
|
...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
|
|
2241
2378
|
});
|
|
2379
|
+
const routeFsFactory = runtime.resolveBridgeFsFactory({
|
|
2380
|
+
// REST routes still return primary-relative paths, so keep their
|
|
2381
|
+
// filesystem boundary primary-only until responses carry root IDs.
|
|
2382
|
+
boundWorkspaces: [boundWorkspace],
|
|
2383
|
+
trusted: trustedWorkspace,
|
|
2384
|
+
emit: deps.fsAuditEmit,
|
|
2385
|
+
pathLocks: sharedPathLocks,
|
|
2386
|
+
...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
|
|
2387
|
+
});
|
|
2242
2388
|
const channelFactory = runtime.createSpawnChannelFactory({
|
|
2389
|
+
sourceEnv: runtimeEffectiveEnv,
|
|
2243
2390
|
onDiagnosticLine: diagnosticSink,
|
|
2244
2391
|
pipeHooks: {
|
|
2245
2392
|
onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
|
|
@@ -2252,10 +2399,21 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2252
2399
|
},
|
|
2253
2400
|
...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
|
|
2254
2401
|
});
|
|
2255
|
-
const statusProvider = runtime.createDaemonStatusProvider(
|
|
2256
|
-
|
|
2402
|
+
const statusProvider = runtime.createDaemonStatusProvider({
|
|
2403
|
+
env: runtimeEffectiveEnv
|
|
2404
|
+
});
|
|
2405
|
+
const workspaceProvidersStatusProvider = runtime.createWorkspaceProvidersStatusProvider({
|
|
2406
|
+
env: runtimeEffectiveEnv
|
|
2407
|
+
});
|
|
2257
2408
|
const workspaceSkillsStatusProvider = runtime.createWorkspaceSkillsStatusProvider();
|
|
2258
2409
|
const clientMcpSenderRegistry = new ClientMcpSenderRegistry();
|
|
2410
|
+
const runtimeBridges = [];
|
|
2411
|
+
const totalSessionAdmission = runtime.createTotalSessionAdmissionController(
|
|
2412
|
+
{
|
|
2413
|
+
maxTotalSessions: opts.maxTotalSessions,
|
|
2414
|
+
getBridges: /* @__PURE__ */ __name(() => runtimeBridges.length > 0 ? runtimeBridges : bridgeRef ? [bridgeRef] : [], "getBridges")
|
|
2415
|
+
}
|
|
2416
|
+
);
|
|
2259
2417
|
const persistDisabledToolsFn = /* @__PURE__ */ __name((workspace, toolName, enabled) => withSettingsLock(workspace, async () => {
|
|
2260
2418
|
const fresh = settingsRuntime.settings.loadSettings(workspace);
|
|
2261
2419
|
const wsScope = fresh.forScope(WORKSPACE_SETTING_SCOPE).settings;
|
|
@@ -2307,8 +2465,10 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2307
2465
|
// connection that hosts a named client MCP server (#5626).
|
|
2308
2466
|
clientMcpSender: clientMcpSenderRegistry.lookup,
|
|
2309
2467
|
maxSessions: opts.maxSessions,
|
|
2468
|
+
freshSessionAdmission: totalSessionAdmission.admit,
|
|
2310
2469
|
...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
|
|
2311
2470
|
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
2471
|
+
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
2312
2472
|
...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
|
|
2313
2473
|
...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
|
|
2314
2474
|
...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
|
|
@@ -2331,7 +2491,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2331
2491
|
});
|
|
2332
2492
|
if (!deps.bridge) {
|
|
2333
2493
|
bridgeRef = bridge;
|
|
2494
|
+
internalRuntimeBridgesForCleanup.push(bridge);
|
|
2334
2495
|
}
|
|
2496
|
+
runtimeBridges.push(bridge);
|
|
2335
2497
|
const workspaceService = runtime.createDaemonWorkspaceService({
|
|
2336
2498
|
boundWorkspace,
|
|
2337
2499
|
contextFilename: contextFilenameForInit ?? "QWEN.md",
|
|
@@ -2346,18 +2508,273 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2346
2508
|
const fresh = settingsRuntime.settings.loadSettings(workspace, {
|
|
2347
2509
|
skipLoadEnvironment: true
|
|
2348
2510
|
});
|
|
2349
|
-
|
|
2511
|
+
const result = settingsRuntime.settings.reloadEnvironment(
|
|
2350
2512
|
fresh.merged,
|
|
2351
2513
|
workspace
|
|
2352
2514
|
);
|
|
2515
|
+
let refreshedRuntimeEnv;
|
|
2516
|
+
let fallbackReason;
|
|
2517
|
+
try {
|
|
2518
|
+
refreshedRuntimeEnv = settingsRuntime.environment.buildRuntimeEnvironment(
|
|
2519
|
+
fresh.merged,
|
|
2520
|
+
workspace,
|
|
2521
|
+
daemonRuntimeBaseEnv
|
|
2522
|
+
);
|
|
2523
|
+
} catch (err) {
|
|
2524
|
+
fallbackReason = err instanceof Error ? err.message : String(err);
|
|
2525
|
+
daemonLog.warn(
|
|
2526
|
+
"failed to rebuild runtime env snapshot after daemon env reload; preserving previous runtime env",
|
|
2527
|
+
{
|
|
2528
|
+
error: fallbackReason
|
|
2529
|
+
}
|
|
2530
|
+
);
|
|
2531
|
+
refreshedRuntimeEnv = {
|
|
2532
|
+
effectiveEnv: { ...runtimeEffectiveEnv },
|
|
2533
|
+
overlayKeys: [...primaryRuntimeEnv.overlayKeys],
|
|
2534
|
+
envFilePaths: [...primaryRuntimeEnv.envFilePaths],
|
|
2535
|
+
envFileReadFailed: primaryRuntimeEnv.envFileReadFailed ?? false,
|
|
2536
|
+
envFileReadFailures: [
|
|
2537
|
+
...primaryRuntimeEnv.envFileReadFailures ?? []
|
|
2538
|
+
]
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
logRuntimeEnvFileReadFailures(workspace, refreshedRuntimeEnv);
|
|
2542
|
+
replaceRuntimeEffectiveEnv(refreshedRuntimeEnv.effectiveEnv);
|
|
2543
|
+
if (fallbackReason) {
|
|
2544
|
+
primaryRuntimeEnv.fallbackReason = fallbackReason;
|
|
2545
|
+
} else {
|
|
2546
|
+
delete primaryRuntimeEnv.fallbackReason;
|
|
2547
|
+
}
|
|
2548
|
+
primaryRuntimeEnv.envFileReadFailed = refreshedRuntimeEnv.envFileReadFailed;
|
|
2549
|
+
primaryRuntimeEnv.envFileReadFailures.splice(
|
|
2550
|
+
0,
|
|
2551
|
+
primaryRuntimeEnv.envFileReadFailures.length,
|
|
2552
|
+
...refreshedRuntimeEnv.envFileReadFailures
|
|
2553
|
+
);
|
|
2554
|
+
primaryRuntimeEnv.overlayKeys.splice(
|
|
2555
|
+
0,
|
|
2556
|
+
primaryRuntimeEnv.overlayKeys.length,
|
|
2557
|
+
...refreshedRuntimeEnv.overlayKeys
|
|
2558
|
+
);
|
|
2559
|
+
primaryRuntimeEnv.envFilePaths.splice(
|
|
2560
|
+
0,
|
|
2561
|
+
primaryRuntimeEnv.envFilePaths.length,
|
|
2562
|
+
...refreshedRuntimeEnv.envFilePaths
|
|
2563
|
+
);
|
|
2564
|
+
return result;
|
|
2353
2565
|
}), "reloadDaemonEnv"),
|
|
2354
2566
|
queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => bridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
|
|
2355
2567
|
invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => bridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
|
|
2356
2568
|
refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => bridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
|
|
2357
2569
|
publishWorkspaceEvent: /* @__PURE__ */ __name((event) => bridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
|
|
2358
2570
|
});
|
|
2571
|
+
const workspaceRuntimes = [
|
|
2572
|
+
{
|
|
2573
|
+
workspaceId: daemonWorkspaceHash,
|
|
2574
|
+
workspaceCwd: boundWorkspace,
|
|
2575
|
+
primary: true,
|
|
2576
|
+
trusted: trustedWorkspace,
|
|
2577
|
+
env: primaryRuntimeEnv,
|
|
2578
|
+
bridge,
|
|
2579
|
+
workspaceService,
|
|
2580
|
+
routeFileSystemFactory: routeFsFactory,
|
|
2581
|
+
clientMcpSenderRegistry
|
|
2582
|
+
}
|
|
2583
|
+
];
|
|
2584
|
+
const createRuntimeEnvMetadata = /* @__PURE__ */ __name((workspace, settings) => {
|
|
2585
|
+
const snapshot = settings ? settingsRuntime.environment.buildRuntimeEnvironment(
|
|
2586
|
+
settings.merged,
|
|
2587
|
+
workspace,
|
|
2588
|
+
daemonRuntimeBaseEnv
|
|
2589
|
+
) : {
|
|
2590
|
+
effectiveEnv: { ...daemonRuntimeBaseEnv },
|
|
2591
|
+
overlayKeys: Object.freeze([]),
|
|
2592
|
+
envFilePaths: Object.freeze([]),
|
|
2593
|
+
envFileReadFailed: false,
|
|
2594
|
+
envFileReadFailures: Object.freeze([])
|
|
2595
|
+
};
|
|
2596
|
+
logRuntimeEnvFileReadFailures(workspace, snapshot);
|
|
2597
|
+
const effectiveEnv = { ...snapshot.effectiveEnv };
|
|
2598
|
+
const metadata = {
|
|
2599
|
+
mode: "runtime-overlay",
|
|
2600
|
+
overlayKeys: [...snapshot.overlayKeys],
|
|
2601
|
+
effectiveEnv,
|
|
2602
|
+
envFilePaths: [...snapshot.envFilePaths],
|
|
2603
|
+
envFileReadFailed: snapshot.envFileReadFailed,
|
|
2604
|
+
envFileReadFailures: [...snapshot.envFileReadFailures]
|
|
2605
|
+
};
|
|
2606
|
+
return {
|
|
2607
|
+
metadata,
|
|
2608
|
+
effectiveEnv,
|
|
2609
|
+
replace(nextEnv) {
|
|
2610
|
+
for (const key of Object.keys(effectiveEnv)) {
|
|
2611
|
+
delete effectiveEnv[key];
|
|
2612
|
+
}
|
|
2613
|
+
Object.assign(effectiveEnv, nextEnv);
|
|
2614
|
+
}
|
|
2615
|
+
};
|
|
2616
|
+
}, "createRuntimeEnvMetadata");
|
|
2617
|
+
for (const workspaceInput of workspaceInputs.slice(1)) {
|
|
2618
|
+
let secondarySettings;
|
|
2619
|
+
try {
|
|
2620
|
+
secondarySettings = settingsRuntime.settings.loadSettings(
|
|
2621
|
+
workspaceInput.cwd
|
|
2622
|
+
);
|
|
2623
|
+
} catch (err) {
|
|
2624
|
+
writeStderrLine(
|
|
2625
|
+
`qwen serve: could not read full settings for secondary workspace ${workspaceInput.cwd} (${err instanceof Error ? err.message : String(err)}); falling back to defaults.`
|
|
2626
|
+
);
|
|
2627
|
+
}
|
|
2628
|
+
const secondaryTrusted = secondarySettings ? settingsRuntime.trustedFolders.getWorkspaceTrustStatus(
|
|
2629
|
+
secondarySettings.merged,
|
|
2630
|
+
workspaceInput.cwd
|
|
2631
|
+
).effective.state === "trusted" : false;
|
|
2632
|
+
if (!secondaryTrusted) {
|
|
2633
|
+
daemonLog.warn("secondary workspace is not trusted", {
|
|
2634
|
+
workspace: workspaceInput.cwd,
|
|
2635
|
+
trustSettingsAvailable: secondarySettings !== void 0
|
|
2636
|
+
});
|
|
2637
|
+
}
|
|
2638
|
+
const secondaryEnv = createRuntimeEnvMetadata(
|
|
2639
|
+
workspaceInput.cwd,
|
|
2640
|
+
secondarySettings
|
|
2641
|
+
);
|
|
2642
|
+
const secondaryWorkspaceHash = core.hashDaemonWorkspace(
|
|
2643
|
+
workspaceInput.cwd
|
|
2644
|
+
);
|
|
2645
|
+
const secondaryStatusProvider = runtime.createDaemonStatusProvider({
|
|
2646
|
+
env: secondaryEnv.effectiveEnv
|
|
2647
|
+
});
|
|
2648
|
+
const secondaryBridgeFsFactory = runtime.resolveBridgeFsFactory({
|
|
2649
|
+
boundWorkspaces: [workspaceInput.cwd],
|
|
2650
|
+
trusted: secondaryTrusted,
|
|
2651
|
+
emit: deps.fsAuditEmit,
|
|
2652
|
+
pathLocks: sharedPathLocks,
|
|
2653
|
+
...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
|
|
2654
|
+
});
|
|
2655
|
+
const secondaryChannelFactory = runtime.createSpawnChannelFactory({
|
|
2656
|
+
sourceEnv: secondaryEnv.effectiveEnv,
|
|
2657
|
+
onDiagnosticLine: diagnosticSink,
|
|
2658
|
+
pipeHooks: {
|
|
2659
|
+
onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
|
|
2660
|
+
onMessageReceived: /* @__PURE__ */ __name((bytes) => recordPipeMessage("inbound", bytes), "onMessageReceived"),
|
|
2661
|
+
onMessageObserved: /* @__PURE__ */ __name(({ direction, bytes, message }) => observeLargePipeFrame({
|
|
2662
|
+
direction: daemonPipeDirection(direction),
|
|
2663
|
+
bytes,
|
|
2664
|
+
message
|
|
2665
|
+
}), "onMessageObserved")
|
|
2666
|
+
},
|
|
2667
|
+
...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
|
|
2668
|
+
});
|
|
2669
|
+
const secondaryClientMcpSenderRegistry = new ClientMcpSenderRegistry();
|
|
2670
|
+
const secondaryBridge = runtime.createAcpSessionBridge({
|
|
2671
|
+
clientMcpSender: secondaryClientMcpSenderRegistry.lookup,
|
|
2672
|
+
maxSessions: opts.maxSessions,
|
|
2673
|
+
freshSessionAdmission: totalSessionAdmission.admit,
|
|
2674
|
+
...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
|
|
2675
|
+
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
2676
|
+
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
2677
|
+
...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
|
|
2678
|
+
...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
|
|
2679
|
+
...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
|
|
2680
|
+
...opts.permissionResponseTimeoutMs !== void 0 ? { permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs } : {},
|
|
2681
|
+
boundWorkspace: workspaceInput.cwd,
|
|
2682
|
+
sessionShellCommandEnabled,
|
|
2683
|
+
childEnvOverrides,
|
|
2684
|
+
channelFactory: secondaryChannelFactory,
|
|
2685
|
+
onDiagnosticLine: diagnosticSink,
|
|
2686
|
+
telemetry: createRuntimeBridgeTelemetry(secondaryWorkspaceHash),
|
|
2687
|
+
...permissionPolicy !== void 0 ? { permissionPolicy } : {},
|
|
2688
|
+
...permissionConsensusQuorum !== void 0 ? {
|
|
2689
|
+
permissionConsensusQuorum
|
|
2690
|
+
} : {},
|
|
2691
|
+
permissionAudit: permissionAuditPublisher,
|
|
2692
|
+
statusProvider: secondaryStatusProvider,
|
|
2693
|
+
fileSystem: createBridgeFileSystemAdapter(secondaryBridgeFsFactory),
|
|
2694
|
+
persistApprovalMode: /* @__PURE__ */ __name((workspace, mode) => withSettingsLock(workspace, async () => {
|
|
2695
|
+
const fresh = settingsRuntime.settings.loadSettings(workspace);
|
|
2696
|
+
fresh.setValue(WORKSPACE_SETTING_SCOPE, "tools.approvalMode", mode);
|
|
2697
|
+
}), "persistApprovalMode")
|
|
2698
|
+
});
|
|
2699
|
+
runtimeBridges.push(secondaryBridge);
|
|
2700
|
+
internalRuntimeBridgesForCleanup.push(secondaryBridge);
|
|
2701
|
+
const secondaryWorkspaceService = runtime.createDaemonWorkspaceService({
|
|
2702
|
+
boundWorkspace: workspaceInput.cwd,
|
|
2703
|
+
contextFilename: contextFilenameForInit ?? "QWEN.md",
|
|
2704
|
+
statusProvider: secondaryStatusProvider,
|
|
2705
|
+
workspaceProvidersStatusProvider: runtime.createWorkspaceProvidersStatusProvider({
|
|
2706
|
+
env: secondaryEnv.effectiveEnv
|
|
2707
|
+
}),
|
|
2708
|
+
workspaceSkillsStatusProvider: runtime.createWorkspaceSkillsStatusProvider(),
|
|
2709
|
+
isChannelLive: /* @__PURE__ */ __name(() => secondaryBridge.isChannelLive(), "isChannelLive"),
|
|
2710
|
+
persistDisabledTools: persistDisabledToolsFn,
|
|
2711
|
+
persistSetting: persistSettingFn,
|
|
2712
|
+
persistSettings: persistSettingsFn,
|
|
2713
|
+
reloadDaemonEnv: /* @__PURE__ */ __name((workspace) => withSettingsLock(workspace, async () => {
|
|
2714
|
+
const fresh = settingsRuntime.settings.loadSettings(workspace, {
|
|
2715
|
+
skipLoadEnvironment: true
|
|
2716
|
+
});
|
|
2717
|
+
const result = settingsRuntime.settings.reloadEnvironment(
|
|
2718
|
+
fresh.merged,
|
|
2719
|
+
workspace
|
|
2720
|
+
);
|
|
2721
|
+
try {
|
|
2722
|
+
const refreshedRuntimeEnv = settingsRuntime.environment.buildRuntimeEnvironment(
|
|
2723
|
+
fresh.merged,
|
|
2724
|
+
workspace,
|
|
2725
|
+
daemonRuntimeBaseEnv
|
|
2726
|
+
);
|
|
2727
|
+
logRuntimeEnvFileReadFailures(workspace, refreshedRuntimeEnv);
|
|
2728
|
+
secondaryEnv.replace(refreshedRuntimeEnv.effectiveEnv);
|
|
2729
|
+
secondaryEnv.metadata.envFileReadFailed = refreshedRuntimeEnv.envFileReadFailed;
|
|
2730
|
+
secondaryEnv.metadata.envFileReadFailures.splice(
|
|
2731
|
+
0,
|
|
2732
|
+
secondaryEnv.metadata.envFileReadFailures.length,
|
|
2733
|
+
...refreshedRuntimeEnv.envFileReadFailures
|
|
2734
|
+
);
|
|
2735
|
+
secondaryEnv.metadata.overlayKeys.splice(
|
|
2736
|
+
0,
|
|
2737
|
+
secondaryEnv.metadata.overlayKeys.length,
|
|
2738
|
+
...refreshedRuntimeEnv.overlayKeys
|
|
2739
|
+
);
|
|
2740
|
+
secondaryEnv.metadata.envFilePaths.splice(
|
|
2741
|
+
0,
|
|
2742
|
+
secondaryEnv.metadata.envFilePaths.length,
|
|
2743
|
+
...refreshedRuntimeEnv.envFilePaths
|
|
2744
|
+
);
|
|
2745
|
+
delete secondaryEnv.metadata.fallbackReason;
|
|
2746
|
+
} catch (err) {
|
|
2747
|
+
secondaryEnv.metadata.fallbackReason = err instanceof Error ? err.message : String(err);
|
|
2748
|
+
daemonLog.warn(
|
|
2749
|
+
"failed to rebuild secondary runtime env snapshot after daemon env reload; preserving previous runtime env",
|
|
2750
|
+
{
|
|
2751
|
+
workspace,
|
|
2752
|
+
error: secondaryEnv.metadata.fallbackReason
|
|
2753
|
+
}
|
|
2754
|
+
);
|
|
2755
|
+
}
|
|
2756
|
+
return result;
|
|
2757
|
+
}), "reloadDaemonEnv"),
|
|
2758
|
+
queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => secondaryBridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
|
|
2759
|
+
invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => secondaryBridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
|
|
2760
|
+
refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => secondaryBridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
|
|
2761
|
+
publishWorkspaceEvent: /* @__PURE__ */ __name((event) => secondaryBridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
|
|
2762
|
+
});
|
|
2763
|
+
workspaceRuntimes.push({
|
|
2764
|
+
workspaceId: secondaryWorkspaceHash,
|
|
2765
|
+
workspaceCwd: workspaceInput.cwd,
|
|
2766
|
+
primary: false,
|
|
2767
|
+
trusted: secondaryTrusted,
|
|
2768
|
+
env: secondaryEnv.metadata,
|
|
2769
|
+
bridge: secondaryBridge,
|
|
2770
|
+
workspaceService: secondaryWorkspaceService,
|
|
2771
|
+
routeFileSystemFactory: secondaryBridgeFsFactory,
|
|
2772
|
+
clientMcpSenderRegistry: secondaryClientMcpSenderRegistry
|
|
2773
|
+
});
|
|
2774
|
+
}
|
|
2775
|
+
const workspaceRegistry = runtime.createWorkspaceRegistry(workspaceRuntimes);
|
|
2359
2776
|
core.registerDaemonGaugeCallbacks({
|
|
2360
|
-
sessionCount: /* @__PURE__ */ __name(() => bridge.sessionCount, "sessionCount"),
|
|
2777
|
+
sessionCount: /* @__PURE__ */ __name(() => workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0), "sessionCount"),
|
|
2361
2778
|
sseCount: /* @__PURE__ */ __name(() => runtime.getActiveSseCount(), "sseCount"),
|
|
2362
2779
|
heapUsed: /* @__PURE__ */ __name(() => process.memoryUsage().heapUsed, "heapUsed")
|
|
2363
2780
|
});
|
|
@@ -2397,9 +2814,15 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2397
2814
|
cpuPercent,
|
|
2398
2815
|
rssBytes: mem.rss,
|
|
2399
2816
|
heapUsedBytes: mem.heapUsed,
|
|
2400
|
-
activeSessions: bridge.sessionCount,
|
|
2401
|
-
activePrompts:
|
|
2402
|
-
|
|
2817
|
+
activeSessions: workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0),
|
|
2818
|
+
activePrompts: workspaceRegistry.list().reduce(
|
|
2819
|
+
(sum, item) => sum + (item.bridge.activePromptCount ?? 0),
|
|
2820
|
+
0
|
|
2821
|
+
),
|
|
2822
|
+
queuedPrompts: workspaceRegistry.list().reduce(
|
|
2823
|
+
(sum, item) => sum + (item.bridge.pendingPromptTotal ?? 0),
|
|
2824
|
+
0
|
|
2825
|
+
),
|
|
2403
2826
|
eventLoopLagP99Ms,
|
|
2404
2827
|
sseConnections: runtime.getActiveSseCount(),
|
|
2405
2828
|
wsConnections: acp?.wsStreams ?? 0,
|
|
@@ -2442,6 +2865,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2442
2865
|
}
|
|
2443
2866
|
};
|
|
2444
2867
|
const app2 = runtime.createServeApp(opts, () => actualPort, {
|
|
2868
|
+
workspaceRegistry,
|
|
2445
2869
|
bridge,
|
|
2446
2870
|
webShellDir,
|
|
2447
2871
|
boundWorkspace,
|
|
@@ -2451,16 +2875,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2451
2875
|
// (keepalive) and reloads them on boot (rehydration). Off by default so
|
|
2452
2876
|
// direct createServeApp embeds/tests don't spawn sessions.
|
|
2453
2877
|
manageScheduledTaskSessions: true,
|
|
2454
|
-
fsFactory:
|
|
2455
|
-
// REST routes still return primary-relative paths, so keep their
|
|
2456
|
-
// filesystem boundary primary-only until responses carry root IDs.
|
|
2457
|
-
boundWorkspaces: [boundWorkspace],
|
|
2458
|
-
trusted: trustedWorkspace,
|
|
2459
|
-
emit: deps.fsAuditEmit,
|
|
2460
|
-
pathLocks: sharedPathLocks,
|
|
2461
|
-
...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
|
|
2462
|
-
}),
|
|
2878
|
+
fsFactory: routeFsFactory,
|
|
2463
2879
|
primaryWorkspaceTrusted: trustedWorkspace,
|
|
2880
|
+
primaryRuntimeEnv,
|
|
2464
2881
|
daemonLog,
|
|
2465
2882
|
getChannelWorkerSnapshot,
|
|
2466
2883
|
getPerfSnapshot: /* @__PURE__ */ __name(() => ({
|
|
@@ -2477,6 +2894,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2477
2894
|
}
|
|
2478
2895
|
}), "getPerfSnapshot"),
|
|
2479
2896
|
getMetricsSeries: /* @__PURE__ */ __name(() => metricsRing.snapshot(), "getMetricsSeries"),
|
|
2897
|
+
getTotalSessionAdmissionSnapshot: totalSessionAdmission.snapshot,
|
|
2480
2898
|
recordDaemonRequest: /* @__PURE__ */ __name((durationMs, statusCode) => metricsRing.recordRequest(durationMs, statusCode), "recordDaemonRequest"),
|
|
2481
2899
|
workspace: workspaceService,
|
|
2482
2900
|
// Reverse tool channel (#5626): the SAME registry wired into `bridge` above,
|
|
@@ -2545,6 +2963,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2545
2963
|
qwenCodeVersion: cliVersion,
|
|
2546
2964
|
sessionShellCommandEnabled,
|
|
2547
2965
|
permissionPolicy,
|
|
2966
|
+
multiWorkspaceCapabilitiesRequireRuntime: workspaceInputs.length > 1,
|
|
2548
2967
|
getRuntimeError: /* @__PURE__ */ __name(() => runtimeStartupError, "getRuntimeError"),
|
|
2549
2968
|
getChannelWorkerSnapshot,
|
|
2550
2969
|
onHealthServed: deferRuntimeUntilFirstHealth ? () => startRuntimeAfterHealth?.() : void 0
|
|
@@ -2694,6 +3113,8 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2694
3113
|
}, "cancelDeferredRuntimeStartup");
|
|
2695
3114
|
const shutdownBridgeAfterFailedStartup = /* @__PURE__ */ __name(async (bridge) => {
|
|
2696
3115
|
if (!bridge || deps.bridge) return;
|
|
3116
|
+
if (shutdownBridges.has(bridge)) return;
|
|
3117
|
+
shutdownBridges.add(bridge);
|
|
2697
3118
|
try {
|
|
2698
3119
|
await bridge.shutdown();
|
|
2699
3120
|
} catch (shutdownErr) {
|
|
@@ -2734,7 +3155,10 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2734
3155
|
await stopChannelWorkerAfterFailedStartup();
|
|
2735
3156
|
disposeDaemonEventLoopMonitor();
|
|
2736
3157
|
removeCurrentServePidfile();
|
|
2737
|
-
|
|
3158
|
+
const bridgesForCleanup = bridgeForCleanup ? [bridgeForCleanup, ...getRuntimeBridgesForCleanup()] : getRuntimeBridgesForCleanup();
|
|
3159
|
+
for (const bridge of [...new Set(bridgesForCleanup)]) {
|
|
3160
|
+
await shutdownBridgeAfterFailedStartup(bridge);
|
|
3161
|
+
}
|
|
2738
3162
|
markRuntimeFailed(error);
|
|
2739
3163
|
}, "failRuntimeStartup");
|
|
2740
3164
|
const armRuntimeStartupTimer = /* @__PURE__ */ __name(() => {
|
|
@@ -2843,7 +3267,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2843
3267
|
daemonLog.warn(`received ${signal} during drain \u2014 forcing exit`);
|
|
2844
3268
|
try {
|
|
2845
3269
|
channelWorker.killAllSync();
|
|
2846
|
-
|
|
3270
|
+
for (const runtimeBridge of getRuntimeBridgesForCleanup()) {
|
|
3271
|
+
runtimeBridge.killAllSync();
|
|
3272
|
+
}
|
|
2847
3273
|
removeCurrentServePidfile();
|
|
2848
3274
|
} catch (err) {
|
|
2849
3275
|
daemonLog.error(
|
|
@@ -2954,8 +3380,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2954
3380
|
);
|
|
2955
3381
|
});
|
|
2956
3382
|
removeCurrentServePidfile();
|
|
2957
|
-
const bridgeForShutdown
|
|
2958
|
-
|
|
3383
|
+
for (const bridgeForShutdown of getRuntimeBridgesForCleanup()) {
|
|
3384
|
+
if (shutdownBridges.has(bridgeForShutdown)) continue;
|
|
3385
|
+
shutdownBridges.add(bridgeForShutdown);
|
|
2959
3386
|
await bridgeForShutdown.shutdown().catch((err) => {
|
|
2960
3387
|
daemonLog.error(
|
|
2961
3388
|
"bridge shutdown error",
|
|
@@ -3034,8 +3461,8 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3034
3461
|
}
|
|
3035
3462
|
}, "onListening");
|
|
3036
3463
|
let server;
|
|
3464
|
+
let httpsServer;
|
|
3037
3465
|
if (tlsOptions) {
|
|
3038
|
-
let httpsServer;
|
|
3039
3466
|
try {
|
|
3040
3467
|
httpsServer = https.createServer(tlsOptions, app);
|
|
3041
3468
|
} catch (err) {
|
|
@@ -3046,14 +3473,40 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3046
3473
|
);
|
|
3047
3474
|
return;
|
|
3048
3475
|
}
|
|
3049
|
-
server = httpsServer.listen(opts.port, listenHostname, onListening);
|
|
3050
|
-
} else {
|
|
3051
|
-
server = app.listen(opts.port, listenHostname, onListening);
|
|
3052
3476
|
}
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3477
|
+
const tryListen = /* @__PURE__ */ __name((attemptPort, attempt) => {
|
|
3478
|
+
try {
|
|
3479
|
+
if (httpsServer) {
|
|
3480
|
+
httpsServer.removeAllListeners("listening");
|
|
3481
|
+
server = httpsServer.listen(attemptPort, listenHostname, onListening);
|
|
3482
|
+
} else {
|
|
3483
|
+
server = app.listen(attemptPort, listenHostname, onListening);
|
|
3484
|
+
}
|
|
3485
|
+
} catch (err) {
|
|
3486
|
+
removeCurrentServePidfile();
|
|
3487
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
3488
|
+
return;
|
|
3489
|
+
}
|
|
3490
|
+
server.once("error", (err) => {
|
|
3491
|
+
server.close();
|
|
3492
|
+
const nextPort = attemptPort + 1;
|
|
3493
|
+
if (err.code === "EADDRINUSE" && opts.port !== 0 && nextPort <= 65535 && attempt < MAX_PORT_ATTEMPTS - 1) {
|
|
3494
|
+
writeStderrLine(
|
|
3495
|
+
`qwen serve: port ${attemptPort} is in use, trying ${nextPort}...`
|
|
3496
|
+
);
|
|
3497
|
+
tryListen(nextPort, attempt + 1);
|
|
3498
|
+
} else {
|
|
3499
|
+
if (err.code === "EADDRINUSE" && attempt > 0) {
|
|
3500
|
+
writeStderrLine(
|
|
3501
|
+
`qwen serve: all ports ${opts.port}\u2013${attemptPort} are in use`
|
|
3502
|
+
);
|
|
3503
|
+
}
|
|
3504
|
+
removeCurrentServePidfile();
|
|
3505
|
+
reject(err);
|
|
3506
|
+
}
|
|
3507
|
+
});
|
|
3508
|
+
}, "tryListen");
|
|
3509
|
+
tryListen(opts.port, 0);
|
|
3057
3510
|
});
|
|
3058
3511
|
}
|
|
3059
3512
|
__name(runQwenServe, "runQwenServe");
|