@qwen-code/qwen-code 0.19.8 → 0.19.9-nightly.20260714.9dd8389eb
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/SKILL.md +1 -0
- package/bundled/qc-helper/docs/configuration/auth.md +40 -55
- package/bundled/qc-helper/docs/configuration/model-providers.md +224 -218
- package/bundled/qc-helper/docs/configuration/settings.md +61 -51
- package/bundled/qc-helper/docs/features/_meta.ts +1 -0
- package/bundled/qc-helper/docs/features/channels/dingtalk.md +12 -2
- package/bundled/qc-helper/docs/features/channels/overview.md +82 -7
- package/bundled/qc-helper/docs/features/channels/wecom.md +6 -0
- package/bundled/qc-helper/docs/features/code-review.md +109 -41
- package/bundled/qc-helper/docs/features/commands.md +45 -44
- package/bundled/qc-helper/docs/features/computer-use.md +77 -0
- package/bundled/qc-helper/docs/features/hooks.md +29 -0
- package/bundled/qc-helper/docs/features/tool-use-summaries.md +19 -23
- package/bundled/qc-helper/docs/integration-vscode.md +2 -2
- package/bundled/qc-helper/docs/qwen-serve.md +60 -22
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +2 -2
- package/bundled/review/DESIGN.md +303 -46
- package/bundled/review/SKILL.md +658 -165
- package/chunks/MaxSizedBox-QAYHOC4F.js +71 -0
- package/chunks/{StandaloneSessionPicker-EYRGH6PJ.js → StandaloneSessionPicker-D3R6YYX3.js} +82 -79
- package/chunks/{acpAgent-GRFTTRHW.js → acpAgent-ENHBW72A.js} +1178 -421
- package/chunks/agent-57LX4KMG.js +69 -0
- package/chunks/agent-headless-AC6EVNAP.js +63 -0
- package/chunks/{anthropicContentGenerator-CPF22MA7.js → anthropicContentGenerator-56U3YCP2.js} +187 -31
- package/chunks/{artifact-tool-D233YJFH.js → artifact-tool-BWZZJ42H.js} +5 -5
- package/chunks/{askUserQuestion-MKL5ZTMC.js → askUserQuestion-WU3S5A5T.js} +6 -6
- package/chunks/bridge-4OZH44MK.js +79 -0
- package/chunks/{ca-MKD32FQL.js → ca-C2JTT2N5.js} +68 -6
- package/chunks/channel-worker-group-K7QKH6IG.js +13 -0
- package/chunks/channel-worker-manager-5RWKSGEU.js +418 -0
- package/chunks/channel-worker-supervisor-PCDAZN4D.js +20 -0
- package/chunks/{chunk-CSOTA7KX.js → chunk-2FO5GFKZ.js} +2 -2
- package/chunks/{chunk-QQDPRDVW.js → chunk-2HRYPZT5.js} +1 -1
- package/chunks/{chunk-I6WGFJJ3.js → chunk-2MF6ICOL.js} +38 -12
- package/chunks/{chunk-X3YGAX7V.js → chunk-2UUAIFQO.js} +4 -2
- package/chunks/{chunk-2PSWA5ID.js → chunk-2X56YUSZ.js} +1 -1
- package/chunks/{chunk-NQKLOAVJ.js → chunk-2Z5UX4KI.js} +2 -2
- package/chunks/chunk-3MX7D6QN.js +516 -0
- package/chunks/{chunk-YDOXPLYL.js → chunk-4DYYRLIE.js} +3890 -975
- package/chunks/{chunk-OQXDAMKY.js → chunk-4FPUAYTT.js} +8 -8
- package/chunks/{chunk-55ZMG67I.js → chunk-4LD5APFL.js} +4 -4
- package/chunks/{chunk-YKZIAK7C.js → chunk-4LJNI7MU.js} +166 -37
- package/chunks/{chunk-BOBOCR5H.js → chunk-4QOPEEL2.js} +4 -4
- package/chunks/{chunk-UIDXQNMV.js → chunk-4WGODMVR.js} +1 -1
- package/chunks/{chunk-E6US47KI.js → chunk-4WKAA4KS.js} +1 -1
- package/chunks/{chunk-3GONHQOA.js → chunk-57OAHC2Y.js} +1 -1
- package/chunks/{chunk-JZSY4WP3.js → chunk-5DTTYNB7.js} +1 -1
- package/chunks/chunk-5HBA2Z7V.js +28 -0
- package/chunks/{chunk-SKAZWEV5.js → chunk-5M6IDOMF.js} +35 -98
- package/chunks/{chunk-A4BMJM77.js → chunk-5O2XNYP6.js} +1 -0
- package/chunks/{chunk-GO6LNQXT.js → chunk-6AM5D4ME.js} +1 -1
- package/chunks/{chunk-BJBWRCSK.js → chunk-6H67XLET.js} +1 -1
- package/chunks/{chunk-AYNCLGTW.js → chunk-6HHAADP2.js} +8 -51
- package/chunks/{chunk-VZ7HY3YU.js → chunk-6OATMEYN.js} +3 -3
- package/chunks/{chunk-3UP777ZS.js → chunk-6RLROE6G.js} +1 -1
- package/chunks/{chunk-ZERZSAZL.js → chunk-75DOP5OR.js} +2 -2
- package/chunks/{chunk-RMLZAUWH.js → chunk-7BIZARI2.js} +10 -12
- package/chunks/{chunk-GN3F6PIU.js → chunk-7NAWTFVY.js} +5 -5
- package/chunks/{chunk-22MNNNXE.js → chunk-7NFB7LBQ.js} +11 -3
- package/chunks/{chunk-ZL5HN75Q.js → chunk-7R4DPSRA.js} +37 -3
- package/chunks/{chunk-BVYU3ZTI.js → chunk-7U7UIO5W.js} +1005 -942
- package/chunks/{chunk-SAIILPQ3.js → chunk-7X7TEQNX.js} +5 -3
- package/chunks/{chunk-IRJWHZWU.js → chunk-A4UCTEB5.js} +2 -2
- package/chunks/{chunk-WF4FAXDL.js → chunk-AAS2Q2TV.js} +62 -62
- package/chunks/{chunk-O7FIRWJV.js → chunk-AAWKZ5R7.js} +3 -3
- package/chunks/{chunk-JCH35JB3.js → chunk-AGBFWLA5.js} +2 -2
- package/chunks/{chunk-QYUE6W3T.js → chunk-ALGGS7UH.js} +2 -39
- package/chunks/{chunk-WMPVYQ4P.js → chunk-ARKANCNX.js} +3 -2
- package/chunks/{chunk-HDOH3QYE.js → chunk-ASVORVFT.js} +2 -2
- package/chunks/{chunk-CHB5SLZZ.js → chunk-AUGSSJX3.js} +3 -3
- package/chunks/{chunk-PUVCVELY.js → chunk-B6ABUBYY.js} +4 -4
- package/chunks/{chunk-L4AMBVQG.js → chunk-B6KHOCU7.js} +49 -21
- package/chunks/{chunk-HW4N45EE.js → chunk-B7NUUEXC.js} +38 -11
- package/chunks/{chunk-CD6USWHZ.js → chunk-BBNVFRGD.js} +2 -2
- package/chunks/{chunk-ZN5T4BHI.js → chunk-BPZALHVR.js} +2 -2
- package/chunks/{chunk-VGGOPZUL.js → chunk-C4CXFRKY.js} +12 -5
- package/chunks/{chunk-OFEVLU4C.js → chunk-CARU2RR2.js} +1 -1
- package/chunks/{chunk-SQ2UATK7.js → chunk-CLTWL6HD.js} +11 -11
- package/chunks/{chunk-GLE2YUPU.js → chunk-COH43MRJ.js} +1 -1
- package/chunks/{chunk-E5A7LHNN.js → chunk-CPBF7KYF.js} +1 -1
- package/chunks/{chunk-UWCTAVOD.js → chunk-CR3C7WXL.js} +1 -1
- package/chunks/{chunk-DIWVZ3VM.js → chunk-CSACSGAW.js} +5 -5
- package/chunks/{chunk-5P5XGNYH.js → chunk-CU3L64TP.js} +1 -1
- package/chunks/{chunk-IWKSG2AR.js → chunk-CXAOG665.js} +1 -1
- package/chunks/{chunk-64WXLC72.js → chunk-DJ2GSRLV.js} +1 -1
- package/chunks/chunk-DKXW66XA.js +38 -0
- package/chunks/{chunk-QN5NZ3UQ.js → chunk-DMTGGOSA.js} +2 -2
- package/chunks/{chunk-JZHIQJOE.js → chunk-DMTQY5GY.js} +6 -6
- package/chunks/{chunk-GSHQYYIV.js → chunk-DNKX35GS.js} +6 -26
- package/chunks/{chunk-6IAWPIQ6.js → chunk-DPSWJWZI.js} +4 -3
- package/chunks/{chunk-X2XNQQJI.js → chunk-E2UVIFI2.js} +186 -399
- package/chunks/{chunk-KHDZHZMH.js → chunk-E5Z2AVNV.js} +1 -1
- package/chunks/{chunk-3B26UVCX.js → chunk-E67NFMF4.js} +39 -10
- package/chunks/{chunk-ON3JA3RU.js → chunk-EU3U7USF.js} +7 -9
- package/chunks/{chunk-L46XKEGM.js → chunk-EUNRLYJG.js} +5 -8
- package/chunks/{chunk-OACJLMLD.js → chunk-FBU7WRZI.js} +18 -2
- package/chunks/{chunk-5IFG2VC4.js → chunk-FCMNKVXT.js} +1 -1
- package/chunks/{chunk-A5JOJ77H.js → chunk-FDL4PB5H.js} +38 -15
- package/chunks/{chunk-E7KNELIZ.js → chunk-FSA7ERJ2.js} +2 -2
- package/chunks/{chunk-TI3BWD4D.js → chunk-G6QTKQN4.js} +39 -19
- package/chunks/{chunk-44NROQYV.js → chunk-GDQQRV43.js} +4 -4
- package/chunks/{chunk-O2YT7VB4.js → chunk-GOXKNSDZ.js} +2 -65
- package/chunks/{chunk-V35MD7KN.js → chunk-GRC5HGPI.js} +1 -1
- package/chunks/chunk-GYGGUR4Q.js +253 -0
- package/chunks/{chunk-S6RLAIUR.js → chunk-GYTKQYDB.js} +1 -1
- package/chunks/{chunk-A2X3KLC3.js → chunk-GZXCZHCT.js} +3 -3
- package/chunks/{chunk-K5PGHDBN.js → chunk-H6XPXXMH.js} +1 -1
- package/chunks/{chunk-E7EMCSUG.js → chunk-HE54PGVI.js} +64 -42
- package/chunks/{chunk-KYMBIKIW.js → chunk-HTHUX2T5.js} +1 -1
- package/chunks/{chunk-LQ7TMOCE.js → chunk-HTO4JFDZ.js} +1 -1
- package/chunks/chunk-HZYUNZDQ.js +296 -0
- package/chunks/chunk-IDS7MSUP.js +74 -0
- package/chunks/chunk-J2TDDOSM.js +493 -0
- package/chunks/{chunk-4CGOWHKM.js → chunk-J4MOFEOK.js} +2 -2
- package/chunks/{chunk-22IFUCVR.js → chunk-JESCGQM3.js} +1 -1
- package/chunks/chunk-JR63TOV4.js +91 -0
- package/chunks/chunk-K3PPUB46.js +445 -0
- package/chunks/{chunk-42XGFRJS.js → chunk-KKRTYONM.js} +8 -6
- package/chunks/{chunk-GGQQA4JW.js → chunk-KSO42X3Z.js} +15 -2
- package/chunks/{chunk-MRO43B25.js → chunk-KW7NOTN6.js} +1 -1
- package/chunks/{chunk-54YZOP7P.js → chunk-L573Z2QZ.js} +11894 -5190
- package/chunks/{chunk-TLWA7TPR.js → chunk-L5U3ELZX.js} +2 -2
- package/chunks/{chunk-WHJQ3JUS.js → chunk-LAM6CGP5.js} +10 -10
- package/chunks/{chunk-H6EMK6QK.js → chunk-LQIDP6K5.js} +11913 -5207
- package/chunks/{chunk-MZ7BABX3.js → chunk-LXLTBIDP.js} +44 -7
- package/chunks/{chunk-HLKG6CZN.js → chunk-M5GB774H.js} +1 -1
- package/chunks/{chunk-EEN2TKST.js → chunk-MBJ3D6SF.js} +2 -2
- package/chunks/{chunk-PMFULMLX.js → chunk-MBP3K324.js} +2234 -377
- package/chunks/chunk-MR3PXB6E.js +48 -0
- package/chunks/{chunk-ZE6E424U.js → chunk-N7FCSERB.js} +2 -2
- package/chunks/{chunk-332PWN27.js → chunk-NHDKSOEY.js} +1 -1
- package/chunks/chunk-OATTJGPJ.js +448 -0
- package/chunks/{chunk-UX6OTBVD.js → chunk-OCC3UTWA.js} +2 -2
- package/chunks/{chunk-P7M4GA57.js → chunk-OCPBI7J5.js} +1 -1
- package/chunks/chunk-OJAMDVF5.js +66 -0
- package/chunks/{chunk-IJRL2S3D.js → chunk-OKAIGAYW.js} +6 -6
- package/chunks/{chunk-WQTHLB5T.js → chunk-P3S67A5R.js} +7 -7
- package/chunks/{chunk-FBET5XZ2.js → chunk-PEJWA3QQ.js} +29 -10
- package/chunks/{chunk-J7RCB6N5.js → chunk-PHYCWSDG.js} +2 -2
- package/chunks/{chunk-LAXNEOBG.js → chunk-PMRH4YYW.js} +18 -3
- package/chunks/{chunk-AGHU5VRK.js → chunk-PZL23GTM.js} +1 -1
- package/chunks/{chunk-PC4ZXHU2.js → chunk-Q6TUALBE.js} +3 -3
- package/chunks/{chunk-FXGLL2HL.js → chunk-Q7YDKOGY.js} +1 -1
- package/chunks/{chunk-P3XEEI3X.js → chunk-QABSSDQH.js} +36 -7
- package/chunks/{chunk-XOHNA2S6.js → chunk-QAW7PIHT.js} +3 -3
- package/chunks/{chunk-LGFAYIKX.js → chunk-QHTIBUWB.js} +1 -1
- package/chunks/{chunk-P3MYAZBY.js → chunk-QMGX2KO2.js} +1 -1
- package/chunks/{chunk-Z3I3QJK3.js → chunk-QRUIS3DN.js} +1 -1
- package/chunks/{chunk-ITOGNELQ.js → chunk-QSWDGAIC.js} +2 -2
- package/chunks/{chunk-GHOTR7HL.js → chunk-QUPXZXLV.js} +1 -1
- package/chunks/{chunk-W7EEOR7D.js → chunk-RCEEXIOO.js} +8 -6
- package/chunks/{chunk-2EM7ECZD.js → chunk-RJL5T4WJ.js} +281 -65
- package/chunks/{chunk-TLRYABYP.js → chunk-RKUWKYED.js} +1 -1
- package/chunks/{chunk-RNBYOUGV.js → chunk-RXFQM6FQ.js} +1 -1
- package/chunks/{chunk-JRQ7EVGE.js → chunk-S2QXYLUB.js} +2 -2
- package/chunks/{chunk-QXPI7FEC.js → chunk-S3TWXGKA.js} +4 -4
- package/chunks/{chunk-O33TBKDC.js → chunk-SE74CIZD.js} +155 -19
- package/chunks/{chunk-FV7425LN.js → chunk-SPJQO2CE.js} +18 -5
- package/chunks/{chunk-3GNOQZDC.js → chunk-SSFDPGFN.js} +11866 -11542
- package/chunks/{chunk-DCZWC4PF.js → chunk-SUWGUGAD.js} +5 -5
- package/chunks/{chunk-IBY3Q3HG.js → chunk-SXU3KKNI.js} +963 -181
- package/chunks/{chunk-MLZQVCF3.js → chunk-SZRN75WQ.js} +1 -1
- package/chunks/{chunk-M7S4GK5Z.js → chunk-T2L6SGQY.js} +115 -29
- package/chunks/{chunk-7RYW5LQV.js → chunk-T2NCM2ET.js} +2 -2
- package/chunks/{chunk-JPALE3PA.js → chunk-T5C2OUCI.js} +6 -6
- package/chunks/{chunk-BUZ6HGL4.js → chunk-T7FSRWQ5.js} +248 -55
- package/chunks/{chunk-Z2Z3GUXZ.js → chunk-TB6UDU4T.js} +1 -1
- package/chunks/{chunk-EXPMGZZV.js → chunk-TEGEBB2I.js} +1 -1
- package/chunks/{chunk-MX2YXRER.js → chunk-TJTKSVIV.js} +1 -1
- package/chunks/{chunk-CCGOFQV3.js → chunk-TQBODCFD.js} +8 -7
- package/chunks/chunk-TV6K2FB4.js +224 -0
- package/chunks/{chunk-5MBO76SL.js → chunk-TXY2C3D2.js} +3 -3
- package/chunks/{chunk-H6BD2ELD.js → chunk-TYAMGABM.js} +2 -2
- package/chunks/{chunk-QYNNN7BK.js → chunk-TYLOFD2U.js} +2 -2
- package/chunks/{chunk-VRDMOSQS.js → chunk-UDXSXLER.js} +2 -2
- package/chunks/{chunk-UXEW557D.js → chunk-UI3W56WF.js} +3 -3
- package/chunks/{chunk-CJCKDMWO.js → chunk-URK542T4.js} +1 -1
- package/chunks/{channel-worker-supervisor-NZQUOEFJ.js → chunk-URU5UEK6.js} +190 -34
- package/chunks/{chunk-AHNXYU4O.js → chunk-V6WHFGST.js} +1 -1
- package/chunks/chunk-V75IOTWF.js +71 -0
- package/chunks/{chunk-ZTQ26VBE.js → chunk-VDDGDZMA.js} +1 -1
- package/chunks/{chunk-OMX7CUOE.js → chunk-VGC4I5JJ.js} +1 -1
- package/chunks/{chunk-43W4YSO6.js → chunk-VJNBRRZG.js} +2 -2
- package/chunks/{chunk-ER3BKOLB.js → chunk-W7FJ3N32.js} +1 -1
- package/chunks/{chunk-3HX5LZ6R.js → chunk-WBL3FJEU.js} +2 -2
- package/chunks/{chunk-7LTB54MK.js → chunk-WIEO4CWB.js} +2 -2
- package/chunks/{chunk-BMFMJINR.js → chunk-WL4L7EZH.js} +1 -1
- package/chunks/{chunk-6VK6FIMQ.js → chunk-WM5HY72H.js} +415 -379
- package/chunks/{chunk-BOBRZZKD.js → chunk-WN4D7YCI.js} +5 -5
- package/chunks/{chunk-DHOLNQLC.js → chunk-WWQ3QIJS.js} +60 -40
- package/chunks/{chunk-FEJ2FZ3U.js → chunk-WX6SD4IQ.js} +2 -2
- package/chunks/{chunk-DICGXFAI.js → chunk-X7EBAABW.js} +11 -9
- package/chunks/{chunk-3RW4AZJV.js → chunk-XFSFZCM5.js} +1 -1
- package/chunks/{chunk-YHKAK72D.js → chunk-XHW5VUIQ.js} +102 -16
- package/chunks/{chunk-2MPVVENX.js → chunk-XU457J4V.js} +2 -2
- package/chunks/{chunk-SIUQ3YYX.js → chunk-XVNQMZ2I.js} +1 -1
- package/chunks/{chunk-SYCJMSIJ.js → chunk-XWRJCPHC.js} +1 -1
- package/chunks/{chunk-SUAKHHK7.js → chunk-Y66VOBRP.js} +3 -3
- package/chunks/chunk-YAF2MQZ6.js +19 -0
- package/chunks/{chunk-FQNC62B2.js → chunk-YH4J5XI3.js} +11 -11
- package/chunks/chunk-YHN5SUIJ.js +219 -0
- package/chunks/{chunk-BR4QREVK.js → chunk-YQ3U5MUC.js} +1 -1
- package/chunks/{chunk-Y6Z2O3WR.js → chunk-YUZI3WAC.js} +1 -1
- package/chunks/{chunk-II73RK2S.js → chunk-YVEDCAUE.js} +1 -1
- package/chunks/{chunk-XYR5RUA5.js → chunk-YWUK7OS7.js} +10 -3
- package/chunks/{chunk-27BHARDE.js → chunk-Z56JO4JZ.js} +2124 -30
- package/chunks/{chunk-TSPB77TG.js → chunk-ZLM3KXBT.js} +1015 -2967
- package/chunks/{chunk-AHNJGLFV.js → chunk-ZPAHLFZU.js} +3 -3
- package/chunks/chunk-ZRKBI3DP.js +34 -0
- package/chunks/cli-entry-path-4VJ3Y6T2.js +10 -0
- package/chunks/{computer-use-WMY3UOBX.js → computer-use-DIP5BWXP.js} +51 -50
- package/chunks/config-utils-CFT33LTP.js +24 -0
- package/chunks/contextCommand-QU4GJWWD.js +69 -0
- package/chunks/create-sub-session-TCLIYVGR.js +376 -0
- package/chunks/create-sub-session-WNX2OQVX.js +207 -0
- package/chunks/{cron-create-JSXEIPVS.js → cron-create-36TIFKRT.js} +9 -9
- package/chunks/{cron-delete-OIFVEPGU.js → cron-delete-OQD3WULU.js} +7 -7
- package/chunks/{cron-list-D4ZX4IOE.js → cron-list-4533T2FH.js} +14 -10
- package/chunks/{daemon-WPAENEBW.js → daemon-CEZ27OH4.js} +734 -24
- package/chunks/daemon-status-provider-SIBFMLBQ.js +77 -0
- package/chunks/{de-ZFPPQVSF.js → de-2VCDRDGU.js} +68 -6
- package/chunks/{devtools-FM6GJPYG.js → devtools-4QFYJT6U.js} +3 -3
- package/chunks/{dist-E6UANPIM.js → dist-3V3ZV6ML.js} +1011 -197
- package/chunks/{dist-SCFLLYMK.js → dist-ERCPDVA6.js} +12 -11
- package/chunks/{dist-Z34QPAQW.js → dist-HNN7DR2L.js} +529 -79
- package/chunks/{dist-O2IRTRPP.js → dist-JZE7F6YR.js} +10 -10
- package/chunks/{dist-BEXOZXLQ.js → dist-MOEC47TR.js} +36 -15
- package/chunks/{dist-H2AEJCZ5.js → dist-PHEPJLXD.js} +5 -5
- package/chunks/{dist-63IS3ZMI.js → dist-PZV5RKM6.js} +4 -4
- package/chunks/earlyInputCapture-L66BEG2C.js +70 -0
- package/chunks/{edit-OTYWAXGP.js → edit-Y5LAJSST.js} +52 -51
- package/chunks/{en-N4EPZAQI.js → en-NJCA3TAA.js} +78 -6
- package/chunks/{enter-worktree-HNYBDVCX.js → enter-worktree-X5LML7T4.js} +51 -50
- package/chunks/{enterPlanMode-CJCNGT63.js → enterPlanMode-XWF32QOW.js} +67 -51
- package/chunks/environment-YVMA5F4I.js +90 -0
- package/chunks/errors-4Y5SUAOC.js +76 -0
- package/chunks/{exit-worktree-DUUKOE3X.js → exit-worktree-SFHU7XYC.js} +51 -50
- package/chunks/{exitPlanMode-AMMSXOAJ.js → exitPlanMode-FP3NAN6E.js} +52 -51
- package/chunks/{fast-path-OV6NIP3K.js → fast-path-ZJNFFCBM.js} +8 -8
- package/chunks/{fast-path-settings-7RIFI3PK.js → fast-path-settings-DAOVFADC.js} +8 -6
- package/chunks/{fileFromPath-IBEHA3CO.js → fileFromPath-UDALK7FM.js} +3 -3
- package/chunks/{fr-5WWMY53B.js → fr-5F3E7WKD.js} +68 -6
- package/chunks/{gemini-NQ3WWBKB.js → gemini-5CAB22BI.js} +122 -109
- package/chunks/{geminiContentGenerator-CDUNEJQE.js → geminiContentGenerator-GE3HPIFB.js} +9 -9
- package/chunks/{getMachineId-bsd-4CASPIU4.js → getMachineId-bsd-EXV7SWPA.js} +3 -3
- package/chunks/{getMachineId-darwin-HPQPEMZR.js → getMachineId-darwin-IUOMFXU3.js} +3 -3
- package/chunks/{getMachineId-linux-AUARKYHL.js → getMachineId-linux-K7XJYFHL.js} +2 -2
- package/chunks/{getMachineId-unsupported-S32ZDA2T.js → getMachineId-unsupported-EA5FDRJ6.js} +2 -2
- package/chunks/{getMachineId-win-4EFLHYIJ.js → getMachineId-win-KBA6RAI5.js} +3 -3
- package/chunks/{glob-ROV3YS4R.js → glob-YPACZAEL.js} +98 -75
- package/chunks/{grep-NRITKDCD.js → grep-IPR4XW37.js} +51 -50
- package/chunks/handleAutoUpdate-P2KEP56V.js +70 -0
- package/chunks/i18n-BRCT66AA.js +85 -0
- package/chunks/initializer-34HXSK3A.js +74 -0
- package/chunks/installationInfo-WOTDQMSC.js +66 -0
- package/chunks/{ja-CUHZOLEJ.js → ja-66J6B53L.js} +69 -7
- package/chunks/{keychain-token-storage-UJV5XP4Z.js → keychain-token-storage-AU22CQI6.js} +4 -4
- package/chunks/{kittyProtocolDetector-OJRCJLIU.js → kittyProtocolDetector-HCNNKJTI.js} +2 -2
- package/chunks/list-XOGP7UPP.js +77 -0
- package/chunks/loadedSettingsAdapter-L4YKGU6F.js +71 -0
- package/chunks/{loop-wakeup-OHWEMFP5.js → loop-wakeup-MVUKDVCP.js} +10 -10
- package/chunks/{lowlight-FYAAUU5J.js → lowlight-J2OZNPCA.js} +1 -1
- package/chunks/{ls-7MFU2QYW.js → ls-RXNIAQDE.js} +6 -6
- package/chunks/{lsp-XHDTPTGV.js → lsp-HB5LM5IL.js} +4 -4
- package/chunks/mcp-HH7DIP7Y.js +71 -0
- package/chunks/{monitor-FL2ZO33W.js → monitor-25DEBT6U.js} +51 -50
- package/chunks/{multipart-parser-AJ4WASWR.js → multipart-parser-AWZKXSQN.js} +3 -3
- package/chunks/nonInteractiveCli-CT3VSSLK.js +130 -0
- package/chunks/{notebook-edit-6PULTHL5.js → notebook-edit-TAVXSWQ6.js} +52 -51
- package/chunks/openaiContentGenerator-6I7DKUAN.js +56 -0
- package/chunks/pidfile-SIQGCFLZ.js +74 -0
- package/chunks/{pt-OLYN42DS.js → pt-TFZO5Y6T.js} +68 -6
- package/chunks/{qwenContentGenerator-NX2E7PB7.js → qwenContentGenerator-5DDIXI2N.js} +53 -52
- package/chunks/{qwenOAuth2-ZV7YLMND.js → qwenOAuth2-LEYOU7RU.js} +9 -9
- package/chunks/read-file-WDOAYRFU.js +30 -0
- package/chunks/{read-mcp-resource-CNQHBSJM.js → read-mcp-resource-6LRTZKXI.js} +5 -5
- package/chunks/{read-package-up-ER5OJUGP.js → read-package-up-TCM6I7S2.js} +2 -2
- package/chunks/{record-artifact-SQ2OKRJW.js → record-artifact-PMDTY4OS.js} +4 -4
- package/chunks/ripGrep-MI7PHN3Q.js +61 -0
- package/chunks/{ru-LDM3GWVQ.js → ru-4L4LFHIT.js} +68 -6
- package/chunks/{run-qwen-serve-JK2DL7PI.js → run-qwen-serve-PNTYF3RE.js} +1289 -256
- package/chunks/runtime-V3FBMUTG.js +100 -0
- package/chunks/{scheduler-O4IGVZKK.js → scheduler-4TAUIJBM.js} +52 -51
- package/chunks/{send-message-76GT3JMC.js → send-message-SR4WSXP2.js} +7 -7
- package/chunks/serve-WB2TR7XM.js +77 -0
- package/chunks/{server-SGNPKX2O.js → server-AF6LNFPK.js} +8094 -2800
- package/chunks/{session-5BNM25EZ.js → session-BIGK4NRW.js} +341 -135
- package/chunks/settings-IXF5FIQO.js +121 -0
- package/chunks/shell-5VWJ2PPG.js +69 -0
- package/chunks/{skill-I22QK5XS.js → skill-SI667Y3B.js} +24 -24
- package/chunks/spawnChannel-IKX6DD7J.js +71 -0
- package/chunks/{src-BBQSM46M.js → src-55DZWDAK.js} +151 -52
- package/chunks/{src-7XL4G4DC.js → src-VLI3TKEY.js} +4 -4
- package/chunks/standalone-update-MHLSFHE6.js +80 -0
- package/chunks/{startInteractiveUI-JII36UGN.js → startInteractiveUI-V2EDWLAX.js} +2239 -1846
- package/chunks/stdioHelpers-UMY72QRP.js +14 -0
- package/chunks/{syntheticOutput-F7LSDCAR.js → syntheticOutput-YKFNUQZD.js} +5 -5
- package/chunks/task-create-NUFOHU53.js +23 -0
- package/chunks/{task-list-TGGJX7EA.js → task-list-Z2IKQY3S.js} +11 -10
- package/chunks/{task-stop-W7NGTMYQ.js → task-stop-KQFIVQTJ.js} +4 -4
- package/chunks/{task-update-XYWMHJGJ.js → task-update-HKADXSTD.js} +13 -12
- package/chunks/{team-create-A7NUU5AQ.js → team-create-IZAMLBJS.js} +51 -50
- package/chunks/{team-delete-UHQQ2QQX.js → team-delete-SDNTGZLG.js} +11 -10
- package/chunks/{team-plan-approval-TOQRJ2KI.js → team-plan-approval-3R4RCKCP.js} +51 -50
- package/chunks/theme-manager-LCOXZ5DO.js +65 -0
- package/chunks/{todoWrite-C4ZAMSR3.js → todoWrite-YNXB27GB.js} +6 -6
- package/chunks/{tool-search-SZ4EFS2T.js → tool-search-NYNCD5LF.js} +24 -24
- package/chunks/total-session-admission-PJWGOMQE.js +73 -0
- package/chunks/tree-sitter-YJVE2ZUK.js +2980 -0
- package/chunks/trustedFolders-DOJDHNYP.js +81 -0
- package/chunks/{types-QX5C3CHJ.js → types-JNKGKUJT.js} +2 -2
- package/chunks/updateCheck-ZXL66KIG.js +70 -0
- package/chunks/updateEventEmitter-5MKC7BLQ.js +10 -0
- package/chunks/validateNonInterActiveAuth-JSNJZCYY.js +195 -0
- package/chunks/{version-NO2XSNNP.js → version-3NLBENG5.js} +3 -3
- package/chunks/{web-fetch-UYGMOHW4.js → web-fetch-ZSPR3PRR.js} +8 -8
- package/chunks/{workflow-WO2H6NRI.js → workflow-BQYLF7XP.js} +52 -51
- package/chunks/workspace-providers-status-FA2DGEZW.js +74 -0
- package/chunks/workspace-registration-store-TARTAGMI.js +27 -0
- package/chunks/workspace-registry-AGE7WAXX.js +77 -0
- package/chunks/workspace-service-ERC5VR2B.js +83 -0
- package/chunks/workspace-skills-status-FKYWGNCN.js +73 -0
- package/chunks/{write-file-PX2Z7IBE.js → write-file-S47KSK7Z.js} +52 -51
- package/chunks/{yargs-B64EYTCF.js → yargs-6H2AUULL.js} +2 -2
- package/chunks/{zh-J4F6QWQV.js → zh-FSAH32JB.js} +79 -7
- package/chunks/{zh-TW-XVDWOLSW.js → zh-TW-D2YIE2LO.js} +79 -7
- package/cli.js +18 -17
- package/locales/ca.js +91 -7
- package/locales/de.js +90 -7
- package/locales/en.js +109 -7
- package/locales/fr.js +91 -7
- package/locales/ja.js +93 -7
- package/locales/pt.js +90 -7
- package/locales/ru.js +90 -7
- package/locales/zh-TW.js +106 -7
- package/locales/zh.js +106 -7
- package/package.json +3 -6
- package/web-shell/assets/{arc-BWyoJpY2.js → arc-Zj4EkBUY.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-BT0mGrz2.js → architectureDiagram-3BPJPVTR-DAk1Ua3Y.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-BLgUWvyf.js → blockDiagram-GPEHLZMM-DBNqUthM.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-DYx9M7oU.js → c4Diagram-AAUBKEIU-Dq5QGJ53.js} +1 -1
- package/web-shell/assets/channel-DWfYijFS.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-CfMHWbuZ.js → chunk-2J33WTMH-DY0AeGru.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-B1URoqEV.js → chunk-4BX2VUAB-COX3OyIi.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-DAIaM4QF.js → chunk-55IACEB6-Csoyddbh.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-B2X34knw.js → chunk-727SXJPM-BJPONdxX.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-Cif-zLTQ.js → chunk-AQP2D5EJ-syLVH6fg.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-H18WCXdY.js → chunk-FMBD7UC4-Cfm59Nhw.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-YFtetHi0.js → chunk-ND2GUHAM-DZf6tAqS.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-By2hiH3r.js → chunk-QZHKN3VN-DKBp_v5q.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-DDht-78J.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-DDht-78J.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-VrcnnLZu.js → cose-bilkent-S5V4N54A-DUU3mMQ5.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-CGo-IaVV.js → dagre-BM42HDAG-BUgNfbh-.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-Dl4QjzIB.js → diagram-2AECGRRQ-DT7MVfAg.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-qMLmsO0u.js → diagram-5GNKFQAL-Cv4YG-ec.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-CHlmuxPI.js → diagram-KO2AKTUF-BAe9LLkn.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-BUwU3GwT.js → diagram-LMA3HP47-DW8wqTIP.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-HEhwPDUM.js → diagram-OG6HWLK6-CmkuWbaK.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-1n0llBmM.js → erDiagram-TEJ5UH35-DwvdHjZ9.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-BN74uMnt.js → flowDiagram-I6XJVG4X-CSsXrhW_.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-BoOq78i3.js → ganttDiagram-6RSMTGT7-BtuznCdi.js} +3 -3
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-CN8b00c8.js → gitGraphDiagram-PVQCEYII-DGmAm06g.js} +1 -1
- package/web-shell/assets/index-B9Xwf4OS.css +5 -0
- package/web-shell/assets/index-BEtz1cvN.js +3 -0
- package/web-shell/assets/index-BUkM4ZXX.js +1088 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-CCurnIna.js → infoDiagram-5YYISTIA-OAiZ1q0K.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-AwuRqdUP.js → ishikawaDiagram-YF4QCWOH-DyK0KTIT.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-B7IICk-E.js → journeyDiagram-JHISSGLW-DzYJlwfO.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-BYF0OKhx.js → kanban-definition-UN3LZRKU-CU_tcDwi.js} +1 -1
- package/web-shell/assets/{linear-GWWguGfD.js → linear-DvZXjF17.js} +1 -1
- package/web-shell/assets/{mermaid.core-JqtkxvCl.js → mermaid.core-_ZFEQlOl.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-B0MmHsZ6.js → mindmap-definition-RKZ34NQL-Or4p64HB.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-DhImUZLQ.js → pieDiagram-4H26LBE5-lXE-zZ6b.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-DGeSC3DT.js → quadrantDiagram-W4KKPZXB-DUXb9mUV.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-DkspY6Re.js → requirementDiagram-4Y6WPE33-D_10uHfo.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-CaOofS2x.js → sankeyDiagram-5OEKKPKP-E8c0fPqe.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-DFQ_kFnN.js → sequenceDiagram-3UESZ5HK-CJMtFttK.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-D3snw0Tz.js → stateDiagram-AJRCARHV-DhbviRbB.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CntljfwW.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-l4zH8nLM.js → timeline-definition-PNZ67QCA-CM5yMkFK.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-BnRlA98M.js → vennDiagram-CIIHVFJN-BCi-zWNN.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-BS0xUdmd.js → wardley-L42UT6IY-BJ_yJNjJ.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-DKGBUWyQ.js → wardleyDiagram-YWT4CUSO-TjtLk-qN.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-DVb2HuOB.js → xychartDiagram-2RQKCTM6-D1TjyoQ3.js} +1 -1
- package/web-shell/index.html +16 -4
- package/chunks/MaxSizedBox-5DT2SD7B.js +0 -71
- package/chunks/agent-H2DGKS77.js +0 -68
- package/chunks/agent-headless-KFMFIT6J.js +0 -62
- package/chunks/bridge-NA3ZQQKJ.js +0 -78
- package/chunks/chunk-6SHO7WFF.js +0 -79
- package/chunks/chunk-IFEWJXFS.js +0 -37
- package/chunks/chunk-XNXVCNAT.js +0 -88
- package/chunks/contextCommand-LXFZRP4L.js +0 -68
- package/chunks/daemon-status-provider-GJRXY5EN.js +0 -76
- package/chunks/earlyInputCapture-KNOYZ4MJ.js +0 -69
- package/chunks/environment-ATFTYMLZ.js +0 -88
- package/chunks/errors-A54HAADA.js +0 -75
- package/chunks/handleAutoUpdate-CEZJAARW.js +0 -65
- package/chunks/initializer-BRFJKRRX.js +0 -71
- package/chunks/list-KVHF7O4X.js +0 -73
- package/chunks/loadedSettingsAdapter-LL5PSFKX.js +0 -68
- package/chunks/mcp-3GCXRTOQ.js +0 -68
- package/chunks/nonInteractiveCli-PTQI3DV6.js +0 -119
- package/chunks/openaiContentGenerator-YE42PKCY.js +0 -56
- package/chunks/pidfile-NZYSCFRK.js +0 -73
- package/chunks/read-file-33XGP5HF.js +0 -30
- package/chunks/ripGrep-QWZLGTAN.js +0 -60
- package/chunks/serve-JTMIGANH.js +0 -74
- package/chunks/settings-3MI4XXP6.js +0 -118
- package/chunks/shell-YJKBE67T.js +0 -68
- package/chunks/spawnChannel-UNV6W4DU.js +0 -70
- package/chunks/task-create-WCHTB435.js +0 -22
- package/chunks/theme-manager-WZ4RRMMB.js +0 -64
- package/chunks/total-session-admission-ULXJWXFV.js +0 -72
- package/chunks/trustedFolders-LAZZPZ3D.js +0 -79
- package/chunks/updateCheck-KONLM73X.js +0 -65
- package/chunks/validateNonInterActiveAuth-MPKSRCXD.js +0 -184
- package/chunks/workspace-providers-status-3W7E7DFW.js +0 -71
- package/chunks/workspace-registry-SXJZNN3O.js +0 -74
- package/chunks/workspace-service-CZRQZ4Q4.js +0 -80
- package/chunks/workspace-skills-status-K7WFREPD.js +0 -70
- package/node_modules/@qwen-code/audio-capture/dist/index.d.ts +0 -35
- package/node_modules/@qwen-code/audio-capture/dist/index.js +0 -48
- package/node_modules/@qwen-code/audio-capture/dist/index.js.map +0 -1
- package/node_modules/@qwen-code/audio-capture/dist/platform.d.ts +0 -7
- package/node_modules/@qwen-code/audio-capture/dist/platform.js +0 -18
- package/node_modules/@qwen-code/audio-capture/dist/platform.js.map +0 -1
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/LICENSE +0 -21
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/README.md +0 -58
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/SECURITY.md +0 -5
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/bin.js +0 -84
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/build-test.js +0 -19
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/index.js +0 -6
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/node-gyp-build.js +0 -207
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/optional.js +0 -7
- package/node_modules/@qwen-code/audio-capture/node_modules/node-gyp-build/package.json +0 -43
- package/node_modules/@qwen-code/audio-capture/package.json +0 -30
- 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/linux-arm64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/linux-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/web-shell/assets/channel-wmPUGHtg.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-BA2ljEjW.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-BA2ljEjW.js +0 -1
- package/web-shell/assets/index-CNwoO1Cn.js +0 -783
- package/web-shell/assets/index-CWQ0z6kZ.css +0 -5
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BbSm_9d0.js +0 -1
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
import {
|
|
4
4
|
DaemonMetricsRing,
|
|
5
5
|
computeCpuPercent
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
findCliEntryPath
|
|
9
|
-
} from "./chunk-AHNXYU4O.js";
|
|
6
|
+
} from "./chunk-YVEDCAUE.js";
|
|
10
7
|
import {
|
|
11
8
|
CAPABILITIES_SCHEMA_VERSION,
|
|
12
9
|
ClientMcpSenderRegistry,
|
|
@@ -22,71 +19,93 @@ import {
|
|
|
22
19
|
getRateLimiter,
|
|
23
20
|
getServeProtocolVersions,
|
|
24
21
|
hostAllowlist,
|
|
22
|
+
isBrowserAutomationMcpAvailable,
|
|
25
23
|
listenerMaxConnections,
|
|
26
24
|
parseAllowOriginPatterns,
|
|
27
25
|
parseDaemonStatusDetail,
|
|
28
26
|
positiveFiniteOrNull,
|
|
29
27
|
require_express,
|
|
30
28
|
resolveWebShellDir
|
|
31
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-4LJNI7MU.js";
|
|
32
30
|
import {
|
|
33
31
|
isLoopbackBind
|
|
34
|
-
} from "./chunk-
|
|
35
|
-
import "./chunk-3HX5LZ6R.js";
|
|
36
|
-
import "./chunk-7RYW5LQV.js";
|
|
32
|
+
} from "./chunk-RXFQM6FQ.js";
|
|
37
33
|
import {
|
|
38
34
|
RUNTIME_STARTUP_CANCELLED_MESSAGE
|
|
39
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-QUPXZXLV.js";
|
|
40
36
|
import {
|
|
41
37
|
LOAD_REPLAY_META_KEY
|
|
42
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-PZL23GTM.js";
|
|
43
39
|
import {
|
|
44
40
|
DEFAULT_COMPACTED_REPLAY_MAX_BYTES,
|
|
45
41
|
normalizeCompactedReplayMaxBytes
|
|
46
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-COH43MRJ.js";
|
|
43
|
+
import "./chunk-WBL3FJEU.js";
|
|
47
44
|
import {
|
|
48
|
-
|
|
49
|
-
} from "./chunk-
|
|
45
|
+
resolveChannelCwd
|
|
46
|
+
} from "./chunk-ZRKBI3DP.js";
|
|
50
47
|
import {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
MAX_REGISTERED_WORKSPACES,
|
|
49
|
+
resolveWorkspaceInputs,
|
|
50
|
+
workspaceRegistrationId
|
|
51
|
+
} from "./chunk-J2TDDOSM.js";
|
|
52
|
+
import {
|
|
53
|
+
canonicalizeWorkspace
|
|
54
|
+
} from "./chunk-W7FJ3N32.js";
|
|
55
|
+
import "./chunk-3MX7D6QN.js";
|
|
54
56
|
import {
|
|
55
57
|
QWEN_SERVER_TOKEN_ENV
|
|
56
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-GYTKQYDB.js";
|
|
57
59
|
import {
|
|
58
60
|
channelSelectionNames
|
|
59
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-TJTKSVIV.js";
|
|
62
|
+
import "./chunk-5HBA2Z7V.js";
|
|
63
|
+
import {
|
|
64
|
+
ChannelWebhookEnqueueError
|
|
65
|
+
} from "./chunk-OJAMDVF5.js";
|
|
66
|
+
import "./chunk-T2NCM2ET.js";
|
|
67
|
+
import {
|
|
68
|
+
sanitizeLogText
|
|
69
|
+
} from "./chunk-SXU3KKNI.js";
|
|
70
|
+
import "./chunk-UDXSXLER.js";
|
|
71
|
+
import {
|
|
72
|
+
loadServeFastPathSettings,
|
|
73
|
+
preResolveServeFastPathHomeEnvOverrides
|
|
74
|
+
} from "./chunk-PEJWA3QQ.js";
|
|
75
|
+
import "./chunk-GOXKNSDZ.js";
|
|
60
76
|
import {
|
|
61
77
|
getGlobalQwenDirLite,
|
|
62
78
|
resolveConfigPathLite
|
|
63
|
-
} from "./chunk-
|
|
64
|
-
import "./chunk-
|
|
79
|
+
} from "./chunk-IDS7MSUP.js";
|
|
80
|
+
import "./chunk-QRUIS3DN.js";
|
|
81
|
+
import "./chunk-ALGGS7UH.js";
|
|
65
82
|
import {
|
|
66
|
-
|
|
67
|
-
} from "./chunk-
|
|
68
|
-
import "./chunk-43W4YSO6.js";
|
|
83
|
+
isWithinRoot
|
|
84
|
+
} from "./chunk-MR3PXB6E.js";
|
|
69
85
|
import {
|
|
70
86
|
writeStderrLine,
|
|
71
87
|
writeStdoutLine
|
|
72
|
-
} from "./chunk-
|
|
88
|
+
} from "./chunk-YUZI3WAC.js";
|
|
73
89
|
import {
|
|
74
|
-
|
|
75
|
-
} from "./chunk-
|
|
76
|
-
import "./chunk-
|
|
77
|
-
import "./chunk-
|
|
78
|
-
import "./chunk-
|
|
79
|
-
import "./chunk-
|
|
90
|
+
getCliVersion
|
|
91
|
+
} from "./chunk-UI3W56WF.js";
|
|
92
|
+
import "./chunk-VJNBRRZG.js";
|
|
93
|
+
import "./chunk-CU3L64TP.js";
|
|
94
|
+
import "./chunk-H6XPXXMH.js";
|
|
95
|
+
import "./chunk-5M6IDOMF.js";
|
|
96
|
+
import "./chunk-E2UVIFI2.js";
|
|
97
|
+
import "./chunk-CR3C7WXL.js";
|
|
98
|
+
import "./chunk-XWRJCPHC.js";
|
|
80
99
|
import {
|
|
81
100
|
finalizeStartupProfile,
|
|
82
101
|
profileCheckpoint
|
|
83
|
-
} from "./chunk-
|
|
84
|
-
import "./chunk-
|
|
85
|
-
import "./chunk-
|
|
86
|
-
import "./chunk-
|
|
102
|
+
} from "./chunk-QSWDGAIC.js";
|
|
103
|
+
import "./chunk-Q7YDKOGY.js";
|
|
104
|
+
import "./chunk-DMTGGOSA.js";
|
|
105
|
+
import "./chunk-YQ3U5MUC.js";
|
|
87
106
|
import {
|
|
88
107
|
init_esbuild_shims
|
|
89
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-5O2XNYP6.js";
|
|
90
109
|
import {
|
|
91
110
|
__name,
|
|
92
111
|
__toESM
|
|
@@ -95,99 +114,13 @@ import {
|
|
|
95
114
|
// packages/cli/src/serve/run-qwen-serve.ts
|
|
96
115
|
init_esbuild_shims();
|
|
97
116
|
var import_express = __toESM(require_express(), 1);
|
|
98
|
-
import { X509Certificate } from "node:crypto";
|
|
117
|
+
import { X509Certificate, createHash as createHash2, timingSafeEqual } from "node:crypto";
|
|
99
118
|
import * as fs from "node:fs";
|
|
100
119
|
import * as https from "node:https";
|
|
101
120
|
import * as path from "node:path";
|
|
102
121
|
import * as os from "node:os";
|
|
103
122
|
import { monitorEventLoopDelay, performance } from "node:perf_hooks";
|
|
104
123
|
|
|
105
|
-
// packages/cli/src/serve/workspace-inputs.ts
|
|
106
|
-
init_esbuild_shims();
|
|
107
|
-
var DuplicateWorkspaceInputError = class extends Error {
|
|
108
|
-
static {
|
|
109
|
-
__name(this, "DuplicateWorkspaceInputError");
|
|
110
|
-
}
|
|
111
|
-
constructor(workspace) {
|
|
112
|
-
super(
|
|
113
|
-
`Duplicate --workspace value resolves to ${JSON.stringify(workspace)}. Pass distinct --workspace values.`
|
|
114
|
-
);
|
|
115
|
-
this.name = "DuplicateWorkspaceInputError";
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
var NestedWorkspaceInputError = class extends Error {
|
|
119
|
-
static {
|
|
120
|
-
__name(this, "NestedWorkspaceInputError");
|
|
121
|
-
}
|
|
122
|
-
constructor(parent, child) {
|
|
123
|
-
super(
|
|
124
|
-
`Nested --workspace values are not supported yet: ${JSON.stringify(child)} is inside ${JSON.stringify(parent)}. Pass non-nested --workspace values.`
|
|
125
|
-
);
|
|
126
|
-
this.name = "NestedWorkspaceInputError";
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
var MissingWorkspaceInputError = class extends Error {
|
|
130
|
-
static {
|
|
131
|
-
__name(this, "MissingWorkspaceInputError");
|
|
132
|
-
}
|
|
133
|
-
constructor() {
|
|
134
|
-
super("--workspace requires a value.");
|
|
135
|
-
this.name = "MissingWorkspaceInputError";
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
function normalizeWorkspaceInputs(workspace) {
|
|
139
|
-
if (Array.isArray(workspace)) {
|
|
140
|
-
if (workspace.length === 0) {
|
|
141
|
-
throw new MissingWorkspaceInputError();
|
|
142
|
-
}
|
|
143
|
-
return workspace.map((value) => String(value));
|
|
144
|
-
}
|
|
145
|
-
if (workspace === void 0) return [process.cwd()];
|
|
146
|
-
return [String(workspace)];
|
|
147
|
-
}
|
|
148
|
-
__name(normalizeWorkspaceInputs, "normalizeWorkspaceInputs");
|
|
149
|
-
function isNestedWorkspace(parent, child) {
|
|
150
|
-
return parent !== child && isWithinRoot(child, parent);
|
|
151
|
-
}
|
|
152
|
-
__name(isNestedWorkspace, "isNestedWorkspace");
|
|
153
|
-
function rejectDuplicateOrNestedWorkspaceInputs(workspaces) {
|
|
154
|
-
if (workspaces.length <= 1) return;
|
|
155
|
-
let canonicalWorkspaces;
|
|
156
|
-
try {
|
|
157
|
-
canonicalWorkspaces = workspaces.map(
|
|
158
|
-
(workspace) => canonicalizeWorkspace(workspace)
|
|
159
|
-
);
|
|
160
|
-
} catch {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
const seen = /* @__PURE__ */ new Set();
|
|
164
|
-
for (const workspace of canonicalWorkspaces) {
|
|
165
|
-
if (seen.has(workspace)) {
|
|
166
|
-
throw new DuplicateWorkspaceInputError(workspace);
|
|
167
|
-
}
|
|
168
|
-
seen.add(workspace);
|
|
169
|
-
}
|
|
170
|
-
for (let i = 0; i < canonicalWorkspaces.length; i++) {
|
|
171
|
-
for (let j = i + 1; j < canonicalWorkspaces.length; j++) {
|
|
172
|
-
const first = canonicalWorkspaces[i];
|
|
173
|
-
const second = canonicalWorkspaces[j];
|
|
174
|
-
if (isNestedWorkspace(first, second)) {
|
|
175
|
-
throw new NestedWorkspaceInputError(first, second);
|
|
176
|
-
}
|
|
177
|
-
if (isNestedWorkspace(second, first)) {
|
|
178
|
-
throw new NestedWorkspaceInputError(second, first);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
__name(rejectDuplicateOrNestedWorkspaceInputs, "rejectDuplicateOrNestedWorkspaceInputs");
|
|
184
|
-
function resolveWorkspaceInputs(workspace) {
|
|
185
|
-
const workspaces = normalizeWorkspaceInputs(workspace);
|
|
186
|
-
rejectDuplicateOrNestedWorkspaceInputs(workspaces);
|
|
187
|
-
return workspaces;
|
|
188
|
-
}
|
|
189
|
-
__name(resolveWorkspaceInputs, "resolveWorkspaceInputs");
|
|
190
|
-
|
|
191
124
|
// packages/cli/src/serve/permission-audit.ts
|
|
192
125
|
init_esbuild_shims();
|
|
193
126
|
var DEFAULT_PERMISSION_AUDIT_RING_SIZE = 512;
|
|
@@ -885,6 +818,120 @@ function asRecord(value) {
|
|
|
885
818
|
}
|
|
886
819
|
__name(asRecord, "asRecord");
|
|
887
820
|
|
|
821
|
+
// packages/cli/src/serve/channel-workspace-grouping.ts
|
|
822
|
+
init_esbuild_shims();
|
|
823
|
+
function resolveChannelOwnerCwd(rawCwd, workspaceCwd) {
|
|
824
|
+
return canonicalizeWorkspace(resolveChannelCwd(rawCwd, workspaceCwd));
|
|
825
|
+
}
|
|
826
|
+
__name(resolveChannelOwnerCwd, "resolveChannelOwnerCwd");
|
|
827
|
+
function rawChannelCwd(entry) {
|
|
828
|
+
if (!entry || typeof entry !== "object") return void 0;
|
|
829
|
+
const cwd = entry.cwd;
|
|
830
|
+
return typeof cwd === "string" && cwd.length > 0 ? cwd : void 0;
|
|
831
|
+
}
|
|
832
|
+
__name(rawChannelCwd, "rawChannelCwd");
|
|
833
|
+
function resolveChannelWorkspaceGroups(input) {
|
|
834
|
+
const { workspaces, selection, loadChannelsConfig } = input;
|
|
835
|
+
const primary = workspaces.find((workspace) => workspace.primary);
|
|
836
|
+
if (!primary) {
|
|
837
|
+
return {
|
|
838
|
+
ok: false,
|
|
839
|
+
error: {
|
|
840
|
+
code: "no_primary_workspace",
|
|
841
|
+
message: "No primary workspace is registered."
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
}
|
|
845
|
+
if (selection.mode === "all") {
|
|
846
|
+
if (!primary.trusted) {
|
|
847
|
+
return {
|
|
848
|
+
ok: false,
|
|
849
|
+
error: {
|
|
850
|
+
code: "untrusted_workspace",
|
|
851
|
+
message: `Primary workspace "${primary.workspaceCwd}" is not trusted; cannot host channels.`
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
return {
|
|
856
|
+
ok: true,
|
|
857
|
+
groups: [
|
|
858
|
+
{ workspaceCwd: primary.workspaceCwd, selection: { mode: "all" } }
|
|
859
|
+
]
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
const channelsConfigByWorkspace = /* @__PURE__ */ new Map();
|
|
863
|
+
for (const workspace of workspaces) {
|
|
864
|
+
channelsConfigByWorkspace.set(
|
|
865
|
+
workspace.workspaceCwd,
|
|
866
|
+
loadChannelsConfig(workspace.workspaceCwd)
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
const namesByWorkspace = /* @__PURE__ */ new Map();
|
|
870
|
+
for (const name of selection.names) {
|
|
871
|
+
const owners = [];
|
|
872
|
+
for (const workspace of workspaces) {
|
|
873
|
+
const entry = (channelsConfigByWorkspace.get(workspace.workspaceCwd) ?? {})[name];
|
|
874
|
+
if (!entry || typeof entry !== "object") continue;
|
|
875
|
+
let ownerCwd;
|
|
876
|
+
try {
|
|
877
|
+
ownerCwd = resolveChannelOwnerCwd(
|
|
878
|
+
rawChannelCwd(entry),
|
|
879
|
+
workspace.workspaceCwd
|
|
880
|
+
);
|
|
881
|
+
} catch {
|
|
882
|
+
continue;
|
|
883
|
+
}
|
|
884
|
+
if (ownerCwd === workspace.workspaceCwd) {
|
|
885
|
+
owners.push(workspace);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
if (owners.length === 0) {
|
|
889
|
+
return {
|
|
890
|
+
ok: false,
|
|
891
|
+
error: {
|
|
892
|
+
code: "channel_workspace_mismatch",
|
|
893
|
+
channel: name,
|
|
894
|
+
message: `Channel "${name}" is not configured in any registered workspace, or its "cwd" points outside them.`
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
if (owners.length > 1) {
|
|
899
|
+
return {
|
|
900
|
+
ok: false,
|
|
901
|
+
error: {
|
|
902
|
+
code: "ambiguous_channel_workspace",
|
|
903
|
+
channel: name,
|
|
904
|
+
message: `Channel "${name}" is configured in multiple registered workspaces (${owners.map((owner2) => owner2.workspaceCwd).join(
|
|
905
|
+
", "
|
|
906
|
+
)}). Define it in one workspace's settings or set an explicit "cwd".`
|
|
907
|
+
}
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
const owner = owners[0];
|
|
911
|
+
if (!owner.trusted) {
|
|
912
|
+
return {
|
|
913
|
+
ok: false,
|
|
914
|
+
error: {
|
|
915
|
+
code: "untrusted_workspace",
|
|
916
|
+
channel: name,
|
|
917
|
+
message: `Channel "${name}" targets untrusted workspace "${owner.workspaceCwd}".`
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
const names = namesByWorkspace.get(owner.workspaceCwd) ?? [];
|
|
922
|
+
names.push(name);
|
|
923
|
+
namesByWorkspace.set(owner.workspaceCwd, names);
|
|
924
|
+
}
|
|
925
|
+
return {
|
|
926
|
+
ok: true,
|
|
927
|
+
groups: [...namesByWorkspace.entries()].map(([workspaceCwd, names]) => ({
|
|
928
|
+
workspaceCwd,
|
|
929
|
+
selection: { mode: "names", names }
|
|
930
|
+
}))
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
__name(resolveChannelWorkspaceGroups, "resolveChannelWorkspaceGroups");
|
|
934
|
+
|
|
888
935
|
// packages/cli/src/serve/run-qwen-serve.ts
|
|
889
936
|
var QWEN_SERVE_CLIENT_MCP_OVER_WS_ENV = "QWEN_SERVE_CLIENT_MCP_OVER_WS";
|
|
890
937
|
var QWEN_SERVE_CDP_TUNNEL_OVER_WS_ENV = "QWEN_SERVE_CDP_TUNNEL_OVER_WS";
|
|
@@ -1074,6 +1121,10 @@ function extractContextFilename(value) {
|
|
|
1074
1121
|
return void 0;
|
|
1075
1122
|
}
|
|
1076
1123
|
__name(extractContextFilename, "extractContextFilename");
|
|
1124
|
+
function sessionArtifactsPersistenceAvailableFromSettings(settings) {
|
|
1125
|
+
return settings?.general?.chatRecording !== false;
|
|
1126
|
+
}
|
|
1127
|
+
__name(sessionArtifactsPersistenceAvailableFromSettings, "sessionArtifactsPersistenceAvailableFromSettings");
|
|
1077
1128
|
var settingsWriteLocks = /* @__PURE__ */ new Map();
|
|
1078
1129
|
function withSettingsLock(workspace, fn) {
|
|
1079
1130
|
const prev = settingsWriteLocks.get(workspace) ?? Promise.resolve();
|
|
@@ -1085,12 +1136,29 @@ __name(withSettingsLock, "withSettingsLock");
|
|
|
1085
1136
|
var channelWorkerRuntimePromise;
|
|
1086
1137
|
async function loadChannelWorkerRuntime() {
|
|
1087
1138
|
channelWorkerRuntimePromise ??= Promise.all([
|
|
1088
|
-
import("./channel-worker-supervisor-
|
|
1089
|
-
import("./pidfile-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1139
|
+
import("./channel-worker-supervisor-PCDAZN4D.js"),
|
|
1140
|
+
import("./pidfile-SIQGCFLZ.js"),
|
|
1141
|
+
import("./runtime-V3FBMUTG.js"),
|
|
1142
|
+
import("./cli-entry-path-4VJ3Y6T2.js"),
|
|
1143
|
+
import("./channel-worker-group-K7QKH6IG.js"),
|
|
1144
|
+
import("./channel-worker-manager-5RWKSGEU.js")
|
|
1145
|
+
]).then(
|
|
1146
|
+
([
|
|
1147
|
+
supervisor,
|
|
1148
|
+
pidfile,
|
|
1149
|
+
channelRuntime,
|
|
1150
|
+
cliEntryPath,
|
|
1151
|
+
workerGroup,
|
|
1152
|
+
workerManager
|
|
1153
|
+
]) => ({
|
|
1154
|
+
createChannelWorkerSupervisor: supervisor.createChannelWorkerSupervisor,
|
|
1155
|
+
channelServicePidfile: pidfile,
|
|
1156
|
+
loadChannelsConfig: channelRuntime.loadChannelsConfig,
|
|
1157
|
+
createChannelWorkerGroup: workerGroup.createChannelWorkerGroup,
|
|
1158
|
+
createChannelWorkerManager: workerManager.createChannelWorkerManager,
|
|
1159
|
+
findCliEntryPath: cliEntryPath.findCliEntryPath
|
|
1160
|
+
})
|
|
1161
|
+
).catch((err) => {
|
|
1094
1162
|
channelWorkerRuntimePromise = void 0;
|
|
1095
1163
|
throw err;
|
|
1096
1164
|
});
|
|
@@ -1108,9 +1176,18 @@ function createDisabledChannelWorkerSupervisor() {
|
|
|
1108
1176
|
},
|
|
1109
1177
|
async stop() {
|
|
1110
1178
|
},
|
|
1179
|
+
async restart() {
|
|
1180
|
+
return { ...snapshot, channels: [] };
|
|
1181
|
+
},
|
|
1111
1182
|
killAllSync() {
|
|
1112
1183
|
},
|
|
1113
|
-
snapshot: /* @__PURE__ */ __name(() => ({ ...snapshot, channels: [] }), "snapshot")
|
|
1184
|
+
snapshot: /* @__PURE__ */ __name(() => ({ ...snapshot, channels: [] }), "snapshot"),
|
|
1185
|
+
async enqueueWebhookTask() {
|
|
1186
|
+
throw new ChannelWebhookEnqueueError(
|
|
1187
|
+
"channel_worker_unavailable",
|
|
1188
|
+
"Channel worker is not running."
|
|
1189
|
+
);
|
|
1190
|
+
}
|
|
1114
1191
|
};
|
|
1115
1192
|
}
|
|
1116
1193
|
__name(createDisabledChannelWorkerSupervisor, "createDisabledChannelWorkerSupervisor");
|
|
@@ -1123,11 +1200,23 @@ function writeServeChannelReservation(channelServicePidfile, channels) {
|
|
|
1123
1200
|
__name(writeServeChannelReservation, "writeServeChannelReservation");
|
|
1124
1201
|
function channelServicePidfileConflictError(info) {
|
|
1125
1202
|
const owner = info.owner === "serve" ? "qwen serve" : "qwen channel start";
|
|
1126
|
-
return
|
|
1127
|
-
|
|
1203
|
+
return Object.assign(
|
|
1204
|
+
new Error(
|
|
1205
|
+
`Channel service is already running under ${owner} (PID ${info.pid}). Stop it before enabling daemon-managed channels.`
|
|
1206
|
+
),
|
|
1207
|
+
{ code: "channel_service_conflict", owner: info.owner, pid: info.pid }
|
|
1128
1208
|
);
|
|
1129
1209
|
}
|
|
1130
1210
|
__name(channelServicePidfileConflictError, "channelServicePidfileConflictError");
|
|
1211
|
+
function channelServiceStartingConflictError() {
|
|
1212
|
+
return Object.assign(
|
|
1213
|
+
new Error(
|
|
1214
|
+
"Channel service is already starting. Retry after the current startup finishes."
|
|
1215
|
+
),
|
|
1216
|
+
{ code: "channel_service_conflict" }
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
__name(channelServiceStartingConflictError, "channelServiceStartingConflictError");
|
|
1131
1220
|
function normalizeInstallModelIds(req, provider, getDefaultModelIds) {
|
|
1132
1221
|
const fromRequest = req.modelIds?.map((id) => id.trim()).filter((id) => id.length > 0);
|
|
1133
1222
|
const modelIds = fromRequest && fromRequest.length > 0 ? fromRequest : getDefaultModelIds(provider);
|
|
@@ -1157,7 +1246,7 @@ function shouldPreheatBridge(deps) {
|
|
|
1157
1246
|
__name(shouldPreheatBridge, "shouldPreheatBridge");
|
|
1158
1247
|
var coreRuntimePromise;
|
|
1159
1248
|
function loadCoreRuntime() {
|
|
1160
|
-
coreRuntimePromise ??= import("./src-
|
|
1249
|
+
coreRuntimePromise ??= import("./src-55DZWDAK.js");
|
|
1161
1250
|
return coreRuntimePromise;
|
|
1162
1251
|
}
|
|
1163
1252
|
__name(loadCoreRuntime, "loadCoreRuntime");
|
|
@@ -1187,10 +1276,10 @@ __name(resolveDaemonLogBaseDirForRun, "resolveDaemonLogBaseDirForRun");
|
|
|
1187
1276
|
var settingsRuntimePromise;
|
|
1188
1277
|
function loadSettingsRuntimeModules() {
|
|
1189
1278
|
settingsRuntimePromise ??= Promise.all([
|
|
1190
|
-
import("./settings-
|
|
1191
|
-
import("./environment-
|
|
1192
|
-
import("./loadedSettingsAdapter-
|
|
1193
|
-
import("./trustedFolders-
|
|
1279
|
+
import("./settings-IXF5FIQO.js"),
|
|
1280
|
+
import("./environment-YVMA5F4I.js"),
|
|
1281
|
+
import("./loadedSettingsAdapter-L4YKGU6F.js"),
|
|
1282
|
+
import("./trustedFolders-DOJDHNYP.js")
|
|
1194
1283
|
]).then(([settings, environment, loadedSettingsAdapter, trustedFolders]) => ({
|
|
1195
1284
|
settings,
|
|
1196
1285
|
environment,
|
|
@@ -1200,6 +1289,21 @@ function loadSettingsRuntimeModules() {
|
|
|
1200
1289
|
return settingsRuntimePromise;
|
|
1201
1290
|
}
|
|
1202
1291
|
__name(loadSettingsRuntimeModules, "loadSettingsRuntimeModules");
|
|
1292
|
+
var channelWebhookConfigRuntimePromise;
|
|
1293
|
+
function loadChannelWebhookConfigRuntime() {
|
|
1294
|
+
channelWebhookConfigRuntimePromise ??= Promise.all([
|
|
1295
|
+
import("./runtime-V3FBMUTG.js"),
|
|
1296
|
+
import("./config-utils-CFT33LTP.js")
|
|
1297
|
+
]).then(([channelRuntime, configUtils]) => ({
|
|
1298
|
+
loadChannelsConfig: channelRuntime.loadChannelsConfig,
|
|
1299
|
+
parseChannelWebhookConfig: configUtils.parseChannelWebhookConfig
|
|
1300
|
+
})).catch((err) => {
|
|
1301
|
+
channelWebhookConfigRuntimePromise = void 0;
|
|
1302
|
+
throw err;
|
|
1303
|
+
});
|
|
1304
|
+
return channelWebhookConfigRuntimePromise;
|
|
1305
|
+
}
|
|
1306
|
+
__name(loadChannelWebhookConfigRuntime, "loadChannelWebhookConfigRuntime");
|
|
1203
1307
|
async function loadServeRuntimeModules() {
|
|
1204
1308
|
const [
|
|
1205
1309
|
serverModule,
|
|
@@ -1213,16 +1317,16 @@ async function loadServeRuntimeModules() {
|
|
|
1213
1317
|
totalSessionAdmissionModule,
|
|
1214
1318
|
workspaceRegistryModule
|
|
1215
1319
|
] = await Promise.all([
|
|
1216
|
-
import("./server-
|
|
1217
|
-
import("./bridge-
|
|
1218
|
-
import("./spawnChannel-
|
|
1219
|
-
import("./workspace-service-
|
|
1220
|
-
import("./types-
|
|
1221
|
-
import("./daemon-status-provider-
|
|
1222
|
-
import("./workspace-providers-status-
|
|
1223
|
-
import("./workspace-skills-status-
|
|
1224
|
-
import("./total-session-admission-
|
|
1225
|
-
import("./workspace-registry-
|
|
1320
|
+
import("./server-AF6LNFPK.js"),
|
|
1321
|
+
import("./bridge-4OZH44MK.js"),
|
|
1322
|
+
import("./spawnChannel-IKX6DD7J.js"),
|
|
1323
|
+
import("./workspace-service-ERC5VR2B.js"),
|
|
1324
|
+
import("./types-JNKGKUJT.js"),
|
|
1325
|
+
import("./daemon-status-provider-SIBFMLBQ.js"),
|
|
1326
|
+
import("./workspace-providers-status-FA2DGEZW.js"),
|
|
1327
|
+
import("./workspace-skills-status-FKYWGNCN.js"),
|
|
1328
|
+
import("./total-session-admission-PJWGOMQE.js"),
|
|
1329
|
+
import("./workspace-registry-AGE7WAXX.js")
|
|
1226
1330
|
]);
|
|
1227
1331
|
return {
|
|
1228
1332
|
createServeApp: serverModule.createServeApp,
|
|
@@ -1237,7 +1341,8 @@ async function loadServeRuntimeModules() {
|
|
|
1237
1341
|
createWorkspaceProvidersStatusProvider: workspaceProvidersStatusModule.createWorkspaceProvidersStatusProvider,
|
|
1238
1342
|
createWorkspaceSkillsStatusProvider: workspaceSkillsStatusModule.createWorkspaceSkillsStatusProvider,
|
|
1239
1343
|
createTotalSessionAdmissionController: totalSessionAdmissionModule.createTotalSessionAdmissionController,
|
|
1240
|
-
createWorkspaceRegistry: workspaceRegistryModule.createWorkspaceRegistry
|
|
1344
|
+
createWorkspaceRegistry: workspaceRegistryModule.createWorkspaceRegistry,
|
|
1345
|
+
createWorkspaceSessionOwnerIndex: workspaceRegistryModule.createWorkspaceSessionOwnerIndex
|
|
1241
1346
|
};
|
|
1242
1347
|
}
|
|
1243
1348
|
__name(loadServeRuntimeModules, "loadServeRuntimeModules");
|
|
@@ -1261,7 +1366,7 @@ function sessionIdleTimeoutMs(value) {
|
|
|
1261
1366
|
return value !== void 0 ? channelIdleTimeoutMs(value) : DEFAULT_SESSION_IDLE_TIMEOUT_MS;
|
|
1262
1367
|
}
|
|
1263
1368
|
__name(sessionIdleTimeoutMs, "sessionIdleTimeoutMs");
|
|
1264
|
-
function currentServeFeaturesForRunQwenServe(opts, sessionShellCommandEnabled) {
|
|
1369
|
+
function currentServeFeaturesForRunQwenServe(opts, sessionShellCommandEnabled, sessionArtifactsPersistenceAvailable, env) {
|
|
1265
1370
|
return getAdvertisedServeFeatures(void 0, {
|
|
1266
1371
|
requireAuth: opts.requireAuth === true,
|
|
1267
1372
|
mcpPoolActive: opts.mcpPoolActive !== false,
|
|
@@ -1270,12 +1375,18 @@ function currentServeFeaturesForRunQwenServe(opts, sessionShellCommandEnabled) {
|
|
|
1270
1375
|
...opts.writerIdleTimeoutMs !== void 0 ? { writerIdleTimeoutMs: opts.writerIdleTimeoutMs } : {},
|
|
1271
1376
|
persistSettingAvailable: true,
|
|
1272
1377
|
sessionShellCommandEnabled,
|
|
1378
|
+
sessionArtifactsPersistenceAvailable,
|
|
1273
1379
|
rateLimit: opts.rateLimit === true,
|
|
1274
1380
|
reloadAvailable: true,
|
|
1381
|
+
channelReloadAvailable: opts.channelSelection !== void 0,
|
|
1382
|
+
channelControlAvailable: true,
|
|
1383
|
+
persistentWorkspaceRegistrationAvailable: true,
|
|
1384
|
+
workspaceRuntimeRemovalAvailable: true,
|
|
1275
1385
|
// Advertise the same WS feature flags as the runtime path (serve-features.ts)
|
|
1276
1386
|
// so the bootstrap `/capabilities` window doesn't briefly under-report them.
|
|
1277
1387
|
clientMcpOverWsEnabled: opts.clientMcpOverWs === true,
|
|
1278
|
-
cdpTunnelOverWsEnabled: opts.cdpTunnelOverWs === true
|
|
1388
|
+
cdpTunnelOverWsEnabled: opts.cdpTunnelOverWs === true,
|
|
1389
|
+
browserAutomationMcpAvailable: isBrowserAutomationMcpAvailable(opts, env)
|
|
1279
1390
|
});
|
|
1280
1391
|
}
|
|
1281
1392
|
__name(currentServeFeaturesForRunQwenServe, "currentServeFeaturesForRunQwenServe");
|
|
@@ -1287,7 +1398,9 @@ function createBootstrapCapabilities(input) {
|
|
|
1287
1398
|
mode: input.opts.mode,
|
|
1288
1399
|
features: currentServeFeaturesForRunQwenServe(
|
|
1289
1400
|
input.opts,
|
|
1290
|
-
input.sessionShellCommandEnabled
|
|
1401
|
+
input.sessionShellCommandEnabled,
|
|
1402
|
+
input.sessionArtifactsPersistenceAvailable,
|
|
1403
|
+
input.env
|
|
1291
1404
|
),
|
|
1292
1405
|
modelServices: [],
|
|
1293
1406
|
workspaceCwd: input.boundWorkspace,
|
|
@@ -1432,10 +1545,12 @@ function createBootstrapServeApp(input) {
|
|
|
1432
1545
|
daemonLog,
|
|
1433
1546
|
qwenCodeVersion,
|
|
1434
1547
|
sessionShellCommandEnabled,
|
|
1548
|
+
sessionArtifactsPersistenceAvailable,
|
|
1435
1549
|
permissionPolicy,
|
|
1436
1550
|
multiWorkspaceCapabilitiesRequireRuntime,
|
|
1437
1551
|
getRuntimeError,
|
|
1438
1552
|
getChannelWorkerSnapshot,
|
|
1553
|
+
getChannelWorkerSnapshots,
|
|
1439
1554
|
onHealthServed
|
|
1440
1555
|
} = input;
|
|
1441
1556
|
const app = (0, import_express.default)();
|
|
@@ -1487,7 +1602,9 @@ function createBootstrapServeApp(input) {
|
|
|
1487
1602
|
boundWorkspace,
|
|
1488
1603
|
qwenCodeVersion,
|
|
1489
1604
|
sessionShellCommandEnabled,
|
|
1490
|
-
|
|
1605
|
+
sessionArtifactsPersistenceAvailable,
|
|
1606
|
+
permissionPolicy,
|
|
1607
|
+
env: process.env
|
|
1491
1608
|
})
|
|
1492
1609
|
);
|
|
1493
1610
|
});
|
|
@@ -1502,6 +1619,7 @@ function createBootstrapServeApp(input) {
|
|
|
1502
1619
|
}
|
|
1503
1620
|
const runtimeError = getRuntimeError();
|
|
1504
1621
|
const channelWorker = getChannelWorkerSnapshot();
|
|
1622
|
+
const channelWorkers = getChannelWorkerSnapshots();
|
|
1505
1623
|
const runtimeFailed = runtimeError !== void 0;
|
|
1506
1624
|
const issue = runtimeError ? {
|
|
1507
1625
|
code: "daemon_runtime_failed",
|
|
@@ -1558,7 +1676,9 @@ function createBootstrapServeApp(input) {
|
|
|
1558
1676
|
protocolVersions: getServeProtocolVersions(),
|
|
1559
1677
|
features: currentServeFeaturesForRunQwenServe(
|
|
1560
1678
|
opts,
|
|
1561
|
-
sessionShellCommandEnabled
|
|
1679
|
+
sessionShellCommandEnabled,
|
|
1680
|
+
sessionArtifactsPersistenceAvailable,
|
|
1681
|
+
process.env
|
|
1562
1682
|
)
|
|
1563
1683
|
},
|
|
1564
1684
|
runtime: {
|
|
@@ -1571,6 +1691,7 @@ function createBootstrapServeApp(input) {
|
|
|
1571
1691
|
},
|
|
1572
1692
|
channel: { live: false },
|
|
1573
1693
|
channelWorker,
|
|
1694
|
+
...channelWorkers.length > 0 ? { channelWorkers } : {},
|
|
1574
1695
|
transport: {
|
|
1575
1696
|
restSseActive: 0,
|
|
1576
1697
|
acp: {
|
|
@@ -1630,13 +1751,12 @@ function createDelegatingServeApp(bootstrapApp, getRuntimeApp, options = {}) {
|
|
|
1630
1751
|
const dispatch = /* @__PURE__ */ __name(async () => {
|
|
1631
1752
|
let target = getRuntimeApp();
|
|
1632
1753
|
if (!target && options.waitForDeferredRuntimeRoutes === true && !isBootstrapServeRoute(req) && !isCorsPreflightRequest(req) && options.startRuntime && options.runtimeReady) {
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
res,
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
return;
|
|
1754
|
+
const webhookRequest = isChannelWebhookRequest(req);
|
|
1755
|
+
const authGate = webhookRequest ? options.authenticateDeferredChannelWebhookRequest ?? options.authenticateDeferredRuntimeRequest : options.authenticateDeferredRuntimeRequest;
|
|
1756
|
+
if (authGate) {
|
|
1757
|
+
if (!runSynchronousRequestGate(authGate, req, res, next)) {
|
|
1758
|
+
return;
|
|
1759
|
+
}
|
|
1640
1760
|
}
|
|
1641
1761
|
options.startRuntime();
|
|
1642
1762
|
try {
|
|
@@ -1658,6 +1778,83 @@ function isBootstrapServeRoute(req) {
|
|
|
1658
1778
|
return BOOTSTRAP_SERVE_PATHS.has(path2);
|
|
1659
1779
|
}
|
|
1660
1780
|
__name(isBootstrapServeRoute, "isBootstrapServeRoute");
|
|
1781
|
+
function isChannelWebhookRequest(req) {
|
|
1782
|
+
return req.method === "POST" && /^\/channels\/[^/]+\/webhooks\/[^/]+\/?$/u.test(req.path);
|
|
1783
|
+
}
|
|
1784
|
+
__name(isChannelWebhookRequest, "isChannelWebhookRequest");
|
|
1785
|
+
function createDeferredChannelWebhookAuth(resolveSource, runtime, daemonLog) {
|
|
1786
|
+
return (req, res, next) => {
|
|
1787
|
+
const match = /^\/channels\/([^/]+)\/webhooks\/([^/]+)\/?$/u.exec(req.path);
|
|
1788
|
+
const channelName = decodeDeferredWebhookPathSegment(match?.[1]);
|
|
1789
|
+
const source = decodeDeferredWebhookPathSegment(match?.[2]);
|
|
1790
|
+
if (!channelName || !source) {
|
|
1791
|
+
daemonLog.warn("deferred webhook auth failed", {
|
|
1792
|
+
channelName: channelName ?? "unknown",
|
|
1793
|
+
source: source ?? "unknown",
|
|
1794
|
+
reason: "invalid webhook path"
|
|
1795
|
+
});
|
|
1796
|
+
res.status(401).json({ error: "Invalid webhook secret" });
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
const configSource = resolveSource(channelName);
|
|
1800
|
+
const secret = readDeferredWebhookSecret(
|
|
1801
|
+
runtime,
|
|
1802
|
+
configSource.workspaceCwd,
|
|
1803
|
+
channelName,
|
|
1804
|
+
source,
|
|
1805
|
+
configSource.env
|
|
1806
|
+
);
|
|
1807
|
+
if (!matchesWebhookSecret(req.get("x-qwen-webhook-secret"), secret)) {
|
|
1808
|
+
daemonLog.warn("deferred webhook auth failed", {
|
|
1809
|
+
channelName,
|
|
1810
|
+
source,
|
|
1811
|
+
reason: secret ? "secret mismatch" : "source not configured"
|
|
1812
|
+
});
|
|
1813
|
+
res.status(401).json({ error: "Invalid webhook secret" });
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
next();
|
|
1817
|
+
};
|
|
1818
|
+
}
|
|
1819
|
+
__name(createDeferredChannelWebhookAuth, "createDeferredChannelWebhookAuth");
|
|
1820
|
+
function decodeDeferredWebhookPathSegment(segment) {
|
|
1821
|
+
if (segment === void 0) return void 0;
|
|
1822
|
+
try {
|
|
1823
|
+
return decodeURIComponent(segment);
|
|
1824
|
+
} catch {
|
|
1825
|
+
return void 0;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
__name(decodeDeferredWebhookPathSegment, "decodeDeferredWebhookPathSegment");
|
|
1829
|
+
function readDeferredWebhookSecret(runtime, workspace, channelName, source, env) {
|
|
1830
|
+
try {
|
|
1831
|
+
const rawConfig = runtime.loadChannelsConfig(workspace)[channelName];
|
|
1832
|
+
if (typeof rawConfig !== "object" || rawConfig === null) {
|
|
1833
|
+
return void 0;
|
|
1834
|
+
}
|
|
1835
|
+
return runtime.parseChannelWebhookConfig(
|
|
1836
|
+
channelName,
|
|
1837
|
+
rawConfig,
|
|
1838
|
+
env
|
|
1839
|
+
)?.sources[source]?.secret;
|
|
1840
|
+
} catch (err) {
|
|
1841
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
1842
|
+
writeStderrLine(
|
|
1843
|
+
`[webhook-secret] failed to read deferred webhook secret for ${sanitizeLogText(channelName, 128)}/${sanitizeLogText(source, 128)}: ${sanitizeLogText(reason, 512)}`
|
|
1844
|
+
);
|
|
1845
|
+
return void 0;
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
__name(readDeferredWebhookSecret, "readDeferredWebhookSecret");
|
|
1849
|
+
function matchesWebhookSecret(candidate, expected) {
|
|
1850
|
+
if (typeof candidate !== "string" || typeof expected !== "string" || expected.length === 0) {
|
|
1851
|
+
return false;
|
|
1852
|
+
}
|
|
1853
|
+
const expectedDigest = createHash2("sha256").update(expected).digest();
|
|
1854
|
+
const candidateDigest = createHash2("sha256").update(candidate).digest();
|
|
1855
|
+
return timingSafeEqual(expectedDigest, candidateDigest);
|
|
1856
|
+
}
|
|
1857
|
+
__name(matchesWebhookSecret, "matchesWebhookSecret");
|
|
1661
1858
|
function isCorsPreflightRequest(req) {
|
|
1662
1859
|
return req.method === "OPTIONS" && Boolean(req.headers.origin) && Boolean(
|
|
1663
1860
|
req.headers["access-control-request-method"] || req.headers["access-control-request-headers"]
|
|
@@ -1723,30 +1920,42 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1723
1920
|
clientMcpOverWs: optsIn.clientMcpOverWs ?? (!envFlagDisabled(clientMcpOverWsEnv) && clientMcpOverWsEnv !== void 0),
|
|
1724
1921
|
cdpTunnelOverWs: optsIn.cdpTunnelOverWs ?? (!envFlagDisabled(cdpTunnelOverWsEnv) && (cdpTunnelOverWsEnv !== void 0 || chromeExtensionOriginAllowed))
|
|
1725
1922
|
};
|
|
1726
|
-
|
|
1727
|
-
|
|
1923
|
+
let channelRuntime = opts.channelSelection ? await loadChannelWorkerRuntime() : void 0;
|
|
1924
|
+
let channelServicePidfile = deps.channelServicePidfile ?? channelRuntime?.channelServicePidfile;
|
|
1925
|
+
const ensureChannelRuntime = /* @__PURE__ */ __name(async () => {
|
|
1926
|
+
channelRuntime ??= await loadChannelWorkerRuntime();
|
|
1927
|
+
channelServicePidfile ??= channelRuntime.channelServicePidfile;
|
|
1928
|
+
return channelRuntime;
|
|
1929
|
+
}, "ensureChannelRuntime");
|
|
1728
1930
|
let channelPidfileReserved = false;
|
|
1729
1931
|
const removeCurrentServePidfile = /* @__PURE__ */ __name(() => {
|
|
1730
|
-
if (!
|
|
1932
|
+
if (!channelServicePidfile) return;
|
|
1731
1933
|
if (!channelPidfileReserved) return;
|
|
1732
1934
|
if (channelServicePidfile.removeServeServiceInfo) {
|
|
1733
1935
|
if (channelServicePidfile.removeServeServiceInfo(process.pid)) {
|
|
1734
1936
|
channelPidfileReserved = false;
|
|
1937
|
+
} else {
|
|
1938
|
+
const info2 = channelServicePidfile.readServiceInfo();
|
|
1939
|
+
if (!info2 || info2.owner !== "serve" || info2.pid !== process.pid || info2.servePid !== process.pid) {
|
|
1940
|
+
channelPidfileReserved = false;
|
|
1941
|
+
}
|
|
1735
1942
|
}
|
|
1736
1943
|
return;
|
|
1737
1944
|
}
|
|
1738
1945
|
const info = channelServicePidfile.readServiceInfo();
|
|
1739
1946
|
if (info?.owner === "serve" && info.pid === process.pid && info.servePid === process.pid) {
|
|
1740
1947
|
channelServicePidfile.removeServiceInfo();
|
|
1948
|
+
const remaining = channelServicePidfile.readServiceInfo();
|
|
1949
|
+
channelPidfileReserved = remaining?.owner === "serve" && remaining.pid === process.pid && remaining.servePid === process.pid;
|
|
1950
|
+
} else {
|
|
1741
1951
|
channelPidfileReserved = false;
|
|
1742
1952
|
}
|
|
1743
1953
|
}, "removeCurrentServePidfile");
|
|
1744
|
-
const reserveChannelServicePidfile = /* @__PURE__ */ __name(() => {
|
|
1745
|
-
if (!opts.channelSelection) return;
|
|
1954
|
+
const reserveChannelServicePidfile = /* @__PURE__ */ __name((selection) => {
|
|
1746
1955
|
if (!channelServicePidfile) {
|
|
1747
1956
|
throw new Error("Channel service pidfile runtime is not available.");
|
|
1748
1957
|
}
|
|
1749
|
-
const channelPidfileNames = channelSelectionNames(
|
|
1958
|
+
const channelPidfileNames = channelSelectionNames(selection);
|
|
1750
1959
|
const existingChannelService = channelServicePidfile.readServiceInfo();
|
|
1751
1960
|
if (existingChannelService) {
|
|
1752
1961
|
throw channelServicePidfileConflictError(existingChannelService);
|
|
@@ -1771,9 +1980,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1771
1980
|
return;
|
|
1772
1981
|
} catch (retryErr) {
|
|
1773
1982
|
if (retryErr && typeof retryErr === "object" && "code" in retryErr && retryErr.code === "EEXIST") {
|
|
1774
|
-
throw
|
|
1775
|
-
"Channel service is already starting. Retry after the current startup finishes."
|
|
1776
|
-
);
|
|
1983
|
+
throw channelServiceStartingConflictError();
|
|
1777
1984
|
}
|
|
1778
1985
|
throw retryErr;
|
|
1779
1986
|
}
|
|
@@ -1892,7 +2099,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1892
2099
|
}, "validateAndCanonicalizeWorkspace");
|
|
1893
2100
|
const workspaceInputs = rawWorkspaces.map((workspace) => ({
|
|
1894
2101
|
raw: workspace,
|
|
1895
|
-
cwd: validateAndCanonicalizeWorkspace(workspace)
|
|
2102
|
+
cwd: validateAndCanonicalizeWorkspace(workspace),
|
|
2103
|
+
removable: false,
|
|
2104
|
+
registrationIds: []
|
|
1896
2105
|
}));
|
|
1897
2106
|
const boundWorkspace = workspaceInputs[0].cwd;
|
|
1898
2107
|
const seenCanonicalWorkspaces = /* @__PURE__ */ new Set();
|
|
@@ -1924,6 +2133,71 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1924
2133
|
}
|
|
1925
2134
|
}
|
|
1926
2135
|
}
|
|
2136
|
+
if (workspaceInputs.length > MAX_REGISTERED_WORKSPACES) {
|
|
2137
|
+
throw new Error(
|
|
2138
|
+
`At most ${MAX_REGISTERED_WORKSPACES} --workspace values may be registered.`
|
|
2139
|
+
);
|
|
2140
|
+
}
|
|
2141
|
+
let workspaceRegistrationStore = deps.workspaceRegistrationStore;
|
|
2142
|
+
if (workspaceRegistrationStore === void 0 && process.env["QWEN_SERVE_NO_PERSISTENT_REGISTRATION"] !== "1") {
|
|
2143
|
+
const { WorkspaceRegistrationStore } = await import("./workspace-registration-store-TARTAGMI.js");
|
|
2144
|
+
workspaceRegistrationStore = new WorkspaceRegistrationStore(boundWorkspace);
|
|
2145
|
+
}
|
|
2146
|
+
if (workspaceRegistrationStore) {
|
|
2147
|
+
try {
|
|
2148
|
+
const stored = await workspaceRegistrationStore.read();
|
|
2149
|
+
for (const storedWorkspace of stored.workspaces) {
|
|
2150
|
+
const registrationId = workspaceRegistrationId(storedWorkspace);
|
|
2151
|
+
let cwd;
|
|
2152
|
+
try {
|
|
2153
|
+
cwd = validateAndCanonicalizeWorkspace(storedWorkspace);
|
|
2154
|
+
} catch (err) {
|
|
2155
|
+
writeStderrLine(
|
|
2156
|
+
`qwen serve: skipping persisted workspace registration ${JSON.stringify(
|
|
2157
|
+
storedWorkspace
|
|
2158
|
+
)}: ${err instanceof Error ? err.message : String(err)}`
|
|
2159
|
+
);
|
|
2160
|
+
continue;
|
|
2161
|
+
}
|
|
2162
|
+
const existingInput = workspaceInputs.find(
|
|
2163
|
+
(workspace) => workspace.cwd === cwd
|
|
2164
|
+
);
|
|
2165
|
+
if (existingInput) {
|
|
2166
|
+
existingInput.registrationIds.push(registrationId);
|
|
2167
|
+
continue;
|
|
2168
|
+
}
|
|
2169
|
+
const nested = workspaceInputs.some(
|
|
2170
|
+
(workspace) => isWithinRoot(cwd, workspace.cwd) || isWithinRoot(workspace.cwd, cwd)
|
|
2171
|
+
);
|
|
2172
|
+
if (nested) {
|
|
2173
|
+
writeStderrLine(
|
|
2174
|
+
`qwen serve: skipping persisted workspace registration ${JSON.stringify(
|
|
2175
|
+
storedWorkspace
|
|
2176
|
+
)}: path nests with an explicit or earlier restored workspace`
|
|
2177
|
+
);
|
|
2178
|
+
continue;
|
|
2179
|
+
}
|
|
2180
|
+
if (workspaceInputs.length >= MAX_REGISTERED_WORKSPACES) {
|
|
2181
|
+
writeStderrLine(
|
|
2182
|
+
`qwen serve: skipping persisted workspace registration ${JSON.stringify(
|
|
2183
|
+
storedWorkspace
|
|
2184
|
+
)}: workspace limit reached`
|
|
2185
|
+
);
|
|
2186
|
+
continue;
|
|
2187
|
+
}
|
|
2188
|
+
workspaceInputs.push({
|
|
2189
|
+
raw: storedWorkspace,
|
|
2190
|
+
cwd,
|
|
2191
|
+
removable: true,
|
|
2192
|
+
registrationIds: [registrationId]
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
2195
|
+
} catch (err) {
|
|
2196
|
+
writeStderrLine(
|
|
2197
|
+
`qwen serve: failed to read persisted workspace registrations: ${err instanceof Error ? err.message : String(err)}; continuing with explicit workspaces only`
|
|
2198
|
+
);
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
1927
2201
|
if (workspaceInputs.length > 1 && deps.bridge) {
|
|
1928
2202
|
throw new Error(
|
|
1929
2203
|
"Injected bridge dependencies are only supported with a single workspace; multiple --workspace values require runQwenServe to construct one bridge per workspace."
|
|
@@ -1933,8 +2207,10 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
1933
2207
|
let permissionPolicy;
|
|
1934
2208
|
let permissionConsensusQuorum;
|
|
1935
2209
|
let bootSettings;
|
|
2210
|
+
let sessionArtifactsPersistenceAvailable = true;
|
|
1936
2211
|
try {
|
|
1937
2212
|
bootSettings = deps.bootSettings ?? loadServeFastPathSettings(boundWorkspace);
|
|
2213
|
+
sessionArtifactsPersistenceAvailable = sessionArtifactsPersistenceAvailableFromSettings(bootSettings);
|
|
1938
2214
|
contextFilenameForInit = extractContextFilename(
|
|
1939
2215
|
bootSettings.context?.fileName
|
|
1940
2216
|
);
|
|
@@ -2112,15 +2388,120 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2112
2388
|
daemonMetricsSampler?.dispose();
|
|
2113
2389
|
daemonMetricsSampler = void 0;
|
|
2114
2390
|
}, "disposeDaemonEventLoopMonitor");
|
|
2115
|
-
let
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2391
|
+
let channelWorkerManager;
|
|
2392
|
+
let channelWorkerManagerStarting;
|
|
2393
|
+
let channelControlDraining = false;
|
|
2394
|
+
let channelWorkspaceGroups;
|
|
2395
|
+
const channelWebhookEnvByWorkspace = /* @__PURE__ */ new Map();
|
|
2396
|
+
let channelWebhookConfigVersion = 0;
|
|
2397
|
+
let refreshChannelWebhookConfigs;
|
|
2398
|
+
let ensureChannelWorkerManager;
|
|
2399
|
+
const getChannelWebhookConfigSources = /* @__PURE__ */ __name(() => {
|
|
2400
|
+
const app2 = runtimeApp ?? runtimeAppForCleanup;
|
|
2401
|
+
const registry = app2?.locals?.["workspaceRegistry"];
|
|
2402
|
+
return (channelWorkspaceGroups ?? []).map((group) => {
|
|
2403
|
+
const env = registry?.getByWorkspaceCwd(group.workspaceCwd)?.env.effectiveEnv ?? channelWebhookEnvByWorkspace.get(group.workspaceCwd);
|
|
2404
|
+
return {
|
|
2405
|
+
workspaceCwd: group.workspaceCwd,
|
|
2406
|
+
...group.selection.mode === "names" ? { channelNames: group.selection.names } : {},
|
|
2407
|
+
...env ? { env } : {}
|
|
2408
|
+
};
|
|
2409
|
+
});
|
|
2410
|
+
}, "getChannelWebhookConfigSources");
|
|
2411
|
+
const resolveChannelWebhookConfigSource = /* @__PURE__ */ __name((channelName) => {
|
|
2412
|
+
const source = getChannelWebhookConfigSources().find(
|
|
2413
|
+
(source2) => !source2.channelNames || source2.channelNames.includes(channelName)
|
|
2414
|
+
);
|
|
2415
|
+
if (source) return source;
|
|
2416
|
+
const env = channelWebhookEnvByWorkspace.get(boundWorkspace);
|
|
2417
|
+
return {
|
|
2418
|
+
workspaceCwd: boundWorkspace,
|
|
2419
|
+
...env ? { env } : {}
|
|
2420
|
+
};
|
|
2421
|
+
}, "resolveChannelWebhookConfigSource");
|
|
2422
|
+
let closeServerAfterChannelWorkerStartupFailure = false;
|
|
2423
|
+
let runtimeFailureListenerClose;
|
|
2424
|
+
const getChannelWorkerSnapshot = /* @__PURE__ */ __name(() => channelWorkerManager?.primarySnapshot() ?? {
|
|
2425
|
+
enabled: false,
|
|
2426
|
+
state: "disabled",
|
|
2427
|
+
channels: []
|
|
2428
|
+
}, "getChannelWorkerSnapshot");
|
|
2429
|
+
const getChannelWorkerSnapshots = /* @__PURE__ */ __name(() => channelWorkerManager?.snapshots() ?? [], "getChannelWorkerSnapshots");
|
|
2430
|
+
const getChannelWorkerControl = /* @__PURE__ */ __name(() => channelWorkerManager?.state() ?? {
|
|
2431
|
+
enabled: false,
|
|
2432
|
+
selection: null,
|
|
2433
|
+
transition: "idle",
|
|
2434
|
+
workers: []
|
|
2435
|
+
}, "getChannelWorkerControl");
|
|
2436
|
+
const daemonDrainingError = /* @__PURE__ */ __name(() => Object.assign(new Error("Daemon is shutting down."), {
|
|
2437
|
+
code: "daemon_draining"
|
|
2438
|
+
}), "daemonDrainingError");
|
|
2439
|
+
const setChannelWorkerSelection = /* @__PURE__ */ __name(async (selection) => {
|
|
2440
|
+
if (channelControlDraining) throw daemonDrainingError();
|
|
2441
|
+
const manager = await ensureChannelWorkerManager?.();
|
|
2442
|
+
if (!manager) throw new Error("Channel worker manager is unavailable.");
|
|
2443
|
+
if (channelControlDraining) {
|
|
2444
|
+
await manager.shutdown().catch(() => void 0);
|
|
2445
|
+
throw daemonDrainingError();
|
|
2446
|
+
}
|
|
2447
|
+
return manager.setSelection(selection);
|
|
2448
|
+
}, "setChannelWorkerSelection");
|
|
2449
|
+
const stopChannelWorker = /* @__PURE__ */ __name(async () => {
|
|
2450
|
+
if (channelControlDraining) throw daemonDrainingError();
|
|
2451
|
+
const manager = channelWorkerManager ?? await channelWorkerManagerStarting;
|
|
2452
|
+
if (channelControlDraining) {
|
|
2453
|
+
await manager?.shutdown().catch(() => void 0);
|
|
2454
|
+
throw daemonDrainingError();
|
|
2455
|
+
}
|
|
2456
|
+
if (!manager) {
|
|
2457
|
+
return { changed: false, state: getChannelWorkerControl() };
|
|
2458
|
+
}
|
|
2459
|
+
return manager.stopSelection();
|
|
2460
|
+
}, "stopChannelWorker");
|
|
2461
|
+
const reloadChannelWorker = /* @__PURE__ */ __name(async () => {
|
|
2462
|
+
if (channelControlDraining) throw daemonDrainingError();
|
|
2463
|
+
const manager = channelWorkerManager ?? await channelWorkerManagerStarting;
|
|
2464
|
+
if (channelControlDraining) {
|
|
2465
|
+
await manager?.shutdown().catch(() => void 0);
|
|
2466
|
+
throw daemonDrainingError();
|
|
2467
|
+
}
|
|
2468
|
+
if (!manager) {
|
|
2469
|
+
return { enabled: false, state: "disabled", channels: [] };
|
|
2470
|
+
}
|
|
2471
|
+
try {
|
|
2472
|
+
return await manager.reload();
|
|
2473
|
+
} finally {
|
|
2474
|
+
writeChannelWorkerPidfile();
|
|
2475
|
+
}
|
|
2476
|
+
}, "reloadChannelWorker");
|
|
2477
|
+
const isLiveWorker = /* @__PURE__ */ __name((snapshot) => snapshot.state === "running" || snapshot.state === "starting", "isLiveWorker");
|
|
2478
|
+
let channelWorkerPidfileUsesWorkers = workspaceInputs.length > 1;
|
|
2479
|
+
const writeChannelWorkerPidfile = /* @__PURE__ */ __name(() => {
|
|
2480
|
+
if (runtimeStartupError !== void 0) return;
|
|
2481
|
+
if (!channelPidfileReserved || !channelServicePidfile) return;
|
|
2482
|
+
const snapshots = getChannelWorkerSnapshots();
|
|
2483
|
+
const workers = snapshots.map((snapshot) => ({
|
|
2484
|
+
workspaceId: snapshot.workspaceId,
|
|
2485
|
+
workspaceCwd: snapshot.workspaceCwd,
|
|
2486
|
+
channels: snapshot.channels,
|
|
2487
|
+
// Drop a stale pid (worker exited/failed/stopped) so readers never signal
|
|
2488
|
+
// a dead process — mirrors the pre-4b clear-on-exit behavior.
|
|
2489
|
+
...isLiveWorker(snapshot) && snapshot.pid !== void 0 ? { workerPid: snapshot.pid } : {}
|
|
2490
|
+
}));
|
|
2491
|
+
const channels = [
|
|
2492
|
+
...new Set(snapshots.flatMap((snapshot) => snapshot.channels))
|
|
2493
|
+
];
|
|
2494
|
+
const primary = snapshots.find((snapshot) => snapshot.primary);
|
|
2495
|
+
if (workers.length > 1 || snapshots.some((snapshot) => !snapshot.primary)) {
|
|
2496
|
+
channelWorkerPidfileUsesWorkers = true;
|
|
2497
|
+
}
|
|
2498
|
+
const includeWorkers = channelWorkerPidfileUsesWorkers && workers.length > 0;
|
|
2119
2499
|
try {
|
|
2120
2500
|
channelServicePidfile.writeServeServiceInfo({
|
|
2121
|
-
channels
|
|
2501
|
+
channels,
|
|
2122
2502
|
servePid: process.pid,
|
|
2123
|
-
|
|
2503
|
+
...primary && isLiveWorker(primary) && primary.pid !== void 0 ? { workerPid: primary.pid } : {},
|
|
2504
|
+
...includeWorkers ? { workers } : {}
|
|
2124
2505
|
});
|
|
2125
2506
|
} catch (err) {
|
|
2126
2507
|
daemonLog.warn(
|
|
@@ -2137,7 +2518,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2137
2518
|
const appForCleanup = runtimeApp ?? runtimeAppForCleanup;
|
|
2138
2519
|
const registry = appForCleanup?.locals?.["workspaceRegistry"];
|
|
2139
2520
|
const bridges = [
|
|
2140
|
-
...registry ? registry.
|
|
2521
|
+
...registry ? registry.listManaged().map((runtime) => runtime.bridge) : [],
|
|
2141
2522
|
...bridgeRef ? [bridgeRef] : [],
|
|
2142
2523
|
...internalRuntimeBridgesForCleanup
|
|
2143
2524
|
];
|
|
@@ -2414,6 +2795,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2414
2795
|
getBridges: /* @__PURE__ */ __name(() => runtimeBridges.length > 0 ? runtimeBridges : bridgeRef ? [bridgeRef] : [], "getBridges")
|
|
2415
2796
|
}
|
|
2416
2797
|
);
|
|
2798
|
+
const sessionOwnerIndex = runtime.createWorkspaceSessionOwnerIndex();
|
|
2417
2799
|
const persistDisabledToolsFn = /* @__PURE__ */ __name((workspace, toolName, enabled) => withSettingsLock(workspace, async () => {
|
|
2418
2800
|
const fresh = settingsRuntime.settings.loadSettings(workspace);
|
|
2419
2801
|
const wsScope = fresh.forScope(WORKSPACE_SETTING_SCOPE).settings;
|
|
@@ -2460,12 +2842,19 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2460
2842
|
);
|
|
2461
2843
|
}
|
|
2462
2844
|
}), "persistSettingsFn");
|
|
2845
|
+
const { createSubSessionLauncher } = await import("./create-sub-session-TCLIYVGR.js");
|
|
2846
|
+
const subSessionLauncher = createSubSessionLauncher({
|
|
2847
|
+
getBridge: /* @__PURE__ */ __name(() => bridgeRef, "getBridge"),
|
|
2848
|
+
boundWorkspace
|
|
2849
|
+
});
|
|
2463
2850
|
const bridge = deps.bridge ?? runtime.createAcpSessionBridge({
|
|
2464
2851
|
// Reverse tool channel: let `BridgeClient.extMethod` reach the WS
|
|
2465
2852
|
// connection that hosts a named client MCP server (#5626).
|
|
2466
2853
|
clientMcpSender: clientMcpSenderRegistry.lookup,
|
|
2854
|
+
onCreateSubSession: subSessionLauncher.launch,
|
|
2467
2855
|
maxSessions: opts.maxSessions,
|
|
2468
2856
|
freshSessionAdmission: totalSessionAdmission.admit,
|
|
2857
|
+
sessionLifecycle: sessionOwnerIndex.handleBridgeSessionLifecycle,
|
|
2469
2858
|
...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
|
|
2470
2859
|
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
2471
2860
|
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
@@ -2504,6 +2893,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2504
2893
|
persistDisabledTools: persistDisabledToolsFn,
|
|
2505
2894
|
persistSetting: persistSettingFn,
|
|
2506
2895
|
persistSettings: persistSettingsFn,
|
|
2896
|
+
preheatAcpChild: /* @__PURE__ */ __name(() => bridge.preheat(), "preheatAcpChild"),
|
|
2507
2897
|
reloadDaemonEnv: /* @__PURE__ */ __name((workspace) => withSettingsLock(workspace, async () => {
|
|
2508
2898
|
const fresh = settingsRuntime.settings.loadSettings(workspace, {
|
|
2509
2899
|
skipLoadEnvironment: true
|
|
@@ -2574,6 +2964,8 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2574
2964
|
workspaceCwd: boundWorkspace,
|
|
2575
2965
|
primary: true,
|
|
2576
2966
|
trusted: trustedWorkspace,
|
|
2967
|
+
removable: false,
|
|
2968
|
+
registrationIds: workspaceInputs[0]?.registrationIds ?? [],
|
|
2577
2969
|
env: primaryRuntimeEnv,
|
|
2578
2970
|
bridge,
|
|
2579
2971
|
workspaceService,
|
|
@@ -2614,6 +3006,13 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2614
3006
|
}
|
|
2615
3007
|
};
|
|
2616
3008
|
}, "createRuntimeEnvMetadata");
|
|
3009
|
+
const subSessionStoppers = [];
|
|
3010
|
+
const subSessionStoppersByWorkspace = /* @__PURE__ */ new Map();
|
|
3011
|
+
const runtimeCleanupPromises = /* @__PURE__ */ new WeakMap();
|
|
3012
|
+
const removeArrayValue = /* @__PURE__ */ __name((values, value) => {
|
|
3013
|
+
const index = values.indexOf(value);
|
|
3014
|
+
if (index >= 0) values.splice(index, 1);
|
|
3015
|
+
}, "removeArrayValue");
|
|
2617
3016
|
for (const workspaceInput of workspaceInputs.slice(1)) {
|
|
2618
3017
|
let secondarySettings;
|
|
2619
3018
|
try {
|
|
@@ -2667,10 +3066,17 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2667
3066
|
...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
|
|
2668
3067
|
});
|
|
2669
3068
|
const secondaryClientMcpSenderRegistry = new ClientMcpSenderRegistry();
|
|
3069
|
+
let secondaryBridgeRef;
|
|
3070
|
+
const secondarySubSessionLauncher = createSubSessionLauncher({
|
|
3071
|
+
getBridge: /* @__PURE__ */ __name(() => secondaryBridgeRef, "getBridge"),
|
|
3072
|
+
boundWorkspace: workspaceInput.cwd
|
|
3073
|
+
});
|
|
2670
3074
|
const secondaryBridge = runtime.createAcpSessionBridge({
|
|
2671
3075
|
clientMcpSender: secondaryClientMcpSenderRegistry.lookup,
|
|
3076
|
+
onCreateSubSession: secondarySubSessionLauncher.launch,
|
|
2672
3077
|
maxSessions: opts.maxSessions,
|
|
2673
3078
|
freshSessionAdmission: totalSessionAdmission.admit,
|
|
3079
|
+
sessionLifecycle: sessionOwnerIndex.handleBridgeSessionLifecycle,
|
|
2674
3080
|
...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
|
|
2675
3081
|
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
2676
3082
|
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
@@ -2696,8 +3102,14 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2696
3102
|
fresh.setValue(WORKSPACE_SETTING_SCOPE, "tools.approvalMode", mode);
|
|
2697
3103
|
}), "persistApprovalMode")
|
|
2698
3104
|
});
|
|
3105
|
+
secondaryBridgeRef = secondaryBridge;
|
|
2699
3106
|
runtimeBridges.push(secondaryBridge);
|
|
2700
3107
|
internalRuntimeBridgesForCleanup.push(secondaryBridge);
|
|
3108
|
+
subSessionStoppers.push(secondarySubSessionLauncher.stop);
|
|
3109
|
+
subSessionStoppersByWorkspace.set(
|
|
3110
|
+
workspaceInput.cwd,
|
|
3111
|
+
secondarySubSessionLauncher.stop
|
|
3112
|
+
);
|
|
2701
3113
|
const secondaryWorkspaceService = runtime.createDaemonWorkspaceService({
|
|
2702
3114
|
boundWorkspace: workspaceInput.cwd,
|
|
2703
3115
|
contextFilename: contextFilenameForInit ?? "QWEN.md",
|
|
@@ -2707,6 +3119,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2707
3119
|
}),
|
|
2708
3120
|
workspaceSkillsStatusProvider: runtime.createWorkspaceSkillsStatusProvider(),
|
|
2709
3121
|
isChannelLive: /* @__PURE__ */ __name(() => secondaryBridge.isChannelLive(), "isChannelLive"),
|
|
3122
|
+
preheatAcpChild: /* @__PURE__ */ __name(() => secondaryBridge.preheat(), "preheatAcpChild"),
|
|
2710
3123
|
persistDisabledTools: persistDisabledToolsFn,
|
|
2711
3124
|
persistSetting: persistSettingFn,
|
|
2712
3125
|
persistSettings: persistSettingsFn,
|
|
@@ -2765,6 +3178,8 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2765
3178
|
workspaceCwd: workspaceInput.cwd,
|
|
2766
3179
|
primary: false,
|
|
2767
3180
|
trusted: secondaryTrusted,
|
|
3181
|
+
removable: workspaceInput.removable,
|
|
3182
|
+
registrationIds: workspaceInput.registrationIds,
|
|
2768
3183
|
env: secondaryEnv.metadata,
|
|
2769
3184
|
bridge: secondaryBridge,
|
|
2770
3185
|
workspaceService: secondaryWorkspaceService,
|
|
@@ -2772,7 +3187,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2772
3187
|
clientMcpSenderRegistry: secondaryClientMcpSenderRegistry
|
|
2773
3188
|
});
|
|
2774
3189
|
}
|
|
2775
|
-
const workspaceRegistry = runtime.createWorkspaceRegistry(workspaceRuntimes
|
|
3190
|
+
const workspaceRegistry = runtime.createWorkspaceRegistry(workspaceRuntimes, {
|
|
3191
|
+
sessionOwnerIndex
|
|
3192
|
+
});
|
|
2776
3193
|
core.registerDaemonGaugeCallbacks({
|
|
2777
3194
|
sessionCount: /* @__PURE__ */ __name(() => workspaceRegistry.list().reduce((sum, item) => sum + item.bridge.sessionCount, 0), "sessionCount"),
|
|
2778
3195
|
sseCount: /* @__PURE__ */ __name(() => runtime.getActiveSseCount(), "sseCount"),
|
|
@@ -2801,7 +3218,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2801
3218
|
prevCpu = cpu;
|
|
2802
3219
|
prevCpuAt = nowMs;
|
|
2803
3220
|
}
|
|
2804
|
-
const acp = app2.locals?.["acpHandle"]?.
|
|
3221
|
+
const acp = app2.locals?.["acpHandle"]?.getSnapshot();
|
|
2805
3222
|
const hits = getRateLimiter(app2)?.getHitCounts();
|
|
2806
3223
|
const rejectedTotal = hits ? hits.prompt + hits.mutation + hits.read : 0;
|
|
2807
3224
|
const rateLimitRejected = prevRateRejected === void 0 ? 0 : Math.max(0, rejectedTotal - prevRateRejected);
|
|
@@ -2864,8 +3281,305 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2864
3281
|
metricsLoopDelay.disable();
|
|
2865
3282
|
}
|
|
2866
3283
|
};
|
|
3284
|
+
const createDynamicWorkspaceRuntime = /* @__PURE__ */ __name(async (cwd) => {
|
|
3285
|
+
let wsSettings;
|
|
3286
|
+
try {
|
|
3287
|
+
wsSettings = settingsRuntime.settings.loadSettings(cwd);
|
|
3288
|
+
} catch (err) {
|
|
3289
|
+
writeStderrLine(
|
|
3290
|
+
`qwen serve: could not read full settings for dynamic workspace ${cwd} (${err instanceof Error ? err.message : String(err)}); falling back to defaults.`
|
|
3291
|
+
);
|
|
3292
|
+
}
|
|
3293
|
+
const trusted = wsSettings ? settingsRuntime.trustedFolders.getWorkspaceTrustStatus(
|
|
3294
|
+
wsSettings.merged,
|
|
3295
|
+
cwd
|
|
3296
|
+
).effective.state === "trusted" : false;
|
|
3297
|
+
const wsEnv = createRuntimeEnvMetadata(cwd, wsSettings);
|
|
3298
|
+
const wsHash = core.hashDaemonWorkspace(cwd);
|
|
3299
|
+
const wsFsFactory = runtime.resolveBridgeFsFactory({
|
|
3300
|
+
boundWorkspaces: [cwd],
|
|
3301
|
+
trusted,
|
|
3302
|
+
emit: deps.fsAuditEmit,
|
|
3303
|
+
pathLocks: sharedPathLocks,
|
|
3304
|
+
...customIgnoreFiles !== void 0 ? { customIgnoreFiles } : {}
|
|
3305
|
+
});
|
|
3306
|
+
const wsChannelFactory = runtime.createSpawnChannelFactory({
|
|
3307
|
+
sourceEnv: wsEnv.effectiveEnv,
|
|
3308
|
+
onDiagnosticLine: diagnosticSink,
|
|
3309
|
+
pipeHooks: {
|
|
3310
|
+
onMessageSent: /* @__PURE__ */ __name((bytes) => recordPipeMessage("outbound", bytes), "onMessageSent"),
|
|
3311
|
+
onMessageReceived: /* @__PURE__ */ __name((bytes) => recordPipeMessage("inbound", bytes), "onMessageReceived"),
|
|
3312
|
+
onMessageObserved: /* @__PURE__ */ __name(({ direction, bytes, message }) => observeLargePipeFrame({
|
|
3313
|
+
direction: daemonPipeDirection(direction),
|
|
3314
|
+
bytes,
|
|
3315
|
+
message
|
|
3316
|
+
}), "onMessageObserved")
|
|
3317
|
+
},
|
|
3318
|
+
...opts.experimentalLsp === true ? { extraArgs: ["--experimental-lsp"] } : {}
|
|
3319
|
+
});
|
|
3320
|
+
const wsClientMcpRegistry = new ClientMcpSenderRegistry();
|
|
3321
|
+
let wsBridgeRef;
|
|
3322
|
+
const wsSubSessionLauncher = createSubSessionLauncher({
|
|
3323
|
+
getBridge: /* @__PURE__ */ __name(() => wsBridgeRef, "getBridge"),
|
|
3324
|
+
boundWorkspace: cwd
|
|
3325
|
+
});
|
|
3326
|
+
let wsBridge;
|
|
3327
|
+
try {
|
|
3328
|
+
wsBridge = runtime.createAcpSessionBridge({
|
|
3329
|
+
clientMcpSender: wsClientMcpRegistry.lookup,
|
|
3330
|
+
onCreateSubSession: wsSubSessionLauncher.launch,
|
|
3331
|
+
maxSessions: opts.maxSessions,
|
|
3332
|
+
freshSessionAdmission: totalSessionAdmission.admit,
|
|
3333
|
+
sessionLifecycle: sessionOwnerIndex.handleBridgeSessionLifecycle,
|
|
3334
|
+
...opts.maxPendingPromptsPerSession !== void 0 ? { maxPendingPromptsPerSession: opts.maxPendingPromptsPerSession } : {},
|
|
3335
|
+
...opts.eventRingSize !== void 0 ? { eventRingSize: opts.eventRingSize } : {},
|
|
3336
|
+
...opts.compactedReplayMaxBytes !== void 0 ? { compactedReplayMaxBytes: opts.compactedReplayMaxBytes } : {},
|
|
3337
|
+
...opts.channelIdleTimeoutMs !== void 0 ? { channelIdleTimeoutMs: opts.channelIdleTimeoutMs } : {},
|
|
3338
|
+
...opts.sessionReapIntervalMs !== void 0 ? { sessionReapIntervalMs: opts.sessionReapIntervalMs } : {},
|
|
3339
|
+
...opts.sessionIdleTimeoutMs !== void 0 ? { sessionIdleTimeoutMs: opts.sessionIdleTimeoutMs } : {},
|
|
3340
|
+
...opts.permissionResponseTimeoutMs !== void 0 ? { permissionResponseTimeoutMs: opts.permissionResponseTimeoutMs } : {},
|
|
3341
|
+
boundWorkspace: cwd,
|
|
3342
|
+
sessionShellCommandEnabled,
|
|
3343
|
+
childEnvOverrides,
|
|
3344
|
+
channelFactory: wsChannelFactory,
|
|
3345
|
+
onDiagnosticLine: diagnosticSink,
|
|
3346
|
+
telemetry: createRuntimeBridgeTelemetry(wsHash),
|
|
3347
|
+
...permissionPolicy !== void 0 ? { permissionPolicy } : {},
|
|
3348
|
+
...permissionConsensusQuorum !== void 0 ? { permissionConsensusQuorum } : {},
|
|
3349
|
+
permissionAudit: permissionAuditPublisher,
|
|
3350
|
+
statusProvider: runtime.createDaemonStatusProvider({
|
|
3351
|
+
env: wsEnv.effectiveEnv
|
|
3352
|
+
}),
|
|
3353
|
+
fileSystem: createBridgeFileSystemAdapter(wsFsFactory),
|
|
3354
|
+
persistApprovalMode: /* @__PURE__ */ __name((workspace, mode) => withSettingsLock(workspace, async () => {
|
|
3355
|
+
const fresh = settingsRuntime.settings.loadSettings(workspace);
|
|
3356
|
+
fresh.setValue(
|
|
3357
|
+
WORKSPACE_SETTING_SCOPE,
|
|
3358
|
+
"tools.approvalMode",
|
|
3359
|
+
mode
|
|
3360
|
+
);
|
|
3361
|
+
}), "persistApprovalMode")
|
|
3362
|
+
});
|
|
3363
|
+
} catch (err) {
|
|
3364
|
+
wsSubSessionLauncher.stop();
|
|
3365
|
+
throw err;
|
|
3366
|
+
}
|
|
3367
|
+
wsBridgeRef = wsBridge;
|
|
3368
|
+
let wsService;
|
|
3369
|
+
try {
|
|
3370
|
+
wsService = runtime.createDaemonWorkspaceService({
|
|
3371
|
+
boundWorkspace: cwd,
|
|
3372
|
+
contextFilename: contextFilenameForInit ?? "QWEN.md",
|
|
3373
|
+
statusProvider: runtime.createDaemonStatusProvider({
|
|
3374
|
+
env: wsEnv.effectiveEnv
|
|
3375
|
+
}),
|
|
3376
|
+
workspaceProvidersStatusProvider: runtime.createWorkspaceProvidersStatusProvider({
|
|
3377
|
+
env: wsEnv.effectiveEnv
|
|
3378
|
+
}),
|
|
3379
|
+
workspaceSkillsStatusProvider: runtime.createWorkspaceSkillsStatusProvider(),
|
|
3380
|
+
isChannelLive: /* @__PURE__ */ __name(() => wsBridge.isChannelLive(), "isChannelLive"),
|
|
3381
|
+
preheatAcpChild: /* @__PURE__ */ __name(() => wsBridge.preheat(), "preheatAcpChild"),
|
|
3382
|
+
persistDisabledTools: persistDisabledToolsFn,
|
|
3383
|
+
persistSetting: persistSettingFn,
|
|
3384
|
+
persistSettings: persistSettingsFn,
|
|
3385
|
+
reloadDaemonEnv: /* @__PURE__ */ __name((workspace) => withSettingsLock(workspace, async () => {
|
|
3386
|
+
const fresh = settingsRuntime.settings.loadSettings(workspace, {
|
|
3387
|
+
skipLoadEnvironment: true
|
|
3388
|
+
});
|
|
3389
|
+
const result = settingsRuntime.settings.reloadEnvironment(
|
|
3390
|
+
fresh.merged,
|
|
3391
|
+
workspace
|
|
3392
|
+
);
|
|
3393
|
+
try {
|
|
3394
|
+
const refreshedRuntimeEnv = settingsRuntime.environment.buildRuntimeEnvironment(
|
|
3395
|
+
fresh.merged,
|
|
3396
|
+
workspace,
|
|
3397
|
+
daemonRuntimeBaseEnv
|
|
3398
|
+
);
|
|
3399
|
+
logRuntimeEnvFileReadFailures(workspace, refreshedRuntimeEnv);
|
|
3400
|
+
wsEnv.replace(refreshedRuntimeEnv.effectiveEnv);
|
|
3401
|
+
wsEnv.metadata.envFileReadFailed = refreshedRuntimeEnv.envFileReadFailed;
|
|
3402
|
+
wsEnv.metadata.envFileReadFailures.splice(
|
|
3403
|
+
0,
|
|
3404
|
+
wsEnv.metadata.envFileReadFailures.length,
|
|
3405
|
+
...refreshedRuntimeEnv.envFileReadFailures
|
|
3406
|
+
);
|
|
3407
|
+
wsEnv.metadata.overlayKeys.splice(
|
|
3408
|
+
0,
|
|
3409
|
+
wsEnv.metadata.overlayKeys.length,
|
|
3410
|
+
...refreshedRuntimeEnv.overlayKeys
|
|
3411
|
+
);
|
|
3412
|
+
wsEnv.metadata.envFilePaths.splice(
|
|
3413
|
+
0,
|
|
3414
|
+
wsEnv.metadata.envFilePaths.length,
|
|
3415
|
+
...refreshedRuntimeEnv.envFilePaths
|
|
3416
|
+
);
|
|
3417
|
+
delete wsEnv.metadata.fallbackReason;
|
|
3418
|
+
} catch (err) {
|
|
3419
|
+
wsEnv.metadata.fallbackReason = err instanceof Error ? err.message : String(err);
|
|
3420
|
+
daemonLog.warn(
|
|
3421
|
+
"failed to rebuild dynamic runtime env snapshot after daemon env reload; preserving previous runtime env",
|
|
3422
|
+
{
|
|
3423
|
+
workspace,
|
|
3424
|
+
error: wsEnv.metadata.fallbackReason
|
|
3425
|
+
}
|
|
3426
|
+
);
|
|
3427
|
+
}
|
|
3428
|
+
return result;
|
|
3429
|
+
}), "reloadDaemonEnv"),
|
|
3430
|
+
queryWorkspaceStatus: /* @__PURE__ */ __name((method, idle) => wsBridge.queryWorkspaceStatus(method, idle), "queryWorkspaceStatus"),
|
|
3431
|
+
invokeWorkspaceCommand: /* @__PURE__ */ __name((method, params, invokeOpts) => wsBridge.invokeWorkspaceCommand(method, params, invokeOpts), "invokeWorkspaceCommand"),
|
|
3432
|
+
refreshExtensionsForAllSessions: /* @__PURE__ */ __name(() => wsBridge.refreshExtensionsForAllSessions(), "refreshExtensionsForAllSessions"),
|
|
3433
|
+
publishWorkspaceEvent: /* @__PURE__ */ __name((event) => wsBridge.publishWorkspaceEvent(event), "publishWorkspaceEvent")
|
|
3434
|
+
});
|
|
3435
|
+
} catch (err) {
|
|
3436
|
+
wsSubSessionLauncher.stop();
|
|
3437
|
+
await wsBridge.shutdown().catch(() => {
|
|
3438
|
+
try {
|
|
3439
|
+
wsBridge.killAllSync();
|
|
3440
|
+
} catch {
|
|
3441
|
+
}
|
|
3442
|
+
});
|
|
3443
|
+
throw err;
|
|
3444
|
+
}
|
|
3445
|
+
runtimeBridges.push(wsBridge);
|
|
3446
|
+
internalRuntimeBridgesForCleanup.push(wsBridge);
|
|
3447
|
+
subSessionStoppers.push(wsSubSessionLauncher.stop);
|
|
3448
|
+
subSessionStoppersByWorkspace.set(cwd, wsSubSessionLauncher.stop);
|
|
3449
|
+
return {
|
|
3450
|
+
workspaceId: wsHash,
|
|
3451
|
+
workspaceCwd: cwd,
|
|
3452
|
+
primary: false,
|
|
3453
|
+
trusted,
|
|
3454
|
+
removable: true,
|
|
3455
|
+
registrationIds: [],
|
|
3456
|
+
env: wsEnv.metadata,
|
|
3457
|
+
bridge: wsBridge,
|
|
3458
|
+
workspaceService: wsService,
|
|
3459
|
+
routeFileSystemFactory: wsFsFactory,
|
|
3460
|
+
clientMcpSenderRegistry: wsClientMcpRegistry
|
|
3461
|
+
};
|
|
3462
|
+
}, "createDynamicWorkspaceRuntime");
|
|
3463
|
+
const workspaceRuntimeRemoval = {
|
|
3464
|
+
async runtimeAdded(runtimeAdded) {
|
|
3465
|
+
const app3 = runtimeApp ?? runtimeAppForCleanup;
|
|
3466
|
+
const startScheduledTaskKeepaliveForWorkspace = app3?.locals?.["startScheduledTaskKeepaliveForWorkspace"];
|
|
3467
|
+
startScheduledTaskKeepaliveForWorkspace?.(runtimeAdded);
|
|
3468
|
+
if (!channelWorkerManager) return;
|
|
3469
|
+
try {
|
|
3470
|
+
await channelWorkerManager.restoreWorkspace(
|
|
3471
|
+
runtimeAdded.workspaceCwd
|
|
3472
|
+
);
|
|
3473
|
+
await channelWorkerManager.refreshWorkspaces();
|
|
3474
|
+
} catch (err) {
|
|
3475
|
+
daemonLog.error(
|
|
3476
|
+
"workspace channel worker startup error",
|
|
3477
|
+
err instanceof Error ? err : null
|
|
3478
|
+
);
|
|
3479
|
+
} finally {
|
|
3480
|
+
writeChannelWorkerPidfile();
|
|
3481
|
+
}
|
|
3482
|
+
},
|
|
3483
|
+
beginDrain(runtimeToDrain) {
|
|
3484
|
+
totalSessionAdmission.beginWorkspaceDrain(runtimeToDrain.workspaceCwd);
|
|
3485
|
+
channelWorkerManager?.beginWorkspaceDrain(runtimeToDrain.workspaceCwd);
|
|
3486
|
+
},
|
|
3487
|
+
cancelDrain(runtimeToDrain) {
|
|
3488
|
+
channelWorkerManager?.cancelWorkspaceDrain(runtimeToDrain.workspaceCwd);
|
|
3489
|
+
totalSessionAdmission.cancelWorkspaceDrain(runtimeToDrain.workspaceCwd);
|
|
3490
|
+
},
|
|
3491
|
+
completeDrain(runtimeToDrain) {
|
|
3492
|
+
totalSessionAdmission.completeWorkspaceDrain(
|
|
3493
|
+
runtimeToDrain.workspaceCwd
|
|
3494
|
+
);
|
|
3495
|
+
},
|
|
3496
|
+
getActivity(runtimeToDrain) {
|
|
3497
|
+
return {
|
|
3498
|
+
pendingSessionStarts: totalSessionAdmission.snapshotForWorkspace(
|
|
3499
|
+
runtimeToDrain.workspaceCwd
|
|
3500
|
+
).inFlight,
|
|
3501
|
+
channelWorkers: channelWorkerManager?.workspaceActivity(
|
|
3502
|
+
runtimeToDrain.workspaceCwd
|
|
3503
|
+
) ?? 0
|
|
3504
|
+
};
|
|
3505
|
+
},
|
|
3506
|
+
disposeRuntime(runtimeToDrain, reason = "workspace_removed") {
|
|
3507
|
+
const existing = runtimeCleanupPromises.get(runtimeToDrain);
|
|
3508
|
+
if (existing) return existing;
|
|
3509
|
+
const cleanup = (async () => {
|
|
3510
|
+
const stopSubSessions = subSessionStoppersByWorkspace.get(
|
|
3511
|
+
runtimeToDrain.workspaceCwd
|
|
3512
|
+
);
|
|
3513
|
+
try {
|
|
3514
|
+
stopSubSessions?.();
|
|
3515
|
+
} catch {
|
|
3516
|
+
}
|
|
3517
|
+
if (reason === "workspace_removed" && channelWorkerManager) {
|
|
3518
|
+
await channelWorkerManager.removeWorkspace(runtimeToDrain.workspaceCwd).catch((err) => {
|
|
3519
|
+
daemonLog.error(
|
|
3520
|
+
"workspace channel worker cleanup error",
|
|
3521
|
+
err instanceof Error ? err : null
|
|
3522
|
+
);
|
|
3523
|
+
});
|
|
3524
|
+
try {
|
|
3525
|
+
await channelWorkerManager.refreshWorkspaces();
|
|
3526
|
+
} catch (err) {
|
|
3527
|
+
channelWorkspaceGroups = (channelWorkspaceGroups ?? []).filter(
|
|
3528
|
+
(group) => group.workspaceCwd !== runtimeToDrain.workspaceCwd
|
|
3529
|
+
);
|
|
3530
|
+
channelWebhookConfigVersion += 1;
|
|
3531
|
+
refreshChannelWebhookConfigs?.();
|
|
3532
|
+
daemonLog.error(
|
|
3533
|
+
"workspace channel worker topology refresh error",
|
|
3534
|
+
err instanceof Error ? err : null
|
|
3535
|
+
);
|
|
3536
|
+
}
|
|
3537
|
+
writeChannelWorkerPidfile();
|
|
3538
|
+
}
|
|
3539
|
+
if (reason === "workspace_removed") {
|
|
3540
|
+
const app3 = runtimeApp ?? runtimeAppForCleanup;
|
|
3541
|
+
const stopWorkspaceGitStateForWorkspace = app3?.locals?.["stopWorkspaceGitStateForWorkspace"];
|
|
3542
|
+
const stopScheduledTaskKeepaliveForWorkspace = app3?.locals?.["stopScheduledTaskKeepaliveForWorkspace"];
|
|
3543
|
+
stopWorkspaceGitStateForWorkspace?.(runtimeToDrain.workspaceCwd);
|
|
3544
|
+
stopScheduledTaskKeepaliveForWorkspace?.(
|
|
3545
|
+
runtimeToDrain.workspaceCwd
|
|
3546
|
+
);
|
|
3547
|
+
}
|
|
3548
|
+
let bridgeStopped = false;
|
|
3549
|
+
try {
|
|
3550
|
+
if (!shutdownBridges.has(runtimeToDrain.bridge)) {
|
|
3551
|
+
await runtimeToDrain.bridge.shutdown({ reason });
|
|
3552
|
+
}
|
|
3553
|
+
bridgeStopped = true;
|
|
3554
|
+
} finally {
|
|
3555
|
+
if (bridgeStopped || reason === "workspace_removed") {
|
|
3556
|
+
subSessionStoppersByWorkspace.delete(runtimeToDrain.workspaceCwd);
|
|
3557
|
+
if (stopSubSessions) {
|
|
3558
|
+
removeArrayValue(subSessionStoppers, stopSubSessions);
|
|
3559
|
+
}
|
|
3560
|
+
removeArrayValue(runtimeBridges, runtimeToDrain.bridge);
|
|
3561
|
+
removeArrayValue(
|
|
3562
|
+
internalRuntimeBridgesForCleanup,
|
|
3563
|
+
runtimeToDrain.bridge
|
|
3564
|
+
);
|
|
3565
|
+
shutdownBridges.add(runtimeToDrain.bridge);
|
|
3566
|
+
}
|
|
3567
|
+
}
|
|
3568
|
+
})();
|
|
3569
|
+
runtimeCleanupPromises.set(runtimeToDrain, cleanup);
|
|
3570
|
+
void cleanup.catch(() => {
|
|
3571
|
+
if (reason === "daemon_shutdown" && runtimeCleanupPromises.get(runtimeToDrain) === cleanup) {
|
|
3572
|
+
runtimeCleanupPromises.delete(runtimeToDrain);
|
|
3573
|
+
}
|
|
3574
|
+
});
|
|
3575
|
+
return cleanup;
|
|
3576
|
+
}
|
|
3577
|
+
};
|
|
2867
3578
|
const app2 = runtime.createServeApp(opts, () => actualPort, {
|
|
2868
3579
|
workspaceRegistry,
|
|
3580
|
+
createWorkspaceRuntime: createDynamicWorkspaceRuntime,
|
|
3581
|
+
workspaceRegistrationStore,
|
|
3582
|
+
workspaceRuntimeRemoval,
|
|
2869
3583
|
bridge,
|
|
2870
3584
|
webShellDir,
|
|
2871
3585
|
boundWorkspace,
|
|
@@ -2880,6 +3594,27 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2880
3594
|
primaryRuntimeEnv,
|
|
2881
3595
|
daemonLog,
|
|
2882
3596
|
getChannelWorkerSnapshot,
|
|
3597
|
+
getChannelWorkerSnapshots,
|
|
3598
|
+
getChannelWorkerControl,
|
|
3599
|
+
isChannelControlDraining: /* @__PURE__ */ __name(() => channelControlDraining, "isChannelControlDraining"),
|
|
3600
|
+
isChannelControlInitializing: /* @__PURE__ */ __name(() => channelWorkerManagerStarting !== void 0, "isChannelControlInitializing"),
|
|
3601
|
+
setChannelWorkerSelection,
|
|
3602
|
+
stopChannelWorker,
|
|
3603
|
+
getChannelWebhookConfigSources,
|
|
3604
|
+
getChannelWebhookConfigVersion: /* @__PURE__ */ __name(() => channelWebhookConfigVersion, "getChannelWebhookConfigVersion"),
|
|
3605
|
+
registerChannelWebhookConfigRefresh: /* @__PURE__ */ __name((refresh) => {
|
|
3606
|
+
refreshChannelWebhookConfigs = refresh;
|
|
3607
|
+
}, "registerChannelWebhookConfigRefresh"),
|
|
3608
|
+
enqueueChannelWebhookTask: /* @__PURE__ */ __name(async (task) => {
|
|
3609
|
+
if (!channelWorkerManager) {
|
|
3610
|
+
throw new ChannelWebhookEnqueueError(
|
|
3611
|
+
"channel_worker_unavailable",
|
|
3612
|
+
"Channel worker is not running."
|
|
3613
|
+
);
|
|
3614
|
+
}
|
|
3615
|
+
return channelWorkerManager.enqueueWebhookTask(task);
|
|
3616
|
+
}, "enqueueChannelWebhookTask"),
|
|
3617
|
+
reloadChannelWorker,
|
|
2883
3618
|
getPerfSnapshot: /* @__PURE__ */ __name(() => ({
|
|
2884
3619
|
eventLoop: currentDaemonEventLoopMonitor.snapshot(),
|
|
2885
3620
|
promptQueueWait: {
|
|
@@ -2903,6 +3638,9 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2903
3638
|
persistDisabledTools: persistDisabledToolsFn,
|
|
2904
3639
|
persistSetting: persistSettingFn,
|
|
2905
3640
|
persistSettings: persistSettingsFn,
|
|
3641
|
+
sessionArtifactsPersistenceAvailable: sessionArtifactsPersistenceAvailableFromSettings(
|
|
3642
|
+
runtimeBootSettings?.merged
|
|
3643
|
+
),
|
|
2906
3644
|
installAuthProvider: /* @__PURE__ */ __name((req) => withSettingsLock(
|
|
2907
3645
|
boundWorkspace,
|
|
2908
3646
|
async () => {
|
|
@@ -2941,14 +3679,17 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2941
3679
|
}
|
|
2942
3680
|
), "installAuthProvider")
|
|
2943
3681
|
});
|
|
3682
|
+
app2.locals.subSessionStoppers = subSessionStoppers;
|
|
3683
|
+
subSessionStoppers.push(subSessionLauncher.stop);
|
|
3684
|
+
subSessionStoppersByWorkspace.set(boundWorkspace, subSessionLauncher.stop);
|
|
2944
3685
|
return { app: app2, bridge };
|
|
2945
3686
|
}, "buildRuntime");
|
|
2946
3687
|
if (deps.bridge) {
|
|
2947
3688
|
const runtime = await buildRuntime();
|
|
2948
3689
|
runtimeAppForCleanup = runtime.app;
|
|
2949
|
-
runtimeApp = runtime.app;
|
|
2950
3690
|
bridgeRef = runtime.bridge;
|
|
2951
3691
|
if (!opts.channelSelection) {
|
|
3692
|
+
runtimeApp = runtime.app;
|
|
2952
3693
|
runtimeStartupSettled = true;
|
|
2953
3694
|
markRuntimeReady();
|
|
2954
3695
|
}
|
|
@@ -2962,17 +3703,25 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2962
3703
|
daemonLog,
|
|
2963
3704
|
qwenCodeVersion: cliVersion,
|
|
2964
3705
|
sessionShellCommandEnabled,
|
|
3706
|
+
sessionArtifactsPersistenceAvailable,
|
|
2965
3707
|
permissionPolicy,
|
|
2966
3708
|
multiWorkspaceCapabilitiesRequireRuntime: workspaceInputs.length > 1,
|
|
2967
3709
|
getRuntimeError: /* @__PURE__ */ __name(() => runtimeStartupError, "getRuntimeError"),
|
|
2968
3710
|
getChannelWorkerSnapshot,
|
|
3711
|
+
getChannelWorkerSnapshots,
|
|
2969
3712
|
onHealthServed: deferRuntimeUntilFirstHealth ? () => startRuntimeAfterHealth?.() : void 0
|
|
2970
3713
|
});
|
|
3714
|
+
const deferredChannelWebhookAuth = deferRuntimeUntilFirstHealth ? createDeferredChannelWebhookAuth(
|
|
3715
|
+
resolveChannelWebhookConfigSource,
|
|
3716
|
+
await loadChannelWebhookConfigRuntime(),
|
|
3717
|
+
daemonLog
|
|
3718
|
+
) : void 0;
|
|
2971
3719
|
const app = runtimeApp ?? createDelegatingServeApp(bootstrapApp, () => runtimeApp, {
|
|
2972
3720
|
waitForDeferredRuntimeRoutes: deferRuntimeUntilFirstHealth,
|
|
2973
3721
|
startRuntime: /* @__PURE__ */ __name(() => startRuntimeForRequest?.(), "startRuntime"),
|
|
2974
3722
|
runtimeReady,
|
|
2975
|
-
authenticateDeferredRuntimeRequest: bearerAuth(opts.token)
|
|
3723
|
+
authenticateDeferredRuntimeRequest: bearerAuth(opts.token),
|
|
3724
|
+
authenticateDeferredChannelWebhookRequest: deferredChannelWebhookAuth
|
|
2976
3725
|
});
|
|
2977
3726
|
let listenHostname = opts.hostname;
|
|
2978
3727
|
if (opts.hostname.startsWith("[")) {
|
|
@@ -2989,7 +3738,70 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
2989
3738
|
`Invalid maxConnections: ${opts.maxConnections}. Must be >= 0 (0 / Infinity = unlimited).`
|
|
2990
3739
|
);
|
|
2991
3740
|
}
|
|
2992
|
-
|
|
3741
|
+
const channelValidationSettingsRuntime = opts.channelSelection ? await loadSettingsRuntimeModules() : void 0;
|
|
3742
|
+
const resolveChannelWorkspaceGroupsAtListen = /* @__PURE__ */ __name(() => {
|
|
3743
|
+
if (!opts.channelSelection || !channelValidationSettingsRuntime || !channelRuntime) {
|
|
3744
|
+
return void 0;
|
|
3745
|
+
}
|
|
3746
|
+
const settingsByWorkspace = /* @__PURE__ */ new Map();
|
|
3747
|
+
if (workspaceInputs.length === 1) {
|
|
3748
|
+
const workspace = workspaceInputs[0];
|
|
3749
|
+
const settings = channelValidationSettingsRuntime.settings.loadSettings(
|
|
3750
|
+
workspace.cwd
|
|
3751
|
+
);
|
|
3752
|
+
channelWebhookEnvByWorkspace.set(
|
|
3753
|
+
workspace.cwd,
|
|
3754
|
+
channelValidationSettingsRuntime.environment.buildRuntimeEnvironment(
|
|
3755
|
+
settings.merged,
|
|
3756
|
+
workspace.cwd,
|
|
3757
|
+
daemonRuntimeBaseEnv
|
|
3758
|
+
).effectiveEnv
|
|
3759
|
+
);
|
|
3760
|
+
return void 0;
|
|
3761
|
+
}
|
|
3762
|
+
const workspaces = workspaceInputs.map((workspace, index) => {
|
|
3763
|
+
const settings = channelValidationSettingsRuntime.settings.loadSettings(
|
|
3764
|
+
workspace.cwd
|
|
3765
|
+
);
|
|
3766
|
+
settingsByWorkspace.set(workspace.cwd, settings);
|
|
3767
|
+
channelWebhookEnvByWorkspace.set(
|
|
3768
|
+
workspace.cwd,
|
|
3769
|
+
channelValidationSettingsRuntime.environment.buildRuntimeEnvironment(
|
|
3770
|
+
settings.merged,
|
|
3771
|
+
workspace.cwd,
|
|
3772
|
+
daemonRuntimeBaseEnv
|
|
3773
|
+
).effectiveEnv
|
|
3774
|
+
);
|
|
3775
|
+
const trusted = index === 0 && deps.trustedWorkspace !== void 0 ? deps.trustedWorkspace : channelValidationSettingsRuntime.trustedFolders.getWorkspaceTrustStatus(
|
|
3776
|
+
settings.merged,
|
|
3777
|
+
workspace.cwd
|
|
3778
|
+
).effective.state === "trusted";
|
|
3779
|
+
return {
|
|
3780
|
+
workspaceCwd: workspace.cwd,
|
|
3781
|
+
primary: index === 0,
|
|
3782
|
+
trusted
|
|
3783
|
+
};
|
|
3784
|
+
});
|
|
3785
|
+
const grouping = resolveChannelWorkspaceGroups({
|
|
3786
|
+
workspaces,
|
|
3787
|
+
selection: opts.channelSelection,
|
|
3788
|
+
loadChannelsConfig: /* @__PURE__ */ __name((cwd) => {
|
|
3789
|
+
const settings = settingsByWorkspace.get(cwd);
|
|
3790
|
+
if (!settings) return {};
|
|
3791
|
+
return channelRuntime.loadChannelsConfig(cwd, settings);
|
|
3792
|
+
}, "loadChannelsConfig")
|
|
3793
|
+
});
|
|
3794
|
+
if (!grouping.ok) {
|
|
3795
|
+
throw Object.assign(new Error(grouping.error.message), {
|
|
3796
|
+
code: grouping.error.code,
|
|
3797
|
+
...grouping.error.channel ? { channel: grouping.error.channel } : {}
|
|
3798
|
+
});
|
|
3799
|
+
}
|
|
3800
|
+
return grouping.groups;
|
|
3801
|
+
}, "resolveChannelWorkspaceGroupsAtListen");
|
|
3802
|
+
if (opts.channelSelection) {
|
|
3803
|
+
reserveChannelServicePidfile(opts.channelSelection);
|
|
3804
|
+
}
|
|
2993
3805
|
return await new Promise((resolve, reject) => {
|
|
2994
3806
|
const onListening = /* @__PURE__ */ __name(() => {
|
|
2995
3807
|
startup.listenerReadyAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -3008,45 +3820,14 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3008
3820
|
const scheme = tlsOptions ? "https" : "http";
|
|
3009
3821
|
const url = `${scheme}://${formatHostForUrl(opts.hostname)}:${actualPort}`;
|
|
3010
3822
|
try {
|
|
3011
|
-
|
|
3012
|
-
const createSupervisor = deps.channelWorkerSupervisorFactory ?? channelRuntime?.createChannelWorkerSupervisor;
|
|
3013
|
-
if (!createSupervisor) {
|
|
3014
|
-
throw new Error(
|
|
3015
|
-
"Channel worker supervisor runtime is not available."
|
|
3016
|
-
);
|
|
3017
|
-
}
|
|
3018
|
-
channelWorker = createSupervisor({
|
|
3019
|
-
cliEntryPath: findCliEntryPath(),
|
|
3020
|
-
daemonUrl: formatChannelWorkerDaemonUrl(opts.hostname, actualPort),
|
|
3021
|
-
...token ? { daemonToken: token } : {},
|
|
3022
|
-
workspace: boundWorkspace,
|
|
3023
|
-
selection: opts.channelSelection,
|
|
3024
|
-
onReady: /* @__PURE__ */ __name((snapshot) => {
|
|
3025
|
-
writeChannelWorkerPidfile(snapshot);
|
|
3026
|
-
}, "onReady"),
|
|
3027
|
-
onLog: /* @__PURE__ */ __name(({ stream, line }) => {
|
|
3028
|
-
const message = `channel worker ${stream}: ${line}`;
|
|
3029
|
-
if (stream === "stderr") {
|
|
3030
|
-
daemonLog.warn(message);
|
|
3031
|
-
} else {
|
|
3032
|
-
daemonLog.info(message);
|
|
3033
|
-
}
|
|
3034
|
-
}, "onLog"),
|
|
3035
|
-
onExit: /* @__PURE__ */ __name((snapshot) => {
|
|
3036
|
-
daemonLog.warn(
|
|
3037
|
-
`channel worker exited (state=${snapshot.state}, pid=${snapshot.pid ?? "unknown"}, code=${snapshot.exitCode ?? "null"}, signal=${snapshot.signal ?? "null"}, error=${snapshot.error ?? "none"}, restartCount=${snapshot.restartCount ?? 0}, nextRestartAt=${snapshot.nextRestartAt ?? "none"}, staleHeartbeatAt=${snapshot.staleHeartbeatAt ?? "none"})`
|
|
3038
|
-
);
|
|
3039
|
-
writeChannelWorkerPidfile(snapshot, { clearWorkerPid: true });
|
|
3040
|
-
}, "onExit")
|
|
3041
|
-
});
|
|
3042
|
-
}
|
|
3823
|
+
channelWorkspaceGroups = resolveChannelWorkspaceGroupsAtListen();
|
|
3043
3824
|
} catch (err) {
|
|
3044
3825
|
removeCurrentServePidfile();
|
|
3045
3826
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
3046
3827
|
server.close((closeErr) => {
|
|
3047
3828
|
if (closeErr) {
|
|
3048
3829
|
daemonLog.error(
|
|
3049
|
-
"server close after channel worker
|
|
3830
|
+
"server close after channel worker validation error failed",
|
|
3050
3831
|
closeErr
|
|
3051
3832
|
);
|
|
3052
3833
|
}
|
|
@@ -3054,6 +3835,19 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3054
3835
|
});
|
|
3055
3836
|
return;
|
|
3056
3837
|
}
|
|
3838
|
+
if (channelWorkspaceGroups) {
|
|
3839
|
+
for (const group of channelWorkspaceGroups) {
|
|
3840
|
+
daemonLog.info("channel worker group assigned", {
|
|
3841
|
+
workspace: group.workspaceCwd,
|
|
3842
|
+
channels: group.selection.mode === "all" ? ["all"] : group.selection.names
|
|
3843
|
+
});
|
|
3844
|
+
}
|
|
3845
|
+
if (opts.channelSelection?.mode === "all") {
|
|
3846
|
+
writeStderrLine(
|
|
3847
|
+
"qwen serve: --channel all is primary-workspace only; non-primary workspace channels are not hosted."
|
|
3848
|
+
);
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3057
3851
|
writeStdoutLine(
|
|
3058
3852
|
`qwen serve listening on ${url} (mode=${opts.mode}, workspace=${boundWorkspace})`
|
|
3059
3853
|
);
|
|
@@ -3129,12 +3923,17 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3129
3923
|
}
|
|
3130
3924
|
}, "shutdownBridgeAfterFailedStartup");
|
|
3131
3925
|
const stopChannelWorkerAfterFailedStartup = /* @__PURE__ */ __name(async () => {
|
|
3132
|
-
|
|
3926
|
+
if (!channelWorkerManager) return true;
|
|
3927
|
+
try {
|
|
3928
|
+
await channelWorkerManager.shutdown();
|
|
3929
|
+
return true;
|
|
3930
|
+
} catch (stopErr) {
|
|
3133
3931
|
daemonLog.error(
|
|
3134
3932
|
"channel worker stop after runtime startup error failed",
|
|
3135
3933
|
stopErr instanceof Error ? stopErr : null
|
|
3136
3934
|
);
|
|
3137
|
-
|
|
3935
|
+
return false;
|
|
3936
|
+
}
|
|
3138
3937
|
}, "stopChannelWorkerAfterFailedStartup");
|
|
3139
3938
|
const failRuntimeStartup = /* @__PURE__ */ __name(async (err, bridgeForCleanup) => {
|
|
3140
3939
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -3143,6 +3942,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3143
3942
|
return;
|
|
3144
3943
|
}
|
|
3145
3944
|
runtimeStartupSettled = true;
|
|
3945
|
+
runtimeApp = void 0;
|
|
3146
3946
|
clearRuntimeStartupTimer();
|
|
3147
3947
|
const message = error.message;
|
|
3148
3948
|
runtimeStartupError = message;
|
|
@@ -3152,14 +3952,28 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3152
3952
|
}
|
|
3153
3953
|
writeStderrLine(`qwen serve: runtime startup failed: ${message}`);
|
|
3154
3954
|
daemonLog.error("runtime startup failed", error);
|
|
3155
|
-
|
|
3955
|
+
markRuntimeFailed(error);
|
|
3956
|
+
if (closeServerAfterChannelWorkerStartupFailure && server.listening) {
|
|
3957
|
+
runtimeFailureListenerClose = new Promise((resolve2) => {
|
|
3958
|
+
server.close((closeErr) => {
|
|
3959
|
+
if (closeErr) {
|
|
3960
|
+
daemonLog.error(
|
|
3961
|
+
"server close after runtime startup error failed",
|
|
3962
|
+
closeErr
|
|
3963
|
+
);
|
|
3964
|
+
}
|
|
3965
|
+
resolve2();
|
|
3966
|
+
});
|
|
3967
|
+
});
|
|
3968
|
+
server.closeAllConnections();
|
|
3969
|
+
}
|
|
3970
|
+
const channelWorkerStopped = await stopChannelWorkerAfterFailedStartup();
|
|
3156
3971
|
disposeDaemonEventLoopMonitor();
|
|
3157
|
-
removeCurrentServePidfile();
|
|
3972
|
+
if (channelWorkerStopped) removeCurrentServePidfile();
|
|
3158
3973
|
const bridgesForCleanup = bridgeForCleanup ? [bridgeForCleanup, ...getRuntimeBridgesForCleanup()] : getRuntimeBridgesForCleanup();
|
|
3159
3974
|
for (const bridge of [...new Set(bridgesForCleanup)]) {
|
|
3160
3975
|
await shutdownBridgeAfterFailedStartup(bridge);
|
|
3161
3976
|
}
|
|
3162
|
-
markRuntimeFailed(error);
|
|
3163
3977
|
}, "failRuntimeStartup");
|
|
3164
3978
|
const armRuntimeStartupTimer = /* @__PURE__ */ __name(() => {
|
|
3165
3979
|
if (runtimeStartupTimeoutMs <= 0 || runtimeStartupTimer) return;
|
|
@@ -3172,10 +3986,152 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3172
3986
|
}, runtimeStartupTimeoutMs);
|
|
3173
3987
|
runtimeStartupTimer.unref();
|
|
3174
3988
|
}, "armRuntimeStartupTimer");
|
|
3175
|
-
const
|
|
3989
|
+
const resolveRuntimeChannelGroups = /* @__PURE__ */ __name(async (channelSelection, candidateApp, operation) => {
|
|
3990
|
+
const registry = candidateApp.locals?.["workspaceRegistry"];
|
|
3991
|
+
if (!registry) {
|
|
3992
|
+
throw new Error(
|
|
3993
|
+
"Workspace registry is not available for channel workers."
|
|
3994
|
+
);
|
|
3995
|
+
}
|
|
3996
|
+
const runtimes = registry.list();
|
|
3997
|
+
if (runtimes.length <= 1 && operation === "initial") {
|
|
3998
|
+
return [
|
|
3999
|
+
{
|
|
4000
|
+
workspaceCwd: registry.primary.workspaceCwd,
|
|
4001
|
+
selection: channelSelection
|
|
4002
|
+
}
|
|
4003
|
+
];
|
|
4004
|
+
}
|
|
4005
|
+
const workerRuntime = await ensureChannelRuntime();
|
|
4006
|
+
const settingsRuntime = await loadSettingsRuntimeModules();
|
|
4007
|
+
const settingsByWorkspace = /* @__PURE__ */ new Map();
|
|
4008
|
+
const grouping = resolveChannelWorkspaceGroups({
|
|
4009
|
+
workspaces: runtimes.map((runtime) => {
|
|
4010
|
+
const settings = settingsRuntime.settings.loadSettings(
|
|
4011
|
+
runtime.workspaceCwd
|
|
4012
|
+
);
|
|
4013
|
+
settingsByWorkspace.set(runtime.workspaceCwd, settings);
|
|
4014
|
+
return {
|
|
4015
|
+
workspaceCwd: runtime.workspaceCwd,
|
|
4016
|
+
primary: runtime.primary,
|
|
4017
|
+
trusted: runtime.trusted
|
|
4018
|
+
};
|
|
4019
|
+
}),
|
|
4020
|
+
selection: channelSelection,
|
|
4021
|
+
loadChannelsConfig: /* @__PURE__ */ __name((cwd) => {
|
|
4022
|
+
const settings = settingsByWorkspace.get(cwd);
|
|
4023
|
+
return settings ? workerRuntime.loadChannelsConfig(cwd, settings) : {};
|
|
4024
|
+
}, "loadChannelsConfig")
|
|
4025
|
+
});
|
|
4026
|
+
if (!grouping.ok) {
|
|
4027
|
+
throw Object.assign(new Error(grouping.error.message), {
|
|
4028
|
+
code: grouping.error.code,
|
|
4029
|
+
...grouping.error.channel ? { channel: grouping.error.channel } : {}
|
|
4030
|
+
});
|
|
4031
|
+
}
|
|
4032
|
+
return grouping.groups;
|
|
4033
|
+
}, "resolveRuntimeChannelGroups");
|
|
4034
|
+
ensureChannelWorkerManager = /* @__PURE__ */ __name(() => {
|
|
4035
|
+
if (channelWorkerManager) return Promise.resolve(channelWorkerManager);
|
|
4036
|
+
if (channelWorkerManagerStarting) return channelWorkerManagerStarting;
|
|
4037
|
+
const starting = (async () => {
|
|
4038
|
+
const candidateApp = runtimeApp ?? runtimeAppForCleanup;
|
|
4039
|
+
const registry = candidateApp?.locals?.["workspaceRegistry"];
|
|
4040
|
+
if (!candidateApp || !registry) {
|
|
4041
|
+
throw new Error(
|
|
4042
|
+
"Workspace registry is not available for channels."
|
|
4043
|
+
);
|
|
4044
|
+
}
|
|
4045
|
+
const workerRuntime = await ensureChannelRuntime();
|
|
4046
|
+
const createSupervisor = deps.channelWorkerSupervisorFactory ?? workerRuntime.createChannelWorkerSupervisor;
|
|
4047
|
+
const createGroup = /* @__PURE__ */ __name((groups) => workerRuntime.createChannelWorkerGroup({
|
|
4048
|
+
groups,
|
|
4049
|
+
registry,
|
|
4050
|
+
createSupervisor,
|
|
4051
|
+
shared: {
|
|
4052
|
+
cliEntryPath: workerRuntime.findCliEntryPath(),
|
|
4053
|
+
daemonUrl: formatChannelWorkerDaemonUrl(
|
|
4054
|
+
opts.hostname,
|
|
4055
|
+
actualPort
|
|
4056
|
+
),
|
|
4057
|
+
...token ? { daemonToken: token } : {}
|
|
4058
|
+
},
|
|
4059
|
+
onReady: /* @__PURE__ */ __name((snapshot) => {
|
|
4060
|
+
if (runtimeStartupError !== void 0) return;
|
|
4061
|
+
if (workspaceInputs.length > 1) {
|
|
4062
|
+
daemonLog.info("channel worker ready", {
|
|
4063
|
+
workspace: snapshot.workspaceCwd,
|
|
4064
|
+
pid: snapshot.pid,
|
|
4065
|
+
channels: snapshot.channels
|
|
4066
|
+
});
|
|
4067
|
+
}
|
|
4068
|
+
channelWorkerManager?.workerChanged();
|
|
4069
|
+
if (!runtimeStartupSettled) writeChannelWorkerPidfile();
|
|
4070
|
+
}, "onReady"),
|
|
4071
|
+
onExit: /* @__PURE__ */ __name((snapshot) => {
|
|
4072
|
+
const workspacePrefix = workspaceInputs.length > 1 ? `workspace=${snapshot.workspaceCwd}, ` : "";
|
|
4073
|
+
daemonLog.warn(
|
|
4074
|
+
`channel worker exited (${workspacePrefix}state=${snapshot.state}, pid=${snapshot.pid ?? "unknown"}, code=${snapshot.exitCode ?? "null"}, signal=${snapshot.signal ?? "null"}, error=${snapshot.error ?? "none"}, restartCount=${snapshot.restartCount ?? 0}, nextRestartAt=${snapshot.nextRestartAt ?? "none"}, staleHeartbeatAt=${snapshot.staleHeartbeatAt ?? "none"})`
|
|
4075
|
+
);
|
|
4076
|
+
channelWorkerManager?.workerChanged();
|
|
4077
|
+
if (!runtimeStartupSettled) writeChannelWorkerPidfile();
|
|
4078
|
+
}, "onExit"),
|
|
4079
|
+
onStateChange: /* @__PURE__ */ __name(() => {
|
|
4080
|
+
channelWorkerManager?.workerChanged();
|
|
4081
|
+
if (!runtimeStartupSettled) writeChannelWorkerPidfile();
|
|
4082
|
+
}, "onStateChange"),
|
|
4083
|
+
onLog: /* @__PURE__ */ __name(({ stream, line, workspaceCwd }) => {
|
|
4084
|
+
const message = workspaceInputs.length > 1 ? `channel worker [${workspaceCwd}] ${stream}: ${line}` : `channel worker ${stream}: ${line}`;
|
|
4085
|
+
if (stream === "stderr") daemonLog.warn(message);
|
|
4086
|
+
else daemonLog.info(message);
|
|
4087
|
+
}, "onLog")
|
|
4088
|
+
}), "createGroup");
|
|
4089
|
+
channelWorkerManager = workerRuntime.createChannelWorkerManager({
|
|
4090
|
+
resolveGroups: /* @__PURE__ */ __name((selection, operation) => resolveRuntimeChannelGroups(selection, candidateApp, operation), "resolveGroups"),
|
|
4091
|
+
createGroup,
|
|
4092
|
+
reserveLease: reserveChannelServicePidfile,
|
|
4093
|
+
releaseLease: /* @__PURE__ */ __name(() => {
|
|
4094
|
+
removeCurrentServePidfile();
|
|
4095
|
+
if (channelPidfileReserved) {
|
|
4096
|
+
throw new Error("Failed to release the channel service lease.");
|
|
4097
|
+
}
|
|
4098
|
+
}, "releaseLease"),
|
|
4099
|
+
initialLeaseReserved: channelPidfileReserved,
|
|
4100
|
+
onCommittedSelection: /* @__PURE__ */ __name((_selection, groups) => {
|
|
4101
|
+
channelWorkspaceGroups = groups;
|
|
4102
|
+
channelWebhookConfigVersion += 1;
|
|
4103
|
+
refreshChannelWebhookConfigs?.();
|
|
4104
|
+
}, "onCommittedSelection"),
|
|
4105
|
+
onStateChange: /* @__PURE__ */ __name(() => {
|
|
4106
|
+
if (runtimeStartupSettled) writeChannelWorkerPidfile();
|
|
4107
|
+
}, "onStateChange")
|
|
4108
|
+
});
|
|
4109
|
+
return channelWorkerManager;
|
|
4110
|
+
})();
|
|
4111
|
+
channelWorkerManagerStarting = starting;
|
|
4112
|
+
void starting.then(
|
|
4113
|
+
() => {
|
|
4114
|
+
if (channelWorkerManagerStarting === starting) {
|
|
4115
|
+
channelWorkerManagerStarting = void 0;
|
|
4116
|
+
}
|
|
4117
|
+
},
|
|
4118
|
+
() => {
|
|
4119
|
+
if (channelWorkerManagerStarting === starting) {
|
|
4120
|
+
channelWorkerManagerStarting = void 0;
|
|
4121
|
+
}
|
|
4122
|
+
}
|
|
4123
|
+
);
|
|
4124
|
+
return starting;
|
|
4125
|
+
}, "ensureChannelWorkerManager");
|
|
4126
|
+
const completeRuntimeStartup = /* @__PURE__ */ __name(async (candidateApp) => {
|
|
3176
4127
|
if (runtimeStartupSettled) return;
|
|
4128
|
+
runtimeApp = candidateApp;
|
|
4129
|
+
const acpHandle = candidateApp.locals?.["acpHandle"];
|
|
4130
|
+
acpHandle?.attachServer?.(server);
|
|
3177
4131
|
if (opts.channelSelection) {
|
|
3178
|
-
|
|
4132
|
+
closeServerAfterChannelWorkerStartupFailure = true;
|
|
4133
|
+
const manager = await ensureChannelWorkerManager();
|
|
4134
|
+
await manager.startInitial(opts.channelSelection);
|
|
3179
4135
|
if (runtimeStartupSettled) return;
|
|
3180
4136
|
}
|
|
3181
4137
|
if (runtimeStartupSettled) return;
|
|
@@ -3222,13 +4178,10 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3222
4178
|
);
|
|
3223
4179
|
return;
|
|
3224
4180
|
}
|
|
3225
|
-
runtimeApp = runtime.app;
|
|
3226
|
-
const acpHandle = runtime.app.locals?.["acpHandle"];
|
|
3227
|
-
acpHandle?.attachServer?.(server);
|
|
3228
4181
|
if (shouldPreheat) {
|
|
3229
4182
|
startBridgePreheat(runtime.bridge);
|
|
3230
4183
|
}
|
|
3231
|
-
await completeRuntimeStartup();
|
|
4184
|
+
await completeRuntimeStartup(runtime.app);
|
|
3232
4185
|
}).catch((err) => failRuntimeStartup(err));
|
|
3233
4186
|
}, "startRuntime");
|
|
3234
4187
|
startRuntimeForRequest = startRuntime;
|
|
@@ -3266,11 +4219,10 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3266
4219
|
if (shuttingDown) {
|
|
3267
4220
|
daemonLog.warn(`received ${signal} during drain \u2014 forcing exit`);
|
|
3268
4221
|
try {
|
|
3269
|
-
|
|
4222
|
+
channelWorkerManager?.killAllSync();
|
|
3270
4223
|
for (const runtimeBridge of getRuntimeBridgesForCleanup()) {
|
|
3271
4224
|
runtimeBridge.killAllSync();
|
|
3272
4225
|
}
|
|
3273
|
-
removeCurrentServePidfile();
|
|
3274
4226
|
} catch (err) {
|
|
3275
4227
|
daemonLog.error(
|
|
3276
4228
|
"force-kill error",
|
|
@@ -3286,16 +4238,24 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3286
4238
|
try {
|
|
3287
4239
|
await handle.close();
|
|
3288
4240
|
await daemonLog.flush();
|
|
3289
|
-
process.exit(0);
|
|
4241
|
+
process.exit(runtimeStartupError === void 0 ? 0 : 1);
|
|
3290
4242
|
} catch (err) {
|
|
3291
4243
|
daemonLog.error("shutdown error", err instanceof Error ? err : null);
|
|
3292
4244
|
await daemonLog.flush().catch(() => {
|
|
3293
4245
|
});
|
|
4246
|
+
if (channelWorkerManager?.state().enabled) {
|
|
4247
|
+
daemonLog.error(
|
|
4248
|
+
"refusing to exit while a channel worker or service lease remains; signal again to retry after the child exits (another signal during that retry forces exit)"
|
|
4249
|
+
);
|
|
4250
|
+
await daemonLog.flush().catch(() => {
|
|
4251
|
+
});
|
|
4252
|
+
return;
|
|
4253
|
+
}
|
|
3294
4254
|
process.exit(1);
|
|
3295
4255
|
}
|
|
3296
4256
|
}, "onSignal");
|
|
3297
4257
|
const onUncaughtExceptionMonitor = /* @__PURE__ */ __name(() => {
|
|
3298
|
-
if (process.listenerCount("uncaughtException") === 0) {
|
|
4258
|
+
if (process.listenerCount("uncaughtException") === 0 && !channelWorkerManager?.state().enabled) {
|
|
3299
4259
|
removeCurrentServePidfile();
|
|
3300
4260
|
}
|
|
3301
4261
|
}, "onUncaughtExceptionMonitor");
|
|
@@ -3310,17 +4270,24 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3310
4270
|
if (closePromise) return closePromise;
|
|
3311
4271
|
closePromise = new Promise((res, rej) => {
|
|
3312
4272
|
shuttingDown = true;
|
|
3313
|
-
|
|
4273
|
+
channelControlDraining = true;
|
|
4274
|
+
const initiallyMountedApp = runtimeApp ?? runtimeAppForCleanup;
|
|
4275
|
+
const initiallyMountedManagement = initiallyMountedApp?.locals?.["workspaceManagementHandle"];
|
|
4276
|
+
const initialManagementWait = initiallyMountedManagement?.sealAndWait?.();
|
|
3314
4277
|
clearRuntimeStartAfterHealthTimer();
|
|
3315
4278
|
clearRuntimeStartFallbackTimer();
|
|
3316
4279
|
cancelDeferredRuntimeStartup();
|
|
3317
4280
|
let settled = false;
|
|
3318
4281
|
let bridgeShutdownError;
|
|
4282
|
+
let channelWorkerShutdownError;
|
|
3319
4283
|
const finish = /* @__PURE__ */ __name((err) => {
|
|
3320
4284
|
if (settled) return;
|
|
3321
4285
|
settled = true;
|
|
3322
|
-
|
|
3323
|
-
|
|
4286
|
+
const preserveSignalHandlers = channelWorkerShutdownError !== void 0 && channelWorkerManager?.state().enabled === true;
|
|
4287
|
+
if (!preserveSignalHandlers) {
|
|
4288
|
+
process.removeListener("SIGINT", onSignal);
|
|
4289
|
+
process.removeListener("SIGTERM", onSignal);
|
|
4290
|
+
}
|
|
3324
4291
|
process.removeListener(
|
|
3325
4292
|
"uncaughtExceptionMonitor",
|
|
3326
4293
|
onUncaughtExceptionMonitor
|
|
@@ -3331,9 +4298,17 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3331
4298
|
);
|
|
3332
4299
|
}).finally(() => daemonLog.flush().catch(() => {
|
|
3333
4300
|
})).finally(() => {
|
|
3334
|
-
const finalErr = err ?? bridgeShutdownError;
|
|
3335
|
-
if (finalErr)
|
|
3336
|
-
|
|
4301
|
+
const finalErr = err ?? bridgeShutdownError ?? channelWorkerShutdownError;
|
|
4302
|
+
if (finalErr) {
|
|
4303
|
+
if (channelWorkerShutdownError && channelWorkerManager?.state().enabled) {
|
|
4304
|
+
closePromise = void 0;
|
|
4305
|
+
shuttingDown = false;
|
|
4306
|
+
channelControlDraining = false;
|
|
4307
|
+
}
|
|
4308
|
+
rej(finalErr);
|
|
4309
|
+
} else {
|
|
4310
|
+
res();
|
|
4311
|
+
}
|
|
3337
4312
|
});
|
|
3338
4313
|
}, "finish");
|
|
3339
4314
|
void (coreRuntimePromise ? coreRuntimePromise.then((core) => core.forceFlushMetrics()) : Promise.resolve()).catch((flushErr) => {
|
|
@@ -3347,6 +4322,19 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3347
4322
|
daemonLog
|
|
3348
4323
|
);
|
|
3349
4324
|
const appForCleanup = runtimeApp ?? runtimeAppForCleanup;
|
|
4325
|
+
const workspaceManagementHandle = appForCleanup?.locals?.["workspaceManagementHandle"];
|
|
4326
|
+
await initialManagementWait;
|
|
4327
|
+
if (workspaceManagementHandle !== initiallyMountedManagement) {
|
|
4328
|
+
await workspaceManagementHandle?.sealAndWait?.();
|
|
4329
|
+
}
|
|
4330
|
+
const stopScheduledTaskKeepalive = appForCleanup?.locals?.["stopScheduledTaskKeepalive"];
|
|
4331
|
+
stopScheduledTaskKeepalive?.();
|
|
4332
|
+
const stopWorkspaceGitState = appForCleanup?.locals?.["stopWorkspaceGitState"];
|
|
4333
|
+
stopWorkspaceGitState?.();
|
|
4334
|
+
const stoppers = appForCleanup?.locals?.["subSessionStoppers"];
|
|
4335
|
+
if (stoppers) {
|
|
4336
|
+
for (const stop of stoppers) stop();
|
|
4337
|
+
}
|
|
3350
4338
|
const deviceFlowRegistry = appForCleanup ? getDeviceFlowRegistry(appForCleanup) : void 0;
|
|
3351
4339
|
if (deviceFlowRegistry) {
|
|
3352
4340
|
try {
|
|
@@ -3373,17 +4361,43 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3373
4361
|
rl.dispose();
|
|
3374
4362
|
}
|
|
3375
4363
|
disposeDaemonEventLoopMonitor();
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
4364
|
+
if (channelWorkerManager) {
|
|
4365
|
+
await channelWorkerManager.shutdown().catch((err) => {
|
|
4366
|
+
daemonLog.error(
|
|
4367
|
+
"channel worker stop error",
|
|
4368
|
+
err instanceof Error ? err : null
|
|
4369
|
+
);
|
|
4370
|
+
channelWorkerShutdownError = err instanceof Error ? err : new Error(String(err));
|
|
4371
|
+
});
|
|
4372
|
+
} else {
|
|
4373
|
+
removeCurrentServePidfile();
|
|
4374
|
+
}
|
|
4375
|
+
const runtimeRemoval = appForCleanup?.locals?.["workspaceRuntimeRemoval"];
|
|
4376
|
+
const workspaceRegistry = appForCleanup?.locals?.["workspaceRegistry"];
|
|
4377
|
+
const managedRuntimeBridges = /* @__PURE__ */ new Set();
|
|
4378
|
+
if (runtimeRemoval && workspaceRegistry) {
|
|
4379
|
+
const managedRuntimes = workspaceRegistry.listManaged();
|
|
4380
|
+
for (const workspaceRuntime of managedRuntimes) {
|
|
4381
|
+
managedRuntimeBridges.add(workspaceRuntime.bridge);
|
|
4382
|
+
await runtimeRemoval.disposeRuntime(workspaceRuntime, "daemon_shutdown").catch((err) => {
|
|
4383
|
+
daemonLog.error(
|
|
4384
|
+
"workspace runtime shutdown error",
|
|
4385
|
+
err instanceof Error ? err : null
|
|
4386
|
+
);
|
|
4387
|
+
bridgeShutdownError = err instanceof Error ? err : new Error(String(err));
|
|
4388
|
+
try {
|
|
4389
|
+
workspaceRuntime.bridge.killAllSync();
|
|
4390
|
+
} catch {
|
|
4391
|
+
}
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4394
|
+
}
|
|
3383
4395
|
for (const bridgeForShutdown of getRuntimeBridgesForCleanup()) {
|
|
4396
|
+
if (managedRuntimeBridges.has(bridgeForShutdown)) continue;
|
|
3384
4397
|
if (shutdownBridges.has(bridgeForShutdown)) continue;
|
|
3385
4398
|
shutdownBridges.add(bridgeForShutdown);
|
|
3386
4399
|
await bridgeForShutdown.shutdown().catch((err) => {
|
|
4400
|
+
shutdownBridges.delete(bridgeForShutdown);
|
|
3387
4401
|
daemonLog.error(
|
|
3388
4402
|
"bridge shutdown error",
|
|
3389
4403
|
err instanceof Error ? err : null
|
|
@@ -3392,6 +4406,12 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3392
4406
|
});
|
|
3393
4407
|
}
|
|
3394
4408
|
}).finally(() => {
|
|
4409
|
+
if (!server.listening) {
|
|
4410
|
+
void (runtimeFailureListenerClose ?? Promise.resolve()).then(
|
|
4411
|
+
() => finish()
|
|
4412
|
+
);
|
|
4413
|
+
return;
|
|
4414
|
+
}
|
|
3395
4415
|
const SECONDARY_DEADLINE_MS = 2e3;
|
|
3396
4416
|
let secondaryTimer;
|
|
3397
4417
|
const forceTimer = setTimeout(() => {
|
|
@@ -3425,17 +4445,19 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3425
4445
|
server.on("error", (err) => {
|
|
3426
4446
|
daemonLog.error("server error", err instanceof Error ? err : null);
|
|
3427
4447
|
});
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
acpHandle?.attachServer?.(server);
|
|
4448
|
+
const preparedRuntimeApp = runtimeApp ?? runtimeAppForCleanup;
|
|
4449
|
+
if (preparedRuntimeApp && bridgeRef && deps.bridge) {
|
|
3431
4450
|
if (shouldPreheat) {
|
|
3432
4451
|
startBridgePreheat(bridgeRef);
|
|
3433
4452
|
}
|
|
3434
4453
|
if (opts.channelSelection && !runtimeStartupSettled) {
|
|
3435
4454
|
armRuntimeStartupTimer();
|
|
3436
|
-
runtimeStarting = completeRuntimeStartup().catch(
|
|
4455
|
+
runtimeStarting = completeRuntimeStartup(preparedRuntimeApp).catch(
|
|
3437
4456
|
(err) => failRuntimeStartup(err, bridgeRef)
|
|
3438
4457
|
);
|
|
4458
|
+
} else {
|
|
4459
|
+
const acpHandle = preparedRuntimeApp.locals?.["acpHandle"];
|
|
4460
|
+
acpHandle?.attachServer?.(server);
|
|
3439
4461
|
}
|
|
3440
4462
|
} else if (deferRuntimeUntilFirstHealth) {
|
|
3441
4463
|
scheduleRuntimeStartFallback();
|
|
@@ -3448,14 +4470,24 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3448
4470
|
void runtimeReady.then(
|
|
3449
4471
|
() => resolve(handle),
|
|
3450
4472
|
(err) => {
|
|
3451
|
-
void handle.close().
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
)
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
4473
|
+
void handle.close().then(
|
|
4474
|
+
() => {
|
|
4475
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
4476
|
+
},
|
|
4477
|
+
(closeErr) => {
|
|
4478
|
+
daemonLog.error(
|
|
4479
|
+
"shutdown after runtime startup error failed",
|
|
4480
|
+
closeErr instanceof Error ? closeErr : null
|
|
4481
|
+
);
|
|
4482
|
+
if (channelWorkerManager?.state().enabled) {
|
|
4483
|
+
daemonLog.error(
|
|
4484
|
+
"runtime startup failed, but qwen serve remains alive to retain the channel service lease until worker exit is confirmed"
|
|
4485
|
+
);
|
|
4486
|
+
return;
|
|
4487
|
+
}
|
|
4488
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
4489
|
+
}
|
|
4490
|
+
);
|
|
3459
4491
|
}
|
|
3460
4492
|
);
|
|
3461
4493
|
}
|
|
@@ -3512,6 +4544,7 @@ async function runQwenServe(optsIn, deps = {}) {
|
|
|
3512
4544
|
__name(runQwenServe, "runQwenServe");
|
|
3513
4545
|
export {
|
|
3514
4546
|
InvalidPolicyConfigError,
|
|
4547
|
+
createDisabledChannelWorkerSupervisor,
|
|
3515
4548
|
createLazyBridgeProxy,
|
|
3516
4549
|
extractContextFilename,
|
|
3517
4550
|
formatChannelWorkerDaemonUrl,
|
|
@@ -3522,11 +4555,11 @@ export {
|
|
|
3522
4555
|
};
|
|
3523
4556
|
/**
|
|
3524
4557
|
* @license
|
|
3525
|
-
* Copyright
|
|
4558
|
+
* Copyright 2025 Qwen Team
|
|
3526
4559
|
* SPDX-License-Identifier: Apache-2.0
|
|
3527
4560
|
*/
|
|
3528
4561
|
/**
|
|
3529
4562
|
* @license
|
|
3530
|
-
* Copyright
|
|
4563
|
+
* Copyright 2026 Qwen Team
|
|
3531
4564
|
* SPDX-License-Identifier: Apache-2.0
|
|
3532
4565
|
*/
|