@qwen-code/qwen-code 0.25.4-preview.0 → 0.25.4-preview.1
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/browser-use/runtime/native-host.js +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_chrome_beta_linux.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_chrome_beta_mac.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_chrome_stable_linux.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_chrome_stable_mac.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_msedge_beta_linux.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_msedge_beta_mac.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_msedge_dev_linux.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_msedge_dev_mac.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_msedge_stable_linux.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/bin/reinstall_msedge_stable_mac.sh +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/cli.js +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
- package/bundled/browser-use/runtime/node_modules/playwright-core/lib/xdg-open +0 -0
- package/bundled/browser-use/runtime/scripts/native-host-setup.js +0 -0
- package/chunks/{MaxSizedBox-M27H235V.js → MaxSizedBox-E4RKSA7W.js} +1 -1
- package/chunks/{StandaloneSessionPicker-LWWDDYOW.js → StandaloneSessionPicker-2D3UKLVS.js} +1 -1
- package/chunks/{acp-subagent-executor-NUV52JVS.js → acp-subagent-executor-UQYUN6AB.js} +1 -1
- package/chunks/{acpAgent-IUJDXLZM.js → acpAgent-P7WGK2BP.js} +3 -3
- package/chunks/{advisor-MSOUBMJ6.js → advisor-GCH2MBXT.js} +1 -1
- package/chunks/{agent-H7XIWYWQ.js → agent-57T4YAYP.js} +1 -1
- package/chunks/{agent-headless-XDN3D3S3.js → agent-headless-IBON3A7N.js} +1 -1
- package/chunks/{agent-host-client-AZP3PZXS.js → agent-host-client-LE7P72FR.js} +1 -1
- package/chunks/{agent-host-connections-JRVX7I6I.js → agent-host-connections-4DM57L26.js} +1 -1
- package/chunks/{anthropicContentGenerator-N7TV53LD.js → anthropicContentGenerator-C4TPFXUK.js} +1 -1
- package/chunks/{batch-MKSJFJUH.js → batch-YJJGMJWO.js} +1 -1
- package/chunks/{bridge-GNMKKHQ4.js → bridge-FIO2ENBG.js} +1 -1
- package/chunks/{channel-settings-store-Y4YCS7JX.js → channel-settings-store-TEBCLK2B.js} +1 -1
- package/chunks/{chunk-GPOUP5OK.js → chunk-27MTSS3T.js} +1 -1
- package/chunks/{chunk-C4ANA47H.js → chunk-2MGCRPM3.js} +1 -1
- package/chunks/{chunk-6DQNNRRC.js → chunk-2WBKWPSO.js} +1 -1
- package/chunks/{chunk-CATL2PQS.js → chunk-34WLYVDK.js} +5 -5
- package/chunks/{chunk-B7CXPNCV.js → chunk-3J2YNEHG.js} +1 -1
- package/chunks/{chunk-VTNHPXNL.js → chunk-3TBFTELA.js} +1 -1
- package/chunks/{chunk-7JT34VGK.js → chunk-46I6JBVL.js} +1 -1
- package/chunks/{chunk-FEMWELCV.js → chunk-4ZKFLOEH.js} +1 -1
- package/chunks/{chunk-7AYXAVTZ.js → chunk-5DUJIOOX.js} +3 -3
- package/chunks/{chunk-6QLHJSVW.js → chunk-6PWOLWTH.js} +1 -1
- package/chunks/{chunk-OW4QBRSR.js → chunk-6UZ65Z2P.js} +1 -1
- package/chunks/{chunk-V2JZO5MS.js → chunk-7DSJE3CL.js} +1 -1
- package/chunks/{chunk-TJMHIEYI.js → chunk-7LCY7GGX.js} +1 -1
- package/chunks/{chunk-TLJHBK3A.js → chunk-7RNTXEWH.js} +1 -1
- package/chunks/{chunk-YZ7OO4AQ.js → chunk-A3IF6IOB.js} +1 -1
- package/chunks/{chunk-VTF6AVZB.js → chunk-A6OQSOUO.js} +1 -1
- package/chunks/{chunk-Y7YDHCON.js → chunk-AJ6JUUP7.js} +1 -1
- package/chunks/{chunk-QTMHQGWQ.js → chunk-AOMEBVFW.js} +1 -1
- package/chunks/{chunk-KVTG2ZNH.js → chunk-AUNAS7AS.js} +1 -1
- package/chunks/{chunk-BOFD4CN3.js → chunk-AVIDPC5K.js} +1 -1
- package/chunks/{chunk-ETYTRKB2.js → chunk-BOLPBPWC.js} +1 -1
- package/chunks/{chunk-OAPA66DR.js → chunk-BQQBFDBY.js} +1 -1
- package/chunks/{chunk-NOS2CNOI.js → chunk-CN22ATWU.js} +1 -1
- package/chunks/{chunk-XYBEQRSZ.js → chunk-DIHJELGW.js} +1 -1
- package/chunks/{chunk-XCEL3EDX.js → chunk-DJFCI7TU.js} +1 -1
- package/chunks/{chunk-VKEL2XTM.js → chunk-DQPDMFS3.js} +1 -1
- package/chunks/{chunk-DJRFEZBY.js → chunk-DSYKB77N.js} +1 -1
- package/chunks/{chunk-UEW7Q26E.js → chunk-EDNOGHMN.js} +2 -2
- package/chunks/{chunk-RXNGYG64.js → chunk-EE36D2EV.js} +1 -1
- package/chunks/{chunk-NZKX7HYL.js → chunk-EGQDN3FJ.js} +1 -1
- package/chunks/{chunk-DFRSQK5Q.js → chunk-FHFBCG6N.js} +1 -1
- package/chunks/{chunk-PECV2VVZ.js → chunk-GI6T3RBV.js} +1 -1
- package/chunks/{chunk-37BNHIUB.js → chunk-GOLT5JXA.js} +1 -1
- package/chunks/{chunk-KITFF4GL.js → chunk-IDGXHMNL.js} +1 -1
- package/chunks/{chunk-6HIOSLUM.js → chunk-IIZWK7ZP.js} +1 -1
- package/chunks/{chunk-MPGEAX4K.js → chunk-IJC6ZH2S.js} +1 -1
- package/chunks/{chunk-TLYJVB5H.js → chunk-IO6LSEPV.js} +1 -1
- package/chunks/{chunk-QIJKEZZR.js → chunk-IYVNCBMS.js} +1 -1
- package/chunks/{chunk-S4GOHFRN.js → chunk-JHGOWK7M.js} +1 -1
- package/chunks/{chunk-GHRD2MMC.js → chunk-JRJY343T.js} +1 -1
- package/chunks/{chunk-WCYZSCG7.js → chunk-JVUXQU3W.js} +1 -1
- package/chunks/{chunk-DMCTJUIJ.js → chunk-K2K2YYWO.js} +1 -1
- package/chunks/{chunk-37OHWQHB.js → chunk-KF6HU732.js} +2 -2
- package/chunks/{chunk-5LSV73BG.js → chunk-KVWUOBH7.js} +1 -1
- package/chunks/{chunk-7V4BAHFT.js → chunk-LBWBGFHD.js} +1 -1
- package/chunks/{chunk-RKPHDO42.js → chunk-LDXZT3SG.js} +5 -5
- package/chunks/{chunk-BGFA2SAQ.js → chunk-LFOZ6AIH.js} +1 -1
- package/chunks/{chunk-4322TZID.js → chunk-LGQHT42X.js} +2 -2
- package/chunks/{chunk-PDXZ2CUO.js → chunk-M3O2XDHA.js} +1 -1
- package/chunks/{chunk-47K2NMP6.js → chunk-M3UC46LS.js} +1 -1
- package/chunks/{chunk-UFRY7WND.js → chunk-M7JLPTQI.js} +1 -1
- package/chunks/{chunk-SATEKHQP.js → chunk-MBUXP3IS.js} +1 -1
- package/chunks/{chunk-RN6JS263.js → chunk-MEZA3VVH.js} +1 -1
- package/chunks/{chunk-OBFKP7RI.js → chunk-MWN6TR36.js} +1 -1
- package/chunks/{chunk-VHJ43ZYJ.js → chunk-O7XRQWCG.js} +1 -1
- package/chunks/{chunk-H224LNV3.js → chunk-OYFRLT5E.js} +1 -1
- package/chunks/{chunk-3NWFV2YF.js → chunk-PMBGV76N.js} +1 -1
- package/chunks/{chunk-YFAPACDE.js → chunk-PVM4IVFL.js} +6 -6
- package/chunks/{chunk-7WS2EYMQ.js → chunk-PWHD4NK3.js} +1 -1
- package/chunks/{chunk-JZIQSEFO.js → chunk-Q54NROBX.js} +1 -1
- package/chunks/{chunk-FCLAPJ22.js → chunk-QE7R4DPT.js} +1 -1
- package/chunks/{chunk-J6TW7GNF.js → chunk-QIUTQICH.js} +1 -1
- package/chunks/{chunk-TWDCN5H2.js → chunk-QK63EULE.js} +1 -1
- package/chunks/{chunk-HZZT75LI.js → chunk-QTAC4W7J.js} +1 -1
- package/chunks/{chunk-P7DIAJNX.js → chunk-R7HBR4QQ.js} +1 -1
- package/chunks/{chunk-U2FJSKS3.js → chunk-RHEMFKMX.js} +1 -1
- package/chunks/{chunk-TRRY3QMM.js → chunk-RL57IU47.js} +1 -1
- package/chunks/{chunk-SPWDYRDH.js → chunk-S2OOQRLJ.js} +1 -1
- package/chunks/{chunk-QBRADQ7L.js → chunk-SWTMWNTZ.js} +1 -1
- package/chunks/{chunk-AZUDF52L.js → chunk-SXTKQHFZ.js} +1 -1
- package/chunks/{chunk-5RQRSPPD.js → chunk-T5S3MJIK.js} +1 -1
- package/chunks/{chunk-I3ORWQ2U.js → chunk-UDGDEIBB.js} +1 -1
- package/chunks/{chunk-EMDEBV33.js → chunk-UIFBF3E7.js} +1 -1
- package/chunks/{chunk-BGEMWNES.js → chunk-UQDPWI7D.js} +1 -1
- package/chunks/{chunk-I5LKOTZT.js → chunk-VON4MVIM.js} +1 -1
- package/chunks/{chunk-HJPO6MEW.js → chunk-W5D2T2JK.js} +1 -1
- package/chunks/{chunk-F6YYDRMH.js → chunk-WNGYYU67.js} +1 -1
- package/chunks/{chunk-S2GKUZZZ.js → chunk-WO3F62ZD.js} +1 -1
- package/chunks/{chunk-K7KW3ZJQ.js → chunk-WVY5Q6YY.js} +1 -1
- package/chunks/{chunk-GH6DPLWU.js → chunk-Y4Q667BW.js} +1 -1
- package/chunks/{chunk-FH74N7Y7.js → chunk-YJLMFUCS.js} +2 -2
- package/chunks/{chunk-C3Y2S5AM.js → chunk-YKHRCSKP.js} +1 -1
- package/chunks/{chunk-P4UJ7CXJ.js → chunk-YLIS36QA.js} +1 -1
- package/chunks/{chunk-4QIFOIBS.js → chunk-YVZ4XZRB.js} +1 -1
- package/chunks/{chunk-KGRD6G5J.js → chunk-Z27JJPKN.js} +1 -1
- package/chunks/{chunk-KOHHDB2L.js → chunk-ZCIS6MJZ.js} +1 -1
- package/chunks/{chunk-QNNDZYVW.js → chunk-ZHLQ222N.js} +1 -1
- package/chunks/{chunk-KWRZ3WJO.js → chunk-ZP7MTWMR.js} +1 -1
- package/chunks/{codex-subagent-executor-H44VDB5E.js → codex-subagent-executor-6OJVGF2S.js} +1 -1
- package/chunks/{config-utils-4X4SV4RL.js → config-utils-FI3A4QAN.js} +1 -1
- package/chunks/{contextCommand-4KVOHTAJ.js → contextCommand-YEBZQHG4.js} +1 -1
- package/chunks/{core-runtime-4RARI4NX.js → core-runtime-CFMHUAS7.js} +1 -1
- package/chunks/{create-sub-session-CNSRJFYG.js → create-sub-session-G26337FT.js} +1 -1
- package/chunks/{daemon-git-worktree-guard-6XQQPP2H.js → daemon-git-worktree-guard-ITU6NQIV.js} +1 -1
- package/chunks/{daemon-status-provider-PRTEQT5T.js → daemon-status-provider-CSWRGMRX.js} +1 -1
- package/chunks/{daemon-trust-policy-GXKJVZDU.js → daemon-trust-policy-IYD7NOGK.js} +1 -1
- package/chunks/{daemon-trust-policy-monitor-L2ORKHMM.js → daemon-trust-policy-monitor-OWUP5SYB.js} +1 -1
- package/chunks/{deferred-core-runtime-RZQFUSPX.js → deferred-core-runtime-CVCQU7O4.js} +1 -1
- package/chunks/{edit-W44XQCIS.js → edit-7YBQLILC.js} +1 -1
- package/chunks/{enterPlanMode-B456A2XO.js → enterPlanMode-L3PVSD2P.js} +1 -1
- package/chunks/{environment-DSGQSQFS.js → environment-BVEOYQHO.js} +1 -1
- package/chunks/{errors-KL725247.js → errors-VQWBGR6D.js} +1 -1
- package/chunks/{execution-tool-KT3EBWHG.js → execution-tool-P7CBXSGZ.js} +1 -1
- package/chunks/{execution-worker-LPQ4HMN4.js → execution-worker-RZXNYK4B.js} +1 -1
- package/chunks/{exitPlanMode-JLKS76IA.js → exitPlanMode-MBUTM3NW.js} +1 -1
- package/chunks/{fast-path-5UD52IHH.js → fast-path-T2FDUSHV.js} +1 -1
- package/chunks/{glob-LYA2H6X3.js → glob-RH7XXSYE.js} +1 -1
- package/chunks/{goal-tools-SHSIDLZX.js → goal-tools-K6XBCE5E.js} +1 -1
- package/chunks/{handleAutoUpdate-T4RE6CZN.js → handleAutoUpdate-PG7R3KPH.js} +1 -1
- package/chunks/{i18n-5DK327WA.js → i18n-EGTBMA3N.js} +1 -1
- package/chunks/{initializer-TJGE4OJA.js → initializer-RIKH4PCP.js} +1 -1
- package/chunks/{installationInfo-MZ62GDIC.js → installationInfo-BBADHZLD.js} +1 -1
- package/chunks/{interactive-mod-session-YCUBQ6RM.js → interactive-mod-session-7RDKAHZ4.js} +1 -1
- package/chunks/{list-4L3LYDQM.js → list-YEGWEHJX.js} +1 -1
- package/chunks/{llm-3JQWBZXV.js → llm-D3LHPY27.js} +4 -4
- package/chunks/{llm-content-generator-6UPJWPOM.js → llm-content-generator-BLTBMV66.js} +1 -1
- package/chunks/{loadedSettingsAdapter-STPKAFJG.js → loadedSettingsAdapter-PLGMKMFO.js} +1 -1
- package/chunks/{local-execution-environment-IE5BOI7Y.js → local-execution-environment-4LDKFNC4.js} +1 -1
- package/chunks/{loggingContentGenerator-4KKWPZJA.js → loggingContentGenerator-376R7DRI.js} +1 -1
- package/chunks/{manage-memory-CRV5SXZZ.js → manage-memory-2ZTIVKNU.js} +1 -1
- package/chunks/{managed-execution-engine-FHLEWVND.js → managed-execution-engine-5LOM3MXG.js} +1 -1
- package/chunks/{managed-npm-update-BRHPOKDU.js → managed-npm-update-2C5JYEXW.js} +1 -1
- package/chunks/{managed-runtime-attestation-worker-GIQKZ5BH.js → managed-runtime-attestation-worker-R2FECMZK.js} +1 -1
- package/chunks/{managed-runtime-bootstrap-P72BT46H.js → managed-runtime-bootstrap-KPLGH4UE.js} +1 -1
- package/chunks/{managed-runtime-session-worker-IYCJDB5K.js → managed-runtime-session-worker-EVKNPK3V.js} +1 -1
- package/chunks/{managed-runtime-ssh-worker-ONT4V5ZG.js → managed-runtime-ssh-worker-IA4HZ3PD.js} +1 -1
- package/chunks/{mcp-NXCQVE2Y.js → mcp-S67IJLI6.js} +1 -1
- package/chunks/{model-call-collection-3DNL45M5.js → model-call-collection-6OGPDTPG.js} +1 -1
- package/chunks/{model-configuration-6HRNYBWV.js → model-configuration-6RWVBOQS.js} +1 -1
- package/chunks/{modelConfigUtils-SKBN64ZW.js → modelConfigUtils-M3TVVYAO.js} +1 -1
- package/chunks/{monitor-7I7Q73UR.js → monitor-ZHOFTN7N.js} +1 -1
- package/chunks/{nonInteractiveCli-YLYRJUBE.js → nonInteractiveCli-6SUGPTJ4.js} +1 -1
- package/chunks/{nonInteractiveToolExecutor-U2ASWT63.js → nonInteractiveToolExecutor-SAHBGO3A.js} +1 -1
- package/chunks/{notebook-edit-WAD7IQCF.js → notebook-edit-ETUOQH6G.js} +1 -1
- package/chunks/{omni-POUUDVU3.js → omni-HV2UBGMZ.js} +1 -1
- package/chunks/{openaiContentGenerator-L7X6IVPL.js → openaiContentGenerator-RZCG7E4M.js} +1 -1
- package/chunks/{openaiResponsesContentGenerator-7XCMFI6P.js → openaiResponsesContentGenerator-X23L5JV3.js} +1 -1
- package/chunks/{pidfile-MQQT2ZDA.js → pidfile-26WXQCHG.js} +1 -1
- package/chunks/{processUtils-OZLF72NC.js → processUtils-WXLFGNBT.js} +1 -1
- package/chunks/{prompt-terminal-ledger-IYUF6SUU.js → prompt-terminal-ledger-EIZZHF4A.js} +1 -1
- package/chunks/{qwenContentGenerator-DKH3ILUO.js → qwenContentGenerator-GOY7Y6KH.js} +1 -1
- package/chunks/{reactive-degrade-KSNGHMBN.js → reactive-degrade-MNMTTHO5.js} +1 -1
- package/chunks/{read-file-VEELW4OQ.js → read-file-OJNGPNTQ.js} +1 -1
- package/chunks/{resumeHistoryUtils-4SFDTBXU.js → resumeHistoryUtils-QWOWF4VY.js} +1 -1
- package/chunks/{review-QA6HRLVU.js → review-5S24HP2V.js} +1 -1
- package/chunks/{ripGrep-4J6ASSE3.js → ripGrep-Y4PY2MQF.js} +1 -1
- package/chunks/{run-qwen-serve-EJ67LA5O.js → run-qwen-serve-EOUUDZUK.js} +2 -2
- package/chunks/{runtime-6E2FSB5U.js → runtime-ZBPOQX6E.js} +1 -1
- package/chunks/{sandboxConfig-4VE4LNRI.js → sandboxConfig-R7KDS3P5.js} +1 -1
- package/chunks/{scheduled-tasks-GM5EJMK7.js → scheduled-tasks-Q6V7D6K6.js} +1 -1
- package/chunks/{scheduler-HOSVIIOE.js → scheduler-EBQY6BOK.js} +1 -1
- package/chunks/{search-memory-HEAQCHIK.js → search-memory-HX6E23JC.js} +1 -1
- package/chunks/{send-message-FAQ7XEZ5.js → send-message-OZCCCH2F.js} +1 -1
- package/chunks/{serve-VNKPOWSW.js → serve-CMGCI4BK.js} +1 -1
- package/chunks/{server-U2XBJLOV.js → server-7LOAKPDN.js} +3 -3
- package/chunks/{session-AZGROSFX.js → session-LVQYZSJE.js} +1 -1
- package/chunks/{session-attachments-root-6M2ECUNK.js → session-attachments-root-NWG7JOMN.js} +1 -1
- package/chunks/{session-execution-engine-selector-PYDVOSJF.js → session-execution-engine-selector-PHH47ZMA.js} +1 -1
- package/chunks/{session-pr-refresh-3IS7DLEV.js → session-pr-refresh-5IACZPCY.js} +1 -1
- package/chunks/{sessionService-3FWNA4ZB.js → sessionService-7PFAWLHC.js} +1 -1
- package/chunks/{settings-VHKT7JJC.js → settings-CPZBOHN5.js} +1 -1
- package/chunks/{shell-TYOPVB7H.js → shell-A7NLPS2W.js} +1 -1
- package/chunks/{skill-GJQIE5AX.js → skill-VGANGVOD.js} +1 -1
- package/chunks/{skill-settings-76NI6SF3.js → skill-settings-TSZO3X6N.js} +1 -1
- package/chunks/{spawnChannel-FMSYLDKB.js → spawnChannel-2JQYNQKT.js} +1 -1
- package/chunks/{standalone-update-BPZQDQHD.js → standalone-update-QXC3RM6I.js} +1 -1
- package/chunks/{start-opentui-ui-X7XYV5N3.js → start-opentui-ui-BKJ4JHVK.js} +1 -1
- package/chunks/{startInteractiveUI-UZDF4JUB.js → startInteractiveUI-4QIPR7ZY.js} +1 -1
- package/chunks/{team-create-RFZNEF76.js → team-create-5MU6BGXX.js} +1 -1
- package/chunks/{team-plan-approval-MGW3JGSC.js → team-plan-approval-NZUJ6FSA.js} +1 -1
- package/chunks/{terminal-image-renderer-3UED5GZV.js → terminal-image-renderer-CTMJULJ2.js} +1 -1
- package/chunks/{theme-manager-SF6FSSZW.js → theme-manager-6H7GA6QR.js} +1 -1
- package/chunks/{tool-call-W2CJR74U.js → tool-call-XG4CAD5X.js} +1 -1
- package/chunks/{tool-result-media-XSFON2ZQ.js → tool-result-media-RJ5ONO7R.js} +1 -1
- package/chunks/{tool-search-7GY5YTOU.js → tool-search-KBINGEWV.js} +1 -1
- package/chunks/{total-session-admission-OATGW6M5.js → total-session-admission-XNWYCO7G.js} +1 -1
- package/chunks/{trustedFolders-AM4PSGUB.js → trustedFolders-JT5MOB3A.js} +1 -1
- package/chunks/{update-relaunch-YKY52XUT.js → update-relaunch-HXMQI3HO.js} +1 -1
- package/chunks/{updateCheck-RKQ5CPZM.js → updateCheck-XWE3TWL5.js} +1 -1
- package/chunks/{upload-config-CBT7ARZY.js → upload-config-ET7NRHU7.js} +1 -1
- package/chunks/{useAutoAcceptIndicator-Z3YWPUNO.js → useAutoAcceptIndicator-TPMYKNJX.js} +1 -1
- package/chunks/{validateNonInterActiveAuth-7CQHU2RF.js → validateNonInterActiveAuth-U52KMEDS.js} +1 -1
- package/chunks/{version-N2OB6KWP.js → version-CW4RTJ3H.js} +1 -1
- package/chunks/{web-fetch-L5XCBCBA.js → web-fetch-UPMJ3XIZ.js} +1 -1
- package/chunks/{web-search-4EHUA3LJ.js → web-search-PXABWQVC.js} +1 -1
- package/chunks/{workflow-FGAUAYIP.js → workflow-UQ4V3NBZ.js} +1 -1
- package/chunks/{workflow-ancestor-trust-F7RRN6I3.js → workflow-ancestor-trust-QII5KTUJ.js} +1 -1
- package/chunks/{workspace-agents-QW4TKC52.js → workspace-agents-Q3KKMDX2.js} +1 -1
- package/chunks/{workspace-providers-status-MFSZT3YA.js → workspace-providers-status-3ASB64FB.js} +1 -1
- package/chunks/{workspace-registration-store-WQRDSIEI.js → workspace-registration-store-2NPD6U3B.js} +1 -1
- package/chunks/{workspace-registry-FXZFRSCH.js → workspace-registry-6QJKRCDR.js} +1 -1
- package/chunks/{workspace-runtime-coordinator-LJ5YAT3A.js → workspace-runtime-coordinator-ZXUWDQIB.js} +1 -1
- package/chunks/{workspace-service-U632SUWU.js → workspace-service-YPYTYYUN.js} +1 -1
- package/chunks/{workspace-skills-status-M7YXM3LF.js → workspace-skills-status-VTFHQ6R7.js} +1 -1
- package/chunks/{workspace-trust-reconciler-NLJGGI4K.js → workspace-trust-reconciler-52CZVPKH.js} +1 -1
- package/chunks/{write-file-BJCKSXX7.js → write-file-FDBR76G5.js} +1 -1
- package/chunks/{zoom-image-TLJPD4DB.js → zoom-image-MYKWCCXO.js} +1 -1
- package/cli.js +2 -2
- package/execution-worker.js +1 -1
- package/export-transcript-document.js +1 -1
- package/package.json +4 -4
- package/vendor/landlock-run/arm64-linux/qwen-landlock-run +0 -0
- package/vendor/landlock-run/x64-linux/qwen-landlock-run +0 -0
- package/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/vendor/ripgrep/arm64-linux/rg +0 -0
- package/vendor/ripgrep/x64-darwin/rg +0 -0
- package/vendor/ripgrep/x64-linux/rg +0 -0
- package/vendor/tree-sitter/tree-sitter-bash.wasm +0 -0
- package/vendor/tree-sitter/tree-sitter.wasm +0 -0
- package/web-shell/assets/{PierreFilePreview-D9tbdFw8.js → PierreFilePreview-DGTp45Z4.js} +1 -1
- package/web-shell/assets/{SpreadsheetPreview-CeFAk2s-.js → SpreadsheetPreview-DVC_YVei.js} +1 -1
- package/web-shell/assets/{WorkspaceFileBrowser-iaURw8SR.js → WorkspaceFileBrowser-DaQNpS06.js} +1 -1
- package/web-shell/assets/{abnfDiagram-VCTEODGH-Z4CT1NCF.js → abnfDiagram-VCTEODGH-wJbiOoPK.js} +1 -1
- package/web-shell/assets/{agents-route-B7o2Rq-a.js → agents-route-DUhhA1KI.js} +1 -1
- package/web-shell/assets/{arc-DcHBdUJQ.js → arc-CvpNMy1d.js} +1 -1
- package/web-shell/assets/{architectureDiagram-5GKGNRK7-DRDhEC81.js → architectureDiagram-5GKGNRK7-DIhi3dIz.js} +1 -1
- package/web-shell/assets/{blockDiagram-NRAW4CY4-CYRE6WIc.js → blockDiagram-NRAW4CY4-CoeyTlVJ.js} +1 -1
- package/web-shell/assets/{c4Diagram-UCG6FXSJ-CIM8N_Sj.js → c4Diagram-UCG6FXSJ-BYoK_I9M.js} +1 -1
- package/web-shell/assets/channel-DvtGOCg6.js +1 -0
- package/web-shell/assets/{chunk-2Q5K7J3B-Bbfka9Fe.js → chunk-2Q5K7J3B-BeD4GwPg.js} +1 -1
- package/web-shell/assets/{chunk-5VM5RSS4-C02zF3RY.js → chunk-5VM5RSS4-BpkJsB_y.js} +1 -1
- package/web-shell/assets/{chunk-F27PBJKO-Dn0wRD2F.js → chunk-F27PBJKO-BROEWQ1J.js} +1 -1
- package/web-shell/assets/{chunk-G27WJ6UU-Dwpl3l0W.js → chunk-G27WJ6UU-DA8Wtppt.js} +1 -1
- package/web-shell/assets/{chunk-JWPE2WC7-sQbzSoTR.js → chunk-JWPE2WC7-GqB-QFh5.js} +1 -1
- package/web-shell/assets/{chunk-LCL6LL3I-DNlNDtfr.js → chunk-LCL6LL3I-DIPUwYsX.js} +1 -1
- package/web-shell/assets/{chunk-POPQ4Y6H-BOgf1Dl3.js → chunk-POPQ4Y6H-DbnU-jxX.js} +1 -1
- package/web-shell/assets/{chunk-SVP7TREG-DOofWP00.js → chunk-SVP7TREG-DvH7bQ-w.js} +1 -1
- package/web-shell/assets/{chunk-XXDRQBXY-Bj9FxhWU.js → chunk-XXDRQBXY-DdVWVo3U.js} +1 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-9NR5W1rE.js +1 -0
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-9NR5W1rE.js +1 -0
- package/web-shell/assets/{cose-bilkent-JH36ORCC-CUlPjyww.js → cose-bilkent-JH36ORCC-JgMKxP9H.js} +1 -1
- package/web-shell/assets/{cynefin-OW5HDTMX-5noArzI7.js → cynefin-OW5HDTMX-BVUpNgVm.js} +1 -1
- package/web-shell/assets/{cynefinDiagram-5FMLGOSQ-DELvTqmf.js → cynefinDiagram-5FMLGOSQ-CxAdk-iS.js} +1 -1
- package/web-shell/assets/{dagre-3AP2YEHR-CAL6Z3hL.js → dagre-3AP2YEHR-CvXWkM86.js} +1 -1
- package/web-shell/assets/{diagram-S7CK7UJ4-DQC2gaIi.js → diagram-S7CK7UJ4-DD_PS4nm.js} +1 -1
- package/web-shell/assets/{diagram-UQ7AKVKN-CkU6M-3R.js → diagram-UQ7AKVKN-EVZkTODD.js} +1 -1
- package/web-shell/assets/{diagram-VSXAHHWV-CvHpHwVx.js → diagram-VSXAHHWV-CGZc1pZU.js} +1 -1
- package/web-shell/assets/{diagram-VX7I27RA-D9l5F9iB.js → diagram-VX7I27RA-DjNql499.js} +1 -1
- package/web-shell/assets/{diagram-Z3DM3KII-DW-VFvYx.js → diagram-Z3DM3KII-CCa0WtmR.js} +1 -1
- package/web-shell/assets/{docx-preview-8MQfOGQh.js → docx-preview-DpVElxvj.js} +1 -1
- package/web-shell/assets/{ebnfDiagram-PWID7BFC-C0Q71wC_.js → ebnfDiagram-PWID7BFC-W2hoOJZF.js} +1 -1
- package/web-shell/assets/{erDiagram-SSCWMZ5O-DWDLRh1S.js → erDiagram-SSCWMZ5O-Dz5NxxEb.js} +1 -1
- package/web-shell/assets/{flowDiagram-A5DVABFB-CVzJnl1P.js → flowDiagram-A5DVABFB-BTMAn8b5.js} +1 -1
- package/web-shell/assets/{ganttDiagram-EL5Y4UJY-B320pcgR.js → ganttDiagram-EL5Y4UJY-BaFrd5ZY.js} +1 -1
- package/web-shell/assets/{gitGraphDiagram-WWUBYQGX-Di4uZh-J.js → gitGraphDiagram-WWUBYQGX-IlmdUqRk.js} +1 -1
- package/web-shell/assets/{index-Csr8Hx_O.js → index-C2ez0ZjE.js} +1 -1
- package/web-shell/assets/{index-C9BecA_H.js → index-Cs-XBNmB.js} +101 -101
- package/web-shell/assets/{infoDiagram-RXCK75RN-CbafhxET.js → infoDiagram-RXCK75RN-BHs9kpar.js} +1 -1
- package/web-shell/assets/{ishikawaDiagram-5VMMS53U-DrQuIDeR.js → ishikawaDiagram-5VMMS53U-DWCEQ85v.js} +1 -1
- package/web-shell/assets/{journeyDiagram-EYS64GPL-BschmjBj.js → journeyDiagram-EYS64GPL-RTDAw9yc.js} +1 -1
- package/web-shell/assets/{kanban-definition-3QL26DDD-B7x9BU9N.js → kanban-definition-3QL26DDD-B7Nl9bq6.js} +1 -1
- package/web-shell/assets/{layout-BewPaOyO.js → layout-BabjFEb1.js} +1 -1
- package/web-shell/assets/{linear-CnLILCVp.js → linear-CZuGjuQd.js} +1 -1
- package/web-shell/assets/{mermaid.core-Csj9KPfJ.js → mermaid.core-CK78bIGt.js} +6 -6
- package/web-shell/assets/{mindmap-definition-FBJOCRG2-CIGTi5gg.js → mindmap-definition-FBJOCRG2-BbcCi_jP.js} +1 -1
- package/web-shell/assets/{pegDiagram-XKGWAZYB-CuWBRQzb.js → pegDiagram-XKGWAZYB-DpLQ7u8i.js} +1 -1
- package/web-shell/assets/{pieDiagram-E7YTZNPT-Co5ukXCE.js → pieDiagram-E7YTZNPT-BpWFVtM0.js} +1 -1
- package/web-shell/assets/{quadrantDiagram-AXDQQJYC-B0hzjh6o.js → quadrantDiagram-AXDQQJYC-CGzYlaN1.js} +1 -1
- package/web-shell/assets/{railroadDiagram-O6MQD6OU-nhkJB0xD.js → railroadDiagram-O6MQD6OU-BNQYW-Zi.js} +1 -1
- package/web-shell/assets/{requirementDiagram-EFPCY7ZU-C7NpxjVR.js → requirementDiagram-EFPCY7ZU-C4fCdIDW.js} +1 -1
- package/web-shell/assets/{sankeyDiagram-P5KCCOFB-CUWlnhZC.js → sankeyDiagram-P5KCCOFB-BvbbAnMA.js} +1 -1
- package/web-shell/assets/{sequenceDiagram-WJ2MYXX4-BoykH0_J.js → sequenceDiagram-WJ2MYXX4-DGXNc6E1.js} +1 -1
- package/web-shell/assets/{sizeCapture-X5ZJPWSS-aF-PkSe5.js → sizeCapture-X5ZJPWSS-C4W45Xf5.js} +1 -1
- package/web-shell/assets/{stateDiagram-HBIQ2CUA-g5q0b922.js → stateDiagram-HBIQ2CUA-D3q0fen-.js} +1 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-XKoYIi05.js +1 -0
- package/web-shell/assets/{swimlanes-XN3QIQJK-BbASszfe.js → swimlanes-XN3QIQJK-D8n-ResR.js} +1 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-C7qJMSzs.js +8 -0
- package/web-shell/assets/{timeline-definition-24CTP7MA-AXIV0TJJ.js → timeline-definition-24CTP7MA-Cio4y1mM.js} +1 -1
- package/web-shell/assets/{vennDiagram-4TSXK5OY-B-E0rj1h.js → vennDiagram-4TSXK5OY-DVlg0xnc.js} +1 -1
- package/web-shell/assets/{wardleyDiagram-VM6X3IG4-DiOOYJ2D.js → wardleyDiagram-VM6X3IG4-CgeIsimQ.js} +1 -1
- package/web-shell/assets/{xychartDiagram-S5SC5T6Z-De_z7HkS.js → xychartDiagram-S5SC5T6Z-UXjyTLnU.js} +1 -1
- package/web-shell/index.html +1 -1
- package/web-shell/sw.js +1 -1
- package/web-shell/assets/channel-Bwr9aS_E.js +0 -1
- package/web-shell/assets/classDiagram-DTDB5LWJ-BmY8Mmyo.js +0 -1
- package/web-shell/assets/classDiagram-v2-JRS7N3AN-BmY8Mmyo.js +0 -1
- package/web-shell/assets/stateDiagram-v2-4QOOHH4V-CTOjUMow.js +0 -1
- package/web-shell/assets/swimlanesDiagram-VK2B7HYN-Bz6ia3oL.js +0 -8
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{redactMcpServersSetting,restoreRedactedMcpServersSetting}from"./chunk-44U2VNWI.js";import{safeLogValue}from"./chunk-K246IFIW.js";import{requireTrustedWorkspaceRuntime,resolveWorkspaceRuntimeFromParam,sendGenerationClosedError}from"./chunk-I5LKOTZT.js";import{isServeDebugMode}from"./chunk-CUNEBE5E.js";import{STATUS_SCHEMA_VERSION}from"./chunk-YQ4ID2TH.js";import{loadSettings}from"./chunk-DFRSQK5Q.js";import{BuiltinAgentRegistry,SubagentManager}from"./chunk-RKPHDO42.js";import{APPROVAL_MODES}from"./chunk-JZK2WGXA.js";import{writeStderrLine}from"./chunk-SLPJ4OII.js";import{SubagentError,SubagentErrorCode}from"./chunk-65UCR6OZ.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import{promises as fs}from"node:fs";import{isDeepStrictEqual}from"node:util";var AGENT_TYPE_PATTERN=/^[\p{L}\p{N}_-]+$/u;var AGENT_TYPE_MAX_LENGTH=64;var AGENT_TYPE_MIN_LENGTH=2;var MAX_DESCRIPTION_BYTES=256*1024;var MAX_SYSTEM_PROMPT_BYTES=256*1024;var MAX_TOOLS_ENTRIES=256;var MAX_TOOL_ID_LENGTH=256;var MAX_RECORD_ENTRIES=128;var SUBAGENT_APPROVAL_MODES=[...APPROVAL_MODES,"bubble"];var SUBAGENT_PERMISSION_MODES=["acceptEdits","auto","bypassPermissions","default","dontAsk","plan"];var SUBAGENT_COLORS=["auto","red","blue","green","yellow","purple","orange","pink","cyan"];function captureTrustedGeneration(deps,res){const assertGenerationOpen=deps.captureGenerationAssertion?.()??(()=>{});try{assertGenerationOpen()}catch{res.set("Retry-After","1");res.status(503).json({error:"Workspace runtime is not active.",code:"workspace_runtime_unavailable"});return null}if(deps.isWorkspaceTrusted?.()===false){res.status(403).json({error:"Workspace is not trusted.",code:"untrusted_workspace"});return null}return assertGenerationOpen}__name(captureTrustedGeneration,"captureTrustedGeneration");function mountWorkspaceAgentsRoutes(app,deps){const manager=createDaemonSubagentManager(deps.boundWorkspace);app.get("/workspace/agents",async(_req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;try{const agents=await manager.listSubagents({force:true});assertGenerationOpen();const status={v:STATUS_SCHEMA_VERSION,workspaceCwd:deps.boundWorkspace,agents:agents.map(toSummary)};res.status(200).json(status)}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to list workspace agents",code:"agent_list_failed"})}});app.post("/workspace/agents",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const body=deps.safeBody(req);const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const scope=body["scope"];if(scope!=="workspace"&&scope!=="global"){res.status(400).json({error:'`scope` must be "workspace" or "global"',code:"invalid_scope"});return}const level=scope==="workspace"?"project":"user";const config=parseAgentConfig(restoreAgentMcpServerSecrets(body,deps.boundWorkspace,level),level,res);if(!config)return;const collision=await manager.loadSubagent(config.name,level);if(collision){res.status(409).json({error:`Subagent "${config.name}" already exists at ${level} level`,code:"agent_already_exists",name:config.name,level});return}try{assertGenerationOpen();await manager.createSubagent(config,{level,assertCanCommit:assertGenerationOpen});assertGenerationOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.ALREADY_EXISTS){res.status(409).json({error:err.message,code:"agent_already_exists",name:err.subagentName??config.name});return}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_CONFIG||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??config.name});return}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??config.name});return}}writeStderrLine(`qwen serve: POST /workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to create workspace agent",code:"agent_create_failed"});return}const created=await manager.loadSubagent(config.name,level);try{assertGenerationOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!created){writeStderrLine(`qwen serve: agent_create_reload_failed (name=${safeLogValue(config.name)} level=${level}) \u2014 file likely persisted on disk; check \`GET /workspace/agents\` for a phantom entry`);res.status(500).json({error:"Agent creation succeeded but reload failed",code:"agent_create_reload_failed",name:config.name,level});return}deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:config.name,level},...originatorClientId?{originatorClientId}:{}});res.status(201).json({ok:true,agent:toDetail(created)})});app.post("/workspace/agents/generate",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const body=deps.safeBody(req);const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const description=body["description"];if(typeof description!=="string"||description.trim().length===0){res.status(400).json({error:"`description` must be a non-empty string",code:"invalid_description"});return}if(Buffer.byteLength(description,"utf8")>4096){res.status(400).json({error:"`description` exceeds the 4096-byte limit",code:"invalid_description"});return}try{const generated=await deps.bridge.generateWorkspaceAgent(description.trim(),originatorClientId);assertGenerationOpen();res.status(200).json(generated)}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST /workspace/agents/generate failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to generate workspace agent",code:"agent_generate_failed"})}});app.get("/workspace/agents/:agentType",async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const agentType=validateAgentType(req,res);if(agentType===null)return;try{const scopedLevel=parseScopeQuery(req,res);if(scopedLevel===null)return;const config=await manager.loadSubagent(agentType,scopedLevel);assertGenerationOpen();if(!config){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}res.status(200).json(toDetail(config))}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to read workspace agent",code:"agent_read_failed"})}});app.post("/workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const preferredLevel=parseScopeQuery(req,res);if(preferredLevel===null)return;const existing=await manager.loadSubagent(agentType,preferredLevel);if(!existing){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}if(assertMutableLevel(existing,agentType,res)){return}const body=restoreAgentMcpServerSecrets(deps.safeBody(req),deps.boundWorkspace,existing.level,existing.mcpServers);const updates=parseAgentUpdates(body,res);if(!updates)return;if(Object.keys(updates).length===0){res.status(400).json({error:"`POST /workspace/agents/:agentType` requires at least one updatable field in the body",code:"invalid_config",name:agentType});return}if(isNoOpUpdate(existing,updates)){res.status(200).json({ok:true,agent:toDetail(existing),changed:false});return}try{assertGenerationOpen();await manager.updateSubagent(agentType,updates,existing.level,{assertCanCommit:assertGenerationOpen});assertGenerationOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??agentType});return}}writeStderrLine(`qwen serve: POST /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to update workspace agent",code:"agent_update_failed"});return}const updated=await manager.loadSubagent(agentType,existing.level);try{assertGenerationOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!updated){writeStderrLine(`qwen serve: agent_update_reload_failed (name=${safeLogValue(agentType)} level=${existing.level}) \u2014 disk write completed; check \`GET /workspace/agents/${safeLogValue(agentType)}\` for the new state`);res.status(500).json({error:"Agent update succeeded but reload failed",code:"agent_update_reload_failed",name:agentType,level:existing.level});return}const eventLevel=existing.level==="project"?"project":"user";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:existing.name,level:eventLevel},...originatorClientId?{originatorClientId}:{}});res.status(200).json({ok:true,agent:toDetail(updated),changed:true})});app.delete("/workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const scopedLevel=parseScopeQuery(req,res);if(scopedLevel===null)return;const levelsToCheck=scopedLevel?[scopedLevel]:["project","user"];const existingAtLevels=[];for(const lvl of levelsToCheck){const found=await manager.loadSubagent(agentType,lvl);if(found)existingAtLevels.push(found)}for(const found of existingAtLevels){if(assertMutableLevel(found,agentType,res))return}try{assertGenerationOpen();await manager.deleteSubagent(agentType,scopedLevel,void 0,{assertCanCommit:assertGenerationOpen});assertGenerationOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return}}writeStderrLine(`qwen serve: DELETE /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to delete workspace agent",code:"agent_delete_failed"});return}const removed=[];const remaining=[];for(const found of existingAtLevels){if(!found.filePath){removed.push(found);continue}try{await fs.access(found.filePath);remaining.push(found)}catch{removed.push(found)}}try{assertGenerationOpen()}catch(err){sendGenerationClosedError(res,err);return}if(remaining.length>0){writeStderrLine(`qwen serve: DELETE /workspace/agents/${safeLogValue(agentType)} partial \u2014 removed=${removed.map(r=>r.level).join(",")||"none"} remaining=${remaining.map(r=>`${r.level}:${r.filePath}`).join(",")}`);for(const found of removed){const evtLevel=found.level==="project"?"project":"user";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:found.name,level:evtLevel},...originatorClientId?{originatorClientId}:{}})}res.status(500).json({error:`Failed to delete every level of subagent "${agentType}" \u2014 ${remaining.length} level(s) still have their file on disk`,code:"agent_delete_partial",name:agentType,removedLevels:removed.map(r=>r.level),remainingLevels:remaining.map(r=>r.level)});return}if(existingAtLevels.length===0){const fallbackLevel=scopedLevel==="user"?"user":"project";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:agentType,level:fallbackLevel},...originatorClientId?{originatorClientId}:{}})}else{for(const found of removed){const evtLevel=found.level==="project"?"project":"user";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:found.name,level:evtLevel},...originatorClientId?{originatorClientId}:{}})}}res.status(204).end()})}__name(mountWorkspaceAgentsRoutes,"mountWorkspaceAgentsRoutes");function mountWorkspaceQualifiedAgentsRoutes(app,deps){app.get("/workspaces/:workspace/agents",async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const manager=createDaemonSubagentManager(runtime.workspaceCwd);try{const agents=await manager.listSubagents({force:true});runtime.generationGuard?.assertOpen();const status={v:STATUS_SCHEMA_VERSION,workspaceCwd:runtime.workspaceCwd,agents:agents.filter(agent=>agent.level==="project").map(toSummary)};res.status(200).json(status)}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspaces/:workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to list workspace agents",code:"agent_list_failed"})}});app.post("/workspaces/:workspace/agents",deps.mutate({strict:true}),async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const routeDeps=workspaceAgentDepsForRuntime(runtime,deps);const body=deps.safeBody(req);const clientIdResult=resolveOriginatorClientId(routeDeps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const level=parseWorkspaceOnlyAgentBodyScope(body,res);if(level===null)return;const manager=createDaemonSubagentManager(runtime.workspaceCwd);const config=parseAgentConfig(restoreAgentMcpServerSecrets(body,runtime.workspaceCwd,level),level,res);if(!config)return;const collision=await manager.loadSubagent(config.name,level);if(collision){res.status(409).json({error:`Subagent "${config.name}" already exists at ${level} level`,code:"agent_already_exists",name:config.name,level});return}try{runtime.generationGuard?.assertOpen();await manager.createSubagent(config,{level,assertCanCommit:__name(()=>runtime.generationGuard?.assertOpen(),"assertCanCommit")});runtime.generationGuard?.assertOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(sendCreateAgentError(res,err,config.name))return;writeStderrLine(`qwen serve: POST /workspaces/:workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to create workspace agent",code:"agent_create_failed"});return}const created=await manager.loadSubagent(config.name,level);try{runtime.generationGuard?.assertOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!created){writeStderrLine(`qwen serve: agent_create_reload_failed (name=${safeLogValue(config.name)} level=${level}) \u2014 file likely persisted on disk; check \`GET /workspaces/:workspace/agents\` for a phantom entry`);res.status(500).json({error:"Agent creation succeeded but reload failed",code:"agent_create_reload_failed",name:config.name,level});return}runtime.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:config.name,level:"project"},...originatorClientId?{originatorClientId}:{}});res.status(201).json({ok:true,agent:toDetail(created)})});app.get("/workspaces/:workspace/agents/:agentType",async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const manager=createDaemonSubagentManager(runtime.workspaceCwd);try{const config=await manager.loadSubagent(agentType,scopedLevel);runtime.generationGuard?.assertOpen();if(!config){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}res.status(200).json(toDetail(config))}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to read workspace agent",code:"agent_read_failed"})}});app.post("/workspaces/:workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const routeDeps=workspaceAgentDepsForRuntime(runtime,deps);const clientIdResult=resolveOriginatorClientId(routeDeps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const manager=createDaemonSubagentManager(runtime.workspaceCwd);const existing=await manager.loadSubagent(agentType,scopedLevel);if(!existing){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}if(assertMutableLevel(existing,agentType,res))return;const body=restoreAgentMcpServerSecrets(deps.safeBody(req),runtime.workspaceCwd,existing.level,existing.mcpServers);const updates=parseAgentUpdates(body,res);if(!updates)return;if(Object.keys(updates).length===0){res.status(400).json({error:"`POST /workspaces/:workspace/agents/:agentType` requires at least one updatable field in the body",code:"invalid_config",name:agentType});return}if(isNoOpUpdate(existing,updates)){res.status(200).json({ok:true,agent:toDetail(existing),changed:false});return}try{runtime.generationGuard?.assertOpen();await manager.updateSubagent(agentType,updates,existing.level,{assertCanCommit:__name(()=>runtime.generationGuard?.assertOpen(),"assertCanCommit")});runtime.generationGuard?.assertOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(sendUpdateAgentError(res,err,agentType))return;writeStderrLine(`qwen serve: POST /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to update workspace agent",code:"agent_update_failed"});return}const updated=await manager.loadSubagent(agentType,existing.level);try{runtime.generationGuard?.assertOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!updated){writeStderrLine(`qwen serve: agent_update_reload_failed (name=${safeLogValue(agentType)} level=${existing.level}) \u2014 disk write completed; check \`GET /workspaces/:workspace/agents/${safeLogValue(agentType)}\` for the new state`);res.status(500).json({error:"Agent update succeeded but reload failed",code:"agent_update_reload_failed",name:agentType,level:existing.level});return}runtime.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:existing.name,level:"project"},...originatorClientId?{originatorClientId}:{}});res.status(200).json({ok:true,agent:toDetail(updated),changed:true})});app.delete("/workspaces/:workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const routeDeps=workspaceAgentDepsForRuntime(runtime,deps);const clientIdResult=resolveOriginatorClientId(routeDeps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const manager=createDaemonSubagentManager(runtime.workspaceCwd);const existing=await manager.loadSubagent(agentType,scopedLevel);if(existing&&assertMutableLevel(existing,agentType,res))return;try{runtime.generationGuard?.assertOpen();await manager.deleteSubagent(agentType,scopedLevel,void 0,{assertCanCommit:__name(()=>runtime.generationGuard?.assertOpen(),"assertCanCommit")});runtime.generationGuard?.assertOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return}}writeStderrLine(`qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to delete workspace agent",code:"agent_delete_failed"});return}if(existing?.filePath){try{await fs.access(existing.filePath);writeStderrLine(`qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} partial \u2014 remaining=${existing.level}:${existing.filePath}`);res.status(500).json({error:`Failed to delete subagent "${agentType}" \u2014 ${existing.level} level still has its file on disk`,code:"agent_delete_partial",name:agentType,removedLevels:[],remainingLevels:[existing.level]});return}catch{}}try{runtime.generationGuard?.assertOpen()}catch(err){sendGenerationClosedError(res,err);return}runtime.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:existing?.name??agentType,level:"project"},...originatorClientId?{originatorClientId}:{}});res.status(204).end()})}__name(mountWorkspaceQualifiedAgentsRoutes,"mountWorkspaceQualifiedAgentsRoutes");function validateAgentType(req,res){const raw=req.params["agentType"];if(!raw||raw.length===0){res.status(400).json({error:"`agentType` path parameter is required",code:"invalid_agent_type"});return null}if(raw.length>AGENT_TYPE_MAX_LENGTH||!AGENT_TYPE_PATTERN.test(raw)){res.status(400).json({error:"`agentType` must contain only letters, numbers, hyphens, or underscores (max 64 chars)",code:"invalid_agent_type",agentType:raw});return null}return raw}__name(validateAgentType,"validateAgentType");function parseScopeQuery(req,res){const raw=req.query["scope"];if(raw===void 0)return void 0;if(typeof raw!=="string"){res.status(400).json({error:'`scope` query must be a single "workspace" or "global" value',code:"invalid_scope"});return null}if(raw!=="workspace"&&raw!=="global"){res.status(400).json({error:'`scope` query must be "workspace" or "global"',code:"invalid_scope"});return null}return raw==="workspace"?"project":"user"}__name(parseScopeQuery,"parseScopeQuery");function assertMutableLevel(found,agentType,res){if(found.isBuiltin||found.level==="builtin"||found.level==="extension"||found.level==="session"){res.status(403).json({error:`Cannot modify ${found.level}-level subagent "${agentType}"`,code:"agent_readonly",name:found.name,level:found.level});return true}return false}__name(assertMutableLevel,"assertMutableLevel");function resolveOriginatorClientId(deps,req,res){const clientId=deps.parseClientId(req,res);if(clientId===null)return null;if(clientId===void 0)return void 0;if(!deps.bridge.knownClientIds().has(clientId)){res.status(400).json({error:`Client id "${clientId}" is not registered for this workspace`,code:"invalid_client_id",clientId});return null}return clientId}__name(resolveOriginatorClientId,"resolveOriginatorClientId");function resolveTrustedWorkspaceAgentRuntime(deps,req,res){const runtime=resolveWorkspaceRuntimeFromParam(deps.workspaceRegistry,req,res);if(!runtime)return void 0;if(!requireTrustedWorkspaceRuntime(runtime,res))return void 0;return runtime}__name(resolveTrustedWorkspaceAgentRuntime,"resolveTrustedWorkspaceAgentRuntime");function workspaceAgentDepsForRuntime(runtime,deps){return{bridge:runtime.bridge,boundWorkspace:runtime.workspaceCwd,mutate:deps.mutate,parseClientId:deps.parseClientId,safeBody:deps.safeBody}}__name(workspaceAgentDepsForRuntime,"workspaceAgentDepsForRuntime");function parseWorkspaceOnlyAgentBodyScope(body,res){const scope=body["scope"];if(scope===void 0||scope==="workspace"||scope==="project"){return"project"}return rejectWorkspaceQualifiedAgentScope(scope,res)}__name(parseWorkspaceOnlyAgentBodyScope,"parseWorkspaceOnlyAgentBodyScope");function parseWorkspaceOnlyAgentScopeQuery(req,res){const raw=req.query["scope"];if(raw===void 0||raw==="workspace"||raw==="project"){return"project"}if(typeof raw!=="string"){res.status(400).json({error:"`scope` query must be a single workspace/project value",code:"invalid_scope"});return null}return rejectWorkspaceQualifiedAgentScope(raw,res)}__name(parseWorkspaceOnlyAgentScopeQuery,"parseWorkspaceOnlyAgentScopeQuery");function rejectWorkspaceQualifiedAgentScope(scope,res){if(scope==="global"||scope==="user"){res.status(400).json({error:"Workspace-qualified agents routes only support workspace/project scope",code:"global_scope_not_supported_for_workspace_route"});return null}res.status(400).json({error:'`scope` must be "workspace" or "project"',code:"invalid_scope"});return null}__name(rejectWorkspaceQualifiedAgentScope,"rejectWorkspaceQualifiedAgentScope");function restoreAgentMcpServerSecrets(body,workspace,level,currentAgentServers){const incoming=body["mcpServers"];if(typeof incoming!=="object"||incoming===null||Array.isArray(incoming)){return body}const settings=loadSettings(workspace);const configuredServers=level==="user"?settings.user.settings.mcpServers??{}:settings.merged.mcpServers??{};return{...body,mcpServers:restoreRedactedMcpServersSetting(incoming,{...configuredServers,...currentAgentServers})}}__name(restoreAgentMcpServerSecrets,"restoreAgentMcpServerSecrets");function sendCreateAgentError(res,err,name){if(!(err instanceof SubagentError))return false;if(err.code===SubagentErrorCode.ALREADY_EXISTS){res.status(409).json({error:err.message,code:"agent_already_exists",name:err.subagentName??name});return true}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_CONFIG||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??name});return true}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??name});return true}return false}__name(sendCreateAgentError,"sendCreateAgentError");function sendUpdateAgentError(res,err,agentType){if(!(err instanceof SubagentError))return false;if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return true}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return true}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??agentType});return true}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??agentType});return true}return false}__name(sendUpdateAgentError,"sendUpdateAgentError");function parseAgentConfig(body,level,res){if("executionBackend"in body){return sendInvalidConfig(res,"Daemon agents do not support executionBackend.")}const rawName=body["name"];if(typeof rawName!=="string"||rawName.trim().length===0){res.status(422).json({error:"`name` is required and must be a non-empty string",code:"invalid_config"});return void 0}const name=rawName.trim();if(name.length<AGENT_TYPE_MIN_LENGTH||name.length>AGENT_TYPE_MAX_LENGTH||!AGENT_TYPE_PATTERN.test(name)){res.status(422).json({error:`\`name\` must be ${AGENT_TYPE_MIN_LENGTH}-${AGENT_TYPE_MAX_LENGTH} characters of letters, numbers, hyphens, or underscores`,code:"invalid_config",name});return void 0}if(BuiltinAgentRegistry.isBuiltinAgent(name)){res.status(422).json({error:`"${name}" shadows a built-in subagent and cannot be used as a project- or user-level agent name. Choose a different name.`,code:"invalid_config",name});return void 0}const description=body["description"];if(typeof description!=="string"||description.trim().length===0){res.status(422).json({error:"`description` is required and must be a non-empty string",code:"invalid_config"});return void 0}if(Buffer.byteLength(description,"utf8")>MAX_DESCRIPTION_BYTES){res.status(422).json({error:`\`description\` exceeds the ${MAX_DESCRIPTION_BYTES}-byte limit`,code:"invalid_config"});return void 0}const systemPrompt=body["systemPrompt"];if(typeof systemPrompt!=="string"||systemPrompt.trim().length===0){res.status(422).json({error:"`systemPrompt` is required and must be a non-empty string (whitespace only is rejected)",code:"invalid_config"});return void 0}if(Buffer.byteLength(systemPrompt,"utf8")>MAX_SYSTEM_PROMPT_BYTES){res.status(422).json({error:`\`systemPrompt\` exceeds the ${MAX_SYSTEM_PROMPT_BYTES}-byte limit`,code:"invalid_config"});return void 0}const tools=parseStringArray(body["tools"],"tools",res);if(tools===null)return void 0;const disallowedTools=parseStringArray(body["disallowedTools"],"disallowedTools",res);if(disallowedTools===null)return void 0;const config={name,description,systemPrompt,level};if(tools!==void 0)config.tools=tools;if(disallowedTools!==void 0)config.disallowedTools=disallowedTools;if(rejectIfPresentWrongType(body,"model","string",res))return void 0;if(typeof body["model"]==="string"){if(!body["model"].trim()){return sendInvalidConfig(res,"`model` must not be empty when provided")}config.model=body["model"].trim()}if(rejectIfPresentWrongType(body,"color","string",res))return void 0;if(typeof body["color"]==="string"){if(!SUBAGENT_COLORS.includes(body["color"])){return sendInvalidConfig(res,`\`color\` must be one of ${JSON.stringify(SUBAGENT_COLORS)}`)}config.color=body["color"]}if(rejectIfPresentWrongType(body,"approvalMode","string",res)){return void 0}if(typeof body["approvalMode"]==="string"){if(!SUBAGENT_APPROVAL_MODES.includes(body["approvalMode"])){return sendInvalidConfig(res,`\`approvalMode\` must be one of ${JSON.stringify(SUBAGENT_APPROVAL_MODES)}`)}config.approvalMode=body["approvalMode"]}if(rejectIfPresentWrongType(body,"permissionMode","string",res)){return void 0}if(typeof body["permissionMode"]==="string"){if(!SUBAGENT_PERMISSION_MODES.includes(body["permissionMode"])){return sendInvalidConfig(res,`\`permissionMode\` must be one of ${JSON.stringify(SUBAGENT_PERMISSION_MODES)}`)}config.permissionMode=body["permissionMode"]}if("maxTurns"in body){const maxTurns=parseMaxTurns(body["maxTurns"],res);if(maxTurns===null)return void 0;config.maxTurns=maxTurns}if("mcpServers"in body){const mcpServers=parseRecordField(body["mcpServers"],"mcpServers",value=>typeof value==="object"&&value!==null&&!Array.isArray(value),"an object of server names to server configuration objects",res);if(mcpServers===null)return void 0;if(Object.keys(mcpServers).length>0)config.mcpServers=mcpServers}if("hooks"in body){const hooks=parseRecordField(body["hooks"],"hooks",Array.isArray,"an object of hook event names to matcher arrays",res);if(hooks===null)return void 0;if(Object.keys(hooks).length>0)config.hooks=hooks}if(rejectIfPresentWrongType(body,"background","boolean",res)){return void 0}if(typeof body["background"]==="boolean"){config.background=body["background"]}const runConfig=body["runConfig"];if(runConfig!==void 0){const sanitized=sanitizeRunConfig(runConfig,res);if(sanitized===null)return void 0;config.runConfig=sanitized}return config}__name(parseAgentConfig,"parseAgentConfig");function parseAgentUpdates(body,res){if("executionBackend"in body){return sendInvalidConfig(res,"Daemon agents do not support executionBackend.")}const updates={};if("description"in body){const value=body["description"];if(typeof value!=="string"||value.trim().length===0){res.status(422).json({error:"`description` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return void 0}if(Buffer.byteLength(value,"utf8")>MAX_DESCRIPTION_BYTES){res.status(422).json({error:`\`description\` exceeds the ${MAX_DESCRIPTION_BYTES}-byte limit`,code:"invalid_config"});return void 0}updates.description=value}if("systemPrompt"in body){const value=body["systemPrompt"];if(typeof value!=="string"||value.trim().length===0){res.status(422).json({error:"`systemPrompt` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return void 0}if(Buffer.byteLength(value,"utf8")>MAX_SYSTEM_PROMPT_BYTES){res.status(422).json({error:`\`systemPrompt\` exceeds the ${MAX_SYSTEM_PROMPT_BYTES}-byte limit`,code:"invalid_config"});return void 0}updates.systemPrompt=value}if("tools"in body){const tools=parseStringArray(body["tools"],"tools",res);if(tools===null)return void 0;if(tools!==void 0)updates.tools=tools}if("disallowedTools"in body){const disallowedTools=parseStringArray(body["disallowedTools"],"disallowedTools",res);if(disallowedTools===null)return void 0;if(disallowedTools!==void 0){updates.disallowedTools=disallowedTools}}if(body["model"]===null){updates.model=void 0}else if(rejectIfPresentWrongType(body,"model","string",res)){return void 0}else if(typeof body["model"]==="string"){if(!body["model"].trim()){return sendInvalidConfig(res,"`model` must not be empty when provided")}updates.model=body["model"].trim()}if(body["color"]===null){updates.color=void 0}else if(rejectIfPresentWrongType(body,"color","string",res)){return void 0}else if(typeof body["color"]==="string"){if(!SUBAGENT_COLORS.includes(body["color"])){return sendInvalidConfig(res,`\`color\` must be one of ${JSON.stringify(SUBAGENT_COLORS)}`)}updates.color=body["color"]}if(body["approvalMode"]===null){updates.approvalMode=void 0}else if(rejectIfPresentWrongType(body,"approvalMode","string",res)){return void 0}else if(typeof body["approvalMode"]==="string"){if(!SUBAGENT_APPROVAL_MODES.includes(body["approvalMode"])){return sendInvalidConfig(res,`\`approvalMode\` must be one of ${JSON.stringify(SUBAGENT_APPROVAL_MODES)}`)}updates.approvalMode=body["approvalMode"]}if(body["permissionMode"]===null){updates.permissionMode=void 0}else if(rejectIfPresentWrongType(body,"permissionMode","string",res)){return void 0}else if(typeof body["permissionMode"]==="string"){if(!SUBAGENT_PERMISSION_MODES.includes(body["permissionMode"])){return sendInvalidConfig(res,`\`permissionMode\` must be one of ${JSON.stringify(SUBAGENT_PERMISSION_MODES)}`)}updates.permissionMode=body["permissionMode"]}if("maxTurns"in body){if(body["maxTurns"]===null){updates.maxTurns=void 0}else{const maxTurns=parseMaxTurns(body["maxTurns"],res);if(maxTurns===null)return void 0;updates.maxTurns=maxTurns}}if("mcpServers"in body){const mcpServers=parseRecordField(body["mcpServers"],"mcpServers",value=>typeof value==="object"&&value!==null&&!Array.isArray(value),"an object of server names to server configuration objects",res);if(mcpServers===null)return void 0;updates.mcpServers=mcpServers}if("hooks"in body){const hooks=parseRecordField(body["hooks"],"hooks",Array.isArray,"an object of hook event names to matcher arrays",res);if(hooks===null)return void 0;updates.hooks=hooks}if(rejectIfPresentWrongType(body,"background","boolean",res)){return void 0}if(typeof body["background"]==="boolean"){updates.background=body["background"]}if("runConfig"in body){const sanitized=sanitizeRunConfig(body["runConfig"],res);if(sanitized===null)return void 0;updates.runConfig=sanitized}return updates}__name(parseAgentUpdates,"parseAgentUpdates");function parseStringArray(value,field,res){if(value===void 0)return void 0;if(!Array.isArray(value)||value.some(v=>typeof v!=="string")){res.status(422).json({error:`\`${field}\` must be an array of strings when provided`,code:"invalid_config"});return null}if(value.length>MAX_TOOLS_ENTRIES){res.status(422).json({error:`\`${field}\` exceeds the ${MAX_TOOLS_ENTRIES}-entry limit`,code:"invalid_config"});return null}if(value.some(v=>v.length>MAX_TOOL_ID_LENGTH)){res.status(422).json({error:`\`${field}\` entries must be at most ${MAX_TOOL_ID_LENGTH} characters`,code:"invalid_config"});return null}return value}__name(parseStringArray,"parseStringArray");function sendInvalidConfig(res,error){res.status(422).json({error,code:"invalid_config"});return void 0}__name(sendInvalidConfig,"sendInvalidConfig");function parseMaxTurns(value,res){if(typeof value!=="number"||!Number.isFinite(value)||!Number.isInteger(value)||value<=0){sendInvalidConfig(res,"`maxTurns` must be a positive integer");return null}return value}__name(parseMaxTurns,"parseMaxTurns");function parseRecordField(value,field,isValidEntry,expected,res){if(typeof value!=="object"||value===null||Array.isArray(value)){sendInvalidConfig(res,`\`${field}\` must be ${expected}`);return null}const entries=Object.entries(value);if(entries.length>MAX_RECORD_ENTRIES){sendInvalidConfig(res,`\`${field}\` exceeds the ${MAX_RECORD_ENTRIES}-entry limit`);return null}const output={};for(const[key,entry]of entries){if(!key||key.length>MAX_TOOL_ID_LENGTH||key==="__proto__"||key==="constructor"||key==="prototype"||!isValidEntry(entry)){sendInvalidConfig(res,`\`${field}\` must be ${expected}`);return null}output[key]=entry}return output}__name(parseRecordField,"parseRecordField");function rejectIfPresentWrongType(body,key,expected,res){if(!(key in body))return false;if(typeof body[key]===expected)return false;res.status(422).json({error:`\`${key}\` must be a ${expected} when provided`,code:"invalid_config"});return true}__name(rejectIfPresentWrongType,"rejectIfPresentWrongType");function isNoOpUpdate(existing,updates){if(updates.description!==void 0&&updates.description!==existing.description){return false}if(updates.systemPrompt!==void 0&&updates.systemPrompt!==existing.systemPrompt){return false}if(updates.tools!==void 0&&!shallowArrayEqual(updates.tools,existing.tools)){return false}if(updates.disallowedTools!==void 0&&!shallowArrayEqual(updates.disallowedTools,existing.disallowedTools)){return false}if("model"in updates&&updates.model!==existing.model){return false}if("color"in updates&&updates.color!==existing.color){return false}if("approvalMode"in updates&&updates.approvalMode!==existing.approvalMode){return false}if("permissionMode"in updates&&updates.permissionMode!==existing.permissionMode){return false}if("maxTurns"in updates&&updates.maxTurns!==existing.maxTurns){return false}if(updates.mcpServers!==void 0&&!isDeepStrictEqual(normalizedRecord(updates.mcpServers),normalizedRecord(existing.mcpServers))){return false}if(updates.hooks!==void 0&&!isDeepStrictEqual(normalizedRecord(updates.hooks),normalizedRecord(existing.hooks))){return false}if(updates.background!==void 0&&updates.background!==existing.background){return false}if(updates.runConfig!==void 0){const e=existing.runConfig??{};const u=updates.runConfig;if("max_time_minutes"in u){if(u["max_time_minutes"]!==e["max_time_minutes"])return false}if("max_turns"in u){if(u["max_turns"]!==e["max_turns"])return false}}return true}__name(isNoOpUpdate,"isNoOpUpdate");function normalizedRecord(value){if(!value||Object.keys(value).length===0)return void 0;return normalizeRecordValue(value)}__name(normalizedRecord,"normalizedRecord");function normalizeRecordValue(value){if(Array.isArray(value))return value.map(normalizeRecordValue);if(typeof value!=="object"||value===null)return value;return Object.fromEntries(Object.entries(value).filter(([,entry])=>entry!==void 0).map(([key,entry])=>[key,normalizeRecordValue(entry)]))}__name(normalizeRecordValue,"normalizeRecordValue");function shallowArrayEqual(a,b){if(a===b)return true;if(!a||!b)return false;if(a.length!==b.length)return false;for(let i=0;i<a.length;i++)if(a[i]!==b[i])return false;return true}__name(shallowArrayEqual,"shallowArrayEqual");function sanitizeRunConfig(raw,res){if(typeof raw!=="object"||raw===null||Array.isArray(raw)){res.status(422).json({error:"`runConfig` must be an object when provided",code:"invalid_config"});return null}const input=raw;const out={};if("max_time_minutes"in input){const v=input["max_time_minutes"];if(typeof v!=="number"||!Number.isFinite(v)||v<=0){res.status(422).json({error:"`runConfig.max_time_minutes` must be a positive finite number when provided",code:"invalid_config"});return null}out["max_time_minutes"]=v}if("max_turns"in input){const v=input["max_turns"];if(typeof v!=="number"||!Number.isFinite(v)||v<=0||!Number.isInteger(v)){res.status(422).json({error:"`runConfig.max_turns` must be a positive integer when provided",code:"invalid_config"});return null}out["max_turns"]=v}return out}__name(sanitizeRunConfig,"sanitizeRunConfig");function toSummary(config){const summary={kind:"agent",name:config.name,description:config.description,level:config.level,isBuiltin:config.isBuiltin===true||config.level==="builtin",hasTools:Array.isArray(config.tools)&&config.tools.length>0};if(config.tools)summary.tools=[...config.tools];if(config.disallowedTools){summary.disallowedTools=[...config.disallowedTools]}if(config.model)summary.model=config.model;if(config.color)summary.color=config.color;if(config.background!==void 0)summary.background=config.background;if(config.approvalMode)summary.approvalMode=config.approvalMode;if(config.permissionMode)summary.permissionMode=config.permissionMode;if(config.maxTurns!==void 0)summary.maxTurns=config.maxTurns;if(config.mcpServers){summary.mcpServerNames=Object.keys(config.mcpServers)}if(config.hooks)summary.hookEvents=Object.keys(config.hooks);if(config.runConfig){const runConfig={};if(typeof config.runConfig.max_time_minutes==="number"){runConfig.max_time_minutes=config.runConfig.max_time_minutes}if(typeof config.runConfig.max_turns==="number"){runConfig.max_turns=config.runConfig.max_turns}summary.runConfig=runConfig}if(config.extensionName)summary.extensionName=config.extensionName;if(config.filePath)summary.filePath=config.filePath;return summary}__name(toSummary,"toSummary");function toDetail(config){const detail={...toSummary(config),systemPrompt:config.systemPrompt};if(config.mcpServers){detail.mcpServers=redactMcpServersSetting(config.mcpServers)}if(config.hooks)detail.hooks=config.hooks;return detail}__name(toDetail,"toDetail");function createDaemonSubagentManager(boundWorkspace,safeMode=false){const stub={getSdkMode:__name(()=>false,"getSdkMode"),getProjectRoot:__name(()=>boundWorkspace,"getProjectRoot"),getActiveExtensions:__name(()=>[],"getActiveExtensions"),isSafeMode:__name(()=>safeMode,"isSafeMode"),getAgentsSettings:__name(()=>({}),"getAgentsSettings")};const guarded=new Proxy(stub,{get(target,prop){if(prop in target){return target[prop]}if(prop==="then")return void 0;throw new Error(`qwen serve workspace agents: SubagentManager touched Config.${String(prop)} which the daemon stub does not implement. Add it to createDaemonSubagentManager and audit safety.`)},has(target,prop){if(prop in target)return true;if(prop==="then")return false;throw new Error(`qwen serve workspace agents: SubagentManager probed Config.${String(prop)} via 'in' check; the daemon stub does not implement it. Add it to createDaemonSubagentManager and audit safety.`)}});return new SubagentManager(guarded)}__name(createDaemonSubagentManager,"createDaemonSubagentManager");export{mountWorkspaceAgentsRoutes,mountWorkspaceQualifiedAgentsRoutes,toSummary,toDetail,createDaemonSubagentManager};
|
|
3
|
+
import{redactMcpServersSetting,restoreRedactedMcpServersSetting}from"./chunk-44U2VNWI.js";import{safeLogValue}from"./chunk-K246IFIW.js";import{requireTrustedWorkspaceRuntime,resolveWorkspaceRuntimeFromParam,sendGenerationClosedError}from"./chunk-VON4MVIM.js";import{isServeDebugMode}from"./chunk-CUNEBE5E.js";import{STATUS_SCHEMA_VERSION}from"./chunk-YQ4ID2TH.js";import{loadSettings}from"./chunk-FHFBCG6N.js";import{BuiltinAgentRegistry,SubagentManager}from"./chunk-LDXZT3SG.js";import{APPROVAL_MODES}from"./chunk-JZK2WGXA.js";import{writeStderrLine}from"./chunk-SLPJ4OII.js";import{SubagentError,SubagentErrorCode}from"./chunk-65UCR6OZ.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import{promises as fs}from"node:fs";import{isDeepStrictEqual}from"node:util";var AGENT_TYPE_PATTERN=/^[\p{L}\p{N}_-]+$/u;var AGENT_TYPE_MAX_LENGTH=64;var AGENT_TYPE_MIN_LENGTH=2;var MAX_DESCRIPTION_BYTES=256*1024;var MAX_SYSTEM_PROMPT_BYTES=256*1024;var MAX_TOOLS_ENTRIES=256;var MAX_TOOL_ID_LENGTH=256;var MAX_RECORD_ENTRIES=128;var SUBAGENT_APPROVAL_MODES=[...APPROVAL_MODES,"bubble"];var SUBAGENT_PERMISSION_MODES=["acceptEdits","auto","bypassPermissions","default","dontAsk","plan"];var SUBAGENT_COLORS=["auto","red","blue","green","yellow","purple","orange","pink","cyan"];function captureTrustedGeneration(deps,res){const assertGenerationOpen=deps.captureGenerationAssertion?.()??(()=>{});try{assertGenerationOpen()}catch{res.set("Retry-After","1");res.status(503).json({error:"Workspace runtime is not active.",code:"workspace_runtime_unavailable"});return null}if(deps.isWorkspaceTrusted?.()===false){res.status(403).json({error:"Workspace is not trusted.",code:"untrusted_workspace"});return null}return assertGenerationOpen}__name(captureTrustedGeneration,"captureTrustedGeneration");function mountWorkspaceAgentsRoutes(app,deps){const manager=createDaemonSubagentManager(deps.boundWorkspace);app.get("/workspace/agents",async(_req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;try{const agents=await manager.listSubagents({force:true});assertGenerationOpen();const status={v:STATUS_SCHEMA_VERSION,workspaceCwd:deps.boundWorkspace,agents:agents.map(toSummary)};res.status(200).json(status)}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to list workspace agents",code:"agent_list_failed"})}});app.post("/workspace/agents",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const body=deps.safeBody(req);const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const scope=body["scope"];if(scope!=="workspace"&&scope!=="global"){res.status(400).json({error:'`scope` must be "workspace" or "global"',code:"invalid_scope"});return}const level=scope==="workspace"?"project":"user";const config=parseAgentConfig(restoreAgentMcpServerSecrets(body,deps.boundWorkspace,level),level,res);if(!config)return;const collision=await manager.loadSubagent(config.name,level);if(collision){res.status(409).json({error:`Subagent "${config.name}" already exists at ${level} level`,code:"agent_already_exists",name:config.name,level});return}try{assertGenerationOpen();await manager.createSubagent(config,{level,assertCanCommit:assertGenerationOpen});assertGenerationOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.ALREADY_EXISTS){res.status(409).json({error:err.message,code:"agent_already_exists",name:err.subagentName??config.name});return}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_CONFIG||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??config.name});return}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??config.name});return}}writeStderrLine(`qwen serve: POST /workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to create workspace agent",code:"agent_create_failed"});return}const created=await manager.loadSubagent(config.name,level);try{assertGenerationOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!created){writeStderrLine(`qwen serve: agent_create_reload_failed (name=${safeLogValue(config.name)} level=${level}) \u2014 file likely persisted on disk; check \`GET /workspace/agents\` for a phantom entry`);res.status(500).json({error:"Agent creation succeeded but reload failed",code:"agent_create_reload_failed",name:config.name,level});return}deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:config.name,level},...originatorClientId?{originatorClientId}:{}});res.status(201).json({ok:true,agent:toDetail(created)})});app.post("/workspace/agents/generate",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const body=deps.safeBody(req);const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const description=body["description"];if(typeof description!=="string"||description.trim().length===0){res.status(400).json({error:"`description` must be a non-empty string",code:"invalid_description"});return}if(Buffer.byteLength(description,"utf8")>4096){res.status(400).json({error:"`description` exceeds the 4096-byte limit",code:"invalid_description"});return}try{const generated=await deps.bridge.generateWorkspaceAgent(description.trim(),originatorClientId);assertGenerationOpen();res.status(200).json(generated)}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: POST /workspace/agents/generate failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to generate workspace agent",code:"agent_generate_failed"})}});app.get("/workspace/agents/:agentType",async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const agentType=validateAgentType(req,res);if(agentType===null)return;try{const scopedLevel=parseScopeQuery(req,res);if(scopedLevel===null)return;const config=await manager.loadSubagent(agentType,scopedLevel);assertGenerationOpen();if(!config){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}res.status(200).json(toDetail(config))}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to read workspace agent",code:"agent_read_failed"})}});app.post("/workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const preferredLevel=parseScopeQuery(req,res);if(preferredLevel===null)return;const existing=await manager.loadSubagent(agentType,preferredLevel);if(!existing){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}if(assertMutableLevel(existing,agentType,res)){return}const body=restoreAgentMcpServerSecrets(deps.safeBody(req),deps.boundWorkspace,existing.level,existing.mcpServers);const updates=parseAgentUpdates(body,res);if(!updates)return;if(Object.keys(updates).length===0){res.status(400).json({error:"`POST /workspace/agents/:agentType` requires at least one updatable field in the body",code:"invalid_config",name:agentType});return}if(isNoOpUpdate(existing,updates)){res.status(200).json({ok:true,agent:toDetail(existing),changed:false});return}try{assertGenerationOpen();await manager.updateSubagent(agentType,updates,existing.level,{assertCanCommit:assertGenerationOpen});assertGenerationOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??agentType});return}}writeStderrLine(`qwen serve: POST /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to update workspace agent",code:"agent_update_failed"});return}const updated=await manager.loadSubagent(agentType,existing.level);try{assertGenerationOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!updated){writeStderrLine(`qwen serve: agent_update_reload_failed (name=${safeLogValue(agentType)} level=${existing.level}) \u2014 disk write completed; check \`GET /workspace/agents/${safeLogValue(agentType)}\` for the new state`);res.status(500).json({error:"Agent update succeeded but reload failed",code:"agent_update_reload_failed",name:agentType,level:existing.level});return}const eventLevel=existing.level==="project"?"project":"user";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:existing.name,level:eventLevel},...originatorClientId?{originatorClientId}:{}});res.status(200).json({ok:true,agent:toDetail(updated),changed:true})});app.delete("/workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const assertGenerationOpen=captureTrustedGeneration(deps,res);if(!assertGenerationOpen)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const clientIdResult=resolveOriginatorClientId(deps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const scopedLevel=parseScopeQuery(req,res);if(scopedLevel===null)return;const levelsToCheck=scopedLevel?[scopedLevel]:["project","user"];const existingAtLevels=[];for(const lvl of levelsToCheck){const found=await manager.loadSubagent(agentType,lvl);if(found)existingAtLevels.push(found)}for(const found of existingAtLevels){if(assertMutableLevel(found,agentType,res))return}try{assertGenerationOpen();await manager.deleteSubagent(agentType,scopedLevel,void 0,{assertCanCommit:assertGenerationOpen});assertGenerationOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return}}writeStderrLine(`qwen serve: DELETE /workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to delete workspace agent",code:"agent_delete_failed"});return}const removed=[];const remaining=[];for(const found of existingAtLevels){if(!found.filePath){removed.push(found);continue}try{await fs.access(found.filePath);remaining.push(found)}catch{removed.push(found)}}try{assertGenerationOpen()}catch(err){sendGenerationClosedError(res,err);return}if(remaining.length>0){writeStderrLine(`qwen serve: DELETE /workspace/agents/${safeLogValue(agentType)} partial \u2014 removed=${removed.map(r=>r.level).join(",")||"none"} remaining=${remaining.map(r=>`${r.level}:${r.filePath}`).join(",")}`);for(const found of removed){const evtLevel=found.level==="project"?"project":"user";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:found.name,level:evtLevel},...originatorClientId?{originatorClientId}:{}})}res.status(500).json({error:`Failed to delete every level of subagent "${agentType}" \u2014 ${remaining.length} level(s) still have their file on disk`,code:"agent_delete_partial",name:agentType,removedLevels:removed.map(r=>r.level),remainingLevels:remaining.map(r=>r.level)});return}if(existingAtLevels.length===0){const fallbackLevel=scopedLevel==="user"?"user":"project";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:agentType,level:fallbackLevel},...originatorClientId?{originatorClientId}:{}})}else{for(const found of removed){const evtLevel=found.level==="project"?"project":"user";deps.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:found.name,level:evtLevel},...originatorClientId?{originatorClientId}:{}})}}res.status(204).end()})}__name(mountWorkspaceAgentsRoutes,"mountWorkspaceAgentsRoutes");function mountWorkspaceQualifiedAgentsRoutes(app,deps){app.get("/workspaces/:workspace/agents",async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const manager=createDaemonSubagentManager(runtime.workspaceCwd);try{const agents=await manager.listSubagents({force:true});runtime.generationGuard?.assertOpen();const status={v:STATUS_SCHEMA_VERSION,workspaceCwd:runtime.workspaceCwd,agents:agents.filter(agent=>agent.level==="project").map(toSummary)};res.status(200).json(status)}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspaces/:workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to list workspace agents",code:"agent_list_failed"})}});app.post("/workspaces/:workspace/agents",deps.mutate({strict:true}),async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const routeDeps=workspaceAgentDepsForRuntime(runtime,deps);const body=deps.safeBody(req);const clientIdResult=resolveOriginatorClientId(routeDeps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const level=parseWorkspaceOnlyAgentBodyScope(body,res);if(level===null)return;const manager=createDaemonSubagentManager(runtime.workspaceCwd);const config=parseAgentConfig(restoreAgentMcpServerSecrets(body,runtime.workspaceCwd,level),level,res);if(!config)return;const collision=await manager.loadSubagent(config.name,level);if(collision){res.status(409).json({error:`Subagent "${config.name}" already exists at ${level} level`,code:"agent_already_exists",name:config.name,level});return}try{runtime.generationGuard?.assertOpen();await manager.createSubagent(config,{level,assertCanCommit:__name(()=>runtime.generationGuard?.assertOpen(),"assertCanCommit")});runtime.generationGuard?.assertOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(sendCreateAgentError(res,err,config.name))return;writeStderrLine(`qwen serve: POST /workspaces/:workspace/agents failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to create workspace agent",code:"agent_create_failed"});return}const created=await manager.loadSubagent(config.name,level);try{runtime.generationGuard?.assertOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!created){writeStderrLine(`qwen serve: agent_create_reload_failed (name=${safeLogValue(config.name)} level=${level}) \u2014 file likely persisted on disk; check \`GET /workspaces/:workspace/agents\` for a phantom entry`);res.status(500).json({error:"Agent creation succeeded but reload failed",code:"agent_create_reload_failed",name:config.name,level});return}runtime.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"created",name:config.name,level:"project"},...originatorClientId?{originatorClientId}:{}});res.status(201).json({ok:true,agent:toDetail(created)})});app.get("/workspaces/:workspace/agents/:agentType",async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const manager=createDaemonSubagentManager(runtime.workspaceCwd);try{const config=await manager.loadSubagent(agentType,scopedLevel);runtime.generationGuard?.assertOpen();if(!config){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}res.status(200).json(toDetail(config))}catch(err){if(sendGenerationClosedError(res,err))return;writeStderrLine(`qwen serve: GET /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to read workspace agent",code:"agent_read_failed"})}});app.post("/workspaces/:workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const routeDeps=workspaceAgentDepsForRuntime(runtime,deps);const clientIdResult=resolveOriginatorClientId(routeDeps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const manager=createDaemonSubagentManager(runtime.workspaceCwd);const existing=await manager.loadSubagent(agentType,scopedLevel);if(!existing){res.status(404).json({error:`Subagent "${agentType}" not found`,code:"agent_not_found",name:agentType});return}if(assertMutableLevel(existing,agentType,res))return;const body=restoreAgentMcpServerSecrets(deps.safeBody(req),runtime.workspaceCwd,existing.level,existing.mcpServers);const updates=parseAgentUpdates(body,res);if(!updates)return;if(Object.keys(updates).length===0){res.status(400).json({error:"`POST /workspaces/:workspace/agents/:agentType` requires at least one updatable field in the body",code:"invalid_config",name:agentType});return}if(isNoOpUpdate(existing,updates)){res.status(200).json({ok:true,agent:toDetail(existing),changed:false});return}try{runtime.generationGuard?.assertOpen();await manager.updateSubagent(agentType,updates,existing.level,{assertCanCommit:__name(()=>runtime.generationGuard?.assertOpen(),"assertCanCommit")});runtime.generationGuard?.assertOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(sendUpdateAgentError(res,err,agentType))return;writeStderrLine(`qwen serve: POST /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to update workspace agent",code:"agent_update_failed"});return}const updated=await manager.loadSubagent(agentType,existing.level);try{runtime.generationGuard?.assertOpen()}catch(err){sendGenerationClosedError(res,err);return}if(!updated){writeStderrLine(`qwen serve: agent_update_reload_failed (name=${safeLogValue(agentType)} level=${existing.level}) \u2014 disk write completed; check \`GET /workspaces/:workspace/agents/${safeLogValue(agentType)}\` for the new state`);res.status(500).json({error:"Agent update succeeded but reload failed",code:"agent_update_reload_failed",name:agentType,level:existing.level});return}runtime.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"updated",name:existing.name,level:"project"},...originatorClientId?{originatorClientId}:{}});res.status(200).json({ok:true,agent:toDetail(updated),changed:true})});app.delete("/workspaces/:workspace/agents/:agentType",deps.mutate({strict:true}),async(req,res)=>{const runtime=resolveTrustedWorkspaceAgentRuntime(deps,req,res);if(!runtime)return;const agentType=validateAgentType(req,res);if(agentType===null)return;const scopedLevel=parseWorkspaceOnlyAgentScopeQuery(req,res);if(scopedLevel===null)return;const routeDeps=workspaceAgentDepsForRuntime(runtime,deps);const clientIdResult=resolveOriginatorClientId(routeDeps,req,res);if(clientIdResult===null)return;const originatorClientId=clientIdResult;const manager=createDaemonSubagentManager(runtime.workspaceCwd);const existing=await manager.loadSubagent(agentType,scopedLevel);if(existing&&assertMutableLevel(existing,agentType,res))return;try{runtime.generationGuard?.assertOpen();await manager.deleteSubagent(agentType,scopedLevel,void 0,{assertCanCommit:__name(()=>runtime.generationGuard?.assertOpen(),"assertCanCommit")});runtime.generationGuard?.assertOpen()}catch(err){if(sendGenerationClosedError(res,err))return;if(err instanceof SubagentError){if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return}}writeStderrLine(`qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} failed: ${err instanceof Error?err.stack??err.message:String(err)}`);res.status(500).json({error:"Failed to delete workspace agent",code:"agent_delete_failed"});return}if(existing?.filePath){try{await fs.access(existing.filePath);writeStderrLine(`qwen serve: DELETE /workspaces/:workspace/agents/${safeLogValue(agentType)} partial \u2014 remaining=${existing.level}:${existing.filePath}`);res.status(500).json({error:`Failed to delete subagent "${agentType}" \u2014 ${existing.level} level still has its file on disk`,code:"agent_delete_partial",name:agentType,removedLevels:[],remainingLevels:[existing.level]});return}catch{}}try{runtime.generationGuard?.assertOpen()}catch(err){sendGenerationClosedError(res,err);return}runtime.bridge.publishWorkspaceEvent({type:"agent_changed",data:{change:"deleted",name:existing?.name??agentType,level:"project"},...originatorClientId?{originatorClientId}:{}});res.status(204).end()})}__name(mountWorkspaceQualifiedAgentsRoutes,"mountWorkspaceQualifiedAgentsRoutes");function validateAgentType(req,res){const raw=req.params["agentType"];if(!raw||raw.length===0){res.status(400).json({error:"`agentType` path parameter is required",code:"invalid_agent_type"});return null}if(raw.length>AGENT_TYPE_MAX_LENGTH||!AGENT_TYPE_PATTERN.test(raw)){res.status(400).json({error:"`agentType` must contain only letters, numbers, hyphens, or underscores (max 64 chars)",code:"invalid_agent_type",agentType:raw});return null}return raw}__name(validateAgentType,"validateAgentType");function parseScopeQuery(req,res){const raw=req.query["scope"];if(raw===void 0)return void 0;if(typeof raw!=="string"){res.status(400).json({error:'`scope` query must be a single "workspace" or "global" value',code:"invalid_scope"});return null}if(raw!=="workspace"&&raw!=="global"){res.status(400).json({error:'`scope` query must be "workspace" or "global"',code:"invalid_scope"});return null}return raw==="workspace"?"project":"user"}__name(parseScopeQuery,"parseScopeQuery");function assertMutableLevel(found,agentType,res){if(found.isBuiltin||found.level==="builtin"||found.level==="extension"||found.level==="session"){res.status(403).json({error:`Cannot modify ${found.level}-level subagent "${agentType}"`,code:"agent_readonly",name:found.name,level:found.level});return true}return false}__name(assertMutableLevel,"assertMutableLevel");function resolveOriginatorClientId(deps,req,res){const clientId=deps.parseClientId(req,res);if(clientId===null)return null;if(clientId===void 0)return void 0;if(!deps.bridge.knownClientIds().has(clientId)){res.status(400).json({error:`Client id "${clientId}" is not registered for this workspace`,code:"invalid_client_id",clientId});return null}return clientId}__name(resolveOriginatorClientId,"resolveOriginatorClientId");function resolveTrustedWorkspaceAgentRuntime(deps,req,res){const runtime=resolveWorkspaceRuntimeFromParam(deps.workspaceRegistry,req,res);if(!runtime)return void 0;if(!requireTrustedWorkspaceRuntime(runtime,res))return void 0;return runtime}__name(resolveTrustedWorkspaceAgentRuntime,"resolveTrustedWorkspaceAgentRuntime");function workspaceAgentDepsForRuntime(runtime,deps){return{bridge:runtime.bridge,boundWorkspace:runtime.workspaceCwd,mutate:deps.mutate,parseClientId:deps.parseClientId,safeBody:deps.safeBody}}__name(workspaceAgentDepsForRuntime,"workspaceAgentDepsForRuntime");function parseWorkspaceOnlyAgentBodyScope(body,res){const scope=body["scope"];if(scope===void 0||scope==="workspace"||scope==="project"){return"project"}return rejectWorkspaceQualifiedAgentScope(scope,res)}__name(parseWorkspaceOnlyAgentBodyScope,"parseWorkspaceOnlyAgentBodyScope");function parseWorkspaceOnlyAgentScopeQuery(req,res){const raw=req.query["scope"];if(raw===void 0||raw==="workspace"||raw==="project"){return"project"}if(typeof raw!=="string"){res.status(400).json({error:"`scope` query must be a single workspace/project value",code:"invalid_scope"});return null}return rejectWorkspaceQualifiedAgentScope(raw,res)}__name(parseWorkspaceOnlyAgentScopeQuery,"parseWorkspaceOnlyAgentScopeQuery");function rejectWorkspaceQualifiedAgentScope(scope,res){if(scope==="global"||scope==="user"){res.status(400).json({error:"Workspace-qualified agents routes only support workspace/project scope",code:"global_scope_not_supported_for_workspace_route"});return null}res.status(400).json({error:'`scope` must be "workspace" or "project"',code:"invalid_scope"});return null}__name(rejectWorkspaceQualifiedAgentScope,"rejectWorkspaceQualifiedAgentScope");function restoreAgentMcpServerSecrets(body,workspace,level,currentAgentServers){const incoming=body["mcpServers"];if(typeof incoming!=="object"||incoming===null||Array.isArray(incoming)){return body}const settings=loadSettings(workspace);const configuredServers=level==="user"?settings.user.settings.mcpServers??{}:settings.merged.mcpServers??{};return{...body,mcpServers:restoreRedactedMcpServersSetting(incoming,{...configuredServers,...currentAgentServers})}}__name(restoreAgentMcpServerSecrets,"restoreAgentMcpServerSecrets");function sendCreateAgentError(res,err,name){if(!(err instanceof SubagentError))return false;if(err.code===SubagentErrorCode.ALREADY_EXISTS){res.status(409).json({error:err.message,code:"agent_already_exists",name:err.subagentName??name});return true}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_CONFIG||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??name});return true}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??name});return true}return false}__name(sendCreateAgentError,"sendCreateAgentError");function sendUpdateAgentError(res,err,agentType){if(!(err instanceof SubagentError))return false;if(err.code===SubagentErrorCode.NOT_FOUND){res.status(404).json({error:err.message,code:"agent_not_found",name:err.subagentName??agentType});return true}if(err.code===SubagentErrorCode.INVALID_CONFIG){res.status(403).json({error:err.message,code:"agent_readonly",name:err.subagentName??agentType});return true}if(err.code===SubagentErrorCode.VALIDATION_ERROR||err.code===SubagentErrorCode.INVALID_NAME||err.code===SubagentErrorCode.TOOL_NOT_FOUND){res.status(422).json({error:err.message,code:"invalid_config",name:err.subagentName??agentType});return true}if(err.code===SubagentErrorCode.FILE_ERROR){const debug=isServeDebugMode();res.status(500).json({error:debug?err.message:"Failed to write workspace agent file",code:"file_error",name:err.subagentName??agentType});return true}return false}__name(sendUpdateAgentError,"sendUpdateAgentError");function parseAgentConfig(body,level,res){if("executionBackend"in body){return sendInvalidConfig(res,"Daemon agents do not support executionBackend.")}const rawName=body["name"];if(typeof rawName!=="string"||rawName.trim().length===0){res.status(422).json({error:"`name` is required and must be a non-empty string",code:"invalid_config"});return void 0}const name=rawName.trim();if(name.length<AGENT_TYPE_MIN_LENGTH||name.length>AGENT_TYPE_MAX_LENGTH||!AGENT_TYPE_PATTERN.test(name)){res.status(422).json({error:`\`name\` must be ${AGENT_TYPE_MIN_LENGTH}-${AGENT_TYPE_MAX_LENGTH} characters of letters, numbers, hyphens, or underscores`,code:"invalid_config",name});return void 0}if(BuiltinAgentRegistry.isBuiltinAgent(name)){res.status(422).json({error:`"${name}" shadows a built-in subagent and cannot be used as a project- or user-level agent name. Choose a different name.`,code:"invalid_config",name});return void 0}const description=body["description"];if(typeof description!=="string"||description.trim().length===0){res.status(422).json({error:"`description` is required and must be a non-empty string",code:"invalid_config"});return void 0}if(Buffer.byteLength(description,"utf8")>MAX_DESCRIPTION_BYTES){res.status(422).json({error:`\`description\` exceeds the ${MAX_DESCRIPTION_BYTES}-byte limit`,code:"invalid_config"});return void 0}const systemPrompt=body["systemPrompt"];if(typeof systemPrompt!=="string"||systemPrompt.trim().length===0){res.status(422).json({error:"`systemPrompt` is required and must be a non-empty string (whitespace only is rejected)",code:"invalid_config"});return void 0}if(Buffer.byteLength(systemPrompt,"utf8")>MAX_SYSTEM_PROMPT_BYTES){res.status(422).json({error:`\`systemPrompt\` exceeds the ${MAX_SYSTEM_PROMPT_BYTES}-byte limit`,code:"invalid_config"});return void 0}const tools=parseStringArray(body["tools"],"tools",res);if(tools===null)return void 0;const disallowedTools=parseStringArray(body["disallowedTools"],"disallowedTools",res);if(disallowedTools===null)return void 0;const config={name,description,systemPrompt,level};if(tools!==void 0)config.tools=tools;if(disallowedTools!==void 0)config.disallowedTools=disallowedTools;if(rejectIfPresentWrongType(body,"model","string",res))return void 0;if(typeof body["model"]==="string"){if(!body["model"].trim()){return sendInvalidConfig(res,"`model` must not be empty when provided")}config.model=body["model"].trim()}if(rejectIfPresentWrongType(body,"color","string",res))return void 0;if(typeof body["color"]==="string"){if(!SUBAGENT_COLORS.includes(body["color"])){return sendInvalidConfig(res,`\`color\` must be one of ${JSON.stringify(SUBAGENT_COLORS)}`)}config.color=body["color"]}if(rejectIfPresentWrongType(body,"approvalMode","string",res)){return void 0}if(typeof body["approvalMode"]==="string"){if(!SUBAGENT_APPROVAL_MODES.includes(body["approvalMode"])){return sendInvalidConfig(res,`\`approvalMode\` must be one of ${JSON.stringify(SUBAGENT_APPROVAL_MODES)}`)}config.approvalMode=body["approvalMode"]}if(rejectIfPresentWrongType(body,"permissionMode","string",res)){return void 0}if(typeof body["permissionMode"]==="string"){if(!SUBAGENT_PERMISSION_MODES.includes(body["permissionMode"])){return sendInvalidConfig(res,`\`permissionMode\` must be one of ${JSON.stringify(SUBAGENT_PERMISSION_MODES)}`)}config.permissionMode=body["permissionMode"]}if("maxTurns"in body){const maxTurns=parseMaxTurns(body["maxTurns"],res);if(maxTurns===null)return void 0;config.maxTurns=maxTurns}if("mcpServers"in body){const mcpServers=parseRecordField(body["mcpServers"],"mcpServers",value=>typeof value==="object"&&value!==null&&!Array.isArray(value),"an object of server names to server configuration objects",res);if(mcpServers===null)return void 0;if(Object.keys(mcpServers).length>0)config.mcpServers=mcpServers}if("hooks"in body){const hooks=parseRecordField(body["hooks"],"hooks",Array.isArray,"an object of hook event names to matcher arrays",res);if(hooks===null)return void 0;if(Object.keys(hooks).length>0)config.hooks=hooks}if(rejectIfPresentWrongType(body,"background","boolean",res)){return void 0}if(typeof body["background"]==="boolean"){config.background=body["background"]}const runConfig=body["runConfig"];if(runConfig!==void 0){const sanitized=sanitizeRunConfig(runConfig,res);if(sanitized===null)return void 0;config.runConfig=sanitized}return config}__name(parseAgentConfig,"parseAgentConfig");function parseAgentUpdates(body,res){if("executionBackend"in body){return sendInvalidConfig(res,"Daemon agents do not support executionBackend.")}const updates={};if("description"in body){const value=body["description"];if(typeof value!=="string"||value.trim().length===0){res.status(422).json({error:"`description` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return void 0}if(Buffer.byteLength(value,"utf8")>MAX_DESCRIPTION_BYTES){res.status(422).json({error:`\`description\` exceeds the ${MAX_DESCRIPTION_BYTES}-byte limit`,code:"invalid_config"});return void 0}updates.description=value}if("systemPrompt"in body){const value=body["systemPrompt"];if(typeof value!=="string"||value.trim().length===0){res.status(422).json({error:"`systemPrompt` must be a non-empty string (whitespace only is rejected) when provided",code:"invalid_config"});return void 0}if(Buffer.byteLength(value,"utf8")>MAX_SYSTEM_PROMPT_BYTES){res.status(422).json({error:`\`systemPrompt\` exceeds the ${MAX_SYSTEM_PROMPT_BYTES}-byte limit`,code:"invalid_config"});return void 0}updates.systemPrompt=value}if("tools"in body){const tools=parseStringArray(body["tools"],"tools",res);if(tools===null)return void 0;if(tools!==void 0)updates.tools=tools}if("disallowedTools"in body){const disallowedTools=parseStringArray(body["disallowedTools"],"disallowedTools",res);if(disallowedTools===null)return void 0;if(disallowedTools!==void 0){updates.disallowedTools=disallowedTools}}if(body["model"]===null){updates.model=void 0}else if(rejectIfPresentWrongType(body,"model","string",res)){return void 0}else if(typeof body["model"]==="string"){if(!body["model"].trim()){return sendInvalidConfig(res,"`model` must not be empty when provided")}updates.model=body["model"].trim()}if(body["color"]===null){updates.color=void 0}else if(rejectIfPresentWrongType(body,"color","string",res)){return void 0}else if(typeof body["color"]==="string"){if(!SUBAGENT_COLORS.includes(body["color"])){return sendInvalidConfig(res,`\`color\` must be one of ${JSON.stringify(SUBAGENT_COLORS)}`)}updates.color=body["color"]}if(body["approvalMode"]===null){updates.approvalMode=void 0}else if(rejectIfPresentWrongType(body,"approvalMode","string",res)){return void 0}else if(typeof body["approvalMode"]==="string"){if(!SUBAGENT_APPROVAL_MODES.includes(body["approvalMode"])){return sendInvalidConfig(res,`\`approvalMode\` must be one of ${JSON.stringify(SUBAGENT_APPROVAL_MODES)}`)}updates.approvalMode=body["approvalMode"]}if(body["permissionMode"]===null){updates.permissionMode=void 0}else if(rejectIfPresentWrongType(body,"permissionMode","string",res)){return void 0}else if(typeof body["permissionMode"]==="string"){if(!SUBAGENT_PERMISSION_MODES.includes(body["permissionMode"])){return sendInvalidConfig(res,`\`permissionMode\` must be one of ${JSON.stringify(SUBAGENT_PERMISSION_MODES)}`)}updates.permissionMode=body["permissionMode"]}if("maxTurns"in body){if(body["maxTurns"]===null){updates.maxTurns=void 0}else{const maxTurns=parseMaxTurns(body["maxTurns"],res);if(maxTurns===null)return void 0;updates.maxTurns=maxTurns}}if("mcpServers"in body){const mcpServers=parseRecordField(body["mcpServers"],"mcpServers",value=>typeof value==="object"&&value!==null&&!Array.isArray(value),"an object of server names to server configuration objects",res);if(mcpServers===null)return void 0;updates.mcpServers=mcpServers}if("hooks"in body){const hooks=parseRecordField(body["hooks"],"hooks",Array.isArray,"an object of hook event names to matcher arrays",res);if(hooks===null)return void 0;updates.hooks=hooks}if(rejectIfPresentWrongType(body,"background","boolean",res)){return void 0}if(typeof body["background"]==="boolean"){updates.background=body["background"]}if("runConfig"in body){const sanitized=sanitizeRunConfig(body["runConfig"],res);if(sanitized===null)return void 0;updates.runConfig=sanitized}return updates}__name(parseAgentUpdates,"parseAgentUpdates");function parseStringArray(value,field,res){if(value===void 0)return void 0;if(!Array.isArray(value)||value.some(v=>typeof v!=="string")){res.status(422).json({error:`\`${field}\` must be an array of strings when provided`,code:"invalid_config"});return null}if(value.length>MAX_TOOLS_ENTRIES){res.status(422).json({error:`\`${field}\` exceeds the ${MAX_TOOLS_ENTRIES}-entry limit`,code:"invalid_config"});return null}if(value.some(v=>v.length>MAX_TOOL_ID_LENGTH)){res.status(422).json({error:`\`${field}\` entries must be at most ${MAX_TOOL_ID_LENGTH} characters`,code:"invalid_config"});return null}return value}__name(parseStringArray,"parseStringArray");function sendInvalidConfig(res,error){res.status(422).json({error,code:"invalid_config"});return void 0}__name(sendInvalidConfig,"sendInvalidConfig");function parseMaxTurns(value,res){if(typeof value!=="number"||!Number.isFinite(value)||!Number.isInteger(value)||value<=0){sendInvalidConfig(res,"`maxTurns` must be a positive integer");return null}return value}__name(parseMaxTurns,"parseMaxTurns");function parseRecordField(value,field,isValidEntry,expected,res){if(typeof value!=="object"||value===null||Array.isArray(value)){sendInvalidConfig(res,`\`${field}\` must be ${expected}`);return null}const entries=Object.entries(value);if(entries.length>MAX_RECORD_ENTRIES){sendInvalidConfig(res,`\`${field}\` exceeds the ${MAX_RECORD_ENTRIES}-entry limit`);return null}const output={};for(const[key,entry]of entries){if(!key||key.length>MAX_TOOL_ID_LENGTH||key==="__proto__"||key==="constructor"||key==="prototype"||!isValidEntry(entry)){sendInvalidConfig(res,`\`${field}\` must be ${expected}`);return null}output[key]=entry}return output}__name(parseRecordField,"parseRecordField");function rejectIfPresentWrongType(body,key,expected,res){if(!(key in body))return false;if(typeof body[key]===expected)return false;res.status(422).json({error:`\`${key}\` must be a ${expected} when provided`,code:"invalid_config"});return true}__name(rejectIfPresentWrongType,"rejectIfPresentWrongType");function isNoOpUpdate(existing,updates){if(updates.description!==void 0&&updates.description!==existing.description){return false}if(updates.systemPrompt!==void 0&&updates.systemPrompt!==existing.systemPrompt){return false}if(updates.tools!==void 0&&!shallowArrayEqual(updates.tools,existing.tools)){return false}if(updates.disallowedTools!==void 0&&!shallowArrayEqual(updates.disallowedTools,existing.disallowedTools)){return false}if("model"in updates&&updates.model!==existing.model){return false}if("color"in updates&&updates.color!==existing.color){return false}if("approvalMode"in updates&&updates.approvalMode!==existing.approvalMode){return false}if("permissionMode"in updates&&updates.permissionMode!==existing.permissionMode){return false}if("maxTurns"in updates&&updates.maxTurns!==existing.maxTurns){return false}if(updates.mcpServers!==void 0&&!isDeepStrictEqual(normalizedRecord(updates.mcpServers),normalizedRecord(existing.mcpServers))){return false}if(updates.hooks!==void 0&&!isDeepStrictEqual(normalizedRecord(updates.hooks),normalizedRecord(existing.hooks))){return false}if(updates.background!==void 0&&updates.background!==existing.background){return false}if(updates.runConfig!==void 0){const e=existing.runConfig??{};const u=updates.runConfig;if("max_time_minutes"in u){if(u["max_time_minutes"]!==e["max_time_minutes"])return false}if("max_turns"in u){if(u["max_turns"]!==e["max_turns"])return false}}return true}__name(isNoOpUpdate,"isNoOpUpdate");function normalizedRecord(value){if(!value||Object.keys(value).length===0)return void 0;return normalizeRecordValue(value)}__name(normalizedRecord,"normalizedRecord");function normalizeRecordValue(value){if(Array.isArray(value))return value.map(normalizeRecordValue);if(typeof value!=="object"||value===null)return value;return Object.fromEntries(Object.entries(value).filter(([,entry])=>entry!==void 0).map(([key,entry])=>[key,normalizeRecordValue(entry)]))}__name(normalizeRecordValue,"normalizeRecordValue");function shallowArrayEqual(a,b){if(a===b)return true;if(!a||!b)return false;if(a.length!==b.length)return false;for(let i=0;i<a.length;i++)if(a[i]!==b[i])return false;return true}__name(shallowArrayEqual,"shallowArrayEqual");function sanitizeRunConfig(raw,res){if(typeof raw!=="object"||raw===null||Array.isArray(raw)){res.status(422).json({error:"`runConfig` must be an object when provided",code:"invalid_config"});return null}const input=raw;const out={};if("max_time_minutes"in input){const v=input["max_time_minutes"];if(typeof v!=="number"||!Number.isFinite(v)||v<=0){res.status(422).json({error:"`runConfig.max_time_minutes` must be a positive finite number when provided",code:"invalid_config"});return null}out["max_time_minutes"]=v}if("max_turns"in input){const v=input["max_turns"];if(typeof v!=="number"||!Number.isFinite(v)||v<=0||!Number.isInteger(v)){res.status(422).json({error:"`runConfig.max_turns` must be a positive integer when provided",code:"invalid_config"});return null}out["max_turns"]=v}return out}__name(sanitizeRunConfig,"sanitizeRunConfig");function toSummary(config){const summary={kind:"agent",name:config.name,description:config.description,level:config.level,isBuiltin:config.isBuiltin===true||config.level==="builtin",hasTools:Array.isArray(config.tools)&&config.tools.length>0};if(config.tools)summary.tools=[...config.tools];if(config.disallowedTools){summary.disallowedTools=[...config.disallowedTools]}if(config.model)summary.model=config.model;if(config.color)summary.color=config.color;if(config.background!==void 0)summary.background=config.background;if(config.approvalMode)summary.approvalMode=config.approvalMode;if(config.permissionMode)summary.permissionMode=config.permissionMode;if(config.maxTurns!==void 0)summary.maxTurns=config.maxTurns;if(config.mcpServers){summary.mcpServerNames=Object.keys(config.mcpServers)}if(config.hooks)summary.hookEvents=Object.keys(config.hooks);if(config.runConfig){const runConfig={};if(typeof config.runConfig.max_time_minutes==="number"){runConfig.max_time_minutes=config.runConfig.max_time_minutes}if(typeof config.runConfig.max_turns==="number"){runConfig.max_turns=config.runConfig.max_turns}summary.runConfig=runConfig}if(config.extensionName)summary.extensionName=config.extensionName;if(config.filePath)summary.filePath=config.filePath;return summary}__name(toSummary,"toSummary");function toDetail(config){const detail={...toSummary(config),systemPrompt:config.systemPrompt};if(config.mcpServers){detail.mcpServers=redactMcpServersSetting(config.mcpServers)}if(config.hooks)detail.hooks=config.hooks;return detail}__name(toDetail,"toDetail");function createDaemonSubagentManager(boundWorkspace,safeMode=false){const stub={getSdkMode:__name(()=>false,"getSdkMode"),getProjectRoot:__name(()=>boundWorkspace,"getProjectRoot"),getActiveExtensions:__name(()=>[],"getActiveExtensions"),isSafeMode:__name(()=>safeMode,"isSafeMode"),getAgentsSettings:__name(()=>({}),"getAgentsSettings")};const guarded=new Proxy(stub,{get(target,prop){if(prop in target){return target[prop]}if(prop==="then")return void 0;throw new Error(`qwen serve workspace agents: SubagentManager touched Config.${String(prop)} which the daemon stub does not implement. Add it to createDaemonSubagentManager and audit safety.`)},has(target,prop){if(prop in target)return true;if(prop==="then")return false;throw new Error(`qwen serve workspace agents: SubagentManager probed Config.${String(prop)} via 'in' check; the daemon stub does not implement it. Add it to createDaemonSubagentManager and audit safety.`)}});return new SubagentManager(guarded)}__name(createDaemonSubagentManager,"createDaemonSubagentManager");export{mountWorkspaceAgentsRoutes,mountWorkspaceQualifiedAgentsRoutes,toSummary,toDetail,createDaemonSubagentManager};
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright 2025 Qwen Team
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{SessionNotFoundError}from"./chunk-VTZZXEWA.js";import{SessionIdCaseConflictError,SessionService,readSessionTranscriptSnapshot}from"./chunk-
|
|
3
|
+
import{SessionNotFoundError}from"./chunk-VTZZXEWA.js";import{SessionIdCaseConflictError,SessionService,readSessionTranscriptSnapshot}from"./chunk-LDXZT3SG.js";import{SessionExecutionEngineError}from"./chunk-VZDZ34KK.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();function createSessionExecutionEngineSelector(options){return async selection=>{const{managed}=options;if(selection.operation==="spawn"){if(!managed||isDeferredCreation(selection))return"legacy";const compatibility2=await checkCompatibility(managed,selection);return compatibility2.status==="compatible"?"managed":"legacy"}const{sessionId,workspaceCwd}=selection.request;const service=new SessionService(workspaceCwd,{runtimeBaseDir:options.runtimeBaseDir});const persistedSessionId=await resolvePersistedSessionId(service,sessionId);const snapshot=persistedSessionId===void 0?void 0:await readSessionTranscriptSnapshot(service.getSessionTranscriptPath(persistedSessionId),persistedSessionId,false);if(!snapshot)throw new SessionNotFoundError(sessionId);const owner=snapshot.executionEngine;if(owner.status!=="verified"){throw new SessionExecutionEngineError(sessionId,owner.reason)}if(owner.engine==="legacy")return"legacy";const compatibility=managed?await checkCompatibility(managed,selection):{status:"unknown",reason:"no Managed engine is available"};if(compatibility.status==="compatible")return"managed";throw new SessionExecutionEngineError(sessionId,`belongs to managed, which cannot run here: ${compatibility.reason}`)}}__name(createSessionExecutionEngineSelector,"createSessionExecutionEngineSelector");function createPairedExecutionEngines(options){return{legacy:options.legacy,managed:options.managed?.factory??managedEngineUnavailable,select:createSessionExecutionEngineSelector(options)}}__name(createPairedExecutionEngines,"createPairedExecutionEngines");var managedEngineUnavailable=__name(async()=>{throw new Error("No Managed execution engine is available in this host.")},"managedEngineUnavailable");function isDeferredCreation(selection){const{request}=selection;return selection.daemonOwnedStandalone||request.parentSessionId!==void 0||request.worktree!==void 0||request.branch!==void 0||request.sourceType!==void 0&&(request.sourceType!=="default"||request.sourceId!==void 0)}__name(isDeferredCreation,"isDeferredCreation");async function checkCompatibility(managed,selection){try{return await managed.evaluate(selection)}catch{return{status:"unknown",reason:"the compatibility check failed"}}}__name(checkCompatibility,"checkCompatibility");async function resolvePersistedSessionId(service,sessionId){try{return await service.findSessionIdIgnoringCase(sessionId)}catch(error){if(error instanceof SessionIdCaseConflictError&&error.reason==="case_conflict"&&error.candidateSessionId===sessionId){return sessionId}throw error}}__name(resolvePersistedSessionId,"resolvePersistedSessionId");export{createSessionExecutionEngineSelector,createPairedExecutionEngines};
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright 2026 Qwen Team
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{customDeepMerge,getSettingsSchema}from"./chunk-
|
|
3
|
+
import{customDeepMerge,getSettingsSchema}from"./chunk-RL57IU47.js";import{DEFAULT_DARK_THEME_NAME,DEFAULT_LIGHT_THEME_NAME}from"./chunk-UWCF7JIF.js";import{CONSOLIDATED_DISABLE_KEYS,V1_INDICATOR_KEYS,V1_TO_V2_MIGRATION_MAP,V1_TO_V2_PRESERVE_DISABLE_MAP,V2_CONTAINER_KEYS}from"./chunk-LMUSSYJH.js";import{SETTINGS_DIRECTORY_NAME,getHomeEnvFallbackVars,loadEnvironment,preResolveHomeEnvOverrides}from"./chunk-M3UC46LS.js";import{ENV_CORRUPTED_PATH,ENV_WAS_RECOVERED}from"./chunk-CVMMNPLX.js";import{t}from"./chunk-H45OX4VY.js";import{SUPPORTED_LANGUAGES,getLanguageNameFromLocale}from"./chunk-MWABT6CH.js";import{parseExecutionSandboxSettings,readBareModeOperatorSettings,readOperatorSandboxSettings,require_strip_json_comments,selectOperatorExecutionSandbox,stripUtf8Bom}from"./chunk-DOLUT3XC.js";import{getGlobalQwenDirLite,getSystemDefaultsPath,getSystemSettingsPath,spawnedEnvironmentView}from"./chunk-PTHIQ7ZN.js";import{isWorkspaceTrusted,updateSettingsFilePreservingFormat}from"./chunk-W5D2T2JK.js";import{isValidAdvisorMaxUses}from"./chunk-LDXZT3SG.js";import{resolveEnvVarsInObject}from"./chunk-OGI5HG6N.js";import{stripRuntimeSnapshotPrefix}from"./chunk-DIHJELGW.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{Storage}from"./chunk-EPODBRBP.js";import{FatalConfigError,getErrorMessage}from"./chunk-XYB7GC5U.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name,__toESM}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import*as fs3 from"node:fs";import*as path2 from"node:path";import{homedir}from"node:os";import process from"node:process";var import_strip_json_comments=__toESM(require_strip_json_comments(),1);init_esbuild_shims();function hasOwnModelProviders(settingsObj){if(!settingsObj||typeof settingsObj!=="object"){return false}const obj=settingsObj;return Object.prototype.hasOwnProperty.call(obj,"modelProviders")}__name(hasOwnModelProviders,"hasOwnModelProviders");function getModelProvidersOwnerScope(settings){if(settings.isTrusted&&hasOwnModelProviders(settings.workspace.settings)){return"Workspace"}if(hasOwnModelProviders(settings.user.settings)){return"User"}return void 0}__name(getModelProvidersOwnerScope,"getModelProvidersOwnerScope");function getPersistScopeForModelSelection(settings){return getModelProvidersOwnerScope(settings)??"User"}__name(getPersistScopeForModelSelection,"getPersistScopeForModelSelection");function getWritableScopes(settings){return settings.isTrusted?["Workspace","User"]:["User"]}__name(getWritableScopes,"getWritableScopes");function getOwnKeyScope(settings,key){for(const scope of getWritableScopes(settings)){const obj=settings.forScope(scope).settings;if(Object.prototype.hasOwnProperty.call(obj,key))return scope}return void 0}__name(getOwnKeyScope,"getOwnKeyScope");init_esbuild_shims();init_esbuild_shims();import*as fs from"node:fs";import*as path from"node:path";var LLM_OUTPUT_LANGUAGE_RULE_FILENAME="output-language.md";var LLM_OUTPUT_LANGUAGE_MARKER_PREFIX="qwen-code:llm-output-language:";var OUTPUT_LANGUAGE_AUTO="auto";function isAutoLanguage(value){return!value||value.toLowerCase()===OUTPUT_LANGUAGE_AUTO}__name(isAutoLanguage,"isAutoLanguage");function normalizeOutputLanguage(language){const normalized=language.trim().replace(/_/g,"-").toLowerCase();const knownLanguageName=SUPPORTED_LANGUAGES.find(supportedLanguage=>supportedLanguage.fullName.toLowerCase()===normalized);if(knownLanguageName){return knownLanguageName.fullName}const knownLocaleCode=SUPPORTED_LANGUAGES.some(supportedLanguage=>{const code=supportedLanguage.code.toLowerCase();const id=supportedLanguage.id.toLowerCase();return normalized===code||normalized===id||normalized.startsWith(`${code}-`)||normalized.startsWith(`${id}-`)||normalized.startsWith(`${code}.`)||normalized.startsWith(`${id}.`)||normalized.startsWith(`${code}@`)||normalized.startsWith(`${id}@`)});if(!knownLocaleCode){return language}return getLanguageNameFromLocale(normalized)}__name(normalizeOutputLanguage,"normalizeOutputLanguage");function resolveOutputLanguage(value){if(isAutoLanguage(value)){throw new Error("resolveOutputLanguage does not accept auto; use resolveOutputLanguageOrPreserveAuto instead.")}return normalizeOutputLanguage(value)}__name(resolveOutputLanguage,"resolveOutputLanguage");function resolveOutputLanguageOrPreserveAuto(value){return isAutoLanguage(value)?OUTPUT_LANGUAGE_AUTO:resolveOutputLanguage(value)}__name(resolveOutputLanguageOrPreserveAuto,"resolveOutputLanguageOrPreserveAuto");function getOutputLanguageFilePath(){return path.join(Storage.getGlobalQwenDir(),LLM_OUTPUT_LANGUAGE_RULE_FILENAME)}__name(getOutputLanguageFilePath,"getOutputLanguageFilePath");function sanitizeForMarker(language){return language.replace(/[\r\n]/g," ").replace(/--!?>/g,"").replace(/--/g,"")}__name(sanitizeForMarker,"sanitizeForMarker");function generateOutputLanguageFileContent(language){const safeLanguage=sanitizeForMarker(language);if(isAutoLanguage(language)){return`# Output language preference: ${OUTPUT_LANGUAGE_AUTO}
|
|
4
4
|
<!-- ${LLM_OUTPUT_LANGUAGE_MARKER_PREFIX} ${OUTPUT_LANGUAGE_AUTO} -->
|
|
5
5
|
|
|
6
6
|
## Rule
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{t}from"./chunk-H45OX4VY.js";import{computeThresholds,estimateContextTextTokens,formatContextFileDisplayPath,getMainSessionBaseSystemPrompt}from"./chunk-
|
|
3
|
+
import{t}from"./chunk-H45OX4VY.js";import{computeThresholds,estimateContextTextTokens,formatContextFileDisplayPath,getMainSessionBaseSystemPrompt}from"./chunk-LDXZT3SG.js";import{stripTerminalControlSequences}from"./chunk-R2EHHA2C.js";import{qualifySkillName}from"./chunk-CV2UAEZA.js";import{isMediaPolicyToolHiddenFromModel}from"./chunk-S2ZKZXHX.js";import{DiscoveredMCPTool,uiTelemetryService}from"./chunk-DR3HLUJ5.js";import{resolveSlimmingConfig}from"./chunk-R54OXALA.js";import{DEFAULT_TOKEN_LIMIT}from"./chunk-TAAJ7TDB.js";import{buildAvailableSkillsReminder,getStartupContextLength,isSkillListingReminder}from"./chunk-65UCR6OZ.js";import{ToolNames}from"./chunk-2UNFJQ2D.js";import{isSubpath}from"./chunk-OKN3Z5C5.js";import{getErrorMessage}from"./chunk-XYB7GC5U.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import*as path from"node:path";init_esbuild_shims();import*as fs from"node:fs/promises";var EXTENSION_REF_PREFIX="ext:";var EXTENSION_CONTEXT_BUDGET=2e5;var EXTENSION_CONTEXT_FILE_CAP=5e4;function parseExtensionRef(pathName){if(!pathName.startsWith(EXTENSION_REF_PREFIX))return null;const name=pathName.slice(EXTENSION_REF_PREFIX.length);if(!name)return null;return{name}}__name(parseExtensionRef,"parseExtensionRef");function buildExtensionRef(extensionName){return`${EXTENSION_REF_PREFIX}${extensionName}`}__name(buildExtensionRef,"buildExtensionRef");function matchExtensionByRef(name,extensions){const lower=name.toLowerCase();return extensions.find(ext=>ext.name.toLowerCase()===lower||ext.config.name.toLowerCase()===lower)}__name(matchExtensionByRef,"matchExtensionByRef");var BIDI_CONTROL_RE=/[]/g;function sanitizeDisplayText(raw){const stripped=stripTerminalControlSequences(raw).replace(BIDI_CONTROL_RE,"").replace(/\s+/g," ").trim();return stripped.length>0?stripped:null}__name(sanitizeDisplayText,"sanitizeDisplayText");function getSanitizedExtensionDisplayName(extension){return sanitizeDisplayText(extension.displayName||extension.name)||extension.name}__name(getSanitizedExtensionDisplayName,"getSanitizedExtensionDisplayName");function buildExtensionContextText(extension){const displayName=getSanitizedExtensionDisplayName(extension);const lines=[];lines.push(`--- Extension: ${displayName} (untrusted third-party content) ---`);if(extension.config.description){const desc=sanitizeDisplayText(extension.config.description);if(desc){lines.push(desc);lines.push("")}}const capabilities=[];if(extension.skills&&extension.skills.length>0){const skillNames=extension.skills.map(s=>sanitizeDisplayText(qualifySkillName(extension.name,s.name))||s.name).join(", ");capabilities.push(`- Skills: ${skillNames} (invoke via /<skill-name>)`)}if(extension.mcpServers&&Object.keys(extension.mcpServers).length>0){const serverNames=Object.keys(extension.mcpServers).map(n=>sanitizeDisplayText(n)||n).join(", ");capabilities.push(`- MCP Servers: ${serverNames}`)}if(extension.agents&&extension.agents.length>0){const agentNames=extension.agents.map(a=>sanitizeDisplayText(a.name)||a.name).join(", ");capabilities.push(`- Agents: ${agentNames}`)}if(capabilities.length>0){lines.push("Available capabilities from this extension:");lines.push(...capabilities);lines.push("")}lines.push(`--- End Extension: ${displayName} ---`);return lines.join("\n")}__name(buildExtensionContextText,"buildExtensionContextText");async function buildExtensionMentionContext(extension,options){let contextText=buildExtensionContextText(extension);let remainingBudget=options.remainingBudget;if(extension.contextFiles.length===0){return{text:contextText,remainingBudget}}const fileReads=await Promise.allSettled(extension.contextFiles.map(async contextFilePath=>{let realPath;let realExtPath;try{realPath=await fs.realpath(contextFilePath);realExtPath=await fs.realpath(extension.path)}catch{options.onDebugMessage?.(`Skipping unreadable context file: ${contextFilePath}`);return null}if(!isSubpath(realExtPath,realPath)){options.onDebugMessage?.(`Skipping context file outside extension directory: ${contextFilePath}`);return null}return fs.readFile(realPath,{encoding:"utf-8",signal:options.signal})}));for(let i=0;i<fileReads.length;i++){const outcome=fileReads[i];if(outcome.status==="rejected"){options.onDebugMessage?.(`Failed to read extension context file ${extension.contextFiles[i]}: ${getErrorMessage(outcome.reason)}`);continue}const content=outcome.value;if(!content||!content.trim())continue;if(remainingBudget<=0){options.onDebugMessage?.("Extension context budget exhausted, skipping remaining files.");break}const cap=Math.min(EXTENSION_CONTEXT_FILE_CAP,remainingBudget);const cappedContent=content.length>cap?content.slice(0,cap)+"\n... (truncated)":content;contextText+=`
|
|
4
4
|
|
|
5
5
|
${cappedContent}`;remainingBudget-=cappedContent.length}return{text:contextText,remainingBudget}}__name(buildExtensionMentionContext,"buildExtensionMentionContext");function currentTier(tokens,thresholds){if(tokens>=thresholds.hard)return"hard";if(tokens>=thresholds.auto)return"auto";if(tokens>=thresholds.warn)return"warn";return"safe"}__name(currentTier,"currentTier");function extensionContextFileOwners(config,workingDir){const owners=new Map;for(const extension of config.getActiveExtensions?.()??[]){const displayName=getSanitizedExtensionDisplayName(extension);for(const contextFile of extension.contextFiles??[]){const absolutePath=path.resolve(workingDir,contextFile);const fileLabel=formatContextFileDisplayPath(absolutePath,extension.path);owners.set(absolutePath,`${t("Extension")}: ${displayName} \xB7 ${fileLabel}`)}}return owners}__name(extensionContextFileOwners,"extensionContextFileOwners");function parseMemoryFiles(memoryContent,workingDir,extensionOwners=new Map){if(!memoryContent||memoryContent.trim().length===0)return[];const results=[];const regex=/--- Context from: (.+?) ---\n([\s\S]*?)--- End of Context from: \1 ---/g;let match;while((match=regex.exec(memoryContent))!==null){const filePath=match[1];const content=match[2];const absolutePath=path.resolve(workingDir,filePath);const owner=extensionOwners.get(absolutePath);results.push({path:owner??formatContextFileDisplayPath(absolutePath,workingDir),tokens:estimateContextTextTokens(content)})}if(results.length===0&&memoryContent.trim().length>0){results.push({path:t("memory"),tokens:estimateContextTextTokens(memoryContent)})}return results}__name(parseMemoryFiles,"parseMemoryFiles");function unescapeXml(text){return text.replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&")}__name(unescapeXml,"unescapeXml");var SKILL_LISTING_ENTRY=/<skill>\n<name>\n([\s\S]*?)\n<\/name>[\s\S]*?<\/skill>/g;function measureSkillListing(text){const byName=new Map;for(const match of text.matchAll(SKILL_LISTING_ENTRY)){const name=unescapeXml(match[1]);byName.set(name.toLowerCase(),{name,tokens:estimateContextTextTokens(match[0])})}return{tokens:estimateContextTextTokens(text),byName}}__name(measureSkillListing,"measureSkillListing");function mergeSkillListing(into,from){into.tokens+=from.tokens;for(const[name,entry]of from.byName){into.byName.set(name,entry)}}__name(mergeSkillListing,"mergeSkillListing");function measureTailSkillListings(conversation){const listing={tokens:0,byName:new Map};const billedTexts=new Set;for(const content of conversation){for(const part of content.parts??[]){const text=part.text;if(typeof text!=="string"||!isSkillListingReminder(text))continue;const measured=measureSkillListing(text);if(measured.byName.size===0)continue;mergeSkillListing(listing,measured);billedTexts.add(text)}}return{listing,billedTexts}}__name(measureTailSkillListings,"measureTailSkillListings");function measureStartupPrelude(prelude){const skillListing={tokens:0,byName:new Map};let startupContextTokens=0;for(const content of prelude){for(const part of content.parts??[]){if(typeof part.text!=="string")continue;if(isSkillListingReminder(part.text)){mergeSkillListing(skillListing,measureSkillListing(part.text))}else{startupContextTokens+=estimateContextTextTokens(part.text)}}}return{skillListing,startupContextTokens}}__name(measureStartupPrelude,"measureStartupPrelude");function estimateFunctionResponseTokens(part,imageTokenEstimate){const response=part.functionResponse;let tokens=estimateContextTextTokens(JSON.stringify({id:response.id,name:response.name,response:response.response}));const nested=response.parts;if(Array.isArray(nested)){for(const inner of nested){if(inner.inlineData||inner.fileData){tokens+=imageTokenEstimate}else if(typeof inner.text==="string"){tokens+=estimateContextTextTokens(inner.text)}}}return tokens}__name(estimateFunctionResponseTokens,"estimateFunctionResponseTokens");function consumeBilledSkillBody(part,billedSkillBodies){if(billedSkillBodies.size===0)return false;const output=part.functionResponse?.response?.output;if(typeof output!=="string")return false;if(billedSkillBodies.delete(output))return true;for(const body of billedSkillBodies){if(output.startsWith(`${body}
|
|
6
6
|
`)){billedSkillBodies.delete(body);return true}}return false}__name(consumeBilledSkillBody,"consumeBilledSkillBody");function estimateConversationTokens(conversation,billing){let tokens=0;const remainingSkillBodies=new Set(billing.billedSkillBodies);for(const content of conversation){for(const part of content.parts??[]){if(typeof part.text==="string"){if(billing.billedListingTexts.has(part.text))continue;tokens+=estimateContextTextTokens(part.text)}else if(part.inlineData||part.fileData){tokens+=billing.imageTokenEstimate}else if(part.functionCall){tokens+=estimateContextTextTokens(JSON.stringify(part.functionCall))}else if(part.functionResponse){if(part.functionResponse.name===ToolNames.SKILL&&consumeBilledSkillBody(part,remainingSkillBodies)){continue}tokens+=estimateFunctionResponseTokens(part,billing.imageTokenEstimate)}}}return tokens}__name(estimateConversationTokens,"estimateConversationTokens");async function collectContextData(config,showDetails){const modelName=config.getModel()||"unknown";const contentGeneratorConfig=config.getContentGeneratorConfig();const contextWindowSize=contentGeneratorConfig.contextWindowSize??DEFAULT_TOKEN_LIMIT;const llmClient=config.getLlmClient?.();const activeChat=llmClient?.isInitialized?.()?llmClient.getChat():void 0;const apiTotalTokens=activeChat?activeChat.getLastPromptTokenCount():uiTelemetryService.getLastPromptTokenCount();const apiCachedTokens=activeChat?.getLastCachedContentTokenCount?.()??uiTelemetryService.getLastCachedContentTokenCount();const history=activeChat?.getHistoryShallow?.()??activeChat?.getHistory?.()??[];const preludeLength=getStartupContextLength(history);const prelude=measureStartupPrelude(history.slice(0,preludeLength));const conversationHistory=history.slice(preludeLength);const tailSkillListings=measureTailSkillListings(conversationHistory);let conversationTokens=0;const systemPromptText=getMainSessionBaseSystemPrompt(config);const systemPromptTokens=estimateContextTextTokens(systemPromptText);const toolRegistry=config.getToolRegistry();const allTools=toolRegistry?toolRegistry.getAllTools():[];const toolDeclarations=toolRegistry?toolRegistry.getFunctionDeclarations():[];const toolsJsonStr=JSON.stringify(toolDeclarations);const allToolsTokens=estimateContextTextTokens(toolsJsonStr);const builtinTools=[];const mcpTools=[];for(const tool of allTools){if(toolRegistry?.isDeferredAndHidden(tool.name)){continue}if(isMediaPolicyToolHiddenFromModel(config,tool)){continue}const toolJsonStr=JSON.stringify(tool.schema);const tokens=estimateContextTextTokens(toolJsonStr);if(tool instanceof DiscoveredMCPTool){mcpTools.push({name:`${tool.serverName}__${tool.serverToolName||tool.name}`,tokens})}else if(tool.name!==ToolNames.SKILL){builtinTools.push({name:tool.name,tokens})}}const memoryContent=config.getUserMemory();const memoryFiles=parseMemoryFiles(memoryContent,config.getWorkingDir(),extensionContextFileOwners(config,config.getWorkingDir()));const autoMemoryPrompt=[config.getAutoMemoryPrompt(),config.getAutoMemoryContext?.()??""].filter(Boolean).join("\n\n");if(autoMemoryPrompt){memoryFiles.push({path:t("auto memory"),tokens:estimateContextTextTokens(autoMemoryPrompt)})}const memoryFilesTokens=memoryFiles.reduce((sum,f)=>sum+f.tokens,0);const skillTool=allTools.find(tool=>tool.name===ToolNames.SKILL);const skillToolDefinitionTokens=skillTool?estimateContextTextTokens(JSON.stringify(skillTool.schema)):0;const loadedContentNames=skillTool&&"getLoadedSkillContentNames"in skillTool?skillTool.getLoadedSkillContentNames():new Map;const bodyTokensByName=new Map;for(const[content,name]of loadedContentNames){bodyTokensByName.set(name,(bodyTokensByName.get(name)??0)+estimateContextTextTokens(content))}const loadedBodiesTokens=[...bodyTokensByName.values()].reduce((sum,tokens)=>sum+tokens,0);const skillManager=config.getSkillManager();const skillConfigs=skillManager?await skillManager.listSkills():[];const enabledSkillNames=new Set(skillConfigs.filter(skill=>config.isSkillEnabled(skill)).map(skill=>skill.name.toLowerCase()));let skillListing=prelude.skillListing;if(!activeChat){const reminder=await buildAvailableSkillsReminder(config);if(reminder){skillListing=measureSkillListing(reminder.reminder)}}mergeSkillListing(skillListing,tailSkillListings.listing);const billedSkillBodies=new Set(loadedContentNames.keys());const skills=skillConfigs.map(skill=>{const listingTokens=skillListing.byName.get(skill.name.toLowerCase())?.tokens??0;const bodyTokens=bodyTokensByName.get(skill.name);const isLoaded=bodyTokens!==void 0;return{name:skill.name,tokens:listingTokens,loaded:isLoaded,bodyTokens}});const discoveredNames=new Set(skillConfigs.map(skill=>skill.name));for(const[name,bodyTokens]of bodyTokensByName){if(!discoveredNames.has(name)){skills.push({name,tokens:skillListing.byName.get(name.toLowerCase())?.tokens??0,loaded:true,bodyTokens})}}const rowedNames=new Set(skills.map(s=>s.name.toLowerCase()));for(const[key,entry]of skillListing.byName){enabledSkillNames.add(key);if(rowedNames.has(key))continue;rowedNames.add(key);skills.push({name:entry.name,tokens:entry.tokens,loaded:false})}conversationTokens=estimateConversationTokens(conversationHistory,{imageTokenEstimate:resolveSlimmingConfig(config.getChatCompression?.()).imageTokenEstimate,billedSkillBodies,billedListingTexts:tailSkillListings.billedTexts});const skillsTokens=skillToolDefinitionTokens+skillListing.tokens+loadedBodiesTokens;const startupContextTokens=prelude.startupContextTokens;const thresholds=computeThresholds(contextWindowSize,config.getAutoCompactThreshold());const autocompactBuffer=Math.max(0,Math.round(contextWindowSize-thresholds.auto));const rawOverhead=systemPromptTokens+allToolsTokens+memoryFilesTokens+skillListing.tokens+loadedBodiesTokens+startupContextTokens;const rawContent=rawOverhead+conversationTokens;const hasTokenCount=apiTotalTokens>0;const isEstimated=!hasTokenCount||activeChat?.isLastPromptTokenCountEstimated()===true;const mcpToolsTotalTokens=mcpTools.reduce((sum,tool)=>sum+tool.tokens,0);let totalTokens;let displaySystemPrompt;let displayBuiltinTools;let displayMcpTools;let displayMemoryFiles;let displaySkills;let displayStartupContext;let messagesTokens;let unattributedTokens=0;let freeSpace;let detailBuiltinTools;let detailMcpTools;let detailMemoryFiles;let detailSkills;const clampDeficit=Math.max(0,skillToolDefinitionTokens+mcpToolsTotalTokens-allToolsTokens);const clampedMcpTools=Math.max(0,mcpToolsTotalTokens-clampDeficit);const clampedSkills=skillsTokens-Math.max(0,clampDeficit-mcpToolsTotalTokens);const clampedBuiltinTools=Math.max(0,allToolsTokens-skillToolDefinitionTokens-clampedMcpTools);const mcpDetailShare=mcpToolsTotalTokens>0?clampedMcpTools/mcpToolsTotalTokens:1;const scaleTokens=__name((items,factor)=>factor<1?items.map(item=>({...item,tokens:Math.round(item.tokens*factor)})):items,"scaleTokens");if(!hasTokenCount){totalTokens=0;displaySystemPrompt=systemPromptTokens;displaySkills=clampedSkills;displayStartupContext=startupContextTokens;displayBuiltinTools=clampedBuiltinTools;displayMcpTools=clampedMcpTools;displayMemoryFiles=memoryFilesTokens;messagesTokens=conversationTokens;freeSpace=Math.max(0,contextWindowSize-rawContent-autocompactBuffer);detailBuiltinTools=builtinTools;detailMcpTools=scaleTokens(mcpTools,mcpDetailShare);detailMemoryFiles=memoryFiles;detailSkills=skills}else{totalTokens=apiTotalTokens;const scale=rawOverhead>totalTokens?totalTokens/rawOverhead:1;displaySystemPrompt=Math.floor(systemPromptTokens*scale);displayBuiltinTools=Math.floor(clampedBuiltinTools*scale);displayMcpTools=Math.floor(clampedMcpTools*scale);displayMemoryFiles=Math.floor(memoryFilesTokens*scale);displaySkills=Math.floor(clampedSkills*scale);displayStartupContext=Math.floor(startupContextTokens*scale);const attributedOverhead=displaySystemPrompt+displayBuiltinTools+displayMcpTools+displayMemoryFiles+displaySkills+displayStartupContext;if(scale<1){messagesTokens=Math.max(0,totalTokens-attributedOverhead)}else{messagesTokens=Math.min(conversationTokens,Math.max(0,totalTokens-attributedOverhead));unattributedTokens=Math.max(0,totalTokens-attributedOverhead-messagesTokens)}freeSpace=Math.max(0,contextWindowSize-totalTokens-autocompactBuffer);detailBuiltinTools=scaleTokens(builtinTools,scale);detailMcpTools=scaleTokens(mcpTools,scale*mcpDetailShare);detailMemoryFiles=scaleTokens(memoryFiles,scale);detailSkills=scale<1?skills.map(item=>({...item,tokens:Math.round(item.tokens*scale),bodyTokens:item.bodyTokens?Math.round(item.bodyTokens*scale):void 0})):skills}const tierTokens=hasTokenCount?apiTotalTokens:rawContent;const breakdown={systemPrompt:displaySystemPrompt,builtinTools:displayBuiltinTools,mcpTools:displayMcpTools,memoryFiles:displayMemoryFiles,skills:displaySkills,startupContext:displayStartupContext,messages:messagesTokens,unattributed:unattributedTokens,cachedTokens:hasTokenCount?apiCachedTokens:0,freeSpace,autocompactBuffer,thresholds,currentTier:currentTier(tierTokens,thresholds)};return{type:"context_usage",modelName,totalTokens,contextWindowSize,breakdown,builtinTools:showDetails?detailBuiltinTools:[],mcpTools:showDetails?detailMcpTools:[],memoryFiles:showDetails?detailMemoryFiles:[],skills:showDetails?detailSkills.filter(skill=>skill.loaded||enabledSkillNames.has(skill.name.toLowerCase())):[],isEstimated,showDetails}}__name(collectContextData,"collectContextData");function fmtTokens(tokens){if(tokens>=1e3){return`${(tokens/1e3).toFixed(1)}k`}return`${tokens}`}__name(fmtTokens,"fmtTokens");function fmtCategoryRow(label,tokens,contextWindowSize,indent=" "){const percentage=contextWindowSize>0?(tokens/contextWindowSize*100).toFixed(1):"0.0";const right=`${fmtTokens(tokens)} tokens (${percentage}%)`;const leftPart=`${indent}${label}`;const totalWidth=56;const dots=Math.max(1,totalWidth-leftPart.length-right.length);return`${leftPart}${" ".repeat(dots)}${right}`}__name(fmtCategoryRow,"fmtCategoryRow");function formatNum(n){return Math.round(n).toLocaleString("en-US")}__name(formatNum,"formatNum");function formatContextUsageText(data){const{modelName,totalTokens,contextWindowSize,breakdown,builtinTools,mcpTools,memoryFiles,skills,isEstimated,showDetails}=data;const hasTokenCount=totalTokens>0;const lines=[];lines.push("## Context Usage");lines.push("");if(!hasTokenCount){const includesConversation=breakdown.messages>0;lines.push(includesConversation?"*No provider usage yet. These are local estimates, including the conversation.*":"*No API response yet. Send a message to see actual usage.*");lines.push("");lines.push(includesConversation?"**Estimated usage, including the conversation**":"**Estimated pre-conversation overhead**");lines.push(`Model: ${modelName} Context window: ${fmtTokens(contextWindowSize)} tokens`);lines.push("")}else{lines.push(`Model: ${modelName} Context window: ${fmtTokens(contextWindowSize)} tokens`);lines.push("");if(isEstimated){lines.push("*Token usage is estimated until provider usage is received.*");lines.push("")}lines.push(fmtCategoryRow("Used",totalTokens,contextWindowSize));if((breakdown.cachedTokens??0)>0){lines.push(fmtCategoryRow("Cached prefix",breakdown.cachedTokens,contextWindowSize," \u2514 "))}lines.push(fmtCategoryRow("Free",breakdown.freeSpace,contextWindowSize));lines.push("");lines.push("**Compaction thresholds**");lines.push(` Effective window: ${formatNum(breakdown.thresholds.effectiveWindow)} (window \u2212 ${formatNum(contextWindowSize-breakdown.thresholds.effectiveWindow)} reserve)`);lines.push(` Warn threshold: ${formatNum(breakdown.thresholds.warn)}`);lines.push(` Auto threshold: ${formatNum(breakdown.thresholds.auto)}`);lines.push(` Hard threshold: ${formatNum(breakdown.thresholds.hard)}`);lines.push(` Current tier: ${breakdown.currentTier}`);lines.push("");lines.push("**Usage by category**")}lines.push(fmtCategoryRow("System prompt",breakdown.systemPrompt,contextWindowSize));lines.push(fmtCategoryRow("Built-in tools",breakdown.builtinTools,contextWindowSize));if(breakdown.mcpTools>0){lines.push(fmtCategoryRow("MCP tools",breakdown.mcpTools,contextWindowSize))}lines.push(fmtCategoryRow("Memory files",breakdown.memoryFiles,contextWindowSize));lines.push(fmtCategoryRow("Skills",breakdown.skills,contextWindowSize));if((breakdown.startupContext??0)>0){lines.push(fmtCategoryRow("Startup context",breakdown.startupContext,contextWindowSize))}if(hasTokenCount||breakdown.messages>0){lines.push(fmtCategoryRow("Messages",breakdown.messages,contextWindowSize));if((breakdown.unattributed??0)>0){lines.push(fmtCategoryRow("Unattributed",breakdown.unattributed,contextWindowSize))}}if(showDetails){const sortedBuiltin=[...builtinTools].sort((a,b)=>b.tokens-a.tokens);const sortedMcp=[...mcpTools].sort((a,b)=>b.tokens-a.tokens);const sortedMemory=[...memoryFiles].sort((a,b)=>b.tokens-a.tokens);const sortedSkills=[...skills].sort((a,b)=>{if(!a.loaded!==!b.loaded)return a.loaded?-1:1;return b.tokens+(b.bodyTokens??0)-(a.tokens+(a.bodyTokens??0))});if(sortedBuiltin.length>0){lines.push("");lines.push("**Built-in tools**");for(const tool of sortedBuiltin){lines.push(fmtCategoryRow(tool.name,tool.tokens,contextWindowSize," \u2514 "))}}if(sortedMcp.length>0){lines.push("");lines.push("**MCP tools**");for(const tool of sortedMcp){lines.push(fmtCategoryRow(tool.name,tool.tokens,contextWindowSize," \u2514 "))}}if(sortedMemory.length>0){lines.push("");lines.push("**Memory files**");for(const file of sortedMemory){lines.push(fmtCategoryRow(file.path,file.tokens,contextWindowSize," \u2514 "))}}if(sortedSkills.length>0){lines.push("");lines.push("**Skills**");for(const skill of sortedSkills){lines.push(fmtCategoryRow(skill.name,skill.tokens,contextWindowSize," \u2514 "));if(skill.loaded&&skill.bodyTokens&&skill.bodyTokens>0){lines.push(fmtCategoryRow("body loaded",skill.bodyTokens,contextWindowSize," \u2514 "))}}}}else{lines.push("");lines.push("*Run /context detail for per-item breakdown.*")}return lines.join("\n")}__name(formatContextUsageText,"formatContextUsageText");var contextCommand={name:"context",get description(){return t('Show context window usage breakdown. Use "/context detail" for per-item breakdown.')},kind:"built-in",supportedModes:["interactive","non_interactive","acp"],action:__name(async(context,args)=>{const normalizedArgs=args?.trim().toLowerCase();const showDetails=normalizedArgs==="detail"||normalizedArgs==="-d";const executionMode=context.executionMode??"interactive";const{config}=context.services;if(!config){if(executionMode==="interactive"){context.ui.addItem({type:"error",text:t("Config not loaded.")},Date.now());return}return{type:"message",messageType:"error",content:t("Config not loaded.")}}const contextUsageItem=await collectContextData(config,showDetails);if(executionMode==="interactive"){context.ui.addItem(contextUsageItem,Date.now());return}return{type:"message",messageType:"info",content:formatContextUsageText(contextUsageItem)}},"action"),subCommands:[{name:"detail",get description(){return t("Show per-item context usage breakdown.")},kind:"built-in",supportedModes:["interactive","non_interactive","acp"],action:__name(async context=>{await contextCommand.action(context,"detail")},"action")}]};export{EXTENSION_CONTEXT_BUDGET,parseExtensionRef,buildExtensionRef,matchExtensionByRef,sanitizeDisplayText,getSanitizedExtensionDisplayName,buildExtensionMentionContext,collectContextData,formatContextUsageText,contextCommand};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{getUserSettingsPath,v1ToV2Migration}from"./chunk-
|
|
3
|
+
import{getUserSettingsPath,v1ToV2Migration}from"./chunk-FHFBCG6N.js";import{require_strip_json_comments}from"./chunk-DOLUT3XC.js";import{getSystemDefaultsPath,getSystemSettingsPath}from"./chunk-PTHIQ7ZN.js";import{LoadedTrustedFolders,TrustLevel,getExplicitTrustLevel,getTrustedFoldersPath,isWorkflowAncestorDirectorySafe,parseJsoncObject}from"./chunk-W5D2T2JK.js";import{arePathsEquivalent}from"./chunk-IDXJIDME.js";import{ideContextStore}from"./chunk-LDXZT3SG.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name,__toESM}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import{createHash}from"node:crypto";import*as fs from"node:fs/promises";var import_strip_json_comments=__toESM(require_strip_json_comments(),1);var MAX_TRUSTED_FOLDERS_BYTES=1024*1024;var MAX_SETTINGS_BYTES=4*1024*1024;function evaluateDaemonWorkflowAncestorTrust(snapshot,query){const denied=__name(()=>query.ancestorDirs.map(()=>false),"denied");if(snapshot.settingsError)return denied();if(!snapshot.folderTrustEnabled){return query.ancestorDirs.map(isWorkflowAncestorDirectorySafe)}if(snapshot.trustedFoldersError||snapshot.ideTrust===false&&(arePathsEquivalent(query.workspaceCwd,query.ideScopeCwd)||arePathsEquivalent(query.canonicalTargetDir,query.ideScopeCwd))){return denied()}const folders=new LoadedTrustedFolders({path:getTrustedFoldersPath(),config:{...snapshot.trustedFolders}},[]);if(folders.isPathTrusted(query.canonicalTargetDir)!==true){return denied()}return query.ancestorDirs.map(directory=>folders.isPathTrusted(directory)===true)}__name(evaluateDaemonWorkflowAncestorTrust,"evaluateDaemonWorkflowAncestorTrust");function policyError(code,filePath,error){return{code,path:filePath,message:error instanceof Error?error.message:String(error)}}__name(policyError,"policyError");async function readJsonObject(filePath,maxBytes,requireRegularFile,retryMissing=false,allowTrailingComma=false){const delays=[0,50,200];let result={};for(const delay of delays){if(delay>0){await new Promise(resolve=>setTimeout(resolve,delay))}result=await readJsonObjectOnce(filePath,maxBytes,requireRegularFile,allowTrailingComma);if(!result.error&&(!result.missing||!retryMissing))return result}return result}__name(readJsonObject,"readJsonObject");async function readJsonObjectOnce(filePath,maxBytes,requireRegularFile,allowTrailingComma){let stat2;try{stat2=await fs.lstat(filePath)}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ENOENT"){return{value:{},missing:true}}return{error:policyError("trust_policy_unreadable",filePath,error)}}if(!requireRegularFile&&stat2.isSymbolicLink()){try{stat2=await fs.stat(filePath)}catch(error){return{error:policyError("trust_policy_unreadable",filePath,error)}}}if(requireRegularFile&&stat2.isSymbolicLink()||!stat2.isFile()){return{error:policyError("trust_policy_invalid",filePath,new Error("Trust policy input must be a regular file."))}}if(stat2.size>maxBytes){return{error:policyError("trust_policy_invalid",filePath,new Error(`Trust policy input exceeds ${maxBytes} bytes.`))}}try{const raw=await fs.readFile(filePath,"utf8");const parsed=allowTrailingComma?parseJsoncObject(raw):JSON.parse((0,import_strip_json_comments.default)(raw));if(typeof parsed!=="object"||parsed===null||Array.isArray(parsed)){throw new Error("Trust policy input must contain a JSON object.")}return{value:parsed}}catch(error){if(error instanceof Error&&"code"in error&&error.code==="ENOENT"){return{value:{},missing:true}}return{error:policyError("trust_policy_invalid",filePath,error)}}}__name(readJsonObjectOnce,"readJsonObjectOnce");function migrateFolderTrustSettings(value,scope){if(!value||!v1ToV2Migration.shouldMigrate(value))return value;return v1ToV2Migration.migrate(value,scope).settings}__name(migrateFolderTrustSettings,"migrateFolderTrustSettings");function folderTrustSetting(value,filePath){if(!value||!("security"in value))return{};const security=value?.["security"];if(typeof security!=="object"||security===null||Array.isArray(security)){return{error:policyError("trust_policy_invalid",filePath,new Error("`security` must be an object."))}}if(!("folderTrust"in security))return{};const folderTrust=security["folderTrust"];if(typeof folderTrust!=="object"||folderTrust===null||Array.isArray(folderTrust)){return{error:policyError("trust_policy_invalid",filePath,new Error("`security.folderTrust` must be an object."))}}if(!("enabled"in folderTrust))return{};const enabled=folderTrust["enabled"];if(typeof enabled==="boolean")return{value:enabled};return{error:policyError("trust_policy_invalid",filePath,new Error("`security.folderTrust.enabled` must be a boolean."))}}__name(folderTrustSetting,"folderTrustSetting");function parseTrustedFolders(value,filePath){const config={};for(const[rulePath,rawLevel]of Object.entries(value??{})){if(!Object.values(TrustLevel).includes(rawLevel)){return{config:{},error:policyError("trust_policy_invalid",filePath,new Error(`Invalid trust level for ${JSON.stringify(rulePath)}.`))}}config[rulePath]=rawLevel}return{config}}__name(parseTrustedFolders,"parseTrustedFolders");function semanticRevision(input){const sortedRules=Object.entries(input.trustedFolders).sort(([a],[b])=>a.localeCompare(b));return createHash("sha256").update(JSON.stringify({folderTrustEnabled:input.folderTrustEnabled,ideTrust:input.ideTrust??null,trustedFolders:sortedRules,settingsError:input.settingsError?.code??null,trustedFoldersError:input.trustedFoldersError?.code??null})).digest("hex")}__name(semanticRevision,"semanticRevision");async function readDaemonTrustPolicySnapshot(){const[user,system,systemDefaults]=await Promise.all([readJsonObject(getUserSettingsPath(),MAX_SETTINGS_BYTES,false),readJsonObject(getSystemSettingsPath(),MAX_SETTINGS_BYTES,false),readJsonObject(getSystemDefaultsPath(),MAX_SETTINGS_BYTES,false)]);const systemFolderTrust=folderTrustSetting(migrateFolderTrustSettings(system.value,"System"),getSystemSettingsPath());const userFolderTrust=folderTrustSetting(migrateFolderTrustSettings(user.value,"User"),getUserSettingsPath());const defaultsFolderTrust=folderTrustSetting(migrateFolderTrustSettings(systemDefaults.value,"SystemDefaults"),getSystemDefaultsPath());const settingsError=system.error??systemFolderTrust.error??user.error??userFolderTrust.error??systemDefaults.error??defaultsFolderTrust.error;const folderTrustEnabled=systemFolderTrust.value??userFolderTrust.value??defaultsFolderTrust.value??false;const trustedFoldersFile=await readJsonObject(getTrustedFoldersPath(),MAX_TRUSTED_FOLDERS_BYTES,true,folderTrustEnabled,true);const parsedTrustedFolders=parseTrustedFolders(trustedFoldersFile.value,getTrustedFoldersPath());const trustedFoldersError=trustedFoldersFile.error??parsedTrustedFolders.error;const ideTrust=ideContextStore.get()?.workspaceState?.isTrusted;const revision=semanticRevision({folderTrustEnabled,ideTrust,trustedFolders:parsedTrustedFolders.config,...settingsError?{settingsError}:{},...trustedFoldersError?{trustedFoldersError}:{}});return{revision,folderTrustEnabled,ideTrust,trustedFolders:Object.freeze({...parsedTrustedFolders.config}),...settingsError?{settingsError}:{},...trustedFoldersError?{trustedFoldersError}:{}}}__name(readDaemonTrustPolicySnapshot,"readDaemonTrustPolicySnapshot");function explicitTrustLevel(snapshot,workspaceCwd){return getExplicitTrustLevel(snapshot.trustedFolders,workspaceCwd)}__name(explicitTrustLevel,"explicitTrustLevel");function evaluateDaemonWorkspaceTrust(snapshot,workspaceCwd,processCwd=process.cwd()){if(snapshot.settingsError){return{state:"error",targetTrusted:false,source:"none",explicitTrustLevel:null,error:snapshot.settingsError}}if(!snapshot.folderTrustEnabled){return{state:"trusted",targetTrusted:true,source:"disabled",explicitTrustLevel:null}}if(snapshot.ideTrust!==void 0&&arePathsEquivalent(workspaceCwd,processCwd)){return{state:snapshot.ideTrust?"trusted":"untrusted",targetTrusted:snapshot.ideTrust,source:"ide",explicitTrustLevel:null}}if(snapshot.trustedFoldersError){return{state:"error",targetTrusted:false,source:"none",explicitTrustLevel:null,error:snapshot.trustedFoldersError}}const folders=new LoadedTrustedFolders({path:getTrustedFoldersPath(),config:{...snapshot.trustedFolders}},[]);const trusted=folders.isPathTrusted(workspaceCwd);return{state:trusted===true?"trusted":trusted===false?"untrusted":"unknown",targetTrusted:trusted===true,source:trusted===void 0?"none":"file",explicitTrustLevel:explicitTrustLevel(snapshot,workspaceCwd)}}__name(evaluateDaemonWorkspaceTrust,"evaluateDaemonWorkspaceTrust");export{evaluateDaemonWorkflowAncestorTrust,readDaemonTrustPolicySnapshot,evaluateDaemonWorkspaceTrust};
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright 2026 Qwen Team
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{GIT_COMMIT_INFO}from"./chunk-
|
|
3
|
+
import{GIT_COMMIT_INFO}from"./chunk-2WBKWPSO.js";import{formatAuxModelSelectorForDisplay}from"./chunk-L42NTHIT.js";import{getCliVersion}from"./chunk-BQQBFDBY.js";import{IdeClient}from"./chunk-LDXZT3SG.js";import{formatMemoryUsage}from"./chunk-NTRFETZB.js";import{createDebugLogger}from"./chunk-JAUJI56S.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();init_esbuild_shims();function formatExecutionSandbox(config){const policy=config?.getShellExecutionSandbox?.();if(!policy)return void 0;const effective=policy.effectiveBackend??"unresolved";const enforcement=policy.enforcement?` (${policy.enforcement}${policy.landlockAbi?`, ABI ${policy.landlockAbi}`:""})`:"";return`tools / ${policy.requestedBackend??"auto"} \u2192 ${effective}${enforcement} / ${policy.filesystem} / command network: ${policy.network}`}__name(formatExecutionSandbox,"formatExecutionSandbox");import process from"node:process";import os from"node:os";import{execFile}from"node:child_process";var debugLogger=createDebugLogger("STATUS");var VERSION_PROBE_TIMEOUT_MS=5e3;function probeVersion(binary){return new Promise(resolve=>{execFile(binary,["--version"],{timeout:VERSION_PROBE_TIMEOUT_MS,encoding:"utf-8"},(err,stdout)=>{if(err){resolve("unknown");return}resolve(typeof stdout==="string"?stdout.trim():"unknown")})})}__name(probeVersion,"probeVersion");async function getNpmVersion(){return probeVersion("npm")}__name(getNpmVersion,"getNpmVersion");async function getGitVersion(){return probeVersion("git")}__name(getGitVersion,"getGitVersion");async function getIdeClientName(context){if(!context.services.config?.getIdeMode()){return""}try{const ideClient=await IdeClient.getInstance();return ideClient?.getDetectedIdeDisplayName()??""}catch{return""}}__name(getIdeClientName,"getIdeClientName");function getSandboxEnv(stripPrefix=false){const sandbox=process.env["SANDBOX"];if(!sandbox||sandbox==="sandbox-exec"){if(sandbox==="sandbox-exec"){const profile=process.env["SEATBELT_PROFILE"]||"unknown";return`sandbox-exec (${profile})`}return"no sandbox"}if(stripPrefix){return sandbox.replace(/^qwen-(?:code-)?/,"")}return sandbox}__name(getSandboxEnv,"getSandboxEnv");async function getSystemInfo(context){const osPlatform=process.platform;const osArch=process.arch;const osRelease=os.release();const nodeVersion=process.version;const executionSandbox=formatExecutionSandbox(context.services.config);const npmVersion=executionSandbox?"not probed (tool execution sandbox active)":await getNpmVersion();const sandboxEnv=executionSandbox??getSandboxEnv();const modelVersion=context.services.config?.getModel()||"Unknown";const cliVersion=await getCliVersion();const selectedAuthType=context.services.config?.getAuthType()||"";const ideClient=await getIdeClientName(context);const sessionId=context.services.config?.getSessionId()||"unknown";const proxy=context.services.config?.getProxy();return{cliVersion,osPlatform,osArch,osRelease,nodeVersion,npmVersion,sandboxEnv,modelVersion,selectedAuthType,ideClient,sessionId,proxy}}__name(getSystemInfo,"getSystemInfo");async function getExtendedSystemInfo(context){const baseInfo=await getSystemInfo(context);const memoryUsage=formatMemoryUsage(process.memoryUsage().rss);const sandboxEnv=formatExecutionSandbox(context.services.config)??getSandboxEnv(true);const contentGeneratorConfig=baseInfo.selectedAuthType==="openai"||baseInfo.selectedAuthType==="openai-responses"||baseInfo.selectedAuthType==="anthropic"?context.services.config?.getContentGeneratorConfig():void 0;const baseUrl=contentGeneratorConfig?.baseUrl;const apiKeyEnvKey=contentGeneratorConfig?.apiKeyEnvKey;const gitCommit=GIT_COMMIT_INFO&&!["N/A"].includes(GIT_COMMIT_INFO)?GIT_COMMIT_INFO:void 0;const fastModelSetting=context.services.settings?.merged?.fastModel||void 0;const fastModel=fastModelSetting?formatAuxModelSelectorForDisplay(fastModelSetting):void 0;const lspStatus=getLspStatus(context);return{...baseInfo,sandboxEnv,memoryUsage,baseUrl,apiKeyEnvKey,gitCommit,fastModel,lspStatus}}__name(getExtendedSystemInfo,"getExtendedSystemInfo");function getLspStatus(context){try{const snapshot=context.services.config?.getLspStatusSnapshot?.();if(!snapshot){return void 0}if(context.services.config?.getDebugMode?.()){debugLogger.debug("LSP status snapshot for /status:",snapshot)}return formatLspStatusSnapshot(snapshot)}catch(error){if(context.services.config?.getDebugMode?.()){debugLogger.debug("Unable to read LSP status snapshot for /status:",error)}return void 0}}__name(getLspStatus,"getLspStatus");function formatLspStatusSnapshot(snapshot){if(!snapshot.enabled){return"disabled"}if(snapshot.initializationError){return`enabled, initialization failed: ${snapshot.initializationError}`}if(snapshot.statusUnavailable){return"enabled, status unavailable"}if(snapshot.configuredServers===0){return"enabled, no servers configured"}const details=[snapshot.failedServers>0?`${snapshot.failedServers} failed`:"",snapshot.inProgressServers>0?`${snapshot.inProgressServers} starting`:"",snapshot.notStartedServers>0?`${snapshot.notStartedServers} not started`:""].filter(Boolean);const detailText=details.length>0?` (${details.join(", ")})`:"";return`enabled, ${snapshot.readyServers}/${snapshot.configuredServers} ready${detailText}`}__name(formatLspStatusSnapshot,"formatLspStatusSnapshot");export{formatExecutionSandbox,getNpmVersion,getGitVersion,getExtendedSystemInfo};
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright 2026 Qwen Team
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Force strict mode and setup for ESM
|
|
2
2
|
"use strict";
|
|
3
|
-
import{msSinceLastInteraction}from"./chunk-UGLQO5K7.js";import{isValidSessionId}from"./chunk-LGFF5PJA.js";import{DEFAULT_OPENAI_LOG_RETENTION_DAYS}from"./chunk-TRRY3QMM.js";import{resolveOpenAILogDir}from"./chunk-LL42CQPA.js";import{FILE_HISTORY_DIR,getSubagentsRootDir}from"./chunk-RKPHDO42.js";import{createDebugLogger,sessionIdContext}from"./chunk-JAUJI56S.js";import{Storage}from"./chunk-EPODBRBP.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import{stat as stat3}from"node:fs/promises";import{createHash}from"node:crypto";import{join as join2}from"node:path";init_esbuild_shims();import{opendir,readdir,stat,rm,rmdir,unlink}from"node:fs/promises";import{join}from"node:path";var DEBUG_LOG_FILE_SUFFIX=".txt";var debugLogger=createDebugLogger("HOUSEKEEPING");var MS_PER_DAY=24*60*60*1e3;var MS_PER_HOUR=60*60*1e3;var MIN_DATE_MS=-864e13;var SWEEP_CONCURRENCY=20;function getCutoffDate(cleanupPeriodDays){const periodMs=cleanupPeriodDays>0?cleanupPeriodDays*MS_PER_DAY:MS_PER_HOUR;return new Date(Math.max(Date.now()-periodMs,MIN_DATE_MS))}__name(getCutoffDate,"getCutoffDate");async function sweepOldSessionDirs(root,opts){const result={removed:0,errors:0};const excludes=opts.excludeSessionIds??new Set;let entries;try{entries=await readdir(root,{withFileTypes:true})}catch(e){if(isENOENT(e))return result;debugLogger.error("readdir failed",e);return result}const sessionDirs=entries.filter(e=>e.isDirectory()&&!excludes.has(e.name)).map(e=>join(root,e.name));for(let i=0;i<sessionDirs.length;i+=SWEEP_CONCURRENCY){const batch=sessionDirs.slice(i,i+SWEEP_CONCURRENCY);await Promise.all(batch.map(async dir=>{try{const s=await stat(dir);if(s.mtime<opts.cutoffDate){await rm(dir,{recursive:true,force:true});result.removed++}}catch(err){result.errors++;debugLogger.error(`failed to sweep ${dir}`,err)}}))}if(opts.removeEmptyRoot!==false){await rmdir(root).catch(()=>{})}return result}__name(sweepOldSessionDirs,"sweepOldSessionDirs");async function cleanupOldFileHistoryBackups(opts){return sweepOldSessionDirs(join(Storage.getGlobalQwenDir(),FILE_HISTORY_DIR),opts)}__name(cleanupOldFileHistoryBackups,"cleanupOldFileHistoryBackups");async function cleanupOldSubagentTranscripts(opts){return sweepOldSessionDirs(opts.subagentsRoot,{...opts,removeEmptyRoot:false})}__name(cleanupOldSubagentTranscripts,"cleanupOldSubagentTranscripts");var OPENAI_LOG_FILE_PATTERN=/^openai-(\d{4}-\d{2}-\d{2})T\d{2}-\d{2}-\d{2}\.\d{3}Z-[a-f0-9]{8}(?:-[a-zA-Z0-9._](?:[a-zA-Z0-9._-]*[a-zA-Z0-9._])?)?\.json$/;async function cleanupOldOpenAILogs(opts){const result={removed:0,errors:0,completed:true};if(opts.signal?.aborted){result.completed=false;return result}let dir;try{dir=await opendir(opts.logDir)}catch(e){if(isENOENT(e))return result;debugLogger.error("opendir failed",e);throw e}const cutoffDay=opts.cutoffDate.toISOString().slice(0,10);let batch=[];for await(const entry of dir){if(opts.signal?.aborted){result.completed=false;break}const filenameDate=entry.isFile()?OPENAI_LOG_FILE_PATTERN.exec(entry.name)?.[1]:void 0;if(!filenameDate)continue;const filePath=join(opts.logDir,entry.name);batch.push((async()=>{try{let shouldRemove;if(filenameDate!==cutoffDay){shouldRemove=filenameDate<cutoffDay}else{const s=await stat(filePath);shouldRemove=s.mtime<opts.cutoffDate}if(shouldRemove){await unlink(filePath);result.removed++}}catch(err){if(isENOENT(err))return;result.errors++;debugLogger.error(`failed to sweep ${filePath}`,err)}})());if(batch.length===SWEEP_CONCURRENCY){await Promise.all(batch);batch=[]}}await Promise.all(batch);return result}__name(cleanupOldOpenAILogs,"cleanupOldOpenAILogs");function isENOENT(e){return e?.code==="ENOENT"}__name(isENOENT,"isENOENT");async function cleanupOldDebugLogs(opts){const result={removed:0,errors:0};const root=Storage.getGlobalDebugDir();const excludes=opts.excludeSessionIds??new Set;let entries;try{entries=await readdir(root,{withFileTypes:true})}catch(e){if(isENOENT(e))return result;debugLogger.error("readdir failed",e);return result}const logFiles=entries.flatMap(entry=>{if(!entry.isFile()||!entry.name.endsWith(DEBUG_LOG_FILE_SUFFIX)){return[]}const sessionId=entry.name.slice(0,-DEBUG_LOG_FILE_SUFFIX.length);if(!opts.isValidSessionId(sessionId)||excludes.has(sessionId)){return[]}return[join(root,entry.name)]});for(let i=0;i<logFiles.length;i+=SWEEP_CONCURRENCY){const batch=logFiles.slice(i,i+SWEEP_CONCURRENCY);await Promise.all(batch.map(async filePath=>{try{const s=await stat(filePath);if(s.mtime<opts.cutoffDate){await unlink(filePath);result.removed++}}catch(err){if(isENOENT(err))return;result.errors++;debugLogger.error(`failed to sweep ${filePath}`,err)}}))}return result}__name(cleanupOldDebugLogs,"cleanupOldDebugLogs");init_esbuild_shims();import{mkdir,open,stat as stat2,unlink as unlink2,writeFile}from"node:fs/promises";import{dirname}from"node:path";var debugLogger2=createDebugLogger("HOUSEKEEPING");var ONE_DAY_MS=24*60*60*1e3;var STALE_LOCK_MS=60*60*1e3;async function runThrottledOnce(opts,task){const minIntervalMs=opts.minIntervalMs??ONE_DAY_MS;const staleLockMs=opts.staleLockMs??STALE_LOCK_MS;await mkdir(dirname(opts.lockPath),{mode:448}).catch(()=>{});const firstFreshForMs=await markerFreshForMs(opts.markerPath,minIntervalMs,opts.name);if(firstFreshForMs!==void 0){return{status:"fresh",retryAfterMs:firstFreshForMs}}let acquired=await tryAcquire(opts.lockPath);if(!acquired){try{const s=await stat2(opts.lockPath);if(Date.now()-s.mtimeMs>staleLockMs){await unlink2(opts.lockPath).catch(()=>{});acquired=await tryAcquire(opts.lockPath)}}catch{acquired=await tryAcquire(opts.lockPath)}if(!acquired){debugLogger2.debug(`${opts.name}: skipping, lock held`);return{status:"locked"}}}try{const secondFreshForMs=await markerFreshForMs(opts.markerPath,minIntervalMs,opts.name);if(secondFreshForMs!==void 0){return{status:"fresh",retryAfterMs:secondFreshForMs}}let taskCompleted=false;try{taskCompleted=await task()!==false}finally{if(taskCompleted){try{await writeFile(opts.markerPath,new Date().toISOString())}catch(err){debugLogger2.debug(`${opts.name}: marker write failed (cleanup succeeded)`,err)}}}return{status:taskCompleted?"completed":"incomplete"}}finally{await unlink2(opts.lockPath).catch(()=>{debugLogger2.debug(`${opts.name}: lock unlink failed (harmless)`)})}}__name(runThrottledOnce,"runThrottledOnce");async function markerFreshForMs(markerPath,minIntervalMs,name){try{const s=await stat2(markerPath);const age=Date.now()-s.mtimeMs;if(age<minIntervalMs){debugLogger2.debug(`${name}: skipping, ran ${age}ms ago`);return minIntervalMs-age}}catch{}return void 0}__name(markerFreshForMs,"markerFreshForMs");async function tryAcquire(lockPath){try{const fh=await open(lockPath,"wx");await fh.close();return true}catch(e){if(e?.code==="EEXIST"){return false}throw e}}__name(tryAcquire,"tryAcquire");var debugLogger3=createDebugLogger("HOUSEKEEPING");var STARTUP_DELAY_MS=10*60*1e3;var RECURRING_INTERVAL_MS=24*60*60*1e3;var RECENT_INTERACTION_MS=60*1e3;var CATCHUP_THRESHOLD_MS=7*24*60*60*1e3;var STARTUP_DELAY_CATCHUP_MS=60*1e3;var NON_INTERACTIVE_LOCK_RETRY_MS=60*1e3;var NON_INTERACTIVE_FAILURE_RETRY_MS=10*60*1e3;var NON_INTERACTIVE_STOP_GRACE_MS=250;var FILE_HISTORY_MARKER=".file-history-cleanup";var SUBAGENT_MARKER=".subagent-cleanup";var OPENAI_LOGS_MARKER=".openai-logs-cleanup";var DEBUG_LOGS_MARKER=".debug-logs-cleanup";var PSEUDO_DEBUG_SESSION_STEMS=new Set(["transcript-replay","workspace-mcp-discovery"]);var started=false;var nonInteractiveJobs=new Map;var nonInteractiveQueue=[];var activeNonInteractiveJob;var activeNonInteractiveAbortController;var nonInteractiveWorker;var nonInteractiveStopping=false;var nonInteractiveStopPromise;function startBackgroundHousekeeping(config,settings){if(started)return;started=true;void scheduleFirstPass(config,settings).catch(err=>{started=false;debugLogger3.error("scheduleFirstPass failed; chain will retry on next start",err)})}__name(startBackgroundHousekeeping,"startBackgroundHousekeeping");async function scheduleFirstPass(config,settings){const delay=await getFirstPassDelay(config,settings);debugLogger3.debug(`first pass in ${delay/1e3}s`);setTimeout(()=>scheduleNextPass(config,settings),delay).unref()}__name(scheduleFirstPass,"scheduleFirstPass");async function getFirstPassDelay(config,settings){const qwenDir=Storage.getGlobalQwenDir();const markerPaths=[join2(qwenDir,FILE_HISTORY_MARKER),getDebugLogsMarkerPath(qwenDir,Storage.getGlobalDebugDir())];const openaiTarget=getOpenAILogCleanupTarget(config,settings);if(openaiTarget){markerPaths.push(getOpenAILogsMarkerPath(qwenDir,openaiTarget.logDir))}const catchUpStates=await Promise.all(markerPaths.map(needsCatchUp));return catchUpStates.some(Boolean)?STARTUP_DELAY_CATCHUP_MS:STARTUP_DELAY_MS}__name(getFirstPassDelay,"getFirstPassDelay");async function needsCatchUp(markerPath){try{const s=await stat3(markerPath);return Date.now()-s.mtimeMs>CATCHUP_THRESHOLD_MS}catch{return true}}__name(needsCatchUp,"needsCatchUp");function getSubagentMarkerPath(qwenDir,projectDir){const projectKey=createHash("sha256").update(projectDir).digest("hex").slice(0,16);return join2(qwenDir,`${SUBAGENT_MARKER}-${projectKey}`)}__name(getSubagentMarkerPath,"getSubagentMarkerPath");function getOpenAILogsMarkerPath(qwenDir,logDir){const logDirKey=createHash("sha256").update(logDir).digest("hex").slice(0,16);return join2(qwenDir,`${OPENAI_LOGS_MARKER}-${logDirKey}`)}__name(getOpenAILogsMarkerPath,"getOpenAILogsMarkerPath");function getDebugLogsMarkerPath(qwenDir,debugDir){const debugDirKey=createHash("sha256").update(debugDir).digest("hex").slice(0,16);return join2(qwenDir,`${DEBUG_LOGS_MARKER}-${debugDirKey}`)}__name(getDebugLogsMarkerPath,"getDebugLogsMarkerPath");function getOpenAILogCleanupTarget(config,settings){try{const customLogDir=config.getContentGeneratorConfig?.()?.openAILoggingDir??config.getModelsConfig?.()?.getGenerationConfig?.().openAILoggingDir??settings.merged.model?.openAILoggingDir;const systemRetention=settings.system?.settings.model?.openAILogRetentionDays;const workspaceRetention=settings.isTrusted?settings.workspace?.settings.model?.openAILogRetentionDays:void 0;if(customLogDir&&workspaceRetention!==void 0&&systemRetention===void 0){debugLogger3.error("workspace-scoped openAILogRetentionDays is unsafe with a custom openAILoggingDir; skipping cleanup");return void 0}const retentionDays=customLogDir?systemRetention??settings.user?.settings.model?.openAILogRetentionDays??settings.systemDefaults?.settings.model?.openAILogRetentionDays??DEFAULT_OPENAI_LOG_RETENTION_DAYS:settings.merged.model?.openAILogRetentionDays??DEFAULT_OPENAI_LOG_RETENTION_DAYS;return{logDir:resolveOpenAILogDir(customLogDir,config.getWorkingDir()),retentionDays}}catch(err){debugLogger3.error("failed to resolve OpenAI log cleanup target; skipping",err);return void 0}}__name(getOpenAILogCleanupTarget,"getOpenAILogCleanupTarget");function startNonInteractiveOpenAILogHousekeeping(config,settings){if(nonInteractiveStopping)return;sessionIdContext.exit(()=>{try{const target=getOpenAILogCleanupTarget(config,settings);if(!target||nonInteractiveJobs.has(target.logDir))return;const markerPath=getOpenAILogsMarkerPath(Storage.getGlobalQwenDir(),target.logDir);const job={target,markerPath,queued:false};nonInteractiveJobs.set(target.logDir,job);enqueueNonInteractiveJob(job)}catch(err){debugLogger3.error("failed to start non-interactive OpenAI log cleanup; skipping",err)}})}__name(startNonInteractiveOpenAILogHousekeeping,"startNonInteractiveOpenAILogHousekeeping");function stopNonInteractiveOpenAILogHousekeeping(){if(nonInteractiveStopPromise)return nonInteractiveStopPromise;nonInteractiveStopping=true;for(const job of nonInteractiveJobs.values()){if(job.timer){clearTimeout(job.timer);job.timer=void 0}job.queued=false}nonInteractiveQueue.length=0;activeNonInteractiveAbortController?.abort();nonInteractiveStopPromise=waitForNonInteractiveWorkerToStop();return nonInteractiveStopPromise}__name(stopNonInteractiveOpenAILogHousekeeping,"stopNonInteractiveOpenAILogHousekeeping");function enqueueNonInteractiveJob(job){if(nonInteractiveStopping||job.queued||activeNonInteractiveJob===job){return}job.queued=true;nonInteractiveQueue.push(job);startNonInteractiveWorker()}__name(enqueueNonInteractiveJob,"enqueueNonInteractiveJob");function startNonInteractiveWorker(){if(nonInteractiveWorker||nonInteractiveStopping)return;nonInteractiveWorker=drainNonInteractiveQueue().catch(err=>{debugLogger3.error("non-interactive OpenAI log worker failed",err)}).finally(()=>{nonInteractiveWorker=void 0;if(nonInteractiveQueue.length>0&&!nonInteractiveStopping){startNonInteractiveWorker()}})}__name(startNonInteractiveWorker,"startNonInteractiveWorker");async function drainNonInteractiveQueue(){while(!nonInteractiveStopping){const job=nonInteractiveQueue.shift();if(!job)return;job.queued=false;activeNonInteractiveJob=job;const abortController=new AbortController;activeNonInteractiveAbortController=abortController;try{const result=await runOpenAILogCleanup(job.target,job.markerPath,abortController.signal);if(nonInteractiveStopping)continue;switch(result.status){case"completed":scheduleNonInteractiveJob(job,RECURRING_INTERVAL_MS);break;case"fresh":scheduleNonInteractiveJob(job,Math.min(RECURRING_INTERVAL_MS,Math.max(NON_INTERACTIVE_LOCK_RETRY_MS,result.retryAfterMs)));break;case"locked":scheduleNonInteractiveJob(job,NON_INTERACTIVE_LOCK_RETRY_MS);break;case"incomplete":break;default:break}}catch(err){debugLogger3.error(`non-interactive OpenAI log cleanup failed for ${job.target.logDir}`,err);if(!nonInteractiveStopping){scheduleNonInteractiveJob(job,NON_INTERACTIVE_FAILURE_RETRY_MS)}}finally{activeNonInteractiveJob=void 0;activeNonInteractiveAbortController=void 0}}}__name(drainNonInteractiveQueue,"drainNonInteractiveQueue");async function runOpenAILogCleanup(target,markerPath,signal){return runThrottledOnce({name:"openai-logs-cleanup",markerPath,lockPath:markerPath+".lock"},async()=>{const r=await cleanupOldOpenAILogs({logDir:target.logDir,cutoffDate:getCutoffDate(target.retentionDays),signal});debugLogger3.debug(`openai-logs: removed=${r.removed} errors=${r.errors} completed=${r.completed}`);return r.completed?void 0:false})}__name(runOpenAILogCleanup,"runOpenAILogCleanup");function scheduleNonInteractiveJob(job,delayMs){if(nonInteractiveStopping)return;job.timer=setTimeout(()=>{job.timer=void 0;enqueueNonInteractiveJob(job)},delayMs);job.timer.unref()}__name(scheduleNonInteractiveJob,"scheduleNonInteractiveJob");async function waitForNonInteractiveWorkerToStop(){const worker=nonInteractiveWorker;if(!worker){nonInteractiveJobs.clear();return}let timeout;try{await Promise.race([worker,new Promise(resolve=>{timeout=setTimeout(resolve,NON_INTERACTIVE_STOP_GRACE_MS)})])}finally{if(timeout)clearTimeout(timeout);nonInteractiveJobs.clear()}}__name(waitForNonInteractiveWorkerToStop,"waitForNonInteractiveWorkerToStop");async function runPass(config,settings){if(msSinceLastInteraction()<RECENT_INTERACTION_MS){debugLogger3.debug("user active, deferring 10 min");setTimeout(()=>scheduleNextPass(config,settings),STARTUP_DELAY_MS).unref();return}try{await runHousekeeping(config,settings)}catch(err){debugLogger3.error("housekeeping pass failed; will retry next cycle",err)}setTimeout(()=>scheduleNextPass(config,settings),RECURRING_INTERVAL_MS).unref()}__name(runPass,"runPass");function scheduleNextPass(config,settings){void runPass(config,settings).catch(err=>{debugLogger3.error("runPass rejected unexpectedly",err)})}__name(scheduleNextPass,"scheduleNextPass");async function runHousekeeping(config,settings){const days=settings.merged.general?.cleanupPeriodDays??30;const cutoff=getCutoffDate(days);const currentSessionId=config.getSessionId();const qwenDir=Storage.getGlobalQwenDir();await runThrottledOnce({name:"file-history-cleanup",markerPath:join2(qwenDir,FILE_HISTORY_MARKER),lockPath:join2(qwenDir,FILE_HISTORY_MARKER+".lock")},async()=>{const r=await cleanupOldFileHistoryBackups({cutoffDate:cutoff,excludeSessionIds:new Set([currentSessionId])});debugLogger3.debug(`file-history: removed=${r.removed} errors=${r.errors}`)});const debugLogsMarkerPath=getDebugLogsMarkerPath(qwenDir,Storage.getGlobalDebugDir());await runThrottledOnce({name:"debug-logs-cleanup",markerPath:debugLogsMarkerPath,lockPath:debugLogsMarkerPath+".lock"},async()=>{const r=await cleanupOldDebugLogs({cutoffDate:cutoff,excludeSessionIds:new Set([currentSessionId]),isValidSessionId:__name(v=>isValidSessionId(v)||PSEUDO_DEBUG_SESSION_STEMS.has(v),"isValidSessionId")});debugLogger3.debug(`debug-logs: removed=${r.removed} errors=${r.errors}`)});const projectDir=config.storage?.getProjectDir?.();if(projectDir){const markerPath=getSubagentMarkerPath(qwenDir,projectDir);await runThrottledOnce({name:"subagent-cleanup",markerPath,lockPath:markerPath+".lock"},async()=>{const r=await cleanupOldSubagentTranscripts({cutoffDate:cutoff,excludeSessionIds:new Set([currentSessionId]),subagentsRoot:getSubagentsRootDir(projectDir)});debugLogger3.debug(`subagents: removed=${r.removed} errors=${r.errors}`)})}const openaiTarget=getOpenAILogCleanupTarget(config,settings);if(openaiTarget){await runOpenAILogCleanup(openaiTarget,getOpenAILogsMarkerPath(qwenDir,openaiTarget.logDir))}}__name(runHousekeeping,"runHousekeeping");function _resetForTesting(){started=false}__name(_resetForTesting,"_resetForTesting");async function _resetNonInteractiveForTesting(){nonInteractiveStopping=true;for(const job of nonInteractiveJobs.values()){if(job.timer)clearTimeout(job.timer)}nonInteractiveQueue.length=0;activeNonInteractiveAbortController?.abort();await nonInteractiveWorker;nonInteractiveJobs.clear();activeNonInteractiveJob=void 0;activeNonInteractiveAbortController=void 0;nonInteractiveWorker=void 0;nonInteractiveStopping=false;nonInteractiveStopPromise=void 0}__name(_resetNonInteractiveForTesting,"_resetNonInteractiveForTesting");var _needsCatchUpForTesting=needsCatchUp;var _getFirstPassDelayForTesting=getFirstPassDelay;var _runHousekeepingForTesting=runHousekeeping;var _runPassForTesting=runPass;var _FILE_HISTORY_MARKER_FOR_TESTING=FILE_HISTORY_MARKER;var _getDebugLogsMarkerPathForTesting=getDebugLogsMarkerPath;var _getSubagentMarkerPathForTesting=getSubagentMarkerPath;var _getOpenAILogsMarkerPathForTesting=getOpenAILogsMarkerPath;export{startBackgroundHousekeeping,startNonInteractiveOpenAILogHousekeeping,stopNonInteractiveOpenAILogHousekeeping,_resetForTesting,_resetNonInteractiveForTesting,_needsCatchUpForTesting,_getFirstPassDelayForTesting,_runHousekeepingForTesting,_runPassForTesting,_FILE_HISTORY_MARKER_FOR_TESTING,_getDebugLogsMarkerPathForTesting,_getSubagentMarkerPathForTesting,_getOpenAILogsMarkerPathForTesting};
|
|
3
|
+
import{msSinceLastInteraction}from"./chunk-UGLQO5K7.js";import{isValidSessionId}from"./chunk-LGFF5PJA.js";import{DEFAULT_OPENAI_LOG_RETENTION_DAYS}from"./chunk-RL57IU47.js";import{resolveOpenAILogDir}from"./chunk-LL42CQPA.js";import{FILE_HISTORY_DIR,getSubagentsRootDir}from"./chunk-LDXZT3SG.js";import{createDebugLogger,sessionIdContext}from"./chunk-JAUJI56S.js";import{Storage}from"./chunk-EPODBRBP.js";import{init_esbuild_shims}from"./chunk-VKDAXTCZ.js";import{__name}from"./chunk-KBWJGX7I.js";init_esbuild_shims();import{stat as stat3}from"node:fs/promises";import{createHash}from"node:crypto";import{join as join2}from"node:path";init_esbuild_shims();import{opendir,readdir,stat,rm,rmdir,unlink}from"node:fs/promises";import{join}from"node:path";var DEBUG_LOG_FILE_SUFFIX=".txt";var debugLogger=createDebugLogger("HOUSEKEEPING");var MS_PER_DAY=24*60*60*1e3;var MS_PER_HOUR=60*60*1e3;var MIN_DATE_MS=-864e13;var SWEEP_CONCURRENCY=20;function getCutoffDate(cleanupPeriodDays){const periodMs=cleanupPeriodDays>0?cleanupPeriodDays*MS_PER_DAY:MS_PER_HOUR;return new Date(Math.max(Date.now()-periodMs,MIN_DATE_MS))}__name(getCutoffDate,"getCutoffDate");async function sweepOldSessionDirs(root,opts){const result={removed:0,errors:0};const excludes=opts.excludeSessionIds??new Set;let entries;try{entries=await readdir(root,{withFileTypes:true})}catch(e){if(isENOENT(e))return result;debugLogger.error("readdir failed",e);return result}const sessionDirs=entries.filter(e=>e.isDirectory()&&!excludes.has(e.name)).map(e=>join(root,e.name));for(let i=0;i<sessionDirs.length;i+=SWEEP_CONCURRENCY){const batch=sessionDirs.slice(i,i+SWEEP_CONCURRENCY);await Promise.all(batch.map(async dir=>{try{const s=await stat(dir);if(s.mtime<opts.cutoffDate){await rm(dir,{recursive:true,force:true});result.removed++}}catch(err){result.errors++;debugLogger.error(`failed to sweep ${dir}`,err)}}))}if(opts.removeEmptyRoot!==false){await rmdir(root).catch(()=>{})}return result}__name(sweepOldSessionDirs,"sweepOldSessionDirs");async function cleanupOldFileHistoryBackups(opts){return sweepOldSessionDirs(join(Storage.getGlobalQwenDir(),FILE_HISTORY_DIR),opts)}__name(cleanupOldFileHistoryBackups,"cleanupOldFileHistoryBackups");async function cleanupOldSubagentTranscripts(opts){return sweepOldSessionDirs(opts.subagentsRoot,{...opts,removeEmptyRoot:false})}__name(cleanupOldSubagentTranscripts,"cleanupOldSubagentTranscripts");var OPENAI_LOG_FILE_PATTERN=/^openai-(\d{4}-\d{2}-\d{2})T\d{2}-\d{2}-\d{2}\.\d{3}Z-[a-f0-9]{8}(?:-[a-zA-Z0-9._](?:[a-zA-Z0-9._-]*[a-zA-Z0-9._])?)?\.json$/;async function cleanupOldOpenAILogs(opts){const result={removed:0,errors:0,completed:true};if(opts.signal?.aborted){result.completed=false;return result}let dir;try{dir=await opendir(opts.logDir)}catch(e){if(isENOENT(e))return result;debugLogger.error("opendir failed",e);throw e}const cutoffDay=opts.cutoffDate.toISOString().slice(0,10);let batch=[];for await(const entry of dir){if(opts.signal?.aborted){result.completed=false;break}const filenameDate=entry.isFile()?OPENAI_LOG_FILE_PATTERN.exec(entry.name)?.[1]:void 0;if(!filenameDate)continue;const filePath=join(opts.logDir,entry.name);batch.push((async()=>{try{let shouldRemove;if(filenameDate!==cutoffDay){shouldRemove=filenameDate<cutoffDay}else{const s=await stat(filePath);shouldRemove=s.mtime<opts.cutoffDate}if(shouldRemove){await unlink(filePath);result.removed++}}catch(err){if(isENOENT(err))return;result.errors++;debugLogger.error(`failed to sweep ${filePath}`,err)}})());if(batch.length===SWEEP_CONCURRENCY){await Promise.all(batch);batch=[]}}await Promise.all(batch);return result}__name(cleanupOldOpenAILogs,"cleanupOldOpenAILogs");function isENOENT(e){return e?.code==="ENOENT"}__name(isENOENT,"isENOENT");async function cleanupOldDebugLogs(opts){const result={removed:0,errors:0};const root=Storage.getGlobalDebugDir();const excludes=opts.excludeSessionIds??new Set;let entries;try{entries=await readdir(root,{withFileTypes:true})}catch(e){if(isENOENT(e))return result;debugLogger.error("readdir failed",e);return result}const logFiles=entries.flatMap(entry=>{if(!entry.isFile()||!entry.name.endsWith(DEBUG_LOG_FILE_SUFFIX)){return[]}const sessionId=entry.name.slice(0,-DEBUG_LOG_FILE_SUFFIX.length);if(!opts.isValidSessionId(sessionId)||excludes.has(sessionId)){return[]}return[join(root,entry.name)]});for(let i=0;i<logFiles.length;i+=SWEEP_CONCURRENCY){const batch=logFiles.slice(i,i+SWEEP_CONCURRENCY);await Promise.all(batch.map(async filePath=>{try{const s=await stat(filePath);if(s.mtime<opts.cutoffDate){await unlink(filePath);result.removed++}}catch(err){if(isENOENT(err))return;result.errors++;debugLogger.error(`failed to sweep ${filePath}`,err)}}))}return result}__name(cleanupOldDebugLogs,"cleanupOldDebugLogs");init_esbuild_shims();import{mkdir,open,stat as stat2,unlink as unlink2,writeFile}from"node:fs/promises";import{dirname}from"node:path";var debugLogger2=createDebugLogger("HOUSEKEEPING");var ONE_DAY_MS=24*60*60*1e3;var STALE_LOCK_MS=60*60*1e3;async function runThrottledOnce(opts,task){const minIntervalMs=opts.minIntervalMs??ONE_DAY_MS;const staleLockMs=opts.staleLockMs??STALE_LOCK_MS;await mkdir(dirname(opts.lockPath),{mode:448}).catch(()=>{});const firstFreshForMs=await markerFreshForMs(opts.markerPath,minIntervalMs,opts.name);if(firstFreshForMs!==void 0){return{status:"fresh",retryAfterMs:firstFreshForMs}}let acquired=await tryAcquire(opts.lockPath);if(!acquired){try{const s=await stat2(opts.lockPath);if(Date.now()-s.mtimeMs>staleLockMs){await unlink2(opts.lockPath).catch(()=>{});acquired=await tryAcquire(opts.lockPath)}}catch{acquired=await tryAcquire(opts.lockPath)}if(!acquired){debugLogger2.debug(`${opts.name}: skipping, lock held`);return{status:"locked"}}}try{const secondFreshForMs=await markerFreshForMs(opts.markerPath,minIntervalMs,opts.name);if(secondFreshForMs!==void 0){return{status:"fresh",retryAfterMs:secondFreshForMs}}let taskCompleted=false;try{taskCompleted=await task()!==false}finally{if(taskCompleted){try{await writeFile(opts.markerPath,new Date().toISOString())}catch(err){debugLogger2.debug(`${opts.name}: marker write failed (cleanup succeeded)`,err)}}}return{status:taskCompleted?"completed":"incomplete"}}finally{await unlink2(opts.lockPath).catch(()=>{debugLogger2.debug(`${opts.name}: lock unlink failed (harmless)`)})}}__name(runThrottledOnce,"runThrottledOnce");async function markerFreshForMs(markerPath,minIntervalMs,name){try{const s=await stat2(markerPath);const age=Date.now()-s.mtimeMs;if(age<minIntervalMs){debugLogger2.debug(`${name}: skipping, ran ${age}ms ago`);return minIntervalMs-age}}catch{}return void 0}__name(markerFreshForMs,"markerFreshForMs");async function tryAcquire(lockPath){try{const fh=await open(lockPath,"wx");await fh.close();return true}catch(e){if(e?.code==="EEXIST"){return false}throw e}}__name(tryAcquire,"tryAcquire");var debugLogger3=createDebugLogger("HOUSEKEEPING");var STARTUP_DELAY_MS=10*60*1e3;var RECURRING_INTERVAL_MS=24*60*60*1e3;var RECENT_INTERACTION_MS=60*1e3;var CATCHUP_THRESHOLD_MS=7*24*60*60*1e3;var STARTUP_DELAY_CATCHUP_MS=60*1e3;var NON_INTERACTIVE_LOCK_RETRY_MS=60*1e3;var NON_INTERACTIVE_FAILURE_RETRY_MS=10*60*1e3;var NON_INTERACTIVE_STOP_GRACE_MS=250;var FILE_HISTORY_MARKER=".file-history-cleanup";var SUBAGENT_MARKER=".subagent-cleanup";var OPENAI_LOGS_MARKER=".openai-logs-cleanup";var DEBUG_LOGS_MARKER=".debug-logs-cleanup";var PSEUDO_DEBUG_SESSION_STEMS=new Set(["transcript-replay","workspace-mcp-discovery"]);var started=false;var nonInteractiveJobs=new Map;var nonInteractiveQueue=[];var activeNonInteractiveJob;var activeNonInteractiveAbortController;var nonInteractiveWorker;var nonInteractiveStopping=false;var nonInteractiveStopPromise;function startBackgroundHousekeeping(config,settings){if(started)return;started=true;void scheduleFirstPass(config,settings).catch(err=>{started=false;debugLogger3.error("scheduleFirstPass failed; chain will retry on next start",err)})}__name(startBackgroundHousekeeping,"startBackgroundHousekeeping");async function scheduleFirstPass(config,settings){const delay=await getFirstPassDelay(config,settings);debugLogger3.debug(`first pass in ${delay/1e3}s`);setTimeout(()=>scheduleNextPass(config,settings),delay).unref()}__name(scheduleFirstPass,"scheduleFirstPass");async function getFirstPassDelay(config,settings){const qwenDir=Storage.getGlobalQwenDir();const markerPaths=[join2(qwenDir,FILE_HISTORY_MARKER),getDebugLogsMarkerPath(qwenDir,Storage.getGlobalDebugDir())];const openaiTarget=getOpenAILogCleanupTarget(config,settings);if(openaiTarget){markerPaths.push(getOpenAILogsMarkerPath(qwenDir,openaiTarget.logDir))}const catchUpStates=await Promise.all(markerPaths.map(needsCatchUp));return catchUpStates.some(Boolean)?STARTUP_DELAY_CATCHUP_MS:STARTUP_DELAY_MS}__name(getFirstPassDelay,"getFirstPassDelay");async function needsCatchUp(markerPath){try{const s=await stat3(markerPath);return Date.now()-s.mtimeMs>CATCHUP_THRESHOLD_MS}catch{return true}}__name(needsCatchUp,"needsCatchUp");function getSubagentMarkerPath(qwenDir,projectDir){const projectKey=createHash("sha256").update(projectDir).digest("hex").slice(0,16);return join2(qwenDir,`${SUBAGENT_MARKER}-${projectKey}`)}__name(getSubagentMarkerPath,"getSubagentMarkerPath");function getOpenAILogsMarkerPath(qwenDir,logDir){const logDirKey=createHash("sha256").update(logDir).digest("hex").slice(0,16);return join2(qwenDir,`${OPENAI_LOGS_MARKER}-${logDirKey}`)}__name(getOpenAILogsMarkerPath,"getOpenAILogsMarkerPath");function getDebugLogsMarkerPath(qwenDir,debugDir){const debugDirKey=createHash("sha256").update(debugDir).digest("hex").slice(0,16);return join2(qwenDir,`${DEBUG_LOGS_MARKER}-${debugDirKey}`)}__name(getDebugLogsMarkerPath,"getDebugLogsMarkerPath");function getOpenAILogCleanupTarget(config,settings){try{const customLogDir=config.getContentGeneratorConfig?.()?.openAILoggingDir??config.getModelsConfig?.()?.getGenerationConfig?.().openAILoggingDir??settings.merged.model?.openAILoggingDir;const systemRetention=settings.system?.settings.model?.openAILogRetentionDays;const workspaceRetention=settings.isTrusted?settings.workspace?.settings.model?.openAILogRetentionDays:void 0;if(customLogDir&&workspaceRetention!==void 0&&systemRetention===void 0){debugLogger3.error("workspace-scoped openAILogRetentionDays is unsafe with a custom openAILoggingDir; skipping cleanup");return void 0}const retentionDays=customLogDir?systemRetention??settings.user?.settings.model?.openAILogRetentionDays??settings.systemDefaults?.settings.model?.openAILogRetentionDays??DEFAULT_OPENAI_LOG_RETENTION_DAYS:settings.merged.model?.openAILogRetentionDays??DEFAULT_OPENAI_LOG_RETENTION_DAYS;return{logDir:resolveOpenAILogDir(customLogDir,config.getWorkingDir()),retentionDays}}catch(err){debugLogger3.error("failed to resolve OpenAI log cleanup target; skipping",err);return void 0}}__name(getOpenAILogCleanupTarget,"getOpenAILogCleanupTarget");function startNonInteractiveOpenAILogHousekeeping(config,settings){if(nonInteractiveStopping)return;sessionIdContext.exit(()=>{try{const target=getOpenAILogCleanupTarget(config,settings);if(!target||nonInteractiveJobs.has(target.logDir))return;const markerPath=getOpenAILogsMarkerPath(Storage.getGlobalQwenDir(),target.logDir);const job={target,markerPath,queued:false};nonInteractiveJobs.set(target.logDir,job);enqueueNonInteractiveJob(job)}catch(err){debugLogger3.error("failed to start non-interactive OpenAI log cleanup; skipping",err)}})}__name(startNonInteractiveOpenAILogHousekeeping,"startNonInteractiveOpenAILogHousekeeping");function stopNonInteractiveOpenAILogHousekeeping(){if(nonInteractiveStopPromise)return nonInteractiveStopPromise;nonInteractiveStopping=true;for(const job of nonInteractiveJobs.values()){if(job.timer){clearTimeout(job.timer);job.timer=void 0}job.queued=false}nonInteractiveQueue.length=0;activeNonInteractiveAbortController?.abort();nonInteractiveStopPromise=waitForNonInteractiveWorkerToStop();return nonInteractiveStopPromise}__name(stopNonInteractiveOpenAILogHousekeeping,"stopNonInteractiveOpenAILogHousekeeping");function enqueueNonInteractiveJob(job){if(nonInteractiveStopping||job.queued||activeNonInteractiveJob===job){return}job.queued=true;nonInteractiveQueue.push(job);startNonInteractiveWorker()}__name(enqueueNonInteractiveJob,"enqueueNonInteractiveJob");function startNonInteractiveWorker(){if(nonInteractiveWorker||nonInteractiveStopping)return;nonInteractiveWorker=drainNonInteractiveQueue().catch(err=>{debugLogger3.error("non-interactive OpenAI log worker failed",err)}).finally(()=>{nonInteractiveWorker=void 0;if(nonInteractiveQueue.length>0&&!nonInteractiveStopping){startNonInteractiveWorker()}})}__name(startNonInteractiveWorker,"startNonInteractiveWorker");async function drainNonInteractiveQueue(){while(!nonInteractiveStopping){const job=nonInteractiveQueue.shift();if(!job)return;job.queued=false;activeNonInteractiveJob=job;const abortController=new AbortController;activeNonInteractiveAbortController=abortController;try{const result=await runOpenAILogCleanup(job.target,job.markerPath,abortController.signal);if(nonInteractiveStopping)continue;switch(result.status){case"completed":scheduleNonInteractiveJob(job,RECURRING_INTERVAL_MS);break;case"fresh":scheduleNonInteractiveJob(job,Math.min(RECURRING_INTERVAL_MS,Math.max(NON_INTERACTIVE_LOCK_RETRY_MS,result.retryAfterMs)));break;case"locked":scheduleNonInteractiveJob(job,NON_INTERACTIVE_LOCK_RETRY_MS);break;case"incomplete":break;default:break}}catch(err){debugLogger3.error(`non-interactive OpenAI log cleanup failed for ${job.target.logDir}`,err);if(!nonInteractiveStopping){scheduleNonInteractiveJob(job,NON_INTERACTIVE_FAILURE_RETRY_MS)}}finally{activeNonInteractiveJob=void 0;activeNonInteractiveAbortController=void 0}}}__name(drainNonInteractiveQueue,"drainNonInteractiveQueue");async function runOpenAILogCleanup(target,markerPath,signal){return runThrottledOnce({name:"openai-logs-cleanup",markerPath,lockPath:markerPath+".lock"},async()=>{const r=await cleanupOldOpenAILogs({logDir:target.logDir,cutoffDate:getCutoffDate(target.retentionDays),signal});debugLogger3.debug(`openai-logs: removed=${r.removed} errors=${r.errors} completed=${r.completed}`);return r.completed?void 0:false})}__name(runOpenAILogCleanup,"runOpenAILogCleanup");function scheduleNonInteractiveJob(job,delayMs){if(nonInteractiveStopping)return;job.timer=setTimeout(()=>{job.timer=void 0;enqueueNonInteractiveJob(job)},delayMs);job.timer.unref()}__name(scheduleNonInteractiveJob,"scheduleNonInteractiveJob");async function waitForNonInteractiveWorkerToStop(){const worker=nonInteractiveWorker;if(!worker){nonInteractiveJobs.clear();return}let timeout;try{await Promise.race([worker,new Promise(resolve=>{timeout=setTimeout(resolve,NON_INTERACTIVE_STOP_GRACE_MS)})])}finally{if(timeout)clearTimeout(timeout);nonInteractiveJobs.clear()}}__name(waitForNonInteractiveWorkerToStop,"waitForNonInteractiveWorkerToStop");async function runPass(config,settings){if(msSinceLastInteraction()<RECENT_INTERACTION_MS){debugLogger3.debug("user active, deferring 10 min");setTimeout(()=>scheduleNextPass(config,settings),STARTUP_DELAY_MS).unref();return}try{await runHousekeeping(config,settings)}catch(err){debugLogger3.error("housekeeping pass failed; will retry next cycle",err)}setTimeout(()=>scheduleNextPass(config,settings),RECURRING_INTERVAL_MS).unref()}__name(runPass,"runPass");function scheduleNextPass(config,settings){void runPass(config,settings).catch(err=>{debugLogger3.error("runPass rejected unexpectedly",err)})}__name(scheduleNextPass,"scheduleNextPass");async function runHousekeeping(config,settings){const days=settings.merged.general?.cleanupPeriodDays??30;const cutoff=getCutoffDate(days);const currentSessionId=config.getSessionId();const qwenDir=Storage.getGlobalQwenDir();await runThrottledOnce({name:"file-history-cleanup",markerPath:join2(qwenDir,FILE_HISTORY_MARKER),lockPath:join2(qwenDir,FILE_HISTORY_MARKER+".lock")},async()=>{const r=await cleanupOldFileHistoryBackups({cutoffDate:cutoff,excludeSessionIds:new Set([currentSessionId])});debugLogger3.debug(`file-history: removed=${r.removed} errors=${r.errors}`)});const debugLogsMarkerPath=getDebugLogsMarkerPath(qwenDir,Storage.getGlobalDebugDir());await runThrottledOnce({name:"debug-logs-cleanup",markerPath:debugLogsMarkerPath,lockPath:debugLogsMarkerPath+".lock"},async()=>{const r=await cleanupOldDebugLogs({cutoffDate:cutoff,excludeSessionIds:new Set([currentSessionId]),isValidSessionId:__name(v=>isValidSessionId(v)||PSEUDO_DEBUG_SESSION_STEMS.has(v),"isValidSessionId")});debugLogger3.debug(`debug-logs: removed=${r.removed} errors=${r.errors}`)});const projectDir=config.storage?.getProjectDir?.();if(projectDir){const markerPath=getSubagentMarkerPath(qwenDir,projectDir);await runThrottledOnce({name:"subagent-cleanup",markerPath,lockPath:markerPath+".lock"},async()=>{const r=await cleanupOldSubagentTranscripts({cutoffDate:cutoff,excludeSessionIds:new Set([currentSessionId]),subagentsRoot:getSubagentsRootDir(projectDir)});debugLogger3.debug(`subagents: removed=${r.removed} errors=${r.errors}`)})}const openaiTarget=getOpenAILogCleanupTarget(config,settings);if(openaiTarget){await runOpenAILogCleanup(openaiTarget,getOpenAILogsMarkerPath(qwenDir,openaiTarget.logDir))}}__name(runHousekeeping,"runHousekeeping");function _resetForTesting(){started=false}__name(_resetForTesting,"_resetForTesting");async function _resetNonInteractiveForTesting(){nonInteractiveStopping=true;for(const job of nonInteractiveJobs.values()){if(job.timer)clearTimeout(job.timer)}nonInteractiveQueue.length=0;activeNonInteractiveAbortController?.abort();await nonInteractiveWorker;nonInteractiveJobs.clear();activeNonInteractiveJob=void 0;activeNonInteractiveAbortController=void 0;nonInteractiveWorker=void 0;nonInteractiveStopping=false;nonInteractiveStopPromise=void 0}__name(_resetNonInteractiveForTesting,"_resetNonInteractiveForTesting");var _needsCatchUpForTesting=needsCatchUp;var _getFirstPassDelayForTesting=getFirstPassDelay;var _runHousekeepingForTesting=runHousekeeping;var _runPassForTesting=runPass;var _FILE_HISTORY_MARKER_FOR_TESTING=FILE_HISTORY_MARKER;var _getDebugLogsMarkerPathForTesting=getDebugLogsMarkerPath;var _getSubagentMarkerPathForTesting=getSubagentMarkerPath;var _getOpenAILogsMarkerPathForTesting=getOpenAILogsMarkerPath;export{startBackgroundHousekeeping,startNonInteractiveOpenAILogHousekeeping,stopNonInteractiveOpenAILogHousekeeping,_resetForTesting,_resetNonInteractiveForTesting,_needsCatchUpForTesting,_getFirstPassDelayForTesting,_runHousekeepingForTesting,_runPassForTesting,_FILE_HISTORY_MARKER_FOR_TESTING,_getDebugLogsMarkerPathForTesting,_getSubagentMarkerPathForTesting,_getOpenAILogsMarkerPathForTesting};
|
|
4
4
|
/**
|
|
5
5
|
* @license
|
|
6
6
|
* Copyright 2025 Google LLC
|