@qwen-code/qwen-code 0.19.5 → 0.19.6
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/dataviz/SKILL.md +50 -0
- package/bundled/dataviz/references/anti-patterns.md +12 -0
- package/bundled/dataviz/references/choosing-a-form.md +16 -0
- package/bundled/dataviz/references/palette.md +57 -0
- package/bundled/dataviz/scripts/validate_palette.js +328 -0
- package/bundled/loop/SKILL.md +1 -1
- package/bundled/qc-helper/docs/configuration/settings.md +9 -8
- package/bundled/qc-helper/docs/features/headless.md +2 -2
- package/bundled/qc-helper/docs/features/scheduled-tasks.md +4 -2
- package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +1 -1
- package/chunks/{MaxSizedBox-5JV77KRA.js → MaxSizedBox-SK7CUWZQ.js} +14 -14
- package/chunks/{StandaloneSessionPicker-MGUGB6PH.js → StandaloneSessionPicker-G44HGSAP.js} +25 -25
- package/chunks/{acpAgent-4F36XM3X.js → acpAgent-PKCTYWJV.js} +346 -131
- package/chunks/{agent-IWBUZI6A.js → agent-IYMHUXWB.js} +11 -11
- package/chunks/{agent-headless-JUTICAYO.js → agent-headless-L2DAW6I5.js} +11 -11
- package/chunks/{anthropicContentGenerator-WL3LJOUB.js → anthropicContentGenerator-H5ZOEENQ.js} +2 -2
- package/chunks/{artifact-tool-W76WC2JX.js → artifact-tool-SLYPWG3C.js} +15 -2
- package/chunks/{askUserQuestion-J3P6TH3V.js → askUserQuestion-OKPTECON.js} +1 -1
- package/chunks/{bridge-DHZHQ4UV.js → bridge-DF3IJQ5V.js} +17 -16
- package/chunks/{channel-worker-supervisor-EVPAYNZ5.js → channel-worker-supervisor-JUYQ5Z4R.js} +5 -5
- package/chunks/chunk-2INJBYLJ.js +949 -0
- package/chunks/chunk-3RW4AZJV.js +5063 -0
- package/chunks/{chunk-NSSVORTQ.js → chunk-3UC7ZC43.js} +16 -12
- package/chunks/chunk-3VJ7MT3N.js +111 -0
- package/chunks/{chunk-DRS2HTNT.js → chunk-3X76L4UF.js} +5 -5
- package/chunks/{chunk-PPFWEV7G.js → chunk-4RQIB5UZ.js} +62 -62
- package/chunks/{chunk-EROWZQN7.js → chunk-57NRQM3P.js} +6 -6
- package/chunks/{chunk-L7OJ3ZO3.js → chunk-5ES5YPED.js} +1 -1
- package/chunks/{chunk-RNGAT2Y2.js → chunk-5WQF27GW.js} +1 -1
- package/chunks/{chunk-7DMQRPC7.js → chunk-6BEOH4KK.js} +1 -1
- package/chunks/{chunk-CXBG27SF.js → chunk-6IAWPIQ6.js} +3 -2
- package/chunks/{chunk-DM4E337C.js → chunk-6QVRLKTZ.js} +4 -4
- package/chunks/{chunk-RM3PGSGL.js → chunk-6SHO7WFF.js} +15 -2
- package/chunks/{chunk-LHMZCIKL.js → chunk-7Z6UEJA4.js} +3 -1
- package/chunks/{chunk-SBMHB6N5.js → chunk-A34EPIUV.js} +12 -12
- package/chunks/{chunk-6QTCOQX7.js → chunk-AGZF43UV.js} +1967 -1399
- package/chunks/{chunk-QHYITL6P.js → chunk-BOAWGUY6.js} +5 -11
- package/chunks/{chunk-TN6RT6EJ.js → chunk-C2QKQZEQ.js} +16 -4
- package/chunks/{chunk-BC4R5C5R.js → chunk-CEYA7K7C.js} +32 -6
- package/chunks/{chunk-R6RI2HIC.js → chunk-CLQPBI4H.js} +40 -13
- package/chunks/{chunk-OQHLUA2Y.js → chunk-DBF3HTLT.js} +3 -3
- package/chunks/{chunk-SJBIFVD2.js → chunk-DMSNJDWG.js} +5 -1
- package/chunks/{chunk-KKQWC6WS.js → chunk-DNV4FSN5.js} +1 -1
- package/chunks/chunk-DXXNMPJH.js +5468 -0
- package/chunks/{chunk-CBJE2PLG.js → chunk-FDY3XOTM.js} +2 -2
- package/chunks/{chunk-NDY7OENU.js → chunk-FPHA7WIZ.js} +2 -2
- package/chunks/{chunk-MNOXKSM2.js → chunk-FZ5NVRVK.js} +1 -1
- package/chunks/{chunk-UJT42DB6.js → chunk-GQBRGBLS.js} +5 -5
- package/chunks/{chunk-Y4UQT3PM.js → chunk-HCFSKO6K.js} +1 -1
- package/chunks/{chunk-2Z43HUXT.js → chunk-HLKG6CZN.js} +3 -2
- package/chunks/{chunk-WALEWZ44.js → chunk-IUSKVKH5.js} +1 -1
- package/chunks/{chunk-XKSCTXPK.js → chunk-J6ABRKAB.js} +2 -1
- package/chunks/{chunk-DX3TKXNT.js → chunk-JA5KWZTJ.js} +1 -1
- package/chunks/{chunk-CHY5C5T4.js → chunk-JN2VJ33O.js} +171 -79
- package/chunks/{chunk-YTFBURQD.js → chunk-KYTQOCDE.js} +1 -1
- package/chunks/{chunk-BPFJQGY7.js → chunk-LM3YCCZJ.js} +164 -5
- package/chunks/{chunk-ZISMVA6U.js → chunk-LXFCHX4X.js} +1371 -24
- package/chunks/{chunk-6KPZJJ6U.js → chunk-MBWLP5OT.js} +9 -9
- package/chunks/{chunk-IMAMNLY6.js → chunk-MHQKYQDS.js} +3 -3
- package/chunks/{chunk-M5ITDKSM.js → chunk-MJKEQSZI.js} +1 -1
- package/chunks/{chunk-MTNTVOJR.js → chunk-MJKMIQMK.js} +5 -2
- package/chunks/{chunk-CSPSJU5R.js → chunk-MX7CTJHR.js} +16 -16
- package/chunks/{chunk-HISPEX42.js → chunk-N2IJLN2L.js} +7 -7
- package/chunks/{chunk-YCU7QV7Q.js → chunk-N4YJQTRL.js} +4 -0
- package/chunks/{chunk-R3UWLLRQ.js → chunk-NUK2PFSU.js} +1 -1
- package/chunks/{chunk-YXK4GPYO.js → chunk-NVFJSIAX.js} +29 -0
- package/chunks/{chunk-4MCC4XHH.js → chunk-O2RJARYU.js} +38 -37
- package/chunks/{chunk-JKGCBO3O.js → chunk-OAYOHSGP.js} +3 -3
- package/chunks/{chunk-G4M7FPNY.js → chunk-OBVBTAX5.js} +1 -1
- package/chunks/{chunk-JJ6B3ZD3.js → chunk-OIFSBXSP.js} +2 -2
- package/chunks/{chunk-NNEJEBCF.js → chunk-QOKV6AO4.js} +30 -21
- package/chunks/{chunk-DG573EOO.js → chunk-RZORUN6X.js} +1 -1
- package/chunks/{chunk-RSBQS6M4.js → chunk-SL2P3JUA.js} +1 -1
- package/chunks/{chunk-K4I4STSL.js → chunk-SOT7OMGL.js} +2 -2
- package/chunks/{chunk-MDBNFHIO.js → chunk-SRNPMG7J.js} +3 -3
- package/chunks/{chunk-SJVPSHXU.js → chunk-UNXGEDX2.js} +4 -4
- package/chunks/{chunk-WZ724G6K.js → chunk-UTL7KABL.js} +5 -5
- package/chunks/{chunk-UY2TCIZS.js → chunk-V5VTULL5.js} +2 -2
- package/chunks/{chunk-Z7XNVNPM.js → chunk-V6NH3CUC.js} +1 -1
- package/chunks/{chunk-J3ERRYYI.js → chunk-WXUDZHOJ.js} +2 -2
- package/chunks/{chunk-2CAII5HD.js → chunk-XH7H6YG4.js} +1 -1
- package/chunks/{chunk-XKZXGIRM.js → chunk-YSU33ACT.js} +2 -2
- package/chunks/{chunk-6QVQZAW6.js → chunk-YTWX5TT2.js} +1 -1
- package/chunks/{chunk-5B2WNM6V.js → chunk-ZI4MGBB5.js} +1 -1
- package/chunks/{chunk-2YH27UNF.js → chunk-ZO5EA3XJ.js} +1 -1
- package/chunks/{computer-use-ON3JQUHW.js → computer-use-5S3NVXRA.js} +11 -11
- package/chunks/{contextCommand-OGCG7W6N.js → contextCommand-DPBALZFK.js} +13 -13
- package/chunks/{cron-create-6YTCOX6P.js → cron-create-7JYUDTUY.js} +20 -5
- package/chunks/{cron-delete-E3NIFSUK.js → cron-delete-YPULQQAK.js} +2 -2
- package/chunks/{cron-list-Q64MNQNE.js → cron-list-HJIW5MHP.js} +2 -2
- package/chunks/{daemon-EEB2RYOL.js → daemon-7XYW4BC3.js} +102 -0
- package/chunks/{daemon-status-provider-P72STMLB.js → daemon-status-provider-2EWTHT7Y.js} +20 -19
- package/chunks/{dist-AP5V4WYU.js → dist-AAO65DPC.js} +2 -2
- package/chunks/{dist-X4ZDE726.js → dist-ABQ7VWRR.js} +3 -3
- package/chunks/{dist-SNXOUPYS.js → dist-AW5ZYMUI.js} +2 -2
- package/chunks/{dist-Z57Q4YF5.js → dist-BV56HW3W.js} +276 -95
- package/chunks/{dist-IZP2VV4C.js → dist-JPSVN367.js} +2 -2
- package/chunks/{earlyInputCapture-DAFHSGVW.js → earlyInputCapture-GGPV4IFT.js} +11 -11
- package/chunks/{edit-3QFNCSZH.js → edit-HJ7ISN4C.js} +12 -12
- package/chunks/{en-M4EBUBNU.js → en-XR3S5VWY.js} +1 -0
- package/chunks/{enter-worktree-62EQQMLD.js → enter-worktree-2BQT675D.js} +11 -11
- package/chunks/{enterPlanMode-VUQSE4EG.js → enterPlanMode-SJXHJ3WD.js} +11 -11
- package/chunks/{errors-PW75PZXE.js → errors-EVGER4AZ.js} +13 -13
- package/chunks/{exit-worktree-VVNH7OVY.js → exit-worktree-RPDDOSPM.js} +11 -11
- package/chunks/{exitPlanMode-RUYRCYZW.js → exitPlanMode-BQEROAJ7.js} +11 -11
- package/chunks/{fast-path-TFRJRTTR.js → fast-path-FX2ICJ2O.js} +3 -3
- package/chunks/{fast-path-settings-UQLRFDQP.js → fast-path-settings-RCRXH2JG.js} +2 -2
- package/chunks/{gemini-XW7ZDUVR.js → gemini-EHUXCOUI.js} +69 -64
- package/chunks/{geminiContentGenerator-MZDVHVZH.js → geminiContentGenerator-YDUUKAM2.js} +1 -1
- package/chunks/{glob-WAY2PUWA.js → glob-3VIGV2DL.js} +11 -11
- package/chunks/{grep-W6CBKSYC.js → grep-4D3S4NUC.js} +11 -11
- package/chunks/{initializer-HK2XE6P2.js → initializer-QZTZSSLW.js} +16 -16
- package/chunks/{list-RVLIIKKL.js → list-WQ24EAMK.js} +18 -18
- package/chunks/{loadedSettingsAdapter-C63OUYZC.js → loadedSettingsAdapter-XV74KOSR.js} +16 -16
- package/chunks/{loop-wakeup-G2EHBRGR.js → loop-wakeup-34YK7T7O.js} +3 -3
- package/chunks/{ls-IDHUVSAG.js → ls-MPD5OJUX.js} +1 -1
- package/chunks/{lsp-FSRYXGFT.js → lsp-72PWTDW7.js} +1 -1
- package/chunks/{workspace-skills-status-ONEPXJV6.js → mcp-CO3MKM7N.js} +20 -16
- package/chunks/{monitor-FOG36ABM.js → monitor-GB56T65A.js} +11 -11
- package/chunks/{nonInteractiveCli-6BYQSJTB.js → nonInteractiveCli-HNZRIM5I.js} +46 -44
- package/chunks/{notebook-edit-GC6NXRCX.js → notebook-edit-VMXAAE3R.js} +12 -12
- package/chunks/{openaiContentGenerator-EXR3ZL3Z.js → openaiContentGenerator-GM77FLII.js} +6 -6
- package/chunks/{pidfile-FNZM2DDH.js → pidfile-HFXSHR64.js} +11 -11
- package/chunks/{qwenContentGenerator-A7B6J4U7.js → qwenContentGenerator-QSCXQIKJ.js} +13 -13
- package/chunks/{read-file-6JL4ULMY.js → read-file-SVH6CGQY.js} +3 -3
- package/chunks/{read-mcp-resource-PIJF24RO.js → read-mcp-resource-OWOBJY72.js} +1 -1
- package/chunks/record-artifact-URK3YUDJ.js +343 -0
- package/chunks/{ripGrep-DIUGLJE5.js → ripGrep-JD5O2FLX.js} +11 -11
- package/chunks/{run-qwen-serve-CME3AKM4.js → run-qwen-serve-FADLRJUN.js} +67 -28
- package/chunks/{scheduler-L7F6GDDT.js → scheduler-Q65SB7DJ.js} +11 -11
- package/chunks/{send-message-33PYFMCT.js → send-message-L7OLQEKH.js} +2 -2
- package/chunks/{serve-SRCBOJGP.js → serve-6ZXAMQ4M.js} +18 -18
- package/chunks/{server-QSQ45QFR.js → server-WKDQA6XR.js} +1184 -490
- package/chunks/{session-5DG6NXHZ.js → session-STWOX7RA.js} +48 -46
- package/chunks/{settings-3EEQI4MN.js → settings-LC4CCWQQ.js} +15 -15
- package/chunks/{shell-B7FNYF5S.js → shell-FEG3RLPW.js} +11 -11
- package/chunks/{skill-AAOGHD5O.js → skill-XTXAMDAP.js} +4 -4
- package/chunks/{spawnChannel-3CBN3ZLK.js → spawnChannel-B6JJPBPV.js} +15 -15
- package/chunks/{src-T5A7P7FS.js → src-HITDGVRM.js} +47 -21
- package/chunks/{startInteractiveUI-2FGEQ6AS.js → startInteractiveUI-IT423PW4.js} +354 -152
- package/chunks/{syntheticOutput-YOSWIHDJ.js → syntheticOutput-J3MLCQAR.js} +2 -2
- package/chunks/{task-create-NHS2NGB3.js → task-create-ELEBZ7H2.js} +3 -3
- package/chunks/{task-list-5UIB564R.js → task-list-IEUZLF3Y.js} +1 -1
- package/chunks/{task-stop-HGXZ2VZ3.js → task-stop-QEZW3UDY.js} +1 -1
- package/chunks/{task-update-IYYWUILG.js → task-update-DW36J5P5.js} +3 -3
- package/chunks/{team-create-KDF6W6PV.js → team-create-DAG6SNHZ.js} +11 -11
- package/chunks/{team-delete-FEKJCU4P.js → team-delete-SVITIMBO.js} +1 -1
- package/chunks/{team-plan-approval-PSFKQX7M.js → team-plan-approval-DRDY5OPC.js} +11 -11
- package/chunks/{theme-manager-5XOA2AO7.js → theme-manager-N67EZC6B.js} +11 -11
- package/chunks/{todoWrite-TKMVZ2HT.js → todoWrite-SFFQHZYY.js} +2 -2
- package/chunks/{tool-search-LFRILZXC.js → tool-search-CMDJ5HGM.js} +4 -4
- package/chunks/{trustedFolders-7HQY6T6X.js → trustedFolders-JD4QX6UJ.js} +12 -12
- package/chunks/{validateNonInterActiveAuth-UC27B7BA.js → validateNonInterActiveAuth-ADDCGZ6A.js} +43 -41
- package/chunks/version-VAONYVE5.js +10 -0
- package/chunks/{web-fetch-J4PIW36Q.js → web-fetch-SXAXJHIO.js} +2 -2
- package/chunks/{workflow-KUTESS6L.js → workflow-DG2BR42M.js} +20 -13
- package/chunks/{workspace-providers-status-LJT5AQDS.js → workspace-providers-status-XGW5OZTD.js} +18 -18
- package/chunks/{workspace-service-YOBYVDXH.js → workspace-service-GX3GGZLU.js} +23 -23
- package/chunks/workspace-skills-status-LFK5WV2V.js +68 -0
- package/chunks/{write-file-FJYBZUHP.js → write-file-UR7FXWOU.js} +12 -12
- package/chunks/yargs-B64EYTCF.js +10 -0
- package/chunks/{zh-SLZNSSZB.js → zh-FSVJTXA4.js} +1 -0
- package/chunks/{zh-TW-P53C2SL5.js → zh-TW-66MG4LWL.js} +1 -0
- package/cli-entry.js +81 -8
- package/cli.js +348 -55
- package/locales/en.js +1 -0
- package/locales/zh-TW.js +1 -0
- package/locales/zh.js +1 -0
- package/node_modules/@qwen-code/audio-capture/package.json +1 -1
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-arm64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/darwin-x64/@qwen-code+audio-capture.node +0 -0
- package/node_modules/@qwen-code/audio-capture/prebuilds/win32-x64/@qwen-code+audio-capture.node +0 -0
- package/package.json +3 -3
- package/web-shell/assets/{arc-D_rAuMDd.js → arc-CUpe0ibu.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-DUCzbHVo.js → architectureDiagram-3BPJPVTR-JvyrY_mK.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-BEEBt1LL.js → blockDiagram-GPEHLZMM-CK3Y_vom.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-5ZJ_DeFL.js → c4Diagram-AAUBKEIU-DprSnyrf.js} +1 -1
- package/web-shell/assets/channel-BAxQ2-aZ.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-Cfw7EiLn.js → chunk-2J33WTMH-DJtRJPmu.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-FGuZNCZY.js → chunk-4BX2VUAB-ON6Q2-BG.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-CaBwYPBF.js → chunk-55IACEB6-c60ou5HZ.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-BlR04OFz.js → chunk-727SXJPM-BamtPKxx.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-D3_mYJH5.js → chunk-AQP2D5EJ-CsVgpu-T.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-7D4q4SbB.js → chunk-FMBD7UC4-vZrpjAx4.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-BjX_Iwmr.js → chunk-ND2GUHAM-qxyNOd5t.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-C3Hz_ZQh.js → chunk-QZHKN3VN-BvTJSM_S.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-Cvd_xhZI.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-Cvd_xhZI.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-Ax4UycaT.js → cose-bilkent-S5V4N54A-1tXB4pju.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-C6hmPtGt.js → dagre-BM42HDAG-DglBzme8.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-tXZnxjmw.js → diagram-2AECGRRQ-DEJpqsWz.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-99dwIzQG.js → diagram-5GNKFQAL-CsQ1NrMG.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-Bqhn0-2s.js → diagram-KO2AKTUF-Z-3codAi.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-DzThVSvo.js → diagram-LMA3HP47-mBuPTA2i.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-DPE8vjln.js → diagram-OG6HWLK6-tcA3K3s9.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-KzUKgQCV.js → erDiagram-TEJ5UH35-D9bXFRyZ.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-DBN-DXw5.js → flowDiagram-I6XJVG4X-Ck0Py04s.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-DuBsP9u8.js → ganttDiagram-6RSMTGT7-rOevCekE.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-BjWHMyKR.js → gitGraphDiagram-PVQCEYII-CoPQaLj0.js} +1 -1
- package/web-shell/assets/index-Cr7MYW6T.css +5 -0
- package/web-shell/assets/index-DCHPAUp3.js +730 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-BVux0vP6.js → infoDiagram-5YYISTIA-a77CUKoI.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-2qzw7f--.js → ishikawaDiagram-YF4QCWOH-DlLgUAO-.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-Dnl65sxL.js → journeyDiagram-JHISSGLW-BXR5kVAZ.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-BElSQYtY.js → kanban-definition-UN3LZRKU-h5CoHZg7.js} +1 -1
- package/web-shell/assets/{linear-BjoycSSY.js → linear-BkaREbyD.js} +1 -1
- package/web-shell/assets/{mermaid.core-xe6bvMRz.js → mermaid.core-Bkagz0ng.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-D8DQgI4U.js → mindmap-definition-RKZ34NQL-D7EMKR_5.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-Dwh7Gp7c.js → pieDiagram-4H26LBE5-DAmPOjsL.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-BXKNBln2.js → quadrantDiagram-W4KKPZXB-e4WFQkQu.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-BzaC3cIA.js → requirementDiagram-4Y6WPE33-v1zo7OiV.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-DP2t7eZk.js → sankeyDiagram-5OEKKPKP-Bstm4aW_.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-XlFiWEYv.js → sequenceDiagram-3UESZ5HK-DzcZy6xN.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-CupgUMJO.js → stateDiagram-AJRCARHV-BEJH6YbH.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BopifCBI.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-DstuGywa.js → timeline-definition-PNZ67QCA-TI1wH-Pm.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-CnbNp6zu.js → vennDiagram-CIIHVFJN-YaH8VDMS.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-DnvoHq6R.js → wardley-L42UT6IY-B80co7OP.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Cz0xHEWB.js → wardleyDiagram-YWT4CUSO-4fHNDEMl.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-p36gfo88.js → xychartDiagram-2RQKCTM6-DT3q4Z3J.js} +1 -1
- package/web-shell/index.html +2 -2
- package/bundled/loop/SKILL.test.ts +0 -119
- package/bundled/loop/autonomous-loop.test.ts +0 -59
- package/bundled/loop/loop-task-file.test.ts +0 -1064
- package/bundled/loop/loop-tick-resolver.test.ts +0 -906
- package/chunks/chunk-EJ7BN3EN.js +0 -11396
- package/web-shell/assets/channel-B5ynH0q8.js +0 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-CK3ibywp.js +0 -1
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-CK3ibywp.js +0 -1
- package/web-shell/assets/index-9qfvU0_r.css +0 -5
- package/web-shell/assets/index-CWzDaQT5.js +0 -717
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-By3E4QwN.js +0 -1
- package/chunks/{chunk-UFC57OYT.js → chunk-VRDMOSQS.js} +54 -54
|
@@ -1,21 +1,39 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import {
|
|
4
|
-
openQwenAsrRealtimeStream,
|
|
5
|
-
openVoiceStream,
|
|
6
|
-
openVoiceStreamWithRetry
|
|
7
|
-
} from "./chunk-G4M7FPNY.js";
|
|
8
3
|
import {
|
|
9
4
|
MAX_REMEMBER_CONTENT_BYTES,
|
|
10
5
|
extractRememberErrorCode,
|
|
6
|
+
formatWorkspaceMemoryDreamSummary,
|
|
7
|
+
formatWorkspaceMemoryForgetSummary,
|
|
11
8
|
isValidServerName
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6SHO7WFF.js";
|
|
10
|
+
import {
|
|
11
|
+
openQwenAsrRealtimeStream,
|
|
12
|
+
openVoiceStream,
|
|
13
|
+
openVoiceStreamWithRetry
|
|
14
|
+
} from "./chunk-OBVBTAX5.js";
|
|
13
15
|
import {
|
|
14
16
|
SetupGithubError,
|
|
15
17
|
setupGithub
|
|
16
18
|
} from "./chunk-L7QPM2YD.js";
|
|
17
19
|
import "./chunk-54YZOP7P.js";
|
|
18
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-XH7H6YG4.js";
|
|
21
|
+
import {
|
|
22
|
+
createDaemonStatusProvider
|
|
23
|
+
} from "./chunk-DBF3HTLT.js";
|
|
24
|
+
import "./chunk-OAYOHSGP.js";
|
|
25
|
+
import "./chunk-KHDZHZMH.js";
|
|
26
|
+
import {
|
|
27
|
+
createWorkspaceProvidersStatusProvider
|
|
28
|
+
} from "./chunk-3UC7ZC43.js";
|
|
29
|
+
import {
|
|
30
|
+
getAuthTypeFromEnv,
|
|
31
|
+
resolveCliGenerationConfig
|
|
32
|
+
} from "./chunk-SOT7OMGL.js";
|
|
33
|
+
import {
|
|
34
|
+
createWorkspaceSkillsStatusProvider
|
|
35
|
+
} from "./chunk-C2QKQZEQ.js";
|
|
36
|
+
import "./chunk-6IAWPIQ6.js";
|
|
19
37
|
import {
|
|
20
38
|
EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
|
|
21
39
|
WorkspaceVoiceError,
|
|
@@ -26,7 +44,14 @@ import {
|
|
|
26
44
|
transcribeWorkspaceVoiceAudio,
|
|
27
45
|
validateWorkspaceVoiceState,
|
|
28
46
|
voiceSettingsScopeToWire
|
|
29
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-MX7CTJHR.js";
|
|
48
|
+
import {
|
|
49
|
+
PermissionRulesValidationError,
|
|
50
|
+
buildPermissionSettings,
|
|
51
|
+
isPermissionRuleType,
|
|
52
|
+
normalizePermissionRules,
|
|
53
|
+
readPermissionRuleSet
|
|
54
|
+
} from "./chunk-YTWX5TT2.js";
|
|
30
55
|
import {
|
|
31
56
|
assertVoiceBaseUrlNetworkAllowed,
|
|
32
57
|
isStreamingVoiceModel,
|
|
@@ -34,20 +59,17 @@ import {
|
|
|
34
59
|
resolveVoiceTranscriptionConfig,
|
|
35
60
|
sanitizeVoiceErrorMessage,
|
|
36
61
|
transcribeVoiceAudio
|
|
37
|
-
} from "./chunk-
|
|
38
|
-
import {
|
|
39
|
-
PermissionRulesValidationError,
|
|
40
|
-
buildPermissionSettings,
|
|
41
|
-
isPermissionRuleType,
|
|
42
|
-
normalizePermissionRules,
|
|
43
|
-
readPermissionRuleSet
|
|
44
|
-
} from "./chunk-6QVQZAW6.js";
|
|
62
|
+
} from "./chunk-FZ5NVRVK.js";
|
|
45
63
|
import {
|
|
46
64
|
isVoiceEnabled,
|
|
47
65
|
isVoiceMode,
|
|
48
66
|
readVoiceModel
|
|
49
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-HCFSKO6K.js";
|
|
50
68
|
import "./chunk-NIOPRZNN.js";
|
|
69
|
+
import {
|
|
70
|
+
WorkspacePermissionRulesSessionRequiredError,
|
|
71
|
+
WorkspaceSettingsPartialPersistError
|
|
72
|
+
} from "./chunk-BMFMJINR.js";
|
|
51
73
|
import {
|
|
52
74
|
CAPABILITIES_SCHEMA_VERSION,
|
|
53
75
|
CLIENT_ID_HEADER,
|
|
@@ -92,21 +114,28 @@ import {
|
|
|
92
114
|
setRateLimiter,
|
|
93
115
|
unsafeRevealSecret,
|
|
94
116
|
validateMcpRuntimeServerName
|
|
95
|
-
} from "./chunk-
|
|
117
|
+
} from "./chunk-N4YJQTRL.js";
|
|
96
118
|
import {
|
|
97
119
|
isLoopbackBind
|
|
98
120
|
} from "./chunk-RNBYOUGV.js";
|
|
99
121
|
import "./chunk-3HX5LZ6R.js";
|
|
100
122
|
import "./chunk-7RYW5LQV.js";
|
|
101
123
|
import {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
getDialogSettingKeys,
|
|
125
|
+
getNestedProperty,
|
|
126
|
+
getSettingDefinition,
|
|
127
|
+
loadSettings,
|
|
128
|
+
validateSettingValue
|
|
129
|
+
} from "./chunk-CEYA7K7C.js";
|
|
107
130
|
import {
|
|
131
|
+
SUPPORTED_LANGUAGES
|
|
132
|
+
} from "./chunk-6QVRLKTZ.js";
|
|
133
|
+
import "./chunk-TLRYABYP.js";
|
|
134
|
+
import "./chunk-4RQIB5UZ.js";
|
|
135
|
+
import {
|
|
136
|
+
SessionArtifactValidationError,
|
|
108
137
|
createAcpSessionBridge
|
|
109
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-LXFCHX4X.js";
|
|
110
139
|
import "./chunk-P7M4GA57.js";
|
|
111
140
|
import {
|
|
112
141
|
BranchWhilePromptActiveError,
|
|
@@ -146,44 +175,19 @@ import {
|
|
|
146
175
|
EVENT_SCHEMA_VERSION,
|
|
147
176
|
SubscriberLimitExceededError
|
|
148
177
|
} from "./chunk-ALX6BUYW.js";
|
|
149
|
-
import "./chunk-
|
|
150
|
-
import
|
|
151
|
-
|
|
152
|
-
} from "./chunk-NSSVORTQ.js";
|
|
153
|
-
import {
|
|
154
|
-
getAuthTypeFromEnv,
|
|
155
|
-
resolveCliGenerationConfig
|
|
156
|
-
} from "./chunk-K4I4STSL.js";
|
|
157
|
-
import {
|
|
158
|
-
createWorkspaceSkillsStatusProvider
|
|
159
|
-
} from "./chunk-TN6RT6EJ.js";
|
|
160
|
-
import "./chunk-CXBG27SF.js";
|
|
178
|
+
import "./chunk-VRDMOSQS.js";
|
|
179
|
+
import "./chunk-57NRQM3P.js";
|
|
180
|
+
import "./chunk-3VJ7MT3N.js";
|
|
161
181
|
import {
|
|
162
182
|
STATUS_SCHEMA_VERSION,
|
|
163
183
|
createIdleWorkspaceMemoryStatus,
|
|
164
184
|
mapDomainErrorToErrorKind
|
|
165
|
-
} from "./chunk-
|
|
166
|
-
import
|
|
167
|
-
|
|
168
|
-
WorkspaceSettingsPartialPersistError
|
|
169
|
-
} from "./chunk-BMFMJINR.js";
|
|
170
|
-
import {
|
|
171
|
-
getDialogSettingKeys,
|
|
172
|
-
getNestedProperty,
|
|
173
|
-
getSettingDefinition,
|
|
174
|
-
loadSettings,
|
|
175
|
-
validateSettingValue
|
|
176
|
-
} from "./chunk-BC4R5C5R.js";
|
|
177
|
-
import {
|
|
178
|
-
SUPPORTED_LANGUAGES
|
|
179
|
-
} from "./chunk-DM4E337C.js";
|
|
180
|
-
import "./chunk-TLRYABYP.js";
|
|
181
|
-
import "./chunk-2Z43HUXT.js";
|
|
182
|
-
import "./chunk-UFC57OYT.js";
|
|
183
|
-
import "./chunk-PPFWEV7G.js";
|
|
185
|
+
} from "./chunk-7Z6UEJA4.js";
|
|
186
|
+
import "./chunk-HLKG6CZN.js";
|
|
187
|
+
import "./chunk-SL2P3JUA.js";
|
|
184
188
|
import {
|
|
185
189
|
getWorkspaceTrustStatus
|
|
186
|
-
} from "./chunk-
|
|
190
|
+
} from "./chunk-V6NH3CUC.js";
|
|
187
191
|
import {
|
|
188
192
|
writeStderrLine
|
|
189
193
|
} from "./chunk-Y6Z2O3WR.js";
|
|
@@ -201,8 +205,6 @@ import {
|
|
|
201
205
|
StandardFileSystemService,
|
|
202
206
|
StdioClientTransport,
|
|
203
207
|
StreamableHTTPClientTransport,
|
|
204
|
-
SubagentError,
|
|
205
|
-
SubagentErrorCode,
|
|
206
208
|
SubagentManager,
|
|
207
209
|
TrustGateError,
|
|
208
210
|
WorkspaceMemoryFileTooLargeError,
|
|
@@ -216,27 +218,29 @@ import {
|
|
|
216
218
|
redactUrlCredentials,
|
|
217
219
|
shouldShowStep,
|
|
218
220
|
writeWorkspaceContextFile
|
|
219
|
-
} from "./chunk-
|
|
221
|
+
} from "./chunk-AGZF43UV.js";
|
|
220
222
|
import "./chunk-5P5XGNYH.js";
|
|
221
|
-
import "./chunk-K5PGHDBN.js";
|
|
222
223
|
import "./chunk-SKAZWEV5.js";
|
|
224
|
+
import "./chunk-K5PGHDBN.js";
|
|
225
|
+
import "./chunk-CLQPBI4H.js";
|
|
223
226
|
import "./chunk-QOMAHFYI.js";
|
|
224
227
|
import "./chunk-G7OQ3RFJ.js";
|
|
225
228
|
import "./chunk-LKWAVAB5.js";
|
|
226
|
-
import "./chunk-
|
|
227
|
-
import "./chunk-R6RI2HIC.js";
|
|
229
|
+
import "./chunk-5ES5YPED.js";
|
|
228
230
|
import "./chunk-2MPVVENX.js";
|
|
229
231
|
import "./chunk-ZTQ26VBE.js";
|
|
230
|
-
import "./chunk-
|
|
232
|
+
import "./chunk-DMSNJDWG.js";
|
|
231
233
|
import "./chunk-MLZQVCF3.js";
|
|
232
234
|
import "./chunk-LQ7TMOCE.js";
|
|
233
235
|
import "./chunk-E5A7LHNN.js";
|
|
234
236
|
import {
|
|
235
|
-
APPROVAL_MODES
|
|
236
|
-
|
|
237
|
+
APPROVAL_MODES,
|
|
238
|
+
SubagentError,
|
|
239
|
+
SubagentErrorCode
|
|
240
|
+
} from "./chunk-LM3YCCZJ.js";
|
|
237
241
|
import "./chunk-GO6LNQXT.js";
|
|
238
242
|
import "./chunk-B236XPGF.js";
|
|
239
|
-
import "./chunk-
|
|
243
|
+
import "./chunk-NVFJSIAX.js";
|
|
240
244
|
import "./chunk-TOAUDIS7.js";
|
|
241
245
|
import "./chunk-NPQWQYU6.js";
|
|
242
246
|
import {
|
|
@@ -252,15 +256,15 @@ import {
|
|
|
252
256
|
recordDaemonHttpRequest,
|
|
253
257
|
recordDaemonHttpResponse,
|
|
254
258
|
withDaemonRequestSpan
|
|
255
|
-
} from "./chunk-
|
|
259
|
+
} from "./chunk-JN2VJ33O.js";
|
|
256
260
|
import "./chunk-E6US47KI.js";
|
|
257
261
|
import "./chunk-UWCTAVOD.js";
|
|
258
262
|
import "./chunk-OFEVLU4C.js";
|
|
259
263
|
import "./chunk-OMX7CUOE.js";
|
|
260
264
|
import "./chunk-MOUXUCXQ.js";
|
|
261
265
|
import "./chunk-BZHLWC6T.js";
|
|
262
|
-
import "./chunk-
|
|
263
|
-
import "./chunk-
|
|
266
|
+
import "./chunk-RZORUN6X.js";
|
|
267
|
+
import "./chunk-MJKMIQMK.js";
|
|
264
268
|
import {
|
|
265
269
|
QwenOAuth2Client,
|
|
266
270
|
QwenOAuthPollError,
|
|
@@ -274,7 +278,7 @@ import "./chunk-GLPV75ES.js";
|
|
|
274
278
|
import "./chunk-22IFUCVR.js";
|
|
275
279
|
import "./chunk-T42ACHFI.js";
|
|
276
280
|
import "./chunk-SIUQ3YYX.js";
|
|
277
|
-
import "./chunk-
|
|
281
|
+
import "./chunk-KYTQOCDE.js";
|
|
278
282
|
import "./chunk-YPCPZSZB.js";
|
|
279
283
|
import "./chunk-IRJWHZWU.js";
|
|
280
284
|
import "./chunk-SYCJMSIJ.js";
|
|
@@ -2998,63 +3002,627 @@ function registerWorkspaceVoiceRoutes(app, deps) {
|
|
|
2998
3002
|
});
|
|
2999
3003
|
return;
|
|
3000
3004
|
}
|
|
3001
|
-
const settings = loadSettings(deps.boundWorkspace);
|
|
3002
|
-
if (!isVoiceEnabled(settings)) {
|
|
3003
|
-
res.status(403).json({
|
|
3004
|
-
error: "Voice transcription is disabled for this workspace",
|
|
3005
|
-
code: "voice_disabled"
|
|
3005
|
+
const settings = loadSettings(deps.boundWorkspace);
|
|
3006
|
+
if (!isVoiceEnabled(settings)) {
|
|
3007
|
+
res.status(403).json({
|
|
3008
|
+
error: "Voice transcription is disabled for this workspace",
|
|
3009
|
+
code: "voice_disabled"
|
|
3010
|
+
});
|
|
3011
|
+
return;
|
|
3012
|
+
}
|
|
3013
|
+
const queryVoiceModel = req.query["voiceModel"];
|
|
3014
|
+
if (queryVoiceModel !== void 0 && typeof queryVoiceModel !== "string") {
|
|
3015
|
+
res.status(400).json({
|
|
3016
|
+
error: "`voiceModel` query parameter must be a string",
|
|
3017
|
+
code: "invalid_voice_model"
|
|
3018
|
+
});
|
|
3019
|
+
return;
|
|
3020
|
+
}
|
|
3021
|
+
const requestedVoiceModel = typeof queryVoiceModel === "string" ? queryVoiceModel.trim() : "";
|
|
3022
|
+
if (requestedVoiceModel && requestedVoiceModel.length > MAX_VOICE_MODEL_LENGTH) {
|
|
3023
|
+
res.status(400).json({
|
|
3024
|
+
error: `\`voiceModel\` exceeds the ${MAX_VOICE_MODEL_LENGTH}-character limit`,
|
|
3025
|
+
code: "invalid_voice_model"
|
|
3026
|
+
});
|
|
3027
|
+
return;
|
|
3028
|
+
}
|
|
3029
|
+
const voiceModel = requestedVoiceModel || readVoiceModel(settings);
|
|
3030
|
+
if (!voiceModel) {
|
|
3031
|
+
res.status(400).json({
|
|
3032
|
+
error: "A valid voiceModel is required before transcription.",
|
|
3033
|
+
code: "voice_model_required"
|
|
3034
|
+
});
|
|
3035
|
+
return;
|
|
3036
|
+
}
|
|
3037
|
+
try {
|
|
3038
|
+
const result = await transcribe({
|
|
3039
|
+
data,
|
|
3040
|
+
mimeType: audioContentType,
|
|
3041
|
+
voiceModel,
|
|
3042
|
+
settings,
|
|
3043
|
+
workspaceCwd: deps.boundWorkspace,
|
|
3044
|
+
abortSignal: requestAbortSignal2(req, res)
|
|
3045
|
+
});
|
|
3046
|
+
res.status(200).json({ v: 1, ...result });
|
|
3047
|
+
} catch (err) {
|
|
3048
|
+
if (sendVoiceError(res, err)) return;
|
|
3049
|
+
const message = err instanceof Error ? sanitizeVoiceErrorMessage(err.message) : sanitizeVoiceErrorMessage(String(err));
|
|
3050
|
+
writeStderrLine(
|
|
3051
|
+
`qwen serve: POST /workspace/voice/transcribe error (workspace=${deps.boundWorkspace}): ${message}`
|
|
3052
|
+
);
|
|
3053
|
+
res.status(502).json({
|
|
3054
|
+
error: "Voice transcription failed",
|
|
3055
|
+
code: "voice_transcription_failed"
|
|
3056
|
+
});
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
);
|
|
3060
|
+
}
|
|
3061
|
+
__name(registerWorkspaceVoiceRoutes, "registerWorkspaceVoiceRoutes");
|
|
3062
|
+
|
|
3063
|
+
// packages/cli/src/serve/workspace-remember.ts
|
|
3064
|
+
init_esbuild_shims();
|
|
3065
|
+
import { randomUUID } from "node:crypto";
|
|
3066
|
+
var debugLogger = createDebugLogger("WORKSPACE_REMEMBER");
|
|
3067
|
+
function nowIso() {
|
|
3068
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3069
|
+
}
|
|
3070
|
+
__name(nowIso, "nowIso");
|
|
3071
|
+
function createMemoryTaskId(kind) {
|
|
3072
|
+
return `${kind}-${randomUUID()}`;
|
|
3073
|
+
}
|
|
3074
|
+
__name(createMemoryTaskId, "createMemoryTaskId");
|
|
3075
|
+
function touchedScopesFromTopics(topics) {
|
|
3076
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
3077
|
+
for (const topic of topics) {
|
|
3078
|
+
scopes.add(topic === "user" || topic === "feedback" ? "user" : "project");
|
|
3079
|
+
}
|
|
3080
|
+
return [...scopes];
|
|
3081
|
+
}
|
|
3082
|
+
__name(touchedScopesFromTopics, "touchedScopesFromTopics");
|
|
3083
|
+
function cloneTask(task) {
|
|
3084
|
+
const base = {
|
|
3085
|
+
taskId: task.taskId,
|
|
3086
|
+
status: task.status,
|
|
3087
|
+
createdAt: task.createdAt,
|
|
3088
|
+
updatedAt: task.updatedAt,
|
|
3089
|
+
error: task.error ? { ...task.error } : void 0
|
|
3090
|
+
};
|
|
3091
|
+
if (task.kind === "remember") {
|
|
3092
|
+
return {
|
|
3093
|
+
...base,
|
|
3094
|
+
contextMode: task.contextMode,
|
|
3095
|
+
result: task.result ? {
|
|
3096
|
+
...task.result,
|
|
3097
|
+
filesTouched: [...task.result.filesTouched],
|
|
3098
|
+
touchedScopes: [...task.result.touchedScopes]
|
|
3099
|
+
} : void 0
|
|
3100
|
+
};
|
|
3101
|
+
}
|
|
3102
|
+
if (task.kind === "forget") {
|
|
3103
|
+
return {
|
|
3104
|
+
...base,
|
|
3105
|
+
result: task.result ? {
|
|
3106
|
+
...task.result,
|
|
3107
|
+
removedEntries: task.result.removedEntries.map((entry) => ({
|
|
3108
|
+
...entry
|
|
3109
|
+
})),
|
|
3110
|
+
touchedTopics: [...task.result.touchedTopics]
|
|
3111
|
+
} : void 0
|
|
3112
|
+
};
|
|
3113
|
+
}
|
|
3114
|
+
return {
|
|
3115
|
+
...base,
|
|
3116
|
+
result: task.result ? {
|
|
3117
|
+
...task.result,
|
|
3118
|
+
touchedTopics: [...task.result.touchedTopics]
|
|
3119
|
+
} : void 0
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
__name(cloneTask, "cloneTask");
|
|
3123
|
+
function publicErrorMessage(code, kind) {
|
|
3124
|
+
if (code === "managed_memory_unavailable") {
|
|
3125
|
+
return "Managed memory is unavailable for this daemon workspace.";
|
|
3126
|
+
}
|
|
3127
|
+
if (code === "remember_path_escape") {
|
|
3128
|
+
return "Remember agent touched a path outside managed memory.";
|
|
3129
|
+
}
|
|
3130
|
+
if (code === "remember_queue_full") {
|
|
3131
|
+
return kind === "remember" ? "Workspace memory remember queue is full." : "Workspace memory task queue is full.";
|
|
3132
|
+
}
|
|
3133
|
+
if (code === "remember_timeout" || code === "forget_timeout" || code === "dream_timeout") {
|
|
3134
|
+
return `Workspace memory ${kind} timed out.`;
|
|
3135
|
+
}
|
|
3136
|
+
return `Workspace memory ${kind} failed.`;
|
|
3137
|
+
}
|
|
3138
|
+
__name(publicErrorMessage, "publicErrorMessage");
|
|
3139
|
+
function publicErrorStatus(code) {
|
|
3140
|
+
if (code === "remember_queue_full") return 429;
|
|
3141
|
+
if (code === "managed_memory_unavailable") return 409;
|
|
3142
|
+
return 500;
|
|
3143
|
+
}
|
|
3144
|
+
__name(publicErrorStatus, "publicErrorStatus");
|
|
3145
|
+
var WorkspaceRememberTaskLane = class _WorkspaceRememberTaskLane {
|
|
3146
|
+
constructor(bridge) {
|
|
3147
|
+
this.bridge = bridge;
|
|
3148
|
+
}
|
|
3149
|
+
static {
|
|
3150
|
+
__name(this, "WorkspaceRememberTaskLane");
|
|
3151
|
+
}
|
|
3152
|
+
static MAX_TASKS = 1e3;
|
|
3153
|
+
static TERMINAL_TASK_TTL_MS = 5 * 6e4;
|
|
3154
|
+
// Two-tier pending capacity: all tasks share the global cap, while
|
|
3155
|
+
// forget/dream share a smaller sub-cap so bursts cannot starve remember.
|
|
3156
|
+
static MAX_PENDING = 16;
|
|
3157
|
+
static MAX_NON_REMEMBER_PENDING = 8;
|
|
3158
|
+
static NON_REMEMBER_KINDS = /* @__PURE__ */ new Set(
|
|
3159
|
+
["forget", "dream"]
|
|
3160
|
+
);
|
|
3161
|
+
tasks = /* @__PURE__ */ new Map();
|
|
3162
|
+
tail = Promise.resolve();
|
|
3163
|
+
pendingCounts() {
|
|
3164
|
+
let total = 0;
|
|
3165
|
+
let nonRemember = 0;
|
|
3166
|
+
for (const task of this.tasks.values()) {
|
|
3167
|
+
if (task.status !== "queued" && task.status !== "running") continue;
|
|
3168
|
+
total++;
|
|
3169
|
+
if (_WorkspaceRememberTaskLane.NON_REMEMBER_KINDS.has(task.kind)) {
|
|
3170
|
+
nonRemember++;
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
return { total, nonRemember };
|
|
3174
|
+
}
|
|
3175
|
+
evictTerminalTasks(nowMs = Date.now()) {
|
|
3176
|
+
const cutoffMs = nowMs - _WorkspaceRememberTaskLane.TERMINAL_TASK_TTL_MS;
|
|
3177
|
+
for (const [id, task] of this.tasks) {
|
|
3178
|
+
if (task.status !== "completed" && task.status !== "failed") continue;
|
|
3179
|
+
const updatedAtMs = Date.parse(task.updatedAt);
|
|
3180
|
+
if (!Number.isNaN(updatedAtMs) && updatedAtMs <= cutoffMs) {
|
|
3181
|
+
this.tasks.delete(id);
|
|
3182
|
+
} else if (Number.isNaN(updatedAtMs)) {
|
|
3183
|
+
debugLogger.warn(
|
|
3184
|
+
"Task with unparseable updatedAt skipped for TTL eviction:",
|
|
3185
|
+
{
|
|
3186
|
+
taskId: id,
|
|
3187
|
+
updatedAt: task.updatedAt
|
|
3188
|
+
}
|
|
3189
|
+
);
|
|
3190
|
+
}
|
|
3191
|
+
}
|
|
3192
|
+
if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) return;
|
|
3193
|
+
for (const [id, task] of this.tasks) {
|
|
3194
|
+
if (task.status === "completed" || task.status === "failed") {
|
|
3195
|
+
this.tasks.delete(id);
|
|
3196
|
+
if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) break;
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
assertCapacity(kind) {
|
|
3201
|
+
const pending = this.pendingCounts();
|
|
3202
|
+
if (pending.total >= _WorkspaceRememberTaskLane.MAX_PENDING) {
|
|
3203
|
+
throw Object.assign(new Error("Workspace memory task queue is full"), {
|
|
3204
|
+
code: "remember_queue_full"
|
|
3205
|
+
});
|
|
3206
|
+
}
|
|
3207
|
+
if (_WorkspaceRememberTaskLane.NON_REMEMBER_KINDS.has(kind) && pending.nonRemember >= _WorkspaceRememberTaskLane.MAX_NON_REMEMBER_PENDING) {
|
|
3208
|
+
throw Object.assign(new Error("Workspace memory task queue is full"), {
|
|
3209
|
+
code: "remember_queue_full"
|
|
3210
|
+
});
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
queue(task, run) {
|
|
3214
|
+
this.tasks.set(task.taskId, task);
|
|
3215
|
+
this.evictTerminalTasks();
|
|
3216
|
+
this.tail = this.tail.then(run, run);
|
|
3217
|
+
void this.tail.catch((err) => {
|
|
3218
|
+
debugLogger.error("Unhandled task lane error:", err);
|
|
3219
|
+
});
|
|
3220
|
+
return cloneTask(task);
|
|
3221
|
+
}
|
|
3222
|
+
publishManagedMemoryChanged(params) {
|
|
3223
|
+
if (params.touchedScopes.length === 0) return;
|
|
3224
|
+
try {
|
|
3225
|
+
this.bridge.publishWorkspaceEvent({
|
|
3226
|
+
type: "memory_changed",
|
|
3227
|
+
data: {
|
|
3228
|
+
scope: "managed",
|
|
3229
|
+
source: params.source,
|
|
3230
|
+
taskId: params.taskId,
|
|
3231
|
+
touchedScopes: params.touchedScopes
|
|
3232
|
+
},
|
|
3233
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3234
|
+
});
|
|
3235
|
+
} catch (err) {
|
|
3236
|
+
debugLogger.error("Failed to publish memory_changed event:", err);
|
|
3237
|
+
}
|
|
3238
|
+
}
|
|
3239
|
+
enqueue(params) {
|
|
3240
|
+
this.assertCapacity("remember");
|
|
3241
|
+
const task = {
|
|
3242
|
+
kind: "remember",
|
|
3243
|
+
taskId: createMemoryTaskId("remember"),
|
|
3244
|
+
status: "queued",
|
|
3245
|
+
contextMode: params.contextMode,
|
|
3246
|
+
createdAt: nowIso(),
|
|
3247
|
+
updatedAt: nowIso(),
|
|
3248
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3249
|
+
};
|
|
3250
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
3251
|
+
task.status = "running";
|
|
3252
|
+
task.updatedAt = nowIso();
|
|
3253
|
+
try {
|
|
3254
|
+
const result = await this.bridge.runWorkspaceMemoryRemember({
|
|
3255
|
+
content: params.content,
|
|
3256
|
+
contextMode: params.contextMode
|
|
3257
|
+
});
|
|
3258
|
+
task.status = "completed";
|
|
3259
|
+
task.result = {
|
|
3260
|
+
summary: result.filesTouched.length > 0 ? "Memory update completed." : "No memory files updated.",
|
|
3261
|
+
filesTouched: result.filesTouched,
|
|
3262
|
+
touchedScopes: result.touchedScopes
|
|
3263
|
+
};
|
|
3264
|
+
task.updatedAt = nowIso();
|
|
3265
|
+
} catch (err) {
|
|
3266
|
+
const code = extractRememberErrorCode(err);
|
|
3267
|
+
debugLogger.error(
|
|
3268
|
+
"Workspace memory remember task failed:",
|
|
3269
|
+
{ taskId: task.taskId },
|
|
3270
|
+
err
|
|
3271
|
+
);
|
|
3272
|
+
task.status = "failed";
|
|
3273
|
+
task.error = {
|
|
3274
|
+
code,
|
|
3275
|
+
message: publicErrorMessage(code, task.kind)
|
|
3276
|
+
};
|
|
3277
|
+
task.updatedAt = nowIso();
|
|
3278
|
+
}
|
|
3279
|
+
try {
|
|
3280
|
+
if (task.status === "completed" && task.result) {
|
|
3281
|
+
this.publishManagedMemoryChanged({
|
|
3282
|
+
source: "workspace_memory_remember",
|
|
3283
|
+
taskId: task.taskId,
|
|
3284
|
+
touchedScopes: task.result.touchedScopes,
|
|
3285
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3286
|
+
});
|
|
3287
|
+
}
|
|
3288
|
+
} finally {
|
|
3289
|
+
this.evictTerminalTasks();
|
|
3290
|
+
}
|
|
3291
|
+
}, "run");
|
|
3292
|
+
return this.queue(task, run);
|
|
3293
|
+
}
|
|
3294
|
+
enqueueForget(params) {
|
|
3295
|
+
this.assertCapacity("forget");
|
|
3296
|
+
const task = {
|
|
3297
|
+
kind: "forget",
|
|
3298
|
+
taskId: createMemoryTaskId("forget"),
|
|
3299
|
+
status: "queued",
|
|
3300
|
+
createdAt: nowIso(),
|
|
3301
|
+
updatedAt: nowIso(),
|
|
3302
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3303
|
+
};
|
|
3304
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
3305
|
+
task.status = "running";
|
|
3306
|
+
task.updatedAt = nowIso();
|
|
3307
|
+
try {
|
|
3308
|
+
const result = await this.bridge.runWorkspaceMemoryForget({
|
|
3309
|
+
query: params.query
|
|
3310
|
+
});
|
|
3311
|
+
task.status = "completed";
|
|
3312
|
+
task.result = {
|
|
3313
|
+
summary: result.summary ?? formatWorkspaceMemoryForgetSummary(result.removedEntries.length),
|
|
3314
|
+
removedEntries: result.removedEntries,
|
|
3315
|
+
touchedTopics: result.touchedTopics
|
|
3316
|
+
};
|
|
3317
|
+
task.updatedAt = nowIso();
|
|
3318
|
+
} catch (err) {
|
|
3319
|
+
const code = extractRememberErrorCode(err, "forget_failed");
|
|
3320
|
+
debugLogger.error(
|
|
3321
|
+
"Workspace memory forget task failed:",
|
|
3322
|
+
{ taskId: task.taskId },
|
|
3323
|
+
err
|
|
3324
|
+
);
|
|
3325
|
+
task.status = "failed";
|
|
3326
|
+
task.error = {
|
|
3327
|
+
code,
|
|
3328
|
+
message: publicErrorMessage(code, task.kind)
|
|
3329
|
+
};
|
|
3330
|
+
task.updatedAt = nowIso();
|
|
3331
|
+
}
|
|
3332
|
+
try {
|
|
3333
|
+
if (task.status === "completed" && task.result) {
|
|
3334
|
+
this.publishManagedMemoryChanged({
|
|
3335
|
+
source: "workspace_memory_forget",
|
|
3336
|
+
taskId: task.taskId,
|
|
3337
|
+
touchedScopes: touchedScopesFromTopics(task.result.touchedTopics),
|
|
3338
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3339
|
+
});
|
|
3340
|
+
}
|
|
3341
|
+
} finally {
|
|
3342
|
+
this.evictTerminalTasks();
|
|
3343
|
+
}
|
|
3344
|
+
}, "run");
|
|
3345
|
+
return this.queue(task, run);
|
|
3346
|
+
}
|
|
3347
|
+
enqueueDream(params) {
|
|
3348
|
+
this.assertCapacity("dream");
|
|
3349
|
+
const task = {
|
|
3350
|
+
kind: "dream",
|
|
3351
|
+
taskId: createMemoryTaskId("dream"),
|
|
3352
|
+
status: "queued",
|
|
3353
|
+
createdAt: nowIso(),
|
|
3354
|
+
updatedAt: nowIso(),
|
|
3355
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3356
|
+
};
|
|
3357
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
3358
|
+
task.status = "running";
|
|
3359
|
+
task.updatedAt = nowIso();
|
|
3360
|
+
try {
|
|
3361
|
+
const result = await this.bridge.runWorkspaceMemoryDream();
|
|
3362
|
+
task.status = "completed";
|
|
3363
|
+
task.result = {
|
|
3364
|
+
summary: result.summary ?? formatWorkspaceMemoryDreamSummary(result.touchedTopics.length),
|
|
3365
|
+
touchedTopics: result.touchedTopics,
|
|
3366
|
+
dedupedEntries: result.dedupedEntries
|
|
3367
|
+
};
|
|
3368
|
+
task.updatedAt = nowIso();
|
|
3369
|
+
} catch (err) {
|
|
3370
|
+
const code = extractRememberErrorCode(err, "dream_failed");
|
|
3371
|
+
debugLogger.error(
|
|
3372
|
+
"Workspace memory dream task failed:",
|
|
3373
|
+
{ taskId: task.taskId },
|
|
3374
|
+
err
|
|
3375
|
+
);
|
|
3376
|
+
task.status = "failed";
|
|
3377
|
+
task.error = {
|
|
3378
|
+
code,
|
|
3379
|
+
message: publicErrorMessage(code, task.kind)
|
|
3380
|
+
};
|
|
3381
|
+
task.updatedAt = nowIso();
|
|
3382
|
+
}
|
|
3383
|
+
try {
|
|
3384
|
+
if (task.status === "completed" && task.result) {
|
|
3385
|
+
this.publishManagedMemoryChanged({
|
|
3386
|
+
source: "workspace_memory_dream",
|
|
3387
|
+
taskId: task.taskId,
|
|
3388
|
+
touchedScopes: touchedScopesFromTopics(task.result.touchedTopics),
|
|
3389
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3390
|
+
});
|
|
3391
|
+
}
|
|
3392
|
+
} finally {
|
|
3393
|
+
this.evictTerminalTasks();
|
|
3394
|
+
}
|
|
3395
|
+
}, "run");
|
|
3396
|
+
return this.queue(task, run);
|
|
3397
|
+
}
|
|
3398
|
+
get(taskId, requesterClientId, kind) {
|
|
3399
|
+
const task = this.tasks.get(taskId);
|
|
3400
|
+
if (!task) return void 0;
|
|
3401
|
+
if (kind && task.kind !== kind) return void 0;
|
|
3402
|
+
if (task.originatorClientId) {
|
|
3403
|
+
if (task.originatorClientId !== requesterClientId) return void 0;
|
|
3404
|
+
} else if (requesterClientId) {
|
|
3405
|
+
return void 0;
|
|
3406
|
+
}
|
|
3407
|
+
return cloneTask(task);
|
|
3408
|
+
}
|
|
3409
|
+
};
|
|
3410
|
+
function validateOriginatorClientId(deps, req, res) {
|
|
3411
|
+
const clientId = deps.parseClientId(req, res);
|
|
3412
|
+
if (clientId === null) return null;
|
|
3413
|
+
if (clientId === void 0) return void 0;
|
|
3414
|
+
const known = deps.bridge.knownClientIds();
|
|
3415
|
+
if (!known.has(clientId)) {
|
|
3416
|
+
res.status(400).json({
|
|
3417
|
+
error: `Client id "${clientId}" is not registered for this workspace`,
|
|
3418
|
+
code: "invalid_client_id",
|
|
3419
|
+
clientId
|
|
3420
|
+
});
|
|
3421
|
+
return null;
|
|
3422
|
+
}
|
|
3423
|
+
return clientId;
|
|
3424
|
+
}
|
|
3425
|
+
__name(validateOriginatorClientId, "validateOriginatorClientId");
|
|
3426
|
+
async function validateManagedMemoryAvailable(deps, res, kind) {
|
|
3427
|
+
try {
|
|
3428
|
+
const available = await deps.bridge.isWorkspaceMemoryRememberAvailable();
|
|
3429
|
+
if (!available) {
|
|
3430
|
+
res.status(409).json({
|
|
3431
|
+
error: "Managed memory is unavailable for this daemon workspace",
|
|
3432
|
+
code: "managed_memory_unavailable"
|
|
3433
|
+
});
|
|
3434
|
+
return false;
|
|
3435
|
+
}
|
|
3436
|
+
return true;
|
|
3437
|
+
} catch (err) {
|
|
3438
|
+
debugLogger.error("Availability check failed:", err);
|
|
3439
|
+
const code = `${kind}_failed`;
|
|
3440
|
+
res.status(500).json({
|
|
3441
|
+
error: publicErrorMessage(code, kind),
|
|
3442
|
+
code
|
|
3443
|
+
});
|
|
3444
|
+
return false;
|
|
3445
|
+
}
|
|
3446
|
+
}
|
|
3447
|
+
__name(validateManagedMemoryAvailable, "validateManagedMemoryAvailable");
|
|
3448
|
+
function mountWorkspaceMemoryRememberRoutes(app, deps) {
|
|
3449
|
+
app.post(
|
|
3450
|
+
"/workspace/memory/remember",
|
|
3451
|
+
deps.mutate({ strict: true }),
|
|
3452
|
+
async (req, res) => {
|
|
3453
|
+
const body = deps.safeBody(req);
|
|
3454
|
+
const content = body["content"];
|
|
3455
|
+
const trimmedContent = typeof content === "string" ? content.trim() : "";
|
|
3456
|
+
if (!trimmedContent) {
|
|
3457
|
+
res.status(400).json({
|
|
3458
|
+
error: "`content` must be a non-empty string",
|
|
3459
|
+
code: "invalid_content"
|
|
3460
|
+
});
|
|
3461
|
+
return;
|
|
3462
|
+
}
|
|
3463
|
+
if (Buffer.byteLength(trimmedContent, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
|
|
3464
|
+
res.status(400).json({
|
|
3465
|
+
error: `\`content\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`,
|
|
3466
|
+
code: "invalid_content"
|
|
3467
|
+
});
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
const contextModeRaw = body["contextMode"] ?? "workspace";
|
|
3471
|
+
if (contextModeRaw !== "workspace" && contextModeRaw !== "clean") {
|
|
3472
|
+
res.status(400).json({
|
|
3473
|
+
error: '`contextMode` must be "workspace", "clean", or omitted',
|
|
3474
|
+
code: "invalid_context_mode"
|
|
3475
|
+
});
|
|
3476
|
+
return;
|
|
3477
|
+
}
|
|
3478
|
+
const originatorClientId = validateOriginatorClientId(deps, req, res);
|
|
3479
|
+
if (originatorClientId === null) return;
|
|
3480
|
+
if (!await validateManagedMemoryAvailable(deps, res, "remember")) {
|
|
3481
|
+
return;
|
|
3482
|
+
}
|
|
3483
|
+
let task;
|
|
3484
|
+
try {
|
|
3485
|
+
task = deps.lane.enqueue({
|
|
3486
|
+
content: trimmedContent,
|
|
3487
|
+
contextMode: contextModeRaw,
|
|
3488
|
+
...originatorClientId ? { originatorClientId } : {}
|
|
3489
|
+
});
|
|
3490
|
+
} catch (err) {
|
|
3491
|
+
const code = extractRememberErrorCode(err);
|
|
3492
|
+
res.status(publicErrorStatus(code)).json({
|
|
3493
|
+
error: publicErrorMessage(code, "remember"),
|
|
3494
|
+
code
|
|
3495
|
+
});
|
|
3496
|
+
return;
|
|
3497
|
+
}
|
|
3498
|
+
res.status(202).json(task);
|
|
3499
|
+
}
|
|
3500
|
+
);
|
|
3501
|
+
app.get(
|
|
3502
|
+
"/workspace/memory/remember/:taskId",
|
|
3503
|
+
deps.mutate({ strict: true }),
|
|
3504
|
+
(req, res) => {
|
|
3505
|
+
const requesterClientId = validateOriginatorClientId(deps, req, res);
|
|
3506
|
+
if (requesterClientId === null) return;
|
|
3507
|
+
const task = deps.lane.get(
|
|
3508
|
+
req.params["taskId"],
|
|
3509
|
+
requesterClientId,
|
|
3510
|
+
"remember"
|
|
3511
|
+
);
|
|
3512
|
+
if (!task) {
|
|
3513
|
+
res.status(404).json({
|
|
3514
|
+
error: "Workspace memory remember task not found",
|
|
3515
|
+
code: "remember_task_not_found"
|
|
3516
|
+
});
|
|
3517
|
+
return;
|
|
3518
|
+
}
|
|
3519
|
+
res.status(200).json(task);
|
|
3520
|
+
}
|
|
3521
|
+
);
|
|
3522
|
+
app.post(
|
|
3523
|
+
"/workspace/memory/forget",
|
|
3524
|
+
deps.mutate({ strict: true }),
|
|
3525
|
+
async (req, res) => {
|
|
3526
|
+
const body = deps.safeBody(req);
|
|
3527
|
+
const query = body["query"];
|
|
3528
|
+
const trimmedQuery = typeof query === "string" ? query.trim() : "";
|
|
3529
|
+
if (!trimmedQuery) {
|
|
3530
|
+
res.status(400).json({
|
|
3531
|
+
error: "`query` must be a non-empty string",
|
|
3532
|
+
code: "invalid_query"
|
|
3006
3533
|
});
|
|
3007
3534
|
return;
|
|
3008
3535
|
}
|
|
3009
|
-
|
|
3010
|
-
if (queryVoiceModel !== void 0 && typeof queryVoiceModel !== "string") {
|
|
3536
|
+
if (Buffer.byteLength(trimmedQuery, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
|
|
3011
3537
|
res.status(400).json({
|
|
3012
|
-
error:
|
|
3013
|
-
code: "
|
|
3538
|
+
error: `\`query\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`,
|
|
3539
|
+
code: "invalid_query"
|
|
3014
3540
|
});
|
|
3015
3541
|
return;
|
|
3016
3542
|
}
|
|
3017
|
-
const
|
|
3018
|
-
if (
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3543
|
+
const originatorClientId = validateOriginatorClientId(deps, req, res);
|
|
3544
|
+
if (originatorClientId === null) return;
|
|
3545
|
+
if (!await validateManagedMemoryAvailable(deps, res, "forget")) return;
|
|
3546
|
+
try {
|
|
3547
|
+
const task = deps.lane.enqueueForget({
|
|
3548
|
+
query: trimmedQuery,
|
|
3549
|
+
...originatorClientId ? { originatorClientId } : {}
|
|
3550
|
+
});
|
|
3551
|
+
res.status(202).json(task);
|
|
3552
|
+
} catch (err) {
|
|
3553
|
+
const code = extractRememberErrorCode(err, "forget_failed");
|
|
3554
|
+
res.status(publicErrorStatus(code)).json({
|
|
3555
|
+
error: publicErrorMessage(code, "forget"),
|
|
3556
|
+
code
|
|
3022
3557
|
});
|
|
3023
|
-
return;
|
|
3024
3558
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3559
|
+
}
|
|
3560
|
+
);
|
|
3561
|
+
app.get(
|
|
3562
|
+
"/workspace/memory/forget/:taskId",
|
|
3563
|
+
deps.mutate({ strict: true }),
|
|
3564
|
+
(req, res) => {
|
|
3565
|
+
const requesterClientId = validateOriginatorClientId(deps, req, res);
|
|
3566
|
+
if (requesterClientId === null) return;
|
|
3567
|
+
const task = deps.lane.get(
|
|
3568
|
+
req.params["taskId"],
|
|
3569
|
+
requesterClientId,
|
|
3570
|
+
"forget"
|
|
3571
|
+
);
|
|
3572
|
+
if (!task) {
|
|
3573
|
+
res.status(404).json({
|
|
3574
|
+
error: "Workspace memory forget task not found",
|
|
3575
|
+
code: "forget_task_not_found"
|
|
3030
3576
|
});
|
|
3031
3577
|
return;
|
|
3032
3578
|
}
|
|
3579
|
+
res.status(200).json(task);
|
|
3580
|
+
}
|
|
3581
|
+
);
|
|
3582
|
+
app.post(
|
|
3583
|
+
"/workspace/memory/dream",
|
|
3584
|
+
deps.mutate({ strict: true }),
|
|
3585
|
+
async (req, res) => {
|
|
3586
|
+
const originatorClientId = validateOriginatorClientId(deps, req, res);
|
|
3587
|
+
if (originatorClientId === null) return;
|
|
3588
|
+
if (!await validateManagedMemoryAvailable(deps, res, "dream")) return;
|
|
3033
3589
|
try {
|
|
3034
|
-
const
|
|
3035
|
-
|
|
3036
|
-
mimeType: audioContentType,
|
|
3037
|
-
voiceModel,
|
|
3038
|
-
settings,
|
|
3039
|
-
workspaceCwd: deps.boundWorkspace,
|
|
3040
|
-
abortSignal: requestAbortSignal2(req, res)
|
|
3590
|
+
const task = deps.lane.enqueueDream({
|
|
3591
|
+
...originatorClientId ? { originatorClientId } : {}
|
|
3041
3592
|
});
|
|
3042
|
-
res.status(
|
|
3593
|
+
res.status(202).json(task);
|
|
3043
3594
|
} catch (err) {
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
);
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3595
|
+
const code = extractRememberErrorCode(err, "dream_failed");
|
|
3596
|
+
res.status(publicErrorStatus(code)).json({
|
|
3597
|
+
error: publicErrorMessage(code, "dream"),
|
|
3598
|
+
code
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
}
|
|
3602
|
+
);
|
|
3603
|
+
app.get(
|
|
3604
|
+
"/workspace/memory/dream/:taskId",
|
|
3605
|
+
deps.mutate({ strict: true }),
|
|
3606
|
+
(req, res) => {
|
|
3607
|
+
const requesterClientId = validateOriginatorClientId(deps, req, res);
|
|
3608
|
+
if (requesterClientId === null) return;
|
|
3609
|
+
const task = deps.lane.get(
|
|
3610
|
+
req.params["taskId"],
|
|
3611
|
+
requesterClientId,
|
|
3612
|
+
"dream"
|
|
3613
|
+
);
|
|
3614
|
+
if (!task) {
|
|
3615
|
+
res.status(404).json({
|
|
3616
|
+
error: "Workspace memory dream task not found",
|
|
3617
|
+
code: "dream_task_not_found"
|
|
3052
3618
|
});
|
|
3619
|
+
return;
|
|
3053
3620
|
}
|
|
3621
|
+
res.status(200).json(task);
|
|
3054
3622
|
}
|
|
3055
3623
|
);
|
|
3056
3624
|
}
|
|
3057
|
-
__name(
|
|
3625
|
+
__name(mountWorkspaceMemoryRememberRoutes, "mountWorkspaceMemoryRememberRoutes");
|
|
3058
3626
|
|
|
3059
3627
|
// packages/cli/src/serve/workspace-memory.ts
|
|
3060
3628
|
init_esbuild_shims();
|
|
@@ -4569,6 +5137,7 @@ function errMsg(err) {
|
|
|
4569
5137
|
return err instanceof Error ? err.message : String(err);
|
|
4570
5138
|
}
|
|
4571
5139
|
__name(errMsg, "errMsg");
|
|
5140
|
+
var debugLogger2 = createDebugLogger("ACP_HTTP_DISPATCH");
|
|
4572
5141
|
var SESSION_SHELL_METHOD = `${QWEN_METHOD_NS}session/shell`;
|
|
4573
5142
|
var INVALID_PERMISSION_OUTCOME_ERROR = '`outcome` must be `{ outcome: "cancelled" }` or `{ outcome: "selected", optionId: string }`';
|
|
4574
5143
|
var ALL_QWEN_VENDOR_METHODS = [
|
|
@@ -4599,11 +5168,18 @@ var ALL_QWEN_VENDOR_METHODS = [
|
|
|
4599
5168
|
`${QWEN_METHOD_NS}session/context_usage`,
|
|
4600
5169
|
`${QWEN_METHOD_NS}session/tasks`,
|
|
4601
5170
|
`${QWEN_METHOD_NS}session/lsp`,
|
|
5171
|
+
`${QWEN_METHOD_NS}session/artifacts`,
|
|
5172
|
+
`${QWEN_METHOD_NS}session/artifacts/add`,
|
|
5173
|
+
`${QWEN_METHOD_NS}session/artifacts/remove`,
|
|
4602
5174
|
// Wave 1: memory
|
|
4603
5175
|
`${QWEN_METHOD_NS}workspace/memory`,
|
|
4604
5176
|
`${QWEN_METHOD_NS}workspace/memory/write`,
|
|
4605
5177
|
`${QWEN_METHOD_NS}workspace/memory/remember`,
|
|
4606
5178
|
`${QWEN_METHOD_NS}workspace/memory/remember/get`,
|
|
5179
|
+
`${QWEN_METHOD_NS}workspace/memory/forget`,
|
|
5180
|
+
`${QWEN_METHOD_NS}workspace/memory/forget/get`,
|
|
5181
|
+
`${QWEN_METHOD_NS}workspace/memory/dream`,
|
|
5182
|
+
`${QWEN_METHOD_NS}workspace/memory/dream/get`,
|
|
4607
5183
|
// Wave 1: files
|
|
4608
5184
|
`${QWEN_METHOD_NS}file/read`,
|
|
4609
5185
|
`${QWEN_METHOD_NS}file/read_bytes`,
|
|
@@ -4736,6 +5312,33 @@ function parsePermissionResponse(params) {
|
|
|
4736
5312
|
return response;
|
|
4737
5313
|
}
|
|
4738
5314
|
__name(parsePermissionResponse, "parsePermissionResponse");
|
|
5315
|
+
function pickSessionArtifactInput(params) {
|
|
5316
|
+
const {
|
|
5317
|
+
title,
|
|
5318
|
+
kind,
|
|
5319
|
+
storage,
|
|
5320
|
+
description,
|
|
5321
|
+
workspacePath,
|
|
5322
|
+
managedId,
|
|
5323
|
+
url,
|
|
5324
|
+
mimeType,
|
|
5325
|
+
sizeBytes,
|
|
5326
|
+
metadata
|
|
5327
|
+
} = params;
|
|
5328
|
+
return {
|
|
5329
|
+
title,
|
|
5330
|
+
kind,
|
|
5331
|
+
storage,
|
|
5332
|
+
description,
|
|
5333
|
+
workspacePath,
|
|
5334
|
+
managedId,
|
|
5335
|
+
url,
|
|
5336
|
+
mimeType,
|
|
5337
|
+
sizeBytes,
|
|
5338
|
+
metadata
|
|
5339
|
+
};
|
|
5340
|
+
}
|
|
5341
|
+
__name(pickSessionArtifactInput, "pickSessionArtifactInput");
|
|
4739
5342
|
function toRpcError(err) {
|
|
4740
5343
|
if (err instanceof AcpParamError || err instanceof InvalidCursorError) {
|
|
4741
5344
|
return { code: RPC.INVALID_PARAMS, message: err.message };
|
|
@@ -4816,6 +5419,16 @@ function toRpcError(err) {
|
|
|
4816
5419
|
data: { errorKind: "client_id_required" }
|
|
4817
5420
|
};
|
|
4818
5421
|
}
|
|
5422
|
+
if (err instanceof SessionArtifactValidationError) {
|
|
5423
|
+
return {
|
|
5424
|
+
code: RPC.INVALID_PARAMS,
|
|
5425
|
+
message: err.message,
|
|
5426
|
+
data: {
|
|
5427
|
+
errorKind: "artifact_validation_failed",
|
|
5428
|
+
...err.field ? { field: err.field } : {}
|
|
5429
|
+
}
|
|
5430
|
+
};
|
|
5431
|
+
}
|
|
4819
5432
|
const name = err instanceof Error ? err.name : "";
|
|
4820
5433
|
switch (name) {
|
|
4821
5434
|
case "SessionArchivedError":
|
|
@@ -6289,6 +6902,46 @@ var AcpDispatcher = class {
|
|
|
6289
6902
|
this.replyConn(conn, id, result);
|
|
6290
6903
|
return;
|
|
6291
6904
|
}
|
|
6905
|
+
case `${QWEN_METHOD_NS}session/artifacts`: {
|
|
6906
|
+
const sessionId = String(params["sessionId"] ?? "");
|
|
6907
|
+
if (!this.requireOwned(conn, sessionId, id)) return;
|
|
6908
|
+
const result = await this.bridge.getSessionArtifacts(sessionId);
|
|
6909
|
+
this.replyConn(conn, id, result);
|
|
6910
|
+
return;
|
|
6911
|
+
}
|
|
6912
|
+
case `${QWEN_METHOD_NS}session/artifacts/add`: {
|
|
6913
|
+
const sessionId = String(params["sessionId"] ?? "");
|
|
6914
|
+
await this.withMutableOwned(conn, sessionId, id, async () => {
|
|
6915
|
+
const result = await this.bridge.addSessionArtifact(
|
|
6916
|
+
sessionId,
|
|
6917
|
+
pickSessionArtifactInput(params),
|
|
6918
|
+
this.sessionCtx(conn, sessionId, loopback)
|
|
6919
|
+
);
|
|
6920
|
+
this.replyConn(conn, id, result);
|
|
6921
|
+
});
|
|
6922
|
+
return;
|
|
6923
|
+
}
|
|
6924
|
+
case `${QWEN_METHOD_NS}session/artifacts/remove`: {
|
|
6925
|
+
const sessionId = String(params["sessionId"] ?? "");
|
|
6926
|
+
await this.withMutableOwned(conn, sessionId, id, async () => {
|
|
6927
|
+
const artifactId = String(params["artifactId"] ?? "");
|
|
6928
|
+
if (!artifactId) {
|
|
6929
|
+
if (id !== void 0) {
|
|
6930
|
+
conn.sendConn(
|
|
6931
|
+
error(id, RPC.INVALID_PARAMS, "`artifactId` is required")
|
|
6932
|
+
);
|
|
6933
|
+
}
|
|
6934
|
+
return;
|
|
6935
|
+
}
|
|
6936
|
+
const result = await this.bridge.removeSessionArtifact(
|
|
6937
|
+
sessionId,
|
|
6938
|
+
artifactId,
|
|
6939
|
+
this.sessionCtx(conn, sessionId, loopback)
|
|
6940
|
+
);
|
|
6941
|
+
this.replyConn(conn, id, result);
|
|
6942
|
+
});
|
|
6943
|
+
return;
|
|
6944
|
+
}
|
|
6292
6945
|
case `${QWEN_METHOD_NS}workspace/memory`: {
|
|
6293
6946
|
const result = await collectWorkspaceMemoryStatus(
|
|
6294
6947
|
this.boundWorkspace
|
|
@@ -6439,23 +7092,186 @@ var AcpDispatcher = class {
|
|
|
6439
7092
|
this.replyConn(conn, id, task);
|
|
6440
7093
|
} catch (err) {
|
|
6441
7094
|
const code = extractRememberErrorCode(err);
|
|
7095
|
+
if (id !== void 0) {
|
|
7096
|
+
conn.sendConn(
|
|
7097
|
+
error(id, -32099, publicErrorMessage(code, "remember"), {
|
|
7098
|
+
errorKind: code,
|
|
7099
|
+
httpStatus: publicErrorStatus(code)
|
|
7100
|
+
})
|
|
7101
|
+
);
|
|
7102
|
+
} else {
|
|
7103
|
+
debugLogger2.warn(
|
|
7104
|
+
"workspace memory remember notification failed:",
|
|
7105
|
+
err
|
|
7106
|
+
);
|
|
7107
|
+
}
|
|
7108
|
+
}
|
|
7109
|
+
return;
|
|
7110
|
+
}
|
|
7111
|
+
case `${QWEN_METHOD_NS}workspace/memory/remember/get`: {
|
|
7112
|
+
const taskId = params["taskId"];
|
|
7113
|
+
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
7114
|
+
if (id !== void 0) {
|
|
7115
|
+
conn.sendConn(error(id, RPC.INVALID_PARAMS, "`taskId` required"));
|
|
7116
|
+
}
|
|
7117
|
+
return;
|
|
7118
|
+
}
|
|
7119
|
+
const task = this.workspaceRememberLane.get(
|
|
7120
|
+
taskId,
|
|
7121
|
+
conn.clientId,
|
|
7122
|
+
"remember"
|
|
7123
|
+
);
|
|
7124
|
+
if (!task) {
|
|
7125
|
+
if (id !== void 0) {
|
|
7126
|
+
conn.sendConn(
|
|
7127
|
+
error(id, -32004, "Workspace memory remember task not found", {
|
|
7128
|
+
errorKind: "remember_task_not_found",
|
|
7129
|
+
httpStatus: 404
|
|
7130
|
+
})
|
|
7131
|
+
);
|
|
7132
|
+
}
|
|
7133
|
+
return;
|
|
7134
|
+
}
|
|
7135
|
+
this.replyConn(conn, id, task);
|
|
7136
|
+
return;
|
|
7137
|
+
}
|
|
7138
|
+
case `${QWEN_METHOD_NS}workspace/memory/forget`: {
|
|
7139
|
+
const query = params["query"];
|
|
7140
|
+
const trimmedQuery = typeof query === "string" ? query.trim() : "";
|
|
7141
|
+
if (!trimmedQuery) {
|
|
6442
7142
|
if (id !== void 0) {
|
|
6443
7143
|
conn.sendConn(
|
|
6444
7144
|
error(
|
|
6445
7145
|
id,
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
7146
|
+
RPC.INVALID_PARAMS,
|
|
7147
|
+
"`query` must be a non-empty string"
|
|
7148
|
+
)
|
|
7149
|
+
);
|
|
7150
|
+
}
|
|
7151
|
+
return;
|
|
7152
|
+
}
|
|
7153
|
+
if (Buffer.byteLength(trimmedQuery, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
|
|
7154
|
+
if (id !== void 0) {
|
|
7155
|
+
conn.sendConn(
|
|
7156
|
+
error(
|
|
7157
|
+
id,
|
|
7158
|
+
RPC.INVALID_PARAMS,
|
|
7159
|
+
`\`query\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`
|
|
6452
7160
|
)
|
|
6453
7161
|
);
|
|
6454
7162
|
}
|
|
7163
|
+
return;
|
|
7164
|
+
}
|
|
7165
|
+
try {
|
|
7166
|
+
const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
|
|
7167
|
+
if (!available) {
|
|
7168
|
+
if (id !== void 0) {
|
|
7169
|
+
conn.sendConn(
|
|
7170
|
+
error(
|
|
7171
|
+
id,
|
|
7172
|
+
-32009,
|
|
7173
|
+
"Managed memory is unavailable for this daemon workspace",
|
|
7174
|
+
{
|
|
7175
|
+
errorKind: "managed_memory_unavailable",
|
|
7176
|
+
httpStatus: 409
|
|
7177
|
+
}
|
|
7178
|
+
)
|
|
7179
|
+
);
|
|
7180
|
+
}
|
|
7181
|
+
return;
|
|
7182
|
+
}
|
|
7183
|
+
const task = this.workspaceRememberLane.enqueueForget({
|
|
7184
|
+
query: trimmedQuery,
|
|
7185
|
+
...conn.clientId ? { originatorClientId: conn.clientId } : {}
|
|
7186
|
+
});
|
|
7187
|
+
this.replyConn(conn, id, task);
|
|
7188
|
+
} catch (err) {
|
|
7189
|
+
const code = extractRememberErrorCode(err, "forget_failed");
|
|
7190
|
+
if (id !== void 0) {
|
|
7191
|
+
conn.sendConn(
|
|
7192
|
+
error(id, -32099, publicErrorMessage(code, "forget"), {
|
|
7193
|
+
errorKind: code,
|
|
7194
|
+
httpStatus: publicErrorStatus(code)
|
|
7195
|
+
})
|
|
7196
|
+
);
|
|
7197
|
+
} else {
|
|
7198
|
+
debugLogger2.warn(
|
|
7199
|
+
"workspace memory forget notification failed:",
|
|
7200
|
+
err
|
|
7201
|
+
);
|
|
7202
|
+
}
|
|
7203
|
+
}
|
|
7204
|
+
return;
|
|
7205
|
+
}
|
|
7206
|
+
case `${QWEN_METHOD_NS}workspace/memory/forget/get`: {
|
|
7207
|
+
const taskId = params["taskId"];
|
|
7208
|
+
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
7209
|
+
if (id !== void 0) {
|
|
7210
|
+
conn.sendConn(error(id, RPC.INVALID_PARAMS, "`taskId` required"));
|
|
7211
|
+
}
|
|
7212
|
+
return;
|
|
7213
|
+
}
|
|
7214
|
+
const task = this.workspaceRememberLane.get(
|
|
7215
|
+
taskId,
|
|
7216
|
+
conn.clientId,
|
|
7217
|
+
"forget"
|
|
7218
|
+
);
|
|
7219
|
+
if (!task) {
|
|
7220
|
+
if (id !== void 0) {
|
|
7221
|
+
conn.sendConn(
|
|
7222
|
+
error(id, -32004, "Workspace memory forget task not found", {
|
|
7223
|
+
errorKind: "forget_task_not_found",
|
|
7224
|
+
httpStatus: 404
|
|
7225
|
+
})
|
|
7226
|
+
);
|
|
7227
|
+
}
|
|
7228
|
+
return;
|
|
7229
|
+
}
|
|
7230
|
+
this.replyConn(conn, id, task);
|
|
7231
|
+
return;
|
|
7232
|
+
}
|
|
7233
|
+
case `${QWEN_METHOD_NS}workspace/memory/dream`: {
|
|
7234
|
+
try {
|
|
7235
|
+
const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
|
|
7236
|
+
if (!available) {
|
|
7237
|
+
if (id !== void 0) {
|
|
7238
|
+
conn.sendConn(
|
|
7239
|
+
error(
|
|
7240
|
+
id,
|
|
7241
|
+
-32009,
|
|
7242
|
+
"Managed memory is unavailable for this daemon workspace",
|
|
7243
|
+
{
|
|
7244
|
+
errorKind: "managed_memory_unavailable",
|
|
7245
|
+
httpStatus: 409
|
|
7246
|
+
}
|
|
7247
|
+
)
|
|
7248
|
+
);
|
|
7249
|
+
}
|
|
7250
|
+
return;
|
|
7251
|
+
}
|
|
7252
|
+
const task = this.workspaceRememberLane.enqueueDream({
|
|
7253
|
+
...conn.clientId ? { originatorClientId: conn.clientId } : {}
|
|
7254
|
+
});
|
|
7255
|
+
this.replyConn(conn, id, task);
|
|
7256
|
+
} catch (err) {
|
|
7257
|
+
const code = extractRememberErrorCode(err, "dream_failed");
|
|
7258
|
+
if (id !== void 0) {
|
|
7259
|
+
conn.sendConn(
|
|
7260
|
+
error(id, -32099, publicErrorMessage(code, "dream"), {
|
|
7261
|
+
errorKind: code,
|
|
7262
|
+
httpStatus: publicErrorStatus(code)
|
|
7263
|
+
})
|
|
7264
|
+
);
|
|
7265
|
+
} else {
|
|
7266
|
+
debugLogger2.warn(
|
|
7267
|
+
"workspace memory dream notification failed:",
|
|
7268
|
+
err
|
|
7269
|
+
);
|
|
7270
|
+
}
|
|
6455
7271
|
}
|
|
6456
7272
|
return;
|
|
6457
7273
|
}
|
|
6458
|
-
case `${QWEN_METHOD_NS}workspace/memory/
|
|
7274
|
+
case `${QWEN_METHOD_NS}workspace/memory/dream/get`: {
|
|
6459
7275
|
const taskId = params["taskId"];
|
|
6460
7276
|
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
6461
7277
|
if (id !== void 0) {
|
|
@@ -6463,12 +7279,16 @@ var AcpDispatcher = class {
|
|
|
6463
7279
|
}
|
|
6464
7280
|
return;
|
|
6465
7281
|
}
|
|
6466
|
-
const task = this.workspaceRememberLane.get(
|
|
7282
|
+
const task = this.workspaceRememberLane.get(
|
|
7283
|
+
taskId,
|
|
7284
|
+
conn.clientId,
|
|
7285
|
+
"dream"
|
|
7286
|
+
);
|
|
6467
7287
|
if (!task) {
|
|
6468
7288
|
if (id !== void 0) {
|
|
6469
7289
|
conn.sendConn(
|
|
6470
|
-
error(id, -32004, "Workspace memory
|
|
6471
|
-
errorKind: "
|
|
7290
|
+
error(id, -32004, "Workspace memory dream task not found", {
|
|
7291
|
+
errorKind: "dream_task_not_found",
|
|
6472
7292
|
httpStatus: 404
|
|
6473
7293
|
})
|
|
6474
7294
|
);
|
|
@@ -7561,7 +8381,7 @@ var AcpDispatcher = class {
|
|
|
7561
8381
|
|
|
7562
8382
|
// packages/cli/src/serve/acp-http/connection-registry.ts
|
|
7563
8383
|
init_esbuild_shims();
|
|
7564
|
-
import { randomUUID } from "node:crypto";
|
|
8384
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
7565
8385
|
var MAX_BUFFERED_FRAMES = 256;
|
|
7566
8386
|
var HARD_BUFFERED_FRAMES_CAP = MAX_BUFFERED_FRAMES * 4;
|
|
7567
8387
|
var DEFAULT_MAX_CONNECTIONS = 64;
|
|
@@ -7569,8 +8389,8 @@ var AcpConnection = class {
|
|
|
7569
8389
|
constructor(connectionId, fromLoopback, onAbandonPending, onDetachSession) {
|
|
7570
8390
|
this.onAbandonPending = onAbandonPending;
|
|
7571
8391
|
this.onDetachSession = onDetachSession;
|
|
7572
|
-
this.connectionId = connectionId ??
|
|
7573
|
-
this.clientId =
|
|
8392
|
+
this.connectionId = connectionId ?? randomUUID2();
|
|
8393
|
+
this.clientId = randomUUID2();
|
|
7574
8394
|
this.fromLoopback = fromLoopback;
|
|
7575
8395
|
}
|
|
7576
8396
|
static {
|
|
@@ -9306,6 +10126,7 @@ var WS_READ_METHODS = /* @__PURE__ */ new Set([
|
|
|
9306
10126
|
"_qwen/session/context_usage",
|
|
9307
10127
|
"_qwen/session/tasks",
|
|
9308
10128
|
"_qwen/session/lsp",
|
|
10129
|
+
"_qwen/session/artifacts",
|
|
9309
10130
|
"_qwen/workspace/mcp",
|
|
9310
10131
|
"_qwen/workspace/skills",
|
|
9311
10132
|
"_qwen/workspace/providers",
|
|
@@ -9321,6 +10142,8 @@ var WS_READ_METHODS = /* @__PURE__ */ new Set([
|
|
|
9321
10142
|
"_qwen/workspace/agents/get",
|
|
9322
10143
|
"_qwen/workspace/memory",
|
|
9323
10144
|
"_qwen/workspace/memory/remember/get",
|
|
10145
|
+
"_qwen/workspace/memory/forget/get",
|
|
10146
|
+
"_qwen/workspace/memory/dream/get",
|
|
9324
10147
|
"_qwen/workspace/auth/status",
|
|
9325
10148
|
"_qwen/workspace/auth/device_flow/get",
|
|
9326
10149
|
"_qwen/file/read",
|
|
@@ -10228,7 +11051,7 @@ function loadDaemonVoiceContext(workspaceCwd) {
|
|
|
10228
11051
|
__name(loadDaemonVoiceContext, "loadDaemonVoiceContext");
|
|
10229
11052
|
|
|
10230
11053
|
// packages/cli/src/serve/voice/voice-ws.ts
|
|
10231
|
-
var
|
|
11054
|
+
var debugLogger3 = createDebugLogger("VOICE_WS");
|
|
10232
11055
|
var MAX_BATCH_AUDIO_BYTES = 10 * 1024 * 1024;
|
|
10233
11056
|
var MAX_QUEUED_AUDIO_BYTES = MAX_BATCH_AUDIO_BYTES * 2;
|
|
10234
11057
|
var MAX_CONNECTION_MS = 6 * 6e4;
|
|
@@ -10267,7 +11090,7 @@ async function defaultOpenStream(ctx, callbacks) {
|
|
|
10267
11090
|
() => cfg.transport === "qwen-asr-realtime" ? openQwenAsrRealtimeStream(cfg, callbacks) : openVoiceStream(cfg, callbacks)
|
|
10268
11091
|
);
|
|
10269
11092
|
} catch (error2) {
|
|
10270
|
-
|
|
11093
|
+
debugLogger3.debug(`[voice-ws] stream open error: ${errMessage(error2)}`);
|
|
10271
11094
|
throw new Error(GENERIC_TRANSCRIPTION_ERROR);
|
|
10272
11095
|
}
|
|
10273
11096
|
}
|
|
@@ -10277,7 +11100,7 @@ function defaultTranscribe(ctx, pcm) {
|
|
|
10277
11100
|
{ data: encodeWav(pcm), mimeType: "audio/wav" },
|
|
10278
11101
|
{ config: ctx.models, settings: ctx.settings, voiceModel: ctx.voiceModel }
|
|
10279
11102
|
).catch((error2) => {
|
|
10280
|
-
|
|
11103
|
+
debugLogger3.debug(
|
|
10281
11104
|
`[voice-ws] batch transcription error: ${errMessage(error2)}`
|
|
10282
11105
|
);
|
|
10283
11106
|
throw new Error(GENERIC_TRANSCRIPTION_ERROR);
|
|
@@ -10407,7 +11230,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10407
11230
|
try {
|
|
10408
11231
|
ctx = loadContext(boundWorkspace);
|
|
10409
11232
|
} catch (error2) {
|
|
10410
|
-
|
|
11233
|
+
debugLogger3.debug(
|
|
10411
11234
|
`[voice-ws] load context error: ${errMessage(error2)}`
|
|
10412
11235
|
);
|
|
10413
11236
|
fail(voiceConfigErrorMessage(error2));
|
|
@@ -10422,7 +11245,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10422
11245
|
const callbacks = {
|
|
10423
11246
|
onInterim: /* @__PURE__ */ __name((text) => sendJson({ type: "interim", text }), "onInterim"),
|
|
10424
11247
|
onError: /* @__PURE__ */ __name((error2) => {
|
|
10425
|
-
|
|
11248
|
+
debugLogger3.debug(
|
|
10426
11249
|
`[voice-ws] upstream error: ${errMessage(error2)}`
|
|
10427
11250
|
);
|
|
10428
11251
|
fail(GENERIC_TRANSCRIPTION_ERROR);
|
|
@@ -10541,7 +11364,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10541
11364
|
releaseSlotWhenIdle();
|
|
10542
11365
|
}
|
|
10543
11366
|
}).catch((error2) => {
|
|
10544
|
-
|
|
11367
|
+
debugLogger3.debug(`[voice-ws] ${errMessage(error2)}`);
|
|
10545
11368
|
fail(GENERIC_TRANSCRIPTION_ERROR);
|
|
10546
11369
|
releaseSlotWhenIdle();
|
|
10547
11370
|
});
|
|
@@ -10551,7 +11374,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10551
11374
|
releaseSlotWhenIdle();
|
|
10552
11375
|
});
|
|
10553
11376
|
ws.on("error", (error2) => {
|
|
10554
|
-
|
|
11377
|
+
debugLogger3.debug(`[voice-ws] socket error: ${error2.message}`);
|
|
10555
11378
|
if (state !== "closed") cleanup();
|
|
10556
11379
|
releaseSlotWhenIdle();
|
|
10557
11380
|
});
|
|
@@ -10597,369 +11420,112 @@ var CdpTunnelRegistry = class {
|
|
|
10597
11420
|
return this.active !== void 0;
|
|
10598
11421
|
}
|
|
10599
11422
|
/**
|
|
10600
|
-
* Route an inbound `cdp_*` frame (from the extension `/acp` socket) to the
|
|
10601
|
-
* active bridge's bound reverse link. Returns true if consumed.
|
|
10602
|
-
*/
|
|
10603
|
-
routeInbound(frame) {
|
|
10604
|
-
return this.active ? this.active.routeInbound(frame) : false;
|
|
10605
|
-
}
|
|
10606
|
-
};
|
|
10607
|
-
|
|
10608
|
-
// packages/cli/src/serve/web-shell-static.ts
|
|
10609
|
-
init_esbuild_shims();
|
|
10610
|
-
var import_express2 = __toESM(require_express(), 1);
|
|
10611
|
-
import * as path9 from "node:path";
|
|
10612
|
-
var WEB_SHELL_CSP_DIRECTIVES = [
|
|
10613
|
-
"default-src 'self'",
|
|
10614
|
-
"script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'",
|
|
10615
|
-
"style-src 'self' 'unsafe-inline'",
|
|
10616
|
-
"font-src 'self' data:",
|
|
10617
|
-
"img-src 'self' data: blob:",
|
|
10618
|
-
"connect-src 'self'",
|
|
10619
|
-
"worker-src 'self' blob:",
|
|
10620
|
-
// base-uri does NOT fall back to default-src; lock it so an injected <base>
|
|
10621
|
-
// (the SPA renders AI-generated markdown) cannot repoint relative URLs to an
|
|
10622
|
-
// attacker origin.
|
|
10623
|
-
"base-uri 'none'"
|
|
10624
|
-
];
|
|
10625
|
-
function buildWebShellCsp(frameAncestors = []) {
|
|
10626
|
-
const fa = frameAncestors.length ? `frame-ancestors ${frameAncestors.join(" ")}` : "frame-ancestors 'none'";
|
|
10627
|
-
return [...WEB_SHELL_CSP_DIRECTIVES, fa].join("; ");
|
|
10628
|
-
}
|
|
10629
|
-
__name(buildWebShellCsp, "buildWebShellCsp");
|
|
10630
|
-
var WEB_SHELL_CSP = buildWebShellCsp();
|
|
10631
|
-
function isDocumentNavigation(req) {
|
|
10632
|
-
const fetchMode = req.headers["sec-fetch-mode"];
|
|
10633
|
-
const fetchDest = req.headers["sec-fetch-dest"];
|
|
10634
|
-
const accept = req.headers.accept ?? "";
|
|
10635
|
-
return fetchMode === "navigate" || fetchDest === "document" || accept.trim().toLowerCase().startsWith("text/html");
|
|
10636
|
-
}
|
|
10637
|
-
__name(isDocumentNavigation, "isDocumentNavigation");
|
|
10638
|
-
function createSendIndex(webShellDir, frameAncestors = []) {
|
|
10639
|
-
const indexPath = path9.join(webShellDir, "index.html");
|
|
10640
|
-
const csp = buildWebShellCsp(frameAncestors);
|
|
10641
|
-
return (res) => {
|
|
10642
|
-
res.status(200).set("Content-Security-Policy", csp).set("X-Content-Type-Options", "nosniff").set("Referrer-Policy", "no-referrer").set(
|
|
10643
|
-
// `microphone=(self)` lets the same-origin Web Shell document request
|
|
10644
|
-
// the mic for voice dictation (the prompt won't even appear under an
|
|
10645
|
-
// empty `microphone=()` allowlist). Still blocks cross-origin iframes;
|
|
10646
|
-
// camera/geolocation/payment stay disabled (unused).
|
|
10647
|
-
"Permissions-Policy",
|
|
10648
|
-
"camera=(), microphone=(self), geolocation=(), payment=()"
|
|
10649
|
-
).set("Cache-Control", "no-cache");
|
|
10650
|
-
if (frameAncestors.length === 0) {
|
|
10651
|
-
res.set("X-Frame-Options", "DENY");
|
|
10652
|
-
}
|
|
10653
|
-
res.sendFile(
|
|
10654
|
-
indexPath,
|
|
10655
|
-
{ cacheControl: false, dotfiles: "allow" },
|
|
10656
|
-
(err) => {
|
|
10657
|
-
if (!err) return;
|
|
10658
|
-
writeStderrLine(
|
|
10659
|
-
`qwen serve: Web Shell index send failed: ${err instanceof Error ? err.message : String(err)}`
|
|
10660
|
-
);
|
|
10661
|
-
if (!res.headersSent) {
|
|
10662
|
-
res.status(500).type("text/plain").send("Failed to load Web Shell");
|
|
10663
|
-
} else {
|
|
10664
|
-
res.end();
|
|
10665
|
-
}
|
|
10666
|
-
}
|
|
10667
|
-
);
|
|
10668
|
-
};
|
|
10669
|
-
}
|
|
10670
|
-
__name(createSendIndex, "createSendIndex");
|
|
10671
|
-
function mountWebShellAssets(app, webShellDir, frameAncestors = []) {
|
|
10672
|
-
const sendIndex = createSendIndex(webShellDir, frameAncestors);
|
|
10673
|
-
app.use(
|
|
10674
|
-
"/assets",
|
|
10675
|
-
import_express2.default.static(path9.join(webShellDir, "assets"), {
|
|
10676
|
-
index: false,
|
|
10677
|
-
immutable: true,
|
|
10678
|
-
maxAge: "1y"
|
|
10679
|
-
})
|
|
10680
|
-
);
|
|
10681
|
-
app.use("/assets", (req, res) => {
|
|
10682
|
-
if (isServeDebugMode()) {
|
|
10683
|
-
writeStderrLine(
|
|
10684
|
-
`qwen serve: Web Shell asset not found: ${req.originalUrl}`
|
|
10685
|
-
);
|
|
10686
|
-
}
|
|
10687
|
-
res.status(404).type("text/plain").send("Not found");
|
|
10688
|
-
});
|
|
10689
|
-
app.get("/", (_req, res) => sendIndex(res));
|
|
10690
|
-
}
|
|
10691
|
-
__name(mountWebShellAssets, "mountWebShellAssets");
|
|
10692
|
-
function mountWebShellSpaFallback(app, webShellDir, frameAncestors = []) {
|
|
10693
|
-
const sendIndex = createSendIndex(webShellDir, frameAncestors);
|
|
10694
|
-
app.use((req, res, next) => {
|
|
10695
|
-
if (req.method !== "GET" && req.method !== "HEAD") return next();
|
|
10696
|
-
if (!isDocumentNavigation(req)) return next();
|
|
10697
|
-
if (isServeDebugMode()) {
|
|
10698
|
-
writeStderrLine(
|
|
10699
|
-
`qwen serve: Web Shell SPA fallback served for ${req.method} ${req.originalUrl}`
|
|
10700
|
-
);
|
|
10701
|
-
}
|
|
10702
|
-
sendIndex(res);
|
|
10703
|
-
});
|
|
10704
|
-
}
|
|
10705
|
-
__name(mountWebShellSpaFallback, "mountWebShellSpaFallback");
|
|
10706
|
-
|
|
10707
|
-
// packages/cli/src/serve/workspace-remember.ts
|
|
10708
|
-
init_esbuild_shims();
|
|
10709
|
-
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
10710
|
-
var debugLogger2 = createDebugLogger("WORKSPACE_REMEMBER");
|
|
10711
|
-
function nowIso() {
|
|
10712
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
10713
|
-
}
|
|
10714
|
-
__name(nowIso, "nowIso");
|
|
10715
|
-
function createRememberTaskId() {
|
|
10716
|
-
return `remember-${randomUUID2()}`;
|
|
10717
|
-
}
|
|
10718
|
-
__name(createRememberTaskId, "createRememberTaskId");
|
|
10719
|
-
function cloneTask(task) {
|
|
10720
|
-
return {
|
|
10721
|
-
taskId: task.taskId,
|
|
10722
|
-
status: task.status,
|
|
10723
|
-
contextMode: task.contextMode,
|
|
10724
|
-
createdAt: task.createdAt,
|
|
10725
|
-
updatedAt: task.updatedAt,
|
|
10726
|
-
result: task.result ? {
|
|
10727
|
-
...task.result,
|
|
10728
|
-
filesTouched: [...task.result.filesTouched],
|
|
10729
|
-
touchedScopes: [...task.result.touchedScopes]
|
|
10730
|
-
} : void 0,
|
|
10731
|
-
error: task.error ? { ...task.error } : void 0
|
|
10732
|
-
};
|
|
10733
|
-
}
|
|
10734
|
-
__name(cloneTask, "cloneTask");
|
|
10735
|
-
function publicErrorMessage(code) {
|
|
10736
|
-
if (code === "managed_memory_unavailable") {
|
|
10737
|
-
return "Managed memory is unavailable for this daemon workspace.";
|
|
10738
|
-
}
|
|
10739
|
-
if (code === "remember_path_escape") {
|
|
10740
|
-
return "Remember agent touched a path outside managed memory.";
|
|
10741
|
-
}
|
|
10742
|
-
if (code === "remember_queue_full") {
|
|
10743
|
-
return "Workspace memory remember queue is full.";
|
|
10744
|
-
}
|
|
10745
|
-
if (code === "remember_timeout") {
|
|
10746
|
-
return "Workspace memory remember timed out.";
|
|
10747
|
-
}
|
|
10748
|
-
return "Workspace memory remember failed.";
|
|
10749
|
-
}
|
|
10750
|
-
__name(publicErrorMessage, "publicErrorMessage");
|
|
10751
|
-
function publicErrorStatus(code) {
|
|
10752
|
-
if (code === "remember_queue_full") return 429;
|
|
10753
|
-
if (code === "managed_memory_unavailable") return 409;
|
|
10754
|
-
return 500;
|
|
10755
|
-
}
|
|
10756
|
-
__name(publicErrorStatus, "publicErrorStatus");
|
|
10757
|
-
var WorkspaceRememberTaskLane = class _WorkspaceRememberTaskLane {
|
|
10758
|
-
constructor(bridge) {
|
|
10759
|
-
this.bridge = bridge;
|
|
10760
|
-
}
|
|
10761
|
-
static {
|
|
10762
|
-
__name(this, "WorkspaceRememberTaskLane");
|
|
10763
|
-
}
|
|
10764
|
-
static MAX_TASKS = 1e3;
|
|
10765
|
-
static MAX_PENDING = 16;
|
|
10766
|
-
tasks = /* @__PURE__ */ new Map();
|
|
10767
|
-
tail = Promise.resolve();
|
|
10768
|
-
pendingCount() {
|
|
10769
|
-
let count = 0;
|
|
10770
|
-
for (const task of this.tasks.values()) {
|
|
10771
|
-
if (task.status === "queued" || task.status === "running") count++;
|
|
10772
|
-
}
|
|
10773
|
-
return count;
|
|
10774
|
-
}
|
|
10775
|
-
evictTerminalTasks() {
|
|
10776
|
-
if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) return;
|
|
10777
|
-
for (const [id, task] of this.tasks) {
|
|
10778
|
-
if (task.status === "completed" || task.status === "failed") {
|
|
10779
|
-
this.tasks.delete(id);
|
|
10780
|
-
if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) break;
|
|
10781
|
-
}
|
|
10782
|
-
}
|
|
10783
|
-
}
|
|
10784
|
-
enqueue(params) {
|
|
10785
|
-
if (this.pendingCount() >= _WorkspaceRememberTaskLane.MAX_PENDING) {
|
|
10786
|
-
throw Object.assign(new Error("Remember queue is full"), {
|
|
10787
|
-
code: "remember_queue_full"
|
|
10788
|
-
});
|
|
10789
|
-
}
|
|
10790
|
-
const task = {
|
|
10791
|
-
taskId: createRememberTaskId(),
|
|
10792
|
-
status: "queued",
|
|
10793
|
-
contextMode: params.contextMode,
|
|
10794
|
-
createdAt: nowIso(),
|
|
10795
|
-
updatedAt: nowIso(),
|
|
10796
|
-
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
10797
|
-
};
|
|
10798
|
-
this.tasks.set(task.taskId, task);
|
|
10799
|
-
this.evictTerminalTasks();
|
|
10800
|
-
const run = /* @__PURE__ */ __name(async () => {
|
|
10801
|
-
task.status = "running";
|
|
10802
|
-
task.updatedAt = nowIso();
|
|
10803
|
-
try {
|
|
10804
|
-
const result = await this.bridge.runWorkspaceMemoryRemember({
|
|
10805
|
-
content: params.content,
|
|
10806
|
-
contextMode: params.contextMode
|
|
10807
|
-
});
|
|
10808
|
-
task.status = "completed";
|
|
10809
|
-
task.result = {
|
|
10810
|
-
summary: result.filesTouched.length > 0 ? "Memory update completed." : "No memory files updated.",
|
|
10811
|
-
filesTouched: result.filesTouched,
|
|
10812
|
-
touchedScopes: result.touchedScopes
|
|
10813
|
-
};
|
|
10814
|
-
task.updatedAt = nowIso();
|
|
10815
|
-
} catch (err) {
|
|
10816
|
-
const code = extractRememberErrorCode(err);
|
|
10817
|
-
debugLogger2.error("Remember task failed:", err);
|
|
10818
|
-
task.status = "failed";
|
|
10819
|
-
task.error = {
|
|
10820
|
-
code,
|
|
10821
|
-
message: publicErrorMessage(code)
|
|
10822
|
-
};
|
|
10823
|
-
task.updatedAt = nowIso();
|
|
10824
|
-
} finally {
|
|
10825
|
-
this.evictTerminalTasks();
|
|
10826
|
-
}
|
|
10827
|
-
if (task.status === "completed" && task.result && task.result.touchedScopes.length > 0) {
|
|
10828
|
-
try {
|
|
10829
|
-
this.bridge.publishWorkspaceEvent({
|
|
10830
|
-
type: "memory_changed",
|
|
10831
|
-
data: {
|
|
10832
|
-
scope: "managed",
|
|
10833
|
-
source: "workspace_memory_remember",
|
|
10834
|
-
taskId: task.taskId,
|
|
10835
|
-
touchedScopes: task.result.touchedScopes
|
|
10836
|
-
},
|
|
10837
|
-
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
10838
|
-
});
|
|
10839
|
-
} catch (err) {
|
|
10840
|
-
debugLogger2.error("Failed to publish memory_changed event:", err);
|
|
10841
|
-
}
|
|
10842
|
-
}
|
|
10843
|
-
}, "run");
|
|
10844
|
-
this.tail = this.tail.then(run, run);
|
|
10845
|
-
void this.tail.catch((err) => {
|
|
10846
|
-
debugLogger2.error("Unhandled task lane error:", err);
|
|
10847
|
-
});
|
|
10848
|
-
return cloneTask(task);
|
|
10849
|
-
}
|
|
10850
|
-
get(taskId, requesterClientId) {
|
|
10851
|
-
const task = this.tasks.get(taskId);
|
|
10852
|
-
if (!task) return void 0;
|
|
10853
|
-
if (task.originatorClientId) {
|
|
10854
|
-
if (task.originatorClientId !== requesterClientId) return void 0;
|
|
10855
|
-
} else if (requesterClientId) {
|
|
10856
|
-
return void 0;
|
|
10857
|
-
}
|
|
10858
|
-
return cloneTask(task);
|
|
10859
|
-
}
|
|
10860
|
-
};
|
|
10861
|
-
function validateOriginatorClientId(deps, req, res) {
|
|
10862
|
-
const clientId = deps.parseClientId(req, res);
|
|
10863
|
-
if (clientId === null) return null;
|
|
10864
|
-
if (clientId === void 0) return void 0;
|
|
10865
|
-
const known = deps.bridge.knownClientIds();
|
|
10866
|
-
if (!known.has(clientId)) {
|
|
10867
|
-
res.status(400).json({
|
|
10868
|
-
error: `Client id "${clientId}" is not registered for this workspace`,
|
|
10869
|
-
code: "invalid_client_id",
|
|
10870
|
-
clientId
|
|
10871
|
-
});
|
|
10872
|
-
return null;
|
|
11423
|
+
* Route an inbound `cdp_*` frame (from the extension `/acp` socket) to the
|
|
11424
|
+
* active bridge's bound reverse link. Returns true if consumed.
|
|
11425
|
+
*/
|
|
11426
|
+
routeInbound(frame) {
|
|
11427
|
+
return this.active ? this.active.routeInbound(frame) : false;
|
|
10873
11428
|
}
|
|
10874
|
-
|
|
11429
|
+
};
|
|
11430
|
+
|
|
11431
|
+
// packages/cli/src/serve/web-shell-static.ts
|
|
11432
|
+
init_esbuild_shims();
|
|
11433
|
+
var import_express2 = __toESM(require_express(), 1);
|
|
11434
|
+
import * as path9 from "node:path";
|
|
11435
|
+
var WEB_SHELL_CSP_DIRECTIVES = [
|
|
11436
|
+
"default-src 'self'",
|
|
11437
|
+
"script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'",
|
|
11438
|
+
"style-src 'self' 'unsafe-inline'",
|
|
11439
|
+
"font-src 'self' data:",
|
|
11440
|
+
"img-src 'self' data: blob:",
|
|
11441
|
+
"connect-src 'self'",
|
|
11442
|
+
"worker-src 'self' blob:",
|
|
11443
|
+
// base-uri does NOT fall back to default-src; lock it so an injected <base>
|
|
11444
|
+
// (the SPA renders AI-generated markdown) cannot repoint relative URLs to an
|
|
11445
|
+
// attacker origin.
|
|
11446
|
+
"base-uri 'none'"
|
|
11447
|
+
];
|
|
11448
|
+
function buildWebShellCsp(frameAncestors = []) {
|
|
11449
|
+
const fa = frameAncestors.length ? `frame-ancestors ${frameAncestors.join(" ")}` : "frame-ancestors 'none'";
|
|
11450
|
+
return [...WEB_SHELL_CSP_DIRECTIVES, fa].join("; ");
|
|
10875
11451
|
}
|
|
10876
|
-
__name(
|
|
10877
|
-
|
|
10878
|
-
|
|
10879
|
-
|
|
10880
|
-
|
|
10881
|
-
|
|
10882
|
-
|
|
10883
|
-
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10889
|
-
|
|
10890
|
-
|
|
10891
|
-
|
|
10892
|
-
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
|
|
10896
|
-
|
|
10897
|
-
|
|
10898
|
-
|
|
10899
|
-
|
|
10900
|
-
|
|
10901
|
-
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10907
|
-
|
|
10908
|
-
|
|
10909
|
-
|
|
10910
|
-
|
|
10911
|
-
|
|
10912
|
-
res.status(409).json({
|
|
10913
|
-
error: "Managed memory is unavailable for this daemon workspace",
|
|
10914
|
-
code: "managed_memory_unavailable"
|
|
10915
|
-
});
|
|
10916
|
-
return;
|
|
11452
|
+
__name(buildWebShellCsp, "buildWebShellCsp");
|
|
11453
|
+
var WEB_SHELL_CSP = buildWebShellCsp();
|
|
11454
|
+
function isDocumentNavigation(req) {
|
|
11455
|
+
const fetchMode = req.headers["sec-fetch-mode"];
|
|
11456
|
+
const fetchDest = req.headers["sec-fetch-dest"];
|
|
11457
|
+
const accept = req.headers.accept ?? "";
|
|
11458
|
+
return fetchMode === "navigate" || fetchDest === "document" || accept.trim().toLowerCase().startsWith("text/html");
|
|
11459
|
+
}
|
|
11460
|
+
__name(isDocumentNavigation, "isDocumentNavigation");
|
|
11461
|
+
function createSendIndex(webShellDir, frameAncestors = []) {
|
|
11462
|
+
const indexPath = path9.join(webShellDir, "index.html");
|
|
11463
|
+
const csp = buildWebShellCsp(frameAncestors);
|
|
11464
|
+
return (res) => {
|
|
11465
|
+
res.status(200).set("Content-Security-Policy", csp).set("X-Content-Type-Options", "nosniff").set("Referrer-Policy", "no-referrer").set(
|
|
11466
|
+
// `microphone=(self)` lets the same-origin Web Shell document request
|
|
11467
|
+
// the mic for voice dictation (the prompt won't even appear under an
|
|
11468
|
+
// empty `microphone=()` allowlist). Still blocks cross-origin iframes;
|
|
11469
|
+
// camera/geolocation/payment stay disabled (unused).
|
|
11470
|
+
"Permissions-Policy",
|
|
11471
|
+
"camera=(), microphone=(self), geolocation=(), payment=()"
|
|
11472
|
+
).set("Cache-Control", "no-cache");
|
|
11473
|
+
if (frameAncestors.length === 0) {
|
|
11474
|
+
res.set("X-Frame-Options", "DENY");
|
|
11475
|
+
}
|
|
11476
|
+
res.sendFile(
|
|
11477
|
+
indexPath,
|
|
11478
|
+
{ cacheControl: false, dotfiles: "allow" },
|
|
11479
|
+
(err) => {
|
|
11480
|
+
if (!err) return;
|
|
11481
|
+
writeStderrLine(
|
|
11482
|
+
`qwen serve: Web Shell index send failed: ${err instanceof Error ? err.message : String(err)}`
|
|
11483
|
+
);
|
|
11484
|
+
if (!res.headersSent) {
|
|
11485
|
+
res.status(500).type("text/plain").send("Failed to load Web Shell");
|
|
11486
|
+
} else {
|
|
11487
|
+
res.end();
|
|
10917
11488
|
}
|
|
10918
|
-
} catch (err) {
|
|
10919
|
-
debugLogger2.error("Availability check failed:", err);
|
|
10920
|
-
res.status(500).json({
|
|
10921
|
-
error: "Workspace memory remember failed.",
|
|
10922
|
-
code: "remember_failed"
|
|
10923
|
-
});
|
|
10924
|
-
return;
|
|
10925
|
-
}
|
|
10926
|
-
let task;
|
|
10927
|
-
try {
|
|
10928
|
-
task = deps.lane.enqueue({
|
|
10929
|
-
content: trimmedContent,
|
|
10930
|
-
contextMode: contextModeRaw,
|
|
10931
|
-
...originatorClientId ? { originatorClientId } : {}
|
|
10932
|
-
});
|
|
10933
|
-
} catch (err) {
|
|
10934
|
-
const code = extractRememberErrorCode(err);
|
|
10935
|
-
res.status(publicErrorStatus(code)).json({
|
|
10936
|
-
error: publicErrorMessage(code),
|
|
10937
|
-
code
|
|
10938
|
-
});
|
|
10939
|
-
return;
|
|
10940
11489
|
}
|
|
10941
|
-
|
|
10942
|
-
|
|
11490
|
+
);
|
|
11491
|
+
};
|
|
11492
|
+
}
|
|
11493
|
+
__name(createSendIndex, "createSendIndex");
|
|
11494
|
+
function mountWebShellAssets(app, webShellDir, frameAncestors = []) {
|
|
11495
|
+
const sendIndex = createSendIndex(webShellDir, frameAncestors);
|
|
11496
|
+
app.use(
|
|
11497
|
+
"/assets",
|
|
11498
|
+
import_express2.default.static(path9.join(webShellDir, "assets"), {
|
|
11499
|
+
index: false,
|
|
11500
|
+
immutable: true,
|
|
11501
|
+
maxAge: "1y"
|
|
11502
|
+
})
|
|
10943
11503
|
);
|
|
10944
|
-
app.
|
|
10945
|
-
|
|
10946
|
-
|
|
10947
|
-
|
|
10948
|
-
|
|
10949
|
-
if (requesterClientId === null) return;
|
|
10950
|
-
const task = deps.lane.get(req.params["taskId"], requesterClientId);
|
|
10951
|
-
if (!task) {
|
|
10952
|
-
res.status(404).json({
|
|
10953
|
-
error: "Workspace memory remember task not found",
|
|
10954
|
-
code: "remember_task_not_found"
|
|
10955
|
-
});
|
|
10956
|
-
return;
|
|
10957
|
-
}
|
|
10958
|
-
res.status(200).json(task);
|
|
11504
|
+
app.use("/assets", (req, res) => {
|
|
11505
|
+
if (isServeDebugMode()) {
|
|
11506
|
+
writeStderrLine(
|
|
11507
|
+
`qwen serve: Web Shell asset not found: ${req.originalUrl}`
|
|
11508
|
+
);
|
|
10959
11509
|
}
|
|
10960
|
-
|
|
11510
|
+
res.status(404).type("text/plain").send("Not found");
|
|
11511
|
+
});
|
|
11512
|
+
app.get("/", (_req, res) => sendIndex(res));
|
|
10961
11513
|
}
|
|
10962
|
-
__name(
|
|
11514
|
+
__name(mountWebShellAssets, "mountWebShellAssets");
|
|
11515
|
+
function mountWebShellSpaFallback(app, webShellDir, frameAncestors = []) {
|
|
11516
|
+
const sendIndex = createSendIndex(webShellDir, frameAncestors);
|
|
11517
|
+
app.use((req, res, next) => {
|
|
11518
|
+
if (req.method !== "GET" && req.method !== "HEAD") return next();
|
|
11519
|
+
if (!isDocumentNavigation(req)) return next();
|
|
11520
|
+
if (isServeDebugMode()) {
|
|
11521
|
+
writeStderrLine(
|
|
11522
|
+
`qwen serve: Web Shell SPA fallback served for ${req.method} ${req.originalUrl}`
|
|
11523
|
+
);
|
|
11524
|
+
}
|
|
11525
|
+
sendIndex(res);
|
|
11526
|
+
});
|
|
11527
|
+
}
|
|
11528
|
+
__name(mountWebShellSpaFallback, "mountWebShellSpaFallback");
|
|
10963
11529
|
|
|
10964
11530
|
// packages/cli/src/serve/routes/daemon-status.ts
|
|
10965
11531
|
init_esbuild_shims();
|
|
@@ -10991,7 +11557,8 @@ function registerDaemonStatusRoutes(app, deps) {
|
|
|
10991
11557
|
supportedDeviceFlowProviders: deps.getSupportedDeviceFlowProviders(),
|
|
10992
11558
|
deviceFlowRegistry: deps.deviceFlowRegistry,
|
|
10993
11559
|
sessionShellCommandEnabled: deps.sessionShellCommandEnabled,
|
|
10994
|
-
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot
|
|
11560
|
+
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot,
|
|
11561
|
+
getPerfSnapshot: deps.getPerfSnapshot
|
|
10995
11562
|
})
|
|
10996
11563
|
);
|
|
10997
11564
|
} catch (err) {
|
|
@@ -13482,6 +14049,21 @@ function parseSessionPageSizeQuery(raw) {
|
|
|
13482
14049
|
__name(parseSessionPageSizeQuery, "parseSessionPageSizeQuery");
|
|
13483
14050
|
|
|
13484
14051
|
// packages/cli/src/serve/routes/session.ts
|
|
14052
|
+
function sendArtifactValidationError(res, err) {
|
|
14053
|
+
if (!(err instanceof SessionArtifactValidationError)) {
|
|
14054
|
+
return false;
|
|
14055
|
+
}
|
|
14056
|
+
res.status(400).json({
|
|
14057
|
+
v: 1,
|
|
14058
|
+
error: {
|
|
14059
|
+
code: err.code,
|
|
14060
|
+
message: err.message,
|
|
14061
|
+
...err.field ? { field: err.field } : {}
|
|
14062
|
+
}
|
|
14063
|
+
});
|
|
14064
|
+
return true;
|
|
14065
|
+
}
|
|
14066
|
+
__name(sendArtifactValidationError, "sendArtifactValidationError");
|
|
13485
14067
|
function registerSessionRoutes(app, deps) {
|
|
13486
14068
|
const {
|
|
13487
14069
|
boundWorkspace,
|
|
@@ -13808,6 +14390,92 @@ function registerSessionRoutes(app, deps) {
|
|
|
13808
14390
|
sendBridgeError2(res, err, { route: "GET /session/:id/hooks", sessionId });
|
|
13809
14391
|
}
|
|
13810
14392
|
});
|
|
14393
|
+
app.get("/session/:id/artifacts", async (req, res) => {
|
|
14394
|
+
const sessionId = requireSessionId(req, res);
|
|
14395
|
+
if (sessionId === null) return;
|
|
14396
|
+
try {
|
|
14397
|
+
res.status(200).json(await bridge.getSessionArtifacts(sessionId));
|
|
14398
|
+
} catch (err) {
|
|
14399
|
+
sendBridgeError2(res, err, {
|
|
14400
|
+
route: "GET /session/:id/artifacts",
|
|
14401
|
+
sessionId
|
|
14402
|
+
});
|
|
14403
|
+
}
|
|
14404
|
+
});
|
|
14405
|
+
app.post(
|
|
14406
|
+
"/session/:id/artifacts",
|
|
14407
|
+
mutate({ strict: true }),
|
|
14408
|
+
withMutableSession(
|
|
14409
|
+
"POST /session/:id/artifacts",
|
|
14410
|
+
async (req, res, sessionId) => {
|
|
14411
|
+
const clientId = parseClientIdHeader(req, res);
|
|
14412
|
+
if (clientId === null) return;
|
|
14413
|
+
try {
|
|
14414
|
+
const body = safeBody(req);
|
|
14415
|
+
const artifact = {
|
|
14416
|
+
title: body["title"],
|
|
14417
|
+
kind: body["kind"],
|
|
14418
|
+
storage: body["storage"],
|
|
14419
|
+
description: body["description"],
|
|
14420
|
+
workspacePath: body["workspacePath"],
|
|
14421
|
+
managedId: body["managedId"],
|
|
14422
|
+
url: body["url"],
|
|
14423
|
+
mimeType: body["mimeType"],
|
|
14424
|
+
sizeBytes: body["sizeBytes"],
|
|
14425
|
+
metadata: body["metadata"]
|
|
14426
|
+
};
|
|
14427
|
+
const result = await bridge.addSessionArtifact(
|
|
14428
|
+
sessionId,
|
|
14429
|
+
artifact,
|
|
14430
|
+
clientId !== void 0 ? { clientId } : void 0
|
|
14431
|
+
);
|
|
14432
|
+
res.status(200).json(result);
|
|
14433
|
+
} catch (err) {
|
|
14434
|
+
if (sendArtifactValidationError(res, err)) return;
|
|
14435
|
+
sendBridgeError2(res, err, {
|
|
14436
|
+
route: "POST /session/:id/artifacts",
|
|
14437
|
+
sessionId
|
|
14438
|
+
});
|
|
14439
|
+
}
|
|
14440
|
+
}
|
|
14441
|
+
)
|
|
14442
|
+
);
|
|
14443
|
+
app.delete(
|
|
14444
|
+
"/session/:id/artifacts/:artifactId",
|
|
14445
|
+
mutate({ strict: true }),
|
|
14446
|
+
withMutableSession(
|
|
14447
|
+
"DELETE /session/:id/artifacts/:artifactId",
|
|
14448
|
+
async (req, res, sessionId) => {
|
|
14449
|
+
const artifactId = req.params["artifactId"];
|
|
14450
|
+
const clientId = parseClientIdHeader(req, res);
|
|
14451
|
+
if (clientId === null) return;
|
|
14452
|
+
if (!artifactId) {
|
|
14453
|
+
res.status(400).json({
|
|
14454
|
+
v: 1,
|
|
14455
|
+
error: {
|
|
14456
|
+
code: "VALIDATION_FAILED",
|
|
14457
|
+
message: "`artifactId` route parameter is required",
|
|
14458
|
+
field: "artifactId"
|
|
14459
|
+
}
|
|
14460
|
+
});
|
|
14461
|
+
return;
|
|
14462
|
+
}
|
|
14463
|
+
try {
|
|
14464
|
+
const result = await bridge.removeSessionArtifact(
|
|
14465
|
+
sessionId,
|
|
14466
|
+
artifactId,
|
|
14467
|
+
clientId !== void 0 ? { clientId } : void 0
|
|
14468
|
+
);
|
|
14469
|
+
res.status(200).json(result);
|
|
14470
|
+
} catch (err) {
|
|
14471
|
+
sendBridgeError2(res, err, {
|
|
14472
|
+
route: "DELETE /session/:id/artifacts/:artifactId",
|
|
14473
|
+
sessionId
|
|
14474
|
+
});
|
|
14475
|
+
}
|
|
14476
|
+
}
|
|
14477
|
+
)
|
|
14478
|
+
);
|
|
13811
14479
|
app.post(
|
|
13812
14480
|
"/session/:id/tasks/:taskId/cancel",
|
|
13813
14481
|
mutate({ strict: true }),
|
|
@@ -14136,6 +14804,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
14136
14804
|
});
|
|
14137
14805
|
app.patch(
|
|
14138
14806
|
"/session/:id/metadata",
|
|
14807
|
+
mutate({ strict: true }),
|
|
14139
14808
|
withMutableSession("PATCH /session/:id/metadata", (req, res, sessionId) => {
|
|
14140
14809
|
const body = safeBody(req);
|
|
14141
14810
|
const clientId = parseClientIdHeader(req, res);
|
|
@@ -15924,6 +16593,30 @@ function resolveDaemonTelemetryRoute(req) {
|
|
|
15924
16593
|
sessionId: sessionMetadata[1]
|
|
15925
16594
|
};
|
|
15926
16595
|
}
|
|
16596
|
+
const sessionArtifacts = path12.match(/^\/session\/([^/]+)\/artifacts$/);
|
|
16597
|
+
if (sessionArtifacts?.[1]) {
|
|
16598
|
+
if (req.method === "GET") {
|
|
16599
|
+
return {
|
|
16600
|
+
route: "GET /session/:id/artifacts",
|
|
16601
|
+
sessionId: sessionArtifacts[1]
|
|
16602
|
+
};
|
|
16603
|
+
}
|
|
16604
|
+
if (req.method === "POST") {
|
|
16605
|
+
return {
|
|
16606
|
+
route: "POST /session/:id/artifacts",
|
|
16607
|
+
sessionId: sessionArtifacts[1]
|
|
16608
|
+
};
|
|
16609
|
+
}
|
|
16610
|
+
}
|
|
16611
|
+
const sessionArtifact = path12.match(
|
|
16612
|
+
/^\/session\/([^/]+)\/artifacts\/([^/]+)$/
|
|
16613
|
+
);
|
|
16614
|
+
if (sessionArtifact?.[1] && req.method === "DELETE") {
|
|
16615
|
+
return {
|
|
16616
|
+
route: "DELETE /session/:id/artifacts/:artifactId",
|
|
16617
|
+
sessionId: sessionArtifact[1]
|
|
16618
|
+
};
|
|
16619
|
+
}
|
|
15927
16620
|
const sessionPermission = path12.match(
|
|
15928
16621
|
/^\/session\/([^/]+)\/permission\/([^/]+)$/
|
|
15929
16622
|
);
|
|
@@ -16858,7 +17551,8 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
16858
17551
|
getSupportedDeviceFlowProviders,
|
|
16859
17552
|
deviceFlowRegistry,
|
|
16860
17553
|
sessionShellCommandEnabled,
|
|
16861
|
-
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot
|
|
17554
|
+
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot,
|
|
17555
|
+
getPerfSnapshot: deps.getPerfSnapshot
|
|
16862
17556
|
});
|
|
16863
17557
|
registerCapabilitiesRoutes(app, {
|
|
16864
17558
|
qwenCodeVersion: deps.qwenCodeVersion,
|
|
@@ -17112,6 +17806,11 @@ export {
|
|
|
17112
17806
|
* Copyright 2025 Qwen Team
|
|
17113
17807
|
* SPDX-License-Identifier: Apache-2.0
|
|
17114
17808
|
*/
|
|
17809
|
+
/**
|
|
17810
|
+
* @license
|
|
17811
|
+
* Copyright 2026 Qwen Team
|
|
17812
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
17813
|
+
*/
|
|
17115
17814
|
/**
|
|
17116
17815
|
* @license
|
|
17117
17816
|
* Copyright 2026 Qwen Team
|
|
@@ -17131,11 +17830,6 @@ export {
|
|
|
17131
17830
|
*
|
|
17132
17831
|
* See `packages/chrome-extension/docs/06-plan-c-cdp-tunnel.md`.
|
|
17133
17832
|
*/
|
|
17134
|
-
/**
|
|
17135
|
-
* @license
|
|
17136
|
-
* Copyright 2026 Qwen Team
|
|
17137
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
17138
|
-
*/
|
|
17139
17833
|
/**
|
|
17140
17834
|
* @license
|
|
17141
17835
|
* Copyright 2026 Qwen Team
|