@qwen-code/qwen-code 0.19.5 → 0.19.6-nightly.20260705.015ee4248
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 +14 -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/bundled/review/DESIGN.md +23 -0
- package/bundled/review/SKILL.md +65 -8
- package/chunks/{MaxSizedBox-5JV77KRA.js → MaxSizedBox-PRXTXIGC.js} +31 -30
- package/chunks/{StandaloneSessionPicker-MGUGB6PH.js → StandaloneSessionPicker-PV7BSC5D.js} +42 -41
- package/chunks/{acpAgent-4F36XM3X.js → acpAgent-F34HNAM3.js} +939 -424
- package/chunks/{agent-IWBUZI6A.js → agent-XSQDKLST.js} +26 -25
- package/chunks/{agent-headless-JUTICAYO.js → agent-headless-B63XCKWX.js} +26 -25
- package/chunks/{anthropicContentGenerator-WL3LJOUB.js → anthropicContentGenerator-INXXI4PW.js} +7 -7
- package/chunks/{artifact-tool-W76WC2JX.js → artifact-tool-H2TNPNP5.js} +16 -3
- package/chunks/{askUserQuestion-J3P6TH3V.js → askUserQuestion-MKL5ZTMC.js} +2 -2
- package/chunks/{bridge-DHZHQ4UV.js → bridge-NCZDJBRF.js} +34 -32
- package/chunks/{channel-worker-supervisor-EVPAYNZ5.js → channel-worker-supervisor-JUYQ5Z4R.js} +5 -5
- package/chunks/{chunk-AVQDCKNF.js → chunk-22MNNNXE.js} +4 -0
- package/chunks/chunk-3RW4AZJV.js +5063 -0
- package/chunks/chunk-3VJ7MT3N.js +111 -0
- package/chunks/{chunk-JKGCBO3O.js → chunk-3VRMGS3A.js} +4 -4
- package/chunks/{chunk-TN6RT6EJ.js → chunk-3WOJO5EJ.js} +16 -4
- package/chunks/{chunk-G7OQ3RFJ.js → chunk-42XGFRJS.js} +3 -3
- package/chunks/{chunk-MOUXUCXQ.js → chunk-4KJ2BPIT.js} +1 -1
- package/chunks/{chunk-PPFWEV7G.js → chunk-4RQIB5UZ.js} +62 -62
- package/chunks/{chunk-JJ6B3ZD3.js → chunk-544UZQBD.js} +3 -3
- package/chunks/{chunk-B236XPGF.js → chunk-5UDYETKK.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-MDBNFHIO.js → chunk-6MDY7FX3.js} +5 -5
- package/chunks/{chunk-RM3PGSGL.js → chunk-6SHO7WFF.js} +15 -2
- package/chunks/{chunk-YCU7QV7Q.js → chunk-73WGF3NW.js} +34 -1
- package/chunks/{chunk-T42ACHFI.js → chunk-7LTB54MK.js} +1 -1
- package/chunks/{chunk-SJVPSHXU.js → chunk-7U6J224Z.js} +132 -25
- package/chunks/{chunk-CSPSJU5R.js → chunk-7WLJPMWU.js} +17 -17
- package/chunks/{chunk-R6RI2HIC.js → chunk-ACD5DFUY.js} +41 -14
- package/chunks/{chunk-EWALXUAD.js → chunk-AGHU5VRK.js} +8 -0
- package/chunks/{chunk-GLPV75ES.js → chunk-AHNJGLFV.js} +2 -2
- package/chunks/{chunk-DRS2HTNT.js → chunk-AOAFX4PL.js} +5 -5
- package/chunks/{chunk-QHYITL6P.js → chunk-CK7IUFOB.js} +63 -22
- package/chunks/{chunk-RSBQS6M4.js → chunk-CODWJXQA.js} +1 -1
- package/chunks/{chunk-LWGLBVWA.js → chunk-CSOTA7KX.js} +1 -1
- package/chunks/{chunk-UJT42DB6.js → chunk-DFH4T5IQ.js} +6 -6
- package/chunks/{chunk-DX3TKXNT.js → chunk-DJACOX4C.js} +2 -2
- package/chunks/{chunk-KKQWC6WS.js → chunk-DNV4FSN5.js} +1 -1
- package/chunks/{chunk-YPCPZSZB.js → chunk-DT3B47QP.js} +1 -1
- package/chunks/{chunk-NIOPRZNN.js → chunk-E7KNELIZ.js} +1 -1
- package/chunks/{chunk-DG573EOO.js → chunk-FEJ2FZ3U.js} +1 -1
- package/chunks/{chunk-M5ITDKSM.js → chunk-FHGQFG2K.js} +1 -1
- package/chunks/{chunk-HISPEX42.js → chunk-FSXFNDTI.js} +7 -7
- package/chunks/{chunk-LHMZCIKL.js → chunk-FUW7YGJU.js} +3 -1
- package/chunks/{chunk-Y4UQT3PM.js → chunk-FV5SBNNC.js} +1 -1
- package/chunks/{chunk-YTFBURQD.js → chunk-GB6HDZIK.js} +10 -2
- package/chunks/{chunk-D5KISTLW.js → chunk-H6EMK6QK.js} +1 -1
- package/chunks/{chunk-2Z43HUXT.js → chunk-HLKG6CZN.js} +3 -2
- package/chunks/{chunk-VXGPYF7U.js → chunk-IFEWJXFS.js} +1 -1
- package/chunks/{chunk-TENOUWY2.js → chunk-IJRL2S3D.js} +3 -3
- package/chunks/{chunk-OQHLUA2Y.js → chunk-IL6ZEDZ2.js} +4 -4
- package/chunks/{chunk-2CAII5HD.js → chunk-J7XUJALJ.js} +1 -1
- package/chunks/chunk-JFFOH2XO.js +2472 -0
- package/chunks/{chunk-NNEJEBCF.js → chunk-K3FZXSTO.js} +95 -107
- package/chunks/{chunk-NDY7OENU.js → chunk-KB4ICCA5.js} +3 -3
- package/chunks/{chunk-MNOXKSM2.js → chunk-LFFF2SPV.js} +3 -3
- package/chunks/{chunk-J3ERRYYI.js → chunk-LTMDKOZC.js} +2 -2
- package/chunks/{chunk-R3UWLLRQ.js → chunk-M7AGQP5D.js} +1 -1
- package/chunks/{chunk-CBJE2PLG.js → chunk-MLB5AB2I.js} +4 -4
- package/chunks/{chunk-YHTNWGRR.js → chunk-MZ7BABX3.js} +1 -1
- package/chunks/{chunk-SJBIFVD2.js → chunk-NFE3DQ4R.js} +7 -3
- package/chunks/{chunk-BC4R5C5R.js → chunk-NLD2WKE3.js} +55 -12
- package/chunks/{chunk-ALX6BUYW.js → chunk-NUGPZXAZ.js} +35 -1
- package/chunks/{chunk-NSSVORTQ.js → chunk-NYKWPUAE.js} +17 -13
- package/chunks/{chunk-K4I4STSL.js → chunk-OGEJMKN5.js} +2 -2
- package/chunks/{chunk-HTWHAN44.js → chunk-PC4ZXHU2.js} +1 -1
- package/chunks/{chunk-2YH27UNF.js → chunk-QLBBV7C6.js} +1 -1
- package/chunks/chunk-QT7XKZT7.js +293 -0
- package/chunks/{chunk-NPQWQYU6.js → chunk-QYNNN7BK.js} +1 -1
- package/chunks/chunk-R4N3OALZ.js +5631 -0
- package/chunks/{chunk-G4M7FPNY.js → chunk-RB5GAQR6.js} +2 -2
- package/chunks/{chunk-SBMHB6N5.js → chunk-RPHMD5UC.js} +15 -15
- package/chunks/{chunk-CHY5C5T4.js → chunk-SJ2CTIYH.js} +185 -88
- package/chunks/chunk-SLQXGMYY.js +949 -0
- package/chunks/{chunk-BZHLWC6T.js → chunk-SUAKHHK7.js} +2 -2
- package/chunks/{chunk-IMAMNLY6.js → chunk-SWV4CVYG.js} +158 -3
- package/chunks/{chunk-XKSCTXPK.js → chunk-TDGF35EN.js} +4 -3
- package/chunks/{chunk-TOAUDIS7.js → chunk-TLWA7TPR.js} +6 -2
- package/chunks/{chunk-WALEWZ44.js → chunk-UVHL5TCO.js} +1 -1
- package/chunks/{chunk-ZISMVA6U.js → chunk-VDMM5LVR.js} +1566 -37
- package/chunks/{chunk-BPFJQGY7.js → chunk-VEB3NYSO.js} +164 -5
- package/chunks/{chunk-L7OJ3ZO3.js → chunk-VZ7HY3YU.js} +1 -1
- package/chunks/{chunk-6KPZJJ6U.js → chunk-W4I6PLEG.js} +131 -38
- package/chunks/{chunk-QOMAHFYI.js → chunk-W7EEOR7D.js} +3 -3
- package/chunks/{chunk-6QVQZAW6.js → chunk-WKP5QZOP.js} +1 -1
- package/chunks/{chunk-YXK4GPYO.js → chunk-WMPVYQ4P.js} +30 -1
- package/chunks/{chunk-DM4E337C.js → chunk-WNTS5A2R.js} +5 -5
- package/chunks/{chunk-6QTCOQX7.js → chunk-WOG7QWIT.js} +3086 -2635
- package/chunks/{chunk-UY2TCIZS.js → chunk-X265R5C6.js} +3 -3
- package/chunks/{chunk-LKWAVAB5.js → chunk-X2XNQQJI.js} +2 -2
- package/chunks/{chunk-MTNTVOJR.js → chunk-X3YGAX7V.js} +6 -3
- package/chunks/{chunk-EROWZQN7.js → chunk-XD3OLPII.js} +6 -6
- package/chunks/{chunk-RNGAT2Y2.js → chunk-YYL6HROQ.js} +1 -1
- package/chunks/{chunk-XKZXGIRM.js → chunk-YZ2LNTHO.js} +2 -2
- package/chunks/{chunk-Z7XNVNPM.js → chunk-YZ5ANQMR.js} +3 -3
- package/chunks/{chunk-4MCC4XHH.js → chunk-Z7EYROOJ.js} +3568 -5508
- package/chunks/{chunk-5B2WNM6V.js → chunk-ZI4MGBB5.js} +1 -1
- package/chunks/{chunk-WZ724G6K.js → chunk-ZPGE42V7.js} +6 -6
- package/chunks/{computer-use-ON3JQUHW.js → computer-use-5I2UHVNY.js} +26 -25
- package/chunks/{contextCommand-OGCG7W6N.js → contextCommand-3NWY7AJG.js} +28 -27
- package/chunks/{cron-create-6YTCOX6P.js → cron-create-O6ZHD3JN.js} +22 -7
- package/chunks/{cron-delete-E3NIFSUK.js → cron-delete-BFD5B2XX.js} +4 -4
- package/chunks/{cron-list-Q64MNQNE.js → cron-list-KI6FV4KN.js} +4 -4
- package/chunks/{daemon-EEB2RYOL.js → daemon-DRUMLVFP.js} +140 -0
- package/chunks/daemon-status-provider-A2DK3ZTO.js +74 -0
- 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-DN6M6TJ5.js} +525 -95
- package/chunks/{dist-IZP2VV4C.js → dist-JPSVN367.js} +2 -2
- package/chunks/{earlyInputCapture-DAFHSGVW.js → earlyInputCapture-5TMSSPQ5.js} +27 -26
- package/chunks/{edit-3QFNCSZH.js → edit-V4ITLSUD.js} +27 -26
- package/chunks/{en-M4EBUBNU.js → en-AXARKOWO.js} +2 -0
- package/chunks/{enter-worktree-62EQQMLD.js → enter-worktree-7ULPRMTJ.js} +26 -25
- package/chunks/{enterPlanMode-VUQSE4EG.js → enterPlanMode-YSHMLHJZ.js} +26 -25
- package/chunks/{errors-PW75PZXE.js → errors-TCUTD7NF.js} +28 -27
- package/chunks/{exit-worktree-VVNH7OVY.js → exit-worktree-JZDCKR6A.js} +26 -25
- package/chunks/{exitPlanMode-RUYRCYZW.js → exitPlanMode-GOQBN6SG.js} +26 -25
- package/chunks/{fast-path-TFRJRTTR.js → fast-path-F2HGAKO2.js} +3 -3
- package/chunks/{fast-path-settings-UQLRFDQP.js → fast-path-settings-RCRXH2JG.js} +2 -2
- package/chunks/{gemini-XW7ZDUVR.js → gemini-3M7ECKNW.js} +86 -80
- package/chunks/{geminiContentGenerator-MZDVHVZH.js → geminiContentGenerator-5EG3QEJM.js} +4 -4
- package/chunks/{glob-WAY2PUWA.js → glob-2DBDTLR4.js} +54 -29
- package/chunks/{grep-W6CBKSYC.js → grep-R27DLGWT.js} +26 -25
- package/chunks/{initializer-HK2XE6P2.js → initializer-OXB6BJZU.js} +32 -31
- package/chunks/{keychain-token-storage-GPAKRDKQ.js → keychain-token-storage-UJV5XP4Z.js} +2 -2
- package/chunks/{list-RVLIIKKL.js → list-HLCOEOSF.js} +33 -32
- package/chunks/{loadedSettingsAdapter-C63OUYZC.js → loadedSettingsAdapter-JHTVH3YO.js} +31 -30
- package/chunks/{loop-wakeup-G2EHBRGR.js → loop-wakeup-CUVIY2JY.js} +5 -5
- package/chunks/{ls-IDHUVSAG.js → ls-L654WOAT.js} +4 -4
- package/chunks/{lsp-FSRYXGFT.js → lsp-M35KE54Y.js} +2 -2
- package/chunks/mcp-2JWEFAIN.js +67 -0
- package/chunks/{monitor-FOG36ABM.js → monitor-5QKFZFDX.js} +26 -25
- package/chunks/nonInteractiveCli-W5W5PIHI.js +112 -0
- package/chunks/{notebook-edit-GC6NXRCX.js → notebook-edit-XAFBWORI.js} +27 -26
- package/chunks/{openaiContentGenerator-EXR3ZL3Z.js → openaiContentGenerator-NULJROYV.js} +13 -12
- package/chunks/{pidfile-FNZM2DDH.js → pidfile-3LT7PZSW.js} +27 -26
- package/chunks/{qwenContentGenerator-A7B6J4U7.js → qwenContentGenerator-KLSURVNH.js} +28 -27
- package/chunks/{qwenOAuth2-LWLA6MQG.js → qwenOAuth2-ZV7YLMND.js} +5 -5
- package/chunks/{read-file-6JL4ULMY.js → read-file-HDAM3RHJ.js} +8 -8
- package/chunks/{read-mcp-resource-PIJF24RO.js → read-mcp-resource-CNQHBSJM.js} +2 -2
- package/chunks/record-artifact-PP3LKHTS.js +343 -0
- package/chunks/{ripGrep-DIUGLJE5.js → ripGrep-W36NLR7M.js} +26 -25
- package/chunks/{run-qwen-serve-CME3AKM4.js → run-qwen-serve-IMI2CQB5.js} +72 -28
- package/chunks/{scheduler-L7F6GDDT.js → scheduler-I5NKE5UJ.js} +26 -25
- package/chunks/{send-message-33PYFMCT.js → send-message-OA6MV4EU.js} +3 -3
- package/chunks/{serve-SRCBOJGP.js → serve-JMHMOYBO.js} +33 -32
- package/chunks/{server-QSQ45QFR.js → server-QIYIN34N.js} +1358 -492
- package/chunks/{session-5DG6NXHZ.js → session-BLL6HB35.js} +68 -65
- package/chunks/{settings-3EEQI4MN.js → settings-ABECXCTY.js} +30 -29
- package/chunks/{shell-B7FNYF5S.js → shell-A2TQI3U4.js} +26 -25
- package/chunks/{skill-AAOGHD5O.js → skill-4GTWZZWR.js} +10 -10
- package/chunks/{spawnChannel-3CBN3ZLK.js → spawnChannel-DFUVGP53.js} +30 -29
- package/chunks/{src-T5A7P7FS.js → src-ZORBMUM7.js} +77 -43
- package/chunks/{startInteractiveUI-2FGEQ6AS.js → startInteractiveUI-FH5MVXUE.js} +449 -175
- package/chunks/{syntheticOutput-YOSWIHDJ.js → syntheticOutput-F7LSDCAR.js} +3 -3
- package/chunks/{task-create-NHS2NGB3.js → task-create-RPFZNB4B.js} +7 -7
- package/chunks/{task-list-5UIB564R.js → task-list-TGGJX7EA.js} +5 -5
- package/chunks/{task-stop-HGXZ2VZ3.js → task-stop-W7NGTMYQ.js} +2 -2
- package/chunks/{task-update-IYYWUILG.js → task-update-5WUG5MVQ.js} +7 -7
- package/chunks/{team-create-KDF6W6PV.js → team-create-F76QOR6H.js} +26 -25
- package/chunks/{team-delete-FEKJCU4P.js → team-delete-UHQQ2QQX.js} +5 -5
- package/chunks/{team-plan-approval-PSFKQX7M.js → team-plan-approval-OKM7YZC2.js} +26 -25
- package/chunks/{theme-manager-5XOA2AO7.js → theme-manager-6R7EVWHW.js} +27 -26
- package/chunks/{todoWrite-TKMVZ2HT.js → todoWrite-C4ZAMSR3.js} +4 -4
- package/chunks/{tool-search-LFRILZXC.js → tool-search-UWXDKI7D.js} +9 -9
- package/chunks/{trustedFolders-7HQY6T6X.js → trustedFolders-DHASVVUP.js} +27 -26
- package/chunks/{validateNonInterActiveAuth-UC27B7BA.js → validateNonInterActiveAuth-56J7MOOP.js} +62 -59
- package/chunks/version-NE2I4PBN.js +10 -0
- package/chunks/{web-fetch-J4PIW36Q.js → web-fetch-UYGMOHW4.js} +5 -5
- package/chunks/{workflow-KUTESS6L.js → workflow-HGF3URV3.js} +35 -27
- package/chunks/{workspace-providers-status-LJT5AQDS.js → workspace-providers-status-KXB2OZFQ.js} +33 -32
- package/chunks/{workspace-service-YOBYVDXH.js → workspace-service-NSTI55BC.js} +39 -38
- package/chunks/workspace-skills-status-X5S6JGQZ.js +69 -0
- package/chunks/{write-file-FJYBZUHP.js → write-file-HVKT5VTX.js} +27 -26
- package/chunks/yargs-B64EYTCF.js +10 -0
- package/chunks/{zh-SLZNSSZB.js → zh-RS3HZHFH.js} +2 -0
- package/chunks/{zh-TW-P53C2SL5.js → zh-TW-L5GRQ4S4.js} +2 -0
- package/cli-entry.js +81 -8
- package/cli.js +348 -55
- package/locales/en.js +2 -0
- package/locales/zh-TW.js +2 -0
- package/locales/zh.js +2 -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-Csx4m4N0.js} +1 -1
- package/web-shell/assets/{architectureDiagram-3BPJPVTR-DUCzbHVo.js → architectureDiagram-3BPJPVTR-BEa0vCM7.js} +1 -1
- package/web-shell/assets/{blockDiagram-GPEHLZMM-BEEBt1LL.js → blockDiagram-GPEHLZMM-BPzbKnn3.js} +1 -1
- package/web-shell/assets/{c4Diagram-AAUBKEIU-5ZJ_DeFL.js → c4Diagram-AAUBKEIU-B8YO71yP.js} +1 -1
- package/web-shell/assets/channel-QU1XUuVe.js +1 -0
- package/web-shell/assets/{chunk-2J33WTMH-Cfw7EiLn.js → chunk-2J33WTMH-32XhwSHt.js} +1 -1
- package/web-shell/assets/{chunk-4BX2VUAB-FGuZNCZY.js → chunk-4BX2VUAB-Bmoyo6PS.js} +1 -1
- package/web-shell/assets/{chunk-55IACEB6-CaBwYPBF.js → chunk-55IACEB6-TwH6PFhs.js} +1 -1
- package/web-shell/assets/{chunk-727SXJPM-BlR04OFz.js → chunk-727SXJPM-RI_IVUtZ.js} +1 -1
- package/web-shell/assets/{chunk-AQP2D5EJ-D3_mYJH5.js → chunk-AQP2D5EJ-DH6GIAZD.js} +1 -1
- package/web-shell/assets/{chunk-FMBD7UC4-7D4q4SbB.js → chunk-FMBD7UC4-DeD3k3D5.js} +1 -1
- package/web-shell/assets/{chunk-ND2GUHAM-BjX_Iwmr.js → chunk-ND2GUHAM-BLPb8nv3.js} +1 -1
- package/web-shell/assets/{chunk-QZHKN3VN-C3Hz_ZQh.js → chunk-QZHKN3VN-PZpyglW1.js} +1 -1
- package/web-shell/assets/classDiagram-4FO5ZUOK-fv1EWO-L.js +1 -0
- package/web-shell/assets/classDiagram-v2-Q7XG4LA2-fv1EWO-L.js +1 -0
- package/web-shell/assets/{cose-bilkent-S5V4N54A-Ax4UycaT.js → cose-bilkent-S5V4N54A-Jsd0yKfz.js} +1 -1
- package/web-shell/assets/{dagre-BM42HDAG-C6hmPtGt.js → dagre-BM42HDAG-B-zADciZ.js} +1 -1
- package/web-shell/assets/{diagram-2AECGRRQ-tXZnxjmw.js → diagram-2AECGRRQ-Cn6GDxoo.js} +1 -1
- package/web-shell/assets/{diagram-5GNKFQAL-99dwIzQG.js → diagram-5GNKFQAL-udLgyJxO.js} +1 -1
- package/web-shell/assets/{diagram-KO2AKTUF-Bqhn0-2s.js → diagram-KO2AKTUF-EcLpfzy3.js} +1 -1
- package/web-shell/assets/{diagram-LMA3HP47-DzThVSvo.js → diagram-LMA3HP47-D-YFbYsJ.js} +1 -1
- package/web-shell/assets/{diagram-OG6HWLK6-DPE8vjln.js → diagram-OG6HWLK6-C8oRUATa.js} +1 -1
- package/web-shell/assets/{erDiagram-TEJ5UH35-KzUKgQCV.js → erDiagram-TEJ5UH35-DPH5nStc.js} +1 -1
- package/web-shell/assets/{flowDiagram-I6XJVG4X-DBN-DXw5.js → flowDiagram-I6XJVG4X-CSOTwkAt.js} +1 -1
- package/web-shell/assets/{ganttDiagram-6RSMTGT7-DuBsP9u8.js → ganttDiagram-6RSMTGT7-D0L988t0.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-PVQCEYII-BjWHMyKR.js → gitGraphDiagram-PVQCEYII-B9Oo7gxS.js} +1 -1
- package/web-shell/assets/index-BYZZL5N7.css +5 -0
- package/web-shell/assets/index-C_oTyz0s.js +753 -0
- package/web-shell/assets/{infoDiagram-5YYISTIA-BVux0vP6.js → infoDiagram-5YYISTIA-Ddj4YN2P.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-YF4QCWOH-2qzw7f--.js → ishikawaDiagram-YF4QCWOH-CBjafcl7.js} +1 -1
- package/web-shell/assets/{journeyDiagram-JHISSGLW-Dnl65sxL.js → journeyDiagram-JHISSGLW-Bn3XD99u.js} +1 -1
- package/web-shell/assets/{kanban-definition-UN3LZRKU-BElSQYtY.js → kanban-definition-UN3LZRKU-D7PBPJmE.js} +1 -1
- package/web-shell/assets/{linear-BjoycSSY.js → linear-Bmfo22rZ.js} +1 -1
- package/web-shell/assets/{mermaid.core-xe6bvMRz.js → mermaid.core-xRkAI-EI.js} +5 -5
- package/web-shell/assets/{mindmap-definition-RKZ34NQL-D8DQgI4U.js → mindmap-definition-RKZ34NQL-B30zRinm.js} +1 -1
- package/web-shell/assets/{pieDiagram-4H26LBE5-Dwh7Gp7c.js → pieDiagram-4H26LBE5-DblnKR9Z.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-W4KKPZXB-BXKNBln2.js → quadrantDiagram-W4KKPZXB-COkHFKjF.js} +1 -1
- package/web-shell/assets/{requirementDiagram-4Y6WPE33-BzaC3cIA.js → requirementDiagram-4Y6WPE33-DDU3MMyn.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-5OEKKPKP-DP2t7eZk.js → sankeyDiagram-5OEKKPKP-Dt4lqEYv.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-3UESZ5HK-XlFiWEYv.js → sequenceDiagram-3UESZ5HK-BRzby5gN.js} +1 -1
- package/web-shell/assets/{stateDiagram-AJRCARHV-CupgUMJO.js → stateDiagram-AJRCARHV-CylzByc3.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-BHNVJYJU-BKWZIKkM.js +1 -0
- package/web-shell/assets/{timeline-definition-PNZ67QCA-DstuGywa.js → timeline-definition-PNZ67QCA-BSzaNx6w.js} +1 -1
- package/web-shell/assets/{vennDiagram-CIIHVFJN-CnbNp6zu.js → vennDiagram-CIIHVFJN-BbzeKzCo.js} +1 -1
- package/web-shell/assets/{wardley-L42UT6IY-DnvoHq6R.js → wardley-L42UT6IY-BRJwCgE_.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-YWT4CUSO-Cz0xHEWB.js → wardleyDiagram-YWT4CUSO-BmAs0mJ-.js} +1 -1
- package/web-shell/assets/{xychartDiagram-2RQKCTM6-p36gfo88.js → xychartDiagram-2RQKCTM6-DqywSqVW.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/chunks/chunk-L7QPM2YD.js +0 -481
- package/chunks/daemon-status-provider-P72STMLB.js +0 -72
- package/chunks/nonInteractiveCli-6BYQSJTB.js +0 -109
- package/chunks/workspace-skills-status-ONEPXJV6.js +0 -62
- 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,46 @@
|
|
|
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-RB5GAQR6.js";
|
|
13
15
|
import {
|
|
14
16
|
SetupGithubError,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
collectSessionData,
|
|
18
|
+
generateExportFilename,
|
|
19
|
+
normalizeSessionData,
|
|
20
|
+
setupGithub,
|
|
21
|
+
toHtml,
|
|
22
|
+
toJson,
|
|
23
|
+
toJsonl,
|
|
24
|
+
toMarkdown
|
|
25
|
+
} from "./chunk-JFFOH2XO.js";
|
|
17
26
|
import "./chunk-54YZOP7P.js";
|
|
18
|
-
import "./chunk-
|
|
27
|
+
import "./chunk-J7XUJALJ.js";
|
|
28
|
+
import {
|
|
29
|
+
createDaemonStatusProvider
|
|
30
|
+
} from "./chunk-IL6ZEDZ2.js";
|
|
31
|
+
import "./chunk-3VRMGS3A.js";
|
|
32
|
+
import "./chunk-KHDZHZMH.js";
|
|
33
|
+
import {
|
|
34
|
+
createWorkspaceProvidersStatusProvider
|
|
35
|
+
} from "./chunk-NYKWPUAE.js";
|
|
36
|
+
import {
|
|
37
|
+
getAuthTypeFromEnv,
|
|
38
|
+
resolveCliGenerationConfig
|
|
39
|
+
} from "./chunk-OGEJMKN5.js";
|
|
40
|
+
import {
|
|
41
|
+
createWorkspaceSkillsStatusProvider
|
|
42
|
+
} from "./chunk-3WOJO5EJ.js";
|
|
43
|
+
import "./chunk-6IAWPIQ6.js";
|
|
19
44
|
import {
|
|
20
45
|
EMPTY_WORKSPACE_VOICE_UPDATE_ERROR,
|
|
21
46
|
WorkspaceVoiceError,
|
|
@@ -26,7 +51,14 @@ import {
|
|
|
26
51
|
transcribeWorkspaceVoiceAudio,
|
|
27
52
|
validateWorkspaceVoiceState,
|
|
28
53
|
voiceSettingsScopeToWire
|
|
29
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-7WLJPMWU.js";
|
|
55
|
+
import {
|
|
56
|
+
PermissionRulesValidationError,
|
|
57
|
+
buildPermissionSettings,
|
|
58
|
+
isPermissionRuleType,
|
|
59
|
+
normalizePermissionRules,
|
|
60
|
+
readPermissionRuleSet
|
|
61
|
+
} from "./chunk-WKP5QZOP.js";
|
|
30
62
|
import {
|
|
31
63
|
assertVoiceBaseUrlNetworkAllowed,
|
|
32
64
|
isStreamingVoiceModel,
|
|
@@ -34,20 +66,17 @@ import {
|
|
|
34
66
|
resolveVoiceTranscriptionConfig,
|
|
35
67
|
sanitizeVoiceErrorMessage,
|
|
36
68
|
transcribeVoiceAudio
|
|
37
|
-
} from "./chunk-
|
|
38
|
-
import {
|
|
39
|
-
PermissionRulesValidationError,
|
|
40
|
-
buildPermissionSettings,
|
|
41
|
-
isPermissionRuleType,
|
|
42
|
-
normalizePermissionRules,
|
|
43
|
-
readPermissionRuleSet
|
|
44
|
-
} from "./chunk-6QVQZAW6.js";
|
|
69
|
+
} from "./chunk-LFFF2SPV.js";
|
|
45
70
|
import {
|
|
46
71
|
isVoiceEnabled,
|
|
47
72
|
isVoiceMode,
|
|
48
73
|
readVoiceModel
|
|
49
|
-
} from "./chunk-
|
|
50
|
-
import "./chunk-
|
|
74
|
+
} from "./chunk-FV5SBNNC.js";
|
|
75
|
+
import "./chunk-E7KNELIZ.js";
|
|
76
|
+
import {
|
|
77
|
+
WorkspacePermissionRulesSessionRequiredError,
|
|
78
|
+
WorkspaceSettingsPartialPersistError
|
|
79
|
+
} from "./chunk-BMFMJINR.js";
|
|
51
80
|
import {
|
|
52
81
|
CAPABILITIES_SCHEMA_VERSION,
|
|
53
82
|
CLIENT_ID_HEADER,
|
|
@@ -92,21 +121,28 @@ import {
|
|
|
92
121
|
setRateLimiter,
|
|
93
122
|
unsafeRevealSecret,
|
|
94
123
|
validateMcpRuntimeServerName
|
|
95
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-73WGF3NW.js";
|
|
96
125
|
import {
|
|
97
126
|
isLoopbackBind
|
|
98
127
|
} from "./chunk-RNBYOUGV.js";
|
|
99
128
|
import "./chunk-3HX5LZ6R.js";
|
|
100
129
|
import "./chunk-7RYW5LQV.js";
|
|
101
130
|
import {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
131
|
+
getDialogSettingKeys,
|
|
132
|
+
getNestedProperty,
|
|
133
|
+
getSettingDefinition,
|
|
134
|
+
loadSettings,
|
|
135
|
+
validateSettingValue
|
|
136
|
+
} from "./chunk-NLD2WKE3.js";
|
|
107
137
|
import {
|
|
138
|
+
SUPPORTED_LANGUAGES
|
|
139
|
+
} from "./chunk-WNTS5A2R.js";
|
|
140
|
+
import "./chunk-TLRYABYP.js";
|
|
141
|
+
import "./chunk-4RQIB5UZ.js";
|
|
142
|
+
import {
|
|
143
|
+
SessionArtifactValidationError,
|
|
108
144
|
createAcpSessionBridge
|
|
109
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-VDMM5LVR.js";
|
|
110
146
|
import "./chunk-P7M4GA57.js";
|
|
111
147
|
import {
|
|
112
148
|
BranchWhilePromptActiveError,
|
|
@@ -137,7 +173,7 @@ import {
|
|
|
137
173
|
WorkspaceInitSymlinkError,
|
|
138
174
|
WorkspaceMismatchError
|
|
139
175
|
} from "./chunk-T22H4V4R.js";
|
|
140
|
-
import "./chunk-
|
|
176
|
+
import "./chunk-AGHU5VRK.js";
|
|
141
177
|
import {
|
|
142
178
|
MAX_WORKSPACE_PATH_LENGTH,
|
|
143
179
|
canonicalizeWorkspace
|
|
@@ -145,45 +181,20 @@ import {
|
|
|
145
181
|
import {
|
|
146
182
|
EVENT_SCHEMA_VERSION,
|
|
147
183
|
SubscriberLimitExceededError
|
|
148
|
-
} from "./chunk-
|
|
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";
|
|
184
|
+
} from "./chunk-NUGPZXAZ.js";
|
|
185
|
+
import "./chunk-VRDMOSQS.js";
|
|
186
|
+
import "./chunk-XD3OLPII.js";
|
|
187
|
+
import "./chunk-3VJ7MT3N.js";
|
|
161
188
|
import {
|
|
162
189
|
STATUS_SCHEMA_VERSION,
|
|
163
190
|
createIdleWorkspaceMemoryStatus,
|
|
164
191
|
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";
|
|
192
|
+
} from "./chunk-FUW7YGJU.js";
|
|
193
|
+
import "./chunk-HLKG6CZN.js";
|
|
194
|
+
import "./chunk-CODWJXQA.js";
|
|
184
195
|
import {
|
|
185
196
|
getWorkspaceTrustStatus
|
|
186
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-YZ5ANQMR.js";
|
|
187
198
|
import {
|
|
188
199
|
writeStderrLine
|
|
189
200
|
} from "./chunk-Y6Z2O3WR.js";
|
|
@@ -195,14 +206,13 @@ import {
|
|
|
195
206
|
Client,
|
|
196
207
|
ClientMcpRegistrar,
|
|
197
208
|
ExtensionManager,
|
|
209
|
+
IMAGE_CAPABILITY,
|
|
198
210
|
ModelsConfig,
|
|
199
211
|
RUNTIME_MCP_IF_ABSENT_CONFIG_FLAG,
|
|
200
212
|
SessionService,
|
|
201
213
|
StandardFileSystemService,
|
|
202
214
|
StdioClientTransport,
|
|
203
215
|
StreamableHTTPClientTransport,
|
|
204
|
-
SubagentError,
|
|
205
|
-
SubagentErrorCode,
|
|
206
216
|
SubagentManager,
|
|
207
217
|
TrustGateError,
|
|
208
218
|
WorkspaceMemoryFileTooLargeError,
|
|
@@ -216,29 +226,32 @@ import {
|
|
|
216
226
|
redactUrlCredentials,
|
|
217
227
|
shouldShowStep,
|
|
218
228
|
writeWorkspaceContextFile
|
|
219
|
-
} from "./chunk-
|
|
229
|
+
} from "./chunk-WOG7QWIT.js";
|
|
220
230
|
import "./chunk-5P5XGNYH.js";
|
|
221
|
-
import "./chunk-K5PGHDBN.js";
|
|
222
231
|
import "./chunk-SKAZWEV5.js";
|
|
223
|
-
import "./chunk-
|
|
224
|
-
import "./chunk-
|
|
225
|
-
import "./chunk-
|
|
226
|
-
import "./chunk-
|
|
227
|
-
import "./chunk-
|
|
232
|
+
import "./chunk-K5PGHDBN.js";
|
|
233
|
+
import "./chunk-ACD5DFUY.js";
|
|
234
|
+
import "./chunk-W7EEOR7D.js";
|
|
235
|
+
import "./chunk-42XGFRJS.js";
|
|
236
|
+
import "./chunk-X2XNQQJI.js";
|
|
237
|
+
import "./chunk-VZ7HY3YU.js";
|
|
228
238
|
import "./chunk-2MPVVENX.js";
|
|
229
239
|
import "./chunk-ZTQ26VBE.js";
|
|
230
|
-
import "./chunk-
|
|
240
|
+
import "./chunk-NFE3DQ4R.js";
|
|
231
241
|
import "./chunk-MLZQVCF3.js";
|
|
232
242
|
import "./chunk-LQ7TMOCE.js";
|
|
233
243
|
import "./chunk-E5A7LHNN.js";
|
|
234
244
|
import {
|
|
235
|
-
APPROVAL_MODES
|
|
236
|
-
|
|
245
|
+
APPROVAL_MODES,
|
|
246
|
+
SubagentError,
|
|
247
|
+
SubagentErrorCode
|
|
248
|
+
} from "./chunk-VEB3NYSO.js";
|
|
237
249
|
import "./chunk-GO6LNQXT.js";
|
|
238
|
-
import "./chunk-
|
|
239
|
-
import "./chunk-
|
|
240
|
-
import "./chunk-
|
|
241
|
-
import "./chunk-
|
|
250
|
+
import "./chunk-5UDYETKK.js";
|
|
251
|
+
import "./chunk-WMPVYQ4P.js";
|
|
252
|
+
import "./chunk-TLWA7TPR.js";
|
|
253
|
+
import "./chunk-QYNNN7BK.js";
|
|
254
|
+
import "./chunk-QT7XKZT7.js";
|
|
242
255
|
import {
|
|
243
256
|
addDaemonRequestAttribute,
|
|
244
257
|
decodeBufferWithEncodingInfo,
|
|
@@ -252,15 +265,15 @@ import {
|
|
|
252
265
|
recordDaemonHttpRequest,
|
|
253
266
|
recordDaemonHttpResponse,
|
|
254
267
|
withDaemonRequestSpan
|
|
255
|
-
} from "./chunk-
|
|
268
|
+
} from "./chunk-SJ2CTIYH.js";
|
|
256
269
|
import "./chunk-E6US47KI.js";
|
|
257
270
|
import "./chunk-UWCTAVOD.js";
|
|
258
271
|
import "./chunk-OFEVLU4C.js";
|
|
259
272
|
import "./chunk-OMX7CUOE.js";
|
|
260
|
-
import "./chunk-
|
|
261
|
-
import "./chunk-
|
|
262
|
-
import "./chunk-
|
|
263
|
-
import "./chunk-
|
|
273
|
+
import "./chunk-4KJ2BPIT.js";
|
|
274
|
+
import "./chunk-SUAKHHK7.js";
|
|
275
|
+
import "./chunk-FEJ2FZ3U.js";
|
|
276
|
+
import "./chunk-X3YGAX7V.js";
|
|
264
277
|
import {
|
|
265
278
|
QwenOAuth2Client,
|
|
266
279
|
QwenOAuthPollError,
|
|
@@ -269,13 +282,13 @@ import {
|
|
|
269
282
|
isDeviceAuthorizationSuccess,
|
|
270
283
|
isDeviceTokenPending,
|
|
271
284
|
isDeviceTokenSuccess
|
|
272
|
-
} from "./chunk-
|
|
273
|
-
import "./chunk-
|
|
285
|
+
} from "./chunk-IJRL2S3D.js";
|
|
286
|
+
import "./chunk-AHNJGLFV.js";
|
|
274
287
|
import "./chunk-22IFUCVR.js";
|
|
275
|
-
import "./chunk-
|
|
288
|
+
import "./chunk-7LTB54MK.js";
|
|
276
289
|
import "./chunk-SIUQ3YYX.js";
|
|
277
|
-
import "./chunk-
|
|
278
|
-
import "./chunk-
|
|
290
|
+
import "./chunk-GB6HDZIK.js";
|
|
291
|
+
import "./chunk-DT3B47QP.js";
|
|
279
292
|
import "./chunk-IRJWHZWU.js";
|
|
280
293
|
import "./chunk-SYCJMSIJ.js";
|
|
281
294
|
import "./chunk-55ZMG67I.js";
|
|
@@ -284,12 +297,12 @@ import {
|
|
|
284
297
|
} from "./chunk-H6BD2ELD.js";
|
|
285
298
|
import "./chunk-5IFG2VC4.js";
|
|
286
299
|
import "./chunk-64WXLC72.js";
|
|
287
|
-
import "./chunk-
|
|
300
|
+
import "./chunk-H6EMK6QK.js";
|
|
288
301
|
import {
|
|
289
302
|
FatalConfigError,
|
|
290
303
|
Storage,
|
|
291
304
|
createDebugLogger
|
|
292
|
-
} from "./chunk-
|
|
305
|
+
} from "./chunk-22MNNNXE.js";
|
|
293
306
|
import "./chunk-ZERZSAZL.js";
|
|
294
307
|
import "./chunk-QN5NZ3UQ.js";
|
|
295
308
|
import "./chunk-BR4QREVK.js";
|
|
@@ -3006,55 +3019,619 @@ function registerWorkspaceVoiceRoutes(app, deps) {
|
|
|
3006
3019
|
});
|
|
3007
3020
|
return;
|
|
3008
3021
|
}
|
|
3009
|
-
const queryVoiceModel = req.query["voiceModel"];
|
|
3010
|
-
if (queryVoiceModel !== void 0 && typeof queryVoiceModel !== "string") {
|
|
3022
|
+
const queryVoiceModel = req.query["voiceModel"];
|
|
3023
|
+
if (queryVoiceModel !== void 0 && typeof queryVoiceModel !== "string") {
|
|
3024
|
+
res.status(400).json({
|
|
3025
|
+
error: "`voiceModel` query parameter must be a string",
|
|
3026
|
+
code: "invalid_voice_model"
|
|
3027
|
+
});
|
|
3028
|
+
return;
|
|
3029
|
+
}
|
|
3030
|
+
const requestedVoiceModel = typeof queryVoiceModel === "string" ? queryVoiceModel.trim() : "";
|
|
3031
|
+
if (requestedVoiceModel && requestedVoiceModel.length > MAX_VOICE_MODEL_LENGTH) {
|
|
3032
|
+
res.status(400).json({
|
|
3033
|
+
error: `\`voiceModel\` exceeds the ${MAX_VOICE_MODEL_LENGTH}-character limit`,
|
|
3034
|
+
code: "invalid_voice_model"
|
|
3035
|
+
});
|
|
3036
|
+
return;
|
|
3037
|
+
}
|
|
3038
|
+
const voiceModel = requestedVoiceModel || readVoiceModel(settings);
|
|
3039
|
+
if (!voiceModel) {
|
|
3040
|
+
res.status(400).json({
|
|
3041
|
+
error: "A valid voiceModel is required before transcription.",
|
|
3042
|
+
code: "voice_model_required"
|
|
3043
|
+
});
|
|
3044
|
+
return;
|
|
3045
|
+
}
|
|
3046
|
+
try {
|
|
3047
|
+
const result = await transcribe({
|
|
3048
|
+
data,
|
|
3049
|
+
mimeType: audioContentType,
|
|
3050
|
+
voiceModel,
|
|
3051
|
+
settings,
|
|
3052
|
+
workspaceCwd: deps.boundWorkspace,
|
|
3053
|
+
abortSignal: requestAbortSignal2(req, res)
|
|
3054
|
+
});
|
|
3055
|
+
res.status(200).json({ v: 1, ...result });
|
|
3056
|
+
} catch (err) {
|
|
3057
|
+
if (sendVoiceError(res, err)) return;
|
|
3058
|
+
const message = err instanceof Error ? sanitizeVoiceErrorMessage(err.message) : sanitizeVoiceErrorMessage(String(err));
|
|
3059
|
+
writeStderrLine(
|
|
3060
|
+
`qwen serve: POST /workspace/voice/transcribe error (workspace=${deps.boundWorkspace}): ${message}`
|
|
3061
|
+
);
|
|
3062
|
+
res.status(502).json({
|
|
3063
|
+
error: "Voice transcription failed",
|
|
3064
|
+
code: "voice_transcription_failed"
|
|
3065
|
+
});
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
);
|
|
3069
|
+
}
|
|
3070
|
+
__name(registerWorkspaceVoiceRoutes, "registerWorkspaceVoiceRoutes");
|
|
3071
|
+
|
|
3072
|
+
// packages/cli/src/serve/workspace-remember.ts
|
|
3073
|
+
init_esbuild_shims();
|
|
3074
|
+
import { randomUUID } from "node:crypto";
|
|
3075
|
+
var debugLogger = createDebugLogger("WORKSPACE_REMEMBER");
|
|
3076
|
+
function nowIso() {
|
|
3077
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
3078
|
+
}
|
|
3079
|
+
__name(nowIso, "nowIso");
|
|
3080
|
+
function createMemoryTaskId(kind) {
|
|
3081
|
+
return `${kind}-${randomUUID()}`;
|
|
3082
|
+
}
|
|
3083
|
+
__name(createMemoryTaskId, "createMemoryTaskId");
|
|
3084
|
+
function touchedScopesFromTopics(topics) {
|
|
3085
|
+
const scopes = /* @__PURE__ */ new Set();
|
|
3086
|
+
for (const topic of topics) {
|
|
3087
|
+
scopes.add(topic === "user" || topic === "feedback" ? "user" : "project");
|
|
3088
|
+
}
|
|
3089
|
+
return [...scopes];
|
|
3090
|
+
}
|
|
3091
|
+
__name(touchedScopesFromTopics, "touchedScopesFromTopics");
|
|
3092
|
+
function cloneTask(task) {
|
|
3093
|
+
const base = {
|
|
3094
|
+
taskId: task.taskId,
|
|
3095
|
+
status: task.status,
|
|
3096
|
+
createdAt: task.createdAt,
|
|
3097
|
+
updatedAt: task.updatedAt,
|
|
3098
|
+
error: task.error ? { ...task.error } : void 0
|
|
3099
|
+
};
|
|
3100
|
+
if (task.kind === "remember") {
|
|
3101
|
+
return {
|
|
3102
|
+
...base,
|
|
3103
|
+
contextMode: task.contextMode,
|
|
3104
|
+
result: task.result ? {
|
|
3105
|
+
...task.result,
|
|
3106
|
+
filesTouched: [...task.result.filesTouched],
|
|
3107
|
+
touchedScopes: [...task.result.touchedScopes]
|
|
3108
|
+
} : void 0
|
|
3109
|
+
};
|
|
3110
|
+
}
|
|
3111
|
+
if (task.kind === "forget") {
|
|
3112
|
+
return {
|
|
3113
|
+
...base,
|
|
3114
|
+
result: task.result ? {
|
|
3115
|
+
...task.result,
|
|
3116
|
+
removedEntries: task.result.removedEntries.map((entry) => ({
|
|
3117
|
+
...entry
|
|
3118
|
+
})),
|
|
3119
|
+
touchedTopics: [...task.result.touchedTopics]
|
|
3120
|
+
} : void 0
|
|
3121
|
+
};
|
|
3122
|
+
}
|
|
3123
|
+
return {
|
|
3124
|
+
...base,
|
|
3125
|
+
result: task.result ? {
|
|
3126
|
+
...task.result,
|
|
3127
|
+
touchedTopics: [...task.result.touchedTopics]
|
|
3128
|
+
} : void 0
|
|
3129
|
+
};
|
|
3130
|
+
}
|
|
3131
|
+
__name(cloneTask, "cloneTask");
|
|
3132
|
+
function publicErrorMessage(code, kind) {
|
|
3133
|
+
if (code === "managed_memory_unavailable") {
|
|
3134
|
+
return "Managed memory is unavailable for this daemon workspace.";
|
|
3135
|
+
}
|
|
3136
|
+
if (code === "remember_path_escape") {
|
|
3137
|
+
return "Remember agent touched a path outside managed memory.";
|
|
3138
|
+
}
|
|
3139
|
+
if (code === "remember_queue_full") {
|
|
3140
|
+
return kind === "remember" ? "Workspace memory remember queue is full." : "Workspace memory task queue is full.";
|
|
3141
|
+
}
|
|
3142
|
+
if (code === "remember_timeout" || code === "forget_timeout" || code === "dream_timeout") {
|
|
3143
|
+
return `Workspace memory ${kind} timed out.`;
|
|
3144
|
+
}
|
|
3145
|
+
return `Workspace memory ${kind} failed.`;
|
|
3146
|
+
}
|
|
3147
|
+
__name(publicErrorMessage, "publicErrorMessage");
|
|
3148
|
+
function publicErrorStatus(code) {
|
|
3149
|
+
if (code === "remember_queue_full") return 429;
|
|
3150
|
+
if (code === "managed_memory_unavailable") return 409;
|
|
3151
|
+
return 500;
|
|
3152
|
+
}
|
|
3153
|
+
__name(publicErrorStatus, "publicErrorStatus");
|
|
3154
|
+
var WorkspaceRememberTaskLane = class _WorkspaceRememberTaskLane {
|
|
3155
|
+
constructor(bridge) {
|
|
3156
|
+
this.bridge = bridge;
|
|
3157
|
+
}
|
|
3158
|
+
static {
|
|
3159
|
+
__name(this, "WorkspaceRememberTaskLane");
|
|
3160
|
+
}
|
|
3161
|
+
static MAX_TASKS = 1e3;
|
|
3162
|
+
static TERMINAL_TASK_TTL_MS = 5 * 6e4;
|
|
3163
|
+
// Two-tier pending capacity: all tasks share the global cap, while
|
|
3164
|
+
// forget/dream share a smaller sub-cap so bursts cannot starve remember.
|
|
3165
|
+
static MAX_PENDING = 16;
|
|
3166
|
+
static MAX_NON_REMEMBER_PENDING = 8;
|
|
3167
|
+
static NON_REMEMBER_KINDS = /* @__PURE__ */ new Set(
|
|
3168
|
+
["forget", "dream"]
|
|
3169
|
+
);
|
|
3170
|
+
tasks = /* @__PURE__ */ new Map();
|
|
3171
|
+
tail = Promise.resolve();
|
|
3172
|
+
pendingCounts() {
|
|
3173
|
+
let total = 0;
|
|
3174
|
+
let nonRemember = 0;
|
|
3175
|
+
for (const task of this.tasks.values()) {
|
|
3176
|
+
if (task.status !== "queued" && task.status !== "running") continue;
|
|
3177
|
+
total++;
|
|
3178
|
+
if (_WorkspaceRememberTaskLane.NON_REMEMBER_KINDS.has(task.kind)) {
|
|
3179
|
+
nonRemember++;
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
return { total, nonRemember };
|
|
3183
|
+
}
|
|
3184
|
+
evictTerminalTasks(nowMs = Date.now()) {
|
|
3185
|
+
const cutoffMs = nowMs - _WorkspaceRememberTaskLane.TERMINAL_TASK_TTL_MS;
|
|
3186
|
+
for (const [id, task] of this.tasks) {
|
|
3187
|
+
if (task.status !== "completed" && task.status !== "failed") continue;
|
|
3188
|
+
const updatedAtMs = Date.parse(task.updatedAt);
|
|
3189
|
+
if (!Number.isNaN(updatedAtMs) && updatedAtMs <= cutoffMs) {
|
|
3190
|
+
this.tasks.delete(id);
|
|
3191
|
+
} else if (Number.isNaN(updatedAtMs)) {
|
|
3192
|
+
debugLogger.warn(
|
|
3193
|
+
"Task with unparseable updatedAt skipped for TTL eviction:",
|
|
3194
|
+
{
|
|
3195
|
+
taskId: id,
|
|
3196
|
+
updatedAt: task.updatedAt
|
|
3197
|
+
}
|
|
3198
|
+
);
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) return;
|
|
3202
|
+
for (const [id, task] of this.tasks) {
|
|
3203
|
+
if (task.status === "completed" || task.status === "failed") {
|
|
3204
|
+
this.tasks.delete(id);
|
|
3205
|
+
if (this.tasks.size <= _WorkspaceRememberTaskLane.MAX_TASKS) break;
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
}
|
|
3209
|
+
assertCapacity(kind) {
|
|
3210
|
+
const pending = this.pendingCounts();
|
|
3211
|
+
if (pending.total >= _WorkspaceRememberTaskLane.MAX_PENDING) {
|
|
3212
|
+
throw Object.assign(new Error("Workspace memory task queue is full"), {
|
|
3213
|
+
code: "remember_queue_full"
|
|
3214
|
+
});
|
|
3215
|
+
}
|
|
3216
|
+
if (_WorkspaceRememberTaskLane.NON_REMEMBER_KINDS.has(kind) && pending.nonRemember >= _WorkspaceRememberTaskLane.MAX_NON_REMEMBER_PENDING) {
|
|
3217
|
+
throw Object.assign(new Error("Workspace memory task queue is full"), {
|
|
3218
|
+
code: "remember_queue_full"
|
|
3219
|
+
});
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
queue(task, run) {
|
|
3223
|
+
this.tasks.set(task.taskId, task);
|
|
3224
|
+
this.evictTerminalTasks();
|
|
3225
|
+
this.tail = this.tail.then(run, run);
|
|
3226
|
+
void this.tail.catch((err) => {
|
|
3227
|
+
debugLogger.error("Unhandled task lane error:", err);
|
|
3228
|
+
});
|
|
3229
|
+
return cloneTask(task);
|
|
3230
|
+
}
|
|
3231
|
+
publishManagedMemoryChanged(params) {
|
|
3232
|
+
if (params.touchedScopes.length === 0) return;
|
|
3233
|
+
try {
|
|
3234
|
+
this.bridge.publishWorkspaceEvent({
|
|
3235
|
+
type: "memory_changed",
|
|
3236
|
+
data: {
|
|
3237
|
+
scope: "managed",
|
|
3238
|
+
source: params.source,
|
|
3239
|
+
taskId: params.taskId,
|
|
3240
|
+
touchedScopes: params.touchedScopes
|
|
3241
|
+
},
|
|
3242
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3243
|
+
});
|
|
3244
|
+
} catch (err) {
|
|
3245
|
+
debugLogger.error("Failed to publish memory_changed event:", err);
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
enqueue(params) {
|
|
3249
|
+
this.assertCapacity("remember");
|
|
3250
|
+
const task = {
|
|
3251
|
+
kind: "remember",
|
|
3252
|
+
taskId: createMemoryTaskId("remember"),
|
|
3253
|
+
status: "queued",
|
|
3254
|
+
contextMode: params.contextMode,
|
|
3255
|
+
createdAt: nowIso(),
|
|
3256
|
+
updatedAt: nowIso(),
|
|
3257
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3258
|
+
};
|
|
3259
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
3260
|
+
task.status = "running";
|
|
3261
|
+
task.updatedAt = nowIso();
|
|
3262
|
+
try {
|
|
3263
|
+
const result = await this.bridge.runWorkspaceMemoryRemember({
|
|
3264
|
+
content: params.content,
|
|
3265
|
+
contextMode: params.contextMode
|
|
3266
|
+
});
|
|
3267
|
+
task.status = "completed";
|
|
3268
|
+
task.result = {
|
|
3269
|
+
summary: result.filesTouched.length > 0 ? "Memory update completed." : "No memory files updated.",
|
|
3270
|
+
filesTouched: result.filesTouched,
|
|
3271
|
+
touchedScopes: result.touchedScopes
|
|
3272
|
+
};
|
|
3273
|
+
task.updatedAt = nowIso();
|
|
3274
|
+
} catch (err) {
|
|
3275
|
+
const code = extractRememberErrorCode(err);
|
|
3276
|
+
debugLogger.error(
|
|
3277
|
+
"Workspace memory remember task failed:",
|
|
3278
|
+
{ taskId: task.taskId },
|
|
3279
|
+
err
|
|
3280
|
+
);
|
|
3281
|
+
task.status = "failed";
|
|
3282
|
+
task.error = {
|
|
3283
|
+
code,
|
|
3284
|
+
message: publicErrorMessage(code, task.kind)
|
|
3285
|
+
};
|
|
3286
|
+
task.updatedAt = nowIso();
|
|
3287
|
+
}
|
|
3288
|
+
try {
|
|
3289
|
+
if (task.status === "completed" && task.result) {
|
|
3290
|
+
this.publishManagedMemoryChanged({
|
|
3291
|
+
source: "workspace_memory_remember",
|
|
3292
|
+
taskId: task.taskId,
|
|
3293
|
+
touchedScopes: task.result.touchedScopes,
|
|
3294
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3295
|
+
});
|
|
3296
|
+
}
|
|
3297
|
+
} finally {
|
|
3298
|
+
this.evictTerminalTasks();
|
|
3299
|
+
}
|
|
3300
|
+
}, "run");
|
|
3301
|
+
return this.queue(task, run);
|
|
3302
|
+
}
|
|
3303
|
+
enqueueForget(params) {
|
|
3304
|
+
this.assertCapacity("forget");
|
|
3305
|
+
const task = {
|
|
3306
|
+
kind: "forget",
|
|
3307
|
+
taskId: createMemoryTaskId("forget"),
|
|
3308
|
+
status: "queued",
|
|
3309
|
+
createdAt: nowIso(),
|
|
3310
|
+
updatedAt: nowIso(),
|
|
3311
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3312
|
+
};
|
|
3313
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
3314
|
+
task.status = "running";
|
|
3315
|
+
task.updatedAt = nowIso();
|
|
3316
|
+
try {
|
|
3317
|
+
const result = await this.bridge.runWorkspaceMemoryForget({
|
|
3318
|
+
query: params.query
|
|
3319
|
+
});
|
|
3320
|
+
task.status = "completed";
|
|
3321
|
+
task.result = {
|
|
3322
|
+
summary: result.summary ?? formatWorkspaceMemoryForgetSummary(result.removedEntries.length),
|
|
3323
|
+
removedEntries: result.removedEntries,
|
|
3324
|
+
touchedTopics: result.touchedTopics
|
|
3325
|
+
};
|
|
3326
|
+
task.updatedAt = nowIso();
|
|
3327
|
+
} catch (err) {
|
|
3328
|
+
const code = extractRememberErrorCode(err, "forget_failed");
|
|
3329
|
+
debugLogger.error(
|
|
3330
|
+
"Workspace memory forget task failed:",
|
|
3331
|
+
{ taskId: task.taskId },
|
|
3332
|
+
err
|
|
3333
|
+
);
|
|
3334
|
+
task.status = "failed";
|
|
3335
|
+
task.error = {
|
|
3336
|
+
code,
|
|
3337
|
+
message: publicErrorMessage(code, task.kind)
|
|
3338
|
+
};
|
|
3339
|
+
task.updatedAt = nowIso();
|
|
3340
|
+
}
|
|
3341
|
+
try {
|
|
3342
|
+
if (task.status === "completed" && task.result) {
|
|
3343
|
+
this.publishManagedMemoryChanged({
|
|
3344
|
+
source: "workspace_memory_forget",
|
|
3345
|
+
taskId: task.taskId,
|
|
3346
|
+
touchedScopes: touchedScopesFromTopics(task.result.touchedTopics),
|
|
3347
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3348
|
+
});
|
|
3349
|
+
}
|
|
3350
|
+
} finally {
|
|
3351
|
+
this.evictTerminalTasks();
|
|
3352
|
+
}
|
|
3353
|
+
}, "run");
|
|
3354
|
+
return this.queue(task, run);
|
|
3355
|
+
}
|
|
3356
|
+
enqueueDream(params) {
|
|
3357
|
+
this.assertCapacity("dream");
|
|
3358
|
+
const task = {
|
|
3359
|
+
kind: "dream",
|
|
3360
|
+
taskId: createMemoryTaskId("dream"),
|
|
3361
|
+
status: "queued",
|
|
3362
|
+
createdAt: nowIso(),
|
|
3363
|
+
updatedAt: nowIso(),
|
|
3364
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3365
|
+
};
|
|
3366
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
3367
|
+
task.status = "running";
|
|
3368
|
+
task.updatedAt = nowIso();
|
|
3369
|
+
try {
|
|
3370
|
+
const result = await this.bridge.runWorkspaceMemoryDream();
|
|
3371
|
+
task.status = "completed";
|
|
3372
|
+
task.result = {
|
|
3373
|
+
summary: result.summary ?? formatWorkspaceMemoryDreamSummary(result.touchedTopics.length),
|
|
3374
|
+
touchedTopics: result.touchedTopics,
|
|
3375
|
+
dedupedEntries: result.dedupedEntries
|
|
3376
|
+
};
|
|
3377
|
+
task.updatedAt = nowIso();
|
|
3378
|
+
} catch (err) {
|
|
3379
|
+
const code = extractRememberErrorCode(err, "dream_failed");
|
|
3380
|
+
debugLogger.error(
|
|
3381
|
+
"Workspace memory dream task failed:",
|
|
3382
|
+
{ taskId: task.taskId },
|
|
3383
|
+
err
|
|
3384
|
+
);
|
|
3385
|
+
task.status = "failed";
|
|
3386
|
+
task.error = {
|
|
3387
|
+
code,
|
|
3388
|
+
message: publicErrorMessage(code, task.kind)
|
|
3389
|
+
};
|
|
3390
|
+
task.updatedAt = nowIso();
|
|
3391
|
+
}
|
|
3392
|
+
try {
|
|
3393
|
+
if (task.status === "completed" && task.result) {
|
|
3394
|
+
this.publishManagedMemoryChanged({
|
|
3395
|
+
source: "workspace_memory_dream",
|
|
3396
|
+
taskId: task.taskId,
|
|
3397
|
+
touchedScopes: touchedScopesFromTopics(task.result.touchedTopics),
|
|
3398
|
+
...params.originatorClientId ? { originatorClientId: params.originatorClientId } : {}
|
|
3399
|
+
});
|
|
3400
|
+
}
|
|
3401
|
+
} finally {
|
|
3402
|
+
this.evictTerminalTasks();
|
|
3403
|
+
}
|
|
3404
|
+
}, "run");
|
|
3405
|
+
return this.queue(task, run);
|
|
3406
|
+
}
|
|
3407
|
+
get(taskId, requesterClientId, kind) {
|
|
3408
|
+
const task = this.tasks.get(taskId);
|
|
3409
|
+
if (!task) return void 0;
|
|
3410
|
+
if (kind && task.kind !== kind) return void 0;
|
|
3411
|
+
if (task.originatorClientId) {
|
|
3412
|
+
if (task.originatorClientId !== requesterClientId) return void 0;
|
|
3413
|
+
} else if (requesterClientId) {
|
|
3414
|
+
return void 0;
|
|
3415
|
+
}
|
|
3416
|
+
return cloneTask(task);
|
|
3417
|
+
}
|
|
3418
|
+
};
|
|
3419
|
+
function validateOriginatorClientId(deps, req, res) {
|
|
3420
|
+
const clientId = deps.parseClientId(req, res);
|
|
3421
|
+
if (clientId === null) return null;
|
|
3422
|
+
if (clientId === void 0) return void 0;
|
|
3423
|
+
const known = deps.bridge.knownClientIds();
|
|
3424
|
+
if (!known.has(clientId)) {
|
|
3425
|
+
res.status(400).json({
|
|
3426
|
+
error: `Client id "${clientId}" is not registered for this workspace`,
|
|
3427
|
+
code: "invalid_client_id",
|
|
3428
|
+
clientId
|
|
3429
|
+
});
|
|
3430
|
+
return null;
|
|
3431
|
+
}
|
|
3432
|
+
return clientId;
|
|
3433
|
+
}
|
|
3434
|
+
__name(validateOriginatorClientId, "validateOriginatorClientId");
|
|
3435
|
+
async function validateManagedMemoryAvailable(deps, res, kind) {
|
|
3436
|
+
try {
|
|
3437
|
+
const available = await deps.bridge.isWorkspaceMemoryRememberAvailable();
|
|
3438
|
+
if (!available) {
|
|
3439
|
+
res.status(409).json({
|
|
3440
|
+
error: "Managed memory is unavailable for this daemon workspace",
|
|
3441
|
+
code: "managed_memory_unavailable"
|
|
3442
|
+
});
|
|
3443
|
+
return false;
|
|
3444
|
+
}
|
|
3445
|
+
return true;
|
|
3446
|
+
} catch (err) {
|
|
3447
|
+
debugLogger.error("Availability check failed:", err);
|
|
3448
|
+
const code = `${kind}_failed`;
|
|
3449
|
+
res.status(500).json({
|
|
3450
|
+
error: publicErrorMessage(code, kind),
|
|
3451
|
+
code
|
|
3452
|
+
});
|
|
3453
|
+
return false;
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3456
|
+
__name(validateManagedMemoryAvailable, "validateManagedMemoryAvailable");
|
|
3457
|
+
function mountWorkspaceMemoryRememberRoutes(app, deps) {
|
|
3458
|
+
app.post(
|
|
3459
|
+
"/workspace/memory/remember",
|
|
3460
|
+
deps.mutate({ strict: true }),
|
|
3461
|
+
async (req, res) => {
|
|
3462
|
+
const body = deps.safeBody(req);
|
|
3463
|
+
const content = body["content"];
|
|
3464
|
+
const trimmedContent = typeof content === "string" ? content.trim() : "";
|
|
3465
|
+
if (!trimmedContent) {
|
|
3466
|
+
res.status(400).json({
|
|
3467
|
+
error: "`content` must be a non-empty string",
|
|
3468
|
+
code: "invalid_content"
|
|
3469
|
+
});
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3472
|
+
if (Buffer.byteLength(trimmedContent, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
|
|
3473
|
+
res.status(400).json({
|
|
3474
|
+
error: `\`content\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`,
|
|
3475
|
+
code: "invalid_content"
|
|
3476
|
+
});
|
|
3477
|
+
return;
|
|
3478
|
+
}
|
|
3479
|
+
const contextModeRaw = body["contextMode"] ?? "workspace";
|
|
3480
|
+
if (contextModeRaw !== "workspace" && contextModeRaw !== "clean") {
|
|
3481
|
+
res.status(400).json({
|
|
3482
|
+
error: '`contextMode` must be "workspace", "clean", or omitted',
|
|
3483
|
+
code: "invalid_context_mode"
|
|
3484
|
+
});
|
|
3485
|
+
return;
|
|
3486
|
+
}
|
|
3487
|
+
const originatorClientId = validateOriginatorClientId(deps, req, res);
|
|
3488
|
+
if (originatorClientId === null) return;
|
|
3489
|
+
if (!await validateManagedMemoryAvailable(deps, res, "remember")) {
|
|
3490
|
+
return;
|
|
3491
|
+
}
|
|
3492
|
+
let task;
|
|
3493
|
+
try {
|
|
3494
|
+
task = deps.lane.enqueue({
|
|
3495
|
+
content: trimmedContent,
|
|
3496
|
+
contextMode: contextModeRaw,
|
|
3497
|
+
...originatorClientId ? { originatorClientId } : {}
|
|
3498
|
+
});
|
|
3499
|
+
} catch (err) {
|
|
3500
|
+
const code = extractRememberErrorCode(err);
|
|
3501
|
+
res.status(publicErrorStatus(code)).json({
|
|
3502
|
+
error: publicErrorMessage(code, "remember"),
|
|
3503
|
+
code
|
|
3504
|
+
});
|
|
3505
|
+
return;
|
|
3506
|
+
}
|
|
3507
|
+
res.status(202).json(task);
|
|
3508
|
+
}
|
|
3509
|
+
);
|
|
3510
|
+
app.get(
|
|
3511
|
+
"/workspace/memory/remember/:taskId",
|
|
3512
|
+
deps.mutate({ strict: true }),
|
|
3513
|
+
(req, res) => {
|
|
3514
|
+
const requesterClientId = validateOriginatorClientId(deps, req, res);
|
|
3515
|
+
if (requesterClientId === null) return;
|
|
3516
|
+
const task = deps.lane.get(
|
|
3517
|
+
req.params["taskId"],
|
|
3518
|
+
requesterClientId,
|
|
3519
|
+
"remember"
|
|
3520
|
+
);
|
|
3521
|
+
if (!task) {
|
|
3522
|
+
res.status(404).json({
|
|
3523
|
+
error: "Workspace memory remember task not found",
|
|
3524
|
+
code: "remember_task_not_found"
|
|
3525
|
+
});
|
|
3526
|
+
return;
|
|
3527
|
+
}
|
|
3528
|
+
res.status(200).json(task);
|
|
3529
|
+
}
|
|
3530
|
+
);
|
|
3531
|
+
app.post(
|
|
3532
|
+
"/workspace/memory/forget",
|
|
3533
|
+
deps.mutate({ strict: true }),
|
|
3534
|
+
async (req, res) => {
|
|
3535
|
+
const body = deps.safeBody(req);
|
|
3536
|
+
const query = body["query"];
|
|
3537
|
+
const trimmedQuery = typeof query === "string" ? query.trim() : "";
|
|
3538
|
+
if (!trimmedQuery) {
|
|
3539
|
+
res.status(400).json({
|
|
3540
|
+
error: "`query` must be a non-empty string",
|
|
3541
|
+
code: "invalid_query"
|
|
3542
|
+
});
|
|
3543
|
+
return;
|
|
3544
|
+
}
|
|
3545
|
+
if (Buffer.byteLength(trimmedQuery, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
|
|
3011
3546
|
res.status(400).json({
|
|
3012
|
-
error:
|
|
3013
|
-
code: "
|
|
3547
|
+
error: `\`query\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`,
|
|
3548
|
+
code: "invalid_query"
|
|
3014
3549
|
});
|
|
3015
3550
|
return;
|
|
3016
3551
|
}
|
|
3017
|
-
const
|
|
3018
|
-
if (
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3552
|
+
const originatorClientId = validateOriginatorClientId(deps, req, res);
|
|
3553
|
+
if (originatorClientId === null) return;
|
|
3554
|
+
if (!await validateManagedMemoryAvailable(deps, res, "forget")) return;
|
|
3555
|
+
try {
|
|
3556
|
+
const task = deps.lane.enqueueForget({
|
|
3557
|
+
query: trimmedQuery,
|
|
3558
|
+
...originatorClientId ? { originatorClientId } : {}
|
|
3559
|
+
});
|
|
3560
|
+
res.status(202).json(task);
|
|
3561
|
+
} catch (err) {
|
|
3562
|
+
const code = extractRememberErrorCode(err, "forget_failed");
|
|
3563
|
+
res.status(publicErrorStatus(code)).json({
|
|
3564
|
+
error: publicErrorMessage(code, "forget"),
|
|
3565
|
+
code
|
|
3022
3566
|
});
|
|
3023
|
-
return;
|
|
3024
3567
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3568
|
+
}
|
|
3569
|
+
);
|
|
3570
|
+
app.get(
|
|
3571
|
+
"/workspace/memory/forget/:taskId",
|
|
3572
|
+
deps.mutate({ strict: true }),
|
|
3573
|
+
(req, res) => {
|
|
3574
|
+
const requesterClientId = validateOriginatorClientId(deps, req, res);
|
|
3575
|
+
if (requesterClientId === null) return;
|
|
3576
|
+
const task = deps.lane.get(
|
|
3577
|
+
req.params["taskId"],
|
|
3578
|
+
requesterClientId,
|
|
3579
|
+
"forget"
|
|
3580
|
+
);
|
|
3581
|
+
if (!task) {
|
|
3582
|
+
res.status(404).json({
|
|
3583
|
+
error: "Workspace memory forget task not found",
|
|
3584
|
+
code: "forget_task_not_found"
|
|
3030
3585
|
});
|
|
3031
3586
|
return;
|
|
3032
3587
|
}
|
|
3588
|
+
res.status(200).json(task);
|
|
3589
|
+
}
|
|
3590
|
+
);
|
|
3591
|
+
app.post(
|
|
3592
|
+
"/workspace/memory/dream",
|
|
3593
|
+
deps.mutate({ strict: true }),
|
|
3594
|
+
async (req, res) => {
|
|
3595
|
+
const originatorClientId = validateOriginatorClientId(deps, req, res);
|
|
3596
|
+
if (originatorClientId === null) return;
|
|
3597
|
+
if (!await validateManagedMemoryAvailable(deps, res, "dream")) return;
|
|
3033
3598
|
try {
|
|
3034
|
-
const
|
|
3035
|
-
|
|
3036
|
-
mimeType: audioContentType,
|
|
3037
|
-
voiceModel,
|
|
3038
|
-
settings,
|
|
3039
|
-
workspaceCwd: deps.boundWorkspace,
|
|
3040
|
-
abortSignal: requestAbortSignal2(req, res)
|
|
3599
|
+
const task = deps.lane.enqueueDream({
|
|
3600
|
+
...originatorClientId ? { originatorClientId } : {}
|
|
3041
3601
|
});
|
|
3042
|
-
res.status(
|
|
3602
|
+
res.status(202).json(task);
|
|
3043
3603
|
} catch (err) {
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
);
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3604
|
+
const code = extractRememberErrorCode(err, "dream_failed");
|
|
3605
|
+
res.status(publicErrorStatus(code)).json({
|
|
3606
|
+
error: publicErrorMessage(code, "dream"),
|
|
3607
|
+
code
|
|
3608
|
+
});
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
);
|
|
3612
|
+
app.get(
|
|
3613
|
+
"/workspace/memory/dream/:taskId",
|
|
3614
|
+
deps.mutate({ strict: true }),
|
|
3615
|
+
(req, res) => {
|
|
3616
|
+
const requesterClientId = validateOriginatorClientId(deps, req, res);
|
|
3617
|
+
if (requesterClientId === null) return;
|
|
3618
|
+
const task = deps.lane.get(
|
|
3619
|
+
req.params["taskId"],
|
|
3620
|
+
requesterClientId,
|
|
3621
|
+
"dream"
|
|
3622
|
+
);
|
|
3623
|
+
if (!task) {
|
|
3624
|
+
res.status(404).json({
|
|
3625
|
+
error: "Workspace memory dream task not found",
|
|
3626
|
+
code: "dream_task_not_found"
|
|
3052
3627
|
});
|
|
3628
|
+
return;
|
|
3053
3629
|
}
|
|
3630
|
+
res.status(200).json(task);
|
|
3054
3631
|
}
|
|
3055
3632
|
);
|
|
3056
3633
|
}
|
|
3057
|
-
__name(
|
|
3634
|
+
__name(mountWorkspaceMemoryRememberRoutes, "mountWorkspaceMemoryRememberRoutes");
|
|
3058
3635
|
|
|
3059
3636
|
// packages/cli/src/serve/workspace-memory.ts
|
|
3060
3637
|
init_esbuild_shims();
|
|
@@ -4569,6 +5146,7 @@ function errMsg(err) {
|
|
|
4569
5146
|
return err instanceof Error ? err.message : String(err);
|
|
4570
5147
|
}
|
|
4571
5148
|
__name(errMsg, "errMsg");
|
|
5149
|
+
var debugLogger2 = createDebugLogger("ACP_HTTP_DISPATCH");
|
|
4572
5150
|
var SESSION_SHELL_METHOD = `${QWEN_METHOD_NS}session/shell`;
|
|
4573
5151
|
var INVALID_PERMISSION_OUTCOME_ERROR = '`outcome` must be `{ outcome: "cancelled" }` or `{ outcome: "selected", optionId: string }`';
|
|
4574
5152
|
var ALL_QWEN_VENDOR_METHODS = [
|
|
@@ -4599,11 +5177,18 @@ var ALL_QWEN_VENDOR_METHODS = [
|
|
|
4599
5177
|
`${QWEN_METHOD_NS}session/context_usage`,
|
|
4600
5178
|
`${QWEN_METHOD_NS}session/tasks`,
|
|
4601
5179
|
`${QWEN_METHOD_NS}session/lsp`,
|
|
5180
|
+
`${QWEN_METHOD_NS}session/artifacts`,
|
|
5181
|
+
`${QWEN_METHOD_NS}session/artifacts/add`,
|
|
5182
|
+
`${QWEN_METHOD_NS}session/artifacts/remove`,
|
|
4602
5183
|
// Wave 1: memory
|
|
4603
5184
|
`${QWEN_METHOD_NS}workspace/memory`,
|
|
4604
5185
|
`${QWEN_METHOD_NS}workspace/memory/write`,
|
|
4605
5186
|
`${QWEN_METHOD_NS}workspace/memory/remember`,
|
|
4606
5187
|
`${QWEN_METHOD_NS}workspace/memory/remember/get`,
|
|
5188
|
+
`${QWEN_METHOD_NS}workspace/memory/forget`,
|
|
5189
|
+
`${QWEN_METHOD_NS}workspace/memory/forget/get`,
|
|
5190
|
+
`${QWEN_METHOD_NS}workspace/memory/dream`,
|
|
5191
|
+
`${QWEN_METHOD_NS}workspace/memory/dream/get`,
|
|
4607
5192
|
// Wave 1: files
|
|
4608
5193
|
`${QWEN_METHOD_NS}file/read`,
|
|
4609
5194
|
`${QWEN_METHOD_NS}file/read_bytes`,
|
|
@@ -4736,6 +5321,33 @@ function parsePermissionResponse(params) {
|
|
|
4736
5321
|
return response;
|
|
4737
5322
|
}
|
|
4738
5323
|
__name(parsePermissionResponse, "parsePermissionResponse");
|
|
5324
|
+
function pickSessionArtifactInput(params) {
|
|
5325
|
+
const {
|
|
5326
|
+
title,
|
|
5327
|
+
kind,
|
|
5328
|
+
storage,
|
|
5329
|
+
description,
|
|
5330
|
+
workspacePath,
|
|
5331
|
+
managedId,
|
|
5332
|
+
url,
|
|
5333
|
+
mimeType,
|
|
5334
|
+
sizeBytes,
|
|
5335
|
+
metadata
|
|
5336
|
+
} = params;
|
|
5337
|
+
return {
|
|
5338
|
+
title,
|
|
5339
|
+
kind,
|
|
5340
|
+
storage,
|
|
5341
|
+
description,
|
|
5342
|
+
workspacePath,
|
|
5343
|
+
managedId,
|
|
5344
|
+
url,
|
|
5345
|
+
mimeType,
|
|
5346
|
+
sizeBytes,
|
|
5347
|
+
metadata
|
|
5348
|
+
};
|
|
5349
|
+
}
|
|
5350
|
+
__name(pickSessionArtifactInput, "pickSessionArtifactInput");
|
|
4739
5351
|
function toRpcError(err) {
|
|
4740
5352
|
if (err instanceof AcpParamError || err instanceof InvalidCursorError) {
|
|
4741
5353
|
return { code: RPC.INVALID_PARAMS, message: err.message };
|
|
@@ -4816,6 +5428,16 @@ function toRpcError(err) {
|
|
|
4816
5428
|
data: { errorKind: "client_id_required" }
|
|
4817
5429
|
};
|
|
4818
5430
|
}
|
|
5431
|
+
if (err instanceof SessionArtifactValidationError) {
|
|
5432
|
+
return {
|
|
5433
|
+
code: RPC.INVALID_PARAMS,
|
|
5434
|
+
message: err.message,
|
|
5435
|
+
data: {
|
|
5436
|
+
errorKind: "artifact_validation_failed",
|
|
5437
|
+
...err.field ? { field: err.field } : {}
|
|
5438
|
+
}
|
|
5439
|
+
};
|
|
5440
|
+
}
|
|
4819
5441
|
const name = err instanceof Error ? err.name : "";
|
|
4820
5442
|
switch (name) {
|
|
4821
5443
|
case "SessionArchivedError":
|
|
@@ -5069,7 +5691,8 @@ var AcpDispatcher = class {
|
|
|
5069
5691
|
methods: advertisedQwenVendorMethods(
|
|
5070
5692
|
this.sessionShellCommandEnabled
|
|
5071
5693
|
)
|
|
5072
|
-
}
|
|
5694
|
+
},
|
|
5695
|
+
imageCapability: IMAGE_CAPABILITY
|
|
5073
5696
|
}
|
|
5074
5697
|
}
|
|
5075
5698
|
};
|
|
@@ -5225,7 +5848,8 @@ var AcpDispatcher = class {
|
|
|
5225
5848
|
return method === "session/load" ? await this.bridge.loadSession({
|
|
5226
5849
|
sessionId,
|
|
5227
5850
|
workspaceCwd: cwd,
|
|
5228
|
-
clientId: conn.clientId
|
|
5851
|
+
clientId: conn.clientId,
|
|
5852
|
+
historyReplay: "response"
|
|
5229
5853
|
}) : await this.bridge.resumeSession({
|
|
5230
5854
|
sessionId,
|
|
5231
5855
|
workspaceCwd: cwd,
|
|
@@ -5255,12 +5879,31 @@ var AcpDispatcher = class {
|
|
|
5255
5879
|
return;
|
|
5256
5880
|
}
|
|
5257
5881
|
conn.getOrCreateSession(sessionId).clientId = restored.clientId;
|
|
5882
|
+
if (method === "session/load") {
|
|
5883
|
+
conn.markInitialReplayPending(sessionId);
|
|
5884
|
+
}
|
|
5258
5885
|
conn.ownSession(sessionId);
|
|
5259
5886
|
const loadConfigOptions = await this.configOptionsFor(sessionId);
|
|
5260
5887
|
const loadModels = this.extractModelState(loadConfigOptions);
|
|
5261
5888
|
const loadModes = this.extractModeState(loadConfigOptions);
|
|
5889
|
+
const loadState = restored.state ?? {};
|
|
5890
|
+
const loadMeta = isObject(loadState._meta) ? loadState._meta : void 0;
|
|
5891
|
+
const loadQwenMeta = isObject(loadMeta?.[QWEN_META_KEY]) ? loadMeta[QWEN_META_KEY] : void 0;
|
|
5892
|
+
const replayStatus = method === "session/load" && restored.partial === true ? {
|
|
5893
|
+
partial: true,
|
|
5894
|
+
...typeof restored.replayError === "string" ? { replayError: restored.replayError } : {}
|
|
5895
|
+
} : void 0;
|
|
5262
5896
|
this.replyConn(conn, id, {
|
|
5263
|
-
...
|
|
5897
|
+
...loadState,
|
|
5898
|
+
...replayStatus ? {
|
|
5899
|
+
_meta: {
|
|
5900
|
+
...loadMeta ?? {},
|
|
5901
|
+
[QWEN_META_KEY]: {
|
|
5902
|
+
...loadQwenMeta ?? {},
|
|
5903
|
+
sessionLoadReplay: replayStatus
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
} : {},
|
|
5264
5907
|
...loadConfigOptions ? { configOptions: loadConfigOptions } : {},
|
|
5265
5908
|
...loadModels ? { models: loadModels } : {},
|
|
5266
5909
|
...loadModes ? { modes: loadModes } : {}
|
|
@@ -6289,6 +6932,46 @@ var AcpDispatcher = class {
|
|
|
6289
6932
|
this.replyConn(conn, id, result);
|
|
6290
6933
|
return;
|
|
6291
6934
|
}
|
|
6935
|
+
case `${QWEN_METHOD_NS}session/artifacts`: {
|
|
6936
|
+
const sessionId = String(params["sessionId"] ?? "");
|
|
6937
|
+
if (!this.requireOwned(conn, sessionId, id)) return;
|
|
6938
|
+
const result = await this.bridge.getSessionArtifacts(sessionId);
|
|
6939
|
+
this.replyConn(conn, id, result);
|
|
6940
|
+
return;
|
|
6941
|
+
}
|
|
6942
|
+
case `${QWEN_METHOD_NS}session/artifacts/add`: {
|
|
6943
|
+
const sessionId = String(params["sessionId"] ?? "");
|
|
6944
|
+
await this.withMutableOwned(conn, sessionId, id, async () => {
|
|
6945
|
+
const result = await this.bridge.addSessionArtifact(
|
|
6946
|
+
sessionId,
|
|
6947
|
+
pickSessionArtifactInput(params),
|
|
6948
|
+
this.sessionCtx(conn, sessionId, loopback)
|
|
6949
|
+
);
|
|
6950
|
+
this.replyConn(conn, id, result);
|
|
6951
|
+
});
|
|
6952
|
+
return;
|
|
6953
|
+
}
|
|
6954
|
+
case `${QWEN_METHOD_NS}session/artifacts/remove`: {
|
|
6955
|
+
const sessionId = String(params["sessionId"] ?? "");
|
|
6956
|
+
await this.withMutableOwned(conn, sessionId, id, async () => {
|
|
6957
|
+
const artifactId = String(params["artifactId"] ?? "");
|
|
6958
|
+
if (!artifactId) {
|
|
6959
|
+
if (id !== void 0) {
|
|
6960
|
+
conn.sendConn(
|
|
6961
|
+
error(id, RPC.INVALID_PARAMS, "`artifactId` is required")
|
|
6962
|
+
);
|
|
6963
|
+
}
|
|
6964
|
+
return;
|
|
6965
|
+
}
|
|
6966
|
+
const result = await this.bridge.removeSessionArtifact(
|
|
6967
|
+
sessionId,
|
|
6968
|
+
artifactId,
|
|
6969
|
+
this.sessionCtx(conn, sessionId, loopback)
|
|
6970
|
+
);
|
|
6971
|
+
this.replyConn(conn, id, result);
|
|
6972
|
+
});
|
|
6973
|
+
return;
|
|
6974
|
+
}
|
|
6292
6975
|
case `${QWEN_METHOD_NS}workspace/memory`: {
|
|
6293
6976
|
const result = await collectWorkspaceMemoryStatus(
|
|
6294
6977
|
this.boundWorkspace
|
|
@@ -6404,15 +7087,180 @@ var AcpDispatcher = class {
|
|
|
6404
7087
|
if (rawContextMode !== "workspace" && rawContextMode !== "clean") {
|
|
6405
7088
|
if (id !== void 0) {
|
|
6406
7089
|
conn.sendConn(
|
|
6407
|
-
error(
|
|
6408
|
-
id,
|
|
6409
|
-
RPC.INVALID_PARAMS,
|
|
6410
|
-
'`contextMode` must be "workspace", "clean", or omitted'
|
|
6411
|
-
)
|
|
7090
|
+
error(
|
|
7091
|
+
id,
|
|
7092
|
+
RPC.INVALID_PARAMS,
|
|
7093
|
+
'`contextMode` must be "workspace", "clean", or omitted'
|
|
7094
|
+
)
|
|
7095
|
+
);
|
|
7096
|
+
}
|
|
7097
|
+
return;
|
|
7098
|
+
}
|
|
7099
|
+
try {
|
|
7100
|
+
const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
|
|
7101
|
+
if (!available) {
|
|
7102
|
+
if (id !== void 0) {
|
|
7103
|
+
conn.sendConn(
|
|
7104
|
+
error(
|
|
7105
|
+
id,
|
|
7106
|
+
-32009,
|
|
7107
|
+
"Managed memory is unavailable for this daemon workspace",
|
|
7108
|
+
{
|
|
7109
|
+
errorKind: "managed_memory_unavailable",
|
|
7110
|
+
httpStatus: 409
|
|
7111
|
+
}
|
|
7112
|
+
)
|
|
7113
|
+
);
|
|
7114
|
+
}
|
|
7115
|
+
return;
|
|
7116
|
+
}
|
|
7117
|
+
const task = this.workspaceRememberLane.enqueue({
|
|
7118
|
+
content: content.trim(),
|
|
7119
|
+
contextMode: rawContextMode,
|
|
7120
|
+
...conn.clientId ? { originatorClientId: conn.clientId } : {}
|
|
7121
|
+
});
|
|
7122
|
+
this.replyConn(conn, id, task);
|
|
7123
|
+
} catch (err) {
|
|
7124
|
+
const code = extractRememberErrorCode(err);
|
|
7125
|
+
if (id !== void 0) {
|
|
7126
|
+
conn.sendConn(
|
|
7127
|
+
error(id, -32099, publicErrorMessage(code, "remember"), {
|
|
7128
|
+
errorKind: code,
|
|
7129
|
+
httpStatus: publicErrorStatus(code)
|
|
7130
|
+
})
|
|
7131
|
+
);
|
|
7132
|
+
} else {
|
|
7133
|
+
debugLogger2.warn(
|
|
7134
|
+
"workspace memory remember notification failed:",
|
|
7135
|
+
err
|
|
7136
|
+
);
|
|
7137
|
+
}
|
|
7138
|
+
}
|
|
7139
|
+
return;
|
|
7140
|
+
}
|
|
7141
|
+
case `${QWEN_METHOD_NS}workspace/memory/remember/get`: {
|
|
7142
|
+
const taskId = params["taskId"];
|
|
7143
|
+
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
7144
|
+
if (id !== void 0) {
|
|
7145
|
+
conn.sendConn(error(id, RPC.INVALID_PARAMS, "`taskId` required"));
|
|
7146
|
+
}
|
|
7147
|
+
return;
|
|
7148
|
+
}
|
|
7149
|
+
const task = this.workspaceRememberLane.get(
|
|
7150
|
+
taskId,
|
|
7151
|
+
conn.clientId,
|
|
7152
|
+
"remember"
|
|
7153
|
+
);
|
|
7154
|
+
if (!task) {
|
|
7155
|
+
if (id !== void 0) {
|
|
7156
|
+
conn.sendConn(
|
|
7157
|
+
error(id, -32004, "Workspace memory remember task not found", {
|
|
7158
|
+
errorKind: "remember_task_not_found",
|
|
7159
|
+
httpStatus: 404
|
|
7160
|
+
})
|
|
7161
|
+
);
|
|
7162
|
+
}
|
|
7163
|
+
return;
|
|
7164
|
+
}
|
|
7165
|
+
this.replyConn(conn, id, task);
|
|
7166
|
+
return;
|
|
7167
|
+
}
|
|
7168
|
+
case `${QWEN_METHOD_NS}workspace/memory/forget`: {
|
|
7169
|
+
const query = params["query"];
|
|
7170
|
+
const trimmedQuery = typeof query === "string" ? query.trim() : "";
|
|
7171
|
+
if (!trimmedQuery) {
|
|
7172
|
+
if (id !== void 0) {
|
|
7173
|
+
conn.sendConn(
|
|
7174
|
+
error(
|
|
7175
|
+
id,
|
|
7176
|
+
RPC.INVALID_PARAMS,
|
|
7177
|
+
"`query` must be a non-empty string"
|
|
7178
|
+
)
|
|
7179
|
+
);
|
|
7180
|
+
}
|
|
7181
|
+
return;
|
|
7182
|
+
}
|
|
7183
|
+
if (Buffer.byteLength(trimmedQuery, "utf8") > MAX_REMEMBER_CONTENT_BYTES) {
|
|
7184
|
+
if (id !== void 0) {
|
|
7185
|
+
conn.sendConn(
|
|
7186
|
+
error(
|
|
7187
|
+
id,
|
|
7188
|
+
RPC.INVALID_PARAMS,
|
|
7189
|
+
`\`query\` exceeds the ${MAX_REMEMBER_CONTENT_BYTES}-byte limit`
|
|
7190
|
+
)
|
|
7191
|
+
);
|
|
7192
|
+
}
|
|
7193
|
+
return;
|
|
7194
|
+
}
|
|
7195
|
+
try {
|
|
7196
|
+
const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
|
|
7197
|
+
if (!available) {
|
|
7198
|
+
if (id !== void 0) {
|
|
7199
|
+
conn.sendConn(
|
|
7200
|
+
error(
|
|
7201
|
+
id,
|
|
7202
|
+
-32009,
|
|
7203
|
+
"Managed memory is unavailable for this daemon workspace",
|
|
7204
|
+
{
|
|
7205
|
+
errorKind: "managed_memory_unavailable",
|
|
7206
|
+
httpStatus: 409
|
|
7207
|
+
}
|
|
7208
|
+
)
|
|
7209
|
+
);
|
|
7210
|
+
}
|
|
7211
|
+
return;
|
|
7212
|
+
}
|
|
7213
|
+
const task = this.workspaceRememberLane.enqueueForget({
|
|
7214
|
+
query: trimmedQuery,
|
|
7215
|
+
...conn.clientId ? { originatorClientId: conn.clientId } : {}
|
|
7216
|
+
});
|
|
7217
|
+
this.replyConn(conn, id, task);
|
|
7218
|
+
} catch (err) {
|
|
7219
|
+
const code = extractRememberErrorCode(err, "forget_failed");
|
|
7220
|
+
if (id !== void 0) {
|
|
7221
|
+
conn.sendConn(
|
|
7222
|
+
error(id, -32099, publicErrorMessage(code, "forget"), {
|
|
7223
|
+
errorKind: code,
|
|
7224
|
+
httpStatus: publicErrorStatus(code)
|
|
7225
|
+
})
|
|
7226
|
+
);
|
|
7227
|
+
} else {
|
|
7228
|
+
debugLogger2.warn(
|
|
7229
|
+
"workspace memory forget notification failed:",
|
|
7230
|
+
err
|
|
7231
|
+
);
|
|
7232
|
+
}
|
|
7233
|
+
}
|
|
7234
|
+
return;
|
|
7235
|
+
}
|
|
7236
|
+
case `${QWEN_METHOD_NS}workspace/memory/forget/get`: {
|
|
7237
|
+
const taskId = params["taskId"];
|
|
7238
|
+
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
7239
|
+
if (id !== void 0) {
|
|
7240
|
+
conn.sendConn(error(id, RPC.INVALID_PARAMS, "`taskId` required"));
|
|
7241
|
+
}
|
|
7242
|
+
return;
|
|
7243
|
+
}
|
|
7244
|
+
const task = this.workspaceRememberLane.get(
|
|
7245
|
+
taskId,
|
|
7246
|
+
conn.clientId,
|
|
7247
|
+
"forget"
|
|
7248
|
+
);
|
|
7249
|
+
if (!task) {
|
|
7250
|
+
if (id !== void 0) {
|
|
7251
|
+
conn.sendConn(
|
|
7252
|
+
error(id, -32004, "Workspace memory forget task not found", {
|
|
7253
|
+
errorKind: "forget_task_not_found",
|
|
7254
|
+
httpStatus: 404
|
|
7255
|
+
})
|
|
6412
7256
|
);
|
|
6413
7257
|
}
|
|
6414
7258
|
return;
|
|
6415
7259
|
}
|
|
7260
|
+
this.replyConn(conn, id, task);
|
|
7261
|
+
return;
|
|
7262
|
+
}
|
|
7263
|
+
case `${QWEN_METHOD_NS}workspace/memory/dream`: {
|
|
6416
7264
|
try {
|
|
6417
7265
|
const available = await this.bridge.isWorkspaceMemoryRememberAvailable();
|
|
6418
7266
|
if (!available) {
|
|
@@ -6431,31 +7279,29 @@ var AcpDispatcher = class {
|
|
|
6431
7279
|
}
|
|
6432
7280
|
return;
|
|
6433
7281
|
}
|
|
6434
|
-
const task = this.workspaceRememberLane.
|
|
6435
|
-
content: content.trim(),
|
|
6436
|
-
contextMode: rawContextMode,
|
|
7282
|
+
const task = this.workspaceRememberLane.enqueueDream({
|
|
6437
7283
|
...conn.clientId ? { originatorClientId: conn.clientId } : {}
|
|
6438
7284
|
});
|
|
6439
7285
|
this.replyConn(conn, id, task);
|
|
6440
7286
|
} catch (err) {
|
|
6441
|
-
const code = extractRememberErrorCode(err);
|
|
7287
|
+
const code = extractRememberErrorCode(err, "dream_failed");
|
|
6442
7288
|
if (id !== void 0) {
|
|
6443
7289
|
conn.sendConn(
|
|
6444
|
-
error(
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
7290
|
+
error(id, -32099, publicErrorMessage(code, "dream"), {
|
|
7291
|
+
errorKind: code,
|
|
7292
|
+
httpStatus: publicErrorStatus(code)
|
|
7293
|
+
})
|
|
7294
|
+
);
|
|
7295
|
+
} else {
|
|
7296
|
+
debugLogger2.warn(
|
|
7297
|
+
"workspace memory dream notification failed:",
|
|
7298
|
+
err
|
|
6453
7299
|
);
|
|
6454
7300
|
}
|
|
6455
7301
|
}
|
|
6456
7302
|
return;
|
|
6457
7303
|
}
|
|
6458
|
-
case `${QWEN_METHOD_NS}workspace/memory/
|
|
7304
|
+
case `${QWEN_METHOD_NS}workspace/memory/dream/get`: {
|
|
6459
7305
|
const taskId = params["taskId"];
|
|
6460
7306
|
if (typeof taskId !== "string" || taskId.length === 0) {
|
|
6461
7307
|
if (id !== void 0) {
|
|
@@ -6463,12 +7309,16 @@ var AcpDispatcher = class {
|
|
|
6463
7309
|
}
|
|
6464
7310
|
return;
|
|
6465
7311
|
}
|
|
6466
|
-
const task = this.workspaceRememberLane.get(
|
|
7312
|
+
const task = this.workspaceRememberLane.get(
|
|
7313
|
+
taskId,
|
|
7314
|
+
conn.clientId,
|
|
7315
|
+
"dream"
|
|
7316
|
+
);
|
|
6467
7317
|
if (!task) {
|
|
6468
7318
|
if (id !== void 0) {
|
|
6469
7319
|
conn.sendConn(
|
|
6470
|
-
error(id, -32004, "Workspace memory
|
|
6471
|
-
errorKind: "
|
|
7320
|
+
error(id, -32004, "Workspace memory dream task not found", {
|
|
7321
|
+
errorKind: "dream_task_not_found",
|
|
6472
7322
|
httpStatus: 404
|
|
6473
7323
|
})
|
|
6474
7324
|
);
|
|
@@ -7324,12 +8174,46 @@ var AcpDispatcher = class {
|
|
|
7324
8174
|
*/
|
|
7325
8175
|
async pumpSessionEvents(conn, sessionId, signal, lastEventId) {
|
|
7326
8176
|
try {
|
|
8177
|
+
let lastDeliveredId = lastEventId ?? 0;
|
|
8178
|
+
let sawEviction = false;
|
|
8179
|
+
let subscribeFromEventId = lastEventId;
|
|
8180
|
+
if (conn.hasInitialReplayPending(sessionId)) {
|
|
8181
|
+
const snapshot = this.bridge.getSessionReplaySnapshot(sessionId);
|
|
8182
|
+
if (snapshot) {
|
|
8183
|
+
const snapshotEvents = [
|
|
8184
|
+
...snapshot.compactedTurns,
|
|
8185
|
+
...snapshot.liveJournal
|
|
8186
|
+
];
|
|
8187
|
+
for (const event of snapshotEvents) {
|
|
8188
|
+
if (signal.aborted) return;
|
|
8189
|
+
if (typeof event.id === "number" && event.id <= lastDeliveredId) {
|
|
8190
|
+
continue;
|
|
8191
|
+
}
|
|
8192
|
+
conn.touch();
|
|
8193
|
+
this.translateEvent(conn, sessionId, event);
|
|
8194
|
+
if (typeof event.id === "number") {
|
|
8195
|
+
lastDeliveredId = event.id;
|
|
8196
|
+
conn.releaseDeferredSessionReplies(sessionId, event.id);
|
|
8197
|
+
}
|
|
8198
|
+
}
|
|
8199
|
+
if (signal.aborted) return;
|
|
8200
|
+
lastDeliveredId = Math.max(lastDeliveredId, snapshot.lastEventId);
|
|
8201
|
+
subscribeFromEventId = Math.max(
|
|
8202
|
+
subscribeFromEventId ?? 0,
|
|
8203
|
+
snapshot.lastEventId
|
|
8204
|
+
);
|
|
8205
|
+
} else {
|
|
8206
|
+
writeStderrLine(
|
|
8207
|
+
`qwen serve: /acp initial replay skipped (no snapshot) session=${logSafe(sessionId)}`
|
|
8208
|
+
);
|
|
8209
|
+
conn.markInitialReplayComplete(sessionId);
|
|
8210
|
+
conn.endReplayDeferral(sessionId, lastDeliveredId, false);
|
|
8211
|
+
}
|
|
8212
|
+
}
|
|
7327
8213
|
const iterable = this.bridge.subscribeEvents(sessionId, {
|
|
7328
8214
|
signal,
|
|
7329
|
-
...
|
|
8215
|
+
...subscribeFromEventId !== void 0 ? { lastEventId: subscribeFromEventId } : {}
|
|
7330
8216
|
});
|
|
7331
|
-
let lastDeliveredId = lastEventId ?? 0;
|
|
7332
|
-
let sawEviction = false;
|
|
7333
8217
|
for await (const event of iterable) {
|
|
7334
8218
|
if (signal.aborted) break;
|
|
7335
8219
|
conn.touch();
|
|
@@ -7341,6 +8225,7 @@ var AcpDispatcher = class {
|
|
|
7341
8225
|
}
|
|
7342
8226
|
if (event.type === "replay_complete") {
|
|
7343
8227
|
conn.endReplayDeferral(sessionId, lastDeliveredId, sawEviction);
|
|
8228
|
+
conn.markInitialReplayComplete(sessionId);
|
|
7344
8229
|
const replayedCount = event.data?.replayedCount;
|
|
7345
8230
|
writeStderrLine(
|
|
7346
8231
|
`qwen serve: /acp replay complete (${logSafe(sessionId)}) from=${lastEventId ?? "none"} delivered_through=${lastDeliveredId} count=${replayedCount ?? "n/a"} evicted=${sawEviction}`
|
|
@@ -7561,7 +8446,7 @@ var AcpDispatcher = class {
|
|
|
7561
8446
|
|
|
7562
8447
|
// packages/cli/src/serve/acp-http/connection-registry.ts
|
|
7563
8448
|
init_esbuild_shims();
|
|
7564
|
-
import { randomUUID } from "node:crypto";
|
|
8449
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
7565
8450
|
var MAX_BUFFERED_FRAMES = 256;
|
|
7566
8451
|
var HARD_BUFFERED_FRAMES_CAP = MAX_BUFFERED_FRAMES * 4;
|
|
7567
8452
|
var DEFAULT_MAX_CONNECTIONS = 64;
|
|
@@ -7569,8 +8454,8 @@ var AcpConnection = class {
|
|
|
7569
8454
|
constructor(connectionId, fromLoopback, onAbandonPending, onDetachSession) {
|
|
7570
8455
|
this.onAbandonPending = onAbandonPending;
|
|
7571
8456
|
this.onDetachSession = onDetachSession;
|
|
7572
|
-
this.connectionId = connectionId ??
|
|
7573
|
-
this.clientId =
|
|
8457
|
+
this.connectionId = connectionId ?? randomUUID2();
|
|
8458
|
+
this.clientId = randomUUID2();
|
|
7574
8459
|
this.fromLoopback = fromLoopback;
|
|
7575
8460
|
}
|
|
7576
8461
|
static {
|
|
@@ -7669,6 +8554,16 @@ var AcpConnection = class {
|
|
|
7669
8554
|
}
|
|
7670
8555
|
return binding;
|
|
7671
8556
|
}
|
|
8557
|
+
markInitialReplayPending(sessionId) {
|
|
8558
|
+
this.getOrCreateSession(sessionId).initialReplayPending = true;
|
|
8559
|
+
}
|
|
8560
|
+
hasInitialReplayPending(sessionId) {
|
|
8561
|
+
return this.sessions.get(sessionId)?.initialReplayPending === true;
|
|
8562
|
+
}
|
|
8563
|
+
markInitialReplayComplete(sessionId) {
|
|
8564
|
+
const binding = this.sessions.get(sessionId);
|
|
8565
|
+
if (binding) binding.initialReplayPending = false;
|
|
8566
|
+
}
|
|
7672
8567
|
getDiagnostic() {
|
|
7673
8568
|
const liveStreams = /* @__PURE__ */ new Set();
|
|
7674
8569
|
if (this.connStream && !this.connStream.isClosed) {
|
|
@@ -7856,15 +8751,16 @@ var AcpConnection = class {
|
|
|
7856
8751
|
if (prevStream && prevStream !== stream && prevStream !== this.connStream) {
|
|
7857
8752
|
prevStream.close();
|
|
7858
8753
|
}
|
|
7859
|
-
|
|
8754
|
+
const replayingOnAttach = resumeFromEventId !== void 0 || binding.initialReplayPending === true;
|
|
8755
|
+
binding.replayPending = replayingOnAttach;
|
|
7860
8756
|
if (binding.replayPending) {
|
|
7861
8757
|
writeStderrLine(
|
|
7862
|
-
`qwen serve: /acp replay deferral armed (${logSafe(sessionId)}, from id ${resumeFromEventId})`
|
|
8758
|
+
`qwen serve: /acp replay deferral armed (${logSafe(sessionId)}, from id ${resumeFromEventId ?? "initial"})`
|
|
7863
8759
|
);
|
|
7864
8760
|
}
|
|
7865
8761
|
const gap = binding.buffer.splice(0);
|
|
7866
8762
|
for (const entry of gap) {
|
|
7867
|
-
if (
|
|
8763
|
+
if (!replayingOnAttach) {
|
|
7868
8764
|
void stream.send(entry.frame, entry.id);
|
|
7869
8765
|
} else if (entry.id !== void 0) {
|
|
7870
8766
|
continue;
|
|
@@ -9306,6 +10202,7 @@ var WS_READ_METHODS = /* @__PURE__ */ new Set([
|
|
|
9306
10202
|
"_qwen/session/context_usage",
|
|
9307
10203
|
"_qwen/session/tasks",
|
|
9308
10204
|
"_qwen/session/lsp",
|
|
10205
|
+
"_qwen/session/artifacts",
|
|
9309
10206
|
"_qwen/workspace/mcp",
|
|
9310
10207
|
"_qwen/workspace/skills",
|
|
9311
10208
|
"_qwen/workspace/providers",
|
|
@@ -9321,6 +10218,8 @@ var WS_READ_METHODS = /* @__PURE__ */ new Set([
|
|
|
9321
10218
|
"_qwen/workspace/agents/get",
|
|
9322
10219
|
"_qwen/workspace/memory",
|
|
9323
10220
|
"_qwen/workspace/memory/remember/get",
|
|
10221
|
+
"_qwen/workspace/memory/forget/get",
|
|
10222
|
+
"_qwen/workspace/memory/dream/get",
|
|
9324
10223
|
"_qwen/workspace/auth/status",
|
|
9325
10224
|
"_qwen/workspace/auth/device_flow/get",
|
|
9326
10225
|
"_qwen/file/read",
|
|
@@ -10228,7 +11127,7 @@ function loadDaemonVoiceContext(workspaceCwd) {
|
|
|
10228
11127
|
__name(loadDaemonVoiceContext, "loadDaemonVoiceContext");
|
|
10229
11128
|
|
|
10230
11129
|
// packages/cli/src/serve/voice/voice-ws.ts
|
|
10231
|
-
var
|
|
11130
|
+
var debugLogger3 = createDebugLogger("VOICE_WS");
|
|
10232
11131
|
var MAX_BATCH_AUDIO_BYTES = 10 * 1024 * 1024;
|
|
10233
11132
|
var MAX_QUEUED_AUDIO_BYTES = MAX_BATCH_AUDIO_BYTES * 2;
|
|
10234
11133
|
var MAX_CONNECTION_MS = 6 * 6e4;
|
|
@@ -10267,7 +11166,7 @@ async function defaultOpenStream(ctx, callbacks) {
|
|
|
10267
11166
|
() => cfg.transport === "qwen-asr-realtime" ? openQwenAsrRealtimeStream(cfg, callbacks) : openVoiceStream(cfg, callbacks)
|
|
10268
11167
|
);
|
|
10269
11168
|
} catch (error2) {
|
|
10270
|
-
|
|
11169
|
+
debugLogger3.debug(`[voice-ws] stream open error: ${errMessage(error2)}`);
|
|
10271
11170
|
throw new Error(GENERIC_TRANSCRIPTION_ERROR);
|
|
10272
11171
|
}
|
|
10273
11172
|
}
|
|
@@ -10277,7 +11176,7 @@ function defaultTranscribe(ctx, pcm) {
|
|
|
10277
11176
|
{ data: encodeWav(pcm), mimeType: "audio/wav" },
|
|
10278
11177
|
{ config: ctx.models, settings: ctx.settings, voiceModel: ctx.voiceModel }
|
|
10279
11178
|
).catch((error2) => {
|
|
10280
|
-
|
|
11179
|
+
debugLogger3.debug(
|
|
10281
11180
|
`[voice-ws] batch transcription error: ${errMessage(error2)}`
|
|
10282
11181
|
);
|
|
10283
11182
|
throw new Error(GENERIC_TRANSCRIPTION_ERROR);
|
|
@@ -10407,7 +11306,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10407
11306
|
try {
|
|
10408
11307
|
ctx = loadContext(boundWorkspace);
|
|
10409
11308
|
} catch (error2) {
|
|
10410
|
-
|
|
11309
|
+
debugLogger3.debug(
|
|
10411
11310
|
`[voice-ws] load context error: ${errMessage(error2)}`
|
|
10412
11311
|
);
|
|
10413
11312
|
fail(voiceConfigErrorMessage(error2));
|
|
@@ -10422,7 +11321,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10422
11321
|
const callbacks = {
|
|
10423
11322
|
onInterim: /* @__PURE__ */ __name((text) => sendJson({ type: "interim", text }), "onInterim"),
|
|
10424
11323
|
onError: /* @__PURE__ */ __name((error2) => {
|
|
10425
|
-
|
|
11324
|
+
debugLogger3.debug(
|
|
10426
11325
|
`[voice-ws] upstream error: ${errMessage(error2)}`
|
|
10427
11326
|
);
|
|
10428
11327
|
fail(GENERIC_TRANSCRIPTION_ERROR);
|
|
@@ -10541,7 +11440,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10541
11440
|
releaseSlotWhenIdle();
|
|
10542
11441
|
}
|
|
10543
11442
|
}).catch((error2) => {
|
|
10544
|
-
|
|
11443
|
+
debugLogger3.debug(`[voice-ws] ${errMessage(error2)}`);
|
|
10545
11444
|
fail(GENERIC_TRANSCRIPTION_ERROR);
|
|
10546
11445
|
releaseSlotWhenIdle();
|
|
10547
11446
|
});
|
|
@@ -10551,7 +11450,7 @@ function createVoiceWsConnectionHandler(boundWorkspace, deps = {}) {
|
|
|
10551
11450
|
releaseSlotWhenIdle();
|
|
10552
11451
|
});
|
|
10553
11452
|
ws.on("error", (error2) => {
|
|
10554
|
-
|
|
11453
|
+
debugLogger3.debug(`[voice-ws] socket error: ${error2.message}`);
|
|
10555
11454
|
if (state !== "closed") cleanup();
|
|
10556
11455
|
releaseSlotWhenIdle();
|
|
10557
11456
|
});
|
|
@@ -10631,335 +11530,78 @@ var WEB_SHELL_CSP = buildWebShellCsp();
|
|
|
10631
11530
|
function isDocumentNavigation(req) {
|
|
10632
11531
|
const fetchMode = req.headers["sec-fetch-mode"];
|
|
10633
11532
|
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;
|
|
10873
|
-
}
|
|
10874
|
-
return clientId;
|
|
11533
|
+
const accept = req.headers.accept ?? "";
|
|
11534
|
+
return fetchMode === "navigate" || fetchDest === "document" || accept.trim().toLowerCase().startsWith("text/html");
|
|
10875
11535
|
}
|
|
10876
|
-
__name(
|
|
10877
|
-
function
|
|
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
|
-
return;
|
|
10906
|
-
}
|
|
10907
|
-
const originatorClientId = validateOriginatorClientId(deps, req, res);
|
|
10908
|
-
if (originatorClientId === null) return;
|
|
10909
|
-
try {
|
|
10910
|
-
const available = await deps.bridge.isWorkspaceMemoryRememberAvailable();
|
|
10911
|
-
if (!available) {
|
|
10912
|
-
res.status(409).json({
|
|
10913
|
-
error: "Managed memory is unavailable for this daemon workspace",
|
|
10914
|
-
code: "managed_memory_unavailable"
|
|
10915
|
-
});
|
|
10916
|
-
return;
|
|
11536
|
+
__name(isDocumentNavigation, "isDocumentNavigation");
|
|
11537
|
+
function createSendIndex(webShellDir, frameAncestors = []) {
|
|
11538
|
+
const indexPath = path9.join(webShellDir, "index.html");
|
|
11539
|
+
const csp = buildWebShellCsp(frameAncestors);
|
|
11540
|
+
return (res) => {
|
|
11541
|
+
res.status(200).set("Content-Security-Policy", csp).set("X-Content-Type-Options", "nosniff").set("Referrer-Policy", "no-referrer").set(
|
|
11542
|
+
// `microphone=(self)` lets the same-origin Web Shell document request
|
|
11543
|
+
// the mic for voice dictation (the prompt won't even appear under an
|
|
11544
|
+
// empty `microphone=()` allowlist). Still blocks cross-origin iframes;
|
|
11545
|
+
// camera/geolocation/payment stay disabled (unused).
|
|
11546
|
+
"Permissions-Policy",
|
|
11547
|
+
"camera=(), microphone=(self), geolocation=(), payment=()"
|
|
11548
|
+
).set("Cache-Control", "no-cache");
|
|
11549
|
+
if (frameAncestors.length === 0) {
|
|
11550
|
+
res.set("X-Frame-Options", "DENY");
|
|
11551
|
+
}
|
|
11552
|
+
res.sendFile(
|
|
11553
|
+
indexPath,
|
|
11554
|
+
{ cacheControl: false, dotfiles: "allow" },
|
|
11555
|
+
(err) => {
|
|
11556
|
+
if (!err) return;
|
|
11557
|
+
writeStderrLine(
|
|
11558
|
+
`qwen serve: Web Shell index send failed: ${err instanceof Error ? err.message : String(err)}`
|
|
11559
|
+
);
|
|
11560
|
+
if (!res.headersSent) {
|
|
11561
|
+
res.status(500).type("text/plain").send("Failed to load Web Shell");
|
|
11562
|
+
} else {
|
|
11563
|
+
res.end();
|
|
10917
11564
|
}
|
|
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
11565
|
}
|
|
10941
|
-
|
|
10942
|
-
|
|
11566
|
+
);
|
|
11567
|
+
};
|
|
11568
|
+
}
|
|
11569
|
+
__name(createSendIndex, "createSendIndex");
|
|
11570
|
+
function mountWebShellAssets(app, webShellDir, frameAncestors = []) {
|
|
11571
|
+
const sendIndex = createSendIndex(webShellDir, frameAncestors);
|
|
11572
|
+
app.use(
|
|
11573
|
+
"/assets",
|
|
11574
|
+
import_express2.default.static(path9.join(webShellDir, "assets"), {
|
|
11575
|
+
index: false,
|
|
11576
|
+
immutable: true,
|
|
11577
|
+
maxAge: "1y"
|
|
11578
|
+
})
|
|
10943
11579
|
);
|
|
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);
|
|
11580
|
+
app.use("/assets", (req, res) => {
|
|
11581
|
+
if (isServeDebugMode()) {
|
|
11582
|
+
writeStderrLine(
|
|
11583
|
+
`qwen serve: Web Shell asset not found: ${req.originalUrl}`
|
|
11584
|
+
);
|
|
10959
11585
|
}
|
|
10960
|
-
|
|
11586
|
+
res.status(404).type("text/plain").send("Not found");
|
|
11587
|
+
});
|
|
11588
|
+
app.get("/", (_req, res) => sendIndex(res));
|
|
10961
11589
|
}
|
|
10962
|
-
__name(
|
|
11590
|
+
__name(mountWebShellAssets, "mountWebShellAssets");
|
|
11591
|
+
function mountWebShellSpaFallback(app, webShellDir, frameAncestors = []) {
|
|
11592
|
+
const sendIndex = createSendIndex(webShellDir, frameAncestors);
|
|
11593
|
+
app.use((req, res, next) => {
|
|
11594
|
+
if (req.method !== "GET" && req.method !== "HEAD") return next();
|
|
11595
|
+
if (!isDocumentNavigation(req)) return next();
|
|
11596
|
+
if (isServeDebugMode()) {
|
|
11597
|
+
writeStderrLine(
|
|
11598
|
+
`qwen serve: Web Shell SPA fallback served for ${req.method} ${req.originalUrl}`
|
|
11599
|
+
);
|
|
11600
|
+
}
|
|
11601
|
+
sendIndex(res);
|
|
11602
|
+
});
|
|
11603
|
+
}
|
|
11604
|
+
__name(mountWebShellSpaFallback, "mountWebShellSpaFallback");
|
|
10963
11605
|
|
|
10964
11606
|
// packages/cli/src/serve/routes/daemon-status.ts
|
|
10965
11607
|
init_esbuild_shims();
|
|
@@ -10991,7 +11633,8 @@ function registerDaemonStatusRoutes(app, deps) {
|
|
|
10991
11633
|
supportedDeviceFlowProviders: deps.getSupportedDeviceFlowProviders(),
|
|
10992
11634
|
deviceFlowRegistry: deps.deviceFlowRegistry,
|
|
10993
11635
|
sessionShellCommandEnabled: deps.sessionShellCommandEnabled,
|
|
10994
|
-
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot
|
|
11636
|
+
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot,
|
|
11637
|
+
getPerfSnapshot: deps.getPerfSnapshot
|
|
10995
11638
|
})
|
|
10996
11639
|
);
|
|
10997
11640
|
} catch (err) {
|
|
@@ -13481,7 +14124,81 @@ function parseSessionPageSizeQuery(raw) {
|
|
|
13481
14124
|
}
|
|
13482
14125
|
__name(parseSessionPageSizeQuery, "parseSessionPageSizeQuery");
|
|
13483
14126
|
|
|
14127
|
+
// packages/cli/src/serve/server/session-export.ts
|
|
14128
|
+
init_esbuild_shims();
|
|
14129
|
+
var SESSION_EXPORT_FORMATS = ["html", "md", "json", "jsonl"];
|
|
14130
|
+
var EXPORT_FORMATS = {
|
|
14131
|
+
html: {
|
|
14132
|
+
mimeType: "text/html; charset=utf-8",
|
|
14133
|
+
render: toHtml
|
|
14134
|
+
},
|
|
14135
|
+
md: {
|
|
14136
|
+
mimeType: "text/markdown; charset=utf-8",
|
|
14137
|
+
render: toMarkdown
|
|
14138
|
+
},
|
|
14139
|
+
json: {
|
|
14140
|
+
mimeType: "application/json; charset=utf-8",
|
|
14141
|
+
render: toJson
|
|
14142
|
+
},
|
|
14143
|
+
jsonl: {
|
|
14144
|
+
mimeType: "application/jsonl; charset=utf-8",
|
|
14145
|
+
render: toJsonl
|
|
14146
|
+
}
|
|
14147
|
+
};
|
|
14148
|
+
function parseSessionExportFormat(rawFormat) {
|
|
14149
|
+
if (rawFormat === void 0) return "html";
|
|
14150
|
+
if (typeof rawFormat !== "string") return void 0;
|
|
14151
|
+
return SESSION_EXPORT_FORMATS.includes(rawFormat) ? rawFormat : void 0;
|
|
14152
|
+
}
|
|
14153
|
+
__name(parseSessionExportFormat, "parseSessionExportFormat");
|
|
14154
|
+
function sessionExportFormatValues() {
|
|
14155
|
+
return [...SESSION_EXPORT_FORMATS];
|
|
14156
|
+
}
|
|
14157
|
+
__name(sessionExportFormatValues, "sessionExportFormatValues");
|
|
14158
|
+
async function exportSessionTranscript(params) {
|
|
14159
|
+
const { workspaceCwd, sessionId, format } = params;
|
|
14160
|
+
const sessionData = await new SessionService(workspaceCwd).loadSession(
|
|
14161
|
+
sessionId
|
|
14162
|
+
);
|
|
14163
|
+
if (!sessionData) {
|
|
14164
|
+
throw new SessionNotFoundError(sessionId);
|
|
14165
|
+
}
|
|
14166
|
+
const exportConfig = params.config ?? {};
|
|
14167
|
+
const collected = await collectSessionData(
|
|
14168
|
+
sessionData.conversation,
|
|
14169
|
+
exportConfig
|
|
14170
|
+
);
|
|
14171
|
+
const normalized = normalizeSessionData(
|
|
14172
|
+
collected,
|
|
14173
|
+
sessionData.conversation.messages,
|
|
14174
|
+
exportConfig
|
|
14175
|
+
);
|
|
14176
|
+
const formatDefinition = EXPORT_FORMATS[format];
|
|
14177
|
+
return {
|
|
14178
|
+
format,
|
|
14179
|
+
filename: generateExportFilename(format),
|
|
14180
|
+
mimeType: formatDefinition.mimeType,
|
|
14181
|
+
content: formatDefinition.render(normalized)
|
|
14182
|
+
};
|
|
14183
|
+
}
|
|
14184
|
+
__name(exportSessionTranscript, "exportSessionTranscript");
|
|
14185
|
+
|
|
13484
14186
|
// packages/cli/src/serve/routes/session.ts
|
|
14187
|
+
function sendArtifactValidationError(res, err) {
|
|
14188
|
+
if (!(err instanceof SessionArtifactValidationError)) {
|
|
14189
|
+
return false;
|
|
14190
|
+
}
|
|
14191
|
+
res.status(400).json({
|
|
14192
|
+
v: 1,
|
|
14193
|
+
error: {
|
|
14194
|
+
code: err.code,
|
|
14195
|
+
message: err.message,
|
|
14196
|
+
...err.field ? { field: err.field } : {}
|
|
14197
|
+
}
|
|
14198
|
+
});
|
|
14199
|
+
return true;
|
|
14200
|
+
}
|
|
14201
|
+
__name(sendArtifactValidationError, "sendArtifactValidationError");
|
|
13485
14202
|
function registerSessionRoutes(app, deps) {
|
|
13486
14203
|
const {
|
|
13487
14204
|
boundWorkspace,
|
|
@@ -13593,6 +14310,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
13593
14310
|
return action === "load" ? await bridge.loadSession({
|
|
13594
14311
|
sessionId,
|
|
13595
14312
|
workspaceCwd: cwd,
|
|
14313
|
+
historyReplay: "response",
|
|
13596
14314
|
...clientId !== void 0 ? { clientId } : {}
|
|
13597
14315
|
}) : await bridge.resumeSession({
|
|
13598
14316
|
sessionId,
|
|
@@ -13723,6 +14441,42 @@ function registerSessionRoutes(app, deps) {
|
|
|
13723
14441
|
});
|
|
13724
14442
|
}
|
|
13725
14443
|
});
|
|
14444
|
+
app.get("/session/:id/export", async (req, res) => {
|
|
14445
|
+
const sessionId = requireSessionId(req, res);
|
|
14446
|
+
if (sessionId === null) return;
|
|
14447
|
+
const rawFormat = req.query["format"];
|
|
14448
|
+
const format = parseSessionExportFormat(rawFormat);
|
|
14449
|
+
if (!format) {
|
|
14450
|
+
res.status(400).json({
|
|
14451
|
+
error: "Invalid export format",
|
|
14452
|
+
code: "invalid_export_format",
|
|
14453
|
+
format: typeof rawFormat === "string" ? rawFormat : String(rawFormat),
|
|
14454
|
+
allowedFormats: sessionExportFormatValues()
|
|
14455
|
+
});
|
|
14456
|
+
return;
|
|
14457
|
+
}
|
|
14458
|
+
try {
|
|
14459
|
+
const result = await archiveCoordinator.runSharedMany(
|
|
14460
|
+
[sessionId],
|
|
14461
|
+
async () => {
|
|
14462
|
+
await assertSessionLoadable(boundWorkspace, sessionId);
|
|
14463
|
+
return exportSessionTranscript({
|
|
14464
|
+
workspaceCwd: boundWorkspace,
|
|
14465
|
+
sessionId,
|
|
14466
|
+
format,
|
|
14467
|
+
config: { getChannel: /* @__PURE__ */ __name(() => "daemon", "getChannel") }
|
|
14468
|
+
});
|
|
14469
|
+
}
|
|
14470
|
+
);
|
|
14471
|
+
const filename = result.filename.replace(/["\\\r\n]/g, "_");
|
|
14472
|
+
res.status(200).set("Cache-Control", "no-store").set("X-Content-Type-Options", "nosniff").set("Content-Type", result.mimeType).set("Content-Disposition", `attachment; filename="${filename}"`).send(result.content);
|
|
14473
|
+
} catch (err) {
|
|
14474
|
+
sendBridgeError2(res, err, {
|
|
14475
|
+
route: "GET /session/:id/export",
|
|
14476
|
+
sessionId
|
|
14477
|
+
});
|
|
14478
|
+
}
|
|
14479
|
+
});
|
|
13726
14480
|
app.get("/session/:id/context", async (req, res) => {
|
|
13727
14481
|
const sessionId = requireSessionId(req, res);
|
|
13728
14482
|
if (sessionId === null) return;
|
|
@@ -13808,6 +14562,92 @@ function registerSessionRoutes(app, deps) {
|
|
|
13808
14562
|
sendBridgeError2(res, err, { route: "GET /session/:id/hooks", sessionId });
|
|
13809
14563
|
}
|
|
13810
14564
|
});
|
|
14565
|
+
app.get("/session/:id/artifacts", async (req, res) => {
|
|
14566
|
+
const sessionId = requireSessionId(req, res);
|
|
14567
|
+
if (sessionId === null) return;
|
|
14568
|
+
try {
|
|
14569
|
+
res.status(200).json(await bridge.getSessionArtifacts(sessionId));
|
|
14570
|
+
} catch (err) {
|
|
14571
|
+
sendBridgeError2(res, err, {
|
|
14572
|
+
route: "GET /session/:id/artifacts",
|
|
14573
|
+
sessionId
|
|
14574
|
+
});
|
|
14575
|
+
}
|
|
14576
|
+
});
|
|
14577
|
+
app.post(
|
|
14578
|
+
"/session/:id/artifacts",
|
|
14579
|
+
mutate({ strict: true }),
|
|
14580
|
+
withMutableSession(
|
|
14581
|
+
"POST /session/:id/artifacts",
|
|
14582
|
+
async (req, res, sessionId) => {
|
|
14583
|
+
const clientId = parseClientIdHeader(req, res);
|
|
14584
|
+
if (clientId === null) return;
|
|
14585
|
+
try {
|
|
14586
|
+
const body = safeBody(req);
|
|
14587
|
+
const artifact = {
|
|
14588
|
+
title: body["title"],
|
|
14589
|
+
kind: body["kind"],
|
|
14590
|
+
storage: body["storage"],
|
|
14591
|
+
description: body["description"],
|
|
14592
|
+
workspacePath: body["workspacePath"],
|
|
14593
|
+
managedId: body["managedId"],
|
|
14594
|
+
url: body["url"],
|
|
14595
|
+
mimeType: body["mimeType"],
|
|
14596
|
+
sizeBytes: body["sizeBytes"],
|
|
14597
|
+
metadata: body["metadata"]
|
|
14598
|
+
};
|
|
14599
|
+
const result = await bridge.addSessionArtifact(
|
|
14600
|
+
sessionId,
|
|
14601
|
+
artifact,
|
|
14602
|
+
clientId !== void 0 ? { clientId } : void 0
|
|
14603
|
+
);
|
|
14604
|
+
res.status(200).json(result);
|
|
14605
|
+
} catch (err) {
|
|
14606
|
+
if (sendArtifactValidationError(res, err)) return;
|
|
14607
|
+
sendBridgeError2(res, err, {
|
|
14608
|
+
route: "POST /session/:id/artifacts",
|
|
14609
|
+
sessionId
|
|
14610
|
+
});
|
|
14611
|
+
}
|
|
14612
|
+
}
|
|
14613
|
+
)
|
|
14614
|
+
);
|
|
14615
|
+
app.delete(
|
|
14616
|
+
"/session/:id/artifacts/:artifactId",
|
|
14617
|
+
mutate({ strict: true }),
|
|
14618
|
+
withMutableSession(
|
|
14619
|
+
"DELETE /session/:id/artifacts/:artifactId",
|
|
14620
|
+
async (req, res, sessionId) => {
|
|
14621
|
+
const artifactId = req.params["artifactId"];
|
|
14622
|
+
const clientId = parseClientIdHeader(req, res);
|
|
14623
|
+
if (clientId === null) return;
|
|
14624
|
+
if (!artifactId) {
|
|
14625
|
+
res.status(400).json({
|
|
14626
|
+
v: 1,
|
|
14627
|
+
error: {
|
|
14628
|
+
code: "VALIDATION_FAILED",
|
|
14629
|
+
message: "`artifactId` route parameter is required",
|
|
14630
|
+
field: "artifactId"
|
|
14631
|
+
}
|
|
14632
|
+
});
|
|
14633
|
+
return;
|
|
14634
|
+
}
|
|
14635
|
+
try {
|
|
14636
|
+
const result = await bridge.removeSessionArtifact(
|
|
14637
|
+
sessionId,
|
|
14638
|
+
artifactId,
|
|
14639
|
+
clientId !== void 0 ? { clientId } : void 0
|
|
14640
|
+
);
|
|
14641
|
+
res.status(200).json(result);
|
|
14642
|
+
} catch (err) {
|
|
14643
|
+
sendBridgeError2(res, err, {
|
|
14644
|
+
route: "DELETE /session/:id/artifacts/:artifactId",
|
|
14645
|
+
sessionId
|
|
14646
|
+
});
|
|
14647
|
+
}
|
|
14648
|
+
}
|
|
14649
|
+
)
|
|
14650
|
+
);
|
|
13811
14651
|
app.post(
|
|
13812
14652
|
"/session/:id/tasks/:taskId/cancel",
|
|
13813
14653
|
mutate({ strict: true }),
|
|
@@ -14136,6 +14976,7 @@ function registerSessionRoutes(app, deps) {
|
|
|
14136
14976
|
});
|
|
14137
14977
|
app.patch(
|
|
14138
14978
|
"/session/:id/metadata",
|
|
14979
|
+
mutate({ strict: true }),
|
|
14139
14980
|
withMutableSession("PATCH /session/:id/metadata", (req, res, sessionId) => {
|
|
14140
14981
|
const body = safeBody(req);
|
|
14141
14982
|
const clientId = parseClientIdHeader(req, res);
|
|
@@ -15924,6 +16765,30 @@ function resolveDaemonTelemetryRoute(req) {
|
|
|
15924
16765
|
sessionId: sessionMetadata[1]
|
|
15925
16766
|
};
|
|
15926
16767
|
}
|
|
16768
|
+
const sessionArtifacts = path12.match(/^\/session\/([^/]+)\/artifacts$/);
|
|
16769
|
+
if (sessionArtifacts?.[1]) {
|
|
16770
|
+
if (req.method === "GET") {
|
|
16771
|
+
return {
|
|
16772
|
+
route: "GET /session/:id/artifacts",
|
|
16773
|
+
sessionId: sessionArtifacts[1]
|
|
16774
|
+
};
|
|
16775
|
+
}
|
|
16776
|
+
if (req.method === "POST") {
|
|
16777
|
+
return {
|
|
16778
|
+
route: "POST /session/:id/artifacts",
|
|
16779
|
+
sessionId: sessionArtifacts[1]
|
|
16780
|
+
};
|
|
16781
|
+
}
|
|
16782
|
+
}
|
|
16783
|
+
const sessionArtifact = path12.match(
|
|
16784
|
+
/^\/session\/([^/]+)\/artifacts\/([^/]+)$/
|
|
16785
|
+
);
|
|
16786
|
+
if (sessionArtifact?.[1] && req.method === "DELETE") {
|
|
16787
|
+
return {
|
|
16788
|
+
route: "DELETE /session/:id/artifacts/:artifactId",
|
|
16789
|
+
sessionId: sessionArtifact[1]
|
|
16790
|
+
};
|
|
16791
|
+
}
|
|
15927
16792
|
const sessionPermission = path12.match(
|
|
15928
16793
|
/^\/session\/([^/]+)\/permission\/([^/]+)$/
|
|
15929
16794
|
);
|
|
@@ -16858,7 +17723,8 @@ function createServeApp(opts, getPort = () => opts.port, deps = {}) {
|
|
|
16858
17723
|
getSupportedDeviceFlowProviders,
|
|
16859
17724
|
deviceFlowRegistry,
|
|
16860
17725
|
sessionShellCommandEnabled,
|
|
16861
|
-
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot
|
|
17726
|
+
getChannelWorkerSnapshot: deps.getChannelWorkerSnapshot,
|
|
17727
|
+
getPerfSnapshot: deps.getPerfSnapshot
|
|
16862
17728
|
});
|
|
16863
17729
|
registerCapabilitiesRoutes(app, {
|
|
16864
17730
|
qwenCodeVersion: deps.qwenCodeVersion,
|
|
@@ -17112,6 +17978,11 @@ export {
|
|
|
17112
17978
|
* Copyright 2025 Qwen Team
|
|
17113
17979
|
* SPDX-License-Identifier: Apache-2.0
|
|
17114
17980
|
*/
|
|
17981
|
+
/**
|
|
17982
|
+
* @license
|
|
17983
|
+
* Copyright 2026 Qwen Team
|
|
17984
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
17985
|
+
*/
|
|
17115
17986
|
/**
|
|
17116
17987
|
* @license
|
|
17117
17988
|
* Copyright 2026 Qwen Team
|
|
@@ -17131,11 +18002,6 @@ export {
|
|
|
17131
18002
|
*
|
|
17132
18003
|
* See `packages/chrome-extension/docs/06-plan-c-cdp-tunnel.md`.
|
|
17133
18004
|
*/
|
|
17134
|
-
/**
|
|
17135
|
-
* @license
|
|
17136
|
-
* Copyright 2026 Qwen Team
|
|
17137
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
17138
|
-
*/
|
|
17139
18005
|
/**
|
|
17140
18006
|
* @license
|
|
17141
18007
|
* Copyright 2026 Qwen Team
|