@qwen-code/qwen-code 0.21.8-nightly.20260810.55e20db328 → 0.21.9
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/README.md +2 -1
- package/bundled/qc-helper/docs/configuration/settings.md +2 -1
- package/bundled/qc-helper/docs/features/code-review.md +2 -0
- package/bundled/qc-helper/docs/qwen-serve.md +38 -37
- package/bundled/review/SKILL.md +7 -7
- package/chunks/{MaxSizedBox-A52T4GEU.js → MaxSizedBox-6BZANW7X.js} +3 -3
- package/chunks/{StandaloneSessionPicker-4J654SOB.js → StandaloneSessionPicker-VDC5KE7T.js} +19 -16
- package/chunks/{acpAgent-65AM4AOR.js → acpAgent-F2NSBCUF.js} +49 -40
- package/chunks/{agent-SVQ7U7NJ.js → agent-VOHJOEBB.js} +3 -3
- package/chunks/{agent-headless-XXGY2SQO.js → agent-headless-J5NFOPHP.js} +3 -3
- package/chunks/{bridge-Y32B5S3G.js → bridge-NQIZZLAS.js} +4 -4
- package/chunks/{channel-settings-store-OW43U6VB.js → channel-settings-store-VIY2OENO.js} +11 -9
- package/chunks/{chunk-OR6R3IUW.js → chunk-23VQTELM.js} +1 -1
- package/chunks/{chunk-VHXPSL57.js → chunk-3WDYBTTI.js} +4 -4
- package/chunks/{chunk-FAD7OC7V.js → chunk-3XVDTHBJ.js} +2 -2
- package/chunks/{chunk-7XX5IBXL.js → chunk-46YJDYCU.js} +6 -6
- package/chunks/{chunk-FYB4GIDW.js → chunk-4XQNB3KN.js} +2 -2
- package/chunks/chunk-5EJZE3FP.js +140 -0
- package/chunks/{chunk-DPMJLKUP.js → chunk-5RBDAGC6.js} +2 -2
- package/chunks/{chunk-D2D7J3EW.js → chunk-7AEPJGL4.js} +1 -1
- package/chunks/{chunk-HKI3KHAO.js → chunk-7GOYZQPR.js} +19 -1976
- package/chunks/{chunk-2ASQDZSJ.js → chunk-7S4JBJLU.js} +3 -3
- package/chunks/{chunk-EISUQQPS.js → chunk-ATMO54WE.js} +2 -2
- package/chunks/{chunk-NZMXUSKS.js → chunk-BAMN6XSD.js} +1 -1
- package/chunks/{chunk-2545EHZR.js → chunk-BIRWP6LU.js} +1 -1
- package/chunks/{chunk-UGUKH3SU.js → chunk-BZP4QPNK.js} +9 -9
- package/chunks/{chunk-AUWN7BAG.js → chunk-D7BXVKSF.js} +1 -1
- package/chunks/{chunk-TXO5BMR2.js → chunk-DH5YXSIF.js} +2 -2
- package/chunks/{chunk-OSVH4SMN.js → chunk-FBMCDU63.js} +3 -3
- package/chunks/{chunk-GY24H6IA.js → chunk-FCLHHEUK.js} +10 -10
- package/chunks/{chunk-FWWQIFDT.js → chunk-G2TX5ZXC.js} +3 -3
- package/chunks/{chunk-HDYQYYWB.js → chunk-GAKGOXTC.js} +1 -1
- package/chunks/{chunk-TWFFY5BP.js → chunk-HADWBW5R.js} +4 -4
- package/chunks/{chunk-E2N554HK.js → chunk-HZGBKOX3.js} +2 -2
- package/chunks/{chunk-V47QNK5W.js → chunk-II6G3EY6.js} +288 -72
- package/chunks/{chunk-ZV7LTLFE.js → chunk-IOEZE2YT.js} +1 -1
- package/chunks/chunk-JUWS2Z5K.js +1995 -0
- package/chunks/{chunk-F3II4BTZ.js → chunk-K4ADGWHU.js} +1 -1
- package/chunks/{chunk-5ZTS3OQ3.js → chunk-KSAFZ5TA.js} +1 -1
- package/chunks/{chunk-KMS57JDD.js → chunk-KTKYGS2P.js} +29 -6
- package/chunks/{chunk-HWXGX534.js → chunk-KTQGGPGV.js} +3 -3
- package/chunks/{chunk-ZIKTCMQF.js → chunk-LZZLUCRS.js} +5 -5
- package/chunks/{chunk-S5CULOHB.js → chunk-MHP476D3.js} +64 -21
- package/chunks/{chunk-PNVPFARW.js → chunk-MTCYGTWH.js} +4 -4
- package/chunks/{chunk-WQYWK4DG.js → chunk-OGDIJKHK.js} +1 -1
- package/chunks/{chunk-WH6QMLUW.js → chunk-OGNFHGIG.js} +3 -3
- package/chunks/{chunk-P5ULXPK5.js → chunk-P2FK2HBV.js} +2 -2
- package/chunks/{chunk-5WZL724W.js → chunk-P3RBMQ4P.js} +3 -3
- package/chunks/{chunk-4EOURKA4.js → chunk-P4ZEZSJZ.js} +177 -17
- package/chunks/{chunk-RQ6U2JJQ.js → chunk-PNBBJOCP.js} +1 -1
- package/chunks/{chunk-E2T7FLDU.js → chunk-PVOGHGSF.js} +5 -5
- package/chunks/{chunk-EUVOKP6Y.js → chunk-QSNSL4R4.js} +1 -1
- package/chunks/{chunk-RYQMJCUO.js → chunk-RBHQXGDK.js} +1 -1
- package/chunks/{chunk-ZI5IH2HP.js → chunk-RVSTTOJ4.js} +2 -2
- package/chunks/{chunk-OW2BWT2P.js → chunk-SCAZZ3Q4.js} +4 -4
- package/chunks/{chunk-OBP6QWD5.js → chunk-T5RLUXWJ.js} +2 -2
- package/chunks/{chunk-KP25NJNM.js → chunk-T6HEQR2Q.js} +16 -5
- package/chunks/{chunk-RMPLEWF3.js → chunk-THIKWITR.js} +2 -2
- package/chunks/{chunk-V2226RFW.js → chunk-TQCYNLNJ.js} +1 -1
- package/chunks/{chunk-O277O7U6.js → chunk-TZ6KJ44L.js} +1 -1
- package/chunks/{chunk-ZCJBCKL5.js → chunk-UJUM2SRN.js} +115 -29
- package/chunks/{chunk-3KJQZEN3.js → chunk-UYAUA63Q.js} +1 -1
- package/chunks/chunk-VFMASYQA.js +389 -0
- package/chunks/chunk-VGHZT6JR.js +51 -0
- package/chunks/{chunk-H4JC7LZX.js → chunk-W3FSZSF2.js} +1 -1
- package/chunks/{chunk-YFRFZCIP.js → chunk-WGK4TSB7.js} +3 -3
- package/chunks/{chunk-BL65MO72.js → chunk-WP5VOXF7.js} +6 -127
- package/chunks/{chunk-T2O6NIOY.js → chunk-XTY5DN4Y.js} +1 -1
- package/chunks/{chunk-47ZUMGGY.js → chunk-XX7QFP34.js} +56 -55
- package/chunks/{chunk-ZSNBQXMZ.js → chunk-YTFDX4PR.js} +8 -3
- package/chunks/{chunk-F6TUUA2U.js → chunk-ZBXGWQ4S.js} +2 -2
- package/chunks/{chunk-YR7ZQ4RD.js → chunk-ZOSTTOUJ.js} +1 -1
- package/chunks/{chunk-UAB6J2IE.js → chunk-ZTQSOV56.js} +3 -3
- package/chunks/{computer-use-SLN7DV2E.js → computer-use-PMZ7ICGY.js} +3 -3
- package/chunks/{contextCommand-EHFYX6FW.js → contextCommand-GEZU7YHE.js} +6 -5
- package/chunks/{core-runtime-FBSP5IIG.js → core-runtime-HRJI2MN6.js} +3 -3
- package/chunks/{create-sub-session-WC7YGVSL.js → create-sub-session-VBNVI4YU.js} +3 -3
- package/chunks/{daemon-VSX3FHTY.js → daemon-POSQPD3G.js} +26 -3
- package/chunks/{daemon-status-provider-WW2AD2T7.js → daemon-status-provider-N4CRQKFI.js} +8 -8
- package/chunks/{daemon-trust-policy-E4MAYWPI.js → daemon-trust-policy-BHO3JUHM.js} +11 -9
- package/chunks/{daemon-trust-policy-monitor-XVIDV6T4.js → daemon-trust-policy-monitor-YEKJ2726.js} +11 -9
- package/chunks/{deferred-core-runtime-5SVUC6UC.js → deferred-core-runtime-SH57E3J3.js} +3 -3
- package/chunks/{earlyInputCapture-72FYHYRD.js → earlyInputCapture-B2JJ2HME.js} +3 -3
- package/chunks/{edit-SWVVWHXW.js → edit-7FTXENAN.js} +5 -3
- package/chunks/{enter-worktree-2HF6WQEO.js → enter-worktree-JPHV2PBG.js} +3 -3
- package/chunks/{enterPlanMode-OW6S7L4P.js → enterPlanMode-CGBJ3AHJ.js} +3 -3
- package/chunks/{environment-LRTBTDXH.js → environment-LXASZAHD.js} +6 -6
- package/chunks/{errors-4CO2DME6.js → errors-XIGVT2AD.js} +5 -5
- package/chunks/{exit-worktree-GHJEIRGL.js → exit-worktree-DKSGXW65.js} +3 -3
- package/chunks/{exitPlanMode-JVP4FNNK.js → exitPlanMode-THFL2HYN.js} +3 -3
- package/chunks/{fast-path-HCCY7GR2.js → fast-path-4NXAT5UL.js} +3 -3
- package/chunks/{fast-path-settings-MN5QQQET.js → fast-path-settings-RPAVBD7P.js} +2 -2
- package/chunks/{gemini-V3YVRKXU.js → gemini-B3N6FACU.js} +39 -44
- package/chunks/{geminiContentGenerator-LVPMQUWX.js → geminiContentGenerator-YYFE2HIE.js} +1 -1
- package/chunks/{glob-7HRXHYDR.js → glob-BPHSCFJP.js} +3 -3
- package/chunks/{grep-BITQUON5.js → grep-ROZIRFLU.js} +3 -3
- package/chunks/{handleAutoUpdate-DKFY454S.js → handleAutoUpdate-WV6SPZQB.js} +8 -7
- package/chunks/{i18n-53BQIQSH.js → i18n-YWJWPQKD.js} +8 -6
- package/chunks/{image-gen-H62FLDFB.js → image-gen-SISRZ6FS.js} +1 -1
- package/chunks/{initializer-Q7NUQRSU.js → initializer-66OAD6GO.js} +11 -9
- package/chunks/{installationInfo-BWFHT7WU.js → installationInfo-3YUGIP36.js} +4 -4
- package/chunks/{list-OWQKR6JK.js → list-VEYR66XB.js} +14 -12
- package/chunks/{loadedSettingsAdapter-HNPKQMFA.js → loadedSettingsAdapter-V2JCPCYD.js} +11 -9
- package/chunks/{loggingContentGenerator-A5I3VQUC.js → loggingContentGenerator-RBLNDREC.js} +1 -1
- package/chunks/{managed-npm-update-CUUJGUTV.js → managed-npm-update-C5ID5R4R.js} +4 -4
- package/chunks/{mcp-GJSC7ZPO.js → mcp-OZ54NZJQ.js} +11 -9
- package/chunks/{monitor-TZ2II7JM.js → monitor-7Y4TVFTK.js} +3 -3
- package/chunks/{nonInteractiveCli-22RS4EVH.js → nonInteractiveCli-QEK4LHAC.js} +35 -33
- package/chunks/{notebook-edit-YZC3YPY2.js → notebook-edit-OG35EBGY.js} +4 -3
- package/chunks/{openaiContentGenerator-OIGO5XNF.js → openaiContentGenerator-443BNRPJ.js} +1 -1
- package/chunks/{pidfile-QJQ65RJ2.js → pidfile-ZK4OLRZA.js} +3 -3
- package/chunks/{processUtils-V5VSDIKS.js → processUtils-4YGB4RUZ.js} +2 -2
- package/chunks/{qwenContentGenerator-HXM25BGB.js → qwenContentGenerator-D5C2LCSZ.js} +3 -3
- package/chunks/{qwenOAuth2-7MTMS2Z5.js → qwenOAuth2-Z4YQBMYN.js} +1 -1
- package/chunks/{read-file-PMGXB3ZB.js → read-file-EXTJLWMU.js} +1 -1
- package/chunks/{resumeHistoryUtils-YUTPLHUH.js → resumeHistoryUtils-UPCGRJUL.js} +7 -6
- package/chunks/{ripGrep-XUS66YIV.js → ripGrep-QBVIRCU4.js} +3 -3
- package/chunks/{run-qwen-serve-4NVSU75L.js → run-qwen-serve-ZYGJNE3E.js} +67 -51
- package/chunks/{runtime-QLRVP6HM.js → runtime-BZZ4LWCP.js} +12 -10
- package/chunks/{scheduler-PBB2NSOP.js → scheduler-YNQNOU2E.js} +131 -11
- package/chunks/{serve-BWKTRX72.js → serve-LJHAXDCH.js} +11 -9
- package/chunks/{server-E7CH7WPK.js → server-ADMLELR6.js} +256 -750
- package/chunks/{session-QEKSJ6YU.js → session-YKZXFFTM.js} +36 -34
- package/chunks/{settings-BRAOSJIM.js → settings-EQBUAQ7Y.js} +10 -8
- package/chunks/{shell-OF3CK4AT.js → shell-3QZOJGTT.js} +3 -3
- package/chunks/{skill-HLH2NO2H.js → skill-UWSSMXE7.js} +1 -1
- package/chunks/{skill-settings-DRPU7YI5.js → skill-settings-T6MLB7NU.js} +10 -8
- package/chunks/{spawnChannel-4KO7YTFM.js → spawnChannel-VS7ZFUFP.js} +3 -3
- package/chunks/{standalone-update-DJN2R3YW.js → standalone-update-2W26SRRO.js} +6 -5
- package/chunks/{startInteractiveUI-O3WQQ2WC.js → startInteractiveUI-CVS7K3D6.js} +55 -45
- package/chunks/{team-create-2E4ACBJD.js → team-create-4WFTNNUL.js} +3 -3
- package/chunks/{team-plan-approval-LWIDXYOA.js → team-plan-approval-DBYI33S3.js} +3 -3
- package/chunks/{terminal-image-renderer-PJM7663W.js → terminal-image-renderer-S5WPPQKH.js} +3 -3
- package/chunks/{theme-manager-FDQTM3RP.js → theme-manager-LI2RIOVR.js} +3 -3
- package/chunks/{tool-search-TL5ZXBF4.js → tool-search-4773EUQ4.js} +1 -1
- package/chunks/{total-session-admission-LS6EY5KT.js → total-session-admission-PAY5CH2Z.js} +4 -4
- package/chunks/{trustedFolders-5RWP5OB7.js → trustedFolders-FRSLE674.js} +4 -4
- package/chunks/{update-relaunch-HWQ4USKY.js → update-relaunch-ZSFQTU6M.js} +5 -5
- package/chunks/{updateCheck-EZMBTEIR.js → updateCheck-AXWSO7KA.js} +7 -6
- package/chunks/{useAutoAcceptIndicator-JDMI627A.js → useAutoAcceptIndicator-VHLXIA7U.js} +11 -9
- package/chunks/{validateNonInterActiveAuth-RRUHC5RO.js → validateNonInterActiveAuth-PDJECMFU.js} +32 -30
- package/chunks/{version-XS4UTKUX.js → version-RBN764QS.js} +1 -1
- package/chunks/{web-fetch-2JV7H6OM.js → web-fetch-7BJK42AF.js} +1 -1
- package/chunks/{web-search-RCTN2GAM.js → web-search-L2CILQXV.js} +2 -2
- package/chunks/{workflow-6MKLKQ6R.js → workflow-5VH2R74I.js} +4 -4
- package/chunks/{workspace-providers-status-YZ2IJ4DK.js → workspace-providers-status-OZTQ6JFH.js} +13 -11
- package/chunks/{workspace-registration-store-IYN72LBS.js → workspace-registration-store-IX5RJQS5.js} +1 -1
- package/chunks/{workspace-registry-7LFBZQLT.js → workspace-registry-73N4BGG4.js} +4 -4
- package/chunks/{workspace-service-2EHSPRJB.js → workspace-service-I5RUPSNV.js} +14 -12
- package/chunks/{workspace-skills-status-5VJ2D5HN.js → workspace-skills-status-DMK6VYDO.js} +11 -9
- package/chunks/{workspace-trust-reconciler-X2LZ6XCI.js → workspace-trust-reconciler-QX4RL3TC.js} +12 -10
- package/chunks/{write-file-CJK6SCCF.js → write-file-UGDD5UTS.js} +3 -3
- package/chunks/{zoom-image-BVW4RFYW.js → zoom-image-ZAHEO3YP.js} +1 -1
- package/cli.js +12 -12
- package/package.json +3 -3
- package/web-shell/assets/{arc-DDtoJrAW.js → arc-CHY4saMJ.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-BAInIW4O.js → architectureDiagram-3BPJPVTR-Bu6CwvHj.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-ChPDk7fP.js → blockDiagram-GPEHLZMM-XGt6iGf_.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-Cd9BJuUy.js → c4Diagram-AAUBKEIU-CBbYl19W.js} +1 -1
- package/web-shell/assets/channel-B40srHOa.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-COQkLp56.js → chunk-2J33WTMH-BEhmVrdx.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-GUJshQ_l.js → chunk-4BX2VUAB-fQLyE0Bg.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-Boaa7c10.js → chunk-55IACEB6-yGdtyx4a.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-CcRXaly2.js → chunk-727SXJPM-DYbX2GLo.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-BY0OARHh.js → chunk-AQP2D5EJ-DyKTEsYn.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-DLFQfv0S.js → chunk-FMBD7UC4-D8Uy_GzX.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-C_S0u-D2.js → chunk-ND2GUHAM-C8wNR2K7.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-DP9m64hw.js → chunk-QZHKN3VN-BnybNxnt.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-qumcXQW_.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-qumcXQW_.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-CGY6zGE1.js → cose-bilkent-S5V4N54A-jq4uiFRp.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-yB7whKNn.js → dagre-BM42HDAG-Bs7oye1U.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-Bdlc59La.js → diagram-2AECGRRQ-BHGGJNyM.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-BUClP18L.js → diagram-5GNKFQAL-BJezVLGT.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-aZm08kjn.js → diagram-KO2AKTUF-5JzQN_rL.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-7DGwEkxC.js → diagram-LMA3HP47-BlPYOgY9.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-CAGKayxx.js → diagram-OG6HWLK6-CtMHEaFK.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-CptoHHQi.js → erDiagram-TEJ5UH35-CRNdq2AB.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-CNOH0s7Q.js → flowDiagram-I6XJVG4X-De1WwLzu.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-CCQuCU3y.js → ganttDiagram-6RSMTGT7-YbWfL5Zn.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-B7gv9f4E.js → gitGraphDiagram-PVQCEYII-DzCN8bmd.js} +1 -1
- package/web-shell/assets/index-BDOGGGaN.css +5 -0
- package/web-shell/assets/{index-BoUPVvpf.js → index-CocPvF9Q.js} +1 -1
- package/web-shell/assets/index-DSH2KrMc.js +1771 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-Bb3KYEbR.js → infoDiagram-5YYISTIA-DLHoopnE.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-DWEzbAGi.js → ishikawaDiagram-YF4QCWOH-XnbU04SS.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-CmxwEqeb.js → journeyDiagram-JHISSGLW-CipPyEeJ.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-Ci0gDD8O.js → kanban-definition-UN3LZRKU-DrSeyE5d.js} +1 -1
- package/web-shell/assets/{linear-BqxZqGhS.js → linear-LrBKnAo_.js} +1 -1
- package/web-shell/assets/{mermaid.core-BDAFffHv.js → mermaid.core-C3U9UVmf.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-Btvx-xvS.js → mindmap-definition-RKZ34NQL-DqRWgC9H.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-CKAg7yG7.js → pieDiagram-4H26LBE5-BNXY5p6H.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-DIt8E1mC.js → quadrantDiagram-W4KKPZXB-Ccj9QzE4.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-BA7mQWQJ.js → requirementDiagram-4Y6WPE33-CjPM2_gx.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-D0JppnVU.js → sankeyDiagram-5OEKKPKP-C0RsvKbj.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-29DIQFjB.js → sequenceDiagram-3UESZ5HK-ClN1P5z7.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-iiXMdK--.js → stateDiagram-AJRCARHV-By0eiB2Y.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-Ds0WlK3F.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-CeF7ngSW.js → timeline-definition-PNZ67QCA-g_iaSQgv.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-Beilq8D6.js → vennDiagram-CIIHVFJN-y9ZqJ-TD.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-DOYjY4zO.js → wardley-L42UT6IY-BVVfaxpF.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Dtqp8o18.js → wardleyDiagram-YWT4CUSO-D3ooZKZT.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-cdAc0Dfv.js → xychartDiagram-2RQKCTM6-6GXrY6M1.js} +1 -1
- package/web-shell/index.html +2 -2
- package/chunks/chunk-R4ZA6GBK.js +0 -208
- package/web-shell/assets/channel-0OQklTfP.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CZ4-apsu.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CZ4-apsu.js +0 -1
- package/web-shell/assets/index-D1YQXYsB.css +0 -5
- package/web-shell/assets/index-J4N7zCmU.js +0 -1768
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-CEGK3l80.js +0 -1
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
shouldSuppressRememberErrorDetails,
|
|
27
27
|
workspaceMemoryFailureCode,
|
|
28
28
|
workspaceMemoryFailureDiagnostics
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-FBMCDU63.js";
|
|
30
30
|
import {
|
|
31
31
|
SetupGithubError,
|
|
32
32
|
collectSessionData,
|
|
@@ -38,12 +38,12 @@ import {
|
|
|
38
38
|
toJson,
|
|
39
39
|
toJsonl,
|
|
40
40
|
toMarkdown
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-P3RBMQ4P.js";
|
|
42
42
|
import {
|
|
43
43
|
OBSERVED_CONTACT_MAX_FRESH_WITHIN_SECONDS,
|
|
44
44
|
ObservedChannelContactStore
|
|
45
45
|
} from "./chunk-OWMAZHIX.js";
|
|
46
|
-
import "./chunk-
|
|
46
|
+
import "./chunk-UYAUA63Q.js";
|
|
47
47
|
import {
|
|
48
48
|
escapeAnsiCtrlCodes
|
|
49
49
|
} from "./chunk-4NFY2S7N.js";
|
|
@@ -107,7 +107,8 @@ import {
|
|
|
107
107
|
setRateLimiter,
|
|
108
108
|
unsafeRevealSecret,
|
|
109
109
|
validateMcpRuntimeServerName
|
|
110
|
-
} from "./chunk-
|
|
110
|
+
} from "./chunk-KTKYGS2P.js";
|
|
111
|
+
import "./chunk-VGHZT6JR.js";
|
|
111
112
|
import {
|
|
112
113
|
isLoopbackBind,
|
|
113
114
|
normalizeSessionIdForLookup,
|
|
@@ -127,14 +128,14 @@ import {
|
|
|
127
128
|
validateWorkspaceSkillName,
|
|
128
129
|
validateWorkspaceVoiceState,
|
|
129
130
|
voiceSettingsScopeToWire
|
|
130
|
-
} from "./chunk-
|
|
131
|
+
} from "./chunk-46YJDYCU.js";
|
|
131
132
|
import {
|
|
132
133
|
PermissionRulesValidationError,
|
|
133
134
|
buildPermissionSettings,
|
|
134
135
|
isPermissionRuleType,
|
|
135
136
|
normalizePermissionRules,
|
|
136
137
|
readPermissionRuleSet
|
|
137
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-BAMN6XSD.js";
|
|
138
139
|
import {
|
|
139
140
|
assertVoiceBaseUrlNetworkAllowed,
|
|
140
141
|
isStreamingVoiceModel,
|
|
@@ -142,12 +143,12 @@ import {
|
|
|
142
143
|
resolveVoiceTranscriptionConfig,
|
|
143
144
|
sanitizeVoiceErrorMessage,
|
|
144
145
|
transcribeVoiceAudio
|
|
145
|
-
} from "./chunk-
|
|
146
|
+
} from "./chunk-RBHQXGDK.js";
|
|
146
147
|
import {
|
|
147
148
|
isVoiceEnabled,
|
|
148
149
|
isVoiceMode,
|
|
149
150
|
readVoiceModel
|
|
150
|
-
} from "./chunk-
|
|
151
|
+
} from "./chunk-GAKGOXTC.js";
|
|
151
152
|
import "./chunk-AOHJKPKL.js";
|
|
152
153
|
import {
|
|
153
154
|
createTotalSessionAdmissionController
|
|
@@ -165,26 +166,26 @@ import {
|
|
|
165
166
|
} from "./chunk-4JRM2BSM.js";
|
|
166
167
|
import {
|
|
167
168
|
assertValidChannelSecretUpdates
|
|
168
|
-
} from "./chunk-
|
|
169
|
+
} from "./chunk-QSNSL4R4.js";
|
|
169
170
|
import {
|
|
170
171
|
createDaemonStatusProvider
|
|
171
|
-
} from "./chunk-
|
|
172
|
+
} from "./chunk-ZTQSOV56.js";
|
|
172
173
|
import "./chunk-NTTBXH7U.js";
|
|
173
|
-
import "./chunk-
|
|
174
|
+
import "./chunk-7S4JBJLU.js";
|
|
174
175
|
import "./chunk-3SH53ANB.js";
|
|
175
176
|
import {
|
|
176
177
|
createWorkspaceProvidersStatusProvider
|
|
177
|
-
} from "./chunk-
|
|
178
|
+
} from "./chunk-3WDYBTTI.js";
|
|
178
179
|
import {
|
|
179
180
|
getAuthTypeFromEnv,
|
|
180
181
|
resolveCliGenerationConfig
|
|
181
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-KTQGGPGV.js";
|
|
182
183
|
import {
|
|
183
184
|
snapshotProcessEnv
|
|
184
|
-
} from "./chunk-
|
|
185
|
+
} from "./chunk-23VQTELM.js";
|
|
185
186
|
import {
|
|
186
187
|
createWorkspaceSkillsStatusProvider
|
|
187
|
-
} from "./chunk-
|
|
188
|
+
} from "./chunk-ZBXGWQ4S.js";
|
|
188
189
|
import "./chunk-BGXZBI5B.js";
|
|
189
190
|
import "./chunk-Z4X5MTRT.js";
|
|
190
191
|
import {
|
|
@@ -203,12 +204,12 @@ import {
|
|
|
203
204
|
import {
|
|
204
205
|
evaluateDaemonWorkspaceTrust,
|
|
205
206
|
readDaemonTrustPolicySnapshot
|
|
206
|
-
} from "./chunk-
|
|
207
|
+
} from "./chunk-G2TX5ZXC.js";
|
|
207
208
|
import {
|
|
208
209
|
daemonObservedContactsPath,
|
|
209
210
|
loadChannelsConfig
|
|
210
|
-
} from "./chunk-
|
|
211
|
-
import "./chunk-
|
|
211
|
+
} from "./chunk-ATMO54WE.js";
|
|
212
|
+
import "./chunk-HADWBW5R.js";
|
|
212
213
|
import "./chunk-57OAHC2Y.js";
|
|
213
214
|
import {
|
|
214
215
|
parseChannelWebhookConfigLenient
|
|
@@ -227,7 +228,7 @@ import {
|
|
|
227
228
|
SessionArtifactValidationError,
|
|
228
229
|
createAcpSessionBridge,
|
|
229
230
|
parseSessionSource
|
|
230
|
-
} from "./chunk-
|
|
231
|
+
} from "./chunk-P4ZEZSJZ.js";
|
|
231
232
|
import {
|
|
232
233
|
EVENT_SCHEMA_VERSION,
|
|
233
234
|
EventBus,
|
|
@@ -253,7 +254,7 @@ import {
|
|
|
253
254
|
WorkspaceRegistrationStoreLimitError,
|
|
254
255
|
normalizeWorkspaceDisplayName,
|
|
255
256
|
workspaceRegistrationId
|
|
256
|
-
} from "./chunk-
|
|
257
|
+
} from "./chunk-W3FSZSF2.js";
|
|
257
258
|
import {
|
|
258
259
|
REQUESTED_SESSION_ID_META_KEY,
|
|
259
260
|
gradeActiveWorkCoverage
|
|
@@ -333,23 +334,26 @@ import {
|
|
|
333
334
|
getWritableScopes,
|
|
334
335
|
loadSettings,
|
|
335
336
|
validateSettingValue
|
|
336
|
-
} from "./chunk-
|
|
337
|
+
} from "./chunk-JUWS2Z5K.js";
|
|
338
|
+
import "./chunk-7GOYZQPR.js";
|
|
337
339
|
import "./chunk-RKUWKYED.js";
|
|
338
340
|
import "./chunk-GOXKNSDZ.js";
|
|
339
341
|
import "./chunk-IDS7MSUP.js";
|
|
340
342
|
import {
|
|
341
|
-
SUPPORTED_LANGUAGES,
|
|
342
343
|
detectSystemLanguage,
|
|
343
|
-
resolveLanguageSetting
|
|
344
|
+
resolveLanguageSetting
|
|
345
|
+
} from "./chunk-WP5VOXF7.js";
|
|
346
|
+
import {
|
|
347
|
+
SUPPORTED_LANGUAGES,
|
|
344
348
|
resolveSupportedLanguage
|
|
345
|
-
} from "./chunk-
|
|
346
|
-
import "./chunk-
|
|
347
|
-
import "./chunk-
|
|
348
|
-
import "./chunk-
|
|
349
|
+
} from "./chunk-5EJZE3FP.js";
|
|
350
|
+
import "./chunk-T6HEQR2Q.js";
|
|
351
|
+
import "./chunk-VFMASYQA.js";
|
|
352
|
+
import "./chunk-IOEZE2YT.js";
|
|
349
353
|
import "./chunk-VJNBRRZG.js";
|
|
350
354
|
import {
|
|
351
355
|
getWorkspaceTrustStatus
|
|
352
|
-
} from "./chunk-
|
|
356
|
+
} from "./chunk-ZOSTTOUJ.js";
|
|
353
357
|
import "./chunk-NPQ5ZKRP.js";
|
|
354
358
|
import {
|
|
355
359
|
isWithinRoot as isWithinRoot2
|
|
@@ -429,7 +433,7 @@ import {
|
|
|
429
433
|
writeWorkspaceContextFile,
|
|
430
434
|
writeWorktreeSession,
|
|
431
435
|
writeWorktreeSessionMarker
|
|
432
|
-
} from "./chunk-
|
|
436
|
+
} from "./chunk-XX7QFP34.js";
|
|
433
437
|
import "./chunk-GOFAQQZA.js";
|
|
434
438
|
import "./chunk-5M6IDOMF.js";
|
|
435
439
|
import "./chunk-TWPJO254.js";
|
|
@@ -442,7 +446,7 @@ import "./chunk-MVUQRLOH.js";
|
|
|
442
446
|
import "./chunk-XCWO3SMQ.js";
|
|
443
447
|
import "./chunk-7MH4J33A.js";
|
|
444
448
|
import "./chunk-6PVPNMXU.js";
|
|
445
|
-
import "./chunk-
|
|
449
|
+
import "./chunk-K4ADGWHU.js";
|
|
446
450
|
import {
|
|
447
451
|
nextFireTime,
|
|
448
452
|
parseCron
|
|
@@ -536,7 +540,7 @@ import "./chunk-FVKHVJZQ.js";
|
|
|
536
540
|
import "./chunk-COBO5EBO.js";
|
|
537
541
|
import "./chunk-6ZRFAKXK.js";
|
|
538
542
|
import "./chunk-PYQADEFD.js";
|
|
539
|
-
import "./chunk-
|
|
543
|
+
import "./chunk-PVOGHGSF.js";
|
|
540
544
|
import "./chunk-F6WFNA7U.js";
|
|
541
545
|
import "./chunk-46UV252V.js";
|
|
542
546
|
import "./chunk-ZBVS26BY.js";
|
|
@@ -1233,26 +1237,165 @@ function createWorkspaceFileSystemFactory(deps) {
|
|
|
1233
1237
|
});
|
|
1234
1238
|
const lowFs = new StandardFileSystemService();
|
|
1235
1239
|
const pathLocks = deps.pathLocks ?? new PathMutexRegistry();
|
|
1240
|
+
const forRequest = /* @__PURE__ */ __name((ctx) => new WorkspaceFileSystemImpl({
|
|
1241
|
+
primaryWorkspace,
|
|
1242
|
+
workspaces,
|
|
1243
|
+
trusted: deps.trusted,
|
|
1244
|
+
audit,
|
|
1245
|
+
ctx,
|
|
1246
|
+
lowFs,
|
|
1247
|
+
pathLocks,
|
|
1248
|
+
generationGuard: deps.generationGuard
|
|
1249
|
+
}), "forRequest");
|
|
1236
1250
|
return {
|
|
1237
1251
|
assertCanWrite() {
|
|
1238
1252
|
deps.generationGuard?.assertOpen();
|
|
1239
1253
|
assertTrustedForIntent(deps.trusted, "write");
|
|
1240
1254
|
},
|
|
1241
|
-
forRequest
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
audit,
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1255
|
+
forRequest,
|
|
1256
|
+
async writeSameHostToolText(ctx, request2) {
|
|
1257
|
+
try {
|
|
1258
|
+
deps.generationGuard?.assertOpen();
|
|
1259
|
+
} catch (err) {
|
|
1260
|
+
throw recordSameHostToolWriteDenied(audit, ctx, request2.path, err);
|
|
1261
|
+
}
|
|
1262
|
+
let resolved;
|
|
1263
|
+
try {
|
|
1264
|
+
resolved = await resolveWithinWorkspace(
|
|
1265
|
+
request2.path,
|
|
1266
|
+
workspaces.map((workspace) => workspace.path),
|
|
1267
|
+
"write"
|
|
1268
|
+
);
|
|
1269
|
+
deps.generationGuard?.assertOpen();
|
|
1270
|
+
} catch (err) {
|
|
1271
|
+
if (!(err instanceof FsError && err.kind === "path_outside_workspace")) {
|
|
1272
|
+
throw recordSameHostToolWriteDenied(audit, ctx, request2.path, err);
|
|
1273
|
+
}
|
|
1274
|
+
try {
|
|
1275
|
+
await writeSameHostToolTextOutsideWorkspace({
|
|
1276
|
+
request: request2,
|
|
1277
|
+
trusted: deps.trusted,
|
|
1278
|
+
audit,
|
|
1279
|
+
ctx,
|
|
1280
|
+
pathLocks,
|
|
1281
|
+
generationGuard: deps.generationGuard
|
|
1282
|
+
});
|
|
1283
|
+
return;
|
|
1284
|
+
} catch (outsideErr) {
|
|
1285
|
+
throw recordSameHostToolWriteDenied(
|
|
1286
|
+
audit,
|
|
1287
|
+
ctx,
|
|
1288
|
+
request2.path,
|
|
1289
|
+
outsideErr
|
|
1290
|
+
);
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
try {
|
|
1294
|
+
await forRequest(ctx).writeTextOverwrite(resolved, request2.content);
|
|
1295
|
+
} catch (err) {
|
|
1296
|
+
if (isWorkspaceGenerationClosedError(err)) {
|
|
1297
|
+
recordSameHostToolWriteDenied(audit, ctx, request2.path, err);
|
|
1298
|
+
}
|
|
1299
|
+
throw err;
|
|
1300
|
+
}
|
|
1252
1301
|
}
|
|
1253
1302
|
};
|
|
1254
1303
|
}
|
|
1255
1304
|
__name(createWorkspaceFileSystemFactory, "createWorkspaceFileSystemFactory");
|
|
1305
|
+
async function writeSameHostToolTextOutsideWorkspace(deps) {
|
|
1306
|
+
const start = performance.now();
|
|
1307
|
+
deps.generationGuard?.assertOpen();
|
|
1308
|
+
assertTrustedForIntent(deps.trusted, "write");
|
|
1309
|
+
enforceWriteSize(Buffer.byteLength(deps.request.content, "utf-8"));
|
|
1310
|
+
const target = await resolveSameHostToolWriteTarget(deps.request.path);
|
|
1311
|
+
await deps.pathLocks.runExclusive(target, async () => {
|
|
1312
|
+
deps.generationGuard?.assertOpen();
|
|
1313
|
+
const meta = mergeWriteMeta(void 0, deps.request.meta ?? {});
|
|
1314
|
+
const content = meta.bom && deps.request.content.charCodeAt(0) === 65279 ? deps.request.content.slice(1) : deps.request.content;
|
|
1315
|
+
const result = await atomicWriteTextResolvedFile({
|
|
1316
|
+
target,
|
|
1317
|
+
content,
|
|
1318
|
+
mode: "overwrite",
|
|
1319
|
+
meta,
|
|
1320
|
+
assertGenerationOpen: /* @__PURE__ */ __name(() => deps.generationGuard?.assertOpen(), "assertGenerationOpen")
|
|
1321
|
+
});
|
|
1322
|
+
deps.audit.recordAccess(deps.ctx, {
|
|
1323
|
+
intent: "write",
|
|
1324
|
+
absolute: target,
|
|
1325
|
+
durationMs: performance.now() - start,
|
|
1326
|
+
sizeBytes: result.sizeBytes
|
|
1327
|
+
});
|
|
1328
|
+
});
|
|
1329
|
+
}
|
|
1330
|
+
__name(writeSameHostToolTextOutsideWorkspace, "writeSameHostToolTextOutsideWorkspace");
|
|
1331
|
+
async function resolveSameHostToolWriteTarget(input) {
|
|
1332
|
+
if (!path4.isAbsolute(input)) {
|
|
1333
|
+
throw new FsError(
|
|
1334
|
+
"path_outside_workspace",
|
|
1335
|
+
`same-host external tool write requires an absolute path: ${input}`
|
|
1336
|
+
);
|
|
1337
|
+
}
|
|
1338
|
+
if (hasSuspiciousPathPattern(input)) {
|
|
1339
|
+
throw new FsError(
|
|
1340
|
+
"path_outside_workspace",
|
|
1341
|
+
`path contains suspicious pattern: ${input}`
|
|
1342
|
+
);
|
|
1343
|
+
}
|
|
1344
|
+
let leaf;
|
|
1345
|
+
try {
|
|
1346
|
+
leaf = await fsp2.lstat(input);
|
|
1347
|
+
} catch (err) {
|
|
1348
|
+
if (err?.code !== "ENOENT") {
|
|
1349
|
+
throw err;
|
|
1350
|
+
}
|
|
1351
|
+
const parent = await fsp2.realpath(path4.dirname(input));
|
|
1352
|
+
const parentStat = await fsp2.lstat(parent);
|
|
1353
|
+
if (!parentStat.isDirectory()) {
|
|
1354
|
+
throw new FsError(
|
|
1355
|
+
"parse_error",
|
|
1356
|
+
`parent path is not a directory: ${parent}`
|
|
1357
|
+
);
|
|
1358
|
+
}
|
|
1359
|
+
return path4.join(parent, path4.basename(input));
|
|
1360
|
+
}
|
|
1361
|
+
if (leaf.isSymbolicLink()) {
|
|
1362
|
+
throw new FsError(
|
|
1363
|
+
"symlink_escape",
|
|
1364
|
+
`path is a symlink and cannot be overwritten: ${input}`,
|
|
1365
|
+
{ hint: "resolve the target explicitly before writing" }
|
|
1366
|
+
);
|
|
1367
|
+
}
|
|
1368
|
+
if (!leaf.isFile()) {
|
|
1369
|
+
throw new FsError("parse_error", `path is not a regular file: ${input}`);
|
|
1370
|
+
}
|
|
1371
|
+
const canonical = await fsp2.realpath(input);
|
|
1372
|
+
const canonicalStat = await fsp2.lstat(canonical);
|
|
1373
|
+
if (!canonicalStat.isFile()) {
|
|
1374
|
+
throw new FsError(
|
|
1375
|
+
"parse_error",
|
|
1376
|
+
`canonical path is not a regular file: ${canonical}`
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
assertSameFile(leaf, canonicalStat, input, "write");
|
|
1380
|
+
return canonical;
|
|
1381
|
+
}
|
|
1382
|
+
__name(resolveSameHostToolWriteTarget, "resolveSameHostToolWriteTarget");
|
|
1383
|
+
function isWorkspaceGenerationClosedError(error2) {
|
|
1384
|
+
return error2 instanceof Error && "code" in error2 && error2.code === "workspace_generation_closed";
|
|
1385
|
+
}
|
|
1386
|
+
__name(isWorkspaceGenerationClosedError, "isWorkspaceGenerationClosedError");
|
|
1387
|
+
function recordSameHostToolWriteDenied(audit, ctx, input, error2) {
|
|
1388
|
+
const fsError = wrapAsFsError(error2);
|
|
1389
|
+
audit.recordDenied(ctx, {
|
|
1390
|
+
intent: "write",
|
|
1391
|
+
input,
|
|
1392
|
+
errorKind: fsError.kind,
|
|
1393
|
+
hint: fsError.hint,
|
|
1394
|
+
message: fsError.message
|
|
1395
|
+
});
|
|
1396
|
+
return isWorkspaceGenerationClosedError(error2) && error2 instanceof Error ? error2 : fsError;
|
|
1397
|
+
}
|
|
1398
|
+
__name(recordSameHostToolWriteDenied, "recordSameHostToolWriteDenied");
|
|
1256
1399
|
function assertNoNestedWorkspaces(workspaces) {
|
|
1257
1400
|
for (let i = 0; i < workspaces.length; i++) {
|
|
1258
1401
|
const a = workspaces[i];
|
|
@@ -16422,690 +16565,10 @@ function registerDaemonStatusRoutes(app, deps) {
|
|
|
16422
16565
|
}
|
|
16423
16566
|
__name(registerDaemonStatusRoutes, "registerDaemonStatusRoutes");
|
|
16424
16567
|
|
|
16425
|
-
// packages/cli/src/serve/routes/health
|
|
16426
|
-
init_esbuild_shims();
|
|
16427
|
-
|
|
16428
|
-
// packages/cli/src/serve/demo.ts
|
|
16568
|
+
// packages/cli/src/serve/routes/health.ts
|
|
16429
16569
|
init_esbuild_shims();
|
|
16430
|
-
function
|
|
16431
|
-
|
|
16432
|
-
/* html */
|
|
16433
|
-
`<!DOCTYPE html>
|
|
16434
|
-
<html lang="en">
|
|
16435
|
-
<head>
|
|
16436
|
-
<meta charset="utf-8" />
|
|
16437
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
16438
|
-
<title>Qwen Serve Demo</title>
|
|
16439
|
-
<style>
|
|
16440
|
-
:root { --bg: #1a1a2e; --surface: #16213e; --border: #0f3460; --accent: #e94560; --text: #eee; --text2: #aab; --ok: #4ade80; --warn: #fbbf24; --err: #f87171; }
|
|
16441
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
16442
|
-
body { font-family: 'SF Mono', 'Menlo', 'Consolas', monospace; font-size: 13px; background: var(--bg); color: var(--text); min-height: 100vh; }
|
|
16443
|
-
.header { background: var(--surface); border-bottom: 1px solid var(--border); padding: 12px 20px; display: flex; align-items: center; gap: 12px; }
|
|
16444
|
-
.header h1 { font-size: 16px; font-weight: 600; }
|
|
16445
|
-
.header .badge { font-size: 11px; background: var(--accent); color: #fff; padding: 2px 8px; border-radius: 10px; }
|
|
16446
|
-
.header .status { margin-left: auto; display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text2); }
|
|
16447
|
-
.header .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--err); }
|
|
16448
|
-
.header .dot.ok { background: var(--ok); }
|
|
16449
|
-
.container { display: grid; grid-template-columns: 340px 1fr; height: calc(100vh - 49px); }
|
|
16450
|
-
.sidebar { background: var(--surface); border-right: 1px solid var(--border); overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 12px; }
|
|
16451
|
-
.panel { background: var(--bg); border: 1px solid var(--border); border-radius: 6px; padding: 12px; }
|
|
16452
|
-
.panel h3 { font-size: 12px; color: var(--accent); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; }
|
|
16453
|
-
.panel label { display: block; font-size: 11px; color: var(--text2); margin-bottom: 3px; }
|
|
16454
|
-
.panel input, .panel textarea { width: 100%; background: var(--surface); border: 1px solid var(--border); color: var(--text); padding: 6px 8px; border-radius: 4px; font-family: inherit; font-size: 12px; margin-bottom: 8px; }
|
|
16455
|
-
.panel input:focus, .panel textarea:focus { outline: none; border-color: var(--accent); }
|
|
16456
|
-
.panel textarea { resize: vertical; min-height: 60px; }
|
|
16457
|
-
.btn { display: inline-flex; align-items: center; gap: 4px; padding: 6px 14px; border: 1px solid var(--border); border-radius: 4px; background: var(--surface); color: var(--text); font-family: inherit; font-size: 12px; cursor: pointer; transition: all 0.15s; }
|
|
16458
|
-
.btn:hover { border-color: var(--accent); color: var(--accent); }
|
|
16459
|
-
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
|
|
16460
|
-
.btn.primary:hover { opacity: 0.85; }
|
|
16461
|
-
.btn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
16462
|
-
.btn-row { display: flex; gap: 6px; flex-wrap: wrap; }
|
|
16463
|
-
.main { display: flex; flex-direction: column; overflow: hidden; }
|
|
16464
|
-
.tabs { display: flex; background: var(--surface); border-bottom: 1px solid var(--border); }
|
|
16465
|
-
.tab { padding: 8px 16px; font-size: 12px; color: var(--text2); cursor: pointer; border-bottom: 2px solid transparent; }
|
|
16466
|
-
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }
|
|
16467
|
-
.tab-content { flex: 1; overflow: hidden; display: none; flex-direction: column; }
|
|
16468
|
-
.tab-content.active { display: flex; }
|
|
16469
|
-
.log { flex: 1; overflow-y: auto; padding: 12px; font-size: 12px; line-height: 1.6; }
|
|
16470
|
-
.log-entry { padding: 3px 0; border-bottom: 1px solid rgba(255,255,255,0.03); word-break: break-all; }
|
|
16471
|
-
.log-entry .ts { color: var(--text2); margin-right: 8px; font-size: 11px; }
|
|
16472
|
-
.log-entry .tag { display: inline-block; padding: 0 5px; border-radius: 3px; font-size: 10px; margin-right: 6px; }
|
|
16473
|
-
.tag-info { background: #1e40af; color: #93c5fd; }
|
|
16474
|
-
.tag-event { background: #065f46; color: #6ee7b7; }
|
|
16475
|
-
.tag-error { background: #7f1d1d; color: #fca5a5; }
|
|
16476
|
-
.tag-response { background: #713f12; color: #fde68a; }
|
|
16477
|
-
.tag-thought { background: #4c1d95; color: #c4b5fd; }
|
|
16478
|
-
.tag-message { background: #164e63; color: #67e8f9; }
|
|
16479
|
-
.chat { flex: 1; overflow-y: auto; padding: 16px; }
|
|
16480
|
-
.chat-msg { margin-bottom: 12px; max-width: 85%; }
|
|
16481
|
-
.chat-msg.user { margin-left: auto; }
|
|
16482
|
-
.chat-msg .bubble { padding: 8px 12px; border-radius: 8px; line-height: 1.5; white-space: pre-wrap; }
|
|
16483
|
-
.chat-msg.user .bubble { background: var(--accent); color: #fff; border-bottom-right-radius: 2px; }
|
|
16484
|
-
.chat-msg.assistant .bubble { background: var(--surface); border: 1px solid var(--border); border-bottom-left-radius: 2px; }
|
|
16485
|
-
.chat-msg .meta { font-size: 10px; color: var(--text2); margin-top: 3px; }
|
|
16486
|
-
.chat-input { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--border); background: var(--surface); }
|
|
16487
|
-
.chat-input input { flex: 1; }
|
|
16488
|
-
.session-info { font-size: 11px; color: var(--text2); padding: 4px 0; }
|
|
16489
|
-
.session-info span { color: var(--ok); }
|
|
16490
|
-
.empty-hint { color: var(--text2); text-align: center; padding: 40px 20px; font-size: 12px; }
|
|
16491
|
-
.permission-card { background: var(--surface); border: 1px solid var(--warn); border-radius: 6px; padding: 10px 12px; margin: 8px 0; }
|
|
16492
|
-
.permission-card h4 { color: var(--warn); font-size: 12px; margin-bottom: 6px; }
|
|
16493
|
-
.permission-card .opt-btn { margin-right: 4px; margin-top: 4px; }
|
|
16494
|
-
</style>
|
|
16495
|
-
</head>
|
|
16496
|
-
<body>
|
|
16497
|
-
|
|
16498
|
-
<div class="header">
|
|
16499
|
-
<h1>Qwen Serve</h1>
|
|
16500
|
-
<span class="badge">Demo</span>
|
|
16501
|
-
<div class="status">
|
|
16502
|
-
<span class="dot" id="statusDot"></span>
|
|
16503
|
-
<span id="statusText">Connecting...</span>
|
|
16504
|
-
</div>
|
|
16505
|
-
</div>
|
|
16506
|
-
|
|
16507
|
-
<div class="container">
|
|
16508
|
-
<div class="sidebar">
|
|
16509
|
-
<div class="panel">
|
|
16510
|
-
<h3>Session</h3>
|
|
16511
|
-
<label>Working Directory (cwd)</label>
|
|
16512
|
-
<input type="text" id="cwdInput" placeholder="/path/to/project" />
|
|
16513
|
-
<div class="btn-row">
|
|
16514
|
-
<button class="btn primary" id="btnCreateSession">Create / Attach</button>
|
|
16515
|
-
<button class="btn" id="btnListSessions">List</button>
|
|
16516
|
-
</div>
|
|
16517
|
-
<div class="session-info" id="sessionInfo" style="display:none">
|
|
16518
|
-
Session: <span id="sessionIdDisplay"></span>
|
|
16519
|
-
</div>
|
|
16520
|
-
<div class="session-info" id="contextUsage" style="display:none"></div>
|
|
16521
|
-
</div>
|
|
16522
|
-
|
|
16523
|
-
<div class="panel">
|
|
16524
|
-
<h3>Prompt</h3>
|
|
16525
|
-
<textarea id="promptInput" placeholder="Type your prompt here..."></textarea>
|
|
16526
|
-
<div class="btn-row">
|
|
16527
|
-
<button class="btn primary" id="btnSendPrompt" disabled>Send</button>
|
|
16528
|
-
<button class="btn" id="btnCancel" disabled>Cancel</button>
|
|
16529
|
-
</div>
|
|
16530
|
-
</div>
|
|
16531
|
-
|
|
16532
|
-
<div class="panel">
|
|
16533
|
-
<h3>Model</h3>
|
|
16534
|
-
<input type="text" id="modelInput" placeholder="Model ID (e.g. qwen3-coder)" />
|
|
16535
|
-
<button class="btn" id="btnSetModel" disabled>Switch Model</button>
|
|
16536
|
-
</div>
|
|
16537
|
-
|
|
16538
|
-
<div class="panel">
|
|
16539
|
-
<h3>Auth Token</h3>
|
|
16540
|
-
<label>Bearer Token (if --token is set)</label>
|
|
16541
|
-
<input type="password" id="tokenInput" placeholder="Optional bearer token" />
|
|
16542
|
-
</div>
|
|
16543
|
-
|
|
16544
|
-
<div class="panel">
|
|
16545
|
-
<h3>Quick Actions</h3>
|
|
16546
|
-
<div class="btn-row">
|
|
16547
|
-
<button class="btn" id="btnHealth">Health</button>
|
|
16548
|
-
<button class="btn" id="btnHealthDeep">Health (deep)</button>
|
|
16549
|
-
<button class="btn" id="btnCaps">Capabilities</button>
|
|
16550
|
-
</div>
|
|
16551
|
-
</div>
|
|
16552
|
-
|
|
16553
|
-
<div class="panel" id="permissionPanel" style="display:none">
|
|
16554
|
-
<h3>Pending Permissions</h3>
|
|
16555
|
-
<div id="permissionList"></div>
|
|
16556
|
-
</div>
|
|
16557
|
-
</div>
|
|
16558
|
-
|
|
16559
|
-
<div class="main">
|
|
16560
|
-
<div class="tabs">
|
|
16561
|
-
<div class="tab active" data-tab="chat">Chat</div>
|
|
16562
|
-
<div class="tab" data-tab="events">Events</div>
|
|
16563
|
-
<div class="tab" data-tab="requests">API Log</div>
|
|
16564
|
-
</div>
|
|
16565
|
-
|
|
16566
|
-
<div class="tab-content active" id="tab-chat">
|
|
16567
|
-
<div class="chat" id="chatArea">
|
|
16568
|
-
<div class="empty-hint">Create a session to start chatting</div>
|
|
16569
|
-
</div>
|
|
16570
|
-
<div class="chat-input">
|
|
16571
|
-
<input type="text" id="chatInput" placeholder="Send a message..." disabled />
|
|
16572
|
-
<button class="btn primary" id="btnChatSend" disabled>Send</button>
|
|
16573
|
-
</div>
|
|
16574
|
-
</div>
|
|
16575
|
-
|
|
16576
|
-
<div class="tab-content" id="tab-events">
|
|
16577
|
-
<div class="log" id="eventLog"></div>
|
|
16578
|
-
</div>
|
|
16579
|
-
|
|
16580
|
-
<div class="tab-content" id="tab-requests">
|
|
16581
|
-
<div class="log" id="requestLog"></div>
|
|
16582
|
-
</div>
|
|
16583
|
-
</div>
|
|
16584
|
-
</div>
|
|
16585
|
-
|
|
16586
|
-
<script>
|
|
16587
|
-
(function() {
|
|
16588
|
-
const BASE = '';
|
|
16589
|
-
let sessionId = null;
|
|
16590
|
-
let eventSource = null;
|
|
16591
|
-
let currentAssistantBubble = null;
|
|
16592
|
-
let currentThought = '';
|
|
16593
|
-
|
|
16594
|
-
// --- DOM refs ---
|
|
16595
|
-
const $ = (s) => document.querySelector(s);
|
|
16596
|
-
const statusDot = $('#statusDot');
|
|
16597
|
-
const statusText = $('#statusText');
|
|
16598
|
-
const cwdInput = $('#cwdInput');
|
|
16599
|
-
const promptInput = $('#promptInput');
|
|
16600
|
-
const modelInput = $('#modelInput');
|
|
16601
|
-
const tokenInput = $('#tokenInput');
|
|
16602
|
-
const chatArea = $('#chatArea');
|
|
16603
|
-
const chatInput = $('#chatInput');
|
|
16604
|
-
const eventLog = $('#eventLog');
|
|
16605
|
-
const requestLog = $('#requestLog');
|
|
16606
|
-
const sessionInfo = $('#sessionInfo');
|
|
16607
|
-
const sessionIdDisplay = $('#sessionIdDisplay');
|
|
16608
|
-
const contextUsage = $('#contextUsage');
|
|
16609
|
-
let lastLoggedContextPct = -1;
|
|
16610
|
-
const permissionPanel = $('#permissionPanel');
|
|
16611
|
-
const permissionList = $('#permissionList');
|
|
16612
|
-
|
|
16613
|
-
// --- Tabs ---
|
|
16614
|
-
document.querySelectorAll('.tab').forEach(tab => {
|
|
16615
|
-
tab.addEventListener('click', () => {
|
|
16616
|
-
document.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
|
16617
|
-
document.querySelectorAll('.tab-content').forEach(t => t.classList.remove('active'));
|
|
16618
|
-
tab.classList.add('active');
|
|
16619
|
-
$('#tab-' + tab.dataset.tab).classList.add('active');
|
|
16620
|
-
});
|
|
16621
|
-
});
|
|
16622
|
-
|
|
16623
|
-
// --- Logging ---
|
|
16624
|
-
function ts() {
|
|
16625
|
-
return new Date().toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
|
16626
|
-
}
|
|
16627
|
-
const MAX_LOG_ENTRIES = 500;
|
|
16628
|
-
function addLog(container, tag, tagClass, msg) {
|
|
16629
|
-
const el = document.createElement('div');
|
|
16630
|
-
el.className = 'log-entry';
|
|
16631
|
-
const text = typeof msg === 'object' ? JSON.stringify(msg, null, 2) : msg;
|
|
16632
|
-
const tsSpan = document.createElement('span');
|
|
16633
|
-
tsSpan.className = 'ts';
|
|
16634
|
-
tsSpan.textContent = ts();
|
|
16635
|
-
const tagSpan = document.createElement('span');
|
|
16636
|
-
tagSpan.className = 'tag ' + tagClass;
|
|
16637
|
-
tagSpan.textContent = tag;
|
|
16638
|
-
el.appendChild(tsSpan);
|
|
16639
|
-
el.appendChild(tagSpan);
|
|
16640
|
-
el.appendChild(document.createTextNode(text));
|
|
16641
|
-
container.appendChild(el);
|
|
16642
|
-
while (container.children.length > MAX_LOG_ENTRIES) {
|
|
16643
|
-
container.removeChild(container.firstChild);
|
|
16644
|
-
}
|
|
16645
|
-
container.scrollTop = container.scrollHeight;
|
|
16646
|
-
}
|
|
16647
|
-
function logEvent(tag, msg) { addLog(eventLog, tag, 'tag-event', msg); }
|
|
16648
|
-
function logRequest(tag, msg) { addLog(requestLog, tag, 'tag-info', msg); }
|
|
16649
|
-
function logResponse(tag, msg) { addLog(requestLog, tag, 'tag-response', msg); }
|
|
16650
|
-
function logError(tag, msg) { addLog(requestLog, tag, 'tag-error', msg); }
|
|
16651
|
-
|
|
16652
|
-
function escHtml(s) {
|
|
16653
|
-
const d = document.createElement('div');
|
|
16654
|
-
d.textContent = String(s);
|
|
16655
|
-
return d.innerHTML;
|
|
16656
|
-
}
|
|
16657
|
-
|
|
16658
|
-
// --- 401 token hint ---
|
|
16659
|
-
let tokenHintTimer = null;
|
|
16660
|
-
function highlightTokenInput(msg) {
|
|
16661
|
-
tokenInput.style.borderColor = 'var(--warn)';
|
|
16662
|
-
tokenInput.focus();
|
|
16663
|
-
// Show hint text below the input
|
|
16664
|
-
let hint = document.getElementById('tokenHint');
|
|
16665
|
-
if (!hint) {
|
|
16666
|
-
hint = document.createElement('div');
|
|
16667
|
-
hint.id = 'tokenHint';
|
|
16668
|
-
hint.style.cssText = 'font-size:11px;color:var(--warn);margin-top:-4px;margin-bottom:4px;';
|
|
16669
|
-
tokenInput.parentNode.insertBefore(hint, tokenInput.nextSibling);
|
|
16670
|
-
}
|
|
16671
|
-
hint.textContent = msg;
|
|
16672
|
-
if (tokenHintTimer) clearTimeout(tokenHintTimer);
|
|
16673
|
-
tokenHintTimer = setTimeout(() => {
|
|
16674
|
-
tokenInput.style.borderColor = '';
|
|
16675
|
-
hint.textContent = '';
|
|
16676
|
-
}, 6000);
|
|
16677
|
-
}
|
|
16678
|
-
|
|
16679
|
-
// --- API helpers ---
|
|
16680
|
-
function authHeaders() {
|
|
16681
|
-
const token = tokenInput.value.trim();
|
|
16682
|
-
return token ? { 'Authorization': 'Bearer ' + token } : {};
|
|
16683
|
-
}
|
|
16684
|
-
|
|
16685
|
-
async function api(method, path, body) {
|
|
16686
|
-
const opts = { method, headers: { ...authHeaders() } };
|
|
16687
|
-
if (body !== undefined) {
|
|
16688
|
-
opts.headers['Content-Type'] = 'application/json';
|
|
16689
|
-
opts.body = JSON.stringify(body);
|
|
16690
|
-
}
|
|
16691
|
-
logRequest(method, path + (body ? ' ' + JSON.stringify(body) : ''));
|
|
16692
|
-
try {
|
|
16693
|
-
const res = await fetch(BASE + path, opts);
|
|
16694
|
-
const text = await res.text();
|
|
16695
|
-
let data;
|
|
16696
|
-
try { data = JSON.parse(text); } catch { data = text; }
|
|
16697
|
-
if (!res.ok) {
|
|
16698
|
-
logError(res.status, JSON.stringify(data));
|
|
16699
|
-
if (res.status === 401) {
|
|
16700
|
-
highlightTokenInput('API returned 401 \u2014 enter your bearer token below');
|
|
16701
|
-
}
|
|
16702
|
-
return { ok: false, status: res.status, data };
|
|
16703
|
-
}
|
|
16704
|
-
logResponse(res.status, JSON.stringify(data));
|
|
16705
|
-
return { ok: true, status: res.status, data };
|
|
16706
|
-
} catch (err) {
|
|
16707
|
-
logError('ERR', err.message);
|
|
16708
|
-
return { ok: false, status: 0, data: { error: err.message } };
|
|
16709
|
-
}
|
|
16710
|
-
}
|
|
16711
|
-
|
|
16712
|
-
// --- Health check on load ---
|
|
16713
|
-
async function checkHealth() {
|
|
16714
|
-
const r = await api('GET', '/health');
|
|
16715
|
-
if (r.ok) {
|
|
16716
|
-
statusDot.classList.add('ok');
|
|
16717
|
-
statusText.textContent = 'Connected';
|
|
16718
|
-
} else {
|
|
16719
|
-
statusDot.classList.remove('ok');
|
|
16720
|
-
statusText.textContent = 'Disconnected';
|
|
16721
|
-
}
|
|
16722
|
-
}
|
|
16723
|
-
|
|
16724
|
-
// --- Session ---
|
|
16725
|
-
async function createSession() {
|
|
16726
|
-
const cwd = cwdInput.value.trim();
|
|
16727
|
-
if (!cwd) { alert('Please enter a working directory'); return; }
|
|
16728
|
-
const r = await api('POST', '/session', { cwd });
|
|
16729
|
-
if (r.ok) {
|
|
16730
|
-
sessionId = r.data.sessionId;
|
|
16731
|
-
sessionInfo.style.display = 'block';
|
|
16732
|
-
sessionIdDisplay.textContent = sessionId;
|
|
16733
|
-
contextUsage.style.display = 'none';
|
|
16734
|
-
lastLoggedContextPct = -1;
|
|
16735
|
-
enablePrompt(true);
|
|
16736
|
-
chatArea.innerHTML = '';
|
|
16737
|
-
currentAssistantBubble = null;
|
|
16738
|
-
pendingPerms.clear();
|
|
16739
|
-
renderPermissions();
|
|
16740
|
-
if (r.data.attached) {
|
|
16741
|
-
addChatMeta('Attached to existing session');
|
|
16742
|
-
} else {
|
|
16743
|
-
addChatMeta('New session created');
|
|
16744
|
-
}
|
|
16745
|
-
connectSSE();
|
|
16746
|
-
} else {
|
|
16747
|
-
const msg = r.data.error || 'session creation failed (' + r.status + ')';
|
|
16748
|
-
addChatMeta('Error: ' + msg);
|
|
16749
|
-
if (r.status === 401) highlightTokenInput('Token required or invalid');
|
|
16750
|
-
}
|
|
16751
|
-
}
|
|
16752
|
-
|
|
16753
|
-
function enablePrompt(on) {
|
|
16754
|
-
$('#btnSendPrompt').disabled = !on;
|
|
16755
|
-
$('#btnCancel').disabled = !on;
|
|
16756
|
-
$('#btnSetModel').disabled = !on;
|
|
16757
|
-
chatInput.disabled = !on;
|
|
16758
|
-
$('#btnChatSend').disabled = !on;
|
|
16759
|
-
}
|
|
16760
|
-
|
|
16761
|
-
// --- SSE ---
|
|
16762
|
-
function connectSSE() {
|
|
16763
|
-
if (eventSource) { eventSource.close(); }
|
|
16764
|
-
const url = BASE + '/session/' + sessionId + '/events';
|
|
16765
|
-
logEvent('SSE', 'Connecting to ' + url);
|
|
16766
|
-
|
|
16767
|
-
// Use fetch-based SSE to avoid Origin header issues with EventSource
|
|
16768
|
-
const abort = new AbortController();
|
|
16769
|
-
eventSource = { close: () => abort.abort() };
|
|
16770
|
-
|
|
16771
|
-
(async function readSSE() {
|
|
16772
|
-
try {
|
|
16773
|
-
const hdrs = authHeaders();
|
|
16774
|
-
const res = await fetch(url, { signal: abort.signal, headers: hdrs });
|
|
16775
|
-
if (!res.ok) {
|
|
16776
|
-
logEvent('SSE-ERR', 'HTTP ' + res.status);
|
|
16777
|
-
statusDot.classList.remove('ok');
|
|
16778
|
-
statusText.textContent = 'SSE failed (' + res.status + ')';
|
|
16779
|
-
enablePrompt(false);
|
|
16780
|
-
if (res.status === 401) {
|
|
16781
|
-
highlightTokenInput('SSE returned 401 \u2014 enter your bearer token and recreate the session');
|
|
16782
|
-
}
|
|
16783
|
-
return;
|
|
16784
|
-
}
|
|
16785
|
-
const reader = res.body.getReader();
|
|
16786
|
-
const decoder = new TextDecoder();
|
|
16787
|
-
let buffer = '';
|
|
16788
|
-
let currentEvent = {};
|
|
16789
|
-
|
|
16790
|
-
while (true) {
|
|
16791
|
-
const { done, value } = await reader.read();
|
|
16792
|
-
if (done) break;
|
|
16793
|
-
buffer += decoder.decode(value, { stream: true });
|
|
16794
|
-
|
|
16795
|
-
const lines = buffer.split('\\n');
|
|
16796
|
-
buffer = lines.pop();
|
|
16797
|
-
|
|
16798
|
-
for (const line of lines) {
|
|
16799
|
-
if (line.startsWith('data: ')) {
|
|
16800
|
-
currentEvent.data = line.slice(6);
|
|
16801
|
-
} else if (line.startsWith('event: ')) {
|
|
16802
|
-
currentEvent.event = line.slice(7);
|
|
16803
|
-
} else if (line.startsWith('id: ')) {
|
|
16804
|
-
currentEvent.id = line.slice(4);
|
|
16805
|
-
} else if (line === '') {
|
|
16806
|
-
if (currentEvent.data) {
|
|
16807
|
-
handleSSEMessage(currentEvent);
|
|
16808
|
-
}
|
|
16809
|
-
currentEvent = {};
|
|
16810
|
-
}
|
|
16811
|
-
}
|
|
16812
|
-
}
|
|
16813
|
-
// Process any remaining buffered data
|
|
16814
|
-
if (currentEvent.data) handleSSEMessage(currentEvent);
|
|
16815
|
-
statusDot.classList.remove('ok');
|
|
16816
|
-
statusText.textContent = 'SSE stream ended';
|
|
16817
|
-
enablePrompt(false);
|
|
16818
|
-
logEvent('SSE', 'Stream ended by server');
|
|
16819
|
-
} catch (err) {
|
|
16820
|
-
if (err.name !== 'AbortError') {
|
|
16821
|
-
logEvent('SSE-ERR', err.message);
|
|
16822
|
-
statusDot.classList.remove('ok');
|
|
16823
|
-
statusText.textContent = 'SSE error';
|
|
16824
|
-
enablePrompt(false);
|
|
16825
|
-
}
|
|
16826
|
-
}
|
|
16827
|
-
})();
|
|
16828
|
-
}
|
|
16829
|
-
|
|
16830
|
-
function handleSSEMessage(msg) {
|
|
16831
|
-
let data;
|
|
16832
|
-
try { data = JSON.parse(msg.data); } catch { data = msg.data; }
|
|
16833
|
-
const type = data.type || msg.event || 'unknown';
|
|
16834
|
-
|
|
16835
|
-
if (type === 'session_update' && data.data) {
|
|
16836
|
-
const update = data.data.update || data.data;
|
|
16837
|
-
const kind = update.sessionUpdate;
|
|
16838
|
-
|
|
16839
|
-
if (kind === 'agent_message_chunk') {
|
|
16840
|
-
const text = update.content?.text || '';
|
|
16841
|
-
if (text) appendAssistantChunk(text);
|
|
16842
|
-
if (update._meta?.usage) {
|
|
16843
|
-
const u = update._meta.usage;
|
|
16844
|
-
addChatMeta('tokens: in=' + u.inputTokens + ' out=' + u.outputTokens + ' | ' + (update._meta.durationMs || 0) + 'ms');
|
|
16845
|
-
currentAssistantBubble = null;
|
|
16846
|
-
}
|
|
16847
|
-
logEvent('MSG', text || '(usage meta)');
|
|
16848
|
-
} else if (kind === 'agent_thought_chunk') {
|
|
16849
|
-
const text = update.content?.text || '';
|
|
16850
|
-
currentThought += text;
|
|
16851
|
-
logEvent('THINK', text);
|
|
16852
|
-
} else if (kind === 'usage_update') {
|
|
16853
|
-
// One frame per model round: a long agentic turn (/review) emits
|
|
16854
|
-
// hundreds, and the raw-JSON fallthrough below turned the Events tab
|
|
16855
|
-
// into a scroll of identical lines. Render an in-place meter instead,
|
|
16856
|
-
// and log only when the integer percentage moves \u2014 the transitions
|
|
16857
|
-
// stay on record without the flood.
|
|
16858
|
-
const used = update.used;
|
|
16859
|
-
const size = update.size;
|
|
16860
|
-
if (typeof used === 'number' && typeof size === 'number' && size > 0) {
|
|
16861
|
-
const pct = Math.round((used / size) * 100);
|
|
16862
|
-
const label = used + ' / ' + size + ' (' + pct + '%)';
|
|
16863
|
-
contextUsage.style.display = 'block';
|
|
16864
|
-
contextUsage.textContent = 'Context: ' + label;
|
|
16865
|
-
if (pct !== lastLoggedContextPct) {
|
|
16866
|
-
lastLoggedContextPct = pct;
|
|
16867
|
-
logEvent('CTX', label);
|
|
16868
|
-
}
|
|
16869
|
-
}
|
|
16870
|
-
} else {
|
|
16871
|
-
logEvent(kind || type, JSON.stringify(update));
|
|
16872
|
-
}
|
|
16873
|
-
} else if (type === 'permission_request') {
|
|
16874
|
-
handlePermissionRequest(data);
|
|
16875
|
-
logEvent('PERM', JSON.stringify(data.data));
|
|
16876
|
-
} else if (type === 'permission_resolved') {
|
|
16877
|
-
logEvent('PERM-OK', JSON.stringify(data.data));
|
|
16878
|
-
removePermission(data.data?.requestId);
|
|
16879
|
-
} else if (type === 'session_died') {
|
|
16880
|
-
addChatMeta('Session died: ' + JSON.stringify(data.data));
|
|
16881
|
-
logEvent('DIED', JSON.stringify(data.data));
|
|
16882
|
-
enablePrompt(false);
|
|
16883
|
-
} else if (type === 'model_switched') {
|
|
16884
|
-
addChatMeta('Model switched: ' + JSON.stringify(data.data));
|
|
16885
|
-
logEvent('MODEL', JSON.stringify(data.data));
|
|
16886
|
-
} else {
|
|
16887
|
-
logEvent(type, JSON.stringify(data));
|
|
16888
|
-
}
|
|
16889
|
-
}
|
|
16890
|
-
|
|
16891
|
-
// --- Chat UI ---
|
|
16892
|
-
function addUserMessage(text) {
|
|
16893
|
-
currentAssistantBubble = null;
|
|
16894
|
-
currentThought = '';
|
|
16895
|
-
const el = document.createElement('div');
|
|
16896
|
-
el.className = 'chat-msg user';
|
|
16897
|
-
el.innerHTML = '<div class="bubble">' + escHtml(text) + '</div>';
|
|
16898
|
-
chatArea.appendChild(el);
|
|
16899
|
-
chatArea.scrollTop = chatArea.scrollHeight;
|
|
16900
|
-
}
|
|
16901
|
-
|
|
16902
|
-
function appendAssistantChunk(text) {
|
|
16903
|
-
if (!currentAssistantBubble) {
|
|
16904
|
-
if (currentThought) {
|
|
16905
|
-
const te = document.createElement('div');
|
|
16906
|
-
te.className = 'chat-msg assistant';
|
|
16907
|
-
te.innerHTML = '<div class="bubble" style="color:var(--text2);font-style:italic;border-color:var(--border)">Thinking: ' + escHtml(currentThought) + '</div>';
|
|
16908
|
-
chatArea.appendChild(te);
|
|
16909
|
-
currentThought = '';
|
|
16910
|
-
}
|
|
16911
|
-
const el = document.createElement('div');
|
|
16912
|
-
el.className = 'chat-msg assistant';
|
|
16913
|
-
el.innerHTML = '<div class="bubble"></div>';
|
|
16914
|
-
chatArea.appendChild(el);
|
|
16915
|
-
currentAssistantBubble = el.querySelector('.bubble');
|
|
16916
|
-
}
|
|
16917
|
-
currentAssistantBubble.textContent += text;
|
|
16918
|
-
chatArea.scrollTop = chatArea.scrollHeight;
|
|
16919
|
-
}
|
|
16920
|
-
|
|
16921
|
-
function addChatMeta(text) {
|
|
16922
|
-
const el = document.createElement('div');
|
|
16923
|
-
el.className = 'chat-msg assistant';
|
|
16924
|
-
el.innerHTML = '<div class="meta">' + escHtml(text) + '</div>';
|
|
16925
|
-
chatArea.appendChild(el);
|
|
16926
|
-
chatArea.scrollTop = chatArea.scrollHeight;
|
|
16927
|
-
}
|
|
16928
|
-
|
|
16929
|
-
// --- Prompt ---
|
|
16930
|
-
let promptInFlight = false;
|
|
16931
|
-
async function sendPrompt(text) {
|
|
16932
|
-
if (!sessionId || !text.trim() || promptInFlight) return;
|
|
16933
|
-
promptInFlight = true;
|
|
16934
|
-
enablePrompt(false);
|
|
16935
|
-
addUserMessage(text.trim());
|
|
16936
|
-
promptInput.value = '';
|
|
16937
|
-
chatInput.value = '';
|
|
16938
|
-
try {
|
|
16939
|
-
const r = await api('POST', '/session/' + sessionId + '/prompt', {
|
|
16940
|
-
prompt: [{ type: 'text', text: text.trim() }]
|
|
16941
|
-
});
|
|
16942
|
-
if (r.ok) {
|
|
16943
|
-
addChatMeta('stopReason: ' + (r.data.stopReason || 'unknown'));
|
|
16944
|
-
} else {
|
|
16945
|
-
addChatMeta('Error: ' + (r.data.error || 'prompt failed (' + r.status + ')'));
|
|
16946
|
-
}
|
|
16947
|
-
} finally {
|
|
16948
|
-
promptInFlight = false;
|
|
16949
|
-
if (sessionId) enablePrompt(true);
|
|
16950
|
-
}
|
|
16951
|
-
}
|
|
16952
|
-
|
|
16953
|
-
// --- Permission handling ---
|
|
16954
|
-
const pendingPerms = new Map();
|
|
16955
|
-
|
|
16956
|
-
function handlePermissionRequest(data) {
|
|
16957
|
-
const req = data.data;
|
|
16958
|
-
const requestId = req?.requestId;
|
|
16959
|
-
if (!requestId) return;
|
|
16960
|
-
pendingPerms.set(requestId, req);
|
|
16961
|
-
renderPermissions();
|
|
16962
|
-
|
|
16963
|
-
addChatMeta('Permission requested: ' + requestId);
|
|
16964
|
-
}
|
|
16965
|
-
|
|
16966
|
-
function removePermission(requestId) {
|
|
16967
|
-
pendingPerms.delete(requestId);
|
|
16968
|
-
renderPermissions();
|
|
16969
|
-
}
|
|
16970
|
-
|
|
16971
|
-
function renderPermissions() {
|
|
16972
|
-
if (pendingPerms.size === 0) {
|
|
16973
|
-
permissionPanel.style.display = 'none';
|
|
16974
|
-
return;
|
|
16975
|
-
}
|
|
16976
|
-
permissionPanel.style.display = 'block';
|
|
16977
|
-
permissionList.innerHTML = '';
|
|
16978
|
-
for (const [id, req] of pendingPerms) {
|
|
16979
|
-
const card = document.createElement('div');
|
|
16980
|
-
card.className = 'permission-card';
|
|
16981
|
-
|
|
16982
|
-
const h4 = document.createElement('h4');
|
|
16983
|
-
h4.textContent = req.tool?.name || 'Permission';
|
|
16984
|
-
card.appendChild(h4);
|
|
16985
|
-
|
|
16986
|
-
const idDiv = document.createElement('div');
|
|
16987
|
-
idDiv.style.cssText = 'font-size:11px;color:var(--text2);margin-bottom:6px';
|
|
16988
|
-
idDiv.textContent = id;
|
|
16989
|
-
card.appendChild(idDiv);
|
|
16990
|
-
|
|
16991
|
-
// Show toolCall context (command, input, path, etc.) when available
|
|
16992
|
-
const tc = req.toolCall || req.tool;
|
|
16993
|
-
if (tc) {
|
|
16994
|
-
const detail = document.createElement('pre');
|
|
16995
|
-
detail.style.cssText = 'font-size:11px;color:var(--text2);margin-bottom:6px;white-space:pre-wrap;word-break:break-all;max-height:120px;overflow-y:auto;background:var(--bg);padding:6px;border-radius:4px;border:1px solid var(--border)';
|
|
16996
|
-
const parts = [];
|
|
16997
|
-
if (tc.command) parts.push('command: ' + tc.command);
|
|
16998
|
-
if (tc.input) parts.push('input: ' + (typeof tc.input === 'string' ? tc.input : JSON.stringify(tc.input, null, 2)));
|
|
16999
|
-
if (tc.path) parts.push('path: ' + tc.path);
|
|
17000
|
-
if (tc.diff) parts.push('diff: ' + tc.diff);
|
|
17001
|
-
if (tc.serverUrl) parts.push('url: ' + tc.serverUrl);
|
|
17002
|
-
if (parts.length === 0 && tc.name) parts.push('tool: ' + tc.name);
|
|
17003
|
-
if (parts.length > 0) {
|
|
17004
|
-
detail.textContent = parts.join('\\n');
|
|
17005
|
-
card.appendChild(detail);
|
|
17006
|
-
}
|
|
17007
|
-
}
|
|
17008
|
-
|
|
17009
|
-
function makePermBtn(reqId, optId, label, isCancel) {
|
|
17010
|
-
const btn = document.createElement('button');
|
|
17011
|
-
btn.className = 'btn opt-btn';
|
|
17012
|
-
btn.textContent = label;
|
|
17013
|
-
btn.dataset.req = reqId;
|
|
17014
|
-
if (isCancel) {
|
|
17015
|
-
btn.dataset.cancel = '1';
|
|
17016
|
-
btn.style.borderColor = 'var(--err)';
|
|
17017
|
-
btn.style.color = 'var(--err)';
|
|
17018
|
-
} else {
|
|
17019
|
-
btn.dataset.opt = optId;
|
|
17020
|
-
}
|
|
17021
|
-
btn.addEventListener('click', async () => {
|
|
17022
|
-
let outcome;
|
|
17023
|
-
if (isCancel) {
|
|
17024
|
-
outcome = { outcome: 'cancelled' };
|
|
17025
|
-
} else {
|
|
17026
|
-
outcome = { outcome: 'selected', optionId: optId };
|
|
17027
|
-
}
|
|
17028
|
-
const result = await api('POST', '/permission/' + reqId, { outcome });
|
|
17029
|
-
if (result.ok) {
|
|
17030
|
-
removePermission(reqId);
|
|
17031
|
-
} else {
|
|
17032
|
-
logError('PERM-ERR', 'Failed to resolve permission ' + reqId + ': ' + JSON.stringify(result.data));
|
|
17033
|
-
}
|
|
17034
|
-
});
|
|
17035
|
-
return btn;
|
|
17036
|
-
}
|
|
17037
|
-
|
|
17038
|
-
if (req.options && Array.isArray(req.options)) {
|
|
17039
|
-
for (const opt of req.options) {
|
|
17040
|
-
card.appendChild(makePermBtn(id, opt.optionId, opt.name || opt.optionId, false));
|
|
17041
|
-
}
|
|
17042
|
-
}
|
|
17043
|
-
card.appendChild(makePermBtn(id, null, 'Cancel', true));
|
|
17044
|
-
permissionList.appendChild(card);
|
|
17045
|
-
}
|
|
17046
|
-
}
|
|
17047
|
-
|
|
17048
|
-
// --- Button bindings ---
|
|
17049
|
-
$('#btnCreateSession').addEventListener('click', createSession);
|
|
17050
|
-
$('#btnListSessions').addEventListener('click', async () => {
|
|
17051
|
-
const cwd = cwdInput.value.trim();
|
|
17052
|
-
if (!cwd) { alert('Enter a cwd first'); return; }
|
|
17053
|
-
await api('GET', '/workspace/' + encodeURIComponent(cwd) + '/sessions');
|
|
17054
|
-
});
|
|
17055
|
-
$('#btnSendPrompt').addEventListener('click', () => sendPrompt(promptInput.value));
|
|
17056
|
-
$('#btnChatSend').addEventListener('click', () => sendPrompt(chatInput.value));
|
|
17057
|
-
chatInput.addEventListener('keydown', (e) => {
|
|
17058
|
-
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendPrompt(chatInput.value); }
|
|
17059
|
-
});
|
|
17060
|
-
promptInput.addEventListener('keydown', (e) => {
|
|
17061
|
-
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendPrompt(promptInput.value); }
|
|
17062
|
-
});
|
|
17063
|
-
$('#btnCancel').addEventListener('click', async () => {
|
|
17064
|
-
if (!sessionId) return;
|
|
17065
|
-
await api('POST', '/session/' + sessionId + '/cancel', {});
|
|
17066
|
-
});
|
|
17067
|
-
$('#btnSetModel').addEventListener('click', async () => {
|
|
17068
|
-
if (!sessionId) return;
|
|
17069
|
-
const mid = modelInput.value.trim();
|
|
17070
|
-
if (!mid) { alert('Enter a model ID'); return; }
|
|
17071
|
-
await api('POST', '/session/' + sessionId + '/model', { modelId: mid });
|
|
17072
|
-
});
|
|
17073
|
-
$('#btnHealth').addEventListener('click', () => api('GET', '/health'));
|
|
17074
|
-
$('#btnHealthDeep').addEventListener('click', () => api('GET', '/health?deep=1'));
|
|
17075
|
-
$('#btnCaps').addEventListener('click', () => api('GET', '/capabilities'));
|
|
17076
|
-
|
|
17077
|
-
// --- Init ---
|
|
17078
|
-
checkHealth();
|
|
17079
|
-
})();
|
|
17080
|
-
</script>
|
|
17081
|
-
</body>
|
|
17082
|
-
</html>`
|
|
17083
|
-
);
|
|
17084
|
-
}
|
|
17085
|
-
__name(getDemoHtml, "getDemoHtml");
|
|
17086
|
-
|
|
17087
|
-
// packages/cli/src/serve/routes/health-demo.ts
|
|
17088
|
-
function createHealthDemoRoutes(deps) {
|
|
17089
|
-
const {
|
|
17090
|
-
opts,
|
|
17091
|
-
getPort,
|
|
17092
|
-
workspaceRegistry,
|
|
17093
|
-
getActiveSseCount: getActiveSseCount2,
|
|
17094
|
-
getRateLimiter
|
|
17095
|
-
} = deps;
|
|
17096
|
-
const demoHandler = /* @__PURE__ */ __name((_req, res) => {
|
|
17097
|
-
try {
|
|
17098
|
-
res.type("html").set("X-Frame-Options", "DENY").set(
|
|
17099
|
-
"Content-Security-Policy",
|
|
17100
|
-
"default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; connect-src 'self'; frame-ancestors 'none'"
|
|
17101
|
-
).send(getDemoHtml(getPort()));
|
|
17102
|
-
} catch (err) {
|
|
17103
|
-
writeStderrLine(
|
|
17104
|
-
`qwen serve: /demo render failed: ${err instanceof Error ? err.message : String(err)}`
|
|
17105
|
-
);
|
|
17106
|
-
res.status(500).json({ error: "Failed to render demo page" });
|
|
17107
|
-
}
|
|
17108
|
-
}, "demoHandler");
|
|
16570
|
+
function createHealthRoutes(deps) {
|
|
16571
|
+
const { opts, workspaceRegistry, getActiveSseCount: getActiveSseCount2, getRateLimiter } = deps;
|
|
17109
16572
|
const healthHandler = /* @__PURE__ */ __name((req, res) => {
|
|
17110
16573
|
if (!isDeepHealthQuery(req.query["deep"])) {
|
|
17111
16574
|
res.status(200).json({ status: "ok" });
|
|
@@ -17195,11 +16658,10 @@ function createHealthDemoRoutes(deps) {
|
|
|
17195
16658
|
exposeHealthPreAuth,
|
|
17196
16659
|
register(app) {
|
|
17197
16660
|
app.get("/health", healthHandler);
|
|
17198
|
-
app.get("/demo", demoHandler);
|
|
17199
16661
|
}
|
|
17200
16662
|
};
|
|
17201
16663
|
}
|
|
17202
|
-
__name(
|
|
16664
|
+
__name(createHealthRoutes, "createHealthRoutes");
|
|
17203
16665
|
|
|
17204
16666
|
// packages/cli/src/serve/routes/workspace-auth.ts
|
|
17205
16667
|
init_esbuild_shims();
|
|
@@ -39862,11 +39324,13 @@ var execFileAsync3 = promisify3(execFile3);
|
|
|
39862
39324
|
var LIVE_HOST_BUNDLE_ID2 = "com.alibaba.qwen-code.live-host";
|
|
39863
39325
|
var LIVE_HOST_TEAM_IDENTIFIER = "NF4574S59H";
|
|
39864
39326
|
var LIVE_HOST_APP_PATH = "/Applications/Qwen Live Host.app";
|
|
39327
|
+
var LIVE_HOST_OSS_BASE_URL = "https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/live-host";
|
|
39865
39328
|
var LIVE_HOST_RELEASE_BASE_URL = "https://github.com/QwenLM/qwen-code/releases/download/live-host-latest";
|
|
39866
39329
|
var LIVE_HOST_MANIFEST_NAME = "Qwen-Live-Host-manifest.json";
|
|
39330
|
+
var LIVE_HOST_MANIFEST_FETCH_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
39331
|
+
var LIVE_HOST_DOWNLOAD_TIMEOUT_MS = 60 * 60 * 1e3;
|
|
39867
39332
|
var LIVE_HOST_APP_NAME = "Qwen Live Host.app";
|
|
39868
39333
|
var MAX_DOWNLOAD_BYTES = 512 * 1024 * 1024;
|
|
39869
|
-
var FETCH_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
39870
39334
|
var COMMAND_TIMEOUT_MS = 2 * 60 * 1e3;
|
|
39871
39335
|
var SHA256_PATTERN = /^[a-f0-9]{64}$/;
|
|
39872
39336
|
var VERSION_PATTERN = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
|
|
@@ -39982,11 +39446,24 @@ async function inspectInstalledHost() {
|
|
|
39982
39446
|
}
|
|
39983
39447
|
}
|
|
39984
39448
|
__name(inspectInstalledHost, "inspectInstalledHost");
|
|
39985
|
-
|
|
39986
|
-
|
|
39987
|
-
`${
|
|
39988
|
-
{
|
|
39989
|
-
|
|
39449
|
+
function resolveLiveHostManifestUrls() {
|
|
39450
|
+
return [
|
|
39451
|
+
`${LIVE_HOST_OSS_BASE_URL}/latest/${LIVE_HOST_MANIFEST_NAME}`,
|
|
39452
|
+
`${LIVE_HOST_RELEASE_BASE_URL}/${LIVE_HOST_MANIFEST_NAME}`
|
|
39453
|
+
];
|
|
39454
|
+
}
|
|
39455
|
+
__name(resolveLiveHostManifestUrls, "resolveLiveHostManifestUrls");
|
|
39456
|
+
function resolveLiveHostAssetUrls(version, assetName) {
|
|
39457
|
+
return [
|
|
39458
|
+
`${LIVE_HOST_OSS_BASE_URL}/v${version}/${assetName}`,
|
|
39459
|
+
`${LIVE_HOST_RELEASE_BASE_URL}/${assetName}`
|
|
39460
|
+
];
|
|
39461
|
+
}
|
|
39462
|
+
__name(resolveLiveHostAssetUrls, "resolveLiveHostAssetUrls");
|
|
39463
|
+
async function fetchManifest(url, fetchImpl) {
|
|
39464
|
+
const response = await fetchImpl(url, {
|
|
39465
|
+
signal: AbortSignal.timeout(LIVE_HOST_MANIFEST_FETCH_TIMEOUT_MS)
|
|
39466
|
+
});
|
|
39990
39467
|
if (!response.ok) {
|
|
39991
39468
|
await response.body?.cancel().catch(() => {
|
|
39992
39469
|
});
|
|
@@ -39995,9 +39472,9 @@ async function fetchManifest() {
|
|
|
39995
39472
|
return parseLiveHostReleaseManifest(await response.json());
|
|
39996
39473
|
}
|
|
39997
39474
|
__name(fetchManifest, "fetchManifest");
|
|
39998
|
-
async function downloadAsset(asset, destination, onProgress) {
|
|
39999
|
-
const response = await
|
|
40000
|
-
signal: AbortSignal.timeout(
|
|
39475
|
+
async function downloadAsset(asset, url, destination, onProgress, fetchImpl) {
|
|
39476
|
+
const response = await fetchImpl(url, {
|
|
39477
|
+
signal: AbortSignal.timeout(LIVE_HOST_DOWNLOAD_TIMEOUT_MS)
|
|
40001
39478
|
});
|
|
40002
39479
|
if (!response.ok || !response.body) {
|
|
40003
39480
|
await response.body?.cancel().catch(() => {
|
|
@@ -40034,13 +39511,36 @@ async function downloadAsset(asset, destination, onProgress) {
|
|
|
40034
39511
|
}
|
|
40035
39512
|
}
|
|
40036
39513
|
__name(downloadAsset, "downloadAsset");
|
|
39514
|
+
async function downloadLiveHostRelease(currentArchitecture, destination, onProgress, fetchImpl = fetch) {
|
|
39515
|
+
const manifestUrls = resolveLiveHostManifestUrls();
|
|
39516
|
+
const labels = ["OSS", "GitHub"];
|
|
39517
|
+
const errors = [];
|
|
39518
|
+
for (let index = 0; index < manifestUrls.length; index += 1) {
|
|
39519
|
+
try {
|
|
39520
|
+
await fsp5.rm(destination, { force: true });
|
|
39521
|
+
const manifest = await fetchManifest(manifestUrls[index], fetchImpl);
|
|
39522
|
+
const asset = manifest.assets[currentArchitecture];
|
|
39523
|
+
const assetUrl = resolveLiveHostAssetUrls(manifest.version, asset.name)[index];
|
|
39524
|
+
await downloadAsset(asset, assetUrl, destination, onProgress, fetchImpl);
|
|
39525
|
+
return { manifest, asset };
|
|
39526
|
+
} catch (error2) {
|
|
39527
|
+
errors.push(
|
|
39528
|
+
new Error(`${labels[index]}: ${errorMessage3(error2)}`, { cause: error2 })
|
|
39529
|
+
);
|
|
39530
|
+
}
|
|
39531
|
+
}
|
|
39532
|
+
await fsp5.rm(destination, { force: true });
|
|
39533
|
+
throw new AggregateError(
|
|
39534
|
+
errors,
|
|
39535
|
+
`Qwen Live Host download failed. ${errors.map((error2) => error2.message).join(" ")}`
|
|
39536
|
+
);
|
|
39537
|
+
}
|
|
39538
|
+
__name(downloadLiveHostRelease, "downloadLiveHostRelease");
|
|
40037
39539
|
async function installLatestHost(currentArchitecture, onStatus) {
|
|
40038
|
-
const manifest = await fetchManifest();
|
|
40039
|
-
const asset = manifest.assets[currentArchitecture];
|
|
40040
39540
|
const temporaryDirectory = await fsp5.mkdtemp(
|
|
40041
39541
|
path14.join(os2.tmpdir(), "qwen-live-host-")
|
|
40042
39542
|
);
|
|
40043
|
-
const archivePath = path14.join(temporaryDirectory,
|
|
39543
|
+
const archivePath = path14.join(temporaryDirectory, "Qwen-Live-Host.zip");
|
|
40044
39544
|
const extractedPath = path14.join(temporaryDirectory, "extracted");
|
|
40045
39545
|
const candidatePath = path14.join(extractedPath, LIVE_HOST_APP_NAME);
|
|
40046
39546
|
const stagingPath = `/Applications/.Qwen Live Host.install-${randomUUID11()}.app`;
|
|
@@ -40049,9 +39549,13 @@ async function installLatestHost(currentArchitecture, onStatus) {
|
|
|
40049
39549
|
let installedCandidate = false;
|
|
40050
39550
|
try {
|
|
40051
39551
|
onStatus({ state: "downloading", progress: 0 });
|
|
40052
|
-
|
|
40053
|
-
|
|
40054
|
-
|
|
39552
|
+
const { manifest } = await downloadLiveHostRelease(
|
|
39553
|
+
currentArchitecture,
|
|
39554
|
+
archivePath,
|
|
39555
|
+
(progress) => {
|
|
39556
|
+
onStatus({ state: "downloading", progress });
|
|
39557
|
+
}
|
|
39558
|
+
);
|
|
40055
39559
|
onStatus({ state: "verifying" });
|
|
40056
39560
|
await fsp5.mkdir(extractedPath, { mode: 448 });
|
|
40057
39561
|
await run("/usr/bin/ditto", ["-x", "-k", archivePath, extractedPath]);
|
|
@@ -43116,9 +42620,12 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
43116
42620
|
// that don't inject `deps.bridge` get daemon env + preflight cells.
|
|
43117
42621
|
statusProvider,
|
|
43118
42622
|
delegateReadTextFileToClient: false,
|
|
43119
|
-
// Final ACP text writes remain delegated
|
|
42623
|
+
// Final ACP text writes remain delegated. Workspace writes use WFS;
|
|
42624
|
+
// marked same-host tool writes may use the factory's host writer.
|
|
43120
42625
|
// Unexpected delegated reads still fail closed at the WFS boundary.
|
|
43121
|
-
fileSystem: createBridgeFileSystemAdapter(fsFactory
|
|
42626
|
+
fileSystem: createBridgeFileSystemAdapter(fsFactory, {
|
|
42627
|
+
allowSameHostToolWritesOutsideWorkspace: deps.fsFactory === void 0
|
|
42628
|
+
}),
|
|
43122
42629
|
// Reverse tool channel: answer the child's `client_mcp/message`
|
|
43123
42630
|
// ext-method by reaching the WS connection that hosts the named server.
|
|
43124
42631
|
clientMcpSender: clientMcpSenderRegistry.lookup
|
|
@@ -43555,15 +43062,14 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
43555
43062
|
mount: false,
|
|
43556
43063
|
workspaceQualifiedAcpEnabled
|
|
43557
43064
|
});
|
|
43558
|
-
const
|
|
43065
|
+
const healthRoutes = createHealthRoutes({
|
|
43559
43066
|
opts,
|
|
43560
|
-
getPort,
|
|
43561
43067
|
workspaceRegistry,
|
|
43562
43068
|
getActiveSseCount,
|
|
43563
43069
|
getRateLimiter: /* @__PURE__ */ __name(() => rateLimiter, "getRateLimiter")
|
|
43564
43070
|
});
|
|
43565
|
-
if (
|
|
43566
|
-
|
|
43071
|
+
if (healthRoutes.exposeHealthPreAuth) {
|
|
43072
|
+
healthRoutes.register(app);
|
|
43567
43073
|
}
|
|
43568
43074
|
installAccessLogMiddleware(app, daemonLog);
|
|
43569
43075
|
const webShellDir = opts.serveWebShell !== false ? deps.webShellDir : void 0;
|
|
@@ -43610,8 +43116,8 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
43610
43116
|
if (rateLimiter) {
|
|
43611
43117
|
app.use(rateLimiter.middleware);
|
|
43612
43118
|
}
|
|
43613
|
-
if (!
|
|
43614
|
-
|
|
43119
|
+
if (!healthRoutes.exposeHealthPreAuth) {
|
|
43120
|
+
healthRoutes.register(app);
|
|
43615
43121
|
}
|
|
43616
43122
|
installJsonBodyParser(app);
|
|
43617
43123
|
const mutate = createMutationGate({
|