@jetcrab/pi-desk 1.1.20-dev → 1.1.22-dev
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/docs/plugins.md +81 -1
- package/package.json +3 -3
- package/src/app/page.tsx +6 -1
- package/src/app/project-preview/page.tsx +10 -0
- package/src/client/l1_entry/pages/l1-home-page.tsx +30 -0
- package/src/client/l1_entry/pages/l1-project-preview-page.tsx +33 -0
- package/src/client/l1_entry/providers/l1-app-providers.tsx +18 -15
- package/src/client/l1_entry/providers/l1-app-runtime-provider.tsx +2 -2
- package/src/client/l2_biz/auth/l2-login-biz.ts +3 -0
- package/src/client/l2_biz/auth/l2-login.tsx +2 -3
- package/src/client/l2_biz/plugin-host/l2-plugin-capability-details.tsx +6 -1
- package/src/client/l2_biz/plugin-host/l2-plugin-contribution-host.tsx +71 -10
- package/src/client/l2_biz/plugin-host/l2-plugin-management-controls.tsx +9 -0
- package/src/client/l2_biz/plugin-host/l2-plugin-session-header-layout.ts +18 -0
- package/src/client/l2_biz/plugin-host/l2-plugin-session-header.tsx +247 -0
- package/src/client/l2_biz/plugin-host/l2-plugin-widgets.tsx +50 -0
- package/src/client/l2_biz/plugin-host/views/l2-plugin-session-header-action.tsx +112 -0
- package/src/client/l2_biz/project-preview/hooks/l2-use-project-picker.ts +76 -0
- package/src/client/l2_biz/project-preview/hooks/l2-use-project-preview.ts +214 -0
- package/src/client/l2_biz/project-preview/l2-project-preview-biz.ts +49 -4
- package/src/client/l2_biz/project-preview/l2-project-preview-dialog.tsx +42 -450
- package/src/client/l2_biz/project-preview/l2-project-preview-page.tsx +61 -0
- package/src/client/l2_biz/project-preview/l2-project-preview.tsx +342 -0
- package/src/client/l2_biz/project-preview/runtime/l2-project-history-runtime.ts +9 -3
- package/src/client/l2_biz/project-preview/views/l2-project-picker.tsx +168 -0
- package/src/client/l2_biz/settings/hooks/l2-use-model-settings.ts +34 -31
- package/src/client/l2_biz/settings/views/l2-model-replacement-preview.tsx +7 -1
- package/src/client/l2_biz/workbench/file-workspace/l2-project-preview-biz.ts +4 -3
- package/src/client/l2_biz/workbench/hooks/l2-workbench-chat-viewport.ts +28 -21
- package/src/client/l2_biz/workbench/l2-work-session-columns.module.css +32 -0
- package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +55 -16
- package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +19 -8
- package/src/client/l2_biz/workbench/l2-workbench-chat-composer.tsx +12 -1
- package/src/client/l2_biz/workbench/l2-workbench-initialization-notice.tsx +8 -3
- package/src/client/l2_biz/workbench/l2-workbench-plugin-slots.ts +13 -0
- package/src/client/l2_biz/workbench/l2-workbench.tsx +15 -2
- package/src/client/l3_modules/conversation/l3-conversation-viewport.tsx +12 -6
- package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +1 -1
- package/src/client/l3_modules/project-files/l3-project-document-git.ts +4 -3
- package/src/client/l3_modules/project-files/l3-project-document-view.tsx +4 -1
- package/src/client/l3_modules/project-files/l3-project-reader.ts +23 -35
- package/src/client/l4_foundation/lib/l4-client-id.tsx +11 -0
- package/src/client/l4_foundation/plugin-host/l4-plugin-host-runtime.ts +316 -35
- package/src/common/l2_biz/auth/l2-auth-return-to.ts +41 -0
- package/src/common/l2_biz/model-settings/l2-model-settings-contract.ts +5 -1
- package/src/common/l2_biz/plugin/l2-plugin-management-messages.ts +4 -0
- package/src/common/l2_biz/project-preview/l2-project-history-messages.ts +28 -0
- package/src/common/l2_biz/project-preview/l2-project-preview-navigation.ts +5 -0
- package/src/common/l2_biz/settings/l2-settings-messages.ts +4 -3
- package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +2 -0
- package/src/server/l1_entry/node/l1-server.ts +8 -4
- package/src/server/l4_foundation/model-settings/l4-model-settings-store.ts +29 -20
- package/src/server/l4_foundation/model-settings/l4-model-settings-types.ts +1 -1
- package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +22 -5
- package/src/server/l4_foundation/pi/l4-pi-plugin-owner-runtime.ts +133 -13
- package/src/server/l4_foundation/pi/l4-pi-session-initialization.ts +9 -0
- package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
- package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +3 -2
- package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
- package/temp/build/pi-desk/release/.next/react-loadable-manifest.json +1 -2
- package/temp/build/pi-desk/release/.next/required-server-files.js +2 -2
- package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
- package/temp/build/pi-desk/release/.next/routes-manifest.json +6 -0
- package/temp/build/pi-desk/release/.next/server/app/_global-error/page.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +3 -3
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +3 -3
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_not-found/page.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/auth/login/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/auth/logout/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/chat/context/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/chat/images/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/chat/messages/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/mcp-check/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/del/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/model-catalog/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/model-settings/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/model-settings/preview/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/model-settings/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directories/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-entries/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/models/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/session-user-messages/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/sessions/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/search/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/reveal/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/search/route.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skill-files/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skill-files/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skill-files/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skills/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/task-center/images/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/task-center/messages/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/add/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree-entry/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/add/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/branch/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/del/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/sort/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/favicon.ico/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/page.js +140 -140
- package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page.js +1 -0
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -0
- package/temp/build/pi-desk/release/.next/server/app-paths-manifest.json +3 -2
- package/temp/build/pi-desk/release/.next/server/chunks/10912.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/20460.js +15 -0
- package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -8
- package/temp/build/pi-desk/release/.next/server/chunks/35985.js +3 -17
- package/temp/build/pi-desk/release/.next/server/chunks/36361.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/48180.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/56830.js +235 -0
- package/temp/build/pi-desk/release/.next/server/chunks/78262.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/79686.js +62 -0
- package/temp/build/pi-desk/release/.next/server/chunks/80780.js +1 -0
- package/temp/build/pi-desk/release/.next/server/chunks/81363.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/82499.js +4 -4
- package/temp/build/pi-desk/release/.next/server/chunks/92386.js +8 -8
- package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
- package/temp/build/pi-desk/release/.next/static/MV6_lBt7Mzmi1rBNI-3dx/_buildManifest.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/11937-1d0a9822f2c7995b.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/14825-5579aed34a631ad7.js +62 -0
- package/temp/build/pi-desk/release/.next/static/chunks/15302-9c807afc6c60de0c.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/19991.8aa2e4b6df15fad6.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/22092-6d1bfbefa825ec03.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/37313-d5970e2d0c270d22.js +238 -0
- package/temp/build/pi-desk/release/.next/static/chunks/57235-03ba1044f22b6c84.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/79267-7d21d7cdbd7cfca1.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/82371-f7ba4a07a5dbcf34.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/9038-03144ed96d613f75.js +15 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/{error-0296a3b20cd1bf00.js → error-216b14b5da089ed3.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-20718f1503910291.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-0d3d4827802108e5.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/{not-found-2aab8b33ebbf3257.js → not-found-720cdf6a606b821a.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-e8a5274c115f528d.js +158 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/page-d70ee4e9409b970a.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/webpack-b60891a214e0925d.js +1 -0
- package/temp/build/pi-desk/release/.next/static/css/{250a6b93cc2222d1.css → 1e780a4936aa6ba3.css} +1 -1
- package/temp/build/pi-desk/release/.next/static/css/f646ca6c07245c4c.css +1 -0
- package/temp/build/pi-desk/release/.next/trace-build +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/10881.js +0 -296
- package/temp/build/pi-desk/release/.next/static/RLKcK-RQF5FvEeDmS9uih/_buildManifest.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/27611-0890482fe76bd9d6.js +0 -238
- package/temp/build/pi-desk/release/.next/static/chunks/31087-d8e5765d541d5c26.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/3814-35cfab0ce3aa7c41.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/70669.07f3670bfb7d6dd2.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/74220-795a2e7185bd66cb.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/77592-5bef6acb8e7c4b96.js +0 -13
- package/temp/build/pi-desk/release/.next/static/chunks/78923-17a9c337b29dcecd.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/81881-f11dbe7dc0d04ed9.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/96995-8f8313ea2ac3abd7.js +0 -62
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-a50c456648537afb.js +0 -3
- package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-84892b06243891f0.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-0789c43551b29dd2.js +0 -158
- package/temp/build/pi-desk/release/.next/static/chunks/webpack-d7248206b7fc7ba8.js +0 -1
- package/temp/build/pi-desk/release/.next/static/css/a4cf28fd76c70165.css +0 -1
- /package/temp/build/pi-desk/release/.next/static/{RLKcK-RQF5FvEeDmS9uih → MV6_lBt7Mzmi1rBNI-3dx}/_ssgManifest.js +0 -0
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
${a.description}`),"各级命令均支持 --help。当前插件管理只支持 global 范围。",..."plugins"===a[0]&&(1===a.length||"install"===a[1])?["install = install + update + reinstall。版本和渠道均可省略:新 npm 插件默认 latest,已有插件沿保存的渠道;--tag 选择跟随渠道,--version 固定完整版本号,两者互斥。","多个插件可共用同一渠道或具体版本;同版本仍重新安装。","本地扩展使用 Pi 全局 extensions 目录中的名字,加载当前代码;不接受版本、渠道或自定义路径。","异步接纳不代表生效;结果会插入本会话并唤醒模型,无需持续查询。"]:[]].join("\n\n")}function g(a){let b,c,g,h;if(a.length>32)throw Error("命令参数最多 32 项");if(0===a.length)return{kind:"help",message:f([])};let i=d.find(b=>b.path.every((b,c)=>a[c]===b));if(a.includes("--help")||a.includes("-h")||1===a.length&&["plugins","session"].includes(a[0])){let b=["plugins","session"].includes(a[0])?a[0]:null,c=i?.path??(b?[b]:[]);if(!i&&!b&&!["--help","-h"].includes(a[0]))throw Error("未知命令,请使用 pidesk --help");if(!i&&b&&a[1]&&!["--help","-h"].includes(a[1]))throw Error(`未知子命令,请使用 pidesk ${b} --help`);return{kind:"help",message:f(c)}}if(!i)throw Error("未知命令,请使用 pidesk --help");let j=[];for(let d=i.path.length;d<a.length;d+=1){let f=a[d];if("--scope"===f&&i.scope){if(void 0!==b)throw Error("--scope 不允许重复");if(!(b=a[++d])||b.startsWith("--"))throw Error("--scope 缺少范围")}else if("--version"===f&&i.version){if(void 0!==c)throw Error("--version 不允许重复");if(!(c=a[++d])||c.startsWith("--"))throw Error("--version 缺少版本号")}else if("--tag"===f&&i.tag){if(void 0!==g)throw Error("--tag 不允许重复");if(!(g=a[++d])||g.startsWith("--"))throw Error("--tag 缺少渠道标签")}else if("--check-updates"===f&&i.checkUpdates){if(void 0!==h)throw Error("--check-updates 不允许重复");h=!0}else if(i.name&&("multiple"===i.name||0===j.length)&&!f.startsWith("-"))j.push(f);else throw Error(`不支持的参数:${f}
|
|
3
3
|
${e(i)}`)}if("required"===i.scope&&void 0===b)throw Error(`必须指定 --scope global
|
|
4
4
|
${e(i)}`);if(void 0!==b&&"global"!==b)throw Error("当前插件管理只支持 global 范围,不支持项目级操作");if(i.name){if(0===j.length)throw Error(`缺少插件名字
|
|
5
|
-
${e(i)}`);for(let a of j)if(!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(a)||"node_modules"===a)throw Error(`插件名字必须是扩展名字或完整 npm 包名,不接受路径或内嵌版本号:${a}`)}if(void 0!==c&&!/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.test(c))throw Error("--version 必须是完整版本号,例如 1.2.3;版本可省略");if(void 0!==g&&(g.length>128||!/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(g)))throw Error("--tag 必须是有效的渠道标签,例如 latest 或 dev");if(void 0!==g&&void 0!==c)throw Error("--tag 与 --version 互斥,不能同时指定");return"--version"===i.path[0]?{kind:"version"}:"info"===i.path[0]?{kind:"info"}:"session"===i.path[0]?{kind:"session",action:"reload"}:{kind:"plugins",action:i.path[1],...1===j.length?{name:j[0]}:j.length>1?{names:j}:{},...void 0===c?{}:{version:c},...void 0===g?{}:{tag:g},...void 0===h?{}:{checkUpdates:h}}}},2476:(a,b,c)=>{c.d(b,{N:()=>l,l:()=>i});var d=c(77598),e=c(51455),f=c(76760);let g=new Set([".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".json",".md",".css",".yaml",".yml",".toml",".wasm",".node"]),h=new Set(["node_modules","temp","logs","coverage"]);class i extends Error{constructor(a){super(`插件来源不存在:${a}`),this.source=a,this.name="L4PiPluginSourceNotFoundError"}}async function j(a){let b=(0,d.createHash)("sha256").update(JSON.stringify({path:a.path,enabled:a.enabled,nativePaths:[...a.nativePaths].sort(),piDeskRoot:a.piDeskRoot,hasPiResources:a.hasPiResources}));if(!a.path||a.error||!a.enabled)return b.update(a.error??"").digest("hex");let c=await (0,e.realpath)(a.path),i=0,j=0,k=async(a,d,l)=>{if(++j>8192)throw Error("源码目录条目超过8192项,请使用独立插件目录");let m=await (0,e.realpath)(a),n=(0,f.relative)(c,m);if(n.startsWith("..")||(0,f.isAbsolute)(n))return;let o=await (0,e.stat)(m);if(o.isDirectory()){if(l.has(m))throw Error("源码目录存在符号链接循环");let a=new Set(l).add(m);for(let b of(await (0,e.readdir)(m,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name)))b.name.startsWith(".")||h.has(b.name)||await k((0,f.join)(m,b.name),`${d}/${b.name}`,a)}else if(o.isFile()&&(""===d||g.has((0,f.extname)(d)))){if(o.size>0x1000000||i+o.size>0x4000000)throw Error("源码指纹内容超过容量上限");let a=await (0,e.readFile)(m),c=await (0,e.stat)(m);if(c.size!==o.size||c.mtimeMs!==o.mtimeMs||a.length!==o.size)throw Error("插件源码正在变化,请保存或构建完成后重新加载");i+=a.length,b.update(d).update("\0").update(a).update("\0")}};return await k(c,"",new Set),b.digest("hex")}async function k(a){try{return{source:a,fingerprint:await j(a)}}catch(c){let b={...a,error:c instanceof Error?c.message:String(c)};return{source:b,fingerprint:`failed:${b.error}`}}}class l{async initialize(a){for(let b of(this.applied.clear(),a.sources))this.applied.set(b.source,await k(b))}async scan(a,b){let c=new Map(a.sources.map(a=>[a.source,a])),d=b?[...new Set(b)]:[...new Set([...this.applied.keys(),...c.keys()])],e=[];for(let f of d){let d=this.applied.get(f),g=c.get(f);if(!d&&!g)throw new i(f);if(!g&&a.errors.length>0){if(b)throw Error(`来源发现不完整,不能确认已删除:${f}`);continue}let h=g?await k(g):null;(b||d?.fingerprint!==h?.fingerprint)&&e.push({source:f,previous:d?.source??null,current:h?.source??null,fingerprint:h?.fingerprint??null})}return e}commit(a){a.current&&null!==a.fingerprint?this.applied.set(a.source,{source:a.current,fingerprint:a.fingerprint}):this.applied.delete(a.source)}constructor(){this.applied=new Map}}},9753:(a,b,c)=>{c.d(b,{LO:()=>d.L,Nb:()=>e.Nb,Nx:()=>e.Nx,O0:()=>e.O0,Sl:()=>e.Sl,k0:()=>e.k0}),c(47511),c(41904);var d=c(41966),e=c(85273)},12727:(a,b,c)=>{c.d(b,{B4:()=>x,Wl:()=>r,b7:()=>u,xf:()=>z,xm:()=>y,zG:()=>k,zK:()=>v,zz:()=>l});var d=c(54174);let e=new Intl.NumberFormat("en-US",{maximumFractionDigits:0});function f(a){if("string"!=typeof a)return null;let b=a.replace(/\s+/g," ").trim();return b?b.length<=500?b:`${b.slice(0,499)}…`:null}function g(a,...b){for(let c of b){let b=f(a[c]);if(b)return b}return null}function h(a,b){let c=a[b];return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}function i(a){if(0===a.length)return 0;let b=1;for(let c of a)"\n"===c&&(b+=1);return b}function j(a){let b=0;for(let c of a)b+=1;return b}function k(a,b,c){return{reasoning:f(b.reasoning),inputPreview:function(a,b){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"bash":return g(b,"command");case"read":case"write":case"edit":return g(b,"path","file_path");case"grep":{let a=g(b,"pattern","query"),c=g(b,"path");return a&&c?f(`${a} \xb7 ${c}`):a??c}case"find":return g(b,"pattern","path");case"ls":return g(b,"path");case"agent":return g(b,"description");case"agent_resume":return g(b,"description","prompt");default:return g(b,"command","path","file_path","pattern","query","description","prompt")}}(a,b),activity:function(a,b,c){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"read":let d=h(b,"offset"),f=h(b,"limit");if(null!==f){let a=d??1;return`${a}-${a+Math.max(0,f-1)}`}return null===d?null:`${d}-`;case"write":return function(a,b){let c,d,f=a.content;if("string"!=typeof f)return null;let g=b?.writeContent;if(b&&void 0!==g&&void 0!==b.writeCharacters&&void 0!==b.writeLines&&f.startsWith(g)){let a=f.slice(g.length);0===a.length?(c=b.writeCharacters,d=b.writeLines):(c=b.writeCharacters+j(a),d=b.writeLines+i(a)-(0!==g.length))}else c=j(f),d=i(f);return b&&(b.writeContent=f,b.writeCharacters=c,b.writeLines=d),`${e.format(c)} \xb7 L${e.format(d)}`}(b,c);case"edit":return function(a){let b=Array.isArray(a.edits)?a.edits.filter(a=>null!==a&&"object"==typeof a&&!Array.isArray(a)):"string"==typeof a.oldText||"string"==typeof a.newText?[a]:[];if(0===b.length)return null;let c=0,d=0,f=!1,g=!1;for(let a of b)"string"==typeof a.oldText&&(f=!0,c+=i(a.oldText)),"string"==typeof a.newText&&(g=!0,d+=i(a.newText));let h=[...f?[`-${e.format(c)}`]:[],...g?[`+${e.format(d)}`]:[]].join(" ");return h?`${e.format(b.length)} \xb7 ${h}`:e.format(b.length)}(b);default:return null}}(a,b,c)}}function l(a){if(!Array.isArray(a))return[];let b=[];for(let c of a){if(!c||"object"!=typeof c||"toolCall"!==c.type||"string"!=typeof c.id||!c.id||"string"!=typeof c.name||!c.name)continue;let a=c.arguments&&"object"==typeof c.arguments&&!Array.isArray(c.arguments)?c.arguments:{};b.push({id:c.id,name:c.name,input:a})}return b}function m(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}function n(a){let b=m(a);return b&&"object"==typeof b&&!Array.isArray(b)?b:{}}function o(a){return"string"==typeof a?a:Array.isArray(a)?a.flatMap(a=>a&&"object"==typeof a&&"text"===a.type&&"string"==typeof a.text?[a.text]:[]).join("\n"):""}function p(a){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||"image"!==a.type||"string"!=typeof a.data)return[];try{return[{data:a.data,metadata:(0,d.Z)(a.data).metadata}]}catch(a){return console.warn("[Pi Desk][PiChatProjection] 已忽略损坏的历史图片",{errorName:a instanceof Error?a.name:"UnknownError"}),[]}}):[]}function q(a){return p(a).map(a=>a.metadata)}function r(a,b){let c=p(a)[b];return c?{mimeType:c.metadata.mimeType,data:c.data}:null}function s(a,b){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||a.type!==b)return[];let c="text"===b?a.text:a.thinking;return"string"==typeof c?[c]:[]}).join("\n"):""}function t(a){return a?{inputTokens:a.input,outputTokens:a.output,cacheReadTokens:a.cacheRead,costUsd:a.cost.total}:null}function u(a,b,c){switch(a.role){case"user":{let b=o(a.content),c=q(a.content);return{type:"user",text:b,images:c,declaration:{message:{kind:"user",text:b,images:c},raw:a}}}case"assistant":{b&&function(a,b,c){for(let d of l(a))b.set(d.id,k(d.name,d.input)),c?.set(d.id,{...d.input})}(a.content,b,c);let d=s(a.content,"text"),e=s(a.content,"thinking");return{type:"assistant",text:d,thinking:e,model:"pi-virtual"!==a.api&&"string"==typeof a.provider&&"string"==typeof(a.responseModel??a.model)?{provider:a.provider,modelId:a.responseModel??a.model}:null,status:function(a){switch(a){case"pending":return"running";case"stop":case"length":case"toolUse":return"completed";case"aborted":return"aborted";default:return"error"}}(a.stopReason),errorMessage:a.errorMessage??null,usage:t(a.usage),declaration:{message:{kind:"assistant",text:d,thinking:e,stopReason:a.stopReason},raw:a}}}case"toolResult":{let d=b?.get(a.toolCallId),e=c?.get(a.toolCallId);b?.delete(a.toolCallId),c?.delete(a.toolCallId);let f=o(a.content),g=q(a.content),h=a.nestedCalls?{complete:a.nestedCalls.complete,calls:a.nestedCalls.calls.map(a=>({name:a.name,...void 0===a.arguments?{}:{arguments:n(a.arguments)},...void 0===a.argumentsBytes?{}:{argumentsBytes:a.argumentsBytes},status:a.status,...void 0===a.durationMs?{}:{durationMs:a.durationMs},...void 0===a.error?{}:{error:a.error}}))}:null;return{type:"tool",name:a.toolName,reasoning:d?.reasoning??null,inputPreview:d?.inputPreview??null,activity:d?.activity??null,status:a.isError?"error":"completed",usage:t(a.usage),output:f,...g.length>0?{images:g}:{},...h?{nestedCalls:h}:{},startedAtMs:null,durationMs:function(a,b){if("bash"!==a||!b||"object"!=typeof b||Array.isArray(b))return null;let c=b.durationMs;return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}(a.toolName,a.details),declaration:{message:{kind:"tool",toolName:a.toolName,toolCallId:a.toolCallId,arguments:n(e),partialResult:null,result:m({content:a.content,details:a.details,output:f}),isError:a.isError},raw:a}}}case"bashExecution":return{type:"bash",command:a.command,status:a.cancelled?"aborted":0===a.exitCode?"completed":"error",output:a.output,declaration:{message:{kind:"bash",command:a.command,output:a.output,exitCode:a.exitCode??null,cancelled:a.cancelled,truncated:a.truncated},raw:a}};case"custom":{if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}default:return null}}function v(a,b,c,d){let e=new Map,f=new Map;return c&&e.set(b,c),d&&f.set(b,d),u(a,e,f)}function w(a,b,c){let d="message"===a.type?u(a.message,b,c):"custom_message"===a.type?function(a){if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}(a):"compaction"===a.type?{type:"compaction",summary:a.summary,declaration:{message:{kind:"custom",customType:"pi-desk/compaction",content:"",details:{text:a.summary}},raw:a}}:null;if(!d)return null;let e=Date.parse(a.timestamp);if(!Number.isSafeInteger(e)||e<0)throw Error(`Pi session entry has an invalid timestamp: ${a.id}`);return{entryId:a.id,timestampMs:e,message:d}}function x(a){return w(a,new Map,new Map)}function y(a,b){let c=[],d=new Map,e=new Map;for(let f of a){let a=w(f,d,e);a&&(c.push(a),void 0!==b&&c.length>b&&c.shift())}return c}function z(a){return{sessionName:a.getSessionName()?.trim()||null,entries:y(a.getBranch())}}},13982:(a,b,c)=>{c.d(b,{V:()=>d});function d(a){let b=(globalThis.__piDeskPackageRootTail??Promise.resolve()).then(a,a);return globalThis.__piDeskPackageRootTail=b.then(()=>void 0,()=>void 0),b}},20369:(a,b,c)=>{c.d(b,{HE:()=>e,IS:()=>d.Dl,Wu:()=>d.j0,f$:()=>d.Qg,rY:()=>d.a4});var d=c(47511);function e(a){return Object.fromEntries(Object.entries(a).map(([a,b])=>[a,b.name]))}},23272:(a,b,c)=>{c.d(b,{H:()=>g,k:()=>h});var d=c(77598),e=c(57975),f=c(67062);class g extends Error{constructor(a,b){super(b),this.code=a,this.name="L4PiUiResponseError"}}class h{get hasPending(){return this.pending.size>0}snapshot(){return structuredClone(this.state)}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}bind(a,b){let c=()=>{b()},d=(a,b)=>(c(),this.request(a,b));return{...a,select:async(a,b,c)=>await d({method:"select",title:a,options:b},c),confirm:async(a,b,c)=>await d({method:"confirm",title:a,message:b},c)===!0,input:async(a,b="",c)=>await d({method:"input",title:a,placeholder:b},c),editor:async(a,b="")=>await d({method:"editor",title:a,prefill:b}),notify:(a,b="info")=>{c(),this.active&&this.emit({type:"notify",message:(0,e.stripVTControlCharacters)(a).slice(0,65536),level:b})},setStatus:(a,b)=>{if(c(),!this.active)return;let d={...this.state.statuses};void 0===b?delete d[a]:d[a]=(0,e.stripVTControlCharacters)(b),this.replace({...this.state,statuses:d})},setWidget:(a,b,d)=>{if(c(),!this.active)return;if("function"==typeof b)return void this.emit({type:"notify",level:"warning",message:"该插件挂件需要终端界面,当前仅支持文本挂件。"});let f={...this.state.widgets};void 0===b?delete f[a]:f[a]={lines:b.map(e.stripVTControlCharacters),placement:d?.placement??"aboveEditor"},this.replace({...this.state,widgets:f})},setEditorText:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"replace",text:a.slice(0,65536)})},pasteToEditor:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"paste",text:a.slice(0,65536)})},custom:async()=>{throw c(),Error("当前界面不支持自定义终端组件,请使用插件提供的网页界面。")}}}respond(a){let b=this.pending.get(a.id);if(!b)throw new g(409,"问题已结束或已失效,请查看最新状态");let{request:c}=b;if(null!==c.expiresAt&&c.expiresAt<=Date.now())throw this.finish(a.id,void 0),new g(409,"问题已超时");if(null!==a.value){if("confirm"===c.method?"boolean"!=typeof a.value:"string"!=typeof a.value)throw new g(400,"回答类型不正确");if("select"===c.method&&!c.options.includes(a.value))throw new g(400,"选择的选项已无效")}this.finish(a.id,a.value??void 0)}cancelAll(){let a=[...this.pending.values()];for(let b of(this.pending.clear(),this.state={...this.state,requests:[]},a))b.cleanup();for(let b of(a.length>0&&(this.publishSnapshot(),console.info("[Pi Desk][NativeUI] 已取消待处理交互",{count:a.length})),a))b.resolve(void 0)}reset(a=!0){this.active=a,this.cancelAll(),this.state=(0,f.l3)(),this.publishSnapshot()}dispose(){this.reset(!1),this.listeners.clear()}async waitForOperation(a,b,c){let d,e=b,f=performance.now(),g=()=>void 0,h=new Promise((a,b)=>{g=b}),i=()=>{d&&(e-=performance.now()-f,clearTimeout(d),d=void 0),this.hasPending||(f=performance.now(),d=setTimeout(()=>g(c()),Math.max(0,e)))},j=this.subscribe(a=>{"snapshot"===a.type&&i()});i();try{return await Promise.race([a,h])}finally{d&&clearTimeout(d),j()}}request(a,b){if(!this.active||b?.signal?.aborted)return Promise.resolve(void 0);let c=f.WR.parse({...a,id:(0,d.randomUUID)(),expiresAt:b?.timeout===void 0?null:Date.now()+Math.max(0,b.timeout)}),e={...this.state,requests:[...this.state.requests,c]};return this.validate(e),new Promise(a=>{let d=()=>this.finish(c.id,void 0),f=null===c.expiresAt?void 0:setTimeout(d,Math.max(0,c.expiresAt-Date.now()));b?.signal?.addEventListener("abort",d,{once:!0}),this.pending.set(c.id,{request:c,resolve:a,cleanup:()=>{f&&clearTimeout(f),b?.signal?.removeEventListener("abort",d)}}),this.state=e,this.publishSnapshot()})}finish(a,b){let c=this.pending.get(a);c&&(this.pending.delete(a),c.cleanup(),this.state={...this.state,requests:this.state.requests.filter(b=>b.id!==a)},c.resolve(b),null===this.snapshotImmediate&&(this.snapshotImmediate=setImmediate(()=>{this.snapshotImmediate=null,this.publishSnapshot()})))}validate(a){if(f.P.parse(a),Object.keys(a.statuses).length>32||Object.keys(a.widgets).length>16||Buffer.byteLength(JSON.stringify(a),"utf8")>262144)throw Error("插件交互内容过多,请先清理已有状态或缩短内容")}replace(a){this.validate(a),this.state=a,this.publishSnapshot()}publishSnapshot(){null!==this.snapshotImmediate&&(clearImmediate(this.snapshotImmediate),this.snapshotImmediate=null),this.emit({type:"snapshot",snapshot:this.snapshot()})}emit(a){for(let b of this.listeners)try{b(a)}catch(a){console.error("[Pi Desk][NativeUI] 交互推送失败",{message:a instanceof Error?a.message:String(a)})}}constructor(){this.state=(0,f.l3)(),this.pending=new Map,this.listeners=new Set,this.active=!0,this.snapshotImmediate=null}}},23404:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{O:()=>i});var e=c(28802),f=c(85273),g=c(47511),h=a([e]);e=(h.then?(await h)():h)[0];class i{constructor(a){this.readMode=a,this.registrations=new Map,this.session=null,this.requestedTools=new Set,this.setTools=null,this.originalSetTools=null,this.ready=!1,this.disposed=!1,this.rules=a()}eventBus(a){return{on:(b,c)=>a.on(b,c),emit:(b,c)=>{this.disposed||(b===f.Hj?this.register(c):a.emit(b,c))}}}createHostExtension(a,b){let c="<inline:pi-desk-input-validator>",d=new Map;return d.set("input",[async(b,c)=>a(b,c)]),d.set("tool_call",[async a=>{if(!this.isToolAllowed(a.toolName))return{block:!0,reason:`当前能力模式不允许工具:${a.toolName}`}}]),d.set("session_shutdown",[async()=>{this.ready=!1,this.registrations.clear(),b?.()}]),{path:c,resolvedPath:c,hidden:!0,sourceInfo:{path:c,source:"inline",scope:"temporary",origin:"top-level"},handlers:d,tools:new Map,commands:new Map,flags:new Map,shortcuts:new Map,messageRenderers:new Map}}resources(a){return new Proxy(a,{get:(a,b)=>{if("getSkills"===b)return()=>{let b=a.getSkills();return{...b,skills:b.skills.filter(a=>(0,g.RC)(this.rules?.skills,a.name))}};let c=Reflect.get(a,b,a);return"function"==typeof c?c.bind(a):c}})}attach(a){this.session!==a&&(this.session=a,this.requestedTools=new Set(a.getActiveToolNames()),this.originalSetTools=a.setActiveToolsByName,this.setTools=a.setActiveToolsByName.bind(a),a.setActiveToolsByName=a=>{this.rememberRequestedTools(a),this.refreshTools()},this.refreshTools())}isToolAllowed(a){return(0,g.RC)(this.rules?.tools,a)}restoreBranchSelection(){let a=this.session;!this.disposed&&a&&((0,e.getCurrentSystemMessage)(a.messages)&&(this.requestedTools=new Set(a.getActiveToolNames())),this.refreshTools())}async apply(){let a=this.session;if(this.disposed||!a)return;this.rememberRequestedTools(a.getActiveToolNames()),this.rules=this.readMode(),this.ready=!0,this.refreshTools();let b=[];for(let c of[...this.registrations.values()])try{await this.applyRegistration(c)}catch(e){let d=e instanceof Error?e.message:String(e);console.error("[Pi Desk][Capabilities] 插件应用能力规则失败",{sessionId:a.sessionId,pluginName:c.pluginName,message:d}),b.push(`${c.pluginName}:${d}`)}if(this.refreshTools(),b.length>0)throw Error(`能力规则应用失败:${b.join(";")}`)}dispose(){this.disposed=!0,this.detach()}detach(){this.ready=!1,this.registrations.clear(),this.session&&this.originalSetTools&&(this.session.setActiveToolsByName=this.originalSetTools),this.session=null,this.setTools=null,this.originalSetTools=null,this.requestedTools.clear()}rememberRequestedTools(a){let b=new Set(this.session?.getAllTools().filter(a=>"hidden"!==a.exposure).map(a=>a.name)),c=[...this.requestedTools].filter(a=>b.has(a)&&!(0,g.RC)(this.rules?.tools,a));this.requestedTools=new Set([...a,...c].filter(a=>b.has(a)))}refreshTools(){this.setTools?.([...this.requestedTools].filter(a=>(0,g.RC)(this.rules?.tools,a)))}async applyRegistration(a){let b=this.session;if(!b||this.disposed||this.registrations.get(a.pluginName)!==a)return;let c={tools:this.rules?.tools??{},skills:this.rules?.skills??{},capabilities:this.rules?.plugins?.[a.pluginName]??{}};await a.execute(structuredClone(c),b.extensionRunner.createContext())}register(a){if(!a||"object"!=typeof a)throw Error("能力回调注册无效");let b=a.registration;if(!b||"string"!=typeof b.pluginName||"function"!=typeof b.execute)throw Error("能力回调缺少插件名称或处理函数");if("unregister"===a.type){this.registrations.get(b.pluginName)===b&&this.registrations.delete(b.pluginName);return}if("register"!==a.type)throw Error("能力回调事件无效");if(this.registrations.has(b.pluginName))throw Error(`能力回调已注册:${b.pluginName}`);b.hostManaged=!0,this.registrations.set(b.pluginName,b),this.ready&&this.applyRegistration(b).catch(a=>{console.error("[Pi Desk][Capabilities] 新注册插件应用规则失败",{pluginName:b.pluginName,message:a instanceof Error?a.message:String(a)})})}}d()}catch(a){d(a)}})},26143:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{h:()=>n});var e=c(76760),f=c(75430),g=c(58801),h=c(13982),i=c(73589),j=a([f,g,i]);[f,g,i]=j.then?(await j)():j;let m=[{name:"codemode",create:f.createCodemodeExtension},{name:"tool-search",create:f.createToolSearchExtension},{name:"mcp",create:()=>(0,f.createMcpExtension)({openUrl:()=>void 0})}];function k(a){let b=(0,e.basename)(a.path),c="package"===a.metadata.origin?a.metadata.source.replace(/^npm:/,""):/^(index\.[^.]+|SKILL\.md)$/.test(b)?(0,e.basename)((0,e.dirname)(a.path)):(0,e.basename)(a.path,(0,e.extname)(a.path));return`插件 ${c}
|
|
5
|
+
${e(i)}`);for(let a of j)if(!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(a)||"node_modules"===a)throw Error(`插件名字必须是扩展名字或完整 npm 包名,不接受路径或内嵌版本号:${a}`)}if(void 0!==c&&!/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/.test(c))throw Error("--version 必须是完整版本号,例如 1.2.3;版本可省略");if(void 0!==g&&(g.length>128||!/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(g)))throw Error("--tag 必须是有效的渠道标签,例如 latest 或 dev");if(void 0!==g&&void 0!==c)throw Error("--tag 与 --version 互斥,不能同时指定");return"--version"===i.path[0]?{kind:"version"}:"info"===i.path[0]?{kind:"info"}:"session"===i.path[0]?{kind:"session",action:"reload"}:{kind:"plugins",action:i.path[1],...1===j.length?{name:j[0]}:j.length>1?{names:j}:{},...void 0===c?{}:{version:c},...void 0===g?{}:{tag:g},...void 0===h?{}:{checkUpdates:h}}}},2476:(a,b,c)=>{c.d(b,{N:()=>l,l:()=>i});var d=c(77598),e=c(51455),f=c(76760);let g=new Set([".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs",".json",".md",".css",".yaml",".yml",".toml",".wasm",".node"]),h=new Set(["node_modules","temp","logs","coverage"]);class i extends Error{constructor(a){super(`插件来源不存在:${a}`),this.source=a,this.name="L4PiPluginSourceNotFoundError"}}async function j(a){let b=(0,d.createHash)("sha256").update(JSON.stringify({path:a.path,enabled:a.enabled,nativePaths:[...a.nativePaths].sort(),piDeskRoot:a.piDeskRoot,hasPiResources:a.hasPiResources}));if(!a.path||a.error||!a.enabled)return b.update(a.error??"").digest("hex");let c=await (0,e.realpath)(a.path),i=0,j=0,k=async(a,d,l)=>{if(++j>8192)throw Error("源码目录条目超过8192项,请使用独立插件目录");let m=await (0,e.realpath)(a),n=(0,f.relative)(c,m);if(n.startsWith("..")||(0,f.isAbsolute)(n))return;let o=await (0,e.stat)(m);if(o.isDirectory()){if(l.has(m))throw Error("源码目录存在符号链接循环");let a=new Set(l).add(m);for(let b of(await (0,e.readdir)(m,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name)))b.name.startsWith(".")||h.has(b.name)||await k((0,f.join)(m,b.name),`${d}/${b.name}`,a)}else if(o.isFile()&&(""===d||g.has((0,f.extname)(d)))){if(o.size>0x1000000||i+o.size>0x4000000)throw Error("源码指纹内容超过容量上限");let a=await (0,e.readFile)(m),c=await (0,e.stat)(m);if(c.size!==o.size||c.mtimeMs!==o.mtimeMs||a.length!==o.size)throw Error("插件源码正在变化,请保存或构建完成后重新加载");i+=a.length,b.update(d).update("\0").update(a).update("\0")}};return await k(c,"",new Set),b.digest("hex")}async function k(a){try{return{source:a,fingerprint:await j(a)}}catch(c){let b={...a,error:c instanceof Error?c.message:String(c)};return{source:b,fingerprint:`failed:${b.error}`}}}class l{async initialize(a){for(let b of(this.applied.clear(),a.sources))this.applied.set(b.source,await k(b))}async scan(a,b){let c=new Map(a.sources.map(a=>[a.source,a])),d=b?[...new Set(b)]:[...new Set([...this.applied.keys(),...c.keys()])],e=[];for(let f of d){let d=this.applied.get(f),g=c.get(f);if(!d&&!g)throw new i(f);if(!g&&a.errors.length>0){if(b)throw Error(`来源发现不完整,不能确认已删除:${f}`);continue}let h=g?await k(g):null;(b||d?.fingerprint!==h?.fingerprint)&&e.push({source:f,previous:d?.source??null,current:h?.source??null,fingerprint:h?.fingerprint??null})}return e}commit(a){a.current&&null!==a.fingerprint?this.applied.set(a.source,{source:a.current,fingerprint:a.fingerprint}):this.applied.delete(a.source)}constructor(){this.applied=new Map}}},5782:(a,b,c)=>{c.d(b,{l:()=>g});var d=c(77598),e=c(73024),f=c(76760);function g(a){let b=a.getSessionFile();if(!b)throw Error("Persisted Pi session is missing a session file");if((0,e.existsSync)(b))return b;let c=a.getHeader();if(!c||c.id!==a.getSessionId())throw Error(`Pi session ${a.getSessionId()} has an invalid header`);(0,e.mkdirSync)((0,f.dirname)(b),{recursive:!0});let g=`${[c,...a.getEntries()].map(a=>JSON.stringify(a)).join("\n")}
|
|
6
|
+
`,h=`${b}.${(0,d.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,g,{encoding:"utf8",flag:"wx"});try{(0,e.linkSync)(h,b)}catch(a){if("EEXIST"!==a.code)throw a}}finally{(0,e.existsSync)(h)&&(0,e.unlinkSync)(h)}if(!(0,e.existsSync)(b))throw Error(`Failed to materialize Pi session: ${a.getSessionId()}`);return b}},9753:(a,b,c)=>{c.d(b,{LO:()=>d.L,Nb:()=>e.Nb,Nx:()=>e.Nx,O0:()=>e.O0,Sl:()=>e.Sl,k0:()=>e.k0}),c(47511),c(41904);var d=c(41966),e=c(85273)},12727:(a,b,c)=>{c.d(b,{B4:()=>x,Wl:()=>r,b7:()=>u,xf:()=>z,xm:()=>y,zG:()=>k,zK:()=>v,zz:()=>l});var d=c(54174);let e=new Intl.NumberFormat("en-US",{maximumFractionDigits:0});function f(a){if("string"!=typeof a)return null;let b=a.replace(/\s+/g," ").trim();return b?b.length<=500?b:`${b.slice(0,499)}…`:null}function g(a,...b){for(let c of b){let b=f(a[c]);if(b)return b}return null}function h(a,b){let c=a[b];return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}function i(a){if(0===a.length)return 0;let b=1;for(let c of a)"\n"===c&&(b+=1);return b}function j(a){let b=0;for(let c of a)b+=1;return b}function k(a,b,c){return{reasoning:f(b.reasoning),inputPreview:function(a,b){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"bash":return g(b,"command");case"read":case"write":case"edit":return g(b,"path","file_path");case"grep":{let a=g(b,"pattern","query"),c=g(b,"path");return a&&c?f(`${a} \xb7 ${c}`):a??c}case"find":return g(b,"pattern","path");case"ls":return g(b,"path");case"agent":return g(b,"description");case"agent_resume":return g(b,"description","prompt");default:return g(b,"command","path","file_path","pattern","query","description","prompt")}}(a,b),activity:function(a,b,c){switch(a.toLowerCase().split(".").at(-1)??a.toLowerCase()){case"read":let d=h(b,"offset"),f=h(b,"limit");if(null!==f){let a=d??1;return`${a}-${a+Math.max(0,f-1)}`}return null===d?null:`${d}-`;case"write":return function(a,b){let c,d,f=a.content;if("string"!=typeof f)return null;let g=b?.writeContent;if(b&&void 0!==g&&void 0!==b.writeCharacters&&void 0!==b.writeLines&&f.startsWith(g)){let a=f.slice(g.length);0===a.length?(c=b.writeCharacters,d=b.writeLines):(c=b.writeCharacters+j(a),d=b.writeLines+i(a)-(0!==g.length))}else c=j(f),d=i(f);return b&&(b.writeContent=f,b.writeCharacters=c,b.writeLines=d),`${e.format(c)} \xb7 L${e.format(d)}`}(b,c);case"edit":return function(a){let b=Array.isArray(a.edits)?a.edits.filter(a=>null!==a&&"object"==typeof a&&!Array.isArray(a)):"string"==typeof a.oldText||"string"==typeof a.newText?[a]:[];if(0===b.length)return null;let c=0,d=0,f=!1,g=!1;for(let a of b)"string"==typeof a.oldText&&(f=!0,c+=i(a.oldText)),"string"==typeof a.newText&&(g=!0,d+=i(a.newText));let h=[...f?[`-${e.format(c)}`]:[],...g?[`+${e.format(d)}`]:[]].join(" ");return h?`${e.format(b.length)} \xb7 ${h}`:e.format(b.length)}(b);default:return null}}(a,b,c)}}function l(a){if(!Array.isArray(a))return[];let b=[];for(let c of a){if(!c||"object"!=typeof c||"toolCall"!==c.type||"string"!=typeof c.id||!c.id||"string"!=typeof c.name||!c.name)continue;let a=c.arguments&&"object"==typeof c.arguments&&!Array.isArray(c.arguments)?c.arguments:{};b.push({id:c.id,name:c.name,input:a})}return b}function m(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}function n(a){let b=m(a);return b&&"object"==typeof b&&!Array.isArray(b)?b:{}}function o(a){return"string"==typeof a?a:Array.isArray(a)?a.flatMap(a=>a&&"object"==typeof a&&"text"===a.type&&"string"==typeof a.text?[a.text]:[]).join("\n"):""}function p(a){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||"image"!==a.type||"string"!=typeof a.data)return[];try{return[{data:a.data,metadata:(0,d.Z)(a.data).metadata}]}catch(a){return console.warn("[Pi Desk][PiChatProjection] 已忽略损坏的历史图片",{errorName:a instanceof Error?a.name:"UnknownError"}),[]}}):[]}function q(a){return p(a).map(a=>a.metadata)}function r(a,b){let c=p(a)[b];return c?{mimeType:c.metadata.mimeType,data:c.data}:null}function s(a,b){return Array.isArray(a)?a.flatMap(a=>{if(!a||"object"!=typeof a||a.type!==b)return[];let c="text"===b?a.text:a.thinking;return"string"==typeof c?[c]:[]}).join("\n"):""}function t(a){return a?{inputTokens:a.input,outputTokens:a.output,cacheReadTokens:a.cacheRead,costUsd:a.cost.total}:null}function u(a,b,c){switch(a.role){case"user":{let b=o(a.content),c=q(a.content);return{type:"user",text:b,images:c,declaration:{message:{kind:"user",text:b,images:c},raw:a}}}case"assistant":{b&&function(a,b,c){for(let d of l(a))b.set(d.id,k(d.name,d.input)),c?.set(d.id,{...d.input})}(a.content,b,c);let d=s(a.content,"text"),e=s(a.content,"thinking");return{type:"assistant",text:d,thinking:e,model:"pi-virtual"!==a.api&&"string"==typeof a.provider&&"string"==typeof(a.responseModel??a.model)?{provider:a.provider,modelId:a.responseModel??a.model}:null,status:function(a){switch(a){case"pending":return"running";case"stop":case"length":case"toolUse":return"completed";case"aborted":return"aborted";default:return"error"}}(a.stopReason),errorMessage:a.errorMessage??null,usage:t(a.usage),declaration:{message:{kind:"assistant",text:d,thinking:e,stopReason:a.stopReason},raw:a}}}case"toolResult":{let d=b?.get(a.toolCallId),e=c?.get(a.toolCallId);b?.delete(a.toolCallId),c?.delete(a.toolCallId);let f=o(a.content),g=q(a.content),h=a.nestedCalls?{complete:a.nestedCalls.complete,calls:a.nestedCalls.calls.map(a=>({name:a.name,...void 0===a.arguments?{}:{arguments:n(a.arguments)},...void 0===a.argumentsBytes?{}:{argumentsBytes:a.argumentsBytes},status:a.status,...void 0===a.durationMs?{}:{durationMs:a.durationMs},...void 0===a.error?{}:{error:a.error}}))}:null;return{type:"tool",name:a.toolName,reasoning:d?.reasoning??null,inputPreview:d?.inputPreview??null,activity:d?.activity??null,status:a.isError?"error":"completed",usage:t(a.usage),output:f,...g.length>0?{images:g}:{},...h?{nestedCalls:h}:{},startedAtMs:null,durationMs:function(a,b){if("bash"!==a||!b||"object"!=typeof b||Array.isArray(b))return null;let c=b.durationMs;return"number"==typeof c&&Number.isSafeInteger(c)&&c>=0?c:null}(a.toolName,a.details),declaration:{message:{kind:"tool",toolName:a.toolName,toolCallId:a.toolCallId,arguments:n(e),partialResult:null,result:m({content:a.content,details:a.details,output:f}),isError:a.isError},raw:a}}}case"bashExecution":return{type:"bash",command:a.command,status:a.cancelled?"aborted":0===a.exitCode?"completed":"error",output:a.output,declaration:{message:{kind:"bash",command:a.command,output:a.output,exitCode:a.exitCode??null,cancelled:a.cancelled,truncated:a.truncated},raw:a}};case"custom":{if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}default:return null}}function v(a,b,c,d){let e=new Map,f=new Map;return c&&e.set(b,c),d&&f.set(b,d),u(a,e,f)}function w(a,b,c){let d="message"===a.type?u(a.message,b,c):"custom_message"===a.type?function(a){if(!a.display)return null;let b=o(a.content);return{type:"custom",text:b,declaration:{message:{kind:"custom",customType:a.customType,content:b,details:m(a.details)},raw:a}}}(a):"compaction"===a.type?{type:"compaction",summary:a.summary,declaration:{message:{kind:"custom",customType:"pi-desk/compaction",content:"",details:{text:a.summary}},raw:a}}:null;if(!d)return null;let e=Date.parse(a.timestamp);if(!Number.isSafeInteger(e)||e<0)throw Error(`Pi session entry has an invalid timestamp: ${a.id}`);return{entryId:a.id,timestampMs:e,message:d}}function x(a){return w(a,new Map,new Map)}function y(a,b){let c=[],d=new Map,e=new Map;for(let f of a){let a=w(f,d,e);a&&(c.push(a),void 0!==b&&c.length>b&&c.shift())}return c}function z(a){return{sessionName:a.getSessionName()?.trim()||null,entries:y(a.getBranch())}}},13982:(a,b,c)=>{c.d(b,{V:()=>d});function d(a){let b=(globalThis.__piDeskPackageRootTail??Promise.resolve()).then(a,a);return globalThis.__piDeskPackageRootTail=b.then(()=>void 0,()=>void 0),b}},20369:(a,b,c)=>{c.d(b,{HE:()=>e,IS:()=>d.Dl,Wu:()=>d.j0,f$:()=>d.Qg,rY:()=>d.a4});var d=c(47511);function e(a){return Object.fromEntries(Object.entries(a).map(([a,b])=>[a,b.name]))}},23272:(a,b,c)=>{c.d(b,{H:()=>g,k:()=>h});var d=c(77598),e=c(57975),f=c(67062);class g extends Error{constructor(a,b){super(b),this.code=a,this.name="L4PiUiResponseError"}}class h{get hasPending(){return this.pending.size>0}snapshot(){return structuredClone(this.state)}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}bind(a,b){let c=()=>{b()},d=(a,b)=>(c(),this.request(a,b));return{...a,select:async(a,b,c)=>await d({method:"select",title:a,options:b},c),confirm:async(a,b,c)=>await d({method:"confirm",title:a,message:b},c)===!0,input:async(a,b="",c)=>await d({method:"input",title:a,placeholder:b},c),editor:async(a,b="")=>await d({method:"editor",title:a,prefill:b}),notify:(a,b="info")=>{c(),this.active&&this.emit({type:"notify",message:(0,e.stripVTControlCharacters)(a).slice(0,65536),level:b})},setStatus:(a,b)=>{if(c(),!this.active)return;let d={...this.state.statuses};void 0===b?delete d[a]:d[a]=(0,e.stripVTControlCharacters)(b),this.replace({...this.state,statuses:d})},setWidget:(a,b,d)=>{if(c(),!this.active)return;if("function"==typeof b)return void this.emit({type:"notify",level:"warning",message:"该插件挂件需要终端界面,当前仅支持文本挂件。"});let f={...this.state.widgets};void 0===b?delete f[a]:f[a]={lines:b.map(e.stripVTControlCharacters),placement:d?.placement??"aboveEditor"},this.replace({...this.state,widgets:f})},setEditorText:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"replace",text:a.slice(0,65536)})},pasteToEditor:a=>{c(),this.active&&this.emit({type:"editor_text",mode:"paste",text:a.slice(0,65536)})},custom:async()=>{throw c(),Error("当前界面不支持自定义终端组件,请使用插件提供的网页界面。")}}}respond(a){let b=this.pending.get(a.id);if(!b)throw new g(409,"问题已结束或已失效,请查看最新状态");let{request:c}=b;if(null!==c.expiresAt&&c.expiresAt<=Date.now())throw this.finish(a.id,void 0),new g(409,"问题已超时");if(null!==a.value){if("confirm"===c.method?"boolean"!=typeof a.value:"string"!=typeof a.value)throw new g(400,"回答类型不正确");if("select"===c.method&&!c.options.includes(a.value))throw new g(400,"选择的选项已无效")}this.finish(a.id,a.value??void 0)}cancelAll(){let a=[...this.pending.values()];for(let b of(this.pending.clear(),this.state={...this.state,requests:[]},a))b.cleanup();for(let b of(a.length>0&&(this.publishSnapshot(),console.info("[Pi Desk][NativeUI] 已取消待处理交互",{count:a.length})),a))b.resolve(void 0)}reset(a=!0){this.active=a,this.cancelAll(),this.state=(0,f.l3)(),this.publishSnapshot()}dispose(){this.reset(!1),this.listeners.clear()}async waitForOperation(a,b,c){let d,e=b,f=performance.now(),g=()=>void 0,h=new Promise((a,b)=>{g=b}),i=()=>{d&&(e-=performance.now()-f,clearTimeout(d),d=void 0),this.hasPending||(f=performance.now(),d=setTimeout(()=>g(c()),Math.max(0,e)))},j=this.subscribe(a=>{"snapshot"===a.type&&i()});i();try{return await Promise.race([a,h])}finally{d&&clearTimeout(d),j()}}request(a,b){if(!this.active||b?.signal?.aborted)return Promise.resolve(void 0);let c=f.WR.parse({...a,id:(0,d.randomUUID)(),expiresAt:b?.timeout===void 0?null:Date.now()+Math.max(0,b.timeout)}),e={...this.state,requests:[...this.state.requests,c]};return this.validate(e),new Promise(a=>{let d=()=>this.finish(c.id,void 0),f=null===c.expiresAt?void 0:setTimeout(d,Math.max(0,c.expiresAt-Date.now()));b?.signal?.addEventListener("abort",d,{once:!0}),this.pending.set(c.id,{request:c,resolve:a,cleanup:()=>{f&&clearTimeout(f),b?.signal?.removeEventListener("abort",d)}}),this.state=e,this.publishSnapshot()})}finish(a,b){let c=this.pending.get(a);c&&(this.pending.delete(a),c.cleanup(),this.state={...this.state,requests:this.state.requests.filter(b=>b.id!==a)},c.resolve(b),null===this.snapshotImmediate&&(this.snapshotImmediate=setImmediate(()=>{this.snapshotImmediate=null,this.publishSnapshot()})))}validate(a){if(f.P.parse(a),Object.keys(a.statuses).length>32||Object.keys(a.widgets).length>16||Buffer.byteLength(JSON.stringify(a),"utf8")>262144)throw Error("插件交互内容过多,请先清理已有状态或缩短内容")}replace(a){this.validate(a),this.state=a,this.publishSnapshot()}publishSnapshot(){null!==this.snapshotImmediate&&(clearImmediate(this.snapshotImmediate),this.snapshotImmediate=null),this.emit({type:"snapshot",snapshot:this.snapshot()})}emit(a){for(let b of this.listeners)try{b(a)}catch(a){console.error("[Pi Desk][NativeUI] 交互推送失败",{message:a instanceof Error?a.message:String(a)})}}constructor(){this.state=(0,f.l3)(),this.pending=new Map,this.listeners=new Set,this.active=!0,this.snapshotImmediate=null}}},23404:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{O:()=>i});var e=c(28802),f=c(85273),g=c(47511),h=a([e]);e=(h.then?(await h)():h)[0];class i{constructor(a){this.readMode=a,this.registrations=new Map,this.session=null,this.requestedTools=new Set,this.setTools=null,this.originalSetTools=null,this.ready=!1,this.disposed=!1,this.rules=a()}eventBus(a){return{on:(b,c)=>a.on(b,c),emit:(b,c)=>{this.disposed||(b===f.Hj?this.register(c):a.emit(b,c))}}}createHostExtension(a,b){let c="<inline:pi-desk-input-validator>",d=new Map;return d.set("input",[async(b,c)=>a(b,c)]),d.set("tool_call",[async a=>{if(!this.isToolAllowed(a.toolName))return{block:!0,reason:`当前能力模式不允许工具:${a.toolName}`}}]),d.set("session_shutdown",[async()=>{this.ready=!1,this.registrations.clear(),b?.()}]),{path:c,resolvedPath:c,hidden:!0,sourceInfo:{path:c,source:"inline",scope:"temporary",origin:"top-level"},handlers:d,tools:new Map,commands:new Map,flags:new Map,shortcuts:new Map,messageRenderers:new Map}}resources(a){return new Proxy(a,{get:(a,b)=>{if("getSkills"===b)return()=>{let b=a.getSkills();return{...b,skills:b.skills.filter(a=>(0,g.RC)(this.rules?.skills,a.name))}};let c=Reflect.get(a,b,a);return"function"==typeof c?c.bind(a):c}})}attach(a){this.session!==a&&(this.session=a,this.requestedTools=new Set(a.getActiveToolNames()),this.originalSetTools=a.setActiveToolsByName,this.setTools=a.setActiveToolsByName.bind(a),a.setActiveToolsByName=a=>{this.rememberRequestedTools(a),this.refreshTools()},this.refreshTools())}isToolAllowed(a){return(0,g.RC)(this.rules?.tools,a)}restoreBranchSelection(){let a=this.session;!this.disposed&&a&&((0,e.getCurrentSystemMessage)(a.messages)&&(this.requestedTools=new Set(a.getActiveToolNames())),this.refreshTools())}async apply(){let a=this.session;if(this.disposed||!a)return;this.rememberRequestedTools(a.getActiveToolNames()),this.rules=this.readMode(),this.ready=!0,this.refreshTools();let b=[];for(let c of[...this.registrations.values()])try{await this.applyRegistration(c)}catch(e){let d=e instanceof Error?e.message:String(e);console.error("[Pi Desk][Capabilities] 插件应用能力规则失败",{sessionId:a.sessionId,pluginName:c.pluginName,message:d}),b.push(`${c.pluginName}:${d}`)}if(this.refreshTools(),b.length>0)throw Error(`能力规则应用失败:${b.join(";")}`)}dispose(){this.disposed=!0,this.detach()}detach(){this.ready=!1,this.registrations.clear(),this.session&&this.originalSetTools&&(this.session.setActiveToolsByName=this.originalSetTools),this.session=null,this.setTools=null,this.originalSetTools=null,this.requestedTools.clear()}rememberRequestedTools(a){let b=new Set(this.session?.getAllTools().filter(a=>"hidden"!==a.exposure).map(a=>a.name)),c=[...this.requestedTools].filter(a=>b.has(a)&&!(0,g.RC)(this.rules?.tools,a));this.requestedTools=new Set([...a,...c].filter(a=>b.has(a)))}refreshTools(){this.setTools?.([...this.requestedTools].filter(a=>(0,g.RC)(this.rules?.tools,a)))}async applyRegistration(a){let b=this.session;if(!b||this.disposed||this.registrations.get(a.pluginName)!==a)return;let c={tools:this.rules?.tools??{},skills:this.rules?.skills??{},capabilities:this.rules?.plugins?.[a.pluginName]??{}};await a.execute(structuredClone(c),b.extensionRunner.createContext())}register(a){if(!a||"object"!=typeof a)throw Error("能力回调注册无效");let b=a.registration;if(!b||"string"!=typeof b.pluginName||"function"!=typeof b.execute)throw Error("能力回调缺少插件名称或处理函数");if("unregister"===a.type){this.registrations.get(b.pluginName)===b&&this.registrations.delete(b.pluginName);return}if("register"!==a.type)throw Error("能力回调事件无效");if(this.registrations.has(b.pluginName))throw Error(`能力回调已注册:${b.pluginName}`);b.hostManaged=!0,this.registrations.set(b.pluginName,b),this.ready&&this.applyRegistration(b).catch(a=>{console.error("[Pi Desk][Capabilities] 新注册插件应用规则失败",{pluginName:b.pluginName,message:a instanceof Error?a.message:String(a)})})}}d()}catch(a){d(a)}})},26143:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{h:()=>n});var e=c(76760),f=c(75430),g=c(58801),h=c(13982),i=c(73589),j=a([f,g,i]);[f,g,i]=j.then?(await j)():j;let m=[{name:"codemode",create:f.createCodemodeExtension},{name:"tool-search",create:f.createToolSearchExtension},{name:"mcp",create:()=>(0,f.createMcpExtension)({openUrl:()=>void 0})}];function k(a){let b=(0,e.basename)(a.path),c="package"===a.metadata.origin?a.metadata.source.replace(/^npm:/,""):/^(index\.[^.]+|SKILL\.md)$/.test(b)?(0,e.basename)((0,e.dirname)(a.path)):(0,e.basename)(a.path,(0,e.extname)(a.path));return`插件 ${c}
|
|
6
7
|
来源:${a.path}`}async function l(a,b,c){b?.(a);let d=performance.now();try{return await c()}catch(c){let b=Math.round(performance.now()-d);throw console.error("[Pi Desk][PluginResources] 资源步骤失败",{stage:a,durationMs:b,message:c instanceof Error?c.stack??c.message:String(c)}),Error(`${a}
|
|
7
8
|
当前步骤耗时:${b} 毫秒
|
|
8
9
|
原因:${c instanceof Error?c.message:String(c)}`,{cause:c})}finally{let b=Math.round(performance.now()-d);b>=1e3&&console.info("[Pi Desk][PluginResources] 资源步骤耗时",{stage:a,durationMs:b})}}class n{current(a,b,c,d){if(this.selection)return d?.("等待已选择的插件资源准备完成"),this.selection;d?.(`等待插件资源队列
|
|
@@ -12,11 +13,11 @@ ${e(i)}`);for(let a of j)if(!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$
|
|
|
12
13
|
配置目录:${h}`,c,()=>f.ModelRuntime.create({authPath:(0,e.join)(h,"auth.json"),modelsPath:(0,e.join)(h,"models.json")})),o=async j=>{j&&((0,g.N)(),this.reset(),await l("重新读取 Pi 配置",c,()=>i.reload()));let n=await this.current(a,h,i,c),o=n.extensions.filter(a=>a.path.startsWith("builtin:")).map(a=>a.path),p=n.extensions.filter(a=>!a.path.startsWith("builtin:")).map(a=>({name:a.path,factory:async b=>{let d=k(a),e=await l(`${d}
|
|
13
14
|
步骤:导入插件模块`,c,()=>(0,g.G)(a.path).catch(a=>{if(a instanceof Error&&a.message.includes("不支持模块顶层 await"))throw Error("原生扩展不支持模块顶层 await,请将异步初始化放入 async 工厂函数",{cause:a});throw a}));await l(`${d}
|
|
14
15
|
步骤:执行插件工厂`,c,async()=>{if("function"!=typeof e.default)throw Error(`扩展必须导出工厂函数:${a.path}`);await e.default(b)})}})),q=f.SettingsManager.inMemory({},{projectTrusted:i.isProjectTrusted()});d=new f.DefaultResourceLoader({...b,cwd:a,agentDir:h,settingsManager:q,noExtensions:!0,noSkills:!0,noPromptTemplates:!0,noThemes:!0,extensionFactories:[...m.map(({name:a,create:b})=>({name:a,factory:b(),builtin:!0,replaceable:!0})),...p],additionalExtensionPaths:o,additionalSkillPaths:n.skills.map(a=>a.path),additionalPromptTemplatePaths:n.prompts.map(a=>a.path),additionalThemePaths:n.themes.map(a=>a.path)}),c?.("装配插件与会话资源"),await d.reload();let r=(a,b,c)=>{if(b)for(let d of c){let c=(0,e.relative)(d.path,b);if(!(c.startsWith("..")||(0,e.isAbsolute)(c))){a.sourceInfo={...d.metadata,path:b};break}}};for(let a of d.getSkills().skills)r(a,a.filePath,n.skills);for(let a of d.getPrompts().prompts)r(a,a.filePath,n.prompts);for(let a of d.getThemes().themes)r(a,a.sourcePath,n.themes);let s=d.getExtensions();for(let a of s.extensions){let b=n.extensions.find(b=>a.path===`<inline:${b.path}>`);if(b){for(let[d,e]of(a.path=b.path,a.resolvedPath=b.path,a.sourceInfo={...b.metadata,path:b.path},[["session_start","启动会话(session_start)"],["session_shutdown","关闭会话(session_shutdown)"],["resources_discover","补充会话资源(resources_discover)"]])){let f=a.handlers.get(d);f&&a.handlers.set(d,f.map(a=>(...d)=>l(`${k(b)}
|
|
15
|
-
步骤:${e}`,c,()=>a(...d))))}for(let b of a.tools.values())b.sourceInfo=a.sourceInfo;for(let b of a.commands.values())b.sourceInfo=a.sourceInfo}}for(let a of s.errors){let b=n.extensions.find(b=>a.path===`<inline:${b.path}>`);b&&(a.path=b.path)}};await o(!1);let p=new Proxy(d,{get:(a,b)=>{if("reload"===b)return()=>o(!0);let c=Reflect.get(d,b,d);return"function"==typeof c?c.bind(d):c}}),q=p.getExtensions().runtime;for(let{name:a,config:b,extensionPath:c}of q.pendingProviderRegistrations)try{n.registerProvider(a,b)}catch(a){j.push({type:"error",message:`${c}: ${String(a)}`})}for(let{provider:a,extensionPath:b}of q.pendingNativeProviderRegistrations)try{n.registerNativeProvider(a)}catch(a){j.push({type:"error",message:`${b}: ${String(a)}`})}for(let{definition:a,extensionPath:b}of q.pendingVirtualModelRegistrations)try{n.registerVirtualModel(a)}catch(a){j.push({type:"error",message:`${b}: ${String(a)}`})}return q.pendingProviderRegistrations=[],q.pendingNativeProviderRegistrations=[],q.pendingVirtualModelRegistrations=[],await l("刷新模型与认证配置",c,()=>n.refresh({allowNetwork:!1})),j.push(...i.drainErrors().map(({error:a})=>({type:"error",message:a.message}))),{cwd:a,agentDir:h,settingsManager:i,modelRuntime:n,resourceLoader:p,diagnostics:j}}constructor(){this.selection=null}}d()}catch(a){d(a)}})},32980:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{EG:()=>D,JX:()=>C,X9:()=>A,yT:()=>B});var e=c(77598),f=c(58500),g=c(83800),h=c(23272),i=c(26143),j=c(95220),k=c(28802),l=c(77844),m=c(12727),n=c(76452),o=c(49080),p=c(65209),q=c(82459),r=a([g,i,k,l,o,p,q]);function s(a){if(!a)return null;let b=Array.from(a);return b.length<=80?a:`${b.slice(0,79).join("")}…`}[g,i,k,l,o,p,q]=r.then?(await r)():r;class A extends Error{constructor(a){super(`Pi Extension Command was not found: ${a}`),this.name="L4PiNativeCommandNotFoundError"}}class B extends Error{constructor(){super("Pi Direct Bash is already running"),this.name="L4PiDirectBashRunningError"}}class C extends Error{constructor(){super("当前会话正在运行,暂时无法查看系统上下文"),this.name="L4PiModelContextBusyError"}}function t(a){if(!a||"object"!=typeof a)return null;let b=a.role;return"string"==typeof b?b:null}function u(a){if(!a||"object"!=typeof a)return null;let b=a.toolCallId;return"string"==typeof b?b:null}function v(a){return a.images.map(({mimeType:a,width:b,height:c})=>({mimeType:a,width:b,height:c}))}function w(a){return{tempId:a.tempId,text:a.input.text,images:v(a.input)}}function x(a){return{tempId:a.tempId,text:a.initial.text,images:v(a.initial)}}function y(a){let b=a.sourceInfo.path.replaceAll("\\","/");return"llama"!==a.name||!b.includes("/extensions/llama/")}function z(a,b){let c=Date.parse(b);if(!Number.isSafeInteger(c)||c<0)throw Error(`Pi session entry has an invalid timestamp: ${a}`);return c}class D{get pluginRuntime(){return this.initialization.plugins}get capabilityRuntime(){return this.initialization.capabilities}get messageGate(){return this.initialization.messages}constructor(a,b,c=()=>void 0,d={mode:()=>null,rules:()=>void 0},e){for(const f of(this.cwd=a,this.sessionManager=b,this.onEntryAppended=c,this.capabilities=d,this.nativeUi=new h.k,this.listeners=new Set,this.commandLifetime=new AbortController,this.reloadRequested=!1,this.initializationError=null,this.steeringQueue=[],this.followUpQueue=[],this.pendingQueueText=new Map,this.bashTempsById=new Map,this.observedRunPromises=new Set,this.committedEntryIds=new Set,this.backgroundTaskIds=new Set,this.liveUpdatesByTempId=new Map,this.acceptedInputs=[],this.presentedInputTempIds=new Set,this.session=null,this.extensionMode=(0,j.P)()?"basic":"normal",this.sessionLifecycle=null,this.treeNavigation=null,this.treeResumeImmediate=null,this.disposePromise=null,this.initializePromise=null,this.unsubscribeAgent=null,this.unsubscribeSession=null,this.toolRuntime=null,this.toolRuntimeLease=null,this.unsubscribeToolRuntime=null,this.pendingPrompt=null,this.activeMessage=null,this.activeValidation=null,this.activeCompactionTempId=null,this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.startingAcceptedInput=!1,this.compactionResumeScheduled=!1,this.manualCompactionFinishPending=!1,this.publishingModel=!1,this.oversizedToolCallAbortRequested=!1,this.disposed=!1,this.resources=e??new i.h,this.ownsResources=void 0===e,this.initialization=this.createInitialization(),this.observedEntryCount=b.getEntries().length,b.getBranch()))this.committedEntryIds.add(f.id)}createInitialization(){return new g.k({cwd:this.cwd,sessionManager:this.sessionManager,mode:this.extensionMode,resources:this.resources,ui:this.nativeUi,readCapabilities:this.capabilities.rules,onInput:a=>this.validateFinalInput(a.text,a.images,a.streamingBehavior),onTree:()=>this.resetBranchRuntime(),onCommand:(a,b)=>{let c=this.commandLifetime.signal;return(0,q.Fr)(a,{cwd:this.cwd,signal:c,reload:()=>this.requestReload(b),notify:a=>this.notifyCommandResult(b,a,c)})},pluginEvents:{onChanged:()=>this.emitRuntime(),onPush:({pluginName:a,event:b,data:c})=>this.emit({type:"plugin_push",pluginName:a,event:b,data:c}),onTasksChanged:a=>this.updateBackgroundTasks(a),onInvalidUpdate:a=>{console.warn("[Pi Desk][PiChatWorker] 已忽略非法插件运行态更新",{sessionId:this.sessionManager.getSessionId(),cwd:this.cwd,errorName:a instanceof Error?a.name:"UnknownError",message:a instanceof Error?a.message:String(a)})}}})}async notifyCommandResult(a,b,c){c.aborted||(await this.sessionLifecycle,c.aborted||this.disposed||!this.session||this.sessionManager.getBranch().some(b=>"message"===b.type&&"assistant"===b.message.role&&b.message.content.some(b=>"toolCall"===b.type&&b.id===a))&&this.session.resourceLoader.getExtensions().runtime.sendMessage({customType:"pi-desk:command-result",content:b,display:!0,details:{toolCallId:a}},{deliverAs:"steer",triggerTurn:!0}))}requestReload(a){if(this.commandLifetime.signal.throwIfAborted(),this.reloadRequested)throw Error("当前会话已有重载请求,请结束本轮并等待完成通知");return this.reloadRequested=!0,console.info("[Pi Desk][Commands] 当前会话重载请求已接纳",{sessionId:this.sessionManager.getSessionId(),toolCallId:a}),this.reloadWhenIdle(a).finally(()=>{this.reloadRequested=!1}),{mode:"async",message:"已收到当前窗口的 Pi 配置重载请求。请结束本轮对话并等待,无需查询或重复调用;会话空闲后会执行重载,完成后向本会话发送结果消息并自动唤醒。"}}async reloadWhenIdle(a){let b,c=this.commandLifetime.signal,d={sessionId:this.sessionManager.getSessionId(),toolCallId:a};try{do await (0,f.setTimeout)(250,void 0,{signal:c});while(null!==this.readPluginReloadBlockReason());if(console.info("[Pi Desk][Commands] 会话已空闲,开始重载 Pi 配置",d),await this.reload(),c.throwIfAborted(),this.initializationError)throw Error(`扩展未恢复,当前使用基础会话。
|
|
16
|
+
步骤:${e}`,c,()=>a(...d))))}for(let b of a.tools.values())b.sourceInfo=a.sourceInfo;for(let b of a.commands.values())b.sourceInfo=a.sourceInfo}}for(let a of s.errors){let b=n.extensions.find(b=>a.path===`<inline:${b.path}>`);b&&(a.path=b.path)}};await o(!1);let p=new Proxy(d,{get:(a,b)=>{if("reload"===b)return()=>o(!0);let c=Reflect.get(d,b,d);return"function"==typeof c?c.bind(d):c}}),q=p.getExtensions().runtime;for(let{name:a,config:b,extensionPath:c}of q.pendingProviderRegistrations)try{n.registerProvider(a,b)}catch(a){j.push({type:"error",message:`${c}: ${String(a)}`})}for(let{provider:a,extensionPath:b}of q.pendingNativeProviderRegistrations)try{n.registerNativeProvider(a)}catch(a){j.push({type:"error",message:`${b}: ${String(a)}`})}for(let{definition:a,extensionPath:b}of q.pendingVirtualModelRegistrations)try{n.registerVirtualModel(a)}catch(a){j.push({type:"error",message:`${b}: ${String(a)}`})}return q.pendingProviderRegistrations=[],q.pendingNativeProviderRegistrations=[],q.pendingVirtualModelRegistrations=[],await l("刷新模型与认证配置",c,()=>n.refresh({allowNetwork:!1})),j.push(...i.drainErrors().map(({error:a})=>({type:"error",message:a.message}))),{cwd:a,agentDir:h,settingsManager:i,modelRuntime:n,resourceLoader:p,diagnostics:j}}constructor(){this.selection=null}}d()}catch(a){d(a)}})},32980:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{EG:()=>D,JX:()=>C,X9:()=>A,yT:()=>B});var e=c(77598),f=c(58500),g=c(83800),h=c(23272),i=c(26143),j=c(95220),k=c(28802),l=c(77844),m=c(12727),n=c(76452),o=c(49080),p=c(65209),q=c(82459),r=a([g,i,k,l,o,p,q]);function s(a){if(!a)return null;let b=Array.from(a);return b.length<=80?a:`${b.slice(0,79).join("")}…`}[g,i,k,l,o,p,q]=r.then?(await r)():r;class A extends Error{constructor(a){super(`Pi Extension Command was not found: ${a}`),this.name="L4PiNativeCommandNotFoundError"}}class B extends Error{constructor(){super("Pi Direct Bash is already running"),this.name="L4PiDirectBashRunningError"}}class C extends Error{constructor(){super("当前会话正在运行,暂时无法查看系统上下文"),this.name="L4PiModelContextBusyError"}}function t(a){if(!a||"object"!=typeof a)return null;let b=a.role;return"string"==typeof b?b:null}function u(a){if(!a||"object"!=typeof a)return null;let b=a.toolCallId;return"string"==typeof b?b:null}function v(a){return a.images.map(({mimeType:a,width:b,height:c})=>({mimeType:a,width:b,height:c}))}function w(a){return{tempId:a.tempId,text:a.input.text,images:v(a.input)}}function x(a){return{tempId:a.tempId,text:a.initial.text,images:v(a.initial)}}function y(a){let b=a.sourceInfo.path.replaceAll("\\","/");return"llama"!==a.name||!b.includes("/extensions/llama/")}function z(a,b){let c=Date.parse(b);if(!Number.isSafeInteger(c)||c<0)throw Error(`Pi session entry has an invalid timestamp: ${a}`);return c}class D{get pluginRuntime(){return this.initialization.plugins}get capabilityRuntime(){return this.initialization.capabilities}get messageGate(){return this.initialization.messages}constructor(a,b,c=()=>void 0,d={mode:()=>null,rules:()=>void 0},e){for(const f of(this.cwd=a,this.sessionManager=b,this.onEntryAppended=c,this.capabilities=d,this.nativeUi=new h.k,this.listeners=new Set,this.commandLifetime=new AbortController,this.reloadRequested=!1,this.initializationError=null,this.steeringQueue=[],this.followUpQueue=[],this.pendingQueueText=new Map,this.bashTempsById=new Map,this.observedRunPromises=new Set,this.committedEntryIds=new Set,this.backgroundTaskIds=new Set,this.liveUpdatesByTempId=new Map,this.acceptedInputs=[],this.presentedInputTempIds=new Set,this.session=null,this.extensionMode=(0,j.P)()?"basic":"normal",this.sessionLifecycle=null,this.treeNavigation=null,this.treeResumeImmediate=null,this.disposePromise=null,this.initializePromise=null,this.unsubscribeAgent=null,this.unsubscribeSession=null,this.toolRuntime=null,this.toolRuntimeLease=null,this.unsubscribeToolRuntime=null,this.pendingPrompt=null,this.activeMessage=null,this.activeValidation=null,this.activeCompactionTempId=null,this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.startingAcceptedInput=!1,this.compactionResumeScheduled=!1,this.manualCompactionFinishPending=!1,this.publishingModel=!1,this.oversizedToolCallAbortRequested=!1,this.disposed=!1,this.resources=e??new i.h,this.ownsResources=void 0===e,this.initialization=this.createInitialization(),this.observedEntryCount=b.getEntries().length,b.getBranch()))this.committedEntryIds.add(f.id)}createInitialization(){return new g.k({cwd:this.cwd,sessionManager:this.sessionManager,mode:this.extensionMode,resources:this.resources,ui:this.nativeUi,readCapabilities:this.capabilities.rules,onInput:a=>this.validateFinalInput(a.text,a.images,a.streamingBehavior),onMessageEnd:({message:a})=>{if(!this.disposed&&this.oversizedToolCallAbortRequested&&"assistant"===a.role&&("aborted"===a.stopReason||"error"===a.stopReason))return{message:{...a,stopReason:"error",errorMessage:"工具参数流超过 262144 字符上限,本次响应中的工具均未执行。Please retry your request."}}},onTree:()=>this.resetBranchRuntime(),onCommand:(a,b)=>{let c=this.commandLifetime.signal;return(0,q.Fr)(a,{cwd:this.cwd,signal:c,reload:()=>this.requestReload(b),notify:a=>this.notifyCommandResult(b,a,c)})},pluginEvents:{onChanged:()=>this.emitRuntime(),onPush:({pluginName:a,event:b,data:c})=>this.emit({type:"plugin_push",pluginName:a,event:b,data:c}),onTasksChanged:a=>this.updateBackgroundTasks(a),onInvalidUpdate:a=>{console.warn("[Pi Desk][PiChatWorker] 已忽略非法插件运行态更新",{sessionId:this.sessionManager.getSessionId(),cwd:this.cwd,errorName:a instanceof Error?a.name:"UnknownError",message:a instanceof Error?a.message:String(a)})}}})}async notifyCommandResult(a,b,c){c.aborted||(await this.sessionLifecycle,c.aborted||this.disposed||!this.session||this.sessionManager.getBranch().some(b=>"message"===b.type&&"assistant"===b.message.role&&b.message.content.some(b=>"toolCall"===b.type&&b.id===a))&&this.session.resourceLoader.getExtensions().runtime.sendMessage({customType:"pi-desk:command-result",content:b,display:!0,details:{toolCallId:a}},{deliverAs:"steer",triggerTurn:!0}))}requestReload(a){if(this.commandLifetime.signal.throwIfAborted(),this.reloadRequested)throw Error("当前会话已有重载请求,请结束本轮并等待完成通知");return this.reloadRequested=!0,console.info("[Pi Desk][Commands] 当前会话重载请求已接纳",{sessionId:this.sessionManager.getSessionId(),toolCallId:a}),this.reloadWhenIdle(a).finally(()=>{this.reloadRequested=!1}),{mode:"async",message:"已收到当前窗口的 Pi 配置重载请求。请结束本轮对话并等待,无需查询或重复调用;会话空闲后会执行重载,完成后向本会话发送结果消息并自动唤醒。"}}async reloadWhenIdle(a){let b,c=this.commandLifetime.signal,d={sessionId:this.sessionManager.getSessionId(),toolCallId:a};try{do await (0,f.setTimeout)(250,void 0,{signal:c});while(null!==this.readPluginReloadBlockReason());if(console.info("[Pi Desk][Commands] 会话已空闲,开始重载 Pi 配置",d),await this.reload(),c.throwIfAborted(),this.initializationError)throw Error(`扩展未恢复,当前使用基础会话。
|
|
16
17
|
${this.initializationError}`);b="basic"===this.extensionMode?"当前窗口的 Pi 配置已重载完成。服务处于基础模式,未加载外部插件。可以继续处理重载前尚未完成的任务。":"当前窗口的 Pi 配置已重载完成,已重新加载配置及本机已安装插件的当前代码。可以继续处理重载前尚未完成的任务。",console.info("[Pi Desk][Commands] 当前会话重载完成",d)}catch(e){if(c.aborted)return;let a=e instanceof Error?e.message:String(e);console.warn("[Pi Desk][Commands] 当前会话重载失败",{...d,reason:a}),b=`当前窗口的 Pi 配置重载失败。
|
|
17
|
-
原因:${a}`}try{if(this.sessionLifecycle||!this.session)throw Error("会话尚未恢复,无法投递重载结果");await this.notifyCommandResult(a,b,c)}catch(a){if(c.aborted)return;console.warn("[Pi Desk][Commands] 会话重载结果投递失败",{...d,message:a instanceof Error?a.message:String(a)})}}getBackgroundTaskIds(){return this.pluginRuntime.activeTaskIds()}getTaskRecord(a){return this.pluginRuntime.taskRecord(a)}async watchTaskDetail(a,b){return await this.ensureSession(),this.pluginRuntime.watchTaskDetail(a,b)}async readTaskMessage(a,b){return await this.ensureSession(),this.pluginRuntime.readTaskMessage(a,b)}async readTaskImage(a,b,c){return await this.ensureSession(),this.pluginRuntime.readTaskImage(a,b,c)}async interruptTask(a){await this.ensureSession(),await this.pluginRuntime.interruptTask(a)}async invokePluginMethod(a,b,c,d){let e=await this.ensureSession();return this.pluginRuntime.invokeMethod(a,b,c,d,e.extensionRunner.createContext())}async listNativeCommands(){let a=await this.ensureSession(),b=a.extensionRunner.getRegisteredCommands(),c=new Set(b.map(a=>a.invocationName)),d=b.filter(y).map(a=>({name:a.invocationName,description:s(a.description),source:"extension"})),e=a.resourceLoader.getSkills().skills.map(a=>({name:`skill:${a.name}`,description:s(a.description),source:"skill"})).filter(a=>!c.has(a.name)),f=new Set(e.map(a=>a.name)),g=a.promptTemplates.filter(a=>!c.has(a.name)&&!f.has(a.name)).map(a=>({name:a.name,description:s(a.description),source:"prompt"}));return[...d,...g,...e]}async executeNativeCommand(a,b){let c=await this.ensureSession(),d=c.extensionRunner.getCommand(a);if(!d)throw new A(a);try{await d.handler(b,c.extensionRunner.createCommandContext())}catch(b){let a=b instanceof Error?b:Error(String(b));throw c.extensionRunner.emitError({extensionPath:d.sourceInfo.path,event:`command:${d.invocationName}`,error:a.message,...a.stack?{stack:a.stack}:{}}),a}}async listNativeTools(a=!1){if(a&&!this.session)return[];let b=await this.ensureSession(),c=new Set(b.getActiveToolNames()),d=new Map;for(let a of b.resourceLoader.getExtensions().extensions)for(let b of a.tools.keys())d.set(b,a.sourceInfo?.path??a.path);return b.getAllTools().map(a=>({name:a.name,description:a.description,parameters:JSON.parse(JSON.stringify(a.parameters)),active:c.has(a.name),exposure:a.exposure??"direct",source:a.namespace?.name??d.get(a.name)??null,blockedByMode:!this.capabilityRuntime.isToolAllowed(a.name)}))}async executeDirectBash(a){let b=await this.ensureSession();if(b.isBashRunning)throw new B;let c=(0,e.randomUUID)();console.info("[Pi Desk][PiChatWorker] Direct Bash 已开始",{sessionId:b.sessionId,executionId:c,excludeFromContext:a.excludeFromContext,commandLength:a.command.length}),this.startBash(c,a.command);try{let d=await b.extensionRunner.emitUserBash({type:"user_bash",command:a.command,excludeFromContext:a.excludeFromContext,cwd:this.cwd}),e=d?.result?d.result:await b.executeBash(a.command,void 0,{excludeFromContext:a.excludeFromContext,id:c,operations:d?.operations});return d?.result&&b.recordBashResult(a.command,e,{excludeFromContext:a.excludeFromContext}),this.completeBash(c,e),{output:e.output,exitCode:e.exitCode??null,cancelled:e.cancelled,truncated:e.truncated,fullOutputPath:e.fullOutputPath??null}}catch(a){throw this.discardBash(c),a}finally{console.info("[Pi Desk][PiChatWorker] Direct Bash 已结束",{sessionId:b.sessionId,executionId:c})}}async abortDirectBash(){(await this.ensureSession()).abortBash()}assertIdle(){if(this.disposed||this.initializePromise)throw Error("Pi 会话仍在初始化或关闭,不能切换分支");if(this.sessionLifecycle)throw Error("Pi 会话生命周期仍在处理,不能切换分支");if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能切换分支");if(this.activeCompactionTempId)throw Error("上下文压缩期间不能切换分支");if(this.session&&!this.session.isIdle)throw Error("主 Agent 运行时不能切换分支")}readPluginReloadBlockReason(){return this.disposed?"Pi Worker 已释放":this.sessionLifecycle?"Pi 扩展重载或关闭仍未完成":this.initializePromise?"AgentSession 正在初始化":this.startingAcceptedInput||this.acceptedInputs.length>0||this.acceptedInputTimer?"聊天输入正在接纳":this.activeValidation||this.pendingPrompt?"聊天输入正在校验":this.activeCompactionTempId?"上下文正在压缩":this.steeringQueue.length>0||this.followUpQueue.length>0?"聊天队列不为空":this.observedRunPromises.size>0?"Agent 运行仍在收尾":this.backgroundTaskIds.size>0?"插件后台任务仍在运行":this.session?.isBashRunning?"Bash 正在运行":this.session&&!this.session.isIdle?"主 Agent 正在运行":this.activeMessage||(this.toolRuntime?.size??0)>0||this.bashTempsById.size>0?"实时消息仍在处理":null}subscribe(a){if(this.disposed)throw Error("Pi chat worker has been disposed");return this.listeners.add(a),()=>this.listeners.delete(a)}async getRuntime(){let a=this.ensureSession(),b=()=>void 0,c=new Promise(a=>{b=this.nativeUi.subscribe(()=>{this.nativeUi.hasPending&&a()}),this.nativeUi.hasPending&&a()});try{return await Promise.race([a,c]),this.runtimeSnapshot()}finally{b()}}async readModelContext(){if(this.startingAcceptedInput||this.acceptedInputs.length>0||this.activeValidation||this.pendingPrompt||this.activeCompactionTempId||this.observedRunPromises.size>0)throw new C;let a=await this.ensureSession();if(!a.isIdle||a.isBashRunning)throw new C;let b=new Set(a.getActiveToolNames()),c=a.getAllTools().filter(a=>b.has(a.name)).map(a=>{var b;let c;return{name:a.name,description:a.description,parameters:(b=a.parameters,(c=function(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}(b))&&"object"==typeof c&&!Array.isArray(c)?c:{})}}),d={systemPrompt:a.systemPrompt,tools:c};return console.info("[Pi Desk][PiChatWorker] 已读取模型上下文",{sessionId:a.sessionId,toolCount:d.tools.length}),d}async listModels(){return(0,o.A)(this.sessionLifecycle?null:this.session,this.cwd)}async send(a){let b=await this.ensureSession(),c=(0,l.ni)(a);if(c.images.length>0&&!b.model?.input.includes("image"))throw Error("当前模型不支持图片输入");let d=this.messageGate.isBlocking;"follow_up"!==a.mode||d||this.resolveMode(b,a.mode),d&&(0,l.mu)([...this.steeringQueue.map(a=>a.input),...this.followUpQueue.map(a=>a.input),...this.acceptedInputs.filter(a=>a.deferredByCompaction).map(a=>a.initial),c]);let f=(0,e.randomUUID)(),g={tempId:f,input:a,initial:c,deferredByCompaction:d,allowIdleFollowUp:d};return this.acceptedInputs.push(g),d&&this.messageGate.defer("web-user-message",()=>this.startDeferredAcceptedInput(g))?this.emitRuntime():(g.deferredByCompaction=!1,this.scheduleAcceptedInputStart()),console.info("[Pi Desk][PiChatWorker] 聊天输入已由 Worker 接管",{sessionId:b.sessionId,tempId:f,requestedMode:a.mode,deferredByCompaction:d}),{tempId:f}}async interrupt(){this.nativeUi.cancelAll(),this.discardAcceptedInputs();let a=await this.ensureSession();a.abortRetry(),a.abortCompaction(),a.agent.abort()}async navigateTree(a){let b=await this.ensureSession();this.assertIdle(),this.treeResumeImmediate&&clearImmediate(this.treeResumeImmediate),this.treeResumeImmediate=null;let c=!1;try{return await this.runSessionLifecycle(async()=>{let d=this.sessionManager.getLeafId(),e={committed:!1};this.treeNavigation=e,this.messageGate.pause();try{this.initialization.setStage("切换会话树"),(c=!(await b.navigateTree(a,{summarize:!1})).cancelled)&&await this.capabilityRuntime.apply()}catch(a){throw e.committed||this.sessionManager.getLeafId()===d||this.resetBranchRuntime(),a}finally{try{if(e.committed)for(let a of(this.syncOwnerAppendedEntries(),this.observedEntryCount=this.sessionManager.getEntries().length,this.committedEntryIds.clear(),this.sessionManager.getBranch()))this.committedEntryIds.add(a.id)}finally{this.treeNavigation=null,e.committed||(this.reconcileAppendedEntries(),this.emitTreeState()),this.scheduleTreeMessageResume()}}}),c}catch(a){throw b.abortCompaction(),a}}resetBranchRuntime(){this.treeNavigation&&(this.treeNavigation.committed=!0),this.commandLifetime.abort(),this.commandLifetime=new AbortController,this.acceptedInputTimer&&clearTimeout(this.acceptedInputTimer),this.compactionResumeTimer&&clearTimeout(this.compactionResumeTimer),this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.messageGate.discardPending(),this.toolRuntime?.discardAll(),this.clearLiveUpdates(),this.clearMemory(),this.nativeUi.reset(),this.capabilityRuntime.restoreBranchSelection(),this.pluginRuntime.resetBranch()}scheduleTreeMessageResume(){if(this.disposed)return;let a=setImmediate(()=>{(async()=>{await this.sessionLifecycle?.catch(()=>void 0),this.treeResumeImmediate!==a||(this.treeResumeImmediate=null,this.disposed||this.treeNavigation||!this.session||(await this.messageGate.resume(),this.disposed||(this.reconcileAppendedEntries(),this.emitTreeState(),this.scheduleAcceptedInputStart())))})().catch(b=>{this.treeResumeImmediate===a&&(this.treeResumeImmediate=null),console.warn("[Pi Desk][PiChatWorker] 分支消息恢复失败",{error:b})})});this.treeResumeImmediate=a}emitTreeState(){this.emitBackgroundTasks(),this.emit({type:"session_info_changed",sessionTitle:this.sessionManager.getSessionName()?.trim()||null}),this.emitRuntime()}get isInitialized(){return null!==this.session}async reload(a){let b=a??((0,j.P)()?"basic":"normal");if((0,j.P)()&&"normal"===b)throw Error("服务处于基础模式,请正常启动 Pi Desk 后再加载外部扩展");let c=this.readPluginReloadBlockReason();if(c)throw Error(`当前会话不能重载 Pi 配置:${c}`);if(b!==this.extensionMode||!this.session)return void await this.runSessionLifecycle(async()=>{if(this.releaseSessionBindings(),this.initialization.dispose(),this.session=null,this.updateBackgroundTasks([]),this.disposed)throw Error("Pi Worker 已释放");this.extensionMode=b,this.initialization=this.createInitialization();try{await this.createSession("normal"===b)}finally{this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()})}},125e3);let d=await this.ensureSession(),e=this.readPluginReloadBlockReason();if(e)throw Error(`当前会话不能重载 Pi 配置:${e}`);await this.runSessionLifecycle(async()=>{this.unsubscribeAgent?.(),this.unsubscribeAgent=null;try{await this.initialization.reload()}catch(a){this.restoreBasicInitialization(a),await this.createSession();return}finally{this.disposed||this.session!==d||this.unsubscribeAgent||(this.unsubscribeAgent=d.agent.subscribe(a=>{this.session===d&&this.handleAgentEvent(a)}))}this.disposed||this.session!==d||(this.messageGate.installExtensionRuntime(d.resourceLoader.getExtensions().runtime),await this.capabilityRuntime.apply(),this.reconcileAppendedEntries(),this.emitRuntime())})}waitForSessionLifecycle(a,b=15e3){return this.nativeUi.waitForOperation(a,b,()=>Error(`Pi 扩展生命周期未在截止时间内完成
|
|
18
|
+
原因:${a}`}try{if(this.sessionLifecycle||!this.session)throw Error("会话尚未恢复,无法投递重载结果");await this.notifyCommandResult(a,b,c)}catch(a){if(c.aborted)return;console.warn("[Pi Desk][Commands] 会话重载结果投递失败",{...d,message:a instanceof Error?a.message:String(a)})}}getBackgroundTaskIds(){return this.pluginRuntime.activeTaskIds()}getTaskRecord(a){return this.pluginRuntime.taskRecord(a)}async watchTaskDetail(a,b){return await this.ensureSession(),this.pluginRuntime.watchTaskDetail(a,b)}async readTaskMessage(a,b){return await this.ensureSession(),this.pluginRuntime.readTaskMessage(a,b)}async readTaskImage(a,b,c){return await this.ensureSession(),this.pluginRuntime.readTaskImage(a,b,c)}async interruptTask(a){await this.ensureSession(),await this.pluginRuntime.interruptTask(a)}async invokePluginMethod(a,b,c,d){let e=await this.ensureSession();return this.pluginRuntime.invokeMethod(a,b,c,d,e.extensionRunner.createContext())}async listNativeCommands(){let a=await this.ensureSession(),b=a.extensionRunner.getRegisteredCommands(),c=new Set(b.map(a=>a.invocationName)),d=b.filter(y).map(a=>({name:a.invocationName,description:s(a.description),source:"extension"})),e=a.resourceLoader.getSkills().skills.map(a=>({name:`skill:${a.name}`,description:s(a.description),source:"skill"})).filter(a=>!c.has(a.name)),f=new Set(e.map(a=>a.name)),g=a.promptTemplates.filter(a=>!c.has(a.name)&&!f.has(a.name)).map(a=>({name:a.name,description:s(a.description),source:"prompt"}));return[...d,...g,...e]}async executeNativeCommand(a,b){let c=await this.ensureSession(),d=c.extensionRunner.getCommand(a);if(!d)throw new A(a);try{await d.handler(b,c.extensionRunner.createCommandContext())}catch(b){let a=b instanceof Error?b:Error(String(b));throw c.extensionRunner.emitError({extensionPath:d.sourceInfo.path,event:`command:${d.invocationName}`,error:a.message,...a.stack?{stack:a.stack}:{}}),a}}async listNativeTools(a=!1){if(a&&!this.session)return[];let b=await this.ensureSession(),c=new Set(b.getActiveToolNames()),d=new Map;for(let a of b.resourceLoader.getExtensions().extensions)for(let b of a.tools.keys())d.set(b,a.sourceInfo?.path??a.path);return b.getAllTools().map(a=>({name:a.name,description:a.description,parameters:JSON.parse(JSON.stringify(a.parameters)),active:c.has(a.name),exposure:a.exposure??"direct",source:a.namespace?.name??d.get(a.name)??null,blockedByMode:!this.capabilityRuntime.isToolAllowed(a.name)}))}async executeDirectBash(a){let b=await this.ensureSession();if(b.isBashRunning)throw new B;let c=(0,e.randomUUID)();console.info("[Pi Desk][PiChatWorker] Direct Bash 已开始",{sessionId:b.sessionId,executionId:c,excludeFromContext:a.excludeFromContext,commandLength:a.command.length}),this.startBash(c,a.command);try{let d=await b.extensionRunner.emitUserBash({type:"user_bash",command:a.command,excludeFromContext:a.excludeFromContext,cwd:this.cwd}),e=d?.result?d.result:await b.executeBash(a.command,void 0,{excludeFromContext:a.excludeFromContext,id:c,operations:d?.operations});return d?.result&&b.recordBashResult(a.command,e,{excludeFromContext:a.excludeFromContext}),this.completeBash(c,e),{output:e.output,exitCode:e.exitCode??null,cancelled:e.cancelled,truncated:e.truncated,fullOutputPath:e.fullOutputPath??null}}catch(a){throw this.discardBash(c),a}finally{console.info("[Pi Desk][PiChatWorker] Direct Bash 已结束",{sessionId:b.sessionId,executionId:c})}}async abortDirectBash(){(await this.ensureSession()).abortBash()}assertIdle(){if(this.disposed||this.initializePromise)throw Error("Pi 会话仍在初始化或关闭,不能切换分支");if(this.sessionLifecycle)throw Error("Pi 会话生命周期仍在处理,不能切换分支");if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能切换分支");if(this.activeCompactionTempId)throw Error("上下文压缩期间不能切换分支");if(this.session&&!this.session.isIdle)throw Error("主 Agent 运行时不能切换分支")}readPluginReloadBlockReason(){return this.disposed?"Pi Worker 已释放":this.sessionLifecycle?"Pi 扩展重载或关闭仍未完成":this.initializePromise?"AgentSession 正在初始化":this.startingAcceptedInput||this.acceptedInputs.length>0||this.acceptedInputTimer?"聊天输入正在接纳":this.activeValidation||this.pendingPrompt?"聊天输入正在校验":this.activeCompactionTempId?"上下文正在压缩":this.steeringQueue.length>0||this.followUpQueue.length>0?"聊天队列不为空":this.observedRunPromises.size>0?"Agent 运行仍在收尾":this.backgroundTaskIds.size>0?"插件后台任务仍在运行":this.session?.isBashRunning?"Bash 正在运行":this.session&&!this.session.isIdle?"主 Agent 正在运行":this.activeMessage||(this.toolRuntime?.size??0)>0||this.bashTempsById.size>0?"实时消息仍在处理":null}subscribe(a){if(this.disposed)throw Error("Pi chat worker has been disposed");return this.listeners.add(a),()=>this.listeners.delete(a)}async getRuntime(){let a=this.ensureSession(),b=()=>void 0,c=new Promise(a=>{b=this.nativeUi.subscribe(()=>{this.nativeUi.hasPending&&a()}),this.nativeUi.hasPending&&a()});try{return await Promise.race([a,c]),this.runtimeSnapshot()}finally{b()}}async readModelContext(){if(this.startingAcceptedInput||this.acceptedInputs.length>0||this.activeValidation||this.pendingPrompt||this.activeCompactionTempId||this.observedRunPromises.size>0)throw new C;let a=await this.ensureSession();if(!a.isIdle||a.isBashRunning)throw new C;let b=new Set(a.getActiveToolNames()),c=a.getAllTools().filter(a=>b.has(a.name)).map(a=>{var b;let c;return{name:a.name,description:a.description,parameters:(b=a.parameters,(c=function(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}(b))&&"object"==typeof c&&!Array.isArray(c)?c:{})}}),d={systemPrompt:a.systemPrompt,tools:c};return console.info("[Pi Desk][PiChatWorker] 已读取模型上下文",{sessionId:a.sessionId,toolCount:d.tools.length}),d}async listModels(){return(0,o.A)(this.sessionLifecycle?null:this.session,this.cwd)}async send(a){let b=await this.ensureSession(),c=(0,l.ni)(a);if(c.images.length>0&&!b.model?.input.includes("image"))throw Error("当前模型不支持图片输入");let d=this.messageGate.isBlocking;"follow_up"!==a.mode||d||this.resolveMode(b,a.mode),d&&(0,l.mu)([...this.steeringQueue.map(a=>a.input),...this.followUpQueue.map(a=>a.input),...this.acceptedInputs.filter(a=>a.deferredByCompaction).map(a=>a.initial),c]);let f=(0,e.randomUUID)(),g={tempId:f,input:a,initial:c,deferredByCompaction:d,allowIdleFollowUp:d};return this.acceptedInputs.push(g),d&&this.messageGate.defer("web-user-message",()=>this.startDeferredAcceptedInput(g))?this.emitRuntime():(g.deferredByCompaction=!1,this.scheduleAcceptedInputStart()),console.info("[Pi Desk][PiChatWorker] 聊天输入已由 Worker 接管",{sessionId:b.sessionId,tempId:f,requestedMode:a.mode,deferredByCompaction:d}),{tempId:f}}async interrupt(){this.nativeUi.cancelAll(),this.discardAcceptedInputs();let a=await this.ensureSession();this.oversizedToolCallAbortRequested=!1,await a.abort()}async navigateTree(a){let b=await this.ensureSession();this.assertIdle(),this.treeResumeImmediate&&clearImmediate(this.treeResumeImmediate),this.treeResumeImmediate=null;let c=!1;try{return await this.runSessionLifecycle(async()=>{let d=this.sessionManager.getLeafId(),e={committed:!1};this.treeNavigation=e,this.messageGate.pause();try{this.initialization.setStage("切换会话树"),(c=!(await b.navigateTree(a,{summarize:!1})).cancelled)&&await this.capabilityRuntime.apply()}catch(a){throw e.committed||this.sessionManager.getLeafId()===d||this.resetBranchRuntime(),a}finally{try{if(e.committed)for(let a of(this.syncOwnerAppendedEntries(),this.observedEntryCount=this.sessionManager.getEntries().length,this.committedEntryIds.clear(),this.sessionManager.getBranch()))this.committedEntryIds.add(a.id)}finally{this.treeNavigation=null,e.committed||(this.reconcileAppendedEntries(),this.emitTreeState()),this.scheduleTreeMessageResume()}}}),c}catch(a){throw b.abortCompaction(),a}}resetBranchRuntime(){this.treeNavigation&&(this.treeNavigation.committed=!0),this.commandLifetime.abort(),this.commandLifetime=new AbortController,this.acceptedInputTimer&&clearTimeout(this.acceptedInputTimer),this.compactionResumeTimer&&clearTimeout(this.compactionResumeTimer),this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.messageGate.discardPending(),this.toolRuntime?.discardAll(),this.clearLiveUpdates(),this.clearMemory(),this.nativeUi.reset(),this.capabilityRuntime.restoreBranchSelection(),this.pluginRuntime.resetBranch()}scheduleTreeMessageResume(){if(this.disposed)return;let a=setImmediate(()=>{(async()=>{await this.sessionLifecycle?.catch(()=>void 0),this.treeResumeImmediate!==a||(this.treeResumeImmediate=null,this.disposed||this.treeNavigation||!this.session||(await this.messageGate.resume(),this.disposed||(this.reconcileAppendedEntries(),this.emitTreeState(),this.scheduleAcceptedInputStart())))})().catch(b=>{this.treeResumeImmediate===a&&(this.treeResumeImmediate=null),console.warn("[Pi Desk][PiChatWorker] 分支消息恢复失败",{error:b})})});this.treeResumeImmediate=a}emitTreeState(){this.emitBackgroundTasks(),this.emit({type:"session_info_changed",sessionTitle:this.sessionManager.getSessionName()?.trim()||null}),this.emitRuntime()}get isInitialized(){return null!==this.session}async reload(a){let b=a??((0,j.P)()?"basic":"normal");if((0,j.P)()&&"normal"===b)throw Error("服务处于基础模式,请正常启动 Pi Desk 后再加载外部扩展");let c=this.readPluginReloadBlockReason();if(c)throw Error(`当前会话不能重载 Pi 配置:${c}`);if(b!==this.extensionMode||!this.session)return void await this.runSessionLifecycle(async()=>{if(this.releaseSessionBindings(),this.initialization.dispose(),this.session=null,this.updateBackgroundTasks([]),this.disposed)throw Error("Pi Worker 已释放");this.extensionMode=b,this.initialization=this.createInitialization();try{await this.createSession("normal"===b)}finally{this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()})}},125e3);let d=await this.ensureSession(),e=this.readPluginReloadBlockReason();if(e)throw Error(`当前会话不能重载 Pi 配置:${e}`);await this.runSessionLifecycle(async()=>{this.unsubscribeAgent?.(),this.unsubscribeAgent=null;try{await this.initialization.reload()}catch(a){this.restoreBasicInitialization(a),await this.createSession();return}finally{this.disposed||this.session!==d||this.unsubscribeAgent||(this.unsubscribeAgent=d.agent.subscribe(a=>{this.session===d&&this.handleAgentEvent(a)}))}this.disposed||this.session!==d||(this.messageGate.installExtensionRuntime(d.resourceLoader.getExtensions().runtime),await this.capabilityRuntime.apply(),this.reconcileAppendedEntries(),this.emitRuntime())})}waitForSessionLifecycle(a,b=15e3){return this.nativeUi.waitForOperation(a,b,()=>Error(`Pi 扩展生命周期未在截止时间内完成
|
|
18
19
|
${this.initialization.describeStage()}`))}async runSessionLifecycle(a,b=15e3){if(this.sessionLifecycle)throw Error("Pi 扩展生命周期尚未完成");let c=Promise.resolve().then(()=>{if(this.disposed)throw Error("Pi Worker 已释放");return a()});this.sessionLifecycle=c;let d=()=>{this.sessionLifecycle===c&&(this.sessionLifecycle=null)};c.then(d,d),await this.waitForSessionLifecycle(c,b)}releaseSessionBindings(){this.unsubscribeAgent?.(),this.unsubscribeSession?.(),this.unsubscribeToolRuntime?.(),this.toolRuntimeLease?.release(),this.unsubscribeAgent=null,this.unsubscribeSession=null,this.unsubscribeToolRuntime=null,this.toolRuntimeLease=null,this.toolRuntime=null}async compact(){if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能压缩上下文");if(this.activeCompactionTempId)throw Error("上下文正在压缩");this.messageGate.pause();let a=null;try{if(!(a=await this.ensureSession()).isIdle)throw Error("主 Agent 运行时不能压缩上下文");if(a.isBashRunning)throw Error("Bash 运行时不能压缩上下文");let b=this.unsubscribeAgent;this.unsubscribeAgent=null,b?.();try{await a.compact()}finally{this.disposed||this.session!==a||this.unsubscribeAgent||(this.unsubscribeAgent=a.agent.subscribe(a=>this.handleAgentEvent(a)))}}finally{this.scheduleCompactionMessageResume()}}async restoreQueuedMessages(){let a=await this.ensureSession(),b=this.acceptedInputs.splice(0),c=b.filter(a=>"auto"===a.input.mode).map(a=>a.initial),d=b.filter(a=>"follow_up"===a.input.mode).map(a=>a.initial),e=this.steeringQueue.splice(0),f=this.followUpQueue.splice(0),g=e.map(a=>a.input),h=f.map(a=>a.input),i=[...g,...c,...h,...d];for(let c of(this.pendingQueueText.clear(),a.clearQueue(),b))this.discardPresentedInput(c.tempId);for(let a of[...e,...f])this.discardPresentedInput(a.tempId);return this.emitRuntime(),{text:i.map(a=>a.text).filter(a=>a.trim()).join("\n\n"),images:i.flatMap(a=>a.images.map(a=>({...a})))}}async applyCapabilityMode(){let a=null!==this.session;await this.ensureSession();try{a&&await this.capabilityRuntime.apply()}finally{this.emitRuntime()}}async setTitle(a){let b=await this.ensureSession(),c=a.replace(/[\r\n]+/g," ").trim();this.sessionManager.getSessionName()!==c&&b.setSessionName(c)}async setModel(a){if(this.startingAcceptedInput||this.acceptedInputs.length>0)throw Error("主 Agent 正在接管聊天输入,不能切换模型");if(this.activeCompactionTempId)throw Error("上下文压缩期间不能切换模型");let b=await this.ensureSession();if(!b.isIdle)throw Error("主 Agent 运行时不能切换模型");let c=b.modelRuntime.getModel(a.provider,a.modelId);if(!c)throw Error("模型不存在或当前不可用");if(!(0,k.getSupportedThinkingLevels)(c).includes(a.thinkingLevel))throw Error("模型不支持该思考等级");this.publishingModel=!0;try{await b.setModel(c),b.setThinkingLevel(a.thinkingLevel)}finally{this.publishingModel=!1,this.emitRuntime()}}dispose(){return this.disposePromise??=this.disposeSession().finally(()=>{this.ownsResources&&this.resources.reset()}),this.disposePromise}async disposeSession(){this.disposed=!0,this.nativeUi.dispose(),this.commandLifetime.abort(),this.treeResumeImmediate&&clearImmediate(this.treeResumeImmediate),this.treeResumeImmediate=null,this.acceptedInputTimer&&clearTimeout(this.acceptedInputTimer),this.compactionResumeTimer&&clearTimeout(this.compactionResumeTimer),this.acceptedInputTimer=null,this.compactionResumeTimer=null,this.messageGate.dispose(),this.clearLiveUpdates(),this.listeners.clear();let a=this.session;a||this.initialization.dispose(),a?.clearQueue(),a?.abortCompaction();let b=a?.abort().catch(()=>void 0);await Promise.allSettled([this.initializePromise,this.sessionLifecycle,b]);let c=this.session;if(!c){this.capabilityRuntime.dispose(),this.pluginRuntime.dispose(),this.clearMemory();return}c!==a&&(c.clearQueue(),c.abortCompaction(),await c.abort().catch(()=>void 0));try{await c.extensionRunner.emit({type:"session_shutdown",reason:"quit"})}catch(a){console.warn("[Pi Desk][PiChatWorker] 扩展关闭失败",{sessionId:c.sessionId,message:a instanceof Error?a.message:String(a)})}this.releaseSessionBindings(),this.initialization.dispose(!1),this.session=null,this.initializationError=null,await Promise.allSettled([...this.observedRunPromises]),this.clearMemory()}resolveMode(a,b,c=!1){if("follow_up"===b){if(a.isStreaming)return"followUp";if(c)return"prompt";throw Error("主 Agent 已空闲,不能添加 Follow-up")}return a.isStreaming?"steer":"prompt"}scheduleCompactionMessageResume(){this.disposed||this.compactionResumeScheduled||this.compactionResumeTimer||(this.compactionResumeScheduled=!0,queueMicrotask(()=>{if(this.compactionResumeScheduled=!1,!this.disposed){if(this.session?.isCompacting){this.compactionResumeTimer=setTimeout(()=>{this.compactionResumeTimer=null,this.scheduleCompactionMessageResume()},0);return}this.activeValidation?.compactionStarted||this.messageGate.resume().then(()=>{this.disposed||(this.scheduleAcceptedInputStart(),this.manualCompactionFinishPending&&(this.manualCompactionFinishPending=!1,this.session?.isStreaming||this.emit({type:"main_operation_finished"})),this.emitRuntime())})}}))}scheduleAcceptedInputStart(){this.disposed||this.startingAcceptedInput||0===this.acceptedInputs.length||this.acceptedInputTimer||this.messageGate.isBlocking||(this.acceptedInputTimer=setTimeout(()=>{this.acceptedInputTimer=null,this.startAcceptedInput()},0))}startAcceptedInput(){if(this.disposed||this.startingAcceptedInput||this.messageGate.isBlocking)return;let a=this.acceptedInputs.shift();a&&(this.startingAcceptedInput=!0,this.runAcceptedInput(a).finally(()=>{this.startingAcceptedInput=!1,this.scheduleAcceptedInputStart()}))}async startDeferredAcceptedInput(a){if(this.disposed)return;let b=this.acceptedInputs.indexOf(a);if(!(b<0)){this.acceptedInputs.splice(b,1),a.deferredByCompaction=!1,this.emitRuntime(),this.startingAcceptedInput=!0;try{await this.runAcceptedInput(a)}finally{this.startingAcceptedInput=!1}}}async runAcceptedInput(a){let b=null;try{let c,d=await this.ensureSession(),e=this.resolveMode(d,a.input.mode,a.allowIdleFollowUp);b={tempId:a.tempId,requestedMode:a.input.mode,mode:e,prepared:null,error:null,compactionStarted:!1,allowIdleFollowUp:a.allowIdleFollowUp},this.activeValidation=b,"prompt"===e&&(this.presentedInputTempIds.add(a.tempId),this.emit({type:"message_start",tempId:a.tempId,message:{type:"user",text:a.initial.text,images:v(a.initial)}}));let f=new Promise(a=>{c=a}),g=null,h=d.prompt(a.input.text,{images:(0,l.ti)(a.initial.images),source:"rpc",streamingBehavior:"follow_up"===a.input.mode?"followUp":"steer",preflightResult:()=>c(!0)}).then(()=>{c(!1),this.finishObservedSend(b)},a=>{g=a,c(!1),this.finishObservedSend(b)});this.observeRun(h);let i=await f;if(this.activeValidation===b&&(this.activeValidation=null),b.compactionStarted&&this.scheduleCompactionMessageResume(),b.error)throw b.error;if(!i)throw await h,g instanceof Error?g:Error("Pi 拒绝接纳聊天输入");if(!b.prepared){this.discardPresentedInput(a.tempId),console.info("[Pi Desk][PiChatWorker] 聊天输入已由扩展直接处理",{sessionId:d.sessionId,tempId:a.tempId});return}console.info("[Pi Desk][PiChatWorker] Pi 已开始处理已接管聊天输入",{sessionId:d.sessionId,tempId:a.tempId,mode:b.mode})}catch(c){this.activeValidation===b&&(this.activeValidation=null),b&&(this.cancelPreflightOperation(b),b.compactionStarted&&this.scheduleCompactionMessageResume()),this.discardPresentedInput(a.tempId),console.warn("[Pi Desk][PiChatWorker] 已撤回未被 Pi 接纳的聊天输入",{sessionId:this.session?.sessionId??this.sessionManager.getSessionId(),tempId:a.tempId,errorName:c instanceof Error?c.name:"UnknownError"})}}discardAcceptedInputs(){let a=this.acceptedInputs.splice(0);for(let b of a)this.discardPresentedInput(b.tempId);a.some(a=>a.deferredByCompaction)&&this.emitRuntime()}discardPresentedInput(a){this.presentedInputTempIds.delete(a)&&this.emit({type:"message_discard",tempId:a})}async ensureSession(){if(this.disposed)throw Error("Pi chat worker has been disposed");if(this.sessionLifecycle)throw Error("Pi 扩展生命周期尚未完成,请等待或在新会话使用基础聊天");return this.session?this.session:(this.initializePromise||(this.initializePromise=this.createSession().finally(()=>{this.initializePromise=null})),this.initializePromise)}restoreBasicInitialization(a){if(this.releaseSessionBindings(),this.initialization.dispose(),this.session=null,this.disposed||"basic"===this.extensionMode)throw a;let b=a instanceof Error?a.message:String(a);this.initializationError=b.length>32e3?`${b.slice(0,31970)}
|
|
19
|
-
…诊断过长,已截断`:b,this.extensionMode="basic",this.updateBackgroundTasks([]),this.initialization=this.createInitialization(),console.warn("[Pi Desk][PiChatWorker] 扩展加载失败,切换基础聊天",{sessionId:this.sessionManager.getSessionId(),cwd:this.cwd,message:this.initializationError})}async createSession(a=!1){let b;try{b=await this.initialization.start(a)}catch(a){this.restoreBasicInitialization(a),b=await this.initialization.start()}if(this.disposed)throw this.initialization.dispose(),Error("Pi Worker 已释放");try{this.syncOwnerAppendedEntries()}catch(a){throw this.initialization.dispose(),a}return this.session=b,"normal"===this.extensionMode&&(this.initializationError=null),this.unsubscribeAgent=b.agent.subscribe(a=>{this.session===b&&this.handleAgentEvent(a)}),this.toolRuntimeLease=(0,n.s)(b),this.toolRuntime=this.toolRuntimeLease.runtime,this.unsubscribeToolRuntime=this.toolRuntime.subscribe(a=>{this.session===b&&(this.emit(a),"message_update"===a.type&&"tool"===a.message.type&&"running"!==a.message.status&&this.flushLiveUpdates())}),this.unsubscribeSession=b.subscribe(a=>{this.session===b&&this.handleSessionEvent(a)}),this.backgroundTaskIds.size>0&&this.emitBackgroundTasks(),this.emitRuntime(),b}syncOwnerAppendedEntries(){for(let a of this.sessionManager.getEntries().slice(this.observedEntryCount))this.onEntryAppended(a)}validateFinalInput(a,b,c){let d=this.activeValidation;if(!d)return{action:"continue"};try{let e=c??"prompt";if("follow_up"===d.requestedMode&&"followUp"!==e&&!(d.allowIdleFollowUp&&"prompt"===e))throw Error("主 Agent 已空闲,不能添加 Follow-up");d.mode=e;let f=this.session;if(!f)throw Error("Pi AgentSession 尚未就绪");let g=(0,l.qc)(a,b,f.resourceLoader.getSkills().skills,f.promptTemplates);if(g.images.length>0&&!f.model?.input.includes("image"))throw Error("当前模型不支持图片输入");if(d.prepared=g,"prompt"===d.mode)this.pendingPrompt={tempId:d.tempId,input:g};else{let a="steer"===d.mode?this.steeringQueue:this.followUpQueue,b={tempId:d.tempId,input:g,confirmed:!1};(0,l.mu)([...this.steeringQueue.map(a=>a.input),...this.followUpQueue.map(a=>a.input),g]),a.push(b)}return{action:"continue"}}catch(a){return d.error=a instanceof Error?a:Error("聊天输入校验失败"),{action:"handled"}}}cancelPreflightOperation(a){a.compactionStarted&&(a.compactionStarted=!1,this.emit({type:"main_operation_cancelled"}))}finishObservedSend(a){this.reconcileAppendedEntries(),this.activeValidation===a&&(this.activeValidation=null),this.pendingPrompt?.tempId===a.tempId&&(this.pendingPrompt=null,this.discardPresentedInput(a.tempId)),this.removeUnconfirmedQueueItem(a.tempId)&&(this.discardPresentedInput(a.tempId),this.emitRuntime())}removeUnconfirmedQueueItem(a){for(let b of[this.steeringQueue,this.followUpQueue]){let c=b.findIndex(b=>b.tempId===a&&!b.confirmed);if(c>=0)return b.splice(c,1),!0}return!1}observeRun(a){this.observedRunPromises.add(a),a.finally(()=>this.observedRunPromises.delete(a))}handleAgentEvent(a){if(!this.disposed&&!this.treeNavigation)switch(a.type){case"agent_start":this.oversizedToolCallAbortRequested=!1,this.emit({type:"agent_started"});return;case"agent_end":this.oversizedToolCallAbortRequested=!1,this.reconcileAppendedEntries();return;case"message_start":if(this.abortOversizedStreamingToolCall(a.message))return;this.startMessage(a.message);return;case"message_update":if(this.abortOversizedStreamingToolCall(a.message))return;this.updateMessage(a.message),this.toolRuntime?.syncStreamingTools(a.message);return;case"message_end":this.toolRuntime?.syncStreamingTools(a.message),this.endMessage(a.message);return;default:return}}abortOversizedStreamingToolCall(a){let b=function(a){if("assistant"!==t(a))return null;let b=a.content;if(!Array.isArray(b))return null;for(let a of b)if(!(!a||"object"!=typeof a||Array.isArray(a))&&"toolCall"===a.type&&"string"==typeof a.partialJson&&!(a.partialJson.length<=262144))return{toolCallId:"string"==typeof a.id?a.id:null,toolName:"string"==typeof a.name?a.name:null,argumentChars:a.partialJson.length};return null}(a);return!!b&&(this.oversizedToolCallAbortRequested||(this.oversizedToolCallAbortRequested=!0,console.warn("[Pi Desk][PiChatWorker] 工具参数流过大,已中止当前 Agent",{sessionId:this.sessionManager.getSessionId(),toolCallId:b.toolCallId,toolName:b.toolName,argumentChars:b.argumentChars,maxArgumentChars:262144}),this.session?.agent.abort()),!0)}handleSessionEvent(a){if(!this.disposed)switch(a.type){case"queue_update":this.handleQueueUpdate(a.steering,a.followUp);return;case"agent_end":a.willRetry&&(this.toolRuntime?.size??0)>0&&(console.warn("[Pi Desk][PiChatWorker] 自动重试前丢弃未闭合 ToolCall",{sessionId:this.sessionManager.getSessionId(),toolCount:this.toolRuntime?.size??0}),this.toolRuntime?.discardAll());return;case"agent_settled":this.oversizedToolCallAbortRequested=!1,this.reconcileAppendedEntries(),this.toolRuntime?.discardAll(),this.emitRuntime(),this.emit({type:"agent_settled"});return;case"compaction_start":if(this.messageGate.pause(),console.info("[Pi Desk][PiChatWorker] 上下文压缩开始",{sessionId:this.session?.sessionId,reason:a.reason}),this.activeCompactionTempId)console.warn("[Pi Desk][PiChatWorker] 已忽略重复的上下文压缩开始事件",{sessionId:this.session?.sessionId,reason:a.reason});else{let a=(0,e.randomUUID)();this.activeCompactionTempId=a,this.emit({type:"message_start",tempId:a,message:function(a=""){return{type:"compaction",summary:a}}()})}this.activeValidation&&(this.activeValidation.compactionStarted=!0),this.emit({type:"agent_started"});return;case"compaction_end":if(a.errorMessage?console.error("[Pi Desk][PiChatWorker] 上下文压缩失败",{sessionId:this.session?.sessionId,reason:a.reason,errorMessage:a.errorMessage}):console.info("[Pi Desk][PiChatWorker] 上下文压缩结束",{sessionId:this.session?.sessionId,reason:a.reason,aborted:a.aborted,compacted:void 0!==a.result,willRetry:a.willRetry}),a.result){let b=this.activeCompactionTempId;this.reconcileAppendedEntries(),b&&this.activeCompactionTempId===b&&(console.error("[Pi Desk][PiChatWorker] 压缩成功但未找到对应 CompactionEntry",{sessionId:this.session?.sessionId,reason:a.reason}),this.discardActiveCompaction())}else this.discardActiveCompaction();this.emitRuntime(),"manual"===a.reason&&(this.manualCompactionFinishPending=!0),this.scheduleCompactionMessageResume();return;case"thinking_level_changed":this.publishingModel||this.emitRuntime();return;case"entry_appended":this.treeNavigation||this.onEntryAppended(a.entry);return;case"session_info_changed":{let b=this.sessionManager.getLeafEntry();this.treeNavigation||b?.type!=="session_info"||this.onEntryAppended(b),this.emit({type:"session_info_changed",sessionTitle:a.name?.trim()||null});return}case"bash_execution_update":a.id&&this.updateBash(a.id,a.delta);return;default:return}}startMessage(a){let b,c=t(a),d=!0,f=!1,g=null;if("user"===c){let a=this.takeUserInput();b=a?.tempId??(0,e.randomUUID)(),f=this.presentedInputTempIds.delete(b)}else if("toolResult"===c){let c=(g=u(a))?this.toolRuntime?.tempId(g):null;b=c??(0,e.randomUUID)(),d=null===c}else b=(0,e.randomUUID)();let h=this.projectLiveMessage(a,g);h&&(this.activeMessage={tempId:b,started:d||f,toolCallId:g},this.emit({type:d&&!f?"message_start":"message_update",tempId:b,message:h}))}updateMessage(a){let b=this.activeMessage;if(!b)return;let c=this.projectLiveMessage(a,b.toolCallId);c&&this.emit({type:"message_update",tempId:b.tempId,message:c})}endMessage(a){let b=this.activeMessage,c=t(a),d="toolResult"===c?u(a):null;if(!b){let c=this.projectLiveMessage(a,d);if(!c)return;b={tempId:(0,e.randomUUID)(),started:!0,toolCallId:d},this.emit({type:"message_start",tempId:b.tempId,message:c})}let f=this.projectLiveMessage(a,b.toolCallId);f&&this.emit({type:"message_update",tempId:b.tempId,message:f});let g=this.sessionManager.getLeafEntry(),h=g?(0,m.B4)(g):null;g&&h?(this.onEntryAppended(g),this.committedEntryIds.add(g.id),this.observedEntryCount=this.sessionManager.getEntries().length,this.emit({type:"message_commit",tempId:b.tempId,entryId:h.entryId,timestampMs:h.timestampMs,message:f??h.message}),this.emitRuntime()):b.started&&this.emit({type:"message_discard",tempId:b.tempId}),b.toolCallId&&this.toolRuntime?.remove(b.toolCallId),this.activeMessage=null}projectLiveMessage(a,b){return"toolResult"===t(a)&&b?this.toolRuntime?.projectLiveResult(a,b)??null:(0,m.b7)(a)}takeUserInput(){if(this.pendingPrompt){let a=this.pendingPrompt;return this.pendingPrompt=null,a}let a=this.steeringQueue.shift()??this.followUpQueue.shift();return a?(this.applyPendingQueueText(),this.emitRuntime(),{tempId:a.tempId,input:a.input}):null}startBash(a,b){let c={tempId:(0,e.randomUUID)(),executionId:a,command:b,output:"",status:"running"};this.bashTempsById.set(a,c),this.emit({type:"message_start",tempId:c.tempId,message:this.bashMessage(c)})}updateBash(a,b){let c=this.bashTempsById.get(a);c&&"running"===c.status&&(c.output+=b,this.emit({type:"message_update",tempId:c.tempId,message:this.bashMessage(c)}))}completeBash(a,b){let c=this.bashTempsById.get(a);if(!c)return;c.output=b.output,c.status=b.cancelled?"aborted":0===b.exitCode?"completed":"error",this.emit({type:"message_update",tempId:c.tempId,message:this.bashMessage(c)}),this.flushLiveUpdates();let d=this.sessionManager.getLeafEntry(),e=d?(0,m.B4)(d):null;d&&e?.message.type==="bash"&&e.message.command===c.command&&(this.onEntryAppended(d),this.commitBash(c,e))}commitBash(a,b){this.flushLiveUpdates(),this.committedEntryIds.add(b.entryId),this.observedEntryCount=this.sessionManager.getEntries().length,this.emit({type:"message_commit",tempId:a.tempId,entryId:b.entryId,timestampMs:b.timestampMs,message:b.message}),this.bashTempsById.delete(a.executionId)}discardBash(a){let b=this.bashTempsById.get(a);b&&(this.bashTempsById.delete(a),this.emit({type:"message_discard",tempId:b.tempId}))}bashMessage(a){return{type:"bash",command:a.command,status:a.status,output:a.output,declaration:{message:{kind:"bash",command:a.command,output:a.output,exitCode:"completed"===a.status?0:null,cancelled:"aborted"===a.status,truncated:!1},raw:{executionId:a.executionId,command:a.command,output:a.output,status:a.status}}}}handleQueueUpdate(a,b){this.confirmAndSyncQueue("steering",a),this.confirmAndSyncQueue("followUp",b),this.emitRuntime()}confirmAndSyncQueue(a,b){let c="steering"===a?this.steeringQueue:this.followUpQueue;for(let a of c)a.confirmed=!0;c.length!==b.length?this.pendingQueueText.set(a,b):(c.forEach((a,c)=>{a.input.text=b[c]??a.input.text}),this.pendingQueueText.delete(a))}applyPendingQueueText(){for(let a of["steering","followUp"]){let b=this.pendingQueueText.get(a);b&&this.confirmAndSyncQueue(a,b)}}reconcileAppendedEntries(){if(this.treeNavigation)return;let a=this.sessionManager.getEntries(),b=a.slice(this.observedEntryCount);for(let c of(this.observedEntryCount=a.length,b)){if(this.onEntryAppended(c),this.committedEntryIds.has(c.id))continue;let a=(0,m.B4)(c);if(!a)continue;if("compaction"===c.type&&this.activeCompactionTempId){let b=this.activeCompactionTempId;this.activeCompactionTempId=null,this.committedEntryIds.add(c.id),this.emit({type:"message_commit",tempId:b,entryId:a.entryId,timestampMs:z(c.id,c.timestamp),message:a.message});continue}if("bash"===a.message.type){let b=a.message.command,c=[...this.bashTempsById.values()].reverse().find(a=>a.command===b);if(c){this.commitBash(c,a);continue}}let b=(0,e.randomUUID)();this.committedEntryIds.add(c.id),this.emit({type:"message_start",tempId:b,message:a.message}),this.emit({type:"message_commit",tempId:b,entryId:a.entryId,timestampMs:z(c.id,c.timestamp),message:a.message})}}discardActiveCompaction(){let a=this.activeCompactionTempId;a&&(this.activeCompactionTempId=null,this.emit({type:"message_discard",tempId:a}))}updateBackgroundTasks(a){let b=new Set(a);if(!(b.size===this.backgroundTaskIds.size&&[...b].every(a=>this.backgroundTaskIds.has(a)))){for(let a of(this.backgroundTaskIds.clear(),b))this.backgroundTaskIds.add(a);this.emitBackgroundTasks()}}emitBackgroundTasks(){this.emit({type:"background_tasks_changed",taskIds:[...this.backgroundTaskIds]})}runtimeSnapshot(){let a=this.session,b=a?.model,c=a?.getContextUsage(),d=this.acceptedInputs.filter(a=>a.deferredByCompaction&&"auto"===a.input.mode).map(x),e=this.acceptedInputs.filter(a=>a.deferredByCompaction&&"follow_up"===a.input.mode).map(x);return{extensionMode:this.extensionMode,initializationError:this.initializationError,queues:{steering:[...this.steeringQueue.map(w),...d],followUp:[...this.followUpQueue.map(w),...e]},model:b?{provider:b.provider,modelId:b.id,thinkingLevel:a.thinkingLevel}:null,contextUsage:c&&c.contextWindow>0?{tokens:c.tokens,contextWindow:c.contextWindow}:null,plugins:this.pluginRuntime.snapshot(),capabilityMode:this.capabilities.mode()}}emitRuntime(){this.session&&this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()})}emit(a){if(!this.disposed&&!this.treeNavigation){if("message_update"===a.type)return void this.scheduleLiveUpdate(a);this.flushLiveUpdates(),"message_start"===a.type?(this.clearLiveUpdate(a.tempId),this.liveUpdatesByTempId.set(a.tempId,{lastPublishedAt:Date.now(),pending:null,timer:null,receivedCount:0,publishedCount:0})):("message_commit"===a.type||"message_discard"===a.type)&&this.finishLiveUpdate(a.tempId),("message_commit"===a.type||"session_info_changed"===a.type)&&(0,p.xt)(this.cwd),this.publish(a)}}scheduleLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a.tempId)??{lastPublishedAt:0,pending:null,timer:null,receivedCount:0,publishedCount:0};if(b.pending=a,b.receivedCount+=1,this.liveUpdatesByTempId.set(a.tempId,b),b.timer)return;let c=Date.now()-b.lastPublishedAt,d=Math.max(0,500-c);0===d?this.publishPendingLiveUpdate(b):b.timer=setTimeout(()=>{this.liveUpdatesByTempId.get(a.tempId)===b&&(b.timer=null,this.publishPendingLiveUpdate(b))},d)}publishPendingLiveUpdate(a){let b=a.pending;b&&!this.disposed&&(a.pending=null,a.lastPublishedAt=Date.now(),a.publishedCount+=1,this.publish(b))}flushLiveUpdates(){for(let a of this.liveUpdatesByTempId.values())a.timer&&clearTimeout(a.timer),a.timer=null,this.publishPendingLiveUpdate(a)}finishLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a);this.clearLiveUpdate(a),b&&b.receivedCount!==b.publishedCount&&console.debug("[Pi Desk][PiChatWorker] 流式消息更新已合并",{sessionId:this.sessionManager.getSessionId(),tempId:a,receivedCount:b.receivedCount,publishedCount:b.publishedCount})}clearLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a);b?.timer&&clearTimeout(b.timer),this.liveUpdatesByTempId.delete(a)}clearLiveUpdates(){for(let a of this.liveUpdatesByTempId.values())a.timer&&clearTimeout(a.timer);this.liveUpdatesByTempId.clear()}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][PiChatWorker] 事件监听器执行失败",{sessionId:this.sessionManager.getSessionId(),eventType:a.type,errorName:b instanceof Error?b.name:"UnknownError"})}}clearMemory(){this.steeringQueue.length=0,this.followUpQueue.length=0,this.pendingQueueText.clear(),this.bashTempsById.clear(),this.pendingPrompt=null,this.activeMessage=null,this.activeValidation=null,this.activeCompactionTempId=null,this.oversizedToolCallAbortRequested=!1,this.acceptedInputs.length=0,this.presentedInputTempIds.clear(),this.committedEntryIds.clear(),this.backgroundTaskIds.clear()}}d()}catch(a){d(a)}})},40333:(a,b,c)=>{c.d(b,{$m:()=>d.$m,FX:()=>d.FX,Pu:()=>d.Pu,QK:()=>d.QK,Tk:()=>d.Tk,nJ:()=>d.nJ,qs:()=>d.qs});var d=c(43969)},41904:(a,b,c)=>{c.d(b,{J:()=>f,a:()=>e});var d=c(59473);let e=d.Ik({locale:d.k5(["zh-CN","en"]),timeZone:d.Yj().trim().min(1).max(100).refine(a=>{try{return new Intl.DateTimeFormat("en",{timeZone:a}),!0}catch{return!1}},"无效的 IANA 时区")}).strict().readonly(),f=d.Ik({region:e}).strict().readonly()},41966:(a,b,c)=>{c.d(b,{L:()=>d});function d(a){if(!(a instanceof Error)||"PiDeskPluginMethodError"!==a.name)return!1;let b=a.code;return 400===b||404===b||409===b}},42520:(a,b,c)=>{c.d(b,{pL:()=>d});function d(a,b){let c=(globalThis.__piDeskNativePluginDiagnostics||(globalThis.__piDeskNativePluginDiagnostics=[]),globalThis.__piDeskNativePluginDiagnostics);!c.some(c=>c.cwd===a&&c.message===b)&&(c.push({cwd:a,message:b}),c.length>100&&c.splice(0,c.length-100))}},42633:(a,b,c)=>{c.d(b,{J8:()=>f,qf:()=>e});var d=c(59473);let e=d.KC([d.Yj(),d.Ik({default:d.Yj(),translations:d.g1(d.Yj().min(1).max(35),d.Yj()).refine(a=>Object.keys(a).length<=16,"too many translations")}).strict()]);function f(a,b){return{default:a,translations:{en:b}}}},43969:(a,b,c)=>{c.d(b,{$m:()=>g,FX:()=>h,Pu:()=>m,QK:()=>i,Tk:()=>k,nJ:()=>j,qs:()=>l});var d=c(59473);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.g1(d.Yj(),d.Pq());function g(a,b){return`${a}\u0000${b}`}function h(a){return e.parse(a)}function i(a){return e.parse(a)}function j(a,b){let c=f.parse(a);if(Buffer.byteLength(JSON.stringify(c),"utf8")>2097152)throw new m(b);return c}class k extends Error{constructor(a,b){super(`Plugin method was not found: ${a}/${b}`),this.name="L4PiPluginMethodNotFoundError"}}class l extends Error{constructor(a,b){super(`Plugin method is already registered: ${a}/${b}`),this.name="L4PiPluginMethodConflictError"}}class m extends Error{constructor(a){super(`Plugin method ${a} exceeds 2MB`),this.direction=a,this.name="L4PiPluginMethodPayloadTooLargeError"}}},44095:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{K:()=>y,y:()=>w});var e=c(77598),f=c(58500),g=c(51455),h=c(76760),i=c(59473),j=c(47511),k=c(58801),l=c(88502),m=c(43969),n=a([k]);k=(n.then?(await n)():n)[0];let r=i.g1(i.Yj(),i.Pq()),s=i.Ik({workId:i.Yj().trim().min(1),sessionId:i.Yj().trim().min(1),branchId:i.Yj().trim().min(1)}).strict(),t=i.Ik({source:s,cwd:i.Yj().trim().min(1),status:i.k5(["main_running","background_running","completed","idle"])}).strict(),u=i.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),v=i.ai().int().safe();class w extends Error{constructor(){super("插件运行时仍有调用正在执行"),this.name="L4PiPluginRuntimeBusyError"}}class x extends Error{constructor(a,b){super(b instanceof Error?b.message:String(b),{cause:b}),this.phase=a,this.name="L4PiPluginPhaseError"}}function o(a,b,c){if("string"!=typeof b||!b.trim())throw Error(`package.json.${c} must be a non-empty string`);let d=(0,h.resolve)(a,b),e=(0,h.relative)(a,d);if(e.startsWith("..")||(0,h.isAbsolute)(e))throw Error(`package.json.${c} must stay inside the package root`);return d}function p(a){return a instanceof Error&&a.message?a.message:String(a)}async function q(a){let b=null;try{if(await Promise.race([Promise.resolve().then(a.execute).then(()=>!0),new Promise(a=>{b=setTimeout(()=>a(!1),1500)})]))return;throw a.onTimeout?.(),Error(`插件 ${a.phase} 超时,关闭结果未确认`)}catch(b){console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 生命周期执行失败",{source:a.owner.source,packageName:a.owner.packageName,phase:a.phase,timeoutMs:1500,message:p(b)})}finally{b&&clearTimeout(b)}}class y{constructor(a,b){this.packageProvider=a,this.hostSettings=b,this.methods=new Map,this.pluginOwners=new Map,this.browserEntries=new Map,this.declarations=new Map,this.capabilityLoaders=new Map,this.owners=[],this.loadingOwners=new Set,this.changeListeners=new Set,this.changingSources=new Set,this.maintainingSources=new Set,this.lifetime=new AbortController,this.packageDiagnostics=new Map,this.initializePromise=null,this.initialized=!1,this.disposed=!1,this.acceptingCalls=!0,this.loadError=null,this.workSessionProvider=null,this.pushSender=null,this.appRuntimeSink=null}initialize(){return this.disposed?Promise.reject(Error("Global plugin runtime has been disposed")):this.initialized?Promise.resolve():(this.initializePromise||(this.initializePromise=this.loadConfiguredPackages().catch(a=>{this.loadError=p(a),console.error("[Pi Desk][GlobalPluginRuntime] 读取插件配置失败,核心应用继续启动",{errorName:a instanceof Error?a.name:"UnknownError",message:this.loadError})}).finally(()=>{this.initializePromise=null,this.initialized=!0,this.publishChanges()})),this.initializePromise)}subscribeChanges(a){return this.changeListeners.add(a),()=>this.changeListeners.delete(a)}publishChanges(){if(!this.disposed)for(let a of this.changeListeners)try{a()}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 状态监听失败",{message:p(a)})}}async withSourceIdle(a,b,c,d){let e,g=AbortSignal.any([c,this.lifetime.signal]);g.throwIfAborted();let h=new Promise((a,b)=>{e=()=>b(g.reason),g.addEventListener("abort",e,{once:!0})});try{await Promise.race([this.initialize(),h])}finally{g.removeEventListener("abort",e)}if(g.throwIfAborted(),!this.acceptingCalls||this.changingSources.has(a)||this.maintainingSources.has(a))throw new w;this.maintainingSources.add(a);try{for(;this.owners.some(b=>b.source===a&&b.activeCalls.size>0);)d(`插件 ${a} 仍有调用正在执行`),await (0,f.setTimeout)(250,void 0,{signal:g});return g.throwIfAborted(),await b()}finally{this.maintainingSources.delete(a)}}async replaceSource(a,b){if(await this.initialize(),this.disposed||!this.acceptingCalls||this.changingSources.has(a))throw new w;let c=this.owners.find(b=>b.source===a);this.changingSources.add(a);try{if(c&&this.releaseOwner(c),this.disposed)throw Error("Global plugin runtime has been disposed");if((0,k.N)(),this.packageDiagnostics.delete(a),null!==b){if(await this.loadPackage(a,b),this.disposed)throw Error("Global plugin runtime has been disposed");let c=this.packageDiagnostics.get(a);if(c?.status==="failed")throw Error(c.error?.message??"插件加载失败")}}finally{this.changingSources.delete(a),this.publishChanges()}}ownerPublished(a){return a.active&&!a.draining&&!this.changingSources.has(a.source)&&this.owners.includes(a)}readDiagnostics(){return{packages:[...this.packageDiagnostics.values()].sort((a,b)=>a.source.localeCompare(b.source)).map(a=>structuredClone(a)),loadError:this.loadError}}readCapabilityRegistrations(){return[...this.owners].filter(a=>this.ownerPublished(a)).sort((a,b)=>a.source.localeCompare(b.source)).map(a=>({source:a.source,methods:[...this.methods.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.method.localeCompare(b.method):c}).map(({pluginName:a,method:b})=>({pluginName:a,method:b})),browserEntries:[...this.browserEntries.values()].filter(b=>b.owner===a).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).map(({pluginName:a})=>({pluginName:a})),messageDeclarations:[...this.declarations.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,priority:c.priority}))}))}async prepareReload(){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls||this.changingSources.size>0||this.maintainingSources.size>0||this.owners.some(a=>a.activeCalls.size>0))throw new w;for(let a of(this.acceptingCalls=!1,this.owners))a.draining=!0;await Promise.all([...this.owners].reverse().map(async a=>{let b=a.beforeReload;if(!b)return;a.beforeReload=null;let c=new AbortController;await q({owner:a,phase:"beforeReload",execute:()=>b({signal:c.signal}),onTimeout:()=>c.abort()})}))}bindWorkSessionProvider(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.workSessionProvider=a,()=>{this.workSessionProvider===a&&(this.workSessionProvider=null)}}bindPushSender(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.pushSender=a,()=>{this.pushSender===a&&(this.pushSender=null)}}bindAppRuntimeSink(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.appRuntimeSink=a,()=>{this.appRuntimeSink===a&&(this.appRuntimeSink=null)}}async runOwnedCall(a,b){let c;if(this.ensureOwnerActive(a),this.maintainingSources.has(a.source))throw new w;let d=new AbortController,e=new Promise((a,b)=>{c=b}),f=()=>{c(Error("Pi Desk Plugin owner is no longer active"))};d.signal.addEventListener("abort",f,{once:!0}),a.activeCalls.add(d);try{let c=await Promise.race([Promise.resolve().then(()=>(this.ensureOwnerActive(a),b(d.signal))),e]);return this.ensureOwnerActive(a),c}finally{a.activeCalls.delete(d),d.signal.removeEventListener("abort",f)}}async invoke(a,b,c){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls)throw new w;let d=(0,m.FX)(a),e=(0,m.QK)(b),f=this.methods.get((0,m.$m)(d,e));if(!f)throw new m.Tk(d,e);if(!this.ownerPublished(f.owner)||this.changingSources.has(f.owner.source))throw new w;let g=(0,m.nJ)(c,"input");return this.runOwnedCall(f.owner,async a=>{let b=await f.execute(g,{signal:a});return(0,m.nJ)(b,"output")})}async listCapabilityDeclarations(){if(await this.initialize(),this.disposed||!this.acceptingCalls)throw new w;let a=await Promise.all([...this.capabilityLoaders].filter(([,a])=>this.ownerPublished(a.owner)&&!this.changingSources.has(a.owner.source)).map(async([a,b])=>{try{return await this.runOwnedCall(b.owner,async c=>{let d=await b.load({signal:c});if(this.capabilityLoaders.get(a)!==b)throw Error(`能力声明已被替换:${a}`);return[a,j.dO.parse(d)]})}catch(b){throw Error(`读取 ${a} 能力选项失败:${p(b)}`,{cause:b})}}));return Object.fromEntries(a)}async listBrowserEntries(){return await this.initialize(),[...this.browserEntries.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).flatMap(({pluginName:a,entryPath:b,resourceKey:c,snapshot:d})=>d?[{pluginName:a,entryPath:b,resourceKey:c,snapshot:d}]:[])}async listMessageDeclarations(){return await this.initialize(),this.readMessageDeclarations()}readMessageDeclarations(){return[...this.declarations.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,declaration:c}))}async dispose(){if(this.disposed)return;this.disposed=!0,this.lifetime.abort(),this.acceptingCalls=!1,this.changeListeners.clear(),this.workSessionProvider=null,this.pushSender=null;let a=[...new Set([...this.owners,...this.loadingOwners])].reverse();this.owners.length=0,this.loadingOwners.clear(),await Promise.all(a.map(a=>this.releaseOwner(a))),this.methods.clear(),this.pluginOwners.clear(),this.browserEntries.clear(),this.declarations.clear(),this.capabilityLoaders.clear(),this.appRuntimeSink=null}async loadConfiguredPackages(){for(let a of(this.loadError=null,this.packageDiagnostics.clear(),await this.packageProvider())){if(this.disposed)return;await this.loadPackage(a.source,a.installedPath)}}async loadOwnerWithinDeadline(a,b,c){let d,e=(async()=>{void 0!==b?await this.loadEntryOwner(a,b):await this.loadLegacyOwner(a,c);try{await this.validateOwnerResources(a)}catch(a){throw new x("resources",a)}this.ensureOwnerActive(a)})();try{await Promise.race([e,new Promise((a,b)=>{d=setTimeout(()=>{b(new x("setup",Error("插件初始化超时,已放弃加载")))},15e3)})])}finally{d&&clearTimeout(d)}}async loadPackage(a,b){let c,d=performance.now(),e=(0,h.resolve)(b);try{let a=(0,h.join)(e,"package.json");c=JSON.parse(await (0,g.readFile)(a,"utf8"))}catch(b){this.packageDiagnostics.set(a,{source:a,packageName:null,version:null,pluginName:null,status:"failed",error:{phase:"package",message:p(b)}});return}let f=c.piDesk?.entry,i=c.piDesk?.global;if(void 0===f&&void 0===i||this.disposed)return;let j={source:a,packageName:"string"==typeof c.name?c.name:null,version:"string"==typeof c.version?c.version:null,packageRoot:e,active:!0,draining:!1,pluginNames:new Set,activeCalls:new Set,subscriptions:new Set,beforeReload:null,disposer:null};console.info("[Pi Desk][GlobalPluginRuntime] 开始加载 Pi Desk Plugin",{source:a,packageName:j.packageName}),this.loadingOwners.add(j);try{await this.loadOwnerWithinDeadline(j,f,i),this.owners.push(j),this.recordOwnerDiagnostic(j),console.info("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 已加载",{source:a,packageName:j.packageName,pluginNames:[...j.pluginNames],methodCount:[...this.methods.values()].filter(a=>a.owner===j).length,browserEntryCount:[...this.browserEntries.values()].filter(a=>a.owner===j).length,declarationCount:[...this.declarations.values()].filter(a=>a.owner===j).length,durationMs:Math.round(performance.now()-d)})}catch(f){let b=f instanceof x?f.phase:"entry",c=[...j.pluginNames][0]??null;await this.releaseOwner(j);let e=p(f);this.packageDiagnostics.set(a,{source:a,packageName:j.packageName,version:j.version,pluginName:c,status:"failed",error:{phase:b,message:e}}),console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 加载失败",{source:a,packageName:j.packageName,phase:b,errorName:f instanceof Error?f.name:"UnknownError",message:e,durationMs:Math.round(performance.now()-d)})}finally{this.loadingOwners.delete(j)}}async loadEntryOwner(a,b){let c=o(a.packageRoot,b,"piDesk.entry");if(!(await (0,g.stat)(c)).isFile())throw Error("Pi Desk Plugin entry is not a file");let d=(await (0,k.G)(c,a.packageRoot)).default;if(!d||"object"!=typeof d||"string"!=typeof d.name||"function"!=typeof d.setup)throw Error("Pi Desk Plugin entry must default-export definePiDeskPlugin(...)");let e=(0,m.FX)(d.name);this.claimPluginName(a,e);try{let b=function(a){if(void 0===a)return{beforeReload:null,disposer:null};if("function"==typeof a)return{beforeReload:null,disposer:a};if(!a||"object"!=typeof a)throw Error("Pi Desk Plugin setup must return void, a disposer, or a lifecycle object");if(void 0!==a.beforeReload&&"function"!=typeof a.beforeReload)throw Error("Pi Desk Plugin lifecycle.beforeReload must be a function");if(void 0!==a.dispose&&"function"!=typeof a.dispose)throw Error("Pi Desk Plugin lifecycle.dispose must be a function");return{beforeReload:a.beforeReload??null,disposer:a.dispose??null}}(await d.setup(this.createPiDeskFacade(a,e,a.packageRoot)));if(a.beforeReload=b.beforeReload,a.disposer=b.disposer,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}async loadLegacyOwner(a,b){let c=o(a.packageRoot,b,"piDesk.global");if(!(await (0,g.stat)(c)).isFile())throw Error("Global Plugin entry is not a file");let d=await (0,k.G)(c,a.packageRoot);if("function"!=typeof d.default)throw Error("Global Plugin entry must default-export a factory function");let e=d.default;try{let b=await e(this.createLegacyApi(a));if(void 0!==b&&"function"!=typeof b)throw Error("Global Plugin factory must return void or a disposer function");if(a.disposer=b??null,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}claimPluginName(a,b){this.ensureOwnerActive(a);let c=this.pluginOwners.get(b);if(c&&c!==a)throw Error(`Pi Desk pluginName is already registered: ${b}`);this.pluginOwners.set(b,a),a.pluginNames.add(b)}createLegacyApi(a){return{bindPlugin:b=>{let c=(0,m.FX)(b);return this.claimPluginName(a,c),{name:c,registerMethod:(b,d)=>this.registerMethod(a,c,b,d)}}}}createPiDeskFacade(a,b,c){return{name:b,host:{settings:{getSnapshot:()=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");return this.hostSettings.getSnapshot()},subscribe:b=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");let c=this.hostSettings.subscribe(()=>{a.active&&!a.draining&&b()});return a.subscriptions.add(c),()=>{if(a.subscriptions.delete(c))return c()}}},workSessions:{listWorkSessions:async()=>{this.ensureOwnerActive(a);let b=await this.readWorkSessions();return this.ensureOwnerActive(a),b}}},notifications:{publish:c=>(this.ensureOwnerActive(a),this.requireAppRuntimeSink().publishNotification(b,c)),update:(c,d)=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().updateNotification(b,c,d)},delete:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().deleteNotification(b,c)}},setState:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().setState(b,c)},registerMethod:(c,d)=>this.registerMethod(a,b,c,d),registerBrowserEntry:d=>{if(this.ensureOwnerActive(a),this.browserEntries.has(b))throw Error(`Browser Entry is already registered: ${b}`);let f=o(c,d,"browserEntry"),g={pluginName:b,entryPath:f,resourceKey:(0,e.randomUUID)(),snapshot:null,owner:a};return this.browserEntries.set(b,g),this.registrationDisposer(a,()=>{this.browserEntries.get(b)===g&&this.browserEntries.delete(b)})},declareCapabilities:c=>{if(this.ensureOwnerActive(a),"function"!=typeof c)throw Error("能力声明必须是按需查询函数");if(this.capabilityLoaders.has(b))throw Error(`能力声明已注册:${b}`);let d={load:c,owner:a};return this.capabilityLoaders.set(b,d),this.registrationDisposer(a,()=>{this.capabilityLoaders.get(b)===d&&this.capabilityLoaders.delete(b)})},declareMessage:(c,d)=>this.registerDeclaration(a,b,c,d),pushGlobal:(c,d)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"global"},c,d)},pushSession:(c,d,e)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"session",source:s.parse(c)},d,e)}}}registerMethod(a,b,c,d){this.ensureOwnerActive(a);let e=(0,m.QK)(c),f=(0,m.$m)(b,e);if(this.methods.has(f))throw new m.qs(b,e);let g={pluginName:b,method:e,execute:d,owner:a};return this.methods.set(f,g),this.registrationDisposer(a,()=>{this.methods.get(f)===g&&this.methods.delete(f)})}registerDeclaration(a,b,c,d){var e;this.ensureOwnerActive(a);let f=u.parse(c);if(!d||"object"!=typeof d||"function"!=typeof d.match||"function"!=typeof d.project)throw Error("Message Declaration must provide match and project functions");let g={priority:(e=d.priority,v.parse(e)),match:d.match,project:d.project},h=`${b}\u0000${f}`;if(this.declarations.has(h))throw Error(`Message Declaration is already registered: ${b}/${f}`);let i={pluginName:b,declarationName:f,declaration:g,owner:a};return this.declarations.set(h,i),this.registrationDisposer(a,()=>{this.declarations.get(h)===i&&this.declarations.delete(h)})}registrationDisposer(a,b){let c=!0;return()=>{c&&(c=!1,a.active&&b())}}requireAppRuntimeSink(){if(!this.appRuntimeSink)throw Error("App Runtime sink has not been bound");return this.appRuntimeSink}sendPush(a,b,c,d){if(this.disposed)return;let e=(0,m.QK)(c),f=function(a){let b=r.parse(a);if(Buffer.byteLength(JSON.stringify(b),"utf8")>65536)throw Error("Plugin Push data exceeds 64KB");return b}(d);this.pushSender?.({pluginName:a,target:b,event:e,data:structuredClone(f)})}async readWorkSessions(){if(!this.workSessionProvider||this.disposed)return[];let a=await this.workSessionProvider();return i.YO(t).parse(a).map(a=>structuredClone(a))}async validateOwnerResources(a){for(let b of[...this.browserEntries.values()].filter(b=>b.owner===a)){if(!(await (0,g.stat)(b.entryPath)).isFile())throw Error("Browser Entry resource is not a file");if("entry.js"!==(0,h.basename)(b.entryPath))throw Error("Browser Entry resource file must be named entry.js");let c=await (0,l.f)(b.entryPath);if(this.ensureOwnerActive(a),[...this.browserEntries.values()].reduce((a,b)=>a+(b.snapshot?.size??0),0)+c.size>0x8000000)throw Error("Browser 模块快照总量超过128MB,拒绝加载此插件");b.snapshot=c}}recordOwnerDiagnostic(a){this.packageDiagnostics.set(a.source,{source:a.source,packageName:a.packageName,version:a.version,pluginName:[...a.pluginNames][0]??null,status:"ready",error:null})}ensureOwnerActive(a){if(!a.active||a.draining||this.disposed)throw Error("Pi Desk Plugin owner is no longer active")}async releaseOwner(a){let b=[...a.subscriptions];if(a.subscriptions.clear(),a.active){for(let b of(a.active=!1,a.activeCalls))b.abort();a.activeCalls.clear();let b=this.owners.indexOf(a);for(let[c,d]of(b>=0&&this.owners.splice(b,1),this.methods))d.owner===a&&this.methods.delete(c);for(let[b,c]of this.browserEntries)c.owner===a&&this.browserEntries.delete(b);for(let[b,c]of this.declarations)c.owner===a&&this.declarations.delete(b);for(let[b,c]of this.capabilityLoaders)c.owner===a&&this.capabilityLoaders.delete(b);for(let b of a.pluginNames)if(this.pluginOwners.get(b)===a){this.pluginOwners.delete(b);try{this.appRuntimeSink?.releasePlugin(b)}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 清理插件 App Runtime 失败",{pluginName:b,errorName:a instanceof Error?a.name:"UnknownError",message:p(a)})}}a.pluginNames.clear()}let c=a.beforeReload,d=a.disposer;a.beforeReload=null,a.disposer=null;let e=new AbortController;await Promise.all([...b.map(b=>q({owner:a,phase:"dispose",execute:b})),c?q({owner:a,phase:"beforeReload",execute:()=>c({signal:e.signal}),onTimeout:()=>e.abort()}):Promise.resolve(),d?q({owner:a,phase:"dispose",execute:d}):Promise.resolve()])}}d()}catch(a){d(a)}})},46107:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Nx:()=>n,cY:()=>m,sv:()=>o,to:()=>l});var e=c(73024),f=c(76760),g=c(77598),h=c(75430),i=c(59473),j=c(58417),k=a([h]);h=(k.then?(await k)():k)[0];let n="https://registry.npmjs.org",o="https://mirrors.cloud.tencent.com/npm",p=i.Ik({downloadSource:j.w3.default({mode:"auto"}),disabled:i.YO(i.Yj()).max(2e3).default([]),registries:i.g1(i.Yj(),j.SZ).default({}),updateTags:i.g1(i.Yj(),j.mR).default({})}).strict();function l(a=(0,h.getAgentDir)()){let b=(0,f.join)(a,"pi-desk-plugins.json");return(0,e.existsSync)(b)?p.parse(JSON.parse((0,e.readFileSync)(b,"utf8"))):p.parse({})}function m(a,b=(0,h.getAgentDir)()){!function(a,b){let c=(0,f.join)(a,"pi-desk-plugins.json"),d=p.parse(b(l(a)));(0,e.mkdirSync)((0,f.dirname)(c),{recursive:!0});let h=`${c}.${(0,g.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,`${JSON.stringify(d,null,2)}
|
|
20
|
+
…诊断过长,已截断`:b,this.extensionMode="basic",this.updateBackgroundTasks([]),this.initialization=this.createInitialization(),console.warn("[Pi Desk][PiChatWorker] 扩展加载失败,切换基础聊天",{sessionId:this.sessionManager.getSessionId(),cwd:this.cwd,message:this.initializationError})}async createSession(a=!1){let b;try{b=await this.initialization.start(a)}catch(a){this.restoreBasicInitialization(a),b=await this.initialization.start()}if(this.disposed)throw this.initialization.dispose(),Error("Pi Worker 已释放");try{this.syncOwnerAppendedEntries()}catch(a){throw this.initialization.dispose(),a}return this.session=b,"normal"===this.extensionMode&&(this.initializationError=null),this.unsubscribeAgent=b.agent.subscribe(a=>{this.session===b&&this.handleAgentEvent(a)}),this.toolRuntimeLease=(0,n.s)(b),this.toolRuntime=this.toolRuntimeLease.runtime,this.unsubscribeToolRuntime=this.toolRuntime.subscribe(a=>{this.session===b&&(this.emit(a),"message_update"===a.type&&"tool"===a.message.type&&"running"!==a.message.status&&this.flushLiveUpdates())}),this.unsubscribeSession=b.subscribe(a=>{this.session===b&&this.handleSessionEvent(a)}),this.backgroundTaskIds.size>0&&this.emitBackgroundTasks(),this.emitRuntime(),b}syncOwnerAppendedEntries(){for(let a of this.sessionManager.getEntries().slice(this.observedEntryCount))this.onEntryAppended(a)}validateFinalInput(a,b,c){let d=this.activeValidation;if(!d)return{action:"continue"};try{let e=c??"prompt";if("follow_up"===d.requestedMode&&"followUp"!==e&&!(d.allowIdleFollowUp&&"prompt"===e))throw Error("主 Agent 已空闲,不能添加 Follow-up");d.mode=e;let f=this.session;if(!f)throw Error("Pi AgentSession 尚未就绪");let g=(0,l.qc)(a,b,f.resourceLoader.getSkills().skills,f.promptTemplates);if(g.images.length>0&&!f.model?.input.includes("image"))throw Error("当前模型不支持图片输入");if(d.prepared=g,"prompt"===d.mode)this.pendingPrompt={tempId:d.tempId,input:g};else{let a="steer"===d.mode?this.steeringQueue:this.followUpQueue,b={tempId:d.tempId,input:g,confirmed:!1};(0,l.mu)([...this.steeringQueue.map(a=>a.input),...this.followUpQueue.map(a=>a.input),g]),a.push(b)}return{action:"continue"}}catch(a){return d.error=a instanceof Error?a:Error("聊天输入校验失败"),{action:"handled"}}}cancelPreflightOperation(a){a.compactionStarted&&(a.compactionStarted=!1,this.emit({type:"main_operation_cancelled"}))}finishObservedSend(a){this.reconcileAppendedEntries(),this.activeValidation===a&&(this.activeValidation=null),this.pendingPrompt?.tempId===a.tempId&&(this.pendingPrompt=null,this.discardPresentedInput(a.tempId)),this.removeUnconfirmedQueueItem(a.tempId)&&(this.discardPresentedInput(a.tempId),this.emitRuntime())}removeUnconfirmedQueueItem(a){for(let b of[this.steeringQueue,this.followUpQueue]){let c=b.findIndex(b=>b.tempId===a&&!b.confirmed);if(c>=0)return b.splice(c,1),!0}return!1}observeRun(a){this.observedRunPromises.add(a),a.finally(()=>this.observedRunPromises.delete(a))}handleAgentEvent(a){if(!this.disposed&&!this.treeNavigation)switch(a.type){case"agent_start":this.oversizedToolCallAbortRequested=!1,this.emit({type:"agent_started"});return;case"agent_end":this.oversizedToolCallAbortRequested=!1,this.reconcileAppendedEntries();return;case"message_start":if(this.abortOversizedStreamingToolCall(a.message))return;this.startMessage(a.message);return;case"message_update":if(this.abortOversizedStreamingToolCall(a.message))return;this.updateMessage(a.message),this.toolRuntime?.syncStreamingTools(a.message);return;case"message_end":this.toolRuntime?.syncStreamingTools(a.message),this.endMessage(a.message);return;default:return}}abortOversizedStreamingToolCall(a){let b=function(a){if("assistant"!==t(a))return null;let b=a.content;if(!Array.isArray(b))return null;for(let a of b)if(!(!a||"object"!=typeof a||Array.isArray(a))&&"toolCall"===a.type&&"string"==typeof a.partialJson&&!(a.partialJson.length<=262144))return{toolCallId:"string"==typeof a.id?a.id:null,toolName:"string"==typeof a.name?a.name:null,argumentChars:a.partialJson.length};return null}(a);return!!b&&(this.oversizedToolCallAbortRequested||this.session?.agent.signal?.aborted||(this.oversizedToolCallAbortRequested=!0,console.warn("[Pi Desk][PiChatWorker] 工具参数流过大,已中止当前运行,交由 Pi 重试策略处理",{sessionId:this.sessionManager.getSessionId(),toolCallId:b.toolCallId,toolName:b.toolName,argumentChars:b.argumentChars,maxArgumentChars:262144}),this.session?.agent.abort()),!0)}handleSessionEvent(a){if(!this.disposed)switch(a.type){case"queue_update":this.handleQueueUpdate(a.steering,a.followUp);return;case"agent_end":a.willRetry&&(this.toolRuntime?.size??0)>0&&(console.warn("[Pi Desk][PiChatWorker] 自动重试前丢弃未闭合 ToolCall",{sessionId:this.sessionManager.getSessionId(),toolCount:this.toolRuntime?.size??0}),this.toolRuntime?.discardAll());return;case"agent_settled":this.oversizedToolCallAbortRequested=!1,this.reconcileAppendedEntries(),this.toolRuntime?.discardAll(),this.emitRuntime(),this.emit({type:"agent_settled"});return;case"compaction_start":if(this.messageGate.pause(),console.info("[Pi Desk][PiChatWorker] 上下文压缩开始",{sessionId:this.session?.sessionId,reason:a.reason}),this.activeCompactionTempId)console.warn("[Pi Desk][PiChatWorker] 已忽略重复的上下文压缩开始事件",{sessionId:this.session?.sessionId,reason:a.reason});else{let a=(0,e.randomUUID)();this.activeCompactionTempId=a,this.emit({type:"message_start",tempId:a,message:function(a=""){return{type:"compaction",summary:a}}()})}this.activeValidation&&(this.activeValidation.compactionStarted=!0),this.emit({type:"agent_started"});return;case"compaction_end":if(a.errorMessage?console.error("[Pi Desk][PiChatWorker] 上下文压缩失败",{sessionId:this.session?.sessionId,reason:a.reason,errorMessage:a.errorMessage}):console.info("[Pi Desk][PiChatWorker] 上下文压缩结束",{sessionId:this.session?.sessionId,reason:a.reason,aborted:a.aborted,compacted:void 0!==a.result,willRetry:a.willRetry}),a.result){let b=this.activeCompactionTempId;this.reconcileAppendedEntries(),b&&this.activeCompactionTempId===b&&(console.error("[Pi Desk][PiChatWorker] 压缩成功但未找到对应 CompactionEntry",{sessionId:this.session?.sessionId,reason:a.reason}),this.discardActiveCompaction())}else this.discardActiveCompaction();this.emitRuntime(),"manual"===a.reason&&(this.manualCompactionFinishPending=!0),this.scheduleCompactionMessageResume();return;case"thinking_level_changed":this.publishingModel||this.emitRuntime();return;case"entry_appended":this.treeNavigation||this.onEntryAppended(a.entry);return;case"session_info_changed":{let b=this.sessionManager.getLeafEntry();this.treeNavigation||b?.type!=="session_info"||this.onEntryAppended(b),this.emit({type:"session_info_changed",sessionTitle:a.name?.trim()||null});return}case"bash_execution_update":a.id&&this.updateBash(a.id,a.delta);return;default:return}}startMessage(a){let b,c=t(a),d=!0,f=!1,g=null;if("user"===c){let a=this.takeUserInput();b=a?.tempId??(0,e.randomUUID)(),f=this.presentedInputTempIds.delete(b)}else if("toolResult"===c){let c=(g=u(a))?this.toolRuntime?.tempId(g):null;b=c??(0,e.randomUUID)(),d=null===c}else b=(0,e.randomUUID)();let h=this.projectLiveMessage(a,g);h&&(this.activeMessage={tempId:b,started:d||f,toolCallId:g},this.emit({type:d&&!f?"message_start":"message_update",tempId:b,message:h}))}updateMessage(a){let b=this.activeMessage;if(!b)return;let c=this.projectLiveMessage(a,b.toolCallId);c&&this.emit({type:"message_update",tempId:b.tempId,message:c})}endMessage(a){let b=this.activeMessage,c=t(a),d="toolResult"===c?u(a):null;if(!b){let c=this.projectLiveMessage(a,d);if(!c)return;b={tempId:(0,e.randomUUID)(),started:!0,toolCallId:d},this.emit({type:"message_start",tempId:b.tempId,message:c})}let f=this.projectLiveMessage(a,b.toolCallId);f&&this.emit({type:"message_update",tempId:b.tempId,message:f});let g=this.sessionManager.getLeafEntry(),h=g?(0,m.B4)(g):null;g&&h?(this.onEntryAppended(g),this.committedEntryIds.add(g.id),this.observedEntryCount=this.sessionManager.getEntries().length,this.emit({type:"message_commit",tempId:b.tempId,entryId:h.entryId,timestampMs:h.timestampMs,message:f??h.message}),this.emitRuntime()):b.started&&this.emit({type:"message_discard",tempId:b.tempId}),b.toolCallId&&this.toolRuntime?.remove(b.toolCallId),this.activeMessage=null}projectLiveMessage(a,b){return"toolResult"===t(a)&&b?this.toolRuntime?.projectLiveResult(a,b)??null:(0,m.b7)(a)}takeUserInput(){if(this.pendingPrompt){let a=this.pendingPrompt;return this.pendingPrompt=null,a}let a=this.steeringQueue.shift()??this.followUpQueue.shift();return a?(this.applyPendingQueueText(),this.emitRuntime(),{tempId:a.tempId,input:a.input}):null}startBash(a,b){let c={tempId:(0,e.randomUUID)(),executionId:a,command:b,output:"",status:"running"};this.bashTempsById.set(a,c),this.emit({type:"message_start",tempId:c.tempId,message:this.bashMessage(c)})}updateBash(a,b){let c=this.bashTempsById.get(a);c&&"running"===c.status&&(c.output+=b,this.emit({type:"message_update",tempId:c.tempId,message:this.bashMessage(c)}))}completeBash(a,b){let c=this.bashTempsById.get(a);if(!c)return;c.output=b.output,c.status=b.cancelled?"aborted":0===b.exitCode?"completed":"error",this.emit({type:"message_update",tempId:c.tempId,message:this.bashMessage(c)}),this.flushLiveUpdates();let d=this.sessionManager.getLeafEntry(),e=d?(0,m.B4)(d):null;d&&e?.message.type==="bash"&&e.message.command===c.command&&(this.onEntryAppended(d),this.commitBash(c,e))}commitBash(a,b){this.flushLiveUpdates(),this.committedEntryIds.add(b.entryId),this.observedEntryCount=this.sessionManager.getEntries().length,this.emit({type:"message_commit",tempId:a.tempId,entryId:b.entryId,timestampMs:b.timestampMs,message:b.message}),this.bashTempsById.delete(a.executionId)}discardBash(a){let b=this.bashTempsById.get(a);b&&(this.bashTempsById.delete(a),this.emit({type:"message_discard",tempId:b.tempId}))}bashMessage(a){return{type:"bash",command:a.command,status:a.status,output:a.output,declaration:{message:{kind:"bash",command:a.command,output:a.output,exitCode:"completed"===a.status?0:null,cancelled:"aborted"===a.status,truncated:!1},raw:{executionId:a.executionId,command:a.command,output:a.output,status:a.status}}}}handleQueueUpdate(a,b){this.confirmAndSyncQueue("steering",a),this.confirmAndSyncQueue("followUp",b),this.emitRuntime()}confirmAndSyncQueue(a,b){let c="steering"===a?this.steeringQueue:this.followUpQueue;for(let a of c)a.confirmed=!0;c.length!==b.length?this.pendingQueueText.set(a,b):(c.forEach((a,c)=>{a.input.text=b[c]??a.input.text}),this.pendingQueueText.delete(a))}applyPendingQueueText(){for(let a of["steering","followUp"]){let b=this.pendingQueueText.get(a);b&&this.confirmAndSyncQueue(a,b)}}reconcileAppendedEntries(){if(this.treeNavigation)return;let a=this.sessionManager.getEntries(),b=a.slice(this.observedEntryCount);for(let c of(this.observedEntryCount=a.length,b)){if(this.onEntryAppended(c),this.committedEntryIds.has(c.id))continue;let a=(0,m.B4)(c);if(!a)continue;if("compaction"===c.type&&this.activeCompactionTempId){let b=this.activeCompactionTempId;this.activeCompactionTempId=null,this.committedEntryIds.add(c.id),this.emit({type:"message_commit",tempId:b,entryId:a.entryId,timestampMs:z(c.id,c.timestamp),message:a.message});continue}if("bash"===a.message.type){let b=a.message.command,c=[...this.bashTempsById.values()].reverse().find(a=>a.command===b);if(c){this.commitBash(c,a);continue}}let b=(0,e.randomUUID)();this.committedEntryIds.add(c.id),this.emit({type:"message_start",tempId:b,message:a.message}),this.emit({type:"message_commit",tempId:b,entryId:a.entryId,timestampMs:z(c.id,c.timestamp),message:a.message})}}discardActiveCompaction(){let a=this.activeCompactionTempId;a&&(this.activeCompactionTempId=null,this.emit({type:"message_discard",tempId:a}))}updateBackgroundTasks(a){let b=new Set(a);if(!(b.size===this.backgroundTaskIds.size&&[...b].every(a=>this.backgroundTaskIds.has(a)))){for(let a of(this.backgroundTaskIds.clear(),b))this.backgroundTaskIds.add(a);this.emitBackgroundTasks()}}emitBackgroundTasks(){this.emit({type:"background_tasks_changed",taskIds:[...this.backgroundTaskIds]})}runtimeSnapshot(){let a=this.session,b=a?.model,c=a?.getContextUsage(),d=this.acceptedInputs.filter(a=>a.deferredByCompaction&&"auto"===a.input.mode).map(x),e=this.acceptedInputs.filter(a=>a.deferredByCompaction&&"follow_up"===a.input.mode).map(x);return{extensionMode:this.extensionMode,initializationError:this.initializationError,queues:{steering:[...this.steeringQueue.map(w),...d],followUp:[...this.followUpQueue.map(w),...e]},model:b?{provider:b.provider,modelId:b.id,thinkingLevel:a.thinkingLevel}:null,contextUsage:c&&c.contextWindow>0?{tokens:c.tokens,contextWindow:c.contextWindow}:null,plugins:this.pluginRuntime.snapshot(),capabilityMode:this.capabilities.mode()}}emitRuntime(){this.session&&this.emit({type:"runtime_changed",runtime:this.runtimeSnapshot()})}emit(a){if(!this.disposed&&!this.treeNavigation){if("message_update"===a.type)return void this.scheduleLiveUpdate(a);this.flushLiveUpdates(),"message_start"===a.type?(this.clearLiveUpdate(a.tempId),this.liveUpdatesByTempId.set(a.tempId,{lastPublishedAt:Date.now(),pending:null,timer:null,receivedCount:0,publishedCount:0})):("message_commit"===a.type||"message_discard"===a.type)&&this.finishLiveUpdate(a.tempId),("message_commit"===a.type||"session_info_changed"===a.type)&&(0,p.xt)(this.cwd),this.publish(a)}}scheduleLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a.tempId)??{lastPublishedAt:0,pending:null,timer:null,receivedCount:0,publishedCount:0};if(b.pending=a,b.receivedCount+=1,this.liveUpdatesByTempId.set(a.tempId,b),b.timer)return;let c=Date.now()-b.lastPublishedAt,d=Math.max(0,500-c);0===d?this.publishPendingLiveUpdate(b):b.timer=setTimeout(()=>{this.liveUpdatesByTempId.get(a.tempId)===b&&(b.timer=null,this.publishPendingLiveUpdate(b))},d)}publishPendingLiveUpdate(a){let b=a.pending;b&&!this.disposed&&(a.pending=null,a.lastPublishedAt=Date.now(),a.publishedCount+=1,this.publish(b))}flushLiveUpdates(){for(let a of this.liveUpdatesByTempId.values())a.timer&&clearTimeout(a.timer),a.timer=null,this.publishPendingLiveUpdate(a)}finishLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a);this.clearLiveUpdate(a),b&&b.receivedCount!==b.publishedCount&&console.debug("[Pi Desk][PiChatWorker] 流式消息更新已合并",{sessionId:this.sessionManager.getSessionId(),tempId:a,receivedCount:b.receivedCount,publishedCount:b.publishedCount})}clearLiveUpdate(a){let b=this.liveUpdatesByTempId.get(a);b?.timer&&clearTimeout(b.timer),this.liveUpdatesByTempId.delete(a)}clearLiveUpdates(){for(let a of this.liveUpdatesByTempId.values())a.timer&&clearTimeout(a.timer);this.liveUpdatesByTempId.clear()}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][PiChatWorker] 事件监听器执行失败",{sessionId:this.sessionManager.getSessionId(),eventType:a.type,errorName:b instanceof Error?b.name:"UnknownError"})}}clearMemory(){this.steeringQueue.length=0,this.followUpQueue.length=0,this.pendingQueueText.clear(),this.bashTempsById.clear(),this.pendingPrompt=null,this.activeMessage=null,this.activeValidation=null,this.activeCompactionTempId=null,this.oversizedToolCallAbortRequested=!1,this.acceptedInputs.length=0,this.presentedInputTempIds.clear(),this.committedEntryIds.clear(),this.backgroundTaskIds.clear()}}d()}catch(a){d(a)}})},40333:(a,b,c)=>{c.d(b,{$m:()=>d.$m,FX:()=>d.FX,Pu:()=>d.Pu,QK:()=>d.QK,Tk:()=>d.Tk,nJ:()=>d.nJ,qs:()=>d.qs});var d=c(43969)},41904:(a,b,c)=>{c.d(b,{J:()=>f,a:()=>e});var d=c(59473);let e=d.Ik({locale:d.k5(["zh-CN","en"]),timeZone:d.Yj().trim().min(1).max(100).refine(a=>{try{return new Intl.DateTimeFormat("en",{timeZone:a}),!0}catch{return!1}},"无效的 IANA 时区")}).strict().readonly(),f=d.Ik({region:e}).strict().readonly()},41966:(a,b,c)=>{c.d(b,{L:()=>d});function d(a){if(!(a instanceof Error)||"PiDeskPluginMethodError"!==a.name)return!1;let b=a.code;return 400===b||404===b||409===b}},42520:(a,b,c)=>{c.d(b,{pL:()=>d});function d(a,b){let c=(globalThis.__piDeskNativePluginDiagnostics||(globalThis.__piDeskNativePluginDiagnostics=[]),globalThis.__piDeskNativePluginDiagnostics);!c.some(c=>c.cwd===a&&c.message===b)&&(c.push({cwd:a,message:b}),c.length>100&&c.splice(0,c.length-100))}},42633:(a,b,c)=>{c.d(b,{J8:()=>f,qf:()=>e});var d=c(59473);let e=d.KC([d.Yj(),d.Ik({default:d.Yj(),translations:d.g1(d.Yj().min(1).max(35),d.Yj()).refine(a=>Object.keys(a).length<=16,"too many translations")}).strict()]);function f(a,b){return{default:a,translations:{en:b}}}},43969:(a,b,c)=>{c.d(b,{$m:()=>g,FX:()=>h,Pu:()=>m,QK:()=>i,Tk:()=>k,nJ:()=>j,qs:()=>l});var d=c(59473);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.g1(d.Yj(),d.Pq());function g(a,b){return`${a}\u0000${b}`}function h(a){return e.parse(a)}function i(a){return e.parse(a)}function j(a,b){let c=f.parse(a);if(Buffer.byteLength(JSON.stringify(c),"utf8")>2097152)throw new m(b);return c}class k extends Error{constructor(a,b){super(`Plugin method was not found: ${a}/${b}`),this.name="L4PiPluginMethodNotFoundError"}}class l extends Error{constructor(a,b){super(`Plugin method is already registered: ${a}/${b}`),this.name="L4PiPluginMethodConflictError"}}class m extends Error{constructor(a){super(`Plugin method ${a} exceeds 2MB`),this.direction=a,this.name="L4PiPluginMethodPayloadTooLargeError"}}},44095:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{K:()=>z,y:()=>w});var e=c(77598),f=c(58500),g=c(51455),h=c(76760),i=c(59473),j=c(47511),k=c(58801),l=c(88502),m=c(43969),n=a([k]);k=(n.then?(await n)():n)[0];let r=i.g1(i.Yj(),i.Pq()),s=i.Ik({workId:i.Yj().trim().min(1),sessionId:i.Yj().trim().min(1),branchId:i.Yj().trim().min(1)}).strict(),t=i.Ik({source:s,cwd:i.Yj().trim().min(1),status:i.k5(["main_running","background_running","completed","idle"])}).strict(),u=i.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),v=i.ai().int().safe();class w extends Error{constructor(){super("插件运行时仍有调用正在执行"),this.name="L4PiPluginRuntimeBusyError"}}class x extends Error{constructor(a,b){super(b instanceof Error?b.message:String(b),{cause:b}),this.phase=a,this.name="L4PiPluginPhaseError"}}class y extends x{constructor(a,b){super(a,Error("插件加载超时,已停止本次加载")),this.execution=b,this.name="L4PiPluginLoadTimeoutError"}}function o(a,b,c){if("string"!=typeof b||!b.trim())throw Error(`package.json.${c} must be a non-empty string`);let d=(0,h.resolve)(a,b),e=(0,h.relative)(a,d);if(e.startsWith("..")||(0,h.isAbsolute)(e))throw Error(`package.json.${c} must stay inside the package root`);return d}function p(a){return a instanceof Error&&a.message?a.message:String(a)}async function q(a){let b=null,c=Promise.resolve().then(a.execute);a.owner.pendingCleanup.add(c);let d=()=>{a.owner.pendingCleanup.delete(c)};c.then(d,d);try{if(await Promise.race([c.then(()=>!0),new Promise(a=>{b=setTimeout(()=>a(!1),1500)})]))return;throw a.onTimeout?.(),Error(`插件 ${a.phase} 超时,关闭结果未确认`)}catch(b){console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 生命周期执行失败",{source:a.owner.source,packageName:a.owner.packageName,phase:a.phase,timeoutMs:1500,message:p(b)})}finally{b&&clearTimeout(b)}}class z{constructor(a,b){this.packageProvider=a,this.hostSettings=b,this.methods=new Map,this.pluginOwners=new Map,this.browserEntries=new Map,this.declarations=new Map,this.capabilityLoaders=new Map,this.owners=[],this.loadingOwners=new Set,this.changeListeners=new Set,this.changingSources=new Set,this.maintainingSources=new Set,this.lifetime=new AbortController,this.packageDiagnostics=new Map,this.recoveries=new Map,this.initializePromise=null,this.initialized=!1,this.disposed=!1,this.acceptingCalls=!0,this.loadError=null,this.workSessionProvider=null,this.pushSender=null,this.appRuntimeSink=null}initialize(){return this.disposed?Promise.reject(Error("Global plugin runtime has been disposed")):this.initialized?Promise.resolve():(this.initializePromise||(this.initializePromise=this.loadConfiguredPackages().catch(a=>{this.loadError=p(a),console.error("[Pi Desk][GlobalPluginRuntime] 读取插件配置失败,核心应用继续启动",{errorName:a instanceof Error?a.name:"UnknownError",message:this.loadError})}).finally(()=>{this.initializePromise=null,this.initialized=!0,this.publishChanges()})),this.initializePromise)}subscribeChanges(a){return this.changeListeners.add(a),()=>this.changeListeners.delete(a)}publishChanges(){if(!this.disposed)for(let a of this.changeListeners)try{a()}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 状态监听失败",{message:p(a)})}}async withSourceIdle(a,b,c,d){let e,g=AbortSignal.any([c,this.lifetime.signal]);g.throwIfAborted();let h=new Promise((a,b)=>{e=()=>b(g.reason),g.addEventListener("abort",e,{once:!0})});try{await Promise.race([this.initialize(),h])}finally{g.removeEventListener("abort",e)}if(g.throwIfAborted(),!this.acceptingCalls||this.changingSources.has(a)||this.maintainingSources.has(a))throw new w;this.cancelRecovery(a),this.maintainingSources.add(a);try{for(;this.owners.some(b=>b.source===a&&b.activeCalls.size>0);)d(`插件 ${a} 仍有调用正在执行`),await (0,f.setTimeout)(250,void 0,{signal:g});return g.throwIfAborted(),await b()}finally{this.maintainingSources.delete(a)}}async replaceSource(a,b){if(await this.initialize(),this.disposed||!this.acceptingCalls||this.changingSources.has(a))throw new w;this.cancelRecovery(a);let c=this.owners.find(b=>b.source===a);this.changingSources.add(a);try{if(c&&this.releaseOwner(c),this.disposed)throw Error("Global plugin runtime has been disposed");if((0,k.N)(),this.packageDiagnostics.delete(a),null!==b){if(await this.loadPackage(a,b),this.disposed)throw Error("Global plugin runtime has been disposed");let c=this.packageDiagnostics.get(a);if(c?.status==="failed")throw Error(c.error?.message??"插件加载失败")}}finally{this.changingSources.delete(a),this.publishChanges()}}ownerPublished(a){return a.active&&!a.draining&&!this.changingSources.has(a.source)&&this.owners.includes(a)}readDiagnostics(){return{packages:[...this.packageDiagnostics.values()].sort((a,b)=>a.source.localeCompare(b.source)).map(a=>structuredClone(a)),loadError:this.loadError}}readCapabilityRegistrations(){return[...this.owners].filter(a=>this.ownerPublished(a)).sort((a,b)=>a.source.localeCompare(b.source)).map(a=>({source:a.source,methods:[...this.methods.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.method.localeCompare(b.method):c}).map(({pluginName:a,method:b})=>({pluginName:a,method:b})),browserEntries:[...this.browserEntries.values()].filter(b=>b.owner===a).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).map(({pluginName:a})=>({pluginName:a})),messageDeclarations:[...this.declarations.values()].filter(b=>b.owner===a).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,priority:c.priority}))}))}async prepareReload(){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls||this.changingSources.size>0||this.maintainingSources.size>0||this.owners.some(a=>a.activeCalls.size>0))throw new w;for(let a of(this.acceptingCalls=!1,this.recoveries.keys()))this.cancelRecovery(a);for(let a of this.owners)a.draining=!0;await Promise.all([...this.owners].reverse().map(async a=>{let b=a.beforeReload;if(!b)return;a.beforeReload=null;let c=new AbortController;await q({owner:a,phase:"beforeReload",execute:()=>b({signal:c.signal}),onTimeout:()=>c.abort()})}))}bindWorkSessionProvider(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.workSessionProvider=a,()=>{this.workSessionProvider===a&&(this.workSessionProvider=null)}}bindPushSender(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.pushSender=a,()=>{this.pushSender===a&&(this.pushSender=null)}}bindAppRuntimeSink(a){if(this.disposed)throw Error("Global plugin runtime has been disposed");return this.appRuntimeSink=a,()=>{this.appRuntimeSink===a&&(this.appRuntimeSink=null)}}async runOwnedCall(a,b){let c;if(this.ensureOwnerActive(a),this.maintainingSources.has(a.source))throw new w;let d=new AbortController,e=new Promise((a,b)=>{c=b}),f=()=>{c(Error("Pi Desk Plugin owner is no longer active"))};d.signal.addEventListener("abort",f,{once:!0}),a.activeCalls.add(d);try{let c=await Promise.race([Promise.resolve().then(()=>(this.ensureOwnerActive(a),b(d.signal))),e]);return this.ensureOwnerActive(a),c}finally{a.activeCalls.delete(d),d.signal.removeEventListener("abort",f)}}async invoke(a,b,c){if(await this.initialize(),this.disposed)throw Error("Global plugin runtime has been disposed");if(!this.acceptingCalls)throw new w;let d=(0,m.FX)(a),e=(0,m.QK)(b),f=this.methods.get((0,m.$m)(d,e));if(!f)throw new m.Tk(d,e);if(!this.ownerPublished(f.owner)||this.changingSources.has(f.owner.source))throw new w;let g=(0,m.nJ)(c,"input");return this.runOwnedCall(f.owner,async a=>{let b=await f.execute(g,{signal:a});return(0,m.nJ)(b,"output")})}async listCapabilityDeclarations(){if(await this.initialize(),this.disposed||!this.acceptingCalls)throw new w;let a=await Promise.all([...this.capabilityLoaders].filter(([,a])=>this.ownerPublished(a.owner)&&!this.changingSources.has(a.owner.source)).map(async([a,b])=>{try{return await this.runOwnedCall(b.owner,async c=>{let d=await b.load({signal:c});if(this.capabilityLoaders.get(a)!==b)throw Error(`能力声明已被替换:${a}`);return[a,j.dO.parse(d)]})}catch(b){throw Error(`读取 ${a} 能力选项失败:${p(b)}`,{cause:b})}}));return Object.fromEntries(a)}async listBrowserEntries(){return await this.initialize(),[...this.browserEntries.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>a.pluginName.localeCompare(b.pluginName)).flatMap(({pluginName:a,entryPath:b,resourceKey:c,snapshot:d})=>d?[{pluginName:a,entryPath:b,resourceKey:c,snapshot:d}]:[])}async listMessageDeclarations(){return await this.initialize(),this.readMessageDeclarations()}readMessageDeclarations(){return[...this.declarations.values()].filter(a=>this.ownerPublished(a.owner)).sort((a,b)=>{let c=a.pluginName.localeCompare(b.pluginName);return 0===c?a.declarationName.localeCompare(b.declarationName):c}).map(({pluginName:a,declarationName:b,declaration:c})=>({pluginName:a,declarationName:b,declaration:c}))}async dispose(){if(this.disposed)return;for(let a of(this.disposed=!0,this.lifetime.abort(),this.recoveries.keys()))this.cancelRecovery(a);this.acceptingCalls=!1,this.changeListeners.clear(),this.workSessionProvider=null,this.pushSender=null;let a=[...new Set([...this.owners,...this.loadingOwners])].reverse();this.owners.length=0,this.loadingOwners.clear(),await Promise.all(a.map(a=>this.releaseOwner(a))),this.methods.clear(),this.pluginOwners.clear(),this.browserEntries.clear(),this.declarations.clear(),this.capabilityLoaders.clear(),this.appRuntimeSink=null}async loadConfiguredPackages(){for(let a of(this.loadError=null,this.packageDiagnostics.clear(),await this.packageProvider())){if(this.disposed)return;let b=await this.loadPackage(a.source,a.installedPath);b&&!this.disposed&&this.recoveries.set(a.source,{installedPath:a.installedPath,settled:b.execution,controller:new AbortController})}for(let[a,b]of this.recoveries)this.recoverSource(a,b)}cancelRecovery(a){let b=this.recoveries.get(a);this.recoveries.delete(a),b?.controller.abort()}async recoverSource(a,b){let c,d=b.controller.signal,e=new Promise((a,b)=>{c=()=>b(d.reason),d.addEventListener("abort",c,{once:!0})});try{await Promise.race([b.settled,e]),d.throwIfAborted(),console.info("[Pi Desk][GlobalPluginRuntime] 插件加载超时,稍后自动重试一次",{source:a,delayMs:1e4}),await (0,f.setTimeout)(1e4,void 0,{signal:d}),d.throwIfAborted(),this.recoveries.delete(a),await this.replaceSource(a,b.installedPath),console.info("[Pi Desk][GlobalPluginRuntime] 插件自动重试成功",{source:a})}catch(b){d.aborted||console.warn("[Pi Desk][GlobalPluginRuntime] 插件自动重试失败,不再自动加载",{source:a,message:p(b)})}finally{d.removeEventListener("abort",c),this.recoveries.get(a)===b&&this.recoveries.delete(a)}}async loadOwnerWithinDeadline(a,b,c){let d,e="entry",f=performance.now(),g=()=>{let b=Math.round(performance.now()-f);b<1e3||console.info("[Pi Desk][GlobalPluginRuntime] 插件加载阶段耗时",{source:a.source,packageName:a.packageName,phase:e,durationMs:b})},h=a=>{g(),e=a,f=performance.now()},i=(async()=>{let d=()=>h("setup");void 0!==b?await this.loadEntryOwner(a,b,d):await this.loadLegacyOwner(a,c,d),h("resources");try{await this.validateOwnerResources(a)}catch(a){throw new x("resources",a)}this.ensureOwnerActive(a)})();try{await Promise.race([i,new Promise((a,b)=>{d=setTimeout(()=>{b(new y(e,i))},15e3)})])}finally{d&&clearTimeout(d),g()}}async loadPackage(a,b){let c,d=performance.now(),e=(0,h.resolve)(b);try{let a=(0,h.join)(e,"package.json");c=JSON.parse(await (0,g.readFile)(a,"utf8"))}catch(b){return this.packageDiagnostics.set(a,{source:a,packageName:null,version:null,pluginName:null,status:"failed",error:{phase:"package",message:p(b)}}),null}let f=c.piDesk?.entry,i=c.piDesk?.global;if(void 0===f&&void 0===i||this.disposed)return null;let j={source:a,packageName:"string"==typeof c.name?c.name:null,version:"string"==typeof c.version?c.version:null,packageRoot:e,active:!0,draining:!1,pluginNames:new Set,activeCalls:new Set,subscriptions:new Set,pendingCleanup:new Set,beforeReload:null,disposer:null};console.info("[Pi Desk][GlobalPluginRuntime] 开始加载 Pi Desk Plugin",{source:a,packageName:j.packageName}),this.loadingOwners.add(j);try{await this.loadOwnerWithinDeadline(j,f,i),this.owners.push(j),this.recordOwnerDiagnostic(j),console.info("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 已加载",{source:a,packageName:j.packageName,pluginNames:[...j.pluginNames],methodCount:[...this.methods.values()].filter(a=>a.owner===j).length,browserEntryCount:[...this.browserEntries.values()].filter(a=>a.owner===j).length,declarationCount:[...this.declarations.values()].filter(a=>a.owner===j).length,durationMs:Math.round(performance.now()-d)})}catch(f){let b=f instanceof x?f.phase:"entry",c=[...j.pluginNames][0]??null;await this.releaseOwner(j);let e=p(f);if(this.packageDiagnostics.set(a,{source:a,packageName:j.packageName,version:j.version,pluginName:c,status:"failed",error:{phase:b,message:e}}),console.warn("[Pi Desk][GlobalPluginRuntime] Pi Desk Plugin 加载失败",{source:a,packageName:j.packageName,phase:b,errorName:f instanceof Error?f.name:"UnknownError",message:e,durationMs:Math.round(performance.now()-d)}),f instanceof y)return{execution:f.execution.catch(()=>{}).then(async()=>{await Promise.allSettled([...j.pendingCleanup])})}}finally{this.loadingOwners.delete(j)}return null}async loadEntryOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.entry");if(!(await (0,g.stat)(d)).isFile())throw Error("Pi Desk Plugin entry is not a file");let e=(await (0,k.G)(d,a.packageRoot)).default;if(!e||"object"!=typeof e||"string"!=typeof e.name||"function"!=typeof e.setup)throw Error("Pi Desk Plugin entry must default-export definePiDeskPlugin(...)");let f=(0,m.FX)(e.name);this.claimPluginName(a,f),c();try{let b=function(a){if(void 0===a)return{beforeReload:null,disposer:null};if("function"==typeof a)return{beforeReload:null,disposer:a};if(!a||"object"!=typeof a)throw Error("Pi Desk Plugin setup must return void, a disposer, or a lifecycle object");if(void 0!==a.beforeReload&&"function"!=typeof a.beforeReload)throw Error("Pi Desk Plugin lifecycle.beforeReload must be a function");if(void 0!==a.dispose&&"function"!=typeof a.dispose)throw Error("Pi Desk Plugin lifecycle.dispose must be a function");return{beforeReload:a.beforeReload??null,disposer:a.dispose??null}}(await e.setup(this.createPiDeskFacade(a,f,a.packageRoot)));if(a.beforeReload=b.beforeReload,a.disposer=b.disposer,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}async loadLegacyOwner(a,b,c){let d=o(a.packageRoot,b,"piDesk.global");if(!(await (0,g.stat)(d)).isFile())throw Error("Global Plugin entry is not a file");let e=await (0,k.G)(d,a.packageRoot);if("function"!=typeof e.default)throw Error("Global Plugin entry must default-export a factory function");let f=e.default;c();try{let b=await f(this.createLegacyApi(a));if(void 0!==b&&"function"!=typeof b)throw Error("Global Plugin factory must return void or a disposer function");if(a.disposer=b??null,!a.active||this.disposed)throw await this.releaseOwner(a),Error("插件初始化完成时 Owner 已失效")}catch(a){throw new x("setup",a)}}claimPluginName(a,b){this.ensureOwnerActive(a);let c=this.pluginOwners.get(b);if(c&&c!==a)throw Error(`Pi Desk pluginName is already registered: ${b}`);this.pluginOwners.set(b,a),a.pluginNames.add(b)}createLegacyApi(a){return{bindPlugin:b=>{let c=(0,m.FX)(b);return this.claimPluginName(a,c),{name:c,registerMethod:(b,d)=>this.registerMethod(a,c,b,d)}}}}createPiDeskFacade(a,b,c){return{name:b,host:{settings:{getSnapshot:()=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");return this.hostSettings.getSnapshot()},subscribe:b=>{if(this.ensureOwnerActive(a),!this.hostSettings)throw Error("宿主共享设置尚未就绪");let c=this.hostSettings.subscribe(()=>{a.active&&!a.draining&&b()});return a.subscriptions.add(c),()=>{if(a.subscriptions.delete(c))return c()}}},workSessions:{listWorkSessions:async()=>{this.ensureOwnerActive(a);let b=await this.readWorkSessions();return this.ensureOwnerActive(a),b}}},notifications:{publish:c=>(this.ensureOwnerActive(a),this.requireAppRuntimeSink().publishNotification(b,c)),update:(c,d)=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().updateNotification(b,c,d)},delete:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().deleteNotification(b,c)}},setState:c=>{this.ensureOwnerActive(a),this.requireAppRuntimeSink().setState(b,c)},registerMethod:(c,d)=>this.registerMethod(a,b,c,d),registerBrowserEntry:d=>{if(this.ensureOwnerActive(a),this.browserEntries.has(b))throw Error(`Browser Entry is already registered: ${b}`);let f=o(c,d,"browserEntry"),g={pluginName:b,entryPath:f,resourceKey:(0,e.randomUUID)(),snapshot:null,owner:a};return this.browserEntries.set(b,g),this.registrationDisposer(a,()=>{this.browserEntries.get(b)===g&&this.browserEntries.delete(b)})},declareCapabilities:c=>{if(this.ensureOwnerActive(a),"function"!=typeof c)throw Error("能力声明必须是按需查询函数");if(this.capabilityLoaders.has(b))throw Error(`能力声明已注册:${b}`);let d={load:c,owner:a};return this.capabilityLoaders.set(b,d),this.registrationDisposer(a,()=>{this.capabilityLoaders.get(b)===d&&this.capabilityLoaders.delete(b)})},declareMessage:(c,d)=>this.registerDeclaration(a,b,c,d),pushGlobal:(c,d)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"global"},c,d)},pushSession:(c,d,e)=>{a.active&&!a.draining&&this.sendPush(b,{scope:"session",source:s.parse(c)},d,e)}}}registerMethod(a,b,c,d){this.ensureOwnerActive(a);let e=(0,m.QK)(c),f=(0,m.$m)(b,e);if(this.methods.has(f))throw new m.qs(b,e);let g={pluginName:b,method:e,execute:d,owner:a};return this.methods.set(f,g),this.registrationDisposer(a,()=>{this.methods.get(f)===g&&this.methods.delete(f)})}registerDeclaration(a,b,c,d){var e;this.ensureOwnerActive(a);let f=u.parse(c);if(!d||"object"!=typeof d||"function"!=typeof d.match||"function"!=typeof d.project)throw Error("Message Declaration must provide match and project functions");let g={priority:(e=d.priority,v.parse(e)),match:d.match,project:d.project},h=`${b}\u0000${f}`;if(this.declarations.has(h))throw Error(`Message Declaration is already registered: ${b}/${f}`);let i={pluginName:b,declarationName:f,declaration:g,owner:a};return this.declarations.set(h,i),this.registrationDisposer(a,()=>{this.declarations.get(h)===i&&this.declarations.delete(h)})}registrationDisposer(a,b){let c=!0;return()=>{c&&(c=!1,a.active&&b())}}requireAppRuntimeSink(){if(!this.appRuntimeSink)throw Error("App Runtime sink has not been bound");return this.appRuntimeSink}sendPush(a,b,c,d){if(this.disposed)return;let e=(0,m.QK)(c),f=function(a){let b=r.parse(a);if(Buffer.byteLength(JSON.stringify(b),"utf8")>65536)throw Error("Plugin Push data exceeds 64KB");return b}(d);this.pushSender?.({pluginName:a,target:b,event:e,data:structuredClone(f)})}async readWorkSessions(){if(!this.workSessionProvider||this.disposed)return[];let a=await this.workSessionProvider();return i.YO(t).parse(a).map(a=>structuredClone(a))}async validateOwnerResources(a){for(let b of[...this.browserEntries.values()].filter(b=>b.owner===a)){if(!(await (0,g.stat)(b.entryPath)).isFile())throw Error("Browser Entry resource is not a file");if("entry.js"!==(0,h.basename)(b.entryPath))throw Error("Browser Entry resource file must be named entry.js");let c=await (0,l.f)(b.entryPath);if(this.ensureOwnerActive(a),[...this.browserEntries.values()].reduce((a,b)=>a+(b.snapshot?.size??0),0)+c.size>0x8000000)throw Error("Browser 模块快照总量超过128MB,拒绝加载此插件");b.snapshot=c}}recordOwnerDiagnostic(a){this.packageDiagnostics.set(a.source,{source:a.source,packageName:a.packageName,version:a.version,pluginName:[...a.pluginNames][0]??null,status:"ready",error:null})}ensureOwnerActive(a){if(!a.active||a.draining||this.disposed)throw Error("Pi Desk Plugin owner is no longer active")}async releaseOwner(a){let b=[...a.subscriptions];if(a.subscriptions.clear(),a.active){for(let b of(a.active=!1,a.activeCalls))b.abort();a.activeCalls.clear();let b=this.owners.indexOf(a);for(let[c,d]of(b>=0&&this.owners.splice(b,1),this.methods))d.owner===a&&this.methods.delete(c);for(let[b,c]of this.browserEntries)c.owner===a&&this.browserEntries.delete(b);for(let[b,c]of this.declarations)c.owner===a&&this.declarations.delete(b);for(let[b,c]of this.capabilityLoaders)c.owner===a&&this.capabilityLoaders.delete(b);for(let b of a.pluginNames)if(this.pluginOwners.get(b)===a){this.pluginOwners.delete(b);try{this.appRuntimeSink?.releasePlugin(b)}catch(a){console.warn("[Pi Desk][GlobalPluginRuntime] 清理插件 App Runtime 失败",{pluginName:b,errorName:a instanceof Error?a.name:"UnknownError",message:p(a)})}}a.pluginNames.clear()}let c=a.beforeReload,d=a.disposer;a.beforeReload=null,a.disposer=null;let e=new AbortController;await Promise.all([...b.map(b=>q({owner:a,phase:"dispose",execute:b})),c?q({owner:a,phase:"beforeReload",execute:()=>c({signal:e.signal}),onTimeout:()=>e.abort()}):Promise.resolve(),d?q({owner:a,phase:"dispose",execute:d}):Promise.resolve()])}}d()}catch(a){d(a)}})},46107:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Nx:()=>n,cY:()=>m,sv:()=>o,to:()=>l});var e=c(73024),f=c(76760),g=c(77598),h=c(75430),i=c(59473),j=c(58417),k=a([h]);h=(k.then?(await k)():k)[0];let n="https://registry.npmjs.org",o="https://mirrors.cloud.tencent.com/npm",p=i.Ik({downloadSource:j.w3.default({mode:"auto"}),disabled:i.YO(i.Yj()).max(2e3).default([]),registries:i.g1(i.Yj(),j.SZ).default({}),updateTags:i.g1(i.Yj(),j.mR).default({})}).strict();function l(a=(0,h.getAgentDir)()){let b=(0,f.join)(a,"pi-desk-plugins.json");return(0,e.existsSync)(b)?p.parse(JSON.parse((0,e.readFileSync)(b,"utf8"))):p.parse({})}function m(a,b=(0,h.getAgentDir)()){!function(a,b){let c=(0,f.join)(a,"pi-desk-plugins.json"),d=p.parse(b(l(a)));(0,e.mkdirSync)((0,f.dirname)(c),{recursive:!0});let h=`${c}.${(0,g.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,`${JSON.stringify(d,null,2)}
|
|
20
21
|
`,"utf8"),(0,e.renameSync)(h,c)}finally{(0,e.rmSync)(h,{force:!0})}}(b,b=>({...b,downloadSource:a}))}d()}catch(a){d(a)}})},46524:(a,b,c)=>{c.d(b,{Ns:()=>f,cg:()=>n,dX:()=>g,eD:()=>q,j0:()=>o,u3:()=>p});var d=c(12727);let e=new WeakMap;class f extends Error{constructor(a){super(`Pi session entry was not found: ${a}`),this.name="L4PiSessionEntryNotFoundError"}}class g extends Error{constructor(a){super(`Pi session fork target is not a user message: ${a}`),this.name="L4PiSessionForkTargetError"}}function h(a){return"string"==typeof a?a:Array.isArray(a)?a.flatMap(a=>a&&"object"==typeof a&&"text"===a.type&&"string"==typeof a.text?[a.text]:[]).join("\n"):""}function i(a){return Array.isArray(a)?a.filter(a=>null!==a&&"object"==typeof a&&"image"===a.type).length:0}function j(a){let b=a.replace(/\s+/g," ").trim();return b.length<=240?b:`${b.slice(0,239)}…`}function k(a){try{return JSON.stringify(a,null,2)??""}catch{return""}}function l(a){let b=a.getEntries(),c=e.get(a);if(c?.entryCount===b.length)return c.callsById;let f=new Map;for(let a of b)if("message"===a.type&&"assistant"===a.message.role)for(let b of(0,d.zz)(a.message.content))f.set(b.id,{name:b.name,input:b.input,display:(0,d.zG)(b.name,b.input)});return e.set(a,{entryCount:b.length,callsById:f}),f}function m(a){switch(a.type){case"message":switch(a.message.role){case"user":return"user";case"assistant":return"assistant";case"toolResult":return"tool";case"bashExecution":return"bash";case"custom":return"custom_message";default:return"custom"}case"custom_message":return"custom_message";case"compaction":return"compaction";case"branch_summary":return"branch_summary";case"custom":case"context_edit":case"usage":return"custom";case"model_change":return"model_change";case"thinking_level_change":return"thinking_level_change";case"session_info":return"session_info";case"label":return"label"}}function n(a,b){let c=l(a);return{sessionId:a.getSessionId(),leafEntryId:a.getLeafId(),nodes:a.getEntries().map(d=>({entryId:d.id,parentEntryId:d.parentId,timestampMs:function(a){let b=Date.parse(a.timestamp);if(!Number.isSafeInteger(b)||b<0)throw Error(`Pi session entry has an invalid timestamp: ${a.id}`);return b}(d),kind:m(d),preview:function(a,b,c){switch(a.type){case"message":let d=a.message;switch(d.role){case"user":{let a=h(d.content),b=i(d.content);return j(a||(b>0?`${b} 张图片`:""))}case"assistant":{let a=h(d.content);if(a)return j(a);if(d.errorMessage)return j(d.errorMessage);return"aborted"===d.stopReason?"已中断":""}case"toolResult":return function(a,b){if(!b)return j(a);let c=b.display.inputPreview??function(a){try{let b=JSON.stringify(a);return"{}"===b?"":j(b)}catch{return""}}(b.input),d=c?`${b.name}: ${c}`:b.name;return j(b.display.activity?`${d} \xb7 ${b.display.activity}`:d)}(d.toolName,b.get(d.toolCallId));case"bashExecution":return j(d.command);case"custom":return j(h(d.content));default:return""}case"custom_message":return j(h(a.content));case"compaction":case"branch_summary":return j(a.summary);case"custom":return j(a.customType);case"context_edit":return j(`${null===a.replacement?"从上下文移除":"替换上下文内容"}:${a.targetId}`);case"usage":return j(`用量记录:${a.kind}`);case"model_change":return j(`${a.provider}/${c?.getModel(a.provider,a.modelId)?.name||a.modelId}`);case"thinking_level_change":return j(a.thinkingLevel);case"session_info":return j(a.name??"");case"label":return j(a.label??"已清除标签")}}(d,c,b),label:a.getLabel(d.id)?.trim()||null}))}}function o(a,b,c){let d=a.getEntry(b);if(!d)throw new f(b);let e=function(a,b,c){switch(a.type){case"message":let d=a.message;switch(d.role){case"user":{let a=h(d.content),b=i(d.content);return[a,b>0?`[图片 ${b} 张]`:""].filter(Boolean).join("\n\n")}case"assistant":return h(d.content)||d.errorMessage||("aborted"===d.stopReason?"已中断":"");case"toolResult":return function(a,b){if(!b)return`工具:${a}
|
|
21
22
|
|
|
22
23
|
未找到对应的 Tool Call 参数`;let c=[`工具:${b.name}`];b.display.reasoning&&c.push(`目的:${b.display.reasoning}`),b.display.inputPreview&&c.push(`调用:${b.display.inputPreview}`),b.display.activity&&c.push(`范围/变化:${b.display.activity}`);let d=Object.fromEntries(Object.entries(b.input).filter(([a])=>"reasoning"!==a));return Object.keys(d).length>0&&c.push("","调用参数:",k(d)),c.join("\n")}(d.toolName,b.get(d.toolCallId));case"bashExecution":return`命令:${d.command}`;case"custom":return h(d.content);default:return""}case"custom_message":return h(a.content);case"compaction":case"branch_summary":return a.summary;case"custom":return[`类型:${a.customType}`,k(a.data)].filter(Boolean).join("\n\n");case"context_edit":return`操作:${null===a.replacement?"从上下文移除":"替换上下文内容"}
|
|
@@ -25,18 +26,17 @@ ${this.initialization.describeStage()}`))}async runSessionLifecycle(a,b=15e3){if
|
|
|
25
26
|
|
|
26
27
|
${k(a.usage)}`;case"model_change":return`${a.provider}/${c?.getModel(a.provider,a.modelId)?.name||a.modelId}`;case"thinking_level_change":return a.thinkingLevel;case"session_info":return a.name??"";case"label":return a.label??"已清除标签"}}(d,l(a),c);return{entryId:b,kind:m(d),content:e.length<=65536?e:e.slice(0,65536),truncated:e.length>65536}}function p(a,b){let c=a.getEntry(b);if(!c)throw new f(b);if("message"!==c.type||"user"!==c.message.role)throw new g(b);return{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.message.content)}}function q(a,b){let c=a.getEntry(b);if(!c)throw new f(b);return a.getLeafId()===b?{selectedEntryId:b,targetLeafEntryId:b,editorText:null,changed:!1}:"message"===c.type&&"user"===c.message.role?{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.message.content),changed:a.getLeafId()!==c.parentId}:"custom_message"===c.type?{selectedEntryId:b,targetLeafEntryId:c.parentId,editorText:h(c.content),changed:a.getLeafId()!==c.parentId}:{selectedEntryId:b,targetLeafEntryId:b,editorText:null,changed:!0}}},47511:(a,b,c)=>{c.d(b,{Dl:()=>o,Qg:()=>m,RC:()=>q,a4:()=>k,dO:()=>j,j0:()=>n});var d=c(59473);let e=d.Yj().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=d.Yj().trim().min(1).max(256),g=d.Ik({allow:d.YO(f).max(5e3).optional(),deny:d.YO(f).max(5e3).optional()}).strict(),h=d.Ik({value:d.Yj().trim().min(1).max(256),label:d.Yj().trim().min(1).max(120).optional(),description:d.Yj().trim().max(1e3).optional()}).strict(),i=d.Ik({label:d.Yj().trim().min(1).max(120),options:d.YO(h).max(5e3)}).strict(),j=d.g1(e,i),k=d.Yj().min(1).max(64),l=d.Ik({name:d.Yj().trim().min(1).max(64),tools:g.optional(),skills:g.optional(),plugins:d.g1(e,d.g1(e,g)).optional()}).strict(),m=d.g1(k,l).refine(a=>Object.keys(a).length<=100,"最多保存 100 个能力模式").refine(a=>new Set(Object.values(a).map(a=>a.name)).size===Object.keys(a).length,"模式名称不能重复"),n=d.g1(k,l.shape.name),o=d.Ik({tools:d.YO(h),skills:d.YO(h),plugins:d.g1(e,j)}).strict();function p(a,b){let c=0,d=0,e=-1,f=0;for(;d<b.length;)if("*"===a[c])e=c++,f=d;else if(a[c]===b[d])c+=1,d+=1;else{if(!(e>=0))return!1;c=e+1,d=++f}for(;"*"===a[c];)c+=1;return c===a.length}function q(a,b){return(a?.allow===void 0||a.allow.some(a=>p(a,b)))&&!a?.deny?.some(a=>p(a,b))}d.Ik({tools:g,skills:g,capabilities:d.g1(e,g)}).strict()},49080:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{A:()=>l});var e=c(73024),f=c(76760),g=c(75430),h=c(78262),i=c(28802),j=a([g,h,i]);[g,h,i]=j.then?(await j)():j;let m=new Set(["off","minimal","low","medium","high","xhigh","max"]);function k(a,b){return`${a}\u0000${b}`}async function l(a,b=process.cwd()){let c=(0,g.getAgentDir)(),d=a?.modelRuntime??await g.ModelRuntime.create({authPath:(0,f.join)(c,"auth.json"),modelsPath:(0,f.join)(c,"models.json")}),j=a?.settingsManager??g.SettingsManager.create(b,c);await d.refresh({allowNetwork:!1});let n=j.getEnabledModels(),o=n?.length?(await (0,g.resolveModelScopeWithDiagnostics)(n,d)).scopedModels.map(a=>a.model):[...await d.getAvailable()],p=new Map;for(let a of(0,h.oj)(o,d))p.set(k(a.provider,a.id),a);let q=[...p.values()].map(a=>({provider:a.provider,modelId:a.id,name:a.name,input:[...a.input],kind:d.getPhysicalModel(a.provider,a.id)?"physical":"virtual",contextWindow:a.contextWindow>0?a.contextWindow:null,thinkingLevels:[...(0,i.getSupportedThinkingLevels)(a)]})),r=new Map(q.map(a=>[k(a.provider,a.modelId),a])),s=[],t=0;for(let a of function(){let a=(0,f.join)((0,g.getAgentDir)(),"models.json");if(!(0,e.existsSync)(a))return[];try{let b=JSON.parse((0,e.readFileSync)(a,"utf8"));return Array.isArray(b.modelPresets)?b.modelPresets:[]}catch(b){return console.warn("[Pi Desk][PiModelCatalog] models.json 读取失败",{path:a,errorName:b instanceof Error?b.name:"UnknownError"}),[]}}()){if("string"!=typeof a.provider||!a.provider.trim()||"string"!=typeof a.modelId||!a.modelId.trim()||"string"!=typeof a.thinkingLevel||!m.has(a.thinkingLevel)||void 0!==a.color&&null!==a.color&&"string"!=typeof a.color){t+=1;continue}let b=a.thinkingLevel,c=r.get(k(a.provider,a.modelId));if(!c||!c.thinkingLevels.includes(b)){t+=1;continue}s.push({provider:a.provider,modelId:a.modelId,thinkingLevel:b,color:"string"==typeof a.color&&a.color.trim()?a.color:null})}return t>0&&console.warn("[Pi Desk][PiModelCatalog] 已忽略无效或不可用的模型预设",{cwd:a?.sessionManager.getCwd()??b,count:t}),{models:q,presets:s}}d()}catch(a){d(a)}})},54174:(a,b,c)=>{c.d(b,{Z:()=>i,f1:()=>j});let d=/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;class e extends Error{constructor(a){super(a),this.name="L4PiImageValidationError"}}function f(a,b){if(!Number.isSafeInteger(a)||a<=0)throw new e(`图片 ${b} 无效`);return a}let g=new Set([192,193,194,195,197,198,199,201,202,203,205,206,207]);function h(a,b){return a[b]|a[b+1]<<8|a[b+2]<<16}function i(a){if(!a||a.startsWith("data:")||!d.test(a))throw new e("图片 Base64 无效");let b=Buffer.from(a,"base64");if(0===b.length)throw new e("图片内容为空");let c=function(a){if(a.length>=8&&137===a[0]&&80===a[1]&&78===a[2]&&71===a[3]&&13===a[4]&&10===a[5]&&26===a[6]&&10===a[7])return"image/png";if(a.length>=3&&255===a[0]&&216===a[1]&&255===a[2])return"image/jpeg";if(a.length>=10&&["GIF87a","GIF89a"].includes(a.toString("ascii",0,6)))return"image/gif";if(a.length>=16&&"RIFF"===a.toString("ascii",0,4)&&"WEBP"===a.toString("ascii",8,12))return"image/webp";throw new e("图片格式不受支持")}(b);return{bytes:b,metadata:{mimeType:c,...function(a,b){switch(b){case"image/png":if(a.length<24||"IHDR"!==a.toString("ascii",12,16))throw new e("PNG 图片头无效");return{width:f(a.readUInt32BE(16),"宽度"),height:f(a.readUInt32BE(20),"高度")};case"image/jpeg":let c=2;for(;c+3<a.length;){for(;c<a.length&&255!==a[c];)c+=1;for(;c<a.length&&255===a[c];)c+=1;if(c>=a.length)break;let b=a[c];if(c+=1,216===b||1===b||b>=208&&b<=215)continue;if(217===b||218===b||c+1>=a.length)break;let d=a.readUInt16BE(c);if(d<2||c+d>a.length)break;if(g.has(b)){if(d<7)break;return{width:f(a.readUInt16BE(c+5),"宽度"),height:f(a.readUInt16BE(c+3),"高度")}}c+=d}throw new e("JPEG 图片尺寸无效");case"image/gif":if(a.length<10)throw new e("GIF 图片头无效");return{width:f(a.readUInt16LE(6),"宽度"),height:f(a.readUInt16LE(8),"高度")};case"image/webp":return function(a){let b=a.toString("ascii",12,16);if("VP8X"===b){if(a.length<30)throw new e("WebP VP8X 图片头无效");return{width:f(h(a,24)+1,"宽度"),height:f(h(a,27)+1,"高度")}}if("VP8L"===b){if(a.length<25||47!==a[20])throw new e("WebP VP8L 图片头无效");let b=a[21],c=a[22],d=a[23],g=a[24];return{width:f(1+((63&c)<<8|b),"宽度"),height:f(1+((15&g)<<10|d<<2|(192&c)>>6),"高度")}}if("VP8 "===b){if(a.length<30||157!==a[23]||1!==a[24]||42!==a[25])throw new e("WebP VP8 图片头无效");return{width:f(16383&a.readUInt16LE(26),"宽度"),height:f(16383&a.readUInt16LE(28),"高度")}}throw new e("WebP 图片编码无效")}(a)}}(b,c)}}}function j(a){let b=i(a.data);if(b.metadata.mimeType!==a.mimeType)throw new e("图片 MIME 与实际内容不一致");if(b.metadata.width!==a.width||b.metadata.height!==a.height)throw new e("图片尺寸与实际内容不一致");return b}},56752:(a,b,c)=>{c.d(b,{C:()=>f,b:()=>e});var d=c(76760);function e(a){return"win32"===process.platform?a.toLocaleLowerCase():a}function f(a,b){let c=(0,d.relative)(a,b);return""===c||!c.startsWith(`..${d.sep}`)&&".."!==c&&!(0,d.isAbsolute)(c)}},56971:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{o:()=>o});var e=c(51455),f=c(48161),g=c(76760),h=c(58417),i=c(73589),j=a([i]);function k(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function l(a){try{return await (0,e.realpath)(a)}catch{return(0,g.resolve)(a)}}function m(a){return"win32"===process.platform?a.toLowerCase():a}async function n(a){try{if((await (0,e.stat)(a)).isFile())return{version:null,description:null,hasNodeEntry:!1,error:null};let b=JSON.parse(await (0,e.readFile)((0,g.join)(a,"package.json"),"utf8"));if(!b||"object"!=typeof b||Array.isArray(b))throw Error("package.json 必须是对象");return{version:"string"==typeof b.version?b.version:null,description:(0,h._C)(b),hasNodeEntry:b.piDesk?.entry!==void 0||b.piDesk?.global!==void 0,hasNativeEntries:Array.isArray(b.pi?.extensions)&&b.pi.extensions.length>0,error:null}}catch(a){if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return{version:null,description:null,hasNodeEntry:!1,error:null};return{version:null,description:null,hasNodeEntry:!1,error:a instanceof Error?a.message:String(a)}}}async function o(a,b,c){let d=c.SettingsManager.create(a,b,{projectTrusted:!1}),h=new c.DefaultPackageManager({cwd:a,agentDir:b,settingsManager:d}),j=d.drainErrors().map(({error:a})=>a.message),o=new Map,p=new Map;for(let a of h.listConfiguredPackages()){if("user"!==a.scope)continue;let b=a.installedPath?await l(a.installedPath):null,c=b?await n(b):null,d=b?p.get(m(b)):void 0;b&&!d&&p.set(m(b),a.source),o.set(a.source,{source:a.source,kind:"package",path:b,nativePaths:[],hasPiResources:!0,piDeskRoot:b&&c?.hasNodeEntry&&!d?b:null,version:c?.version??null,description:c?.description??null,enabled:!0,error:d?`此目录已由 ${d} 声明,不能重复加载`:b?c?.error??null:"插件包未安装或安装目录不存在"})}let q=(0,g.join)(b,"extensions"),r=new Set;try{for(let a of(await (0,e.readdir)(q,{withFileTypes:!0})))if(!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink()))try{let b=await l((0,g.join)(q,a.name));(await (0,e.stat)(b)).isDirectory()&&r.add(b)}catch(b){j.push(`${a.name}: ${b instanceof Error?b.message:String(b)}`)}}catch(a){a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code||j.push(a instanceof Error?a.message:String(a))}for(let a of d.getGlobalSettings().extensions??[]){if(/^[!+-]|[?*{}]/.test(a))continue;let c=await l(a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a));try{(await (0,e.stat)(c)).isDirectory()&&r.add(c)}catch{}}let s=[...r].sort((a,b)=>b.length-a.length);try{let a=await h.resolve(async()=>"skip");for(let a of o.values())a.hasPiResources=!1;for(let b of[...a.extensions,...a.skills,...a.prompts,...a.themes])if(b.enabled&&"user"===b.metadata.scope&&"package"===b.metadata.origin){let a=o.get(b.metadata.source);a&&(a.hasPiResources=!0)}for(let b of a.extensions){if("user"!==b.metadata.scope)continue;let a=await l(b.path);if("package"===b.metadata.origin){let c=o.get(b.metadata.source);c&&b.enabled&&!c.nativePaths.includes(a)&&c.nativePaths.push(a);continue}let c=s.find(b=>k(b,a))??a,d=[...p].find(([b])=>k(b,m(a)));if(d){let c=o.get(d[1]);b.enabled&&c&&!c.nativePaths.includes(a)&&c.nativePaths.push(a),j.push(`扩展入口 ${a} 与已配置包 ${d[1]} 重复,保留包来源`);continue}let e=o.get(c);e||(e={source:c,kind:"extension",path:c,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!1,error:null},o.set(c,e)),b.enabled&&(e.enabled=!0,e.nativePaths.includes(a)||e.nativePaths.push(a))}}catch(a){j.push(a instanceof Error?a.message:String(a))}for(let a of s){if([...p.keys()].some(b=>k(b,m(a))))continue;let b=await n(a),c=o.get(a);if(!c&&!b.hasNodeEntry&&!b.error)continue;let d=(await Promise.all(["index.ts","index.js"].map(b=>(0,e.stat)((0,g.join)(a,b)).then(a=>a.isFile(),()=>!1)))).some(Boolean),f=c??{source:a,kind:"extension",path:a,nativePaths:[],piDeskRoot:null,version:null,description:null,enabled:!b.hasNativeEntries&&!d,error:null};f.version=b.version,f.description=b.description,f.error=b.error,b.hasNodeEntry&&f.enabled&&(f.piDeskRoot=a),o.set(a,f)}let t=await (0,i.n)(b,h,d);for(let a of o.values())await t(a.source,a.path,"package"===a.kind)&&(a.enabled=!1);return{sources:[...o.values()].sort((a,b)=>a.source.localeCompare(b.source)),errors:j}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},58417:(a,b,c)=>{c.d(b,{LD:()=>k,SZ:()=>f,_C:()=>j,mR:()=>e,w3:()=>g});var d=c(59473);let e=d.Yj().trim().min(1).max(128).regex(/^[a-zA-Z][a-zA-Z0-9._-]*$/),f=d.Yj().trim().url().max(2048).refine(a=>{let b=new URL(a);return["https:","http:"].includes(b.protocol)&&!b.username&&!b.password&&!b.search&&!b.hash},"插件源必须是 HTTP 或 HTTPS 仓库地址"),g=d.gM("mode",[d.Ik({mode:d.eu("auto")}).strict(),d.Ik({mode:d.eu("local")}).strict(),d.Ik({mode:d.eu("official")}).strict(),d.Ik({mode:d.eu("domestic")}).strict(),d.Ik({mode:d.eu("custom"),registry:f}).strict()]),h=d.Ik({description:d.Yj().trim().min(1).max(4e3).optional(),readme:d.Yj().trim().min(1).max(1024).optional()}),i=d.Ik({description:d.Yj().optional(),piDesk:d.Ik({i18n:d.g1(d.Yj().min(1).max(35),h).optional()}).passthrough().optional()}).passthrough();function j(a){let b=i.safeParse(a);if(!b.success)return null;let c=b.data.description?.trim();if(!c)return null;let d=Object.fromEntries(Object.entries(b.data.piDesk?.i18n??{}).slice(0,16).flatMap(([a,b])=>b.description?[[a,b.description]]:[]));return Object.keys(d).length?{default:c,translations:d}:c}function k(a){let b=/^npm:((?:@[^/]+\/)?[^@]+)(?:@.+)?$/.exec(a);return b?`npm:${b[1]}`:a.replaceAll("\\","/")}},58801:(a,b,c)=>{c.a(a,async(a,d)=>{try{let n;c.d(b,{G:()=>m,N:()=>k});var e=c(93736),f=c(73024),g=c(76760),h=a([e]);e=(h.then?(await h)():h)[0];let o=(0,g.join)(process.cwd(),"package.json"),{createRequire:p}=process.getBuiltinModule("module"),q=(0,e.createJiti)((0,g.join)(process.env.PI_DESK_PI_PACKAGE_DIR??process.cwd(),"package.json")),r=new Map,s=0;function i(a){let b=r.get(a);return b&&(r.delete(a),r.set(a,b)),b}function j(a,b){let c=r.get(a);if(c&&(r.delete(a),s-=c.bytes),!(b.bytes>0x2000000)){for(;r.size>=512||s+b.bytes>0x2000000;){let a=r.entries().next().value;r.delete(a[0]),s-=a[1].bytes}r.set(a,b),s+=b.bytes}}function k(){r.size>0&&console.info("[Pi Desk][PluginResources] 已清除插件代码缓存",{fileCount:r.size,bytes:s}),r.clear(),s=0}async function l(){let[a,b,c,d,f,h,k,l,m]=await Promise.all([q.import("@earendil-works/pi-coding-agent"),q.import("@earendil-works/pi-agent-core"),q.import("@earendil-works/pi-tui"),q.import("@earendil-works/pi-ai/compat"),q.import("@earendil-works/pi-ai/oauth"),q.import("@earendil-works/pi-ai/providers/all"),q.import("typebox"),q.import("typebox/compile"),q.import("typebox/value")]),n=(0,e.createJiti)(o,{moduleCache:!1,fsCache:!1,tryNative:!1,virtualModules:{"@earendil-works/pi-coding-agent":a,"@earendil-works/pi-agent-core":b,"@earendil-works/pi-tui":c,"@earendil-works/pi-ai/providers/all":h,"@earendil-works/pi-ai/compat":d,"@earendil-works/pi-ai/oauth":f,"@earendil-works/pi-ai":d,"@mariozechner/pi-coding-agent":a,"@mariozechner/pi-agent-core":b,"@mariozechner/pi-tui":c,"@mariozechner/pi-ai/providers/all":h,"@mariozechner/pi-ai/compat":d,"@mariozechner/pi-ai/oauth":f,"@mariozechner/pi-ai":d,typebox:k,"typebox/compile":l,"typebox/value":m,"@sinclair/typebox":k,"@sinclair/typebox/compile":l,"@sinclair/typebox/value":m}}),p=n.options.transform;return n.options.transform=a=>(function(a,b){if(!a.filename)return b(a);let c=(0,g.resolve)(a.filename),d=i(c),e=d?.source===a.source?d:void 0,f=!0===a.async,h=e?.transforms.get(f);if(h)return h;let k=a.source,l=b(a);return l.error||l.code.includes("__JITI_ERROR__")||j(c,{source:k,transforms:new Map(e?.transforms).set(f,l),bytes:(e?.bytes??Buffer.byteLength(k))+Buffer.byteLength(l.code)}),l})(a,p),n}async function m(a,b=(0,g.dirname)(a)){let c=await (n??=l()),d=p(o).cache,e=(0,g.resolve)(b);for(let a of Object.keys(d)){let b=(0,g.relative)(e,a);b.startsWith("..")||(0,g.isAbsolute)(b)||b.split(/[\\/]/).includes("node_modules")||delete d[a]}try{let b,d=(0,g.resolve)(a),e=c.evalModule((b=(0,f.readFileSync)(d,"utf8"),i(d)?.source!==b&&j(d,{source:b,transforms:new Map,bytes:Buffer.byteLength(b)}),b),{filename:d,async:!1});return{default:e?.default??e}}catch(a){if(k(),a instanceof Error&&/await is only valid|top.level await|ERR_REQUIRE_ASYNC_MODULE/i.test(a.message))throw Error("Pi Desk Node Entry 不支持模块顶层 await,请将异步初始化放入 async setup()",{cause:a});throw a}}d()}catch(a){d(a)}})},61035:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{J:()=>l});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=c(41904),j=a([h]);function k(){let a=Intl.DateTimeFormat().resolvedOptions();return i.J.parse({region:{locale:a.locale.toLowerCase().startsWith("zh")?"zh-CN":"en",timeZone:a.timeZone||"UTC"}})}h=(j.then?(await j)():j)[0];class m{constructor(a=(0,g.join)((0,h.getAgentDir)(),"pi-desk-settings.json"),b=k){this.path=a,this.defaults=b,this.snapshot=null,this.listeners=new Set,this.tail=Promise.resolve()}getSnapshot(){if(!this.snapshot)if((0,f.existsSync)(this.path))this.snapshot=i.J.parse(JSON.parse((0,f.readFileSync)(this.path,"utf8")));else{let a=i.J.parse(this.defaults());this.save(a),this.snapshot=a}return this.snapshot}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}update(a){let b=this.tail.then(()=>{let b=this.getSnapshot(),c=i.J.parse({region:{...b.region,...a}});if(JSON.stringify(b)!==JSON.stringify(c))for(let a of(this.save(c),this.snapshot=c,console.info("[Pi Desk][Settings] 共享地区设置已保存",c.region),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Settings] 设置订阅回调失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=b.catch(()=>void 0),b}save(a){(0,f.mkdirSync)((0,g.dirname)(this.path),{recursive:!0});let b=`${this.path}.${process.pid}.${(0,e.randomUUID)()}.tmp`;try{(0,f.writeFileSync)(b,`${JSON.stringify(a,null,2)}
|
|
27
28
|
`,"utf8"),(0,f.renameSync)(b,this.path)}finally{(0,f.existsSync)(b)&&(0,f.unlinkSync)(b)}}}function l(){return globalThis.__piDeskHostSettingsStore??=new m}d()}catch(a){d(a)}})},61518:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{O:()=>k});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=c(47511),j=a([h]);h=(j.then?(await j)():j)[0];class l{constructor(a=function(){let a=(0,h.getAgentDir)(),b=(0,g.join)(a,"pi-desk-capability-modes.json"),c=(0,g.join)(a,"pi-super-capability-modes.json");return!(0,f.existsSync)(b)&&(0,f.existsSync)(c)&&(0,f.copyFileSync)(c,b),b}()){this.path=a,this.modes=null,this.listeners=new Set,this.tail=Promise.resolve()}read(){if(null===this.modes){let a=(0,f.existsSync)(this.path)?JSON.parse((0,f.readFileSync)(this.path,"utf8")):{modes:{}};if(!a||"object"!=typeof a||!("modes"in a))throw Error("能力模式配置缺少 modes");this.modes=i.Qg.parse(a.modes)}return structuredClone(this.modes)}subscribe(a){return this.listeners.add(a),()=>{this.listeners.delete(a)}}replace(a){let b=i.Qg.parse(a),c=this.tail.then(()=>{(0,f.mkdirSync)((0,g.dirname)(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.${(0,e.randomUUID)()}.tmp`;try{(0,f.writeFileSync)(a,`${JSON.stringify({modes:b},null,2)}
|
|
28
|
-
`,"utf8"),(0,f.renameSync)(a,this.path)}finally{(0,f.existsSync)(a)&&(0,f.unlinkSync)(a)}for(let a of(this.modes=structuredClone(b),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Capabilities] 模式配置监听器失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=c.catch(()=>void 0),c}}function k(){return globalThis.__piDeskCapabilityModesStore??=new l}d()}catch(a){d(a)}})},63719:(a,b,c)=>{c.d(b,{CT:()=>r,Db:()=>k,JH:()=>t,NL:()=>j,Nu:()=>u,O_:()=>l,Ys:()=>h,_g:()=>o,eC:()=>p,ih:()=>z,jI:()=>y,lt:()=>g,p$:()=>q,rh:()=>n,uV:()=>e,w9:()=>i,xm:()=>f});var d=c(59473);let e=4096,f=5e3,g=100,h=200,i=1e3,j=5242880,k=0xa00000,l=5e7;function m(a,b){return""===a?b:!(a.length>e||a.startsWith("/")||a.includes("\\")||a.includes("\0")||/^[a-zA-Z]:/.test(a))&&a.split("/").every(a=>a.length>0&&"."!==a&&".."!==a)}let n=d.Yj().max(e).refine(a=>m(a,!0),"目录路径必须是规范相对路径"),o=d.Yj().min(1).max(e).refine(a=>m(a,!1),"文件路径必须是规范相对路径"),p=d.Yj().min(1).max(e).refine(a=>m(a,!1)||a.length>0&&a.length<=e&&!a.includes("\0")&&(a.startsWith("/")||a.startsWith("\\\\")||/^[a-zA-Z]:[\\/]/.test(a)),"预览路径必须是规范相对路径或绝对路径"),q=d.k5(["compressed","original"]),r=d.k5(["image/jpeg","image/png","image/webp","image/gif"]),s=d.Ik({name:d.Yj().min(1),type:d.k5(["directory","file"])}).strict(),t=d.Ik({entries:d.YO(s).max(f),truncated:d.zM()}).strict(),u=d.Ik({query:d.Yj().min(1).max(200).refine(a=>a.trim().length>0&&!/[\0\r\n]/.test(a),"搜索词必须是非空单行文本"),scope:d.k5(["all","files","content"]).default("all"),caseSensitive:d.zM().default(!1),wholeWord:d.zM().default(!1),regex:d.zM().default(!1)}).strict(),v=d.Ik({start:d.ai().int().nonnegative(),end:d.ai().int().nonnegative()}).strict().refine(a=>a.start<=a.end,"搜索命中区间无效"),w=d.Ik({path:o,ranges:d.YO(v)}).strict().refine(a=>a.ranges.every(b=>b.end<=a.path.length),"文件名命中区间越界"),x=d.Ik({path:o,line:d.ai().int().positive(),text:d.Yj().max(i),ranges:d.YO(v)}).strict().refine(a=>a.ranges.every(b=>b.end<=a.text.length),"正文命中区间越界"),y=d.Ik({fileMatches:d.YO(w).max(g),contentMatches:d.YO(x).max(h),truncated:d.zM()}).strict(),z=d.gM("kind",[d.Ik({kind:d.eu("text"),content:d.Yj(),size:d.ai().int().nonnegative().max(j)}).strict(),d.Ik({kind:d.eu("image"),mimeType:r,data:d.Yj().min(1),size:d.ai().int().positive().max(k)}).strict()])},67062:(a,b,c)=>{c.d(b,{P:()=>h,WR:()=>g,YB:()=>i,Z$:()=>j,l3:()=>k});var d=c(59473);let e=d.Yj().max(65536),f=d.Ik({id:d.Yj().uuid(),title:e,expiresAt:d.ai().int().nonnegative().nullable()}),g=d.gM("method",[f.extend({method:d.eu("confirm"),message:e}).strict(),f.extend({method:d.eu("select"),options:d.YO(e).max(200)}).strict(),f.extend({method:d.eu("input"),placeholder:e}).strict(),f.extend({method:d.eu("editor"),prefill:e}).strict()]),h=d.Ik({requests:d.YO(g).max(32),statuses:d.g1(d.Yj().max(128),e),widgets:d.g1(d.Yj().max(128),d.Ik({lines:d.YO(e).max(200),placement:d.k5(["aboveEditor","belowEditor"])}).strict())}).strict(),i=d.Ik({id:d.Yj().uuid(),value:d.KC([d.zM(),e,d.ch()])}).strict(),j=d.gM("type",[d.Ik({type:d.eu("snapshot"),snapshot:h}).strict(),d.Ik({type:d.eu("notify"),message:e,level:d.k5(["info","warning","error"])}).strict(),d.Ik({type:d.eu("editor_text"),text:e,mode:d.k5(["replace","paste"])}).strict()]);function k(){return{requests:[],statuses:{},widgets:{}}}},69503:(a,b,c)=>{c.d(b,{D:()=>h,Yj:()=>i,s6:()=>e,xI:()=>f});var d=c(59473);let e="project-preview",f=32,g=d.Ik({directories:d.YO(d.Yj().min(1).max(4096)).max(f),defaultDirectory:d.Yj().min(1).max(4096).nullable()}).strict();function h(a){let b=g.safeParse(a);return b.success?b.data:{directories:[],defaultDirectory:null}}function i(a){let b=a.replaceAll("\\","/").replace(/\/+$/,"")||"/";return/^[a-z]:/i.test(b)||b.startsWith("//")?b.toLowerCase():b}},69765:(a,b,c)=>{c.d(b,{U:()=>d});class d{constructor(a=()=>void 0){this.onDispatchError=a,this.deferred=[],this.restoreExtensionRuntime=null,this.draining=null,this.paused=!1,this.disposed=!1}get isBlocking(){return this.paused||null!==this.draining||this.deferred.length>0}pause(){this.disposed||(this.paused=!0)}defer(a,b){return!!this.isBlocking&&!this.disposed&&(this.deferred.push({source:a,dispatch:b}),!0)}resume(){if(this.disposed)return Promise.resolve();if(this.paused=!1,this.draining)return this.draining;let a=this.drain().finally(()=>{this.draining===a&&(this.draining=null),!this.paused&&this.deferred.length>0&&this.resume()});return this.draining=a,a}installExtensionRuntime(a){if(this.disposed)return;this.restoreExtensionRuntime?.();let b=a.sendMessage,c=a.sendUserMessage,d=(a,c)=>{this.defer("extension-message",()=>b(a,c))||b(a,c)},e=(a,b)=>{this.defer("extension-user-message",()=>c(a,b))||c(a,b)};a.sendMessage=d,a.sendUserMessage=e,this.restoreExtensionRuntime=()=>{a.sendMessage===d&&(a.sendMessage=b),a.sendUserMessage===e&&(a.sendUserMessage=c)}}discardPending(){this.deferred.length=0}dispose(){this.disposed||(this.disposed=!0,this.paused=!0,this.deferred.length=0,this.restoreExtensionRuntime?.(),this.restoreExtensionRuntime=null)}async drain(){for(;!this.paused&&!this.disposed;){let a=this.deferred.shift();if(!a)return;try{await a.dispatch()}catch(b){this.onDispatchError(a.source,b)}}}}},72498:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Wo:()=>v,Zd:()=>s,er:()=>w,gb:()=>t,ls:()=>r,vC:()=>x,wz:()=>u});var e=c(73024),f=c(76760),g=c(75430),h=c(61518),i=c(32980),j=c(87468),k=c(12727),l=c(65209),m=c(83401),n=c(46524),o=c(26143),p=a([g,h,i,l,o]);[g,h,i,l,o]=p.then?(await p)():p;class v extends Error{constructor(a){super(a),this.name="L4PiSessionBranchBlockedError"}}class w extends Error{constructor(){super("Pi session has no durable entry to clone"),this.name="L4PiSessionCloneEmptyError"}}function q(){return globalThis.__piDeskPiWorkSessionRuntimes||(globalThis.__piDeskPiWorkSessionRuntimes=new Map),globalThis.__piDeskPiWorkSessionRuntimes}class x{constructor(a,b){this.sessionManager=a,this.branchIndex=b,this.resources=new o.h,this.pendingBranchAppend=null,this.capabilityModeValue=null,this.capabilityTail=Promise.resolve(),this.disposed=!1,this.closePromise=null,this.indexedEntryCount=a.getEntries().length,this.branchIdValue=b.branchIdForHead(a.getLeafId()),this.chatWorker=this.createChatWorker(),this.unsubscribeCapabilities=(0,h.O)().subscribe(()=>{if(null===this.capabilityModeValue||this.disposed)return;let a=(0,h.O)().read(),b=Object.hasOwn(a,this.capabilityModeValue)?this.capabilityModeValue:null;this.setCapabilityMode(b).catch(a=>{console.error("[Pi Desk][Capabilities] 会话同步模式配置失败",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})})})}static create(a){let b=g.SessionManager.create(a),c=(0,m.l)(b);return(0,l.Ko)(a),x.fromManager(g.SessionManager.open(c,b.getSessionDir()))}static async open(a,b){let c=q().get(b);if(c){if(c.assertActive(),(0,f.resolve)(c.cwd)!==(0,f.resolve)(a))throw Error(`Pi session ${b} cwd does not match requested cwd`);return c}let d=await (0,l.vg)(a,b);if(!d)throw Error(`Pi session ${b} was not found in ${a}`);let e=x.fromManager(g.SessionManager.open(d));if((0,f.resolve)(e.cwd)!==(0,f.resolve)(a))throw Error(`Pi session ${b} cwd does not match persisted cwd`);return e}get cwd(){return this.sessionManager.getCwd()}get sessionId(){return this.sessionManager.getSessionId()}get branchId(){return this.branchIdValue}get isWorkerInitialized(){return this.assertActive(),this.chatWorker.isInitialized}readChatBackgroundTaskIds(){return this.assertActive(),this.chatWorker.getBackgroundTaskIds()}readPluginReloadBlockReason(){return this.assertActive(),this.chatWorker.readPluginReloadBlockReason()}readChatSnapshot(){return this.assertActive(),(0,k.xf)(this.sessionManager)}async readSessionTree(){this.assertActive();let a=this.sessionManager.getEntries().some(a=>"model_change"===a.type)?await g.ModelRuntime.create():void 0;return(0,n.cg)(this.sessionManager,a)}async readSessionTreeEntryDetail(a){this.assertActive();let b=this.sessionManager.getEntry(a)?.type==="model_change"?await g.ModelRuntime.create():void 0;return(0,n.j0)(this.sessionManager,a,b)}readChatImage(a,b){if(this.assertActive(),!Number.isSafeInteger(b)||b<0)throw Error("图片位置无效");if(!this.sessionManager.getBranch().some(b=>b.id===a))throw Error(`Pi session entry is not on the current branch: ${a}`);let c=this.sessionManager.getEntry(a);if(c?.type!=="message"||"user"!==c.message.role&&"toolResult"!==c.message.role)throw Error(`Pi session entry has no message images: ${a}`);let d=(0,k.Wl)(c.message.content,b);if(!d)throw Error(`Pi message image was not found: ${a}/${b}`);return d}subscribeChat(a){return this.assertActive(),this.chatWorker.subscribe(a)}get nativeUi(){return this.assertActive(),this.chatWorker.nativeUi}async readChatRuntime(){return this.assertActive(),this.chatWorker.getRuntime()}async readModelContext(){return this.assertActive(),this.chatWorker.readModelContext()}watchTaskDetail(a,b){return this.assertActive(),this.chatWorker.watchTaskDetail(a,b)}readTaskMessage(a,b){return this.assertActive(),this.chatWorker.readTaskMessage(a,b)}readTaskImage(a,b,c){return this.assertActive(),this.chatWorker.readTaskImage(a,b,c)}async interruptTask(a){this.assertActive(),await this.chatWorker.interruptTask(a)}async invokePluginMethod(a,b,c,d){if(this.assertActive(),a.sessionId!==this.sessionId||a.branchId!==this.branchId)throw Error("Pi session plugin source does not match the current runtime");return this.chatWorker.invokePluginMethod(b,c,d,a)}async listModels(){return this.assertActive(),this.chatWorker.listModels()}async listNativeCommands(){return this.assertActive(),this.chatWorker.listNativeCommands()}async executeNativeCommand(a,b){this.assertActive(),await this.chatWorker.executeNativeCommand(a,b)}async listNativeTools(a=!1){return a&&this.disposed?[]:(this.assertActive(),this.chatWorker.listNativeTools(a))}async executeDirectBash(a){return this.assertActive(),this.chatWorker.executeDirectBash(a)}async abortDirectBash(){this.assertActive(),await this.chatWorker.abortDirectBash()}async send(a){return this.assertActive(),this.chatWorker.send(a)}async interrupt(){this.assertActive(),await this.chatWorker.interrupt()}async compact(){this.assertActive(),await this.chatWorker.compact()}async reload(a){this.assertActive(),await this.chatWorker.reload(a)}async restoreQueuedMessages(){return this.assertActive(),this.chatWorker.restoreQueuedMessages()}async setTitle(a){this.assertActive(),await this.chatWorker.setTitle(a)}async setModel(a){this.assertActive(),await this.chatWorker.setModel(a)}setCapabilityMode(a){let b=this.capabilityTail.then(async()=>{if(this.assertActive(),null!==a&&!Object.hasOwn((0,h.O)().read(),a))throw Error("能力模式已不存在,请重新选择");this.capabilityModeValue=a,await this.chatWorker.applyCapabilityMode()});return this.capabilityTail=b.catch(()=>void 0),b}async dispose(){this.closePromise||(this.disposed=!0,this.unsubscribeCapabilities(),this.closePromise=this.chatWorker.dispose().finally(()=>this.resources.reset()),this.closePromise.then(()=>{q().get(this.sessionId)===this&&q().delete(this.sessionId)},a=>{console.warn("[Pi Desk][WorkSessionRuntime] 会话关闭未确认,保留实例占用直到重启",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})})),await this.waitForWorkerClose(this.closePromise,1500).catch(()=>void 0)}async waitForWorkerClose(a,b){let c;try{await Promise.race([a.then(()=>!0),new Promise(a=>{c=setTimeout(()=>a(!1),b)})])}finally{c&&clearTimeout(c)}}async branch(a){this.assertActive(),this.assertBranchable(),this.syncBranchIndex();let b=(0,n.eD)(this.sessionManager,a);if(!b.changed)return b;let c=this.sessionManager.getLeafId(),d=this.pendingBranchAppend;this.pendingBranchAppend=null;let e=!1;try{return(e=await this.chatWorker.navigateTree(b.selectedEntryId))?b:{...b,changed:!1,targetLeafEntryId:this.sessionManager.getLeafId(),editorText:null}}finally{this.syncBranchIndex();let a=this.sessionManager.getLeafId();e||a!==c?(this.pendingBranchAppend=this.branchIndex.predictAppend(a),this.branchIdValue=this.pendingBranchAppend.branchId):this.pendingBranchAppend=d}}createBranchedSession(a){let b,c,d,f,h;this.assertActive(),"at"===a.position&&this.assertBranchable(),this.syncBranchIndex();let i=this.sessionManager.getSessionFile();if(!i||!(0,e.existsSync)(i))throw Error(`Pi session ${this.sessionId} has no authoritative JSONL file`);if("before"===a.position){if(!a.entryId)throw new n.Ns("");let e=(0,n.u3)(this.sessionManager,a.entryId);b=e.selectedEntryId,c=e.targetLeafEntryId,d=e.editorText}else{if(!(b=a.entryId??this.sessionManager.getLeafId()??""))throw new w;if(!this.sessionManager.getEntry(b))throw new n.Ns(b);c=b,d=null}if(!(h=null===c?(f=g.SessionManager.create(this.cwd,this.sessionManager.getSessionDir())).newSession({parentSession:i}):(f=g.SessionManager.open(i,this.sessionManager.getSessionDir())).createBranchedSession(c)))throw Error(`Failed to create Pi session from entry: ${b}`);(0,m.l)(f),(0,l.Ko)(this.cwd);let j=x.fromManager(g.SessionManager.open(h,this.sessionManager.getSessionDir()));return console.info("[Pi Desk][PiWorkSessionRuntime] 已创建路径分支 Pi 会话",{sourceSessionId:this.sessionId,sourceBranchId:this.branchIndex.branchIdForEntry(b),selectedEntryId:b,targetLeafEntryId:c,position:a.position,sessionId:j.sessionId,branchId:j.branchId}),{runtime:j,editorText:d}}assertBranchable(){try{this.chatWorker.assertIdle()}catch(a){throw new v(a instanceof Error?a.message:"当前 Pi 会话不能切换分支")}}createChatWorker(){return new i.EG(this.cwd,this.sessionManager,a=>this.confirmAppendedEntry(a),{mode:()=>this.capabilityModeValue,rules:()=>null===this.capabilityModeValue?void 0:(0,h.O)().read()[this.capabilityModeValue]},this.resources)}confirmAppendedEntry(a){try{this.syncBranchIndex(),this.branchIndex.branchIdForEntry(a.id)}catch(b){throw console.error("[Pi Desk][PiWorkSessionRuntime] 增量同步 Pi 分支索引失败",{sessionId:this.sessionId,entryId:a.id,parentId:a.parentId,errorName:b instanceof Error?b.name:"UnknownError",errorMessage:b instanceof Error?b.message:String(b)}),b}}syncBranchIndex(){let a=this.sessionManager.getEntries();for(;this.indexedEntryCount<a.length;){let b,c=a[this.indexedEntryCount];this.pendingBranchAppend?(b=this.branchIndex.confirmAppend(this.pendingBranchAppend,c),this.pendingBranchAppend=null):b=this.branchIndex.appendEntry(c).branchId,this.indexedEntryCount+=1,this.sessionManager.getLeafId()===c.id&&(this.branchIdValue=b)}}static fromManager(a){let b=q().get(a.getSessionId());if(b)return b.assertActive(),b;let c=new x(a,new j.u(a.getEntries()));return q().set(c.sessionId,c),c}assertActive(){if(this.disposed)throw Error(`Pi session runtime has been disposed: ${this.sessionId}`)}}function r(a){let b=q().get(a);if(!b)throw Error(`Pi session runtime is not initialized: ${a}`);return b}async function s(){let a=await Promise.all([...q().values()].map(a=>a.listNativeTools(!0)));return[...new Map(a.flat().map(a=>[a.name,a])).values()]}async function t(a){await q().get(a)?.dispose()}async function u(){await Promise.all([...q().values()].map(a=>a.dispose()))}d()}catch(a){d(a)}})},73383:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{JF:()=>s,cI:()=>r,jd:()=>q});var e=c(76760),f=c(9753),g=c(99327),h=c(76452),i=a([g]);function j(a,b,c){if("string"!=typeof a)throw Error(`${b} must be a string`);let d=a.trim();if(!d||d.length>c)throw Error(`${b} must contain 1-${c} characters`);return d}function k(a,b,c){return null==a?null:j(a,b,c)}function l(a){if(void 0===a)return[];if(!Array.isArray(a)||a.length>12)throw Error("Task info must be an array with at most 12 items");return a.map((a,b)=>{if(!a||"object"!=typeof a||Array.isArray(a))throw Error(`Task info ${b} must be an object`);return{label:j(a.label,`Task info ${b} label`,64),value:j(a.value,`Task info ${b} value`,500)}})}function m(a,b){if("number"!=typeof a||!Number.isSafeInteger(a)||a<0)throw Error(`${b} must be a non-negative Unix millisecond timestamp`);return a}function n(a){if(!a||"object"!=typeof a)throw Error("Task snapshot is invalid");let b=function(a){switch(a){case"running":case"completed":case"failed":case"stopped":case"interrupted":return a;default:throw Error("Task status is invalid")}}(a.status),c=null===a.endedAt?null:m(a.endedAt,"Task endedAt");if("running"===b&&null!==c)throw Error("Running task requires endedAt=null");if("running"!==b&&null===c)throw Error("Terminal task requires endedAt");let d=function(a){if(null===a)return null;if(!a||"object"!=typeof a)throw Error("Task detailSource is invalid");if("text-file"===a.kind){let b=j(a.path,"Task text-file path",32768);if(!(0,e.isAbsolute)(b))throw Error("Task text-file path must be absolute");return{kind:"text-file",path:b}}if("pi-conversation"!==a.kind)throw Error("Task detailSource kind is invalid");if(void 0!==a.session){var b;if(!((b=a.session)&&"object"==typeof b&&"string"==typeof b.sessionId&&"function"==typeof b.sessionManager?.getBranch&&"function"==typeof b.agent?.subscribe))throw Error("Task AgentSession is invalid");return{kind:"pi-conversation",session:a.session}}let c=j(a.sessionFile,"Task sessionFile",32768);if(!(0,e.isAbsolute)(c))throw Error("Task sessionFile must be absolute");return{kind:"pi-conversation",sessionFile:c}}(a.detailSource);if("running"!==b&&d?.kind==="pi-conversation"&&d.session){let a=d.session.sessionFile;d=a?{kind:"pi-conversation",sessionFile:a}:null}return{record:{taskId:j(a.taskId,"Task id",200),taskKind:k(a.taskKind,"Task kind",100),taskType:k(a.taskType,"Task type",100),title:j(a.title,"Task title",200),info:l(a.info),status:b,activity:function(a){if(null==a)return null;if("string"!=typeof a)throw Error("Task activity must be a string");let b=a.trim();return b?b.length<=300?b:`${b.slice(0,299)}…`:null}(a.activity),startedAt:m(a.startedAt,"Task startedAt"),endedAt:c,detailSource:d,interrupt:"running"===b&&"function"==typeof a.interrupt?a.interrupt:null},infoLoader:function(a){if(null==a)return null;if("function"!=typeof a)throw Error("Task infoLoader must be a function");return a}(a.infoLoader)}}function o(a){let{detailSource:b,interrupt:c,...d}=a;return{...d,info:d.info.map(a=>({...a}))}}function p(a){let b=[],c=[];for(let d of a)"running"===d.status?b.push(d):c.push(d);return c.sort((a,b)=>(b.endedAt??0)-(a.endedAt??0)||b.startedAt-a.startedAt),[...b,...c.slice(0,100)].sort((a,b)=>b.startedAt-a.startedAt)}g=(i.then?(await i)():i)[0];class q{constructor(a,b){this.options=b,this.records=new Map,this.infoRuntimes=new Map,this.toolRuntimeOwners=new Map,this.disposed=!1,this.detailPool=new g.Il(a=>{let b=this.records.get(a);return b?{taskId:b.taskId,status:b.status,detailSource:b.detailSource,canInterrupt:"running"===b.status&&null!==b.interrupt}:null}),this.unsubscribe=a.on(f.O0,a=>{if(!this.disposed)try{this.apply(a)}catch(a){this.options.onInvalidReport(a)}})}summaries(){return p(this.records.values()).map(o)}activeTaskIds(){return[...this.records.values()].filter(a=>"running"===a.status).map(a=>a.taskId).sort()}record(a){return this.records.get(a)??null}async watchDetail(a,b){return await this.loadInfo(a),this.detailPool.watch(a,b)}readMessage(a,b){return this.detailPool.readMessage(a,b)}readImage(a,b,c){return this.detailPool.readImage(a,b,c)}async interrupt(a){let b=this.records.get(a);if(!b)throw new r(a);if("running"!==b.status||!b.interrupt)throw new s(a);await b.interrupt()}dispose(){if(!this.disposed){for(let a of(this.disposed=!0,this.unsubscribe(),this.detailPool.dispose(),this.toolRuntimeOwners.values()))a.lease.release();this.toolRuntimeOwners.clear(),this.records.clear(),this.infoRuntimes.clear()}}setToolRuntime(a,b){let c=b?.kind==="pi-conversation"?b.session:void 0,d=this.toolRuntimeOwners.get(a);if(d?.session!==c){if(d?.lease.release(),!c)return void this.toolRuntimeOwners.delete(a);this.toolRuntimeOwners.set(a,{session:c,lease:(0,h.s)(c)})}}releaseToolRuntime(a){this.toolRuntimeOwners.get(a)?.lease.release(),this.toolRuntimeOwners.delete(a)}setInfoLoader(a,b){let c=this.infoRuntimes.get(a);if(!b||c?.loader!==b){if(!b)return void this.infoRuntimes.delete(a);this.infoRuntimes.set(a,{loader:b,promise:null})}}async loadInfo(a){let b=this.infoRuntimes.get(a);if(!b)return;if(b.promise)return b.promise;let c=(async()=>{try{var c;if(!this.records.has(a))return;let d=l(await b.loader());if(this.infoRuntimes.get(a)!==b)return;this.infoRuntimes.delete(a);let e=this.records.get(a);if(!e||(c=e.info,c.length===d.length&&c.every((a,b)=>{let c=d[b];return a.label===c?.label&&a.value===c.value})))return;e.info=d,this.options.onChanged(this.summaries(),this.activeTaskIds())}catch(b){console.warn("[Pi Desk][TaskRuntime] 按需加载任务 info 失败",{taskId:a,errorName:b instanceof Error?b.name:"UnknownError"})}finally{this.infoRuntimes.get(a)===b&&(b.promise=null)}})();b.promise=c,await c}apply(a){if(!a||"object"!=typeof a)throw Error("Task report is invalid");let b=!1,c=new Set;if("upsert"===a.type){if(!Array.isArray(a.tasks))throw Error("Task upsert requires tasks");let d=a.tasks.map(n),e=new Set;for(let a of d){if(e.has(a.record.taskId))throw Error(`Task report contains duplicate id: ${a.record.taskId}`);e.add(a.record.taskId)}for(let a of d)this.records.set(a.record.taskId,a.record),this.setToolRuntime(a.record.taskId,a.record.detailSource),this.setInfoLoader(a.record.taskId,a.infoLoader),c.add(a.record.taskId),b=!0}else if("remove"===a.type){if(!Array.isArray(a.taskIds))throw Error("Task remove requires taskIds");for(let d of a.taskIds){let a=j(d,"Task id",200),e=this.records.delete(a);this.infoRuntimes.delete(a),this.releaseToolRuntime(a),e&&c.add(a),b=e||b}}else throw Error("Task report type is invalid");if(b){for(let a of this.trimTerminalHistory())c.add(a);for(let a of c)this.detailPool.taskChanged(a);this.options.onChanged(this.summaries(),this.activeTaskIds())}}trimTerminalHistory(){let a=[],b=new Set(p(this.records.values()).map(a=>a.taskId));for(let[c,d]of this.records)"running"===d.status||b.has(c)||(this.records.delete(c),this.infoRuntimes.delete(c),this.releaseToolRuntime(c),a.push(c));return a}}class r extends Error{constructor(a){super(`Task was not found: ${a}`),this.name="L4PiTaskNotFoundError"}}class s extends Error{constructor(a){super(`Task is not interruptible: ${a}`),this.name="L4PiTaskNotInterruptibleError"}}d()}catch(a){d(a)}})},73589:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{n:()=>n});var e=c(51455),f=c(48161),g=c(76760),h=c(58417),i=c(46107),j=a([i]);async function k(a){let b=await (0,e.realpath)(a).catch(()=>(0,g.resolve)(a));return"win32"===process.platform?b.toLowerCase():b}function l(a,b){return/^(npm:|git:|https?:|ssh:|git@)/.test(a)?null:a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a)}function m(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function n(a,b,c){let d=new Set((0,i.to)(a).disabled.map(h.LD)),f=new Set;for(let b of d){let c=l(b,a);c&&f.add(await k(c))}for(let c of b.listConfiguredPackages()){if("user"!==c.scope||!c.installedPath)continue;let b=l(c.source,a),e=b&&f.has(await k(b));(d.has((0,h.LD)(c.source))||e)&&f.add(await k(c.installedPath))}if(f.size>0){let d=(0,g.join)(a,"extensions"),h=await (0,e.readdir)(d,{withFileTypes:!0}).catch(a=>{if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return[];throw a}),i=[...b.listConfiguredPackages().filter(a=>"user"===a.scope).flatMap(a=>a.installedPath??[]),...h.filter(a=>!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink())).map(a=>(0,g.join)(d,a.name)),...(c.getGlobalSettings().extensions??[]).filter(a=>!/^[!+-]|[?*{}]/.test(a)).flatMap(b=>l(b,a)??[])],j=[];for(let a of i)await (0,e.stat)(a).then(a=>a.isDirectory(),()=>!1)&&j.push(await k(a));for(let a of(j.sort((a,b)=>b.length-a.length),[...f])){if(!await (0,e.stat)(a).then(a=>a.isFile(),()=>!1))continue;let b=j.find(b=>m(b,a));b&&f.add(b)}}let j=new Map;return async(a,b,c)=>{if(c&&d.has((0,h.LD)(a)))return!0;if(!b||b.startsWith("builtin:")||0===f.size)return!1;let e=j.get(b);e||(e=k(b),j.set(b,e));let g=await e;return[...f].some(a=>m(a,g))}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},75613:(a,b,c)=>{c.d(b,{i:()=>n});var d=c(73024),e=c(51455),f=c(76760),g=c(56752);let h=/\u001b(?:\[[0-?]*[ -/]*[@-~]|\][^\u0007]*(?:\u0007|\u001b\\))/g;function i(a,b,c){for(let d of[...a])try{d(b)}catch(a){console.error("[Pi Desk][TextLogRuntime] 日志监听器执行失败",{path:c,errorName:a instanceof Error?a.name:"UnknownError"})}}async function j(a){let b;try{b=await (0,e.stat)(a)}catch(a){if("ENOENT"===a.code)return{text:"",truncated:!1};throw a}if(!b.isFile())throw Error(`Text log source is not a file: ${a}`);let c=Math.max(0,b.size-131072),d=b.size-c,f=await (0,e.open)(a,"r");try{let a=Buffer.alloc(d);d>0&&await f.read(a,0,d,c);let b=a.toString("utf8").replace(h,""),e=c>0;if(c>0){let a=b.indexOf("\n");a>=0&&(b=b.slice(a+1))}let g=b.split("\n");return g.length>1e3&&(b=g.slice(g.length-1e3).join("\n"),e=!0),{text:b,truncated:e}}finally{await f.close()}}class k{constructor(a,b){this.path=a,this.listeners=new Set,this.watcher=null,this.interval=null,this.refreshTimer=null,this.refreshPromise=null,this.disposed=!1,this.current=b}static async create(a){let b=new k(a,await j(a));return b.startWatching(),b}snapshot(){return{...this.current}}subscribe(a){if(this.disposed)throw Error("Text log runtime has been disposed");return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.watcher?.close(),this.interval&&clearInterval(this.interval),this.refreshTimer&&clearTimeout(this.refreshTimer),this.watcher=null,this.interval=null,this.refreshTimer=null,this.listeners.clear())}startWatching(){try{this.watcher=(0,d.watch)(this.path,()=>this.scheduleRefresh()),this.watcher.on("error",()=>this.scheduleRefresh())}catch{this.watcher=null}this.interval=setInterval(()=>this.scheduleRefresh(),500)}scheduleRefresh(){this.disposed||this.refreshTimer||(this.refreshTimer=setTimeout(()=>{this.refreshTimer=null,this.refresh()},40))}refresh(){return this.disposed?Promise.resolve():(this.refreshPromise||(this.refreshPromise=(async()=>{try{let a=await j(this.path);if(this.disposed||a.text===this.current.text&&a.truncated===this.current.truncated)return;let b=this.current;this.current=a;let c=a.text.startsWith(b.text)?a.text.slice(b.text.length):"";c&&a.truncated===b.truncated?i(this.listeners,{type:"text_append",text:c},this.path):i(this.listeners,{type:"snapshot",snapshot:{...a}},this.path)}catch(a){console.warn("[Pi Desk][TextLogRuntime] 刷新日志失败",{path:this.path,errorName:a instanceof Error?a.name:"UnknownError"}),i(this.listeners,{type:"unavailable"},this.path)}})().finally(()=>{this.refreshPromise=null})),this.refreshPromise)}}class l{async observe(a,b){if(this.disposed)throw Error("Text log pool has been disposed");let c=function(a){let b=a.trim();if(!b||b.length>32768||!(0,f.isAbsolute)(b))throw Error("Text log path must be an absolute path");return(0,f.resolve)(b)}(a),d=(0,g.b)(c),e=this.sharedByPath.get(d);if(!e){let a=this.pendingByPath.get(d);a||(a=k.create(c).then(a=>{if(this.disposed)throw a.dispose(),Error("Text log pool was disposed during initialization");let b={runtime:a,references:0};return this.sharedByPath.set(d,b),b}).finally(()=>{this.pendingByPath.delete(d)}),this.pendingByPath.set(d,a)),e=await a}e.references+=1;let h=e.runtime.subscribe(b),i=!1;return{snapshot:e.runtime.snapshot(),readSnapshot:()=>e.runtime.snapshot(),release:()=>{i||(i=!0,h(),e.references-=1,e.references>0||(this.sharedByPath.get(d)===e&&this.sharedByPath.delete(d),e.runtime.dispose()))}}}dispose(){if(!this.disposed){for(let a of(this.disposed=!0,this.sharedByPath.values()))a.runtime.dispose();this.sharedByPath.clear(),this.pendingByPath.clear()}}constructor(){this.sharedByPath=new Map,this.pendingByPath=new Map,this.disposed=!1}}let m=new l;function n(){return m}},76452:(a,b,c)=>{c.d(b,{s:()=>i});var d=c(77598),e=c(12727);let f=new WeakMap;function g(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}class h{constructor(a){this.session=a,this.listeners=new Set,this.toolsById=new Map,this.disposed=!1,this.unsubscribeAgent=a.agent.subscribe(a=>this.captureAgentEvent(a)),this.unsubscribeSession=a.subscribe(a=>this.captureSessionEvent(a));const b=a.sessionManager.getBranch(),c=a.agent.state.pendingToolCalls;for(const a of function(a){let b=new Map;for(let c of a)if("message"===c.type)if("assistant"===c.message.role)for(let a of(0,e.zz)(c.message.content))b.set(a.id,a);else"toolResult"===c.message.role&&b.delete(c.message.toolCallId);return[...b.values()]}(b))c.has(a.id)&&this.upsertTool(a.id,a.name,a.input);const d=a.agent.state.streamingMessage;d&&this.syncStreamingTools(d,!1)}get size(){return this.toolsById.size}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}activeMessages(){return[...this.toolsById.values()].map(a=>({tempId:a.tempId,message:this.toolMessage(a)}))}tempId(a){return this.toolsById.get(a)?.tempId??null}syncStreamingTools(a,b=!0){if("assistant"===a.role)for(let c of(0,e.zz)(a.content)){let{tool:a,created:d,changed:e}=this.upsertTool(c.id,c.name,c.input);b&&(d?this.publish({type:"message_start",tempId:a.tempId,message:this.toolMessage(a)}):e&&this.publishToolUpdate(a))}}projectLiveResult(a,b){let c=this.toolsById.get(b);return(0,e.zK)(a,b,c?.display,c?.input)}remove(a){this.toolsById.delete(a)}discardAll(){for(let a of this.toolsById.values())this.publish({type:"message_discard",tempId:a.tempId});this.toolsById.clear()}dispose(){this.disposed||(this.disposed=!0,this.unsubscribeAgent(),this.unsubscribeSession(),this.listeners.clear(),this.toolsById.clear())}captureAgentEvent(a){if(!this.disposed&&(!("parentToolCallId"in a)||void 0===a.parentToolCallId))switch(a.type){case"tool_execution_start":this.startTool(a.toolCallId,a.toolName,a.args);return;case"tool_execution_update":this.updateTool(a.toolCallId,a.toolName,a.args,a.partialResult);return;case"tool_execution_end":this.endTool(a.toolCallId,a.toolName,a.result,a.isError);return;case"turn_end":this.discardAll();return;default:return}}captureSessionEvent(a){("agent_end"===a.type&&a.willRetry||"agent_settled"===a.type)&&queueMicrotask(()=>{this.disposed||this.discardAll()})}upsertTool(a,b,c){let f=c&&"object"==typeof c&&!Array.isArray(c)?{...c}:{},g=this.toolsById.get(a);if(g){var h;let a=(0,e.zG)(b,f,g.displayCache),c=g.name!==b||(h=g.display,h.reasoning!==a.reasoning||h.inputPreview!==a.inputPreview||h.activity!==a.activity);return g.name=b,g.input=f,g.display=a,{tool:g,created:!1,changed:c}}let i={},j={tempId:(0,d.randomUUID)(),toolCallId:a,name:b,display:(0,e.zG)(b,f,i),displayCache:i,input:f,partialResult:null,result:null,status:"running",startedAtMs:null,durationMs:null};return this.toolsById.set(a,j),{tool:j,created:!0,changed:!0}}startTool(a,b,c){let{tool:d,created:e,changed:f}=this.upsertTool(a,b,c),g="bash"===b&&null===d.startedAtMs;d.status="running",g&&(d.startedAtMs=Date.now()),e?this.publish({type:"message_start",tempId:d.tempId,message:this.toolMessage(d)}):(f||g)&&this.publishToolUpdate(d)}updateTool(a,b,c,d){this.startTool(a,b,c);let e=this.toolsById.get(a);e&&(e.partialResult=d,e.status="running",this.publishToolUpdate(e))}endTool(a,b,c,d){this.toolsById.has(a)||this.startTool(a,b,{});let e=this.toolsById.get(a);e&&("bash"===e.name&&null!==e.startedAtMs&&(e.durationMs=Math.max(0,Date.now()-e.startedAtMs),function(a,b){if(!a||"object"!=typeof a||Array.isArray(a))return;let c=a.details&&"object"==typeof a.details&&!Array.isArray(a.details)?a.details:{};a.details={...c,durationMs:b}}(c,e.durationMs)),e.result=c,e.status=d?"error":"completed",this.publishToolUpdate(e))}publishToolUpdate(a){this.publish({type:"message_update",tempId:a.tempId,message:this.toolMessage(a)})}toolMessage(a){let b;return{type:"tool",name:a.name,reasoning:a.display.reasoning,inputPreview:a.display.inputPreview,activity:a.display.activity,status:a.status,usage:null,output:"",startedAtMs:a.startedAtMs,durationMs:a.durationMs,declaration:{message:{kind:"tool",toolName:a.name,toolCallId:a.toolCallId,arguments:(b=g(a.input))&&"object"==typeof b&&!Array.isArray(b)?b:{},partialResult:g(a.partialResult),result:g(a.result),isError:"error"===a.status},raw:{toolCallId:a.toolCallId,toolName:a.name,args:a.input,partialResult:a.partialResult,result:a.result}}}}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][AgentToolRuntime] 事件监听器执行失败",{sessionId:this.session.sessionId,eventType:a.type,errorName:b instanceof Error?b.name:"UnknownError"})}}}function i(a){let b=f.get(a);b||(b={runtime:new h(a),references:0},f.set(a,b)),b.references+=1;let c=!1;return{runtime:b.runtime,release:()=>{c||(c=!0,b.references-=1,b.references>0||(f.delete(a),b.runtime.dispose()))}}}},77662:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{p:()=>r});var e=c(76760),f=c(75430),g=c(9753),h=c(59473),i=c(69503),j=c(73383),k=c(40333),l=a([f,j]);[f,j]=l.then?(await l)():l;let m=h.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),n=h.g1(h.Yj(),h.Pq()),o=h.g1(h.Yj().min(1),h.KC([n,h.ch()])),p=h.Ik({pluginName:m,event:m,data:n}).strict(),q=h.Ik({directory:h.Yj().min(1).max(4096).refine(a=>(0,e.isAbsolute)(a)&&!a.includes("\0")),default:h.zM().optional()}).strict();class r{constructor(a){this.options=a,this.controller=(0,f.createEventBus)(),this.slots=new Map,this.methods=new Map,this.unsubscribe=()=>void 0,this.unsubscribePush=()=>void 0,this.unsubscribePreviewDirectory=()=>void 0,this.disposed=!1,this.eventBus={emit:(a,b)=>{if(!this.disposed){if(a===g.Sl)return void this.applyMethodEvent(b);this.controller.emit(a,b)}},on:(a,b)=>this.disposed?()=>void 0:this.controller.on(a,b)},this.bindChannels()}createTaskRuntime(){let a=this.options;return new j.jd(this.controller,{onChanged:(b,c)=>{this.applyTaskSummaries(b),a.onTasksChanged(c),a.onChanged()},onInvalidReport:b=>a.onInvalidUpdate(b)})}bindChannels(){let a=this.options;this.taskRuntime=this.createTaskRuntime(),this.unsubscribe=this.controller.on(g.k0,b=>{if(this.disposed)return;let c=o.safeParse(b);if(!c.success)return void a.onInvalidUpdate(c.error);try{this.apply(c.data)&&a.onChanged()}catch(b){a.onInvalidUpdate(b)}}),this.unsubscribePreviewDirectory=this.controller.on(g.Nx,b=>{if(this.disposed)return;let c=q.safeParse(b);if(!c.success)return void a.onInvalidUpdate(c.error);try{this.applyPreviewDirectory(c.data)&&a.onChanged()}catch(b){a.onInvalidUpdate(b)}}),this.unsubscribePush=this.controller.on(g.Nb,b=>{if(this.disposed)return;let c=p.safeParse(b);c.success?Buffer.byteLength(JSON.stringify(c.data.data),"utf8")>65536?a.onInvalidUpdate(Error("Session Plugin Push data exceeds 64KB")):a.onPush(structuredClone(c.data)):a.onInvalidUpdate(c.error)})}activeTaskIds(){return this.taskRuntime.activeTaskIds()}taskRecord(a){return this.taskRuntime.record(a)}watchTaskDetail(a,b){return this.taskRuntime.watchDetail(a,b)}readTaskMessage(a,b){return this.taskRuntime.readMessage(a,b)}readTaskImage(a,b,c){return this.taskRuntime.readImage(a,b,c)}interruptTask(a){return this.taskRuntime.interrupt(a)}snapshot(){return Object.fromEntries([...this.slots.entries()].sort(([a],[b])=>a.localeCompare(b)).map(([a,b])=>[a,structuredClone(b.value)]))}async invokeMethod(a,b,c,d,e){if(this.disposed)throw Error("Pi session plugin runtime has been disposed");let f=(0,k.FX)(a),g=(0,k.QK)(b),h=this.methods.get((0,k.$m)(f,g));if(!h)throw new k.Tk(f,g);let i=await h.execute((0,k.nJ)(c,"input"),{source:d,extensionContext:e});return(0,k.nJ)(i,"output")}resetBranch(){this.disposed||(this.taskRuntime.dispose(),this.slots.clear(),this.taskRuntime=this.createTaskRuntime(),this.options.onTasksChanged([]),this.options.onChanged())}reset(){this.disposed||(this.unsubscribe(),this.unsubscribePush(),this.unsubscribePreviewDirectory(),this.taskRuntime.dispose(),this.controller.clear(),this.methods.clear(),this.slots.clear(),this.bindChannels(),this.options.onTasksChanged([]),this.options.onChanged())}dispose(){this.disposed||(this.disposed=!0,this.unsubscribe(),this.unsubscribePush(),this.unsubscribePreviewDirectory(),this.taskRuntime.dispose(),this.controller.clear(),this.methods.clear(),this.slots.clear())}applyMethodEvent(a){if(!a||"object"!=typeof a||Array.isArray(a))throw Error("Session plugin method event is invalid");let b=a.registration;if("register"!==a.type&&"unregister"!==a.type||!b||"object"!=typeof b||"string"!=typeof b.pluginName||"string"!=typeof b.method||"function"!=typeof b.execute)throw Error("Session plugin method registration is invalid");let c=(0,k.FX)(b.pluginName),d=(0,k.QK)(b.method),e=(0,k.$m)(c,d);if("register"===a.type){if(this.methods.has(e))throw new k.qs(c,d);this.methods.set(e,b);return}this.methods.get(e)===b&&this.methods.delete(e)}applyTaskSummaries(a){if(0===a.length)return void this.slots.delete("task-center");let b={tasks:a.map(a=>({...a,info:a.info.map(a=>({...a}))}))};this.slots.set("task-center",{serialized:JSON.stringify(b),value:b})}applyPreviewDirectory(a){let b=(0,e.resolve)(a.directory),c=(0,i.Yj)(b),d=this.slots.get(i.s6),f=(0,i.D)(d?.value),g=f.directories.find(a=>(0,i.Yj)(a)===c);if(!g&&f.directories.length>=i.xI)throw Error(`会话预览目录数量已达上限 ${i.xI}`);let h=g??b,j={directories:g?f.directories:[...f.directories,h],defaultDirectory:!0===a.default?h:f.defaultDirectory},k=JSON.stringify(j);return d?.serialized!==k&&(this.slots.set(i.s6,{serialized:k,value:j}),!0)}apply(a){if(Object.hasOwn(a,"task-center"))throw Error("task-center plugin slot is reserved by the Task Runtime");if(Object.hasOwn(a,i.s6))throw Error("project-preview 插件槽由会话预览目录登记管理");let b=!1;for(let[c,d]of Object.entries(a)){if(null===d){b=this.slots.delete(c)||b;continue}let a=JSON.stringify(d);this.slots.get(c)?.serialized!==a&&(this.slots.set(c,{serialized:a,value:d}),b=!0)}return b}}d()}catch(a){d(a)}})},77844:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{lr:()=>m,mu:()=>l,ni:()=>i,qc:()=>j,ti:()=>k});var e=c(73024),f=c(75430),g=c(54174),h=a([f]);f=(h.then?(await h)():h)[0];let m=0x1f00000;class n extends Error{constructor(a){super(a),this.name="L4PiChatInputError"}}function i(a){if(!a.text.trim()&&0===a.images.length)throw new n("请输入文字或添加图片");return{text:a.text,images:a.images.map(a=>({...a})),imageBytes:function(a){if(a.length>10)throw new n("单次最多发送 10 张图片");let b=0;for(let c of a){let a=(0,g.f1)(c);if(a.bytes.length>0xa00000)throw new n("单张图片压缩后不能超过 10MB");b+=a.bytes.length}if(b>0x1400000)throw new n("单次发送图片总量不能超过 20MB");return b}(a.images)}}function j(a,b,c,d){let h=function(a,b){var c,d;let e;if(!a.startsWith("/"))return a;let f=a.match(/^\/([^\s]+)(?:\s+([\s\S]*))?$/);if(!f)return a;let g=b.find(a=>a.name===f[1]);return g?(c=g.content,e=(d=function(a){let b=[],c="",d=null;for(let e of a){if(d){e===d?d=null:c+=e;continue}if('"'===e||"'"===e){d=e;continue}if(/\s/.test(e)){c&&b.push(c),c="";continue}c+=e}return c&&b.push(c),b}(f[2]??"")).join(" "),c.replace(/\$\{(\d+|ARGUMENTS|@):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g,(a,b,c,f,g,h)=>{if("string"==typeof b)return("@"===b||"ARGUMENTS"===b?e:d[Number.parseInt(b,10)-1])||c;if("string"==typeof f){let a=Math.max(0,Number.parseInt(f,10)-1);return"string"==typeof g?d.slice(a,a+Number.parseInt(g,10)).join(" "):d.slice(a).join(" ")}return"ARGUMENTS"===h||"@"===h?e:d[Number.parseInt(h,10)-1]??""})):a}(function(a,b){if(!a.startsWith("/skill:"))return a;let c=a.indexOf(" "),d=-1===c?a.slice(7):a.slice(7,c),g=-1===c?"":a.slice(c+1).trim(),h=b.find(a=>a.name===d);if(!h)return a;try{let a=(0,f.stripFrontmatter)((0,e.readFileSync)(h.filePath,"utf8")).trim(),b=`<skill name="${h.name}" location="${h.filePath}">
|
|
29
|
+
`,"utf8"),(0,f.renameSync)(a,this.path)}finally{(0,f.existsSync)(a)&&(0,f.unlinkSync)(a)}for(let a of(this.modes=structuredClone(b),this.listeners))try{a()}catch(a){console.error("[Pi Desk][Capabilities] 模式配置监听器失败",{message:a instanceof Error?a.message:String(a)})}});return this.tail=c.catch(()=>void 0),c}}function k(){return globalThis.__piDeskCapabilityModesStore??=new l}d()}catch(a){d(a)}})},63719:(a,b,c)=>{c.d(b,{CT:()=>r,Db:()=>k,JH:()=>t,NL:()=>j,Nu:()=>u,O_:()=>l,Ys:()=>h,_g:()=>o,eC:()=>p,ih:()=>z,jI:()=>y,lt:()=>g,p$:()=>q,rh:()=>n,uV:()=>e,w9:()=>i,xm:()=>f});var d=c(59473);let e=4096,f=5e3,g=100,h=200,i=1e3,j=5242880,k=0xa00000,l=5e7;function m(a,b){return""===a?b:!(a.length>e||a.startsWith("/")||a.includes("\\")||a.includes("\0")||/^[a-zA-Z]:/.test(a))&&a.split("/").every(a=>a.length>0&&"."!==a&&".."!==a)}let n=d.Yj().max(e).refine(a=>m(a,!0),"目录路径必须是规范相对路径"),o=d.Yj().min(1).max(e).refine(a=>m(a,!1),"文件路径必须是规范相对路径"),p=d.Yj().min(1).max(e).refine(a=>m(a,!1)||a.length>0&&a.length<=e&&!a.includes("\0")&&(a.startsWith("/")||a.startsWith("\\\\")||/^[a-zA-Z]:[\\/]/.test(a)),"预览路径必须是规范相对路径或绝对路径"),q=d.k5(["compressed","original"]),r=d.k5(["image/jpeg","image/png","image/webp","image/gif"]),s=d.Ik({name:d.Yj().min(1),type:d.k5(["directory","file"])}).strict(),t=d.Ik({entries:d.YO(s).max(f),truncated:d.zM()}).strict(),u=d.Ik({query:d.Yj().min(1).max(200).refine(a=>a.trim().length>0&&!/[\0\r\n]/.test(a),"搜索词必须是非空单行文本"),scope:d.k5(["all","files","content"]).default("all"),caseSensitive:d.zM().default(!1),wholeWord:d.zM().default(!1),regex:d.zM().default(!1)}).strict(),v=d.Ik({start:d.ai().int().nonnegative(),end:d.ai().int().nonnegative()}).strict().refine(a=>a.start<=a.end,"搜索命中区间无效"),w=d.Ik({path:o,ranges:d.YO(v)}).strict().refine(a=>a.ranges.every(b=>b.end<=a.path.length),"文件名命中区间越界"),x=d.Ik({path:o,line:d.ai().int().positive(),text:d.Yj().max(i),ranges:d.YO(v)}).strict().refine(a=>a.ranges.every(b=>b.end<=a.text.length),"正文命中区间越界"),y=d.Ik({fileMatches:d.YO(w).max(g),contentMatches:d.YO(x).max(h),truncated:d.zM()}).strict(),z=d.gM("kind",[d.Ik({kind:d.eu("text"),content:d.Yj(),size:d.ai().int().nonnegative().max(j)}).strict(),d.Ik({kind:d.eu("image"),mimeType:r,data:d.Yj().min(1),size:d.ai().int().positive().max(k)}).strict()])},67062:(a,b,c)=>{c.d(b,{P:()=>h,WR:()=>g,YB:()=>i,Z$:()=>j,l3:()=>k});var d=c(59473);let e=d.Yj().max(65536),f=d.Ik({id:d.Yj().uuid(),title:e,expiresAt:d.ai().int().nonnegative().nullable()}),g=d.gM("method",[f.extend({method:d.eu("confirm"),message:e}).strict(),f.extend({method:d.eu("select"),options:d.YO(e).max(200)}).strict(),f.extend({method:d.eu("input"),placeholder:e}).strict(),f.extend({method:d.eu("editor"),prefill:e}).strict()]),h=d.Ik({requests:d.YO(g).max(32),statuses:d.g1(d.Yj().max(128),e),widgets:d.g1(d.Yj().max(128),d.Ik({lines:d.YO(e).max(200),placement:d.k5(["aboveEditor","belowEditor"])}).strict())}).strict(),i=d.Ik({id:d.Yj().uuid(),value:d.KC([d.zM(),e,d.ch()])}).strict(),j=d.gM("type",[d.Ik({type:d.eu("snapshot"),snapshot:h}).strict(),d.Ik({type:d.eu("notify"),message:e,level:d.k5(["info","warning","error"])}).strict(),d.Ik({type:d.eu("editor_text"),text:e,mode:d.k5(["replace","paste"])}).strict()]);function k(){return{requests:[],statuses:{},widgets:{}}}},69503:(a,b,c)=>{c.d(b,{D:()=>h,Yj:()=>i,s6:()=>e,xI:()=>f});var d=c(59473);let e="project-preview",f=32,g=d.Ik({directories:d.YO(d.Yj().min(1).max(4096)).max(f),defaultDirectory:d.Yj().min(1).max(4096).nullable()}).strict();function h(a){let b=g.safeParse(a);return b.success?b.data:{directories:[],defaultDirectory:null}}function i(a){let b=a.replaceAll("\\","/").replace(/\/+$/,"")||"/";return/^[a-z]:/i.test(b)||b.startsWith("//")?b.toLowerCase():b}},69765:(a,b,c)=>{c.d(b,{U:()=>d});class d{constructor(a=()=>void 0){this.onDispatchError=a,this.deferred=[],this.restoreExtensionRuntime=null,this.draining=null,this.paused=!1,this.disposed=!1}get isBlocking(){return this.paused||null!==this.draining||this.deferred.length>0}pause(){this.disposed||(this.paused=!0)}defer(a,b){return!!this.isBlocking&&!this.disposed&&(this.deferred.push({source:a,dispatch:b}),!0)}resume(){if(this.disposed)return Promise.resolve();if(this.paused=!1,this.draining)return this.draining;let a=this.drain().finally(()=>{this.draining===a&&(this.draining=null),!this.paused&&this.deferred.length>0&&this.resume()});return this.draining=a,a}installExtensionRuntime(a){if(this.disposed)return;this.restoreExtensionRuntime?.();let b=a.sendMessage,c=a.sendUserMessage,d=(a,c)=>{this.defer("extension-message",()=>b(a,c))||b(a,c)},e=(a,b)=>{this.defer("extension-user-message",()=>c(a,b))||c(a,b)};a.sendMessage=d,a.sendUserMessage=e,this.restoreExtensionRuntime=()=>{a.sendMessage===d&&(a.sendMessage=b),a.sendUserMessage===e&&(a.sendUserMessage=c)}}discardPending(){this.deferred.length=0}dispose(){this.disposed||(this.disposed=!0,this.paused=!0,this.deferred.length=0,this.restoreExtensionRuntime?.(),this.restoreExtensionRuntime=null)}async drain(){for(;!this.paused&&!this.disposed;){let a=this.deferred.shift();if(!a)return;try{await a.dispatch()}catch(b){this.onDispatchError(a.source,b)}}}}},72498:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Wo:()=>v,Zd:()=>s,er:()=>w,gb:()=>t,ls:()=>r,vC:()=>x,wz:()=>u});var e=c(73024),f=c(76760),g=c(75430),h=c(61518),i=c(32980),j=c(87468),k=c(12727),l=c(65209),m=c(5782),n=c(46524),o=c(26143),p=a([g,h,i,l,o]);[g,h,i,l,o]=p.then?(await p)():p;class v extends Error{constructor(a){super(a),this.name="L4PiSessionBranchBlockedError"}}class w extends Error{constructor(){super("Pi session has no durable entry to clone"),this.name="L4PiSessionCloneEmptyError"}}function q(){return globalThis.__piDeskPiWorkSessionRuntimes||(globalThis.__piDeskPiWorkSessionRuntimes=new Map),globalThis.__piDeskPiWorkSessionRuntimes}class x{constructor(a,b){this.sessionManager=a,this.branchIndex=b,this.resources=new o.h,this.pendingBranchAppend=null,this.capabilityModeValue=null,this.capabilityTail=Promise.resolve(),this.disposed=!1,this.closePromise=null,this.indexedEntryCount=a.getEntries().length,this.branchIdValue=b.branchIdForHead(a.getLeafId()),this.chatWorker=this.createChatWorker(),this.unsubscribeCapabilities=(0,h.O)().subscribe(()=>{if(null===this.capabilityModeValue||this.disposed)return;let a=(0,h.O)().read(),b=Object.hasOwn(a,this.capabilityModeValue)?this.capabilityModeValue:null;this.setCapabilityMode(b).catch(a=>{console.error("[Pi Desk][Capabilities] 会话同步模式配置失败",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})})})}static create(a){let b=g.SessionManager.create(a),c=(0,m.l)(b);return(0,l.Ko)(a),x.fromManager(g.SessionManager.open(c,b.getSessionDir()))}static async open(a,b){let c=q().get(b);if(c){if(c.assertActive(),(0,f.resolve)(c.cwd)!==(0,f.resolve)(a))throw Error(`Pi session ${b} cwd does not match requested cwd`);return c}let d=await (0,l.vg)(a,b);if(!d)throw Error(`Pi session ${b} was not found in ${a}`);let e=x.fromManager(g.SessionManager.open(d));if((0,f.resolve)(e.cwd)!==(0,f.resolve)(a))throw Error(`Pi session ${b} cwd does not match persisted cwd`);return e}get cwd(){return this.sessionManager.getCwd()}get sessionId(){return this.sessionManager.getSessionId()}get branchId(){return this.branchIdValue}get isWorkerInitialized(){return this.assertActive(),this.chatWorker.isInitialized}readChatBackgroundTaskIds(){return this.assertActive(),this.chatWorker.getBackgroundTaskIds()}readPluginReloadBlockReason(){return this.assertActive(),this.chatWorker.readPluginReloadBlockReason()}readChatSnapshot(){return this.assertActive(),(0,k.xf)(this.sessionManager)}async readSessionTree(){this.assertActive();let a=this.sessionManager.getEntries().some(a=>"model_change"===a.type)?await g.ModelRuntime.create():void 0;return(0,n.cg)(this.sessionManager,a)}async readSessionTreeEntryDetail(a){this.assertActive();let b=this.sessionManager.getEntry(a)?.type==="model_change"?await g.ModelRuntime.create():void 0;return(0,n.j0)(this.sessionManager,a,b)}readChatImage(a,b){if(this.assertActive(),!Number.isSafeInteger(b)||b<0)throw Error("图片位置无效");if(!this.sessionManager.getBranch().some(b=>b.id===a))throw Error(`Pi session entry is not on the current branch: ${a}`);let c=this.sessionManager.getEntry(a);if(c?.type!=="message"||"user"!==c.message.role&&"toolResult"!==c.message.role)throw Error(`Pi session entry has no message images: ${a}`);let d=(0,k.Wl)(c.message.content,b);if(!d)throw Error(`Pi message image was not found: ${a}/${b}`);return d}subscribeChat(a){return this.assertActive(),this.chatWorker.subscribe(a)}get nativeUi(){return this.assertActive(),this.chatWorker.nativeUi}async readChatRuntime(){return this.assertActive(),this.chatWorker.getRuntime()}async readModelContext(){return this.assertActive(),this.chatWorker.readModelContext()}watchTaskDetail(a,b){return this.assertActive(),this.chatWorker.watchTaskDetail(a,b)}readTaskMessage(a,b){return this.assertActive(),this.chatWorker.readTaskMessage(a,b)}readTaskImage(a,b,c){return this.assertActive(),this.chatWorker.readTaskImage(a,b,c)}async interruptTask(a){this.assertActive(),await this.chatWorker.interruptTask(a)}async invokePluginMethod(a,b,c,d){if(this.assertActive(),a.sessionId!==this.sessionId||a.branchId!==this.branchId)throw Error("Pi session plugin source does not match the current runtime");return this.chatWorker.invokePluginMethod(b,c,d,a)}async listModels(){return this.assertActive(),this.chatWorker.listModels()}async listNativeCommands(){return this.assertActive(),this.chatWorker.listNativeCommands()}async executeNativeCommand(a,b){this.assertActive(),await this.chatWorker.executeNativeCommand(a,b)}async listNativeTools(a=!1){return a&&this.disposed?[]:(this.assertActive(),this.chatWorker.listNativeTools(a))}async executeDirectBash(a){return this.assertActive(),this.chatWorker.executeDirectBash(a)}async abortDirectBash(){this.assertActive(),await this.chatWorker.abortDirectBash()}async send(a){return this.assertActive(),this.chatWorker.send(a)}async interrupt(){this.assertActive(),await this.chatWorker.interrupt()}async compact(){this.assertActive(),await this.chatWorker.compact()}async reload(a){this.assertActive(),await this.chatWorker.reload(a)}async restoreQueuedMessages(){return this.assertActive(),this.chatWorker.restoreQueuedMessages()}async setTitle(a){this.assertActive(),await this.chatWorker.setTitle(a)}async setModel(a){this.assertActive(),await this.chatWorker.setModel(a)}setCapabilityMode(a){let b=this.capabilityTail.then(async()=>{if(this.assertActive(),null!==a&&!Object.hasOwn((0,h.O)().read(),a))throw Error("能力模式已不存在,请重新选择");this.capabilityModeValue=a,await this.chatWorker.applyCapabilityMode()});return this.capabilityTail=b.catch(()=>void 0),b}async dispose(){this.closePromise||(this.disposed=!0,this.unsubscribeCapabilities(),this.closePromise=this.chatWorker.dispose().finally(()=>this.resources.reset()),this.closePromise.then(()=>{q().get(this.sessionId)===this&&q().delete(this.sessionId)},a=>{console.warn("[Pi Desk][WorkSessionRuntime] 会话关闭未确认,保留实例占用直到重启",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})})),await this.waitForWorkerClose(this.closePromise,1500).catch(()=>void 0)}async waitForWorkerClose(a,b){let c;try{await Promise.race([a.then(()=>!0),new Promise(a=>{c=setTimeout(()=>a(!1),b)})])}finally{c&&clearTimeout(c)}}async branch(a){this.assertActive(),this.assertBranchable(),this.syncBranchIndex();let b=(0,n.eD)(this.sessionManager,a);if(!b.changed)return b;let c=this.sessionManager.getLeafId(),d=this.pendingBranchAppend;this.pendingBranchAppend=null;let e=!1;try{return(e=await this.chatWorker.navigateTree(b.selectedEntryId))?b:{...b,changed:!1,targetLeafEntryId:this.sessionManager.getLeafId(),editorText:null}}finally{this.syncBranchIndex();let a=this.sessionManager.getLeafId();e||a!==c?(this.pendingBranchAppend=this.branchIndex.predictAppend(a),this.branchIdValue=this.pendingBranchAppend.branchId):this.pendingBranchAppend=d}}createBranchedSession(a){let b,c,d,f,h;this.assertActive(),"at"===a.position&&this.assertBranchable(),this.syncBranchIndex();let i=this.sessionManager.getSessionFile();if(!i||!(0,e.existsSync)(i))throw Error(`Pi session ${this.sessionId} has no authoritative JSONL file`);if("before"===a.position){if(!a.entryId)throw new n.Ns("");let e=(0,n.u3)(this.sessionManager,a.entryId);b=e.selectedEntryId,c=e.targetLeafEntryId,d=e.editorText}else{if(!(b=a.entryId??this.sessionManager.getLeafId()??""))throw new w;if(!this.sessionManager.getEntry(b))throw new n.Ns(b);c=b,d=null}if(!(h=null===c?(f=g.SessionManager.create(this.cwd,this.sessionManager.getSessionDir())).newSession({parentSession:i}):(f=g.SessionManager.open(i,this.sessionManager.getSessionDir())).createBranchedSession(c)))throw Error(`Failed to create Pi session from entry: ${b}`);(0,m.l)(f),(0,l.Ko)(this.cwd);let j=x.fromManager(g.SessionManager.open(h,this.sessionManager.getSessionDir()));return console.info("[Pi Desk][PiWorkSessionRuntime] 已创建路径分支 Pi 会话",{sourceSessionId:this.sessionId,sourceBranchId:this.branchIndex.branchIdForEntry(b),selectedEntryId:b,targetLeafEntryId:c,position:a.position,sessionId:j.sessionId,branchId:j.branchId}),{runtime:j,editorText:d}}assertBranchable(){try{this.chatWorker.assertIdle()}catch(a){throw new v(a instanceof Error?a.message:"当前 Pi 会话不能切换分支")}}createChatWorker(){return new i.EG(this.cwd,this.sessionManager,a=>this.confirmAppendedEntry(a),{mode:()=>this.capabilityModeValue,rules:()=>null===this.capabilityModeValue?void 0:(0,h.O)().read()[this.capabilityModeValue]},this.resources)}confirmAppendedEntry(a){try{this.syncBranchIndex(),this.branchIndex.branchIdForEntry(a.id)}catch(b){throw console.error("[Pi Desk][PiWorkSessionRuntime] 增量同步 Pi 分支索引失败",{sessionId:this.sessionId,entryId:a.id,parentId:a.parentId,errorName:b instanceof Error?b.name:"UnknownError",errorMessage:b instanceof Error?b.message:String(b)}),b}}syncBranchIndex(){let a=this.sessionManager.getEntries();for(;this.indexedEntryCount<a.length;){let b,c=a[this.indexedEntryCount];this.pendingBranchAppend?(b=this.branchIndex.confirmAppend(this.pendingBranchAppend,c),this.pendingBranchAppend=null):b=this.branchIndex.appendEntry(c).branchId,this.indexedEntryCount+=1,this.sessionManager.getLeafId()===c.id&&(this.branchIdValue=b)}}static fromManager(a){let b=q().get(a.getSessionId());if(b)return b.assertActive(),b;let c=new x(a,new j.u(a.getEntries()));return q().set(c.sessionId,c),c}assertActive(){if(this.disposed)throw Error(`Pi session runtime has been disposed: ${this.sessionId}`)}}function r(a){let b=q().get(a);if(!b)throw Error(`Pi session runtime is not initialized: ${a}`);return b}async function s(){let a=await Promise.all([...q().values()].map(a=>a.listNativeTools(!0)));return[...new Map(a.flat().map(a=>[a.name,a])).values()]}async function t(a){await q().get(a)?.dispose()}async function u(){await Promise.all([...q().values()].map(a=>a.dispose()))}d()}catch(a){d(a)}})},73383:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{JF:()=>s,cI:()=>r,jd:()=>q});var e=c(76760),f=c(9753),g=c(99327),h=c(76452),i=a([g]);function j(a,b,c){if("string"!=typeof a)throw Error(`${b} must be a string`);let d=a.trim();if(!d||d.length>c)throw Error(`${b} must contain 1-${c} characters`);return d}function k(a,b,c){return null==a?null:j(a,b,c)}function l(a){if(void 0===a)return[];if(!Array.isArray(a)||a.length>12)throw Error("Task info must be an array with at most 12 items");return a.map((a,b)=>{if(!a||"object"!=typeof a||Array.isArray(a))throw Error(`Task info ${b} must be an object`);return{label:j(a.label,`Task info ${b} label`,64),value:j(a.value,`Task info ${b} value`,500)}})}function m(a,b){if("number"!=typeof a||!Number.isSafeInteger(a)||a<0)throw Error(`${b} must be a non-negative Unix millisecond timestamp`);return a}function n(a){if(!a||"object"!=typeof a)throw Error("Task snapshot is invalid");let b=function(a){switch(a){case"running":case"completed":case"failed":case"stopped":case"interrupted":return a;default:throw Error("Task status is invalid")}}(a.status),c=null===a.endedAt?null:m(a.endedAt,"Task endedAt");if("running"===b&&null!==c)throw Error("Running task requires endedAt=null");if("running"!==b&&null===c)throw Error("Terminal task requires endedAt");let d=function(a){if(null===a)return null;if(!a||"object"!=typeof a)throw Error("Task detailSource is invalid");if("text-file"===a.kind){let b=j(a.path,"Task text-file path",32768);if(!(0,e.isAbsolute)(b))throw Error("Task text-file path must be absolute");return{kind:"text-file",path:b}}if("pi-conversation"!==a.kind)throw Error("Task detailSource kind is invalid");if(void 0!==a.session){var b;if(!((b=a.session)&&"object"==typeof b&&"string"==typeof b.sessionId&&"function"==typeof b.sessionManager?.getBranch&&"function"==typeof b.agent?.subscribe))throw Error("Task AgentSession is invalid");return{kind:"pi-conversation",session:a.session}}let c=j(a.sessionFile,"Task sessionFile",32768);if(!(0,e.isAbsolute)(c))throw Error("Task sessionFile must be absolute");return{kind:"pi-conversation",sessionFile:c}}(a.detailSource);if("running"!==b&&d?.kind==="pi-conversation"&&d.session){let a=d.session.sessionFile;d=a?{kind:"pi-conversation",sessionFile:a}:null}return{record:{taskId:j(a.taskId,"Task id",200),taskKind:k(a.taskKind,"Task kind",100),taskType:k(a.taskType,"Task type",100),title:j(a.title,"Task title",200),info:l(a.info),status:b,activity:function(a){if(null==a)return null;if("string"!=typeof a)throw Error("Task activity must be a string");let b=a.trim();return b?b.length<=300?b:`${b.slice(0,299)}…`:null}(a.activity),startedAt:m(a.startedAt,"Task startedAt"),endedAt:c,detailSource:d,interrupt:"running"===b&&"function"==typeof a.interrupt?a.interrupt:null},infoLoader:function(a){if(null==a)return null;if("function"!=typeof a)throw Error("Task infoLoader must be a function");return a}(a.infoLoader)}}function o(a){let{detailSource:b,interrupt:c,...d}=a;return{...d,info:d.info.map(a=>({...a}))}}function p(a){let b=[],c=[];for(let d of a)"running"===d.status?b.push(d):c.push(d);return c.sort((a,b)=>(b.endedAt??0)-(a.endedAt??0)||b.startedAt-a.startedAt),[...b,...c.slice(0,100)].sort((a,b)=>b.startedAt-a.startedAt)}g=(i.then?(await i)():i)[0];class q{constructor(a,b){this.options=b,this.records=new Map,this.infoRuntimes=new Map,this.toolRuntimeOwners=new Map,this.disposed=!1,this.detailPool=new g.Il(a=>{let b=this.records.get(a);return b?{taskId:b.taskId,status:b.status,detailSource:b.detailSource,canInterrupt:"running"===b.status&&null!==b.interrupt}:null}),this.unsubscribe=a.on(f.O0,a=>{if(!this.disposed)try{this.apply(a)}catch(a){this.options.onInvalidReport(a)}})}summaries(){return p(this.records.values()).map(o)}activeTaskIds(){return[...this.records.values()].filter(a=>"running"===a.status).map(a=>a.taskId).sort()}record(a){return this.records.get(a)??null}async watchDetail(a,b){return await this.loadInfo(a),this.detailPool.watch(a,b)}readMessage(a,b){return this.detailPool.readMessage(a,b)}readImage(a,b,c){return this.detailPool.readImage(a,b,c)}async interrupt(a){let b=this.records.get(a);if(!b)throw new r(a);if("running"!==b.status||!b.interrupt)throw new s(a);await b.interrupt()}dispose(){if(!this.disposed){for(let a of(this.disposed=!0,this.unsubscribe(),this.detailPool.dispose(),this.toolRuntimeOwners.values()))a.lease.release();this.toolRuntimeOwners.clear(),this.records.clear(),this.infoRuntimes.clear()}}setToolRuntime(a,b){let c=b?.kind==="pi-conversation"?b.session:void 0,d=this.toolRuntimeOwners.get(a);if(d?.session!==c){if(d?.lease.release(),!c)return void this.toolRuntimeOwners.delete(a);this.toolRuntimeOwners.set(a,{session:c,lease:(0,h.s)(c)})}}releaseToolRuntime(a){this.toolRuntimeOwners.get(a)?.lease.release(),this.toolRuntimeOwners.delete(a)}setInfoLoader(a,b){let c=this.infoRuntimes.get(a);if(!b||c?.loader!==b){if(!b)return void this.infoRuntimes.delete(a);this.infoRuntimes.set(a,{loader:b,promise:null})}}async loadInfo(a){let b=this.infoRuntimes.get(a);if(!b)return;if(b.promise)return b.promise;let c=(async()=>{try{var c;if(!this.records.has(a))return;let d=l(await b.loader());if(this.infoRuntimes.get(a)!==b)return;this.infoRuntimes.delete(a);let e=this.records.get(a);if(!e||(c=e.info,c.length===d.length&&c.every((a,b)=>{let c=d[b];return a.label===c?.label&&a.value===c.value})))return;e.info=d,this.options.onChanged(this.summaries(),this.activeTaskIds())}catch(b){console.warn("[Pi Desk][TaskRuntime] 按需加载任务 info 失败",{taskId:a,errorName:b instanceof Error?b.name:"UnknownError"})}finally{this.infoRuntimes.get(a)===b&&(b.promise=null)}})();b.promise=c,await c}apply(a){if(!a||"object"!=typeof a)throw Error("Task report is invalid");let b=!1,c=new Set;if("upsert"===a.type){if(!Array.isArray(a.tasks))throw Error("Task upsert requires tasks");let d=a.tasks.map(n),e=new Set;for(let a of d){if(e.has(a.record.taskId))throw Error(`Task report contains duplicate id: ${a.record.taskId}`);e.add(a.record.taskId)}for(let a of d)this.records.set(a.record.taskId,a.record),this.setToolRuntime(a.record.taskId,a.record.detailSource),this.setInfoLoader(a.record.taskId,a.infoLoader),c.add(a.record.taskId),b=!0}else if("remove"===a.type){if(!Array.isArray(a.taskIds))throw Error("Task remove requires taskIds");for(let d of a.taskIds){let a=j(d,"Task id",200),e=this.records.delete(a);this.infoRuntimes.delete(a),this.releaseToolRuntime(a),e&&c.add(a),b=e||b}}else throw Error("Task report type is invalid");if(b){for(let a of this.trimTerminalHistory())c.add(a);for(let a of c)this.detailPool.taskChanged(a);this.options.onChanged(this.summaries(),this.activeTaskIds())}}trimTerminalHistory(){let a=[],b=new Set(p(this.records.values()).map(a=>a.taskId));for(let[c,d]of this.records)"running"===d.status||b.has(c)||(this.records.delete(c),this.infoRuntimes.delete(c),this.releaseToolRuntime(c),a.push(c));return a}}class r extends Error{constructor(a){super(`Task was not found: ${a}`),this.name="L4PiTaskNotFoundError"}}class s extends Error{constructor(a){super(`Task is not interruptible: ${a}`),this.name="L4PiTaskNotInterruptibleError"}}d()}catch(a){d(a)}})},73589:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{n:()=>n});var e=c(51455),f=c(48161),g=c(76760),h=c(58417),i=c(46107),j=a([i]);async function k(a){let b=await (0,e.realpath)(a).catch(()=>(0,g.resolve)(a));return"win32"===process.platform?b.toLowerCase():b}function l(a,b){return/^(npm:|git:|https?:|ssh:|git@)/.test(a)?null:a.startsWith("~/")?(0,g.join)((0,f.homedir)(),a.slice(2)):(0,g.resolve)(b,a)}function m(a,b){let c=(0,g.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,g.isAbsolute)(c)}async function n(a,b,c){let d=new Set((0,i.to)(a).disabled.map(h.LD)),f=new Set;for(let b of d){let c=l(b,a);c&&f.add(await k(c))}for(let c of b.listConfiguredPackages()){if("user"!==c.scope||!c.installedPath)continue;let b=l(c.source,a),e=b&&f.has(await k(b));(d.has((0,h.LD)(c.source))||e)&&f.add(await k(c.installedPath))}if(f.size>0){let d=(0,g.join)(a,"extensions"),h=await (0,e.readdir)(d,{withFileTypes:!0}).catch(a=>{if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return[];throw a}),i=[...b.listConfiguredPackages().filter(a=>"user"===a.scope).flatMap(a=>a.installedPath??[]),...h.filter(a=>!a.name.startsWith(".")&&"node_modules"!==a.name&&(a.isDirectory()||a.isSymbolicLink())).map(a=>(0,g.join)(d,a.name)),...(c.getGlobalSettings().extensions??[]).filter(a=>!/^[!+-]|[?*{}]/.test(a)).flatMap(b=>l(b,a)??[])],j=[];for(let a of i)await (0,e.stat)(a).then(a=>a.isDirectory(),()=>!1)&&j.push(await k(a));for(let a of(j.sort((a,b)=>b.length-a.length),[...f])){if(!await (0,e.stat)(a).then(a=>a.isFile(),()=>!1))continue;let b=j.find(b=>m(b,a));b&&f.add(b)}}let j=new Map;return async(a,b,c)=>{if(c&&d.has((0,h.LD)(a)))return!0;if(!b||b.startsWith("builtin:")||0===f.size)return!1;let e=j.get(b);e||(e=k(b),j.set(b,e));let g=await e;return[...f].some(a=>m(a,g))}}i=(j.then?(await j)():j)[0],d()}catch(a){d(a)}})},75613:(a,b,c)=>{c.d(b,{i:()=>n});var d=c(73024),e=c(51455),f=c(76760),g=c(56752);let h=/\u001b(?:\[[0-?]*[ -/]*[@-~]|\][^\u0007]*(?:\u0007|\u001b\\))/g;function i(a,b,c){for(let d of[...a])try{d(b)}catch(a){console.error("[Pi Desk][TextLogRuntime] 日志监听器执行失败",{path:c,errorName:a instanceof Error?a.name:"UnknownError"})}}async function j(a){let b;try{b=await (0,e.stat)(a)}catch(a){if("ENOENT"===a.code)return{text:"",truncated:!1};throw a}if(!b.isFile())throw Error(`Text log source is not a file: ${a}`);let c=Math.max(0,b.size-131072),d=b.size-c,f=await (0,e.open)(a,"r");try{let a=Buffer.alloc(d);d>0&&await f.read(a,0,d,c);let b=a.toString("utf8").replace(h,""),e=c>0;if(c>0){let a=b.indexOf("\n");a>=0&&(b=b.slice(a+1))}let g=b.split("\n");return g.length>1e3&&(b=g.slice(g.length-1e3).join("\n"),e=!0),{text:b,truncated:e}}finally{await f.close()}}class k{constructor(a,b){this.path=a,this.listeners=new Set,this.watcher=null,this.interval=null,this.refreshTimer=null,this.refreshPromise=null,this.disposed=!1,this.current=b}static async create(a){let b=new k(a,await j(a));return b.startWatching(),b}snapshot(){return{...this.current}}subscribe(a){if(this.disposed)throw Error("Text log runtime has been disposed");return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.watcher?.close(),this.interval&&clearInterval(this.interval),this.refreshTimer&&clearTimeout(this.refreshTimer),this.watcher=null,this.interval=null,this.refreshTimer=null,this.listeners.clear())}startWatching(){try{this.watcher=(0,d.watch)(this.path,()=>this.scheduleRefresh()),this.watcher.on("error",()=>this.scheduleRefresh())}catch{this.watcher=null}this.interval=setInterval(()=>this.scheduleRefresh(),500)}scheduleRefresh(){this.disposed||this.refreshTimer||(this.refreshTimer=setTimeout(()=>{this.refreshTimer=null,this.refresh()},40))}refresh(){return this.disposed?Promise.resolve():(this.refreshPromise||(this.refreshPromise=(async()=>{try{let a=await j(this.path);if(this.disposed||a.text===this.current.text&&a.truncated===this.current.truncated)return;let b=this.current;this.current=a;let c=a.text.startsWith(b.text)?a.text.slice(b.text.length):"";c&&a.truncated===b.truncated?i(this.listeners,{type:"text_append",text:c},this.path):i(this.listeners,{type:"snapshot",snapshot:{...a}},this.path)}catch(a){console.warn("[Pi Desk][TextLogRuntime] 刷新日志失败",{path:this.path,errorName:a instanceof Error?a.name:"UnknownError"}),i(this.listeners,{type:"unavailable"},this.path)}})().finally(()=>{this.refreshPromise=null})),this.refreshPromise)}}class l{async observe(a,b){if(this.disposed)throw Error("Text log pool has been disposed");let c=function(a){let b=a.trim();if(!b||b.length>32768||!(0,f.isAbsolute)(b))throw Error("Text log path must be an absolute path");return(0,f.resolve)(b)}(a),d=(0,g.b)(c),e=this.sharedByPath.get(d);if(!e){let a=this.pendingByPath.get(d);a||(a=k.create(c).then(a=>{if(this.disposed)throw a.dispose(),Error("Text log pool was disposed during initialization");let b={runtime:a,references:0};return this.sharedByPath.set(d,b),b}).finally(()=>{this.pendingByPath.delete(d)}),this.pendingByPath.set(d,a)),e=await a}e.references+=1;let h=e.runtime.subscribe(b),i=!1;return{snapshot:e.runtime.snapshot(),readSnapshot:()=>e.runtime.snapshot(),release:()=>{i||(i=!0,h(),e.references-=1,e.references>0||(this.sharedByPath.get(d)===e&&this.sharedByPath.delete(d),e.runtime.dispose()))}}}dispose(){if(!this.disposed){for(let a of(this.disposed=!0,this.sharedByPath.values()))a.runtime.dispose();this.sharedByPath.clear(),this.pendingByPath.clear()}}constructor(){this.sharedByPath=new Map,this.pendingByPath=new Map,this.disposed=!1}}let m=new l;function n(){return m}},76452:(a,b,c)=>{c.d(b,{s:()=>i});var d=c(77598),e=c(12727);let f=new WeakMap;function g(a){try{let b=JSON.stringify(a);return void 0===b?null:JSON.parse(b)}catch{return null}}class h{constructor(a){this.session=a,this.listeners=new Set,this.toolsById=new Map,this.disposed=!1,this.unsubscribeAgent=a.agent.subscribe(a=>this.captureAgentEvent(a)),this.unsubscribeSession=a.subscribe(a=>this.captureSessionEvent(a));const b=a.sessionManager.getBranch(),c=a.agent.state.pendingToolCalls;for(const a of function(a){let b=new Map;for(let c of a)if("message"===c.type)if("assistant"===c.message.role)for(let a of(0,e.zz)(c.message.content))b.set(a.id,a);else"toolResult"===c.message.role&&b.delete(c.message.toolCallId);return[...b.values()]}(b))c.has(a.id)&&this.upsertTool(a.id,a.name,a.input);const d=a.agent.state.streamingMessage;d&&this.syncStreamingTools(d,!1)}get size(){return this.toolsById.size}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}activeMessages(){return[...this.toolsById.values()].map(a=>({tempId:a.tempId,message:this.toolMessage(a)}))}tempId(a){return this.toolsById.get(a)?.tempId??null}syncStreamingTools(a,b=!0){if("assistant"===a.role)for(let c of(0,e.zz)(a.content)){let{tool:a,created:d,changed:e}=this.upsertTool(c.id,c.name,c.input);b&&(d?this.publish({type:"message_start",tempId:a.tempId,message:this.toolMessage(a)}):e&&this.publishToolUpdate(a))}}projectLiveResult(a,b){let c=this.toolsById.get(b);return(0,e.zK)(a,b,c?.display,c?.input)}remove(a){this.toolsById.delete(a)}discardAll(){for(let a of this.toolsById.values())this.publish({type:"message_discard",tempId:a.tempId});this.toolsById.clear()}dispose(){this.disposed||(this.disposed=!0,this.unsubscribeAgent(),this.unsubscribeSession(),this.listeners.clear(),this.toolsById.clear())}captureAgentEvent(a){if(!this.disposed&&(!("parentToolCallId"in a)||void 0===a.parentToolCallId))switch(a.type){case"tool_execution_start":this.startTool(a.toolCallId,a.toolName,a.args);return;case"tool_execution_update":this.updateTool(a.toolCallId,a.toolName,a.args,a.partialResult);return;case"tool_execution_end":this.endTool(a.toolCallId,a.toolName,a.result,a.isError);return;case"turn_end":this.discardAll();return;default:return}}captureSessionEvent(a){("agent_end"===a.type&&a.willRetry||"agent_settled"===a.type)&&queueMicrotask(()=>{this.disposed||this.discardAll()})}upsertTool(a,b,c){let f=c&&"object"==typeof c&&!Array.isArray(c)?{...c}:{},g=this.toolsById.get(a);if(g){var h;let a=(0,e.zG)(b,f,g.displayCache),c=g.name!==b||(h=g.display,h.reasoning!==a.reasoning||h.inputPreview!==a.inputPreview||h.activity!==a.activity);return g.name=b,g.input=f,g.display=a,{tool:g,created:!1,changed:c}}let i={},j={tempId:(0,d.randomUUID)(),toolCallId:a,name:b,display:(0,e.zG)(b,f,i),displayCache:i,input:f,partialResult:null,result:null,status:"running",startedAtMs:null,durationMs:null};return this.toolsById.set(a,j),{tool:j,created:!0,changed:!0}}startTool(a,b,c){let{tool:d,created:e,changed:f}=this.upsertTool(a,b,c),g="bash"===b&&null===d.startedAtMs;d.status="running",g&&(d.startedAtMs=Date.now()),e?this.publish({type:"message_start",tempId:d.tempId,message:this.toolMessage(d)}):(f||g)&&this.publishToolUpdate(d)}updateTool(a,b,c,d){this.startTool(a,b,c);let e=this.toolsById.get(a);e&&(e.partialResult=d,e.status="running",this.publishToolUpdate(e))}endTool(a,b,c,d){this.toolsById.has(a)||this.startTool(a,b,{});let e=this.toolsById.get(a);e&&("bash"===e.name&&null!==e.startedAtMs&&(e.durationMs=Math.max(0,Date.now()-e.startedAtMs),function(a,b){if(!a||"object"!=typeof a||Array.isArray(a))return;let c=a.details&&"object"==typeof a.details&&!Array.isArray(a.details)?a.details:{};a.details={...c,durationMs:b}}(c,e.durationMs)),e.result=c,e.status=d?"error":"completed",this.publishToolUpdate(e))}publishToolUpdate(a){this.publish({type:"message_update",tempId:a.tempId,message:this.toolMessage(a)})}toolMessage(a){let b;return{type:"tool",name:a.name,reasoning:a.display.reasoning,inputPreview:a.display.inputPreview,activity:a.display.activity,status:a.status,usage:null,output:"",startedAtMs:a.startedAtMs,durationMs:a.durationMs,declaration:{message:{kind:"tool",toolName:a.name,toolCallId:a.toolCallId,arguments:(b=g(a.input))&&"object"==typeof b&&!Array.isArray(b)?b:{},partialResult:g(a.partialResult),result:g(a.result),isError:"error"===a.status},raw:{toolCallId:a.toolCallId,toolName:a.name,args:a.input,partialResult:a.partialResult,result:a.result}}}}publish(a){for(let b of[...this.listeners])try{b(a)}catch(b){console.error("[Pi Desk][AgentToolRuntime] 事件监听器执行失败",{sessionId:this.session.sessionId,eventType:a.type,errorName:b instanceof Error?b.name:"UnknownError"})}}}function i(a){let b=f.get(a);b||(b={runtime:new h(a),references:0},f.set(a,b)),b.references+=1;let c=!1;return{runtime:b.runtime,release:()=>{c||(c=!0,b.references-=1,b.references>0||(f.delete(a),b.runtime.dispose()))}}}},77662:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{p:()=>r});var e=c(76760),f=c(75430),g=c(9753),h=c(59473),i=c(69503),j=c(73383),k=c(40333),l=a([f,j]);[f,j]=l.then?(await l)():l;let m=h.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),n=h.g1(h.Yj(),h.Pq()),o=h.g1(h.Yj().min(1),h.KC([n,h.ch()])),p=h.Ik({pluginName:m,event:m,data:n}).strict(),q=h.Ik({directory:h.Yj().min(1).max(4096).refine(a=>(0,e.isAbsolute)(a)&&!a.includes("\0")),default:h.zM().optional()}).strict();class r{constructor(a){this.options=a,this.controller=(0,f.createEventBus)(),this.slots=new Map,this.methods=new Map,this.unsubscribe=()=>void 0,this.unsubscribePush=()=>void 0,this.unsubscribePreviewDirectory=()=>void 0,this.disposed=!1,this.eventBus={emit:(a,b)=>{if(!this.disposed){if(a===g.Sl)return void this.applyMethodEvent(b);this.controller.emit(a,b)}},on:(a,b)=>this.disposed?()=>void 0:this.controller.on(a,b)},this.bindChannels()}createTaskRuntime(){let a=this.options;return new j.jd(this.controller,{onChanged:(b,c)=>{this.applyTaskSummaries(b),a.onTasksChanged(c),a.onChanged()},onInvalidReport:b=>a.onInvalidUpdate(b)})}bindChannels(){let a=this.options;this.taskRuntime=this.createTaskRuntime(),this.unsubscribe=this.controller.on(g.k0,b=>{if(this.disposed)return;let c=o.safeParse(b);if(!c.success)return void a.onInvalidUpdate(c.error);try{this.apply(c.data)&&a.onChanged()}catch(b){a.onInvalidUpdate(b)}}),this.unsubscribePreviewDirectory=this.controller.on(g.Nx,b=>{if(this.disposed)return;let c=q.safeParse(b);if(!c.success)return void a.onInvalidUpdate(c.error);try{this.applyPreviewDirectory(c.data)&&a.onChanged()}catch(b){a.onInvalidUpdate(b)}}),this.unsubscribePush=this.controller.on(g.Nb,b=>{if(this.disposed)return;let c=p.safeParse(b);c.success?Buffer.byteLength(JSON.stringify(c.data.data),"utf8")>65536?a.onInvalidUpdate(Error("Session Plugin Push data exceeds 64KB")):a.onPush(structuredClone(c.data)):a.onInvalidUpdate(c.error)})}activeTaskIds(){return this.taskRuntime.activeTaskIds()}taskRecord(a){return this.taskRuntime.record(a)}watchTaskDetail(a,b){return this.taskRuntime.watchDetail(a,b)}readTaskMessage(a,b){return this.taskRuntime.readMessage(a,b)}readTaskImage(a,b,c){return this.taskRuntime.readImage(a,b,c)}interruptTask(a){return this.taskRuntime.interrupt(a)}snapshot(){return Object.fromEntries([...this.slots.entries()].sort(([a],[b])=>a.localeCompare(b)).map(([a,b])=>[a,structuredClone(b.value)]))}async invokeMethod(a,b,c,d,e){if(this.disposed)throw Error("Pi session plugin runtime has been disposed");let f=(0,k.FX)(a),g=(0,k.QK)(b),h=this.methods.get((0,k.$m)(f,g));if(!h)throw new k.Tk(f,g);let i=await h.execute((0,k.nJ)(c,"input"),{source:d,extensionContext:e});return(0,k.nJ)(i,"output")}resetBranch(){this.disposed||(this.taskRuntime.dispose(),this.slots.clear(),this.taskRuntime=this.createTaskRuntime(),this.options.onTasksChanged([]),this.options.onChanged())}reset(){this.disposed||(this.unsubscribe(),this.unsubscribePush(),this.unsubscribePreviewDirectory(),this.taskRuntime.dispose(),this.controller.clear(),this.methods.clear(),this.slots.clear(),this.bindChannels(),this.options.onTasksChanged([]),this.options.onChanged())}dispose(){this.disposed||(this.disposed=!0,this.unsubscribe(),this.unsubscribePush(),this.unsubscribePreviewDirectory(),this.taskRuntime.dispose(),this.controller.clear(),this.methods.clear(),this.slots.clear())}applyMethodEvent(a){if(!a||"object"!=typeof a||Array.isArray(a))throw Error("Session plugin method event is invalid");let b=a.registration;if("register"!==a.type&&"unregister"!==a.type||!b||"object"!=typeof b||"string"!=typeof b.pluginName||"string"!=typeof b.method||"function"!=typeof b.execute)throw Error("Session plugin method registration is invalid");let c=(0,k.FX)(b.pluginName),d=(0,k.QK)(b.method),e=(0,k.$m)(c,d);if("register"===a.type){if(this.methods.has(e))throw new k.qs(c,d);this.methods.set(e,b);return}this.methods.get(e)===b&&this.methods.delete(e)}applyTaskSummaries(a){if(0===a.length)return void this.slots.delete("task-center");let b={tasks:a.map(a=>({...a,info:a.info.map(a=>({...a}))}))};this.slots.set("task-center",{serialized:JSON.stringify(b),value:b})}applyPreviewDirectory(a){let b=(0,e.resolve)(a.directory),c=(0,i.Yj)(b),d=this.slots.get(i.s6),f=(0,i.D)(d?.value),g=f.directories.find(a=>(0,i.Yj)(a)===c);if(!g&&f.directories.length>=i.xI)throw Error(`会话预览目录数量已达上限 ${i.xI}`);let h=g??b,j={directories:g?f.directories:[...f.directories,h],defaultDirectory:!0===a.default?h:f.defaultDirectory},k=JSON.stringify(j);return d?.serialized!==k&&(this.slots.set(i.s6,{serialized:k,value:j}),!0)}apply(a){if(Object.hasOwn(a,"task-center"))throw Error("task-center plugin slot is reserved by the Task Runtime");if(Object.hasOwn(a,i.s6))throw Error("project-preview 插件槽由会话预览目录登记管理");let b=!1;for(let[c,d]of Object.entries(a)){if(null===d){b=this.slots.delete(c)||b;continue}let a=JSON.stringify(d);this.slots.get(c)?.serialized!==a&&(this.slots.set(c,{serialized:a,value:d}),b=!0)}return b}}d()}catch(a){d(a)}})},77844:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{lr:()=>m,mu:()=>l,ni:()=>i,qc:()=>j,ti:()=>k});var e=c(73024),f=c(75430),g=c(54174),h=a([f]);f=(h.then?(await h)():h)[0];let m=0x1f00000;class n extends Error{constructor(a){super(a),this.name="L4PiChatInputError"}}function i(a){if(!a.text.trim()&&0===a.images.length)throw new n("请输入文字或添加图片");return{text:a.text,images:a.images.map(a=>({...a})),imageBytes:function(a){if(a.length>10)throw new n("单次最多发送 10 张图片");let b=0;for(let c of a){let a=(0,g.f1)(c);if(a.bytes.length>0xa00000)throw new n("单张图片压缩后不能超过 10MB");b+=a.bytes.length}if(b>0x1400000)throw new n("单次发送图片总量不能超过 20MB");return b}(a.images)}}function j(a,b,c,d){let h=function(a,b){var c,d;let e;if(!a.startsWith("/"))return a;let f=a.match(/^\/([^\s]+)(?:\s+([\s\S]*))?$/);if(!f)return a;let g=b.find(a=>a.name===f[1]);return g?(c=g.content,e=(d=function(a){let b=[],c="",d=null;for(let e of a){if(d){e===d?d=null:c+=e;continue}if('"'===e||"'"===e){d=e;continue}if(/\s/.test(e)){c&&b.push(c),c="";continue}c+=e}return c&&b.push(c),b}(f[2]??"")).join(" "),c.replace(/\$\{(\d+|ARGUMENTS|@):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g,(a,b,c,f,g,h)=>{if("string"==typeof b)return("@"===b||"ARGUMENTS"===b?e:d[Number.parseInt(b,10)-1])||c;if("string"==typeof f){let a=Math.max(0,Number.parseInt(f,10)-1);return"string"==typeof g?d.slice(a,a+Number.parseInt(g,10)).join(" "):d.slice(a).join(" ")}return"ARGUMENTS"===h||"@"===h?e:d[Number.parseInt(h,10)-1]??""})):a}(function(a,b){if(!a.startsWith("/skill:"))return a;let c=a.indexOf(" "),d=-1===c?a.slice(7):a.slice(7,c),g=-1===c?"":a.slice(c+1).trim(),h=b.find(a=>a.name===d);if(!h)return a;try{let a=(0,f.stripFrontmatter)((0,e.readFileSync)(h.filePath,"utf8")).trim(),b=`<skill name="${h.name}" location="${h.filePath}">
|
|
29
30
|
References are relative to ${h.baseDir}.
|
|
30
31
|
|
|
31
32
|
${a}
|
|
32
33
|
</skill>`;return g?`${b}
|
|
33
34
|
|
|
34
35
|
${g}`:b}catch{return a}}(a,c),d),j=(b??[]).map(a=>{let b=(0,g.Z)(a.data);if(b.metadata.mimeType!==a.mimeType)throw new n("图片 MIME 与实际内容不一致");return{...b.metadata,data:a.data}});return i({text:h,images:j})}function k(a){return a.map(a=>({type:"image",data:a.data,mimeType:a.mimeType}))}function l(a){let b,c;if(a.length>32)throw new n("当前 WorkSession 最多排队 32 条输入");if(a.reduce((a,b)=>a+b.imageBytes,0)>0x1400000)throw new n("全部排队图片总量不能超过 20MB");if(b=a.map(a=>a.text).filter(a=>a.trim()).join("\n\n"),c=a.flatMap(a=>a.images),Buffer.byteLength(JSON.stringify({text:b,images:c}),"utf8")+1024>m)throw new n("排队内容过大,无法通过一次恢复响应返回")}d()}catch(a){d(a)}})},82459:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{Ee:()=>k,Fr:()=>m,ue:()=>l,zP:()=>n}),c(51455),c(76760);var e=c(75430),f=c(60815),g=c(71473),h=c(95220),i=c(2234),j=a([e,f,g]);function k(){globalThis.__piDeskCommandRuntime=void 0}function l(a=[]){let b=globalThis.__piDeskCommandRuntime?.systemPrompt;return b?[...a,b]:[...a]}async function m(a,b){let c=globalThis.__piDeskCommandRuntime;if(!c)throw Error("Pi Desk 命令入口尚未准备完成");b.signal.throwIfAborted();let d=(0,i.h)(a);if("help"===d.kind)return{mode:"sync",message:d.message};if("version"===d.kind)return{mode:"sync",message:c.version};if("info"===d.kind)return{mode:"sync",message:JSON.stringify({version:c.version,environment:c.development?"development":"production",mode:(0,h.P)()?"basic":"normal",cwd:b.cwd,agentDir:c.agentDir,docsDirectory:c.docsDirectory})};if("session"===d.kind)return b.reload();if("plugins"!==d.kind)throw Error("Pi Desk 命令无效");return c.handler(d,b)}[e,f,g]=j.then?(await j)():j;let o=f.Type.Object({args:f.Type.Array(f.Type.String({minLength:1,maxLength:2048}),{maxItems:32})},{additionalProperties:!1});function n(a){return globalThis.__piDeskCommandRuntime?(0,e.defineTool)({name:"pidesk",exposure:"model-only",label:"Pi Desk",description:"Pi Desk 命令入口。",parameters:o,async execute(b,c){let d=await a(c.args,b),f=(0,e.truncateHead)(d.message),g={mode:d.mode,message:f.truncated?`${f.content}
|
|
35
|
-
…结果过长,已截断。`:d.message};return{content:[{type:"text",text:JSON.stringify(g)}],details:g}}}):null}d()}catch(a){d(a)}})},
|
|
36
|
-
`,h=`${b}.${(0,d.randomUUID)()}.tmp`;try{(0,e.writeFileSync)(h,g,{encoding:"utf8",flag:"wx"});try{(0,e.linkSync)(h,b)}catch(a){if("EEXIST"!==a.code)throw a}}finally{(0,e.existsSync)(h)&&(0,e.unlinkSync)(h)}if(!(0,e.existsSync)(b))throw Error(`Failed to materialize Pi session: ${a.getSessionId()}`);return b}},83800:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{k:()=>q});var e=c(75430),f=c(82459),g=c(23404),h=c(84889),i=c(58801),j=c(42520),k=c(69765),l=c(77662),m=c(23272),n=a([e,f,g,h,i,l]);[e,f,g,h,i,l]=n.then?(await n)():n;let o=new Set,p="Pi 会话实例已失效,不能继续访问当前会话";class q{constructor(a){this.options=a,this.active=!0,this.accessRevoked=!1,this.session=null,this.execution=null,this.result=null,this.onLifecycleError=null,this.stage="等待初始化资源",this.stageStartedAt=performance.now(),this.sessionId=a.sessionManager.getSessionId(),this.ui=a.ui??new m.k,this.capabilities=new g.O(a.readCapabilities),this.plugins=new l.p({onChanged:()=>{this.active&&a.pluginEvents.onChanged()},onPush:b=>{this.active&&a.pluginEvents.onPush(b)},onTasksChanged:b=>{this.active&&a.pluginEvents.onTasksChanged(b)},onInvalidUpdate:b=>{this.active&&a.pluginEvents.onInvalidUpdate(b)}}),this.messages=new k.U((a,b)=>{console.warn("[Pi Desk][PiSession] 延后消息投递失败",{sessionId:this.sessionId,source:a,message:b instanceof Error?b.message:String(b)})}),this.manager=new Proxy(a.sessionManager,{get:(a,b)=>{this.assertAccess();let c=Reflect.get(a,b,a);return"function"!=typeof c?c:(...b)=>(this.assertAccess(),Reflect.apply(c,a,b))},set:()=>{throw Error("Pi 会话只能通过 SessionManager 方法修改")}})}start(a=!1){return this.result??=this.initialize(a),this.result}async reload(){this.assertActive();let a=await this.start(),b=null;this.onLifecycleError=a=>{b??=a},this.setStage("重载 Pi 配置");try{if(await a.reload({beforeSessionStart:async()=>{this.assertActive(),this.validateResources(a.resourceLoader,a.settingsManager.drainErrors().map(({error:a})=>({type:"error",message:a.message})))}}),this.assertActive(),b)throw b}finally{this.onLifecycleError=null}}setStage(a){this.active&&(this.stage=a,this.stageStartedAt=performance.now())}describeStage(){return`${this.stage}
|
|
36
|
+
…结果过长,已截断。`:d.message};return{content:[{type:"text",text:JSON.stringify(g)}],details:g}}}):null}d()}catch(a){d(a)}})},83800:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{k:()=>q});var e=c(75430),f=c(82459),g=c(23404),h=c(84889),i=c(58801),j=c(42520),k=c(69765),l=c(77662),m=c(23272),n=a([e,f,g,h,i,l]);[e,f,g,h,i,l]=n.then?(await n)():n;let o=new Set,p="Pi 会话实例已失效,不能继续访问当前会话";class q{constructor(a){this.options=a,this.active=!0,this.accessRevoked=!1,this.session=null,this.execution=null,this.result=null,this.onLifecycleError=null,this.stage="等待初始化资源",this.stageStartedAt=performance.now(),this.sessionId=a.sessionManager.getSessionId(),this.ui=a.ui??new m.k,this.capabilities=new g.O(a.readCapabilities),this.plugins=new l.p({onChanged:()=>{this.active&&a.pluginEvents.onChanged()},onPush:b=>{this.active&&a.pluginEvents.onPush(b)},onTasksChanged:b=>{this.active&&a.pluginEvents.onTasksChanged(b)},onInvalidUpdate:b=>{this.active&&a.pluginEvents.onInvalidUpdate(b)}}),this.messages=new k.U((a,b)=>{console.warn("[Pi Desk][PiSession] 延后消息投递失败",{sessionId:this.sessionId,source:a,message:b instanceof Error?b.message:String(b)})}),this.manager=new Proxy(a.sessionManager,{get:(a,b)=>{this.assertAccess();let c=Reflect.get(a,b,a);return"function"!=typeof c?c:(...b)=>(this.assertAccess(),Reflect.apply(c,a,b))},set:()=>{throw Error("Pi 会话只能通过 SessionManager 方法修改")}})}start(a=!1){return this.result??=this.initialize(a),this.result}async reload(){this.assertActive();let a=await this.start(),b=null;this.onLifecycleError=a=>{b??=a},this.setStage("重载 Pi 配置");try{if(await a.reload({beforeSessionStart:async()=>{this.assertActive(),this.validateResources(a.resourceLoader,a.settingsManager.drainErrors().map(({error:a})=>({type:"error",message:a.message})))}}),this.assertActive(),b)throw b}finally{this.onLifecycleError=null}}setStage(a){this.active&&(this.stage=a,this.stageStartedAt=performance.now())}describeStage(){return`${this.stage}
|
|
37
37
|
当前步骤耗时:${Math.round(performance.now()-this.stageStartedAt)} 毫秒`}async initialize(a){let b=performance.now();if(this.assertActive(),"normal"===this.options.mode&&o.size>=4)throw Error("尚未结束的插件初始化或关闭任务过多,请重启服务后再加载插件");let c=new Promise((a,b)=>{this.onLifecycleError=b}),d=async()=>(this.assertActive(),a&&(this.setStage("刷新插件资源"),(0,i.N)(),this.options.resources.reset(),this.assertActive()),this.create());this.execution=d();try{let a=await this.ui.waitForOperation(Promise.race([this.execution,c]),6e4,()=>Error("Pi 会话初始化超时(60 秒);不含等待用户回答"));return this.assertActive(),this.setStage("会话已就绪"),console.info("[Pi Desk][PiSession] 会话初始化完成",{sessionId:this.sessionId,cwd:this.options.cwd,mode:this.options.mode,durationMs:Math.round(performance.now()-b)}),a}catch(d){let a=d instanceof Error?d:Error(String(d));if(!this.active)throw console.info("[Pi Desk][PiSession] 会话初始化已取消",{sessionId:this.sessionId,cwd:this.options.cwd,mode:this.options.mode,durationMs:Math.round(performance.now()-b)}),a;let c=`${a.stack??a.message}
|
|
38
38
|
|
|
39
39
|
最后处理步骤:${this.describeStage()}`;throw console.error("[Pi Desk][PiSession] 会话初始化失败",{sessionId:this.sessionId,cwd:this.options.cwd,mode:this.options.mode,durationMs:Math.round(performance.now()-b),message:c}),this.dispose(),Error(c)}finally{this.onLifecycleError=null}}dispose(a=!0){if(!this.active)return;this.active=!1,this.onLifecycleError?.(Error(p)),this.ui.reset(!1),this.messages.dispose(),this.plugins.dispose(),this.capabilities.dispose();let b=this.session;this.session=null;try{b?.dispose()}catch(a){console.warn("[Pi Desk][PiSession] 释放会话失败",{sessionId:this.sessionId,message:a instanceof Error?a.message:String(a)})}finally{this.accessRevoked=!0}if(!this.execution)return;let c=b&&a?Promise.resolve().then(()=>b.extensionRunner.emit({type:"session_shutdown",reason:"quit"})):Promise.resolve(),d=Promise.allSettled([this.execution,c]);o.add(d);let e=setTimeout(()=>{console.warn("[Pi Desk][PiSession] 旧实例仍在后台清理,不阻塞基础聊天",{sessionId:this.sessionId,cwd:this.options.cwd,stage:this.describeStage()})},1500);e.unref(),d.then(()=>{clearTimeout(e),o.delete(d)})}assertActive(){if(!this.active)throw Error(p)}assertAccess(){if(this.accessRevoked)throw Error(p)}validateResources(a,b){let c=a.getExtensions().errors.map(({path:a,error:b})=>`${b}
|
|
40
|
-
插件入口:${a}`);for(let a of b)"error"===a.type?c.push(a.message):console.info("[Pi Desk][PiSession] 初始化诊断",{cwd:this.options.cwd,...a});if(c.length>0){for(let a of c)(0,j.pL)(this.options.cwd,a);throw a.getExtensions().runtime.invalidate(p),Error(c.join("\n"))}}async create(){this.setStage("加载 Pi 配置与插件");let a=()=>{this.ui.reset();let a=this.capabilities.createHostExtension((a,b)=>(this.assertActive(),this.options.onInput(a,b)),()=>{this.ui.reset(!1),this.plugins.reset()});a.handlers.set("session_tree",[async()=>this.options.onTree?.()]),a.handlers.set("session_before_tree",[async a=>{if(a.signal.aborted)return{cancel:!0}}]);let b=this.options.onCommand?(0,f.zP)(this.options.onCommand):null;return b&&a.tools.set(b.name,{definition:b,sourceInfo:a.sourceInfo}),a},b="basic"===this.options.mode?await (0,h.I)({cwd:this.options.cwd,createHostExtension:a}):await this.options.resources.createServices(this.options.cwd,{appendSystemPromptOverride:f.ue,eventBus:this.capabilities.eventBus(this.plugins.eventBus),extensionsOverride:b=>{if(!this.active)throw b.runtime.invalidate(p),Error(p);let c=a(),d="<inline:pi-desk-branch-state>",e={...c,path:d,resolvedPath:d,sourceInfo:{...c.sourceInfo,path:d},handlers:new Map([["session_tree",c.handlers.get("session_tree")]]),tools:new Map};return c.handlers.delete("session_tree"),{...b,extensions:[e,...b.extensions,c]}}},a=>this.setStage(a));this.assertActive(),this.validateResources(b.resourceLoader,b.diagnostics),this.setStage("创建会话与恢复模型"),b.resourceLoader=this.capabilities.resources(b.resourceLoader);let{session:c}=await (0,e.createAgentSessionFromServices)({services:b,sessionManager:this.manager});return this.assertActive(),this.session=c,this.capabilities.attach(c),this.setStage("启动插件"),await c.bindExtensions({mode:"rpc",uiContext:this.ui.bind(c.extensionRunner.getUIContext(),()=>this.assertActive()),onError:a=>{let b=`${a.stack??a.error}
|
|
40
|
+
插件入口:${a}`);for(let a of b)"error"===a.type?c.push(a.message):console.info("[Pi Desk][PiSession] 初始化诊断",{cwd:this.options.cwd,...a});if(c.length>0){for(let a of c)(0,j.pL)(this.options.cwd,a);throw a.getExtensions().runtime.invalidate(p),Error(c.join("\n"))}}async create(){this.setStage("加载 Pi 配置与插件");let a=()=>{this.ui.reset();let a=this.capabilities.createHostExtension((a,b)=>(this.assertActive(),this.options.onInput(a,b)),()=>{this.ui.reset(!1),this.plugins.reset()});a.handlers.set("message_end",[async a=>(this.assertActive(),this.options.onMessageEnd(a))]),a.handlers.set("session_tree",[async()=>this.options.onTree?.()]),a.handlers.set("session_before_tree",[async a=>{if(a.signal.aborted)return{cancel:!0}}]);let b=this.options.onCommand?(0,f.zP)(this.options.onCommand):null;return b&&a.tools.set(b.name,{definition:b,sourceInfo:a.sourceInfo}),a},b="basic"===this.options.mode?await (0,h.I)({cwd:this.options.cwd,createHostExtension:a}):await this.options.resources.createServices(this.options.cwd,{appendSystemPromptOverride:f.ue,eventBus:this.capabilities.eventBus(this.plugins.eventBus),extensionsOverride:b=>{if(!this.active)throw b.runtime.invalidate(p),Error(p);let c=a(),d="<inline:pi-desk-branch-state>",e={...c,path:d,resolvedPath:d,sourceInfo:{...c.sourceInfo,path:d},handlers:new Map([["session_tree",c.handlers.get("session_tree")]]),tools:new Map};return c.handlers.delete("session_tree"),{...b,extensions:[e,...b.extensions,c]}}},a=>this.setStage(a));this.assertActive(),this.validateResources(b.resourceLoader,b.diagnostics),this.setStage("创建会话与恢复模型"),b.resourceLoader=this.capabilities.resources(b.resourceLoader);let{session:c}=await (0,e.createAgentSessionFromServices)({services:b,sessionManager:this.manager});return this.assertActive(),this.session=c,this.capabilities.attach(c),this.setStage("启动插件"),await c.bindExtensions({mode:"rpc",uiContext:this.ui.bind(c.extensionRunner.getUIContext(),()=>this.assertActive()),onError:a=>{let b=`${a.stack??a.error}
|
|
41
41
|
插件入口:${a.extensionPath}
|
|
42
42
|
事件:${a.event}`;this.active&&(console.error("[Pi Desk][PiSession] 扩展处理失败",{sessionId:this.sessionId,message:b}),this.onLifecycleError?.(Error(b)),("session_tree"===a.event||"session_before_tree"===a.event)&&this.session?.extensionRunner.getUIContext().notify(`会话树扩展处理失败:${a.error}`,"error"))}}),this.assertActive(),this.messages.installExtensionRuntime(b.resourceLoader.getExtensions().runtime),this.setStage("应用会话能力"),await this.capabilities.apply(),this.assertActive(),c}}d()}catch(a){d(a)}})},84889:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{I:()=>j});var e=c(73024),f=c(76760),g=c(82459),h=c(75430),i=a([g,h]);[g,h]=i.then?(await i)():i;class k{constructor(a,b,c,d){this.cwd=a,this.agentDir=b,this.settings=c,this.createHostExtension=d,this.extensions={extensions:[],errors:[],runtime:(0,h.createExtensionRuntime)()},this.agentsFiles={agentsFiles:[]}}getExtensions(){return this.extensions}getSkills(){return{skills:[],diagnostics:[]}}getPrompts(){return{prompts:[],diagnostics:[]}}getThemes(){return{themes:[],diagnostics:[]}}getAgentsFiles(){return this.agentsFiles}getSystemPrompt(){return this.systemPrompt?.content}getSystemPromptSource(){return this.systemPrompt?{path:this.systemPrompt.path}:void 0}getAppendSystemPrompt(){return(0,g.ue)(this.appendPrompt?[this.appendPrompt.content]:[])}getAppendSystemPromptSources(){return this.appendPrompt?[{path:this.appendPrompt.path}]:[]}extendResources(){}async reload(){await this.settings.reload(),this.extensions={extensions:[this.createHostExtension()],errors:[],runtime:(0,h.createExtensionRuntime)()},this.agentsFiles={agentsFiles:(0,h.loadProjectContextFiles)({cwd:this.cwd,agentDir:this.agentDir})},this.systemPrompt=this.readPrompt("SYSTEM.md"),this.appendPrompt=this.readPrompt("APPEND_SYSTEM.md")}readPrompt(a){let b=[...this.settings.isProjectTrusted()?[(0,f.join)(this.cwd,h.CONFIG_DIR_NAME,a)]:[],(0,f.join)(this.agentDir,a)].find(a=>(0,e.existsSync)(a));return b?{path:b,content:(0,e.readFileSync)(b,"utf8")}:void 0}}async function j(a){let b=(0,h.getAgentDir)(),c=h.SettingsManager.create(a.cwd,b),d=await h.ModelRuntime.create({authPath:(0,f.join)(b,"auth.json"),modelsPath:(0,f.join)(b,"models.json")}),e=new k(a.cwd,b,c,a.createHostExtension);return await e.reload(),await d.refresh({allowNetwork:!1}),{cwd:a.cwd,agentDir:b,settingsManager:c,modelRuntime:d,resourceLoader:e,diagnostics:c.drainErrors().map(({error:a})=>({type:"error",message:a.message}))}}d()}catch(a){d(a)}})},85273:(a,b,c)=>{c.d(b,{Hj:()=>g,Nb:()=>f,Nx:()=>h,O0:()=>i,Sl:()=>e,k0:()=>d}),c(77598),c(41966);let d="pi-desk:session-plugins",e="pi-desk:session-plugin-methods:v1",f="pi-desk:session-plugin-push:v1",g="pi-desk:session-capabilities",h="pi-desk:session-preview-directory",i="pi-desk:task-report:v1"},87468:(a,b,c)=>{c.d(b,{u:()=>e});let d="v1:main";class e{constructor(a){for(const b of(this.entryIds=new Set,this.branchIdByEntryId=new Map,this.childCountByParentId=new Map,a))this.appendEntry(b)}branchIdForEntry(a){let b=this.branchIdByEntryId.get(a);if(!b)throw Error(`Pi session entry has no branch identity: ${a}`);return b}branchIdForHead(a){return null===a?d:this.branchIdForEntry(a)}predictAppend(a){if(null!==a&&!this.entryIds.has(a))throw Error(`Cannot append to missing Pi session parent: ${a}`);let b=(this.childCountByParentId.get(a)??0)+1;return{parentEntryId:a,childOrdinal:b,branchId:this.branchIdForChild(a,b)}}appendEntry(a){this.assertEntry(a);let b=this.predictAppend(a.parentId);return this.entryIds.add(a.id),this.branchIdByEntryId.set(a.id,b.branchId),this.childCountByParentId.set(a.parentId,b.childOrdinal),b}confirmAppend(a,b){let c=this.predictAppend(b.parentId);if(a.parentEntryId!==c.parentEntryId||a.childOrdinal!==c.childOrdinal||a.branchId!==c.branchId)throw Error(`Pi branch append conflict: expected ${a.branchId}/${a.childOrdinal}, got ${c.branchId}/${c.childOrdinal}`);return this.appendEntry(b),c.branchId}branchIdForChild(a,b){return null===a?1===b?d:`v1:fork:r:${b}`:1===b?this.branchIdForEntry(a):`v1:fork:e:${encodeURIComponent(a)}:${b}`}assertEntry(a){if(!a.id)throw Error("Pi session entry is missing an id");if(this.entryIds.has(a.id))throw Error(`Pi session contains duplicate entry id: ${a.id}`);if(null!==a.parentId&&(!a.parentId||!this.entryIds.has(a.parentId)))throw Error(`Pi session entry ${a.id} has missing parent: ${a.parentId}`)}}},88502:(a,b,c)=>{c.d(b,{f:()=>h});var d=c(77598),e=c(51455),f=c(76760);function g(a,b){let c=(0,f.relative)(a,b);return""===c||!c.startsWith("..")&&!(0,f.isAbsolute)(c)}async function h(a){if("entry.js"!==(0,f.basename)(a))throw Error("Browser Entry 必须命名为 entry.js");let b=await (0,e.realpath)((0,f.dirname)(a)),c=new Map,h=0,i=0,j=[],k=async(a,l,m)=>{let n=await (0,e.realpath)(a);if(!g(b,n))return;if(m.has(n))throw Error("Browser 模块目录存在符号链接循环");let o=new Set(m).add(n);for(let a of(await (0,e.readdir)(n,{withFileTypes:!0})).sort((a,b)=>a.name.localeCompare(b.name))){if(++i>4096)throw Error("Browser 模块目录条目超过上限");if(a.name.startsWith(".")||"node_modules"===a.name)continue;let m=(0,f.join)(n,a.name),p=await (0,e.realpath)(m);if(!g(b,p))continue;let q=await (0,e.stat)(p),r=l?`${l}/${a.name}`:a.name;if(q.isDirectory()){await k(p,r,o);continue}if(!q.isFile()||!a.name.endsWith(".js"))continue;if("entry.js"===r&&"entry.js"!==(0,f.basename)(p))throw Error("Browser Entry 符号链接必须指向 entry.js");if(c.size>=2048||q.size>0x1000000||h+q.size>0x2000000)throw Error("Browser 模块快照超过数量或容量上限");let s=await (0,e.readFile)(p),t=await (0,e.stat)(p);if(s.length!==q.size||t.size!==q.size||t.mtimeMs!==q.mtimeMs)throw Error("Browser 模块在读取时发生变化,请构建完成后重新加载");h+=s.length,j.push({path:p,size:t.size,mtimeMs:t.mtimeMs,ino:t.ino}),c.set(r,{content:s,etag:`"${(0,d.createHash)("sha256").update(s).digest("hex")}"`})}};for(let a of(await k(b,"",new Set),j)){let b=await (0,e.stat)(a.path);if(b.size!==a.size||b.mtimeMs!==a.mtimeMs||b.ino!==a.ino)throw Error("Browser 模块组在读取时发生变化,请构建完成后重新加载")}if(!c.has("entry.js"))throw Error("Browser Entry 模块缺失或越出专用目录");return{size:h,modules:c}}},95220:(a,b,c)=>{c.d(b,{P:()=>e});let d=process.argv.includes("--safe-mode")||"1"===process.env.PI_DESK_SAFE_MODE;function e(){return d}},96459:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{H0:()=>n,WE:()=>m});var e=c(61035),f=c(75430),g=c(44095),h=c(95220),i=c(56971),j=c(2476),k=c(58801),l=a([e,f,g,i,k]);[e,f,g,i,k]=l.then?(await l)():l;class o extends g.K{constructor(a=process.cwd(),b=(0,f.getAgentDir)()){const c=new j.N,d=async()=>(0,h.P)()?{sources:[],errors:[]}:(0,i.o)(a,b,{DefaultPackageManager:f.DefaultPackageManager,SettingsManager:f.SettingsManager});super(async()=>{let a=await d();for(let b of a.errors)console.warn("[Pi Desk][GlobalPluginRuntime] 插件来源发现诊断",{message:b});return await c.initialize(a),a.sources.flatMap(a=>a.enabled&&!a.error&&a.piDeskRoot?[{source:a.source,installedPath:a.piDeskRoot}]:[])},(0,e.J)()),this.sourceChanges=c,this.discover=d}async scanSourceChanges(a){return await this.initialize(),this.sourceChanges.scan(await this.discover(),a)}async applySourceChange(a){let[b]=await this.scanSourceChanges([a.source]);if(!b||b.fingerprint!==a.fingerprint||b.current?.enabled&&b.current.error)throw Error(b?.current?.error??"插件源码在预检后发生变化,请重新加载");a.previous?.piDeskRoot||a.current?.piDeskRoot?await this.replaceSource(a.source,a.current?.enabled?a.current.piDeskRoot:null):(0,k.N)(),this.sourceChanges.commit(a)}}function m(){return globalThis.__piDeskGlobalPluginRuntime||(globalThis.__piDeskGlobalPluginRuntime=new o),globalThis.__piDeskGlobalPluginRuntime}async function n(){let a=globalThis.__piDeskGlobalPluginRuntime;globalThis.__piDeskGlobalPluginRuntime=void 0,await a?.dispose()}d()}catch(a){d(a)}})},99327:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{HJ:()=>x,Il:()=>u,L9:()=>v,dw:()=>w});var e=c(77598),f=c(73024),g=c(75613),h=c(12727),i=c(76452),j=c(568),k=a([j]);function l(a){if(!a||"object"!=typeof a)return null;let b=a.role;return"string"==typeof b?b:null}function m(a){if(!a||"object"!=typeof a)return null;let b=a.toolCallId;return"string"==typeof b?b:null}function n(a){return null===a?null:"text-file"===a.kind?`text:${a.path}`:void 0!==a.session?a.session:`session-file:${a.sessionFile}`}function o(a,b,c){for(let d of[...a])try{d(b)}catch(a){console.error("[Pi Desk][TaskDetailRuntime] 事件监听器执行失败",{label:c,errorName:a instanceof Error?a.name:"UnknownError"})}}j=(k.then?(await k)():k)[0];class q{snapshot(){return null}subscribe(){return()=>void 0}dispose(){}}class r{constructor(a,b,c){this.path=a,this.observation=c,this.listeners=new Set,this.disposed=!1,this.current=b}static async create(a){let b=[],c=null,d=await (0,g.i)().observe(a,a=>{c?c.handleLogEvent(a):b.push(a)});for(let e of(c=new r(a,d.snapshot,d),b))c.handleLogEvent(e);return c}snapshot(){return{kind:"text",...this.current}}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.observation.release(),this.listeners.clear())}handleLogEvent(a){if(!this.disposed){if("snapshot"===a.type){this.current={...a.snapshot},o(this.listeners,{type:"snapshot"},this.path);return}if("text_append"===a.type){this.current={...this.current,text:this.current.text+a.text},o(this.listeners,a,this.path);return}o(this.listeners,a,this.path)}}}class s{constructor(a,b){this.sessionFile=a,this.listeners=new Set,this.watcher=null,this.interval=null,this.refreshTimer=null,this.refreshPromise=null,this.disposed=!1,this.current=b}static async create(a){let b=new s(a,await (0,j.mH)(a));return b.startWatching(),b}snapshot(){return{kind:"conversation",entries:this.current.entries,temporaryMessages:[],truncated:this.current.truncated}}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.watcher?.close(),this.interval&&clearInterval(this.interval),this.refreshTimer&&clearTimeout(this.refreshTimer),this.watcher=null,this.interval=null,this.refreshTimer=null,this.listeners.clear())}startWatching(){try{this.watcher=(0,f.watch)(this.sessionFile,()=>this.scheduleRefresh()),this.watcher.on("error",()=>this.scheduleRefresh())}catch{this.watcher=null}this.interval=setInterval(()=>this.scheduleRefresh(),500)}scheduleRefresh(){this.disposed||this.refreshTimer||(this.refreshTimer=setTimeout(()=>{this.refreshTimer=null,this.refresh()},40))}refresh(){return this.disposed?Promise.resolve():(this.refreshPromise||(this.refreshPromise=(async()=>{try{let a=await (0,j.mH)(this.sessionFile);if(this.disposed)return;let b=this.current.entries.map(a=>a.entryId),c=a.entries.map(a=>a.entryId);if(b.length===c.length&&b.every((a,b)=>a===c[b])){this.current=a;return}let d=!this.current.truncated&&!a.truncated&&b.every((a,b)=>a===c[b])?a.entries.slice(b.length):[];this.current=a,d.length>0?o(this.listeners,{type:"conversation_event",event:{type:"durable_append",entries:d}},this.sessionFile):o(this.listeners,{type:"snapshot"},this.sessionFile)}catch(a){console.warn("[Pi Desk][TaskSessionFileDetail] 刷新会话失败",{sessionFile:this.sessionFile,errorName:a instanceof Error?a.name:"UnknownError"}),o(this.listeners,{type:"unavailable"},this.sessionFile)}})().finally(()=>{this.refreshPromise=null})),this.refreshPromise)}}class t{constructor(a){for(const b of(this.session=a,this.listeners=new Set,this.temporaryMessages=new Map,this.temporaryOrder=[],this.pendingEvents=[],this.activeMessage=null,this.drainScheduled=!1,this.disposed=!1,this.toolRuntimeLease=(0,i.s)(a),this.toolRuntime=this.toolRuntimeLease.runtime,this.unsubscribeToolRuntime=this.toolRuntime.subscribe(a=>this.captureToolEvent(a)),this.unsubscribeAgent=a.agent.subscribe(b=>{try{this.captureAgentEvent(b)}catch(c){console.error("[Pi Desk][TaskAgentDetail] 捕获 AgentEvent 失败",{sessionId:a.sessionId,eventType:b.type,errorName:c instanceof Error?c.name:"UnknownError"})}}),this.entries=(0,h.xm)(a.sessionManager.getBranch()),this.toolRuntime.activeMessages()))this.setTemporary(b.tempId,b.message);const b=a.agent.state.streamingMessage;if(b){const a=(0,h.b7)(b);if(a){const c=(0,e.randomUUID)();for(const d of(this.activeMessage={tempId:c,started:!0,toolCallId:null},this.setTemporary(c,a),this.toolRuntime.syncStreamingTools(b,!1),this.toolRuntime.activeMessages()))this.setTemporary(d.tempId,d.message)}}}snapshot(){return{kind:"conversation",entries:this.entries,temporaryMessages:this.temporaryOrder.flatMap(a=>{let b=this.temporaryMessages.get(a);return b?[{tempId:a,message:b}]:[]}),truncated:!1}}subscribe(a){return this.listeners.add(a),()=>this.listeners.delete(a)}dispose(){this.disposed||(this.disposed=!0,this.unsubscribeAgent(),this.unsubscribeToolRuntime(),this.toolRuntimeLease.release(),this.listeners.clear(),this.pendingEvents.length=0,this.temporaryMessages.clear(),this.temporaryOrder.length=0)}captureAgentEvent(a){if(!this.disposed)switch(a.type){case"message_start":this.startMessage(a.message);return;case"message_update":this.updateMessage(a.message),this.toolRuntime.syncStreamingTools(a.message);return;case"message_end":this.toolRuntime.syncStreamingTools(a.message),this.endMessage(a.message);return;default:return}}captureToolEvent(a){if(!this.disposed){if("message_discard"===a.type){this.removeTemporary(a.tempId),this.queueEvent(a);return}this.setTemporary(a.tempId,a.message),this.queueEvent(a)}}startMessage(a){let b=l(a),c=(0,e.randomUUID)(),d=!0,f=null;if("toolResult"===b){let b=(f=m(a))?this.toolRuntime.tempId(f):null;b&&(c=b,d=!1)}let g=this.projectLiveMessage(a,f);g&&(this.activeMessage={tempId:c,started:d,toolCallId:f},this.setTemporary(c,g),this.queueEvent({type:d?"message_start":"message_update",tempId:c,message:g}))}updateMessage(a){let b=this.activeMessage;if(!b)return;let c=this.projectLiveMessage(a,b.toolCallId);c&&(this.setTemporary(b.tempId,c),this.queueEvent({type:"message_update",tempId:b.tempId,message:c}))}endMessage(a){let b=this.activeMessage,c=l(a),d="toolResult"===c?m(a):null;if(!b){let c=this.projectLiveMessage(a,d);if(!c)return;b={tempId:(0,e.randomUUID)(),started:!0,toolCallId:d},this.setTemporary(b.tempId,c),this.queueEvent({type:"message_start",tempId:b.tempId,message:c})}let f=this.projectLiveMessage(a,b.toolCallId);f&&(this.setTemporary(b.tempId,f),this.queueEvent({type:"message_update",tempId:b.tempId,message:f}));let g=this.session.sessionManager.getLeafEntry(),i=g?(0,h.B4)(g):null;g&&i?(this.entries.some(a=>a.entryId===i.entryId)||(this.entries=[...this.entries,i]),this.removeTemporary(b.tempId),this.queueEvent({type:"message_commit",tempId:b.tempId,entryId:i.entryId,timestampMs:function(a,b){let c=Date.parse(b);if(!Number.isSafeInteger(c)||c<0)throw Error(`Pi session entry has an invalid timestamp: ${a}`);return c}(g.id,g.timestamp)})):b.started&&(this.removeTemporary(b.tempId),this.queueEvent({type:"message_discard",tempId:b.tempId})),b.toolCallId&&this.toolRuntime.remove(b.toolCallId),this.activeMessage=null}projectLiveMessage(a,b){return"toolResult"===l(a)&&b?this.toolRuntime.projectLiveResult(a,b):(0,h.b7)(a)}setTemporary(a,b){this.temporaryMessages.has(a)||this.temporaryOrder.push(a),this.temporaryMessages.set(a,b)}removeTemporary(a){this.temporaryMessages.delete(a);let b=this.temporaryOrder.indexOf(a);b>=0&&this.temporaryOrder.splice(b,1)}queueEvent(a){if(!this.disposed){if("message_update"===a.type){let b=this.pendingEvents.at(-1);b?.type==="message_update"&&b.tempId===a.tempId?this.pendingEvents[this.pendingEvents.length-1]=a:this.pendingEvents.push(a)}else this.pendingEvents.push(a);this.drainScheduled||(this.drainScheduled=!0,queueMicrotask(()=>this.drainEvents()))}}drainEvents(){if(this.drainScheduled=!1,!this.disposed)for(;this.pendingEvents.length>0;){let a=this.pendingEvents.shift();o(this.listeners,{type:"conversation_event",event:a},this.session.sessionId)}}}async function p(a){return null===a?new q:"text-file"===a.kind?r.create(a.path):void 0!==a.session?new t(a.session):s.create(a.sessionFile)}class u{constructor(a){this.readRecord=a,this.sharedByTaskId=new Map,this.operationTail=Promise.resolve(),this.disposed=!1}watch(a,b){return this.enqueue(()=>this.watchInternal(a,b))}taskChanged(a){this.enqueue(async()=>{let b=this.sharedByTaskId.get(a);if(!b)return;let c=this.readRecord(a);if(!c){o(b.listeners,{type:"unavailable"},a),this.disposeShared(a,b);return}n(c.detailSource)!==b.sourceIdentity?await this.replaceShared(a,b,c):b.canInterrupt!==c.canInterrupt&&(b.canInterrupt=c.canInterrupt,o(b.listeners,{type:"snapshot",snapshot:this.snapshot(a,b)},a))})}async readMessage(a,b){let c=this.readRecord(a);if(!c)throw new v(a);let d=c.detailSource;if(d?.kind!=="pi-conversation")throw new w(a);if(void 0!==d.session){let a=(0,h.xm)(d.session.sessionManager.getBranch()),c=a.findIndex(a=>a.entryId===b);if(c<0)throw new x(b);return{index:c,entry:a[c]}}let e=await (0,j.uS)(d.sessionFile,b),f=e.snapshot.entries.findIndex(a=>a.entryId===b);if(f<0)throw new x(b);return{index:f,entry:e.projected}}async readImage(a,b,c){if(!Number.isSafeInteger(c)||c<0)throw Error("图片位置无效");let d=this.readRecord(a);if(!d)throw new v(a);let e=d.detailSource;if(e?.kind!=="pi-conversation")throw new w(a);if(void 0===e.session)return(0,j.tE)(e.sessionFile,b,c);if(!e.session.sessionManager.getBranch().some(a=>a.id===b))throw new x(b);let f=e.session.sessionManager.getEntry(b);if(f?.type!=="message"||"user"!==f.message.role&&"toolResult"!==f.message.role)throw new x(b);let g=(0,h.Wl)(f.message.content,c);if(!g)throw new x(`${b}/${c}`);return g}dispose(){if(!this.disposed){for(let[a,b]of(this.disposed=!0,this.sharedByTaskId))this.disposeShared(a,b);this.sharedByTaskId.clear()}}async watchInternal(a,b){if(this.disposed)throw Error("Task detail pool has been disposed");let c=this.readRecord(a);if(!c)throw new v(a);let d=this.sharedByTaskId.get(a),e=n(c.detailSource);if(!d||d.sourceIdentity!==e){d?.unsubscribeSource(),d?.sourceRuntime.dispose();let b=await p(c.detailSource);if(this.disposed)throw b.dispose(),Error("Task detail pool was disposed during initialization");(d={sourceRuntime:b,sourceIdentity:e,canInterrupt:c.canInterrupt,listeners:new Set,unsubscribeSource:()=>void 0}).unsubscribeSource=b.subscribe(b=>this.handleSourceEvent(a,d,b)),this.sharedByTaskId.set(a,d)}d.canInterrupt=c.canInterrupt,d.listeners.add(b);let f=!1;return{snapshot:this.snapshot(a,d),readSnapshot:()=>this.snapshot(a,d),release:()=>{f||(f=!0,this.release(a,d,b))}}}enqueue(a){let b=this.operationTail.then(a,a);return this.operationTail=b.then(()=>void 0,()=>void 0),b}snapshot(a,b){return{taskId:a,canInterrupt:b.canInterrupt,body:b.sourceRuntime.snapshot()}}handleSourceEvent(a,b,c){if(this.sharedByTaskId.get(a)===b){if("snapshot"===c.type)return void o(b.listeners,{type:"snapshot",snapshot:this.snapshot(a,b)},a);o(b.listeners,c,a)}}release(a,b,c){this.sharedByTaskId.get(a)===b&&(b.listeners.delete(c),0===b.listeners.size&&this.disposeShared(a,b))}disposeShared(a,b){this.sharedByTaskId.get(a)===b&&this.sharedByTaskId.delete(a),b.unsubscribeSource(),b.sourceRuntime.dispose(),b.listeners.clear()}async replaceShared(a,b,c){try{let d=await p(c.detailSource);if(this.sharedByTaskId.get(a)!==b)return void d.dispose();b.unsubscribeSource(),b.sourceRuntime.dispose(),b.sourceRuntime=d,b.sourceIdentity=n(c.detailSource),b.canInterrupt=c.canInterrupt,b.unsubscribeSource=d.subscribe(c=>this.handleSourceEvent(a,b,c)),o(b.listeners,{type:"snapshot",snapshot:this.snapshot(a,b)},a)}catch(c){console.warn("[Pi Desk][TaskDetailPool] 替换详情来源失败",{taskId:a,errorName:c instanceof Error?c.name:"UnknownError"}),o(b.listeners,{type:"unavailable"},a),this.disposeShared(a,b)}}}class v extends Error{constructor(a){super(`Task detail was not found: ${a}`),this.name="L4PiTaskDetailNotFoundError"}}class w extends Error{constructor(a){super(`Task does not provide conversation detail: ${a}`),this.name="L4PiTaskDetailUnsupportedError"}}class x extends Error{constructor(a){super(`Task conversation message was not found: ${a}`),this.name="L4PiTaskMessageNotFoundError"}}d()}catch(a){d(a)}})}};
|