@jetcrab/pi-desk 1.1.18-dev → 1.1.21
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 +82 -2
- package/next.config.ts +1 -0
- package/package.json +4 -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-file-workspace-runtime.ts +1 -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-reload.ts +42 -0
- 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 +38 -9
- package/src/client/l2_biz/workbench/l2-workbench-chat-composer.tsx +12 -1
- package/src/client/l2_biz/workbench/l2-workbench-chat.ts +45 -0
- 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 +19 -2
- package/src/client/l3_modules/conversation/l3-conversation-markdown.tsx +10 -1
- 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-markdown-preview.tsx +10 -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 +6 -1
- package/src/client/l3_modules/project-files/l3-project-file-browser.tsx +171 -229
- package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +133 -70
- package/src/client/l3_modules/project-files/l3-project-reader.ts +26 -37
- package/src/client/l3_modules/project-files/views/l3-project-search-controls.tsx +201 -0
- package/src/client/l3_modules/project-files/views/l3-project-search-results.tsx +333 -0
- 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/client/l4_foundation/ui/code/l4-code-preview.tsx +47 -3
- package/src/client/l4_foundation/ui/markdown/l4-markdown-remark.ts +89 -0
- package/src/client/l4_foundation/ui/markdown/l4-markdown.module.css +58 -0
- package/src/client/l4_foundation/ui/markdown/l4-markdown.tsx +108 -0
- 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/work-session/l2-work-session-file-contract.ts +4 -3
- package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +8 -0
- package/src/common/l3_modules/project-files/l3-project-files-contract.ts +2 -3
- package/src/common/l3_modules/project-files/l3-project-files-locale-messages.ts +56 -10
- package/src/common/l4_foundation/file/l4-project-file-contract.ts +51 -1
- package/src/common/l4_foundation/locale/l4-host-error-messages.ts +11 -0
- package/src/common/l4_foundation/locale/l4-locale-messages.ts +16 -0
- package/src/instrumentation.ts +0 -2
- package/src/server/l1_entry/api/l1-project-read-routes.ts +6 -4
- package/src/server/l1_entry/api/l1-project-route.ts +9 -8
- package/src/server/l1_entry/api/l1-work-session-file-error.ts +23 -0
- package/src/server/l1_entry/node/l1-server.ts +8 -4
- package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +0 -3
- package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +30 -58
- package/src/server/l2_biz/work-session/l2-work-session-manage.ts +0 -4
- package/src/server/l4_foundation/file/l4-project-file-index.ts +276 -0
- package/src/server/l4_foundation/file/l4-project-search.ts +399 -0
- package/src/server/l4_foundation/file/l4-ripgrep-search.ts +192 -0
- package/src/server/l4_foundation/file/l4-work-session-project-file.ts +8 -332
- 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-package-maintenance.ts +0 -6
- package/src/server/l4_foundation/pi/l4-pi-plugin-capability-probe.ts +1 -3
- package/src/server/l4_foundation/pi/l4-pi-plugin-owner-runtime.ts +133 -13
- package/src/server/l4_foundation/pi/l4-pi-plugin-probe.ts +1 -3
- package/src/server/l4_foundation/pi/l4-pi-runner-process.ts +2 -2
- package/src/server/l4_foundation/pi/l4-pi-session-initialization.ts +9 -0
- package/src/server/l4_foundation/process/l4-process-tree.js +23 -4
- 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/prerender-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 +4 -3
- package/temp/build/pi-desk/release/.next/required-server-files.json +4 -3
- 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 +2 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +2 -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 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +2 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +2 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +2 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +2 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +2 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +2 -1
- 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 +72 -72
- 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/23054.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/25406.js +10 -10
- 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/50520.js +2 -4
- package/temp/build/pi-desk/release/.next/server/chunks/56830.js +235 -0
- package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/70780.js +1 -0
- package/temp/build/pi-desk/release/.next/server/chunks/74528.js +1 -1
- 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/instrumentation.js +1 -1
- 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/server/server-reference-manifest.json +1 -1
- package/temp/build/pi-desk/release/.next/static/8Yd33M0zPi4tbRn4xCaRY/_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/{49516-cc4dcd84d64ab4fe.js → 51474-8dc714cb76b2e60a.js} +2 -2
- 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-6ebc1c877f6025dd.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/1e780a4936aa6ba3.css +1 -0
- package/temp/build/pi-desk/release/.next/static/css/6dbae2922f88ca31.css +1 -0
- 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/33658.js +0 -296
- package/temp/build/pi-desk/release/.next/server/chunks/8584.js +0 -2
- package/temp/build/pi-desk/release/.next/static/chunks/31087-ba426d09d6f68bfd.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/39654-b5fedd762ea0312e.js +0 -238
- 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/75130-d2ca74894aff8085.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-c0e1c5cef8620cf8.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-a984139e99586041.js +0 -158
- package/temp/build/pi-desk/release/.next/static/chunks/webpack-40a782fc8a3535b9.js +0 -1
- package/temp/build/pi-desk/release/.next/static/css/6427d02b6edf406f.css +0 -1
- package/temp/build/pi-desk/release/.next/static/css/79e06f05df9edff0.css +0 -1
- package/temp/build/pi-desk/release/.next/static/n2LrXQgq8UkbH_AzhR3fw/_buildManifest.js +0 -1
- /package/temp/build/pi-desk/release/.next/static/{n2LrXQgq8UkbH_AzhR3fw → 8Yd33M0zPi4tbRn4xCaRY}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
"use strict";exports.id=50520,exports.ids=[50520],exports.modules={621:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{JM:()=>k,w$:()=>m});var e=c(51455),f=c(76760),g=c(38522),h=c(57975);c(77598);var i=c(73159),j=a([i]);function k(a){return a&&"object"==typeof a&&!Array.isArray(a)?a:{}}async function l(a,b){let c;if(!(c=b.replaceAll("\\","/").replace(/^\.\//,""))||(0,f.isAbsolute)(b)||f.win32.isAbsolute(b)||c.includes("\0")||c.split("/").some(a=>".."===a)||!c)return null;try{let c=await (0,e.realpath)((0,f.resolve)(a,b)),d=(0,f.relative)(a,c);if((0,f.isAbsolute)(d)||".."===d||d.startsWith(`..${"win32"===process.platform?"\\":"/"}`))return null;let g=await (0,e.open)(c,"r");try{let a=await g.stat();if(!a.isFile()||a.size>65536)return null;let b=Buffer.alloc(65537),c=0;for(;c<b.length;){let{bytesRead:a}=await g.read(b,c,b.length-c,c);if(!a)break;c+=a}return c<=65536?b.subarray(0,c).toString("utf8"):null}finally{await g.close()}}catch(a){if(["ENOENT","ENOTDIR"].includes(a.code??""))return null;throw a}}async function m(a){let b,c=await (0,e.realpath)(a),d=await l(c,"package.json"),f=d?k(JSON.parse(d)):{},g={};for(let[a,d]of(b=k(k(f.piDesk).i18n),Object.entries(b).slice(0,16).flatMap(([a,b])=>{let c=k(b).readme;return a.length>0&&a.length<=35&&"string"==typeof c&&c.length<=1024?[[a,c]]:[]}))){let b=await l(c,d);null!==b&&(g[a]=b)}var h=await l(c,"README.md");if(null===h&&!Object.keys(g).length)return null;let i=h??Object.values(g)[0];return Object.keys(g).length?{default:i,translations:g}:i}i=(j.then?(await j)():j)[0],(0,h.promisify)(g.gunzip),d()}catch(a){d(a)}})},2472:(a,b,c)=>{c.d(b,{i:()=>i});var d=c(31421),e=c(76760),f=c(73136);let{createRequire:g}=process.getBuiltinModule("module"),h=g((0,e.join)(process.cwd(),"package.json"))("./src/server/l4_foundation/process/l4-process-tree.js");function i(a){return new Promise((b,c)=>{if(a.signal?.aborted)return void c(Error("操作已取消"));let g=(0,f.pathToFileURL)((0,e.join)(process.cwd(),"src/server/l4_foundation/pi/l4-pi-runtime-register.mjs")).href,i=(0,d.spawn)(process.execPath,["--import",g,...a.args],{cwd:process.cwd(),env:{...process.env,PI_CODING_AGENT_DIR:a.agentDir,PI_CODING_AGENT_SESSION_DIR:(0,e.join)(a.agentDir,"sessions"),TSX_TSCONFIG_PATH:(0,e.join)(process.cwd(),"tsconfig.json"),...a.env},stdio:["ignore","pipe","pipe"],windowsHide:!0,detached:"win32"!==process.platform}),j="",k="",l=!1,m=null,n=b=>{!l&&(l=!0,m&&clearTimeout(m),a.signal?.removeEventListener("abort",o),h.terminateManagedTree(i).then(b,
|
|
1
|
+
"use strict";exports.id=50520,exports.ids=[50520],exports.modules={621:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{JM:()=>k,w$:()=>m});var e=c(51455),f=c(76760),g=c(38522),h=c(57975);c(77598);var i=c(73159),j=a([i]);function k(a){return a&&"object"==typeof a&&!Array.isArray(a)?a:{}}async function l(a,b){let c;if(!(c=b.replaceAll("\\","/").replace(/^\.\//,""))||(0,f.isAbsolute)(b)||f.win32.isAbsolute(b)||c.includes("\0")||c.split("/").some(a=>".."===a)||!c)return null;try{let c=await (0,e.realpath)((0,f.resolve)(a,b)),d=(0,f.relative)(a,c);if((0,f.isAbsolute)(d)||".."===d||d.startsWith(`..${"win32"===process.platform?"\\":"/"}`))return null;let g=await (0,e.open)(c,"r");try{let a=await g.stat();if(!a.isFile()||a.size>65536)return null;let b=Buffer.alloc(65537),c=0;for(;c<b.length;){let{bytesRead:a}=await g.read(b,c,b.length-c,c);if(!a)break;c+=a}return c<=65536?b.subarray(0,c).toString("utf8"):null}finally{await g.close()}}catch(a){if(["ENOENT","ENOTDIR"].includes(a.code??""))return null;throw a}}async function m(a){let b,c=await (0,e.realpath)(a),d=await l(c,"package.json"),f=d?k(JSON.parse(d)):{},g={};for(let[a,d]of(b=k(k(f.piDesk).i18n),Object.entries(b).slice(0,16).flatMap(([a,b])=>{let c=k(b).readme;return a.length>0&&a.length<=35&&"string"==typeof c&&c.length<=1024?[[a,c]]:[]}))){let b=await l(c,d);null!==b&&(g[a]=b)}var h=await l(c,"README.md");if(null===h&&!Object.keys(g).length)return null;let i=h??Object.values(g)[0];return Object.keys(g).length?{default:i,translations:g}:i}i=(j.then?(await j)():j)[0],(0,h.promisify)(g.gunzip),d()}catch(a){d(a)}})},2472:(a,b,c)=>{c.d(b,{i:()=>i});var d=c(31421),e=c(76760),f=c(73136);let{createRequire:g}=process.getBuiltinModule("module"),h=g((0,e.join)(process.cwd(),"package.json"))("./src/server/l4_foundation/process/l4-process-tree.js");function i(a){return new Promise((b,c)=>{if(a.signal?.aborted)return void c(Error("操作已取消"));let g=(0,f.pathToFileURL)((0,e.join)(process.cwd(),"src/server/l4_foundation/pi/l4-pi-runtime-register.mjs")).href,i=(0,d.spawn)(process.execPath,["--import",g,...a.args],{cwd:process.cwd(),env:{...process.env,PI_CODING_AGENT_DIR:a.agentDir,PI_CODING_AGENT_SESSION_DIR:(0,e.join)(a.agentDir,"sessions"),TSX_TSCONFIG_PATH:(0,e.join)(process.cwd(),"tsconfig.json"),...a.env},stdio:["ignore","pipe","pipe"],windowsHide:!0,detached:"win32"!==process.platform}),j="",k="",l=!1,m=null,n=b=>{!l&&(l=!0,m&&clearTimeout(m),a.signal?.removeEventListener("abort",o),h.terminateManagedTree(i).then(b,a=>{let c=a instanceof Error?a:Error(String(a));console.error("[Pi Desk][Runner] 子进程清理未完成",{pid:i.pid,exitCode:i.exitCode,reason:c.message}),b()}))},o=()=>n(()=>c(Error("操作已取消"))),p=(b,c)=>`${b}${c.toString("utf8")}`.slice(-a.maxOutputBytes);i.stdout.on("data",a=>{j=p(j,a)}),i.stderr.on("data",a=>{k=p(k,a)}),i.once("error",a=>n(()=>c(a))),i.once("close",a=>n(()=>b({stdout:j,stderr:k,code:a}))),(m=setTimeout(()=>{let b=a.timeoutError(),d=`${k}
|
|
2
2
|
${j}`.trim().slice(-4e3);d&&(b.message+=`
|
|
3
3
|
${d}`),n(()=>c(b))},a.timeoutMs)).unref(),a.signal?.addEventListener("abort",o,{once:!0}),a.signal?.aborted&&o()})}},17691:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{M:()=>j});var e=c(77598),f=c(73024),g=c(76760),h=c(75430),i=a([h]);function j(){let a=(0,h.getAgentDir)(),b=(0,g.join)(a,"pi-desk"),c=(0,g.join)(a,"pi-super");if((0,f.existsSync)(b)||!(0,f.existsSync)(c))return b;let d=(0,g.join)(a,`.pi-desk-migration-${(0,e.randomUUID)()}`);try{(0,f.cpSync)(c,d,{recursive:!0,errorOnExist:!0,force:!1}),(0,f.renameSync)(d,b),console.info("[Pi Desk] 已复制旧版应用数据到新目录")}finally{(0,f.rmSync)(d,{recursive:!0,force:!0})}return b}h=(i.then?(await i)():i)[0],d()}catch(a){d(a)}})},20700:(a,b,c)=>{function d(){return globalThis.__piDeskRestartHandler??null}function e(){return null!==d()}function f(a,b){let c=d();if(!c)throw Error("当前启动方式不支持自动重启 Pi Desk");setTimeout(()=>c(a,b),150).unref()}c.d(b,{Z:()=>f,k:()=>e})},33290:(a,b,c)=>{function d(){return globalThis.__piDeskNativePluginDiagnostics||(globalThis.__piDeskNativePluginDiagnostics=[]),globalThis.__piDeskNativePluginDiagnostics}function e(a,b){let c=d();!c.some(c=>c.cwd===a&&c.message===b)&&(c.push({cwd:a,message:b}),c.length>100&&c.splice(0,c.length-100))}function f(a){let b=a=>{let b=a.replaceAll("\\","/");return"win32"===process.platform?b.toLowerCase():b},c=b(a).replace(/\/$/,""),e=d();for(let a=e.length-1;a>=0;a-=1){let d=b(e[a].message);(d.includes(`${c}:`)||d.includes(`${c}/`))&&e.splice(a,1)}}function g(){return d().map(a=>({...a}))}c.d(b,{pL:()=>e,tt:()=>f,u7:()=>g})},34458:(a,b,c)=>{c.a(a,async(a,d)=>{try{let r;c.d(b,{dz:()=>o,qX:()=>n,w$:()=>i.w$});var e=c(4287),f=c(5235),g=c(64253),h=c(73159),i=c(621),j=a([f,g,h,i]);function k(a){return new URL(e.SZ.parse(a)).href.replace(/\/+$/,"")}function l(a,b,c){return new URL(`${k(a)}/${encodeURIComponent(b)}${c?`/${encodeURIComponent(c)}`:""}`)}function m(a,b){let c=(0,i.JM)(a.versions),d=(0,i.JM)(a["dist-tags"]),e="string"==typeof d[b]?d[b]:b.replace(/^v(?=\d+\.)/,"");if("string"!=typeof e||!Object.hasOwn(c,e))throw new h.XH("插件源不存在指定版本或标签",404,"missing");if(!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(e))throw new h.XH("插件源返回的版本无效");return e}async function n(a,b){let c=(0,f.to)(b.agentDir),d=b.downloadSource??c.downloadSource;if("local"===d.mode){let c=await (0,g.B)(b.agentDir),d=a.startsWith("@")?c[`${a.split("/")[0]}:registry`]:void 0;return{registry:k(d||c.registry||f.Nx),fallback:!1}}if(b.registry){let a=k(b.registry);if(![f.Nx,f.sv].includes(a))return{registry:a,fallback:!1}}let e=c.registries[`npm:${a}`];if(e)return{registry:k(e),fallback:!1};if(a.startsWith("@")){let c=(await (0,g.B)(b.agentDir))[`${a.split("/")[0]}:registry`];if(c){let a=k(c);if(![f.Nx,f.sv].includes(a))return{registry:a,fallback:!1}}}return"custom"===d.mode?{registry:k(d.registry),fallback:!1}:"official"===d.mode?{registry:f.Nx,fallback:!1}:"domestic"===d.mode?{registry:f.sv,fallback:!1}:{registry:await function(){if(!r||r.expires<=Date.now()){let a=(async()=>{try{let a=await (0,h.NL)(new URL("https://ipwho.is/?fields=success,country_code"),{limit:1024,timeout:3e3,cache:!1,auth:!1}),b=(0,i.JM)(JSON.parse(a.toString("utf8")));if(!0!==b.success)throw Error("出口地区检测失败");return"CN"===b.country_code?f.sv:f.Nx}catch{return r&&(r.expires=Date.now()+6e4),f.Nx}})();r={expires:Date.now()+18e5,value:a}}return r.value}(),fallback:!0}}async function o(a,b={}){let c;if(!a.startsWith("npm:"))return{source:a};let d=/^npm:((?:@[^/]+\/)?[^@]+)(?:@([^@]+))?$/.exec(a);if(!d)throw new h.XH("npm 插件来源无效",400);let e=d[1];if(e.length>214||!/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*$/i.test(e))throw new h.XH("npm 插件包名无效",400);let g=d[2]??"latest";if(g.length>128||!/^[a-zA-Z0-9._+-]+$/.test(g))throw new h.XH("npm 插件版本或标签无效",400);let j=b.downloadSource??(0,f.to)(b.agentDir).downloadSource,k=await n(e,{...b,downloadSource:j}),r=k.registry,s=g;try{let a=await p(l(r,e),b),d=(0,i.JM)(a["dist-tags"])[g];"string"==typeof d&&(s=d),c=m(a,s),q((0,i.JM)(a.versions)[c],e,c)}catch(d){if(!k.fallback||r===f.Nx||!(d instanceof h.XH)||!["network","missing"].includes(d.reason))throw d;console.warn("[Pi Desk][PluginRegistry] 自动下载源不可用,回退 npm 官方源",{name:e,reason:d.reason}),r=f.Nx;let a=await p(l(r,e),b);c=m(a,s),q((0,i.JM)(a.versions)[c],e,c)}return{source:`npm:${e}@${c}`,..."local"===j.mode?{}:{registry:r}}}async function p(a,b){if(!1!==b.cache)return(0,h.Yq)(a,b.signal,b.agentDir);let c=await (0,h.NL)(a,{limit:8388608,signal:b.signal,cache:!1,agentDir:b.agentDir});try{let a=JSON.parse(c.toString("utf8"));if(!a||"object"!=typeof a||Array.isArray(a))throw Error("invalid");return a}catch{throw new h.XH("插件源返回的元数据格式无效")}}function q(a,b,c){let d=(0,i.JM)(a);if(d.name!==b||"string"!=typeof d.version||c&&d.version!==c)throw new h.XH("插件源返回的包名或版本不匹配");return d}[f,g,h,i]=j.then?(await j)():j,d()}catch(a){d(a)}})},47154:(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}},50520:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{L2PluginManagement:()=>P,L2PluginManagementInvalidPackageError:()=>L,L2PluginManagementNotFoundError:()=>J,L2PluginManagementOperationConflictError:()=>K,L2PluginManagementPackageRootError:()=>M,L2PluginManagementRestartPendingError:()=>N,L2PluginManagementRestartUnavailableError:()=>O,disposeL2PluginManagement:()=>G,getL2PluginManagement:()=>I,initializeL2PluginManagement:()=>H});var e=c(16056),f=c(17691),g=c(76019),h=c(77598),i=c(51455),j=c(76760),k=c(75430),l=c(93951),m=c(4287),n=c(34458),o=c(5235),p=c(36361),q=c(69371),r=c(75157),s=c(47154),t=c(60719),u=c(33290),v=c(53584),w=c(96783),x=c(20700),y=c(78597),z=a([f,k,n,o,p,t,y]);[f,k,n,o,p,t,y]=z.then?(await z)():z;class J extends Error{constructor(a){super(`插件不存在:${a}`),this.source=a,this.name="L2PluginManagementNotFoundError"}}class K extends Error{constructor(a){super(a),this.name="L2PluginManagementOperationConflictError"}}class L extends Error{constructor(a){super(a),this.name="L2PluginManagementInvalidPackageError"}}class M extends Error{constructor(a){super(a.message),this.rootError=a,this.name="L2PluginManagementPackageRootError"}}class N extends Error{constructor(){super("已有插件操作需要重启完成"),this.name="L2PluginManagementRestartPendingError"}}class O extends Error{constructor(){super("当前启动方式不支持自动重启 Pi Desk"),this.name="L2PluginManagementRestartUnavailableError"}}function A(a,b,c){let d=(0,j.resolve)(a,b),e=(0,j.relative)(a,d);if(e.startsWith("..")||(0,j.isAbsolute)(e))throw Error(`${c} 必须位于插件包目录内`);return d}async function B(a){try{return(await (0,i.stat)(a)).isFile()}catch{return!1}}function C(a){return a instanceof Error&&a.message?a.message:String(a)}async function D(a){let b;if((await (0,i.stat)(a)).isFile())return{version:null,error:null};try{b=JSON.parse(await (0,i.readFile)((0,j.join)(a,"package.json"),"utf8"))}catch(a){if(a&&"object"==typeof a&&"code"in a&&"ENOENT"===a.code)return{version:null,error:null};return{version:null,error:{phase:"package",message:C(a)}}}let c="string"==typeof b.version&&b.version.trim()?b.version.trim():null;try{let d=b.piDesk?.entry??b.piDesk?.global;if(void 0!==d){if("string"!=typeof d||!d.trim())throw Error("piDesk.entry 必须是非空字符串");let b=A(a,d,"piDesk.entry");if(!await B(b))throw Error("Pi Desk Entry 文件不存在")}let e=b.pi?.extensions;if(void 0!==e&&!Array.isArray(e))throw Error("pi.extensions 必须是数组");for(let b of e??[]){if("string"!=typeof b||!b.trim())throw Error("pi.extensions 只允许非空字符串");if(/[*?[\]{}]/.test(b))continue;let c=A(a,b,"pi.extensions");if(!await B(c))throw Error(`Native Extension 文件不存在:${b}`)}return{version:c,error:null}}catch(a){return{version:c,error:{phase:"entry",message:C(a)}}}}async function E(a,b){let[c,d]=await Promise.all([(0,i.realpath)(a),(0,i.realpath)(b)]),e=(0,j.relative)(c,d);if(e.startsWith("..")||(0,j.isAbsolute)(e))throw Error("插件能力资源必须位于 Package 目录内");let f=await (0,i.open)(d,"r");try{let a=Buffer.alloc(65537),{bytesRead:b}=await f.read(a,0,a.length,0);return{content:a.subarray(0,Math.min(b,65536)).toString("utf8"),truncated:b>65536}}finally{await f.close()}}function F(a,b,c){return{error:function(a){if(!a)return null;if(a.length<=32768)return a;let b=a.slice(0,32752);return(0,g.J8)(`${b}
|
|
4
4
|
…(已截断)`,`${b}
|
|
5
|
-
… (truncated)`)}(a?.error??c),extensions:a?.extensions??[],tools:a?.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,promptSnippet:a.promptSnippet,promptGuidelineCount:a.promptGuidelineCount,promptGuidelinePreview:a.promptGuidelinePreview}))??[],skills:a?.skills.map(a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible}))??[],prompts:a?.prompts.map(a=>({name:a.name,description:a.description,path:a.path}))??[],themes:a?.themes??[],providers:a?.providers??[],piDesk:{methods:b?[...b.methods]:[],browserEntries:b?[...b.browserEntries]:[],messageDeclarations:b?[...b.messageDeclarations]:[]}}}class P{get restartRequired(){return this.deferredMaintenance.size>0}constructor(a,b=process.cwd(),c=(0,k.getAgentDir)()){this.workSessions=a,this.cwd=b,this.agentDir=c,this.operationTail=Promise.resolve(),this.operations=new Map,this.listeners=new Set,this.lifetime=new AbortController,this.disposed=!1,this.activeSource=null,this.sourceCache=null,this.capabilityCache=null,this.deferredMaintenance=new Map;const d=(0,h.createHash)("sha256").update(this.agentDir).digest("hex").slice(0,16);this.stagingRoot=(0,j.join)(this.cwd,"temp","pi",`plugin-management-${d}`),this.packageManagerCwd=(0,j.join)((0,f.M)(),"plugin-package-manager"),this.updates=new y.E(this.agentDir,this.packageManagerCwd,this.lifetime.signal),this.maintenanceError=process.env.PI_DESK_PLUGIN_MAINTENANCE_ERROR?.trim()||null,this.unsubscribeRuntime=(0,p.getL4PiGlobalPluginRuntime)().subscribeChanges(()=>this.publish()),this.staleStagingCleanup=(0,i.rm)(this.stagingRoot,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理上次中断的候选目录失败",{path:this.stagingRoot,errorName:a instanceof Error?a.name:"UnknownError"})})}list(a=!1){return this.assertOpen(),this.readSnapshot(a)}async batch(a){this.assertOpen();let b=[],c=new Set,d="add"===a.action||"update"===a.action?await this.readSources():null,e=[];for(let f of"add"===a.action?a.items:a.sources.map(a=>({source:a})))try{let g="add"===a.action?this.normalizeAddedSource(f.source):f.source,h=(0,m.LD)(g);if(c.has(h))throw new K("批量请求中包含重复来源");if(c.add(h),"add"===a.action){let{source:a,...b}=f;e.push(this.acceptMutation("add",g,d,!0,void 0,b))}else"update"===a.action?e.push(this.acceptMutation("update",g,d)):"del"===a.action?await this.del(g):await this.setUpdateTag(g,a.tag);b.push({source:f.source,error:null})}catch(a){b.push({source:f.source,error:C(a).slice(0,4e3)})}return e.length>0&&this.enqueueMutations(e),{snapshot:await this.readSnapshot(!1),results:b}}subscribe(a){return this.assertOpen(),this.listeners.add(a),()=>this.listeners.delete(a)}get(a){return this.assertOpen(),this.readDetail(a)}add(a,b={}){return this.mutate("add",this.normalizeAddedSource(a),!1,void 0,b)}setEnabled(a,b){return this.mutate(b?"enable":"disable",a)}async update(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");this.assertSourceIdle(a);let b=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!b)throw new J(a);if((0,m.ug)(b.source)){let a=await this.readSnapshot({checkUpdates:!0,sources:[b.source]}),c=a.plugins.find(a=>a.source===b.source);if(c.updateError)throw new L(c.updateError);if(!0!==c.updateAvailable)return a}return this.mutate("update",b.source)}reinstall(a,b,c={}){return this.mutate("add",this.normalizeAddedSource(a),!0,b,c)}async setUpdateTag(a,b){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");let c=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!c)throw new J(a);if("package"!==c.kind||!(0,m.ug)(c.source))throw new L("只有 npm 插件包支持更新渠道");this.assertSourceIdle(c.source),(0,o.ks)(c.source,m.mR.parse(b),this.agentDir),this.updates.clear(c.source),this.publish()}assertSourceIdle(a){let b=(0,m.LD)(a);if(this.activeSource&&(0,m.LD)(this.activeSource)===b||[...this.operations].some(([a,c])=>(0,m.LD)(a)===b&&"failed"!==c.phase))throw new K("该来源已有未完成的维护操作")}waitForOperations(a,b){return b=AbortSignal.any([b,this.lifetime.signal]),new Promise((c,d)=>{let e=()=>void 0,f=a=>{e(),b.removeEventListener("abort",g),a?d(a):c()},g=()=>f(Error(this.disposed?"插件管理已关闭":"发起命令的会话已关闭")),h=()=>{if(this.disposed)return f(Error("插件管理已关闭"));for(let b of a){let a=this.operations.get(b);if(a?.phase==="failed")return f(Error(a.message??"插件操作失败"));if(a?.phase==="waiting"&&this.activeSource!==b&&this.restartRequired)return f(Error(`插件尚未生效,需要在设置的插件管理中重启 Pi Desk。${a.message??""}`))}a.some(a=>this.operations.has(a)||this.activeSource===a)||f()};if(b.aborted)return g();e=this.subscribe(h),b.addEventListener("abort",g,{once:!0}),h()})}del(a){return this.mutate("del",a)}async apply(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不加载外部插件");if(a?.some(a=>this.deferredMaintenance.has(a)))throw new N;let b=await (0,p.getL4PiGlobalPluginRuntime)().scanSourceChanges(a);this.assertOpen();let c=b.filter(b=>{if(this.deferredMaintenance.has(b.source))return!1;let c=this.operations.get(b.source);if(!c||"failed"===c.phase)return!0;if(a)throw new K("该来源已有未完成操作");return!1}),d=new Set([...this.operations].filter(([,a])=>"failed"!==a.phase).map(([a])=>a));for(let a of c)d.add(a.source);if(d.size>32)throw new K("加载变更超过队列上限,请选择部分来源");for(let a of c){if(!this.operations.has(a.source)&&this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}this.operations.set(a.source,{action:"apply",phase:"queued",message:null}),this.enqueueApply(a)}return this.publish(),this.readSnapshot(!1)}enqueueApply(a){this.runExclusive(async()=>{this.activeSource=a.source;try{this.setOperation(a.source,"checking",null),await this.probeSourceChange(a),this.assertOpen(),this.setOperation(a.source,"applying",null),await (0,p.getL4PiGlobalPluginRuntime)().applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path),this.capabilityCache=null,this.workSessions.refreshPluginMessages(),this.operations.delete(a.source)}catch(b){this.setOperation(a.source,"failed",C(b))}finally{this.activeSource=null,this.sourceCache=null,this.publish()}}).catch(b=>{this.disposed||this.setOperation(a.source,"failed",C(b))})}async probeSourceChange(a){let b=a.current;if(!b||!b.enabled)return;if(b.error)throw new L(b.error);if(!b.path)throw new L("插件来源目录不存在");let c=performance.now();console.info("[Pi Desk][PluginManagement] 源码候选预检开始",{source:a.source});let d=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),e=(0,j.join)(d,"agent"),f=(0,j.join)(d,"workspace");await (0,i.mkdir)(e,{recursive:!0}),await (0,i.mkdir)(f,{recursive:!0});try{if(await (0,i.writeFile)((0,j.join)(e,"settings.json"),JSON.stringify({extensions:[b.path]}),"utf8"),b.piDeskRoot||b.nativePaths.length>0){let c=await (0,w.Y)(f,e,b.nativePaths.length>0),d=c.loadError??c.packages.find(a=>"failed"===a.status)?.error?.message;if(d)throw new L(d);if(b.piDeskRoot&&!c.packages.some(a=>"ready"===a.status))throw new L("预检未加载到候选 Node Entry,放弃本次变更");for(let b of c.packages)if(b.pluginName&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==a.source&&"ready"===c.status&&c.pluginName===b.pluginName))throw new L(`插件名冲突:${b.pluginName}`)}this.assertOpen()}finally{await (0,i.rm)(d,{recursive:!0,force:!0}),console.info("[Pi Desk][PluginManagement] 源码候选预检结束",{source:a.source,durationMs:Math.round(performance.now()-c)})}}reload(a){return this.activeSource||[...this.operations].some(([a,b])=>"failed"!==b.phase&&!this.deferredMaintenance.has(a))?Promise.reject(new K("维护仍在执行或等待,请先完成当前操作")):this.runExclusive(async()=>(this.assertRestartAvailable(),this.restartWhenQuiet(a)))}async mutate(a,b,c=!1,d,e={}){this.assertOpen();let f=await this.readSources(),g=this.acceptMutation(a,b,f,c,d,e);return this.enqueueMutations([g]),this.readSnapshot(!1)}acceptMutation(a,b,c,d=!1,f,g={}){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护,请通过基础聊天修复或正常启动后维护");let h=c.sources.find(a=>(0,m.LD)(a.source)===(0,m.LD)(b));if("add"!==a){if(!h)throw new J(b);if("package"!==h.kind&&"enable"!==a&&"disable"!==a)throw new L("裸扩展不是已安装包,请编辑源码后加载变更;此操作不会删除源码")}let i=(f??=h?.source)??b;if(g.tag&&!(0,m.ug)(b))throw new L("只有 npm 插件包支持更新渠道");for(let a of[b,i])this.assertSourceIdle(a);if([...this.operations.values()].filter(a=>"failed"!==a.phase).length>=32)throw new K("插件维护队列已满,请等待当前操作完成");if(this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}return f&&f!==b&&this.operations.get(f)?.phase==="failed"&&this.operations.delete(f),this.operations.set(i,{action:a,phase:"queued",message:null}),this.updates.clear(i),this.updates.clear(b),{mutation:a,source:b,operationSource:i,reinstall:d,options:g}}enqueueMutations(a){this.runExclusive(async()=>{let b=performance.now(),c=await Promise.all(a.map(async a=>{try{let b=await this.prepareMutation(a);return this.assertOpen(),this.setOperation(a.operationSource,"queued","候选检查完成,等待应用"),{input:a,prepared:b}}catch(b){return this.setOperation(a.operationSource,"failed",C(b)),null}}));for(let d of(a.length>1&&console.info("[Pi Desk][PluginManagement] 批量并行准备收尾",{count:a.length,failedCount:c.filter(a=>null===a).length,durationMs:Math.round(performance.now()-b)}),c)){if(!d)continue;let{input:a,prepared:b}=d,{source:c,operationSource:e}=a;this.activeSource=e;try{this.assertOpen(),b&&await this.executeMutation(a,b),this.deferredMaintenance.has(e)||this.operations.delete(e)}catch(a){this.setOperation(e,"failed",C(a))}finally{this.updates.clear(e),this.updates.clear(c),this.sourceCache=null,this.activeSource=null,this.publish()}}}).catch(b=>{if(!this.disposed)for(let c of a)this.setOperation(c.operationSource,"failed",C(b))}),this.publish()}async prepareMutation(a){let{mutation:b,source:c,operationSource:d,reinstall:e,options:f}=a;this.assertOpen();let g=this.createPackageManager();this.throwSettingsErrors(g.settingsManager);let h=g.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),i=h.find(a=>a.source===d),j=null,k=null,l=null;if("enable"!==b&&"disable"!==b){var n;let a=await (0,r.c)({agentDir:this.agentDir,configured:h,repairSource:"add"===b&&e?d:void 0});if(a)throw new M(a);if("add"!==b&&!i)throw new J(c);this.setOperation(d,"checking","正在确认插件版本和下载源");let g=this.candidateSource(c,i?.installedPath),o=(0,m.ug)(g),p="del"===b?{source:g,updateTag:null}:await this.updates.resolveInstall(g,d,f,"update"===b);if(k=p.updateTag,"update"===b&&o&&i?.installedPath){let a=await D(i.installedPath),b=p.source.slice(p.source.lastIndexOf("@")+1);if(!a.version)throw new L("无法读取插件已安装版本");if(!(0,m.zj)(b,a.version))return null}j={...o&&"del"!==b&&(e||i||"update"===b)?{action:"reinstall",source:p.source}:(n=p.source,{action:"add"===b?"install":"update"===b?"update":"remove",source:n}),..."registry"in p&&p.registry?{registry:p.registry}:{}},"del"!==b&&(l=await this.probeCandidate(p.source,j.registry))}return{request:j,updateTag:k,pluginName:l}}async executeMutation(a,b){let{mutation:c,source:d,operationSource:e}=a,{request:f,updateTag:g,pluginName:h}=b,i=(0,p.getL4PiGlobalPluginRuntime)(),j=a=>this.setOperation(e,"waiting",a);if(f&&(this.assertPluginNameAvailable(h,e),g&&((0,o.ks)(e,g,this.agentDir),this.updates.clear(e)),this.deferredMaintenance.size>0)){this.deferredMaintenance.set(e,f),j("等待重启后完成安装维护");return}this.assertOpen(),await i.withSourceIdle(e,async()=>{if(f){let b=this.createPackageManager();this.throwSettingsErrors(b.settingsManager);let d=b.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),f=await (0,r.c)({agentDir:this.agentDir,configured:d,repairSource:"add"===c&&a.reinstall?e:void 0});if(f)throw new M(f)}if(this.assertOpen(),this.setOperation(e,"applying",f?.registry?`下载源:${f.registry}`:null),"enable"===c||"disable"===c){let a=(0,o.to)(this.agentDir).disabled.includes((0,m.LD)(d));(0,o.El)(d,"enable"===c,this.agentDir),this.sourceCache=null;try{if(await this.applyMutationSources([d],!0),"enable"===c&&!(await this.readSources()).sources.find(a=>a.source===d)?.enabled)throw new L("此插件仍被 Pi 配置排除,请先调整原有资源配置")}catch(b){throw(0,o.El)(d,!a,this.agentDir),this.sourceCache=null,b}}else if(f)try{await i.replaceSource(e,null),await (0,s.V)(async()=>{await (0,q.wC)({maintenance:f,agentDir:this.agentDir,cwd:this.packageManagerCwd}),"del"!==c&&await this.verifyInstalledPackage(f.source)}),this.sourceCache=null,await this.applyMutationSources([e,f.source],!1)}catch(a){if(a instanceof q.rZ&&"locked"===a.kind&&(0,x.k)())this.deferredMaintenance.set(e,f),j("文件正在被使用,需要重启后完成操作");else throw a}this.updates.clear(e),this.updates.clear(d),this.capabilityCache=null,this.workSessions.refreshPluginMessages()},this.lifetime.signal,j)}async verifyInstalledPackage(a){let b=this.createPackageManager();this.throwSettingsErrors(b.settingsManager);let c=(0,m.LD)(a),d=b.packageManager.listConfiguredPackages().find(a=>"user"===a.scope&&(0,m.LD)(a.source)===c);if(!d?.installedPath)throw new L("插件安装后没有有效目录");await this.verifyPackageVersion(a,d.installedPath)}async verifyPackageVersion(a,b){let c=await D(b);if(c.error)throw new L("string"==typeof c.error.message?c.error.message:c.error.message.default);if((0,m.ug)(a)){let b=a.slice(a.lastIndexOf("@")+1);if(c.version!==b)throw new L(`插件实际安装版本与目标不一致:${c.version??"未知"},目标 ${b}`)}}async applyMutationSources(a,b){let c=new Set(a.map(m.LD)),d=(0,p.getL4PiGlobalPluginRuntime)(),e=await d.scanSourceChanges(),f=await this.readSources(),g=[...new Set([...e.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source),...f.sources.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source)])];for(let a of g.length?await d.scanSourceChanges(g):[])b&&await this.probeSourceChange(a),await d.applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path)}dispose(){this.disposed||(this.disposed=!0,this.lifetime.abort(),this.unsubscribeRuntime(),this.listeners.clear())}assertOpen(){if(this.disposed)throw new K("插件管理已关闭")}setOperation(a,b,c){let d=this.operations.get(a);if(!d)return;let e=c?.slice(0,4e3)??null;(d.phase!==b||d.message!==e)&&(this.operations.set(a,{...d,phase:b,message:e}),"failed"===b&&console.warn("[Pi Desk][PluginManagement] 插件操作失败",{source:a,action:d.action,message:e}),this.publish())}publish(){if(!this.disposed)for(let a of this.listeners)try{a()}catch(a){console.warn("[Pi Desk][PluginManagement] 状态监听失败",{message:C(a)})}}async readSources(){let a=()=>null!==this.activeSource&&this.operations.get(this.activeSource)?.phase==="applying";if(a()&&this.sourceCache)return this.sourceCache;let b=await (0,t.o)(this.packageManagerCwd,this.agentDir,{DefaultPackageManager:k.DefaultPackageManager,SettingsManager:k.SettingsManager});return a()&&this.sourceCache||(this.sourceCache=b),a()&&this.sourceCache?this.sourceCache:b}async probeCandidate(a,b){let c=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),d=(0,j.join)(c,"agent"),e=(0,j.join)(c,"workspace");await (0,i.mkdir)(e,{recursive:!0}),console.info("[Pi Desk][PluginManagement] 开始在隔离 AgentDir 预检候选插件",{source:a});try{if(!b&&(0,m.ug)(a))for(let b of[".npmrc",(0,j.join)("etc","npmrc")]){let c=(0,j.join)(d,"npm",b);await (0,i.mkdir)((0,j.dirname)(c),{recursive:!0});try{await (0,i.copyFile)((0,j.join)(this.agentDir,"npm",b),c),console.info("[Pi Desk][PluginManagement] 已为隔离预检继承本机 npm 配置",{source:a,configPath:b})}catch(a){if("ENOENT"!==a.code)throw new L(`无法继承本机 npm 配置(${b}):${C(a)}`)}}await (0,q.wC)({maintenance:{action:"install",source:a,...b?{registry:b}:{}},agentDir:d,cwd:e,signal:this.lifetime.signal}),this.assertOpen();let c=this.createPackageManager(d,e);this.throwSettingsErrors(c.settingsManager);let f=c.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope)[0];if(!f?.installedPath)throw new L("候选插件安装后没有有效目录");await this.verifyPackageVersion(a,f.installedPath);let g=await (0,w.Y)(e,d,!0,this.lifetime.signal);if(g.loadError)throw new L(g.loadError);let h=g.packages.find(a=>"failed"===a.status);if(h?.error)throw new L(h.error.message);let k=g.packages[0]?.pluginName??null;return this.assertOpen(),console.info("[Pi Desk][PluginManagement] 候选插件隔离预检通过",{source:a}),k}catch(a){if(a instanceof L)throw a;throw new L(C(a))}finally{await (0,i.rm)(c,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理候选插件目录失败",{path:c,errorName:a instanceof Error?a.name:"UnknownError"})})}}assertPluginNameAvailable(a,b){if(a&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==b&&c.pluginName===a))throw new L(`pluginName 已由其他 Package 注册:${a}`)}restartWhenQuiet(a){return this.workSessions.runPluginRestart(async()=>{let b=(0,p.getL4PiGlobalPluginRuntime)(),c=await this.readSnapshot(!1);return await b.prepareReload(),console.info("[Pi Desk][PluginManagement] 插件 Runtime 已通过静默检查,准备重启",{deferredCount:this.deferredMaintenance.size}),(0,x.Z)("basic"===a||0===this.deferredMaintenance.size?void 0:[...this.deferredMaintenance.values()],a),c})}async readDetail(a){if((0,e.P)())throw new K("基础模式不执行插件能力盘点");let b=(await this.readSources()).sources.find(b=>b.source===a),c=b?await (0,t.W)(b):null;if(!c)throw new J(a);let d=await this.readCapabilities(!1),f=d.packages.find(b=>b.source===a);if(!f)throw Error(d.loadError??`插件能力详情不可用:${a}`);let[g,h]=await Promise.all([Promise.all(f.skills.map(async a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible,...await E(c,a.filePath)}))),Promise.all(f.prompts.map(async a=>({name:a.name,description:a.description,path:a.path,...await E(c,a.filePath)})))]);return l.tA.parse({source:a,readme:await (0,n.w$)(c),tools:f.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,parameters:a.parameters,promptSnippet:a.promptSnippetDetail,promptGuidelines:a.promptGuidelines})),skills:g,prompts:h})}async readSnapshot(a){if((0,e.P)())return{plugins:[],restartRequired:!1,loadError:this.maintenanceError};let b=this.createPackageManager(),c=b.settingsManager.drainErrors().map(a=>a.error.message),d=b.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),f=await (0,r.c)({agentDir:this.agentDir,configured:d}),h=await this.readSources(),i=await this.updates.read(h.sources,"boolean"==typeof a?{checkUpdates:a}:a),j=(0,p.getL4PiGlobalPluginRuntime)(),k=j.readDiagnostics(),n=new Map(k.packages.map(a=>[a.source,a])),q=(0,u.u7)(),s=this.capabilityCache??{packages:[],loadError:null},t=new Map(s.packages.map(a=>[a.source,a])),v=new Map(j.readCapabilityRegistrations().map(a=>[a.source,a])),w=await Promise.all(h.sources.map(async a=>{let b=n.get(a.source),c=a.path?this.findNativeDiagnostic(a.path,q):null,d=(a.error?{phase:"package"===a.kind?"package":"entry",message:a.error}:null)??(b?.status==="failed"?b.error:null)??(c?{phase:"native",message:c}:null);return{source:a.source,kind:a.kind,operation:this.operationFor(a.source),pluginName:b?.pluginName??null,description:a.description,version:a.version??b?.version??null,updateAvailable:i.get(a.source)?.updateAvailable??null,updateTag:i.get(a.source)?.updateTag??null,availableVersion:i.get(a.source)?.availableVersion??null,updateError:i.get(a.source)?.updateError??null,status:a.enabled?d?"failed":b?.status==="ready"?"ready":"available":"disabled",error:d,capabilities:F(t.get(a.source),v.get(a.source),s.loadError)}}));for(let[a,b]of this.operations)w.some(b=>(0,m.LD)(b.source)===(0,m.LD)(a))||w.push({source:a,kind:"package",operation:b,pluginName:null,description:null,version:null,updateAvailable:null,updateTag:(0,m.ug)(a)?(0,o.ey)(a,this.agentDir):null,availableVersion:null,updateError:null,status:"failed"===b.phase?"failed":"available",error:null,capabilities:F(void 0,void 0,null)});return l.oP.parse({plugins:w.sort((a,b)=>a.source.localeCompare(b.source)),restartRequired:this.restartRequired,loadError:function(a){let b=[...new Map(a.flatMap(a=>{let b=("string"==typeof a?a:a.message).trim();return b?[[b,{defaultText:b,englishText:"string"==typeof a?b:a.englishMessage.trim()}]]:[]})).values()];if(0===b.length)return null;let c=b.map(a=>a.defaultText).join("; ");return b.every(a=>a.defaultText===a.englishText)?c:(0,g.J8)(c,b.map(a=>a.englishText).join("; "))}([...c,...h.errors,...k.loadError?[k.loadError]:[],...this.maintenanceError?[this.maintenanceError]:[],...f?[f]:[]])})}async readCapabilities(a){if(!a&&this.capabilityCache)return this.capabilityCache;try{return this.capabilityCache=await (0,s.V)(()=>(this.assertOpen(),!a&&this.capabilityCache)?Promise.resolve(this.capabilityCache):(0,v.a)(this.cwd,this.agentDir)),this.publish(),console.info("[Pi Desk][PluginManagement] 插件能力盘点完成",{packageCount:this.capabilityCache.packages.length,hasLoadError:null!==this.capabilityCache.loadError}),this.capabilityCache}catch(b){let a=C(b);return console.warn("[Pi Desk][PluginManagement] 插件能力盘点失败",{errorName:b instanceof Error?b.name:"UnknownError",message:a}),this.capabilityCache={packages:[],loadError:a},this.publish(),this.capabilityCache}}findNativeDiagnostic(a,b){let c,d=(c=(0,j.resolve)(a).replaceAll("\\","/"),"win32"===process.platform?c.toLowerCase():c),e=b.find(a=>("win32"===process.platform?a.message.replaceAll("\\","/").toLowerCase():a.message.replaceAll("\\","/")).includes(d));return e?.message??null}createPackageManager(a=this.agentDir,b=this.packageManagerCwd){let c=k.SettingsManager.create(b,a,{projectTrusted:!1});return{settingsManager:c,packageManager:new k.DefaultPackageManager({cwd:b,agentDir:a,settingsManager:c})}}candidateSource(a,b){return(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:b?(0,j.resolve)(b):(0,j.resolve)(this.agentDir,a)}operationFor(a){let b=(0,m.LD)(a);return[...this.operations].find(([a])=>(0,m.LD)(a)===b)?.[1]??null}normalizeAddedSource(a){return/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*(?:@[^\s/]+)?$/i.test(a)?`npm:${a}`:(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:(0,j.resolve)(this.cwd,a)}throwSettingsErrors(a){let b=a.drainErrors();if(0!==b.length)throw Error(b.map(a=>a.error.message).join("; "))}assertRestartAvailable(){if(!(0,x.k)())throw new O}runExclusive(a){let b=()=>this.staleStagingCleanup.then(()=>(this.assertOpen(),a())),c=this.operationTail.then(b,b);return this.operationTail=c.then(()=>void 0,()=>void 0),c}}function G(){globalThis.__piDeskPluginManagement?.dispose()}function H(a){globalThis.__piDeskPluginManagement||(globalThis.__piDeskPluginManagement=new P(a))}function I(){if(!globalThis.__piDeskPluginManagement)throw Error("插件管理尚未完成进程级装配");return globalThis.__piDeskPluginManagement}d()}catch(a){d(a)}})},53584:(a,b,c)=>{c.d(b,{a:()=>l});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_CAPABILITIES__",i=e.Yj(),j=e.Ik({name:e.Yj(),description:e.Yj().nullable()}).strict(),k=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),error:e.Yj().nullable(),extensions:e.YO(e.Ik({path:e.Yj(),events:e.YO(e.Ik({name:e.Yj(),count:e.ai().int().positive()}).strict()),commands:e.YO(j),shortcuts:e.YO(e.Ik({shortcut:e.Yj(),description:e.Yj().nullable()}).strict()),flags:e.YO(e.Ik({name:e.Yj(),type:e.k5(["boolean","string"]),description:e.Yj().nullable(),default:e.KC([e.zM(),e.Yj(),e.ch()])}).strict()),messageRenderers:e.YO(e.Yj()),entryRenderers:e.YO(e.Yj())}).strict()),tools:e.YO(e.Ik({name:e.Yj(),label:i,state:e.k5(["active","inactive","shadowed"]),description:i,parameters:e.g1(e.Yj(),e.Pq()),promptSnippet:i.nullable(),promptSnippetDetail:i.nullable(),promptGuidelines:e.YO(i),promptGuidelineCount:e.ai().int().nonnegative(),promptGuidelinePreview:i.nullable()}).strict()),skills:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj(),modelVisible:e.zM()}).strict()),prompts:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj()}).strict()),themes:e.YO(e.Ik({name:e.Yj(),path:e.Yj()}).strict()),providers:e.YO(e.Ik({name:e.Yj(),kind:e.k5(["config","native"])}).strict())}).strict()),loadError:e.Yj().nullable()}).strict();async function l(a,b){let c=(0,f.I)(),e=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-capability-probe-runner.mts"),{stdout:i,stderr:j,code:l}=await (0,g.i)({args:["--conditions=react-server","--import",c,e],agentDir:b,env:{PI_DESK_PLUGIN_CAPABILITY_AGENT_DIR:b,PI_DESK_PLUGIN_CAPABILITY_CWD:a},maxOutputBytes:4194304,timeoutMs:3e4,timeoutError:()=>Error("插件能力盘点超时"),cleanupError:(a,b)=>Error(`${a}
|
|
6
|
-
能力盘点进程树清理失败`,{cause:b})});if(0!==l)throw Error(j.trim()||`插件能力盘点进程退出码 ${l??"null"}`);let m=i.lastIndexOf(h);if(m<0)throw Error("插件能力盘点没有返回有效结果");let n=i.slice(m+h.length).split(/\r?\n/,1)[0];return k.parse(JSON.parse(n))}},64253:(a,b,c)=>{c.a(a,async(a,d)=>{try{let s;c.d(b,{B:()=>q,I:()=>r});var e=c(31421),f=c(73024),g=c(51455),h=c(76760),i=c(48161),j=c(57975),k=c(75430),l=a([k]);k=(l.then?(await l)():l)[0];let t=(0,j.promisify)(e.execFile);function m(a){return a.replace(/\$\{([^}]+)\}/g,(a,b)=>process.env[b]??a)}async function n(a,b){let c;try{let b=await (0,g.readFile)(a);if(b.length>262144)throw Error("npm 配置文件过大");c=b.toString("utf8")}catch(a){if("ENOENT"===a.code)return;throw a}for(let a of c.split(/\r?\n/)){let c=/^\s*([^;#][^=]*?)\s*=\s*(.*?)\s*$/.exec(a);if(!c)continue;let d=c[2].replace(/\s+[;#].*$/,"").replace(/^(['"])(.*)\1$/,"$2");b[c[1].trim()]=m(d)}}function o(a,b){return("win32"===process.platform?/^~[\\/]/:/^~\//).test(a)?(0,h.resolve)((0,i.homedir)(),a.slice(2)):(0,h.resolve)(b,a)}async function p(a,b){let c={};for(let[a,b]of Object.entries(process.env))if(void 0!==b&&""!==b&&/^npm_config_/i.test(a)){let d=a.slice(11);c[d.startsWith("//")?d:d.replace(/(?!^)_/g,"-").toLowerCase()]=m(b)}let d=function(){for(let a of[(0,h.dirname)(process.execPath),...(process.env.PATH??"").split("win32"===process.platform?";":":")])for(let b of[(0,h.join)(a,"node_modules/npm/bin/npm-cli.js"),(0,h.resolve)(a,"../lib/node_modules/npm/bin/npm-cli.js")])if((0,f.existsSync)(b))return b}(),e={};if(d)try{await (0,g.mkdir)(a,{recursive:!0});let c=await t(process.execPath,[d,"config","list","--json","--prefix",b],{cwd:a,timeout:4e3,maxBuffer:524288,windowsHide:!0});e=JSON.parse(c.stdout)}catch{console.warn("[Pi Desk][PluginRegistry] npm 有效配置读取失败,改用 npmrc 和环境配置")}let j={};d&&await n((0,h.resolve)((0,h.dirname)(d),"../npmrc"),j);let k="string"==typeof e.globalconfig?e.globalconfig:c.globalconfig??(0,h.join)(b,"etc/npmrc"),l="string"==typeof e.userconfig?e.userconfig:c.userconfig??(0,h.join)((0,i.homedir)(),".npmrc");for(let[d,f]of(await n(o(k,a),j),await n(o(l,a),j),!0!==e.global&&"true"!==c.global&&"global"!==e.location&&"global"!==c.location&&await n((0,h.join)(b,".npmrc"),j),Object.entries(e)))"string"!=typeof f||"(protected)"===f||/auth|password|username/i.test(d)||(j[d]=f);return{...j,...c}}function q(a=(0,k.getAgentDir)()){let b=process.env.PI_DESK_PACKAGE_MAINTENANCE_CWD??(0,h.join)(a,"pi-desk","plugin-package-manager"),c=(0,h.join)(a,"npm");if(!s||s.cwd!==b||s.prefix!==c||s.expires<=Date.now()){let a=p(b,c);s={cwd:b,prefix:c,expires:Date.now()+3e4,value:a},a.catch(()=>{s?.value===a&&(s=void 0)})}return s.value}function r(a,b){let c=`//${a.host}${a.pathname}`;for(let a of Object.keys(b).flatMap(a=>{let b=/^(\/\/.*\/):(?:_authToken|_auth|username|_password)$/i.exec(a);return b&&c.startsWith(b[1])?[b[1]]:[]}).sort((a,b)=>b.length-a.length)){let c=b[`${a}:_authToken`]??b[`${a}:_authtoken`];if(c&&!c.includes("${"))return`Bearer ${c}`;let d=b[`${a}:_auth`];if(d&&!d.includes("${"))return`Basic ${d}`;let e=b[`${a}:username`],f=b[`${a}:_password`];if(e&&f&&!f.includes("${"))return`Basic ${Buffer.from(`${e}:${Buffer.from(f,"base64").toString("utf8")}`).toString("base64")}`}let d=b.registry;if(d){let c=new URL(d);if(a.origin===c.origin&&a.pathname.startsWith(`${c.pathname.replace(/\/+$/,"")}/`)){let a=b._authToken??b._authtoken;if(a&&!a.includes("${"))return`Bearer ${a}`;if(b._auth&&!b._auth.includes("${"))return`Basic ${b._auth}`}}}d()}catch(a){d(a)}})},69371:(a,b,c)=>{c.d(b,{rZ:()=>g,wC:()=>h});var d=c(76760),e=c(86148),f=c(2472);class g extends Error{constructor(a,b,c){super(b.slice(-4e3)||`Pi Package 命令退出码 ${c??"null"}`),this.kind=a,this.output=b,this.exitCode=c,this.name="L4PiPackageMaintenanceError"}}async function h(a){let b=(0,e.I)(),c=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-package-maintenance-runner.mts"),{stdout:h,stderr:i,code:j}=await (0,f.i)({args:["--import",b,c,a.maintenance.action,a.maintenance.source,...a.maintenance.registry?[a.maintenance.registry]:[]],agentDir:a.agentDir,env:{PI_DESK_PACKAGE_MAINTENANCE_CWD:a.cwd},maxOutputBytes:1048576,timeoutMs:12e4,signal:a.signal,timeoutError:()=>new g("failed","包维护超过120秒,已停止;结果未确认,请检查配置后手动处理",null),cleanupError:(a,b)=>new g("failed",`维护进程树未确认释放:${b instanceof Error?b.message:String(b)}`,null)});if(0===j)return;let k=(i||h).trim();throw new g(function(a){let b=a.toLowerCase();if(b.includes("ebusy")||b.includes("etxtbsy")||b.includes("resource busy")||b.includes("being used by another process")||b.includes("used by another process")||b.includes("process cannot access the file because it is being used"))return"locked";let c=b.includes("eperm")||b.includes("eacces")||b.includes("operation not permitted"),d=/\b(unlink|rename|rmdir|rimraf|remove|cleanup)\b/.test(b);return c&&d?"locked":"failed"}(k),k,j)}},69375:(a,b,c)=>{c.d(b,{Od:()=>r,tU:()=>n,hE:()=>q,P9:()=>f,_G:()=>j,Vc:()=>i});var d=c(36153);d.Yj().uuid();let e=d.Ik({key:d.Yj().min(1).max(160),params:d.g1(d.Yj().min(1).max(80),d.KC([d.Yj().max(1e3),d.ai().finite()])).optional()}).strict(),f=4001,g=d.Yj().trim().min(1),h=d.Yj().uuid();function i(a){return Object.freeze({op:"req",path:g.parse(a.path),inputSchema:a.inputSchema,outputSchema:a.outputSchema,...void 0===a.timeoutMs?{}:{timeoutMs:d.ai().int().positive().parse(a.timeoutMs)}})}function j(a){return Object.freeze({op:"push",path:g.parse(a.path),bodySchema:a.bodySchema})}let k=d.Ik({op:d.eu("req"),path:g,requestId:h}).strict(),l=d.Ik({op:d.eu("resp"),path:g,requestId:h}).strict(),m=d.Ik({op:d.eu("push"),path:g}).strict(),n=d.Ik({head:k,body:d.Pq()}).strict(),o=d.Ik({head:l,body:d.Ik({code:d.eu(0),msg:d.eu(""),data:d.Pq()}).strict()}).strict(),p=d.Ik({head:l,body:d.Ik({code:d.ai().int().positive(),msg:d.Yj().min(1),data:d.ch(),i18n:e.optional()}).strict()}).strict(),q=d.KC([o,p]),r=d.Ik({head:m,body:d.Pq()}).strict()},72497:(a,b,c)=>{c.d(b,{Dz:()=>h,f7:()=>g,tv:()=>f});var d=c(36153);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=e,g=e,h=d.g1(d.Yj(),d.Pq());d.Yj().trim().min(3).max(129).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*\/[a-z0-9]+(?:-[a-z0-9]+)*$/);let i=d.k5(["plugin","server","rocket","settings","panel","message","terminal","file","folder","bot","wrench","database","globe"]);d.gM("type",[d.Ik({type:d.eu("builtin"),name:i}).strict(),d.Ik({type:d.eu("svg"),content:d.Yj().trim().min(1).max(16384)}).strict()])},73159:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{NL:()=>h,XH:()=>j,Yq:()=>i});var e=c(77598),f=c(64253),g=a([f]);f=(g.then?(await g)():g)[0];class j extends Error{constructor(a,b=502,c="invalid"){super(a),this.status=b,this.reason=c,this.name="L4PluginRegistryError"}}let k=new Map,l=0;async function h(a,b){b.signal?.throwIfAborted();let c=!1===b.auth?{}:await (0,f.B)(b.agentDir),d=(0,f.I)(a,c),g=`${a.href}:${b.limit}:${(0,e.createHash)("sha256").update(d??"").digest("hex")}`,h=k.get(g);if(!1!==b.cache&&h&&h.expires>Date.now())return h.body;let i=AbortSignal.any([AbortSignal.timeout(b.timeout??1e4),...b.signal?[b.signal]:[]]),m=a;try{for(let a=0;a<=3;a++){let d=(0,f.I)(m,c),e=await fetch(m,{signal:i,redirect:"manual",headers:d?{Authorization:d}:{}});if([301,302,303,307,308].includes(e.status)){await e.body?.cancel();let b=e.headers.get("location");if(!b||3===a)throw new j("插件源重定向无效");let c=new URL(b,m);if(!["http:","https:"].includes(c.protocol)||c.username||c.password||"https:"===m.protocol&&"https:"!==c.protocol)throw new j("插件源重定向不安全");m=c;continue}if(!e.ok){await e.body?.cancel();let a=404===e.status?"missing":[401,403].includes(e.status)?"denied":e.status>=500?"network":"invalid";throw new j(`插件源请求失败(HTTP ${e.status})`,e.status,a)}if(Number(e.headers.get("content-length")??0)>b.limit)throw await e.body?.cancel(),new j("插件源响应超过大小限制");let h=e.body?.getReader(),n=[],o=0;if(h)try{for(;;){let a=await h.read();if(a.done)break;if((o+=a.value.byteLength)>b.limit)throw new j("插件源响应超过大小限制");n.push(a.value)}}finally{await h.cancel().catch(()=>void 0),h.releaseLock()}let p=Buffer.concat(n);if(!1!==b.cache){for(let[a,b]of k)(b.expires<=Date.now()||a===g)&&(k.delete(a),l-=b.body.length);for(;k.size>=96||l+p.length>0x1800000;){let a=k.entries().next().value;if(!a)break;k.delete(a[0]),l-=a[1].body.length}p.length<=0x1800000&&(k.set(g,{body:p,expires:Date.now()+12e4}),l+=p.length)}return p}throw new j("插件源重定向过多")}catch(a){if(b.signal?.aborted)throw b.signal.reason;if(a instanceof j)throw a;throw new j("插件源网络连接失败或超时",502,"network")}}async function i(a,b,c){let d=await h(a,{limit:8388608,signal:b,agentDir:c});try{let a=JSON.parse(d.toString("utf8"));if(!a||"object"!=typeof a||Array.isArray(a))throw Error("invalid");return a}catch{throw new j("插件源返回的元数据格式无效")}}d()}catch(a){d(a)}})},75157:(a,b,c)=>{c.d(b,{c:()=>h});var d=c(51455),e=c(76760);function f(a){if(!a.startsWith("npm:"))return null;let b=a.slice(4).trim(),c=b.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);return c?.[1]??(b||null)}async function g(a){try{return(await (0,d.stat)(a)).isDirectory()}catch{return!1}}async function h(a){let b=a.configured.flatMap(a=>{let b=f(a.source);return b?[{name:b,item:a}]:[]}),c=(0,e.join)(a.agentDir,"npm","package.json"),h={};try{let a=JSON.parse(await (0,d.readFile)(c,"utf8"));a.dependencies&&"object"==typeof a.dependencies&&(h=a.dependencies)}catch(c){if(0===b.length)return null;let a=c instanceof Error&&c.message?c.message:String(c);return{message:`Pi Package npm 根不可用:${a}`,englishMessage:`Pi Package npm root is unavailable: ${a}`,i18n:{key:"errors:pluginNpmRootUnavailable",params:{detail:a.slice(0,1e3)}}}}let i=a.repairSource?f(a.repairSource):null,j=b.filter(a=>a.name!==i),k=new Set(j.map(a=>a.name)),l=new Set(Object.keys(h)),m=[...k].filter(a=>!l.has(a)),n=[];for(let{name:a,item:b}of j)b.installedPath&&await g(b.installedPath)||n.push(a);if(0===m.length&&0===n.length)return null;let o=[m.length>0?`缺少声明:${m.join("、")}`:null,n.length>0?`缺少目录:${n.join("、")}`:null].filter(a=>null!==a),p=[m.length>0?`missing declarations: ${m.join(", ")}`:null,n.length>0?`missing folders: ${n.join(", ")}`:null].filter(a=>null!==a),q=m.length>0?n.length>0?"errors:pluginNpmRootMissingBoth":"errors:pluginNpmRootMissingDeclarations":"errors:pluginNpmRootMissingFolders";return{message:`Pi Package 配置与 npm 根不一致(${o.join(";")})`,englishMessage:`Pi Package configuration does not match the npm root (${p.join("; ")})`,i18n:{key:q,params:{declarations:m.join(", ").slice(0,1e3),folders:n.join(", ").slice(0,1e3)}}}}},76019:(a,b,c)=>{c.d(b,{J8:()=>f,fD:()=>g,qf:()=>e});var d=c(36153);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}}}function g(a,b){return"string"==typeof a?a:a.translations[b]??a.translations[b.split("-")[0]]??a.default}},78597:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{E:()=>k});var e=c(75430),f=c(4287),g=c(5235),h=c(34458),i=c(47154),j=a([e,g,h]);[e,g,h]=j.then?(await j)():j;class k{constructor(a,b,c){this.agentDir=a,this.cwd=b,this.signal=c,this.cache=new Map}async resolveInstall(a,b,c,d){let e=(0,f.ug)(a),i=e?/^npm:(?:@[^/]+\/)?[^@]+@([^@]+)$/.exec(a)?.[1]:void 0,j=i&&!/^v?\d+\./.test(i)&&f.mR.safeParse(i).success?i:null,k=e?d?(0,g.ey)(b,this.agentDir):c.tag??j??(0,g.ey)(b,this.agentDir):null,l=e&&k&&(d||!i)?`npm:${e}@${k}`:a;return{...await (0,h.dz)(l,{...c,agentDir:this.agentDir,signal:this.signal,cache:!d&&void 0}),updateTag:k}}clear(a){let b=(0,f.LD)(a);for(let[a,c]of this.cache)c.identity===b&&this.cache.delete(a)}async read(a,b){for(let[a,b]of this.cache)b.expiresAt<=Date.now()&&this.cache.delete(a);let c=b.sources?new Set(b.sources.map(f.LD)):null,d=new Map;for(let j of a){if("package"!==j.kind)continue;let a=(0,f.LD)(j.source),k=(0,f.ug)(j.source),l=k?(0,g.ey)(j.source,this.agentDir):null,m={updateTag:l,updateAvailable:null,availableVersion:null,updateError:null};d.set(j.source,m);let n=!0===b.checkUpdates&&(!c||c.has(a))&&(!b.tag||b.tag===l);if(k){if(!n&&![...this.cache.values()].some(b=>b.identity===a))continue;let b=null;try{let c=(0,g.to)(this.agentDir).downloadSource,e=await (0,h.qX)(k,{agentDir:this.agentDir,downloadSource:c});b=JSON.stringify([a,l,c.mode,e.registry,e.fallback]);let i=this.cache.get(b)?.value;if(n){if(!j.path||!j.version)throw Error("无法读取插件已安装版本");let d=await (0,h.dz)(`npm:${k}@${l}`,{downloadSource:c,agentDir:this.agentDir,signal:this.signal,cache:!1}),e=d.source.slice(d.source.lastIndexOf("@")+1);i={...m,availableVersion:e},this.store(b,a,i)}i&&d.set(j.source,{...i,updateAvailable:!i.updateError&&j.version&&i.availableVersion?(0,f.zj)(i.availableVersion,j.version):null})}catch(e){let c={...m,updateError:this.message(j.source,e)};d.set(j.source,c),b&&this.store(b,a,c)}}else if(/^(?:git:|https?:|git@)/.test(j.source)){let b=JSON.stringify([a,"git"]),c=this.cache.get(b)?.value;if(c&&d.set(j.source,c),!n)continue;try{let c=e.SettingsManager.inMemory({packages:[j.source]}),f=new e.DefaultPackageManager({agentDir:this.agentDir,cwd:this.cwd,settingsManager:c}),g=await (0,i.V)(()=>f.checkForAvailableUpdates()),h={...m,updateAvailable:g.some(a=>"user"===a.scope)};d.set(j.source,h),this.store(b,a,h)}catch(e){let c={...m,updateError:this.message(j.source,e)};d.set(j.source,c),this.store(b,a,c)}}}return d}store(a,b,c){for(this.cache.delete(a);this.cache.size>=128;){let a=this.cache.keys().next().value;if(void 0===a)break;this.cache.delete(a)}this.cache.set(a,{identity:b,expiresAt:Date.now()+3e5,value:c})}message(a,b){let c=(b instanceof Error?b.message:String(b)).slice(0,4e3);return console.warn("[Pi Desk][PluginManagement] 检查插件更新失败",{source:a,message:c}),this.clear(a),c}}d()}catch(a){d(a)}})},86148:(a,b,c)=>{function d(a){let b=a.replaceAll("\\","/");return"tsx"===b||/(?:^|\/)tsx(?:\/|$)/.test(b)}function e(a=process.execArgv){for(let b=0;b<a.length;b+=1){let c=a[b];if("--import"===c){let c=a[b+1];if(c&&d(c))return c;b+=1;continue}if(c.startsWith("--import=")){let a=c.slice(9);if(d(a))return a}}throw Error("Pi Desk 服务缺少 tsx loader,无法启动插件维护子进程")}c.d(b,{I:()=>e})},93951:(a,b,c)=>{c.d(b,{LC:()=>E,tA:()=>G,oP:()=>H});var d=c(36153),e=c(72497),f=c(76019),g=c(4287),h=c(69375);let i=g.SZ,j=g.w3;d.Ik({downloadSource:j,recommendedRegistry:i}).strict(),d.Ik({downloadSource:j}).strict(),d.Ik({query:d.Yj().trim().max(200).default(""),page:d.ai().int().min(1).max(100).default(1),kind:d.k5(["all","desk","pi"]).default("all"),registry:i.optional()}).strict(),d.Ik({name:d.Yj().trim().min(1).max(214).regex(/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*$/i),version:d.Yj().trim().min(1).max(128).optional(),registry:i.optional()}).strict();let k=d.Ik({name:d.Yj(),description:f.qf.nullable(),version:d.Yj(),publisher:d.Yj().nullable(),kind:d.k5(["desk","pi","unknown"]),official:d.zM(),registry:i}).strict();d.Ik({items:d.YO(k),hasMore:d.zM()}).strict(),k.extend({versions:d.YO(d.Yj()),readme:f.qf.nullable(),homepage:d.Yj().nullable(),repository:d.Yj().nullable(),compatible:d.zM().nullable(),compatibilityNote:d.Yj().nullable()}).strict();let l=d.Yj().trim().min(1).max(2048),m=g.mR,n=d.YO(l).min(1).max(32),o=d.Ik({phase:d.k5(["package","entry","setup","resources","resolve","native"]),message:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0)}).strict(),p=d.Yj().trim().min(1).max(4096),q=d.Yj().trim().min(1).max(256),r=d.Yj().max(32768),s=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,promptSnippet:r.nullable(),promptGuidelineCount:d.ai().int().nonnegative(),promptGuidelinePreview:r.nullable()}).strict(),t=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,parameters:e.Dz,promptSnippet:r.nullable(),promptGuidelines:d.YO(r)}).strict(),u=d.Ik({path:p,events:d.YO(d.Ik({name:q,count:d.ai().int().positive()}).strict()),commands:d.YO(d.Ik({name:q,description:r.nullable()}).strict()),shortcuts:d.YO(d.Ik({shortcut:q,description:r.nullable()}).strict()),flags:d.YO(d.Ik({name:q,type:d.k5(["boolean","string"]),description:r.nullable(),default:d.KC([d.zM(),d.Yj(),d.ch()])}).strict()),messageRenderers:d.YO(q),entryRenderers:d.YO(q)}).strict(),v=d.Ik({name:q,description:r,path:p}).strict(),w=v.extend({modelVisible:d.zM()}).strict(),x=v.extend({content:d.Yj().max(65536),truncated:d.zM()}).strict(),y=x.extend({modelVisible:d.zM()}).strict(),z=d.Ik({name:q,path:p}).strict(),A=d.Ik({name:q,kind:d.k5(["config","native"])}).strict(),B=d.Ik({methods:d.YO(d.Ik({pluginName:q,method:q}).strict()),browserEntries:d.YO(d.Ik({pluginName:q}).strict()),messageDeclarations:d.YO(d.Ik({pluginName:q,declarationName:q,priority:d.ai().int().safe()}).strict())}).strict(),C=d.Ik({error:f.qf.refine(a=>"string"==typeof a?a.length<=32768:[a.default,...Object.values(a.translations)].every(a=>a.length<=32768)).nullable(),extensions:d.YO(u),tools:d.YO(s),skills:d.YO(w),prompts:d.YO(v),themes:d.YO(z),providers:d.YO(A),piDesk:B}).strict(),D=d.Ik({action:d.k5(["add","update","del","apply","enable","disable"]),phase:d.k5(["queued","checking","applying","waiting","failed"]),message:d.Yj().max(4e3).nullable()}).strict(),E=(0,h._G)({path:"plugins/management-update",bodySchema:d.Ik({}).strict()}),F=d.Ik({source:l,kind:d.k5(["package","extension"]).default("package"),operation:D.nullable().default(null),pluginName:d.Yj().trim().min(1).nullable(),description:f.qf.nullable().default(null),version:d.Yj().trim().min(1).nullable(),updateAvailable:d.zM().nullable(),updateTag:m.nullable().optional(),availableVersion:d.Yj().min(1).nullable().optional(),updateError:d.Yj().max(4e3).nullable().optional(),status:d.k5(["ready","available","disabled","failed"]),error:o.nullable(),capabilities:C}).strict(),G=d.Ik({source:l,readme:f.qf.nullable().default(null),tools:d.YO(t),skills:d.YO(y),prompts:d.YO(x)}).strict(),H=d.Ik({plugins:d.YO(F),restartRequired:d.zM(),loadError:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0).nullable()}).strict();d.Ik({sources:d.YO(l).min(1).max(32).optional()}).strict(),d.Ik({}).strict().extend({mode:d.k5(["normal","basic"]).optional()}).strict(),d.Ik({checkUpdates:d.zM().optional(),sources:n.optional(),tag:m.optional()}).strict();let I=d.Ik({source:l}).strict(),J=I.extend({downloadSource:j.optional(),registry:i.optional(),tag:m.optional()}).strict();d.gM("action",[d.Ik({action:d.eu("add"),items:d.YO(J).min(1).max(32)}).strict(),d.Ik({action:d.eu("update"),sources:n}).strict(),d.Ik({action:d.eu("del"),sources:n}).strict(),d.Ik({action:d.eu("tag"),sources:n,tag:m}).strict()]),d.Ik({snapshot:H,results:d.YO(d.Ik({source:l,error:d.Yj().max(4e3).nullable()}).strict()).max(32)}).strict(),I.extend({enabled:d.zM()}).strict()},96783:(a,b,c)=>{c.d(b,{Y:()=>j});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_PROBE__",i=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),packageName:e.Yj().nullable(),version:e.Yj().nullable(),pluginName:e.Yj().nullable(),status:e.k5(["ready","failed"]),error:e.Ik({phase:e.k5(["package","entry","setup","resources","resolve"]),message:e.Yj()}).strict().nullable()}).strict()),loadError:e.Yj().nullable()}).strict();async function j(a,b,c=!1,e){let k=(0,f.I)(),l=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-probe-runner.mts"),{stdout:m,stderr:n,code:o}=await (0,g.i)({args:["--conditions=react-server","--import",k,l],agentDir:b,env:{PI_DESK_PLUGIN_PROBE_AGENT_DIR:b,PI_DESK_PLUGIN_PROBE_CWD:a,PI_DESK_PLUGIN_PROBE_NATIVE:c?"1":void 0},maxOutputBytes:1048576,timeoutMs:3e4,signal:e,timeoutError:()=>Error("插件预检超时"),cleanupError:(a,b)=>Error(`${a}
|
|
7
|
-
插件预检进程树清理失败`,{cause:b})});if(0!==o)throw Error(n.trim()||`插件预检进程退出码 ${o??"null"}`);let p=m.lastIndexOf(h);if(p<0)throw Error("插件预检没有返回有效结果");let q=m.slice(p+h.length).split(/\r?\n/,1)[0];return i.parse(JSON.parse(q))}}};
|
|
5
|
+
… (truncated)`)}(a?.error??c),extensions:a?.extensions??[],tools:a?.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,promptSnippet:a.promptSnippet,promptGuidelineCount:a.promptGuidelineCount,promptGuidelinePreview:a.promptGuidelinePreview}))??[],skills:a?.skills.map(a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible}))??[],prompts:a?.prompts.map(a=>({name:a.name,description:a.description,path:a.path}))??[],themes:a?.themes??[],providers:a?.providers??[],piDesk:{methods:b?[...b.methods]:[],browserEntries:b?[...b.browserEntries]:[],messageDeclarations:b?[...b.messageDeclarations]:[]}}}class P{get restartRequired(){return this.deferredMaintenance.size>0}constructor(a,b=process.cwd(),c=(0,k.getAgentDir)()){this.workSessions=a,this.cwd=b,this.agentDir=c,this.operationTail=Promise.resolve(),this.operations=new Map,this.listeners=new Set,this.lifetime=new AbortController,this.disposed=!1,this.activeSource=null,this.sourceCache=null,this.capabilityCache=null,this.deferredMaintenance=new Map;const d=(0,h.createHash)("sha256").update(this.agentDir).digest("hex").slice(0,16);this.stagingRoot=(0,j.join)(this.cwd,"temp","pi",`plugin-management-${d}`),this.packageManagerCwd=(0,j.join)((0,f.M)(),"plugin-package-manager"),this.updates=new y.E(this.agentDir,this.packageManagerCwd,this.lifetime.signal),this.maintenanceError=process.env.PI_DESK_PLUGIN_MAINTENANCE_ERROR?.trim()||null,this.unsubscribeRuntime=(0,p.getL4PiGlobalPluginRuntime)().subscribeChanges(()=>this.publish()),this.staleStagingCleanup=(0,i.rm)(this.stagingRoot,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理上次中断的候选目录失败",{path:this.stagingRoot,errorName:a instanceof Error?a.name:"UnknownError"})})}list(a=!1){return this.assertOpen(),this.readSnapshot(a)}async batch(a){this.assertOpen();let b=[],c=new Set,d="add"===a.action||"update"===a.action?await this.readSources():null,e=[];for(let f of"add"===a.action?a.items:a.sources.map(a=>({source:a})))try{let g="add"===a.action?this.normalizeAddedSource(f.source):f.source,h=(0,m.LD)(g);if(c.has(h))throw new K("批量请求中包含重复来源");if(c.add(h),"add"===a.action){let{source:a,...b}=f;e.push(this.acceptMutation("add",g,d,!0,void 0,b))}else"update"===a.action?e.push(this.acceptMutation("update",g,d)):"del"===a.action?await this.del(g):await this.setUpdateTag(g,a.tag);b.push({source:f.source,error:null})}catch(a){b.push({source:f.source,error:C(a).slice(0,4e3)})}return e.length>0&&this.enqueueMutations(e),{snapshot:await this.readSnapshot(!1),results:b}}subscribe(a){return this.assertOpen(),this.listeners.add(a),()=>this.listeners.delete(a)}get(a){return this.assertOpen(),this.readDetail(a)}add(a,b={}){return this.mutate("add",this.normalizeAddedSource(a),!1,void 0,b)}setEnabled(a,b){return this.mutate(b?"enable":"disable",a)}async update(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");this.assertSourceIdle(a);let b=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!b)throw new J(a);if((0,m.ug)(b.source)){let a=await this.readSnapshot({checkUpdates:!0,sources:[b.source]}),c=a.plugins.find(a=>a.source===b.source);if(c.updateError)throw new L(c.updateError);if(!0!==c.updateAvailable)return a}return this.mutate("update",b.source)}reinstall(a,b,c={}){return this.mutate("add",this.normalizeAddedSource(a),!0,b,c)}async setUpdateTag(a,b){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护");let c=(await this.readSources()).sources.find(b=>(0,m.LD)(b.source)===(0,m.LD)(a));if(!c)throw new J(a);if("package"!==c.kind||!(0,m.ug)(c.source))throw new L("只有 npm 插件包支持更新渠道");this.assertSourceIdle(c.source),(0,o.ks)(c.source,m.mR.parse(b),this.agentDir),this.updates.clear(c.source),this.publish()}assertSourceIdle(a){let b=(0,m.LD)(a);if(this.activeSource&&(0,m.LD)(this.activeSource)===b||[...this.operations].some(([a,c])=>(0,m.LD)(a)===b&&"failed"!==c.phase))throw new K("该来源已有未完成的维护操作")}waitForOperations(a,b){return b=AbortSignal.any([b,this.lifetime.signal]),new Promise((c,d)=>{let e=()=>void 0,f=a=>{e(),b.removeEventListener("abort",g),a?d(a):c()},g=()=>f(Error(this.disposed?"插件管理已关闭":"发起命令的会话已关闭")),h=()=>{if(this.disposed)return f(Error("插件管理已关闭"));for(let b of a){let a=this.operations.get(b);if(a?.phase==="failed")return f(Error(a.message??"插件操作失败"));if(a?.phase==="waiting"&&this.activeSource!==b&&this.restartRequired)return f(Error(`插件尚未生效,需要在设置的插件管理中重启 Pi Desk。${a.message??""}`))}a.some(a=>this.operations.has(a)||this.activeSource===a)||f()};if(b.aborted)return g();e=this.subscribe(h),b.addEventListener("abort",g,{once:!0}),h()})}del(a){return this.mutate("del",a)}async apply(a){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不加载外部插件");if(a?.some(a=>this.deferredMaintenance.has(a)))throw new N;let b=await (0,p.getL4PiGlobalPluginRuntime)().scanSourceChanges(a);this.assertOpen();let c=b.filter(b=>{if(this.deferredMaintenance.has(b.source))return!1;let c=this.operations.get(b.source);if(!c||"failed"===c.phase)return!0;if(a)throw new K("该来源已有未完成操作");return!1}),d=new Set([...this.operations].filter(([,a])=>"failed"!==a.phase).map(([a])=>a));for(let a of c)d.add(a.source);if(d.size>32)throw new K("加载变更超过队列上限,请选择部分来源");for(let a of c){if(!this.operations.has(a.source)&&this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}this.operations.set(a.source,{action:"apply",phase:"queued",message:null}),this.enqueueApply(a)}return this.publish(),this.readSnapshot(!1)}enqueueApply(a){this.runExclusive(async()=>{this.activeSource=a.source;try{this.setOperation(a.source,"checking",null),await this.probeSourceChange(a),this.assertOpen(),this.setOperation(a.source,"applying",null),await (0,p.getL4PiGlobalPluginRuntime)().applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path),this.capabilityCache=null,this.operations.delete(a.source)}catch(b){this.setOperation(a.source,"failed",C(b))}finally{this.activeSource=null,this.sourceCache=null,this.publish()}}).catch(b=>{this.disposed||this.setOperation(a.source,"failed",C(b))})}async probeSourceChange(a){let b=a.current;if(!b||!b.enabled)return;if(b.error)throw new L(b.error);if(!b.path)throw new L("插件来源目录不存在");let c=performance.now();console.info("[Pi Desk][PluginManagement] 源码候选预检开始",{source:a.source});let d=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),e=(0,j.join)(d,"agent"),f=(0,j.join)(d,"workspace");await (0,i.mkdir)(e,{recursive:!0}),await (0,i.mkdir)(f,{recursive:!0});try{if(await (0,i.writeFile)((0,j.join)(e,"settings.json"),JSON.stringify({extensions:[b.path]}),"utf8"),b.piDeskRoot||b.nativePaths.length>0){let c=await (0,w.Y)(f,e,b.nativePaths.length>0),d=c.loadError??c.packages.find(a=>"failed"===a.status)?.error?.message;if(d)throw new L(d);if(b.piDeskRoot&&!c.packages.some(a=>"ready"===a.status))throw new L("预检未加载到候选 Node Entry,放弃本次变更");for(let b of c.packages)if(b.pluginName&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==a.source&&"ready"===c.status&&c.pluginName===b.pluginName))throw new L(`插件名冲突:${b.pluginName}`)}this.assertOpen()}finally{await (0,i.rm)(d,{recursive:!0,force:!0}),console.info("[Pi Desk][PluginManagement] 源码候选预检结束",{source:a.source,durationMs:Math.round(performance.now()-c)})}}reload(a){return this.activeSource||[...this.operations].some(([a,b])=>"failed"!==b.phase&&!this.deferredMaintenance.has(a))?Promise.reject(new K("维护仍在执行或等待,请先完成当前操作")):this.runExclusive(async()=>(this.assertRestartAvailable(),this.restartWhenQuiet(a)))}async mutate(a,b,c=!1,d,e={}){this.assertOpen();let f=await this.readSources(),g=this.acceptMutation(a,b,f,c,d,e);return this.enqueueMutations([g]),this.readSnapshot(!1)}acceptMutation(a,b,c,d=!1,f,g={}){if(this.assertOpen(),(0,e.P)())throw new K("基础模式不执行插件维护,请通过基础聊天修复或正常启动后维护");let h=c.sources.find(a=>(0,m.LD)(a.source)===(0,m.LD)(b));if("add"!==a){if(!h)throw new J(b);if("package"!==h.kind&&"enable"!==a&&"disable"!==a)throw new L("裸扩展不是已安装包,请编辑源码后加载变更;此操作不会删除源码")}let i=(f??=h?.source)??b;if(g.tag&&!(0,m.ug)(b))throw new L("只有 npm 插件包支持更新渠道");for(let a of[b,i])this.assertSourceIdle(a);if([...this.operations.values()].filter(a=>"failed"!==a.phase).length>=32)throw new K("插件维护队列已满,请等待当前操作完成");if(this.operations.size>=64){let a=[...this.operations].find(([,a])=>"failed"===a.phase);a&&this.operations.delete(a[0])}return f&&f!==b&&this.operations.get(f)?.phase==="failed"&&this.operations.delete(f),this.operations.set(i,{action:a,phase:"queued",message:null}),this.updates.clear(i),this.updates.clear(b),{mutation:a,source:b,operationSource:i,reinstall:d,options:g}}enqueueMutations(a){this.runExclusive(async()=>{let b=performance.now(),c=await Promise.all(a.map(async a=>{try{let b=await this.prepareMutation(a);return this.assertOpen(),this.setOperation(a.operationSource,"queued","候选检查完成,等待应用"),{input:a,prepared:b}}catch(b){return this.setOperation(a.operationSource,"failed",C(b)),null}}));for(let d of(a.length>1&&console.info("[Pi Desk][PluginManagement] 批量并行准备收尾",{count:a.length,failedCount:c.filter(a=>null===a).length,durationMs:Math.round(performance.now()-b)}),c)){if(!d)continue;let{input:a,prepared:b}=d,{source:c,operationSource:e}=a;this.activeSource=e;try{this.assertOpen(),b&&await this.executeMutation(a,b),this.deferredMaintenance.has(e)||this.operations.delete(e)}catch(a){this.setOperation(e,"failed",C(a))}finally{this.updates.clear(e),this.updates.clear(c),this.sourceCache=null,this.activeSource=null,this.publish()}}}).catch(b=>{if(!this.disposed)for(let c of a)this.setOperation(c.operationSource,"failed",C(b))}),this.publish()}async prepareMutation(a){let{mutation:b,source:c,operationSource:d,reinstall:e,options:f}=a;this.assertOpen();let g=this.createPackageManager();this.throwSettingsErrors(g.settingsManager);let h=g.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),i=h.find(a=>a.source===d),j=null,k=null,l=null;if("enable"!==b&&"disable"!==b){var n;let a=await (0,r.c)({agentDir:this.agentDir,configured:h,repairSource:"add"===b&&e?d:void 0});if(a)throw new M(a);if("add"!==b&&!i)throw new J(c);this.setOperation(d,"checking","正在确认插件版本和下载源");let g=this.candidateSource(c,i?.installedPath),o=(0,m.ug)(g),p="del"===b?{source:g,updateTag:null}:await this.updates.resolveInstall(g,d,f,"update"===b);if(k=p.updateTag,"update"===b&&o&&i?.installedPath){let a=await D(i.installedPath),b=p.source.slice(p.source.lastIndexOf("@")+1);if(!a.version)throw new L("无法读取插件已安装版本");if(!(0,m.zj)(b,a.version))return null}j={...o&&"del"!==b&&(e||i||"update"===b)?{action:"reinstall",source:p.source}:(n=p.source,{action:"add"===b?"install":"update"===b?"update":"remove",source:n}),..."registry"in p&&p.registry?{registry:p.registry}:{}},"del"!==b&&(l=await this.probeCandidate(p.source,j.registry))}return{request:j,updateTag:k,pluginName:l}}async executeMutation(a,b){let{mutation:c,source:d,operationSource:e}=a,{request:f,updateTag:g,pluginName:h}=b,i=(0,p.getL4PiGlobalPluginRuntime)(),j=a=>this.setOperation(e,"waiting",a);if(f&&(this.assertPluginNameAvailable(h,e),g&&((0,o.ks)(e,g,this.agentDir),this.updates.clear(e)),this.deferredMaintenance.size>0)){this.deferredMaintenance.set(e,f),j("等待重启后完成安装维护");return}this.assertOpen(),await i.withSourceIdle(e,async()=>{if(f){let b=this.createPackageManager();this.throwSettingsErrors(b.settingsManager);let d=b.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),f=await (0,r.c)({agentDir:this.agentDir,configured:d,repairSource:"add"===c&&a.reinstall?e:void 0});if(f)throw new M(f)}if(this.assertOpen(),this.setOperation(e,"applying",f?.registry?`下载源:${f.registry}`:null),"enable"===c||"disable"===c){let a=(0,o.to)(this.agentDir).disabled.includes((0,m.LD)(d));(0,o.El)(d,"enable"===c,this.agentDir),this.sourceCache=null;try{if(await this.applyMutationSources([d],!0),"enable"===c&&!(await this.readSources()).sources.find(a=>a.source===d)?.enabled)throw new L("此插件仍被 Pi 配置排除,请先调整原有资源配置")}catch(b){throw(0,o.El)(d,!a,this.agentDir),this.sourceCache=null,b}}else if(f)try{await i.replaceSource(e,null),await (0,s.V)(async()=>{await (0,q.wC)({maintenance:f,agentDir:this.agentDir,cwd:this.packageManagerCwd}),"del"!==c&&await this.verifyInstalledPackage(f.source)}),this.sourceCache=null,await this.applyMutationSources([e,f.source],!1)}catch(a){if(a instanceof q.rZ&&"locked"===a.kind&&(0,x.k)())this.deferredMaintenance.set(e,f),j("文件正在被使用,需要重启后完成操作");else throw a}this.updates.clear(e),this.updates.clear(d),this.capabilityCache=null},this.lifetime.signal,j)}async verifyInstalledPackage(a){let b=this.createPackageManager();this.throwSettingsErrors(b.settingsManager);let c=(0,m.LD)(a),d=b.packageManager.listConfiguredPackages().find(a=>"user"===a.scope&&(0,m.LD)(a.source)===c);if(!d?.installedPath)throw new L("插件安装后没有有效目录");await this.verifyPackageVersion(a,d.installedPath)}async verifyPackageVersion(a,b){let c=await D(b);if(c.error)throw new L("string"==typeof c.error.message?c.error.message:c.error.message.default);if((0,m.ug)(a)){let b=a.slice(a.lastIndexOf("@")+1);if(c.version!==b)throw new L(`插件实际安装版本与目标不一致:${c.version??"未知"},目标 ${b}`)}}async applyMutationSources(a,b){let c=new Set(a.map(m.LD)),d=(0,p.getL4PiGlobalPluginRuntime)(),e=await d.scanSourceChanges(),f=await this.readSources(),g=[...new Set([...e.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source),...f.sources.filter(a=>c.has((0,m.LD)(a.source))).map(a=>a.source)])];for(let a of g.length?await d.scanSourceChanges(g):[])b&&await this.probeSourceChange(a),await d.applySourceChange(a),a.current?.path&&(0,u.tt)(a.current.path),a.previous?.path&&(0,u.tt)(a.previous.path)}dispose(){this.disposed||(this.disposed=!0,this.lifetime.abort(),this.unsubscribeRuntime(),this.listeners.clear())}assertOpen(){if(this.disposed)throw new K("插件管理已关闭")}setOperation(a,b,c){let d=this.operations.get(a);if(!d)return;let e=c?.slice(0,4e3)??null;(d.phase!==b||d.message!==e)&&(this.operations.set(a,{...d,phase:b,message:e}),"failed"===b&&console.warn("[Pi Desk][PluginManagement] 插件操作失败",{source:a,action:d.action,message:e}),this.publish())}publish(){if(!this.disposed)for(let a of this.listeners)try{a()}catch(a){console.warn("[Pi Desk][PluginManagement] 状态监听失败",{message:C(a)})}}async readSources(){let a=()=>null!==this.activeSource&&this.operations.get(this.activeSource)?.phase==="applying";if(a()&&this.sourceCache)return this.sourceCache;let b=await (0,t.o)(this.packageManagerCwd,this.agentDir,{DefaultPackageManager:k.DefaultPackageManager,SettingsManager:k.SettingsManager});return a()&&this.sourceCache||(this.sourceCache=b),a()&&this.sourceCache?this.sourceCache:b}async probeCandidate(a,b){let c=(0,j.join)(this.stagingRoot,(0,h.randomUUID)()),d=(0,j.join)(c,"agent"),e=(0,j.join)(c,"workspace");await (0,i.mkdir)(e,{recursive:!0}),console.info("[Pi Desk][PluginManagement] 开始在隔离 AgentDir 预检候选插件",{source:a});try{if(!b&&(0,m.ug)(a))for(let b of[".npmrc",(0,j.join)("etc","npmrc")]){let c=(0,j.join)(d,"npm",b);await (0,i.mkdir)((0,j.dirname)(c),{recursive:!0});try{await (0,i.copyFile)((0,j.join)(this.agentDir,"npm",b),c),console.info("[Pi Desk][PluginManagement] 已为隔离预检继承本机 npm 配置",{source:a,configPath:b})}catch(a){if("ENOENT"!==a.code)throw new L(`无法继承本机 npm 配置(${b}):${C(a)}`)}}await (0,q.wC)({maintenance:{action:"install",source:a,...b?{registry:b}:{}},agentDir:d,cwd:e,signal:this.lifetime.signal}),this.assertOpen();let c=this.createPackageManager(d,e);this.throwSettingsErrors(c.settingsManager);let f=c.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope)[0];if(!f?.installedPath)throw new L("候选插件安装后没有有效目录");await this.verifyPackageVersion(a,f.installedPath);let g=await (0,w.Y)(e,d,!0,this.lifetime.signal);if(g.loadError)throw new L(g.loadError);let h=g.packages.find(a=>"failed"===a.status);if(h?.error)throw new L(h.error.message);let k=g.packages[0]?.pluginName??null;return this.assertOpen(),console.info("[Pi Desk][PluginManagement] 候选插件隔离预检通过",{source:a}),k}catch(a){if(a instanceof L)throw a;throw new L(C(a))}finally{await (0,i.rm)(c,{recursive:!0,force:!0}).catch(a=>{console.warn("[Pi Desk][PluginManagement] 清理候选插件目录失败",{path:c,errorName:a instanceof Error?a.name:"UnknownError"})})}}assertPluginNameAvailable(a,b){if(a&&(0,p.getL4PiGlobalPluginRuntime)().readDiagnostics().packages.some(c=>c.source!==b&&c.pluginName===a))throw new L(`pluginName 已由其他 Package 注册:${a}`)}restartWhenQuiet(a){return this.workSessions.runPluginRestart(async()=>{let b=(0,p.getL4PiGlobalPluginRuntime)(),c=await this.readSnapshot(!1);return await b.prepareReload(),console.info("[Pi Desk][PluginManagement] 插件 Runtime 已通过静默检查,准备重启",{deferredCount:this.deferredMaintenance.size}),(0,x.Z)("basic"===a||0===this.deferredMaintenance.size?void 0:[...this.deferredMaintenance.values()],a),c})}async readDetail(a){if((0,e.P)())throw new K("基础模式不执行插件能力盘点");let b=(await this.readSources()).sources.find(b=>b.source===a),c=b?await (0,t.W)(b):null;if(!c)throw new J(a);let d=await this.readCapabilities(!1),f=d.packages.find(b=>b.source===a);if(!f)throw Error(d.loadError??`插件能力详情不可用:${a}`);let[g,h]=await Promise.all([Promise.all(f.skills.map(async a=>({name:a.name,description:a.description,path:a.path,modelVisible:a.modelVisible,...await E(c,a.filePath)}))),Promise.all(f.prompts.map(async a=>({name:a.name,description:a.description,path:a.path,...await E(c,a.filePath)})))]);return l.tA.parse({source:a,readme:await (0,n.w$)(c),tools:f.tools.map(a=>({name:a.name,label:a.label,state:a.state,description:a.description,parameters:a.parameters,promptSnippet:a.promptSnippetDetail,promptGuidelines:a.promptGuidelines})),skills:g,prompts:h})}async readSnapshot(a){if((0,e.P)())return{plugins:[],restartRequired:!1,loadError:this.maintenanceError};let b=this.createPackageManager(),c=b.settingsManager.drainErrors().map(a=>a.error.message),d=b.packageManager.listConfiguredPackages().filter(a=>"user"===a.scope),f=await (0,r.c)({agentDir:this.agentDir,configured:d}),h=await this.readSources(),i=await this.updates.read(h.sources,"boolean"==typeof a?{checkUpdates:a}:a),j=(0,p.getL4PiGlobalPluginRuntime)(),k=j.readDiagnostics(),n=new Map(k.packages.map(a=>[a.source,a])),q=(0,u.u7)(),s=this.capabilityCache??{packages:[],loadError:null},t=new Map(s.packages.map(a=>[a.source,a])),v=new Map(j.readCapabilityRegistrations().map(a=>[a.source,a])),w=await Promise.all(h.sources.map(async a=>{let b=n.get(a.source),c=a.path?this.findNativeDiagnostic(a.path,q):null,d=(a.error?{phase:"package"===a.kind?"package":"entry",message:a.error}:null)??(b?.status==="failed"?b.error:null)??(c?{phase:"native",message:c}:null);return{source:a.source,kind:a.kind,operation:this.operationFor(a.source),pluginName:b?.pluginName??null,description:a.description,version:a.version??b?.version??null,updateAvailable:i.get(a.source)?.updateAvailable??null,updateTag:i.get(a.source)?.updateTag??null,availableVersion:i.get(a.source)?.availableVersion??null,updateError:i.get(a.source)?.updateError??null,status:a.enabled?d?"failed":b?.status==="ready"?"ready":"available":"disabled",error:d,capabilities:F(t.get(a.source),v.get(a.source),s.loadError)}}));for(let[a,b]of this.operations)w.some(b=>(0,m.LD)(b.source)===(0,m.LD)(a))||w.push({source:a,kind:"package",operation:b,pluginName:null,description:null,version:null,updateAvailable:null,updateTag:(0,m.ug)(a)?(0,o.ey)(a,this.agentDir):null,availableVersion:null,updateError:null,status:"failed"===b.phase?"failed":"available",error:null,capabilities:F(void 0,void 0,null)});return l.oP.parse({plugins:w.sort((a,b)=>a.source.localeCompare(b.source)),restartRequired:this.restartRequired,loadError:function(a){let b=[...new Map(a.flatMap(a=>{let b=("string"==typeof a?a:a.message).trim();return b?[[b,{defaultText:b,englishText:"string"==typeof a?b:a.englishMessage.trim()}]]:[]})).values()];if(0===b.length)return null;let c=b.map(a=>a.defaultText).join("; ");return b.every(a=>a.defaultText===a.englishText)?c:(0,g.J8)(c,b.map(a=>a.englishText).join("; "))}([...c,...h.errors,...k.loadError?[k.loadError]:[],...this.maintenanceError?[this.maintenanceError]:[],...f?[f]:[]])})}async readCapabilities(a){if(!a&&this.capabilityCache)return this.capabilityCache;try{return this.capabilityCache=await (0,s.V)(()=>(this.assertOpen(),!a&&this.capabilityCache)?Promise.resolve(this.capabilityCache):(0,v.a)(this.cwd,this.agentDir)),this.publish(),console.info("[Pi Desk][PluginManagement] 插件能力盘点完成",{packageCount:this.capabilityCache.packages.length,hasLoadError:null!==this.capabilityCache.loadError}),this.capabilityCache}catch(b){let a=C(b);return console.warn("[Pi Desk][PluginManagement] 插件能力盘点失败",{errorName:b instanceof Error?b.name:"UnknownError",message:a}),this.capabilityCache={packages:[],loadError:a},this.publish(),this.capabilityCache}}findNativeDiagnostic(a,b){let c,d=(c=(0,j.resolve)(a).replaceAll("\\","/"),"win32"===process.platform?c.toLowerCase():c),e=b.find(a=>("win32"===process.platform?a.message.replaceAll("\\","/").toLowerCase():a.message.replaceAll("\\","/")).includes(d));return e?.message??null}createPackageManager(a=this.agentDir,b=this.packageManagerCwd){let c=k.SettingsManager.create(b,a,{projectTrusted:!1});return{settingsManager:c,packageManager:new k.DefaultPackageManager({cwd:b,agentDir:a,settingsManager:c})}}candidateSource(a,b){return(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:b?(0,j.resolve)(b):(0,j.resolve)(this.agentDir,a)}operationFor(a){let b=(0,m.LD)(a);return[...this.operations].find(([a])=>(0,m.LD)(a)===b)?.[1]??null}normalizeAddedSource(a){return/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*(?:@[^\s/]+)?$/i.test(a)?`npm:${a}`:(0,j.isAbsolute)(a)||/^(?:[a-z][a-z0-9+.-]*:|git@)/i.test(a)?a:(0,j.resolve)(this.cwd,a)}throwSettingsErrors(a){let b=a.drainErrors();if(0!==b.length)throw Error(b.map(a=>a.error.message).join("; "))}assertRestartAvailable(){if(!(0,x.k)())throw new O}runExclusive(a){let b=()=>this.staleStagingCleanup.then(()=>(this.assertOpen(),a())),c=this.operationTail.then(b,b);return this.operationTail=c.then(()=>void 0,()=>void 0),c}}function G(){globalThis.__piDeskPluginManagement?.dispose()}function H(a){globalThis.__piDeskPluginManagement||(globalThis.__piDeskPluginManagement=new P(a))}function I(){if(!globalThis.__piDeskPluginManagement)throw Error("插件管理尚未完成进程级装配");return globalThis.__piDeskPluginManagement}d()}catch(a){d(a)}})},53584:(a,b,c)=>{c.d(b,{a:()=>l});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_CAPABILITIES__",i=e.Yj(),j=e.Ik({name:e.Yj(),description:e.Yj().nullable()}).strict(),k=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),error:e.Yj().nullable(),extensions:e.YO(e.Ik({path:e.Yj(),events:e.YO(e.Ik({name:e.Yj(),count:e.ai().int().positive()}).strict()),commands:e.YO(j),shortcuts:e.YO(e.Ik({shortcut:e.Yj(),description:e.Yj().nullable()}).strict()),flags:e.YO(e.Ik({name:e.Yj(),type:e.k5(["boolean","string"]),description:e.Yj().nullable(),default:e.KC([e.zM(),e.Yj(),e.ch()])}).strict()),messageRenderers:e.YO(e.Yj()),entryRenderers:e.YO(e.Yj())}).strict()),tools:e.YO(e.Ik({name:e.Yj(),label:i,state:e.k5(["active","inactive","shadowed"]),description:i,parameters:e.g1(e.Yj(),e.Pq()),promptSnippet:i.nullable(),promptSnippetDetail:i.nullable(),promptGuidelines:e.YO(i),promptGuidelineCount:e.ai().int().nonnegative(),promptGuidelinePreview:i.nullable()}).strict()),skills:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj(),modelVisible:e.zM()}).strict()),prompts:e.YO(e.Ik({name:e.Yj(),description:e.Yj(),path:e.Yj(),filePath:e.Yj()}).strict()),themes:e.YO(e.Ik({name:e.Yj(),path:e.Yj()}).strict()),providers:e.YO(e.Ik({name:e.Yj(),kind:e.k5(["config","native"])}).strict())}).strict()),loadError:e.Yj().nullable()}).strict();async function l(a,b){let c=(0,f.I)(),e=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-capability-probe-runner.mts"),{stdout:i,stderr:j,code:l}=await (0,g.i)({args:["--conditions=react-server","--import",c,e],agentDir:b,env:{PI_DESK_PLUGIN_CAPABILITY_AGENT_DIR:b,PI_DESK_PLUGIN_CAPABILITY_CWD:a},maxOutputBytes:4194304,timeoutMs:3e4,timeoutError:()=>Error("插件能力盘点超时")});if(0!==l)throw Error(j.trim()||`插件能力盘点进程退出码 ${l??"null"}`);let m=i.lastIndexOf(h);if(m<0)throw Error("插件能力盘点没有返回有效结果");let n=i.slice(m+h.length).split(/\r?\n/,1)[0];return k.parse(JSON.parse(n))}},64253:(a,b,c)=>{c.a(a,async(a,d)=>{try{let s;c.d(b,{B:()=>q,I:()=>r});var e=c(31421),f=c(73024),g=c(51455),h=c(76760),i=c(48161),j=c(57975),k=c(75430),l=a([k]);k=(l.then?(await l)():l)[0];let t=(0,j.promisify)(e.execFile);function m(a){return a.replace(/\$\{([^}]+)\}/g,(a,b)=>process.env[b]??a)}async function n(a,b){let c;try{let b=await (0,g.readFile)(a);if(b.length>262144)throw Error("npm 配置文件过大");c=b.toString("utf8")}catch(a){if("ENOENT"===a.code)return;throw a}for(let a of c.split(/\r?\n/)){let c=/^\s*([^;#][^=]*?)\s*=\s*(.*?)\s*$/.exec(a);if(!c)continue;let d=c[2].replace(/\s+[;#].*$/,"").replace(/^(['"])(.*)\1$/,"$2");b[c[1].trim()]=m(d)}}function o(a,b){return("win32"===process.platform?/^~[\\/]/:/^~\//).test(a)?(0,h.resolve)((0,i.homedir)(),a.slice(2)):(0,h.resolve)(b,a)}async function p(a,b){let c={};for(let[a,b]of Object.entries(process.env))if(void 0!==b&&""!==b&&/^npm_config_/i.test(a)){let d=a.slice(11);c[d.startsWith("//")?d:d.replace(/(?!^)_/g,"-").toLowerCase()]=m(b)}let d=function(){for(let a of[(0,h.dirname)(process.execPath),...(process.env.PATH??"").split("win32"===process.platform?";":":")])for(let b of[(0,h.join)(a,"node_modules/npm/bin/npm-cli.js"),(0,h.resolve)(a,"../lib/node_modules/npm/bin/npm-cli.js")])if((0,f.existsSync)(b))return b}(),e={};if(d)try{await (0,g.mkdir)(a,{recursive:!0});let c=await t(process.execPath,[d,"config","list","--json","--prefix",b],{cwd:a,timeout:4e3,maxBuffer:524288,windowsHide:!0});e=JSON.parse(c.stdout)}catch{console.warn("[Pi Desk][PluginRegistry] npm 有效配置读取失败,改用 npmrc 和环境配置")}let j={};d&&await n((0,h.resolve)((0,h.dirname)(d),"../npmrc"),j);let k="string"==typeof e.globalconfig?e.globalconfig:c.globalconfig??(0,h.join)(b,"etc/npmrc"),l="string"==typeof e.userconfig?e.userconfig:c.userconfig??(0,h.join)((0,i.homedir)(),".npmrc");for(let[d,f]of(await n(o(k,a),j),await n(o(l,a),j),!0!==e.global&&"true"!==c.global&&"global"!==e.location&&"global"!==c.location&&await n((0,h.join)(b,".npmrc"),j),Object.entries(e)))"string"!=typeof f||"(protected)"===f||/auth|password|username/i.test(d)||(j[d]=f);return{...j,...c}}function q(a=(0,k.getAgentDir)()){let b=process.env.PI_DESK_PACKAGE_MAINTENANCE_CWD??(0,h.join)(a,"pi-desk","plugin-package-manager"),c=(0,h.join)(a,"npm");if(!s||s.cwd!==b||s.prefix!==c||s.expires<=Date.now()){let a=p(b,c);s={cwd:b,prefix:c,expires:Date.now()+3e4,value:a},a.catch(()=>{s?.value===a&&(s=void 0)})}return s.value}function r(a,b){let c=`//${a.host}${a.pathname}`;for(let a of Object.keys(b).flatMap(a=>{let b=/^(\/\/.*\/):(?:_authToken|_auth|username|_password)$/i.exec(a);return b&&c.startsWith(b[1])?[b[1]]:[]}).sort((a,b)=>b.length-a.length)){let c=b[`${a}:_authToken`]??b[`${a}:_authtoken`];if(c&&!c.includes("${"))return`Bearer ${c}`;let d=b[`${a}:_auth`];if(d&&!d.includes("${"))return`Basic ${d}`;let e=b[`${a}:username`],f=b[`${a}:_password`];if(e&&f&&!f.includes("${"))return`Basic ${Buffer.from(`${e}:${Buffer.from(f,"base64").toString("utf8")}`).toString("base64")}`}let d=b.registry;if(d){let c=new URL(d);if(a.origin===c.origin&&a.pathname.startsWith(`${c.pathname.replace(/\/+$/,"")}/`)){let a=b._authToken??b._authtoken;if(a&&!a.includes("${"))return`Bearer ${a}`;if(b._auth&&!b._auth.includes("${"))return`Basic ${b._auth}`}}}d()}catch(a){d(a)}})},69371:(a,b,c)=>{c.d(b,{rZ:()=>g,wC:()=>h});var d=c(76760),e=c(86148),f=c(2472);class g extends Error{constructor(a,b,c){super(b.slice(-4e3)||`Pi Package 命令退出码 ${c??"null"}`),this.kind=a,this.output=b,this.exitCode=c,this.name="L4PiPackageMaintenanceError"}}async function h(a){let b=(0,e.I)(),c=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-package-maintenance-runner.mts"),{stdout:h,stderr:i,code:j}=await (0,f.i)({args:["--import",b,c,a.maintenance.action,a.maintenance.source,...a.maintenance.registry?[a.maintenance.registry]:[]],agentDir:a.agentDir,env:{PI_DESK_PACKAGE_MAINTENANCE_CWD:a.cwd},maxOutputBytes:1048576,timeoutMs:12e4,signal:a.signal,timeoutError:()=>new g("failed","包维护超过120秒,已停止;结果未确认,请检查配置后手动处理",null)});if(0===j)return;let k=(i||h).trim();throw new g(function(a){let b=a.toLowerCase();if(b.includes("ebusy")||b.includes("etxtbsy")||b.includes("resource busy")||b.includes("being used by another process")||b.includes("used by another process")||b.includes("process cannot access the file because it is being used"))return"locked";let c=b.includes("eperm")||b.includes("eacces")||b.includes("operation not permitted"),d=/\b(unlink|rename|rmdir|rimraf|remove|cleanup)\b/.test(b);return c&&d?"locked":"failed"}(k),k,j)}},69375:(a,b,c)=>{c.d(b,{Od:()=>r,tU:()=>n,hE:()=>q,P9:()=>f,_G:()=>j,Vc:()=>i});var d=c(36153);d.Yj().uuid();let e=d.Ik({key:d.Yj().min(1).max(160),params:d.g1(d.Yj().min(1).max(80),d.KC([d.Yj().max(1e3),d.ai().finite()])).optional()}).strict(),f=4001,g=d.Yj().trim().min(1),h=d.Yj().uuid();function i(a){return Object.freeze({op:"req",path:g.parse(a.path),inputSchema:a.inputSchema,outputSchema:a.outputSchema,...void 0===a.timeoutMs?{}:{timeoutMs:d.ai().int().positive().parse(a.timeoutMs)}})}function j(a){return Object.freeze({op:"push",path:g.parse(a.path),bodySchema:a.bodySchema})}let k=d.Ik({op:d.eu("req"),path:g,requestId:h}).strict(),l=d.Ik({op:d.eu("resp"),path:g,requestId:h}).strict(),m=d.Ik({op:d.eu("push"),path:g}).strict(),n=d.Ik({head:k,body:d.Pq()}).strict(),o=d.Ik({head:l,body:d.Ik({code:d.eu(0),msg:d.eu(""),data:d.Pq()}).strict()}).strict(),p=d.Ik({head:l,body:d.Ik({code:d.ai().int().positive(),msg:d.Yj().min(1),data:d.ch(),i18n:e.optional()}).strict()}).strict(),q=d.KC([o,p]),r=d.Ik({head:m,body:d.Pq()}).strict()},72497:(a,b,c)=>{c.d(b,{Dz:()=>h,f7:()=>g,tv:()=>f});var d=c(36153);let e=d.Yj().trim().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),f=e,g=e,h=d.g1(d.Yj(),d.Pq());d.Yj().trim().min(3).max(129).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*\/[a-z0-9]+(?:-[a-z0-9]+)*$/);let i=d.k5(["plugin","server","rocket","settings","panel","message","terminal","file","folder","bot","wrench","database","globe"]);d.gM("type",[d.Ik({type:d.eu("builtin"),name:i}).strict(),d.Ik({type:d.eu("svg"),content:d.Yj().trim().min(1).max(16384)}).strict()])},73159:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{NL:()=>h,XH:()=>j,Yq:()=>i});var e=c(77598),f=c(64253),g=a([f]);f=(g.then?(await g)():g)[0];class j extends Error{constructor(a,b=502,c="invalid"){super(a),this.status=b,this.reason=c,this.name="L4PluginRegistryError"}}let k=new Map,l=0;async function h(a,b){b.signal?.throwIfAborted();let c=!1===b.auth?{}:await (0,f.B)(b.agentDir),d=(0,f.I)(a,c),g=`${a.href}:${b.limit}:${(0,e.createHash)("sha256").update(d??"").digest("hex")}`,h=k.get(g);if(!1!==b.cache&&h&&h.expires>Date.now())return h.body;let i=AbortSignal.any([AbortSignal.timeout(b.timeout??1e4),...b.signal?[b.signal]:[]]),m=a;try{for(let a=0;a<=3;a++){let d=(0,f.I)(m,c),e=await fetch(m,{signal:i,redirect:"manual",headers:d?{Authorization:d}:{}});if([301,302,303,307,308].includes(e.status)){await e.body?.cancel();let b=e.headers.get("location");if(!b||3===a)throw new j("插件源重定向无效");let c=new URL(b,m);if(!["http:","https:"].includes(c.protocol)||c.username||c.password||"https:"===m.protocol&&"https:"!==c.protocol)throw new j("插件源重定向不安全");m=c;continue}if(!e.ok){await e.body?.cancel();let a=404===e.status?"missing":[401,403].includes(e.status)?"denied":e.status>=500?"network":"invalid";throw new j(`插件源请求失败(HTTP ${e.status})`,e.status,a)}if(Number(e.headers.get("content-length")??0)>b.limit)throw await e.body?.cancel(),new j("插件源响应超过大小限制");let h=e.body?.getReader(),n=[],o=0;if(h)try{for(;;){let a=await h.read();if(a.done)break;if((o+=a.value.byteLength)>b.limit)throw new j("插件源响应超过大小限制");n.push(a.value)}}finally{await h.cancel().catch(()=>void 0),h.releaseLock()}let p=Buffer.concat(n);if(!1!==b.cache){for(let[a,b]of k)(b.expires<=Date.now()||a===g)&&(k.delete(a),l-=b.body.length);for(;k.size>=96||l+p.length>0x1800000;){let a=k.entries().next().value;if(!a)break;k.delete(a[0]),l-=a[1].body.length}p.length<=0x1800000&&(k.set(g,{body:p,expires:Date.now()+12e4}),l+=p.length)}return p}throw new j("插件源重定向过多")}catch(a){if(b.signal?.aborted)throw b.signal.reason;if(a instanceof j)throw a;throw new j("插件源网络连接失败或超时",502,"network")}}async function i(a,b,c){let d=await h(a,{limit:8388608,signal:b,agentDir:c});try{let a=JSON.parse(d.toString("utf8"));if(!a||"object"!=typeof a||Array.isArray(a))throw Error("invalid");return a}catch{throw new j("插件源返回的元数据格式无效")}}d()}catch(a){d(a)}})},75157:(a,b,c)=>{c.d(b,{c:()=>h});var d=c(51455),e=c(76760);function f(a){if(!a.startsWith("npm:"))return null;let b=a.slice(4).trim(),c=b.match(/^(@?[^@]+(?:\/[^@]+)?)(?:@(.+))?$/);return c?.[1]??(b||null)}async function g(a){try{return(await (0,d.stat)(a)).isDirectory()}catch{return!1}}async function h(a){let b=a.configured.flatMap(a=>{let b=f(a.source);return b?[{name:b,item:a}]:[]}),c=(0,e.join)(a.agentDir,"npm","package.json"),h={};try{let a=JSON.parse(await (0,d.readFile)(c,"utf8"));a.dependencies&&"object"==typeof a.dependencies&&(h=a.dependencies)}catch(c){if(0===b.length)return null;let a=c instanceof Error&&c.message?c.message:String(c);return{message:`Pi Package npm 根不可用:${a}`,englishMessage:`Pi Package npm root is unavailable: ${a}`,i18n:{key:"errors:pluginNpmRootUnavailable",params:{detail:a.slice(0,1e3)}}}}let i=a.repairSource?f(a.repairSource):null,j=b.filter(a=>a.name!==i),k=new Set(j.map(a=>a.name)),l=new Set(Object.keys(h)),m=[...k].filter(a=>!l.has(a)),n=[];for(let{name:a,item:b}of j)b.installedPath&&await g(b.installedPath)||n.push(a);if(0===m.length&&0===n.length)return null;let o=[m.length>0?`缺少声明:${m.join("、")}`:null,n.length>0?`缺少目录:${n.join("、")}`:null].filter(a=>null!==a),p=[m.length>0?`missing declarations: ${m.join(", ")}`:null,n.length>0?`missing folders: ${n.join(", ")}`:null].filter(a=>null!==a),q=m.length>0?n.length>0?"errors:pluginNpmRootMissingBoth":"errors:pluginNpmRootMissingDeclarations":"errors:pluginNpmRootMissingFolders";return{message:`Pi Package 配置与 npm 根不一致(${o.join(";")})`,englishMessage:`Pi Package configuration does not match the npm root (${p.join("; ")})`,i18n:{key:q,params:{declarations:m.join(", ").slice(0,1e3),folders:n.join(", ").slice(0,1e3)}}}}},76019:(a,b,c)=>{c.d(b,{J8:()=>f,fD:()=>g,qf:()=>e});var d=c(36153);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}}}function g(a,b){return"string"==typeof a?a:a.translations[b]??a.translations[b.split("-")[0]]??a.default}},78597:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.d(b,{E:()=>k});var e=c(75430),f=c(4287),g=c(5235),h=c(34458),i=c(47154),j=a([e,g,h]);[e,g,h]=j.then?(await j)():j;class k{constructor(a,b,c){this.agentDir=a,this.cwd=b,this.signal=c,this.cache=new Map}async resolveInstall(a,b,c,d){let e=(0,f.ug)(a),i=e?/^npm:(?:@[^/]+\/)?[^@]+@([^@]+)$/.exec(a)?.[1]:void 0,j=i&&!/^v?\d+\./.test(i)&&f.mR.safeParse(i).success?i:null,k=e?d?(0,g.ey)(b,this.agentDir):c.tag??j??(0,g.ey)(b,this.agentDir):null,l=e&&k&&(d||!i)?`npm:${e}@${k}`:a;return{...await (0,h.dz)(l,{...c,agentDir:this.agentDir,signal:this.signal,cache:!d&&void 0}),updateTag:k}}clear(a){let b=(0,f.LD)(a);for(let[a,c]of this.cache)c.identity===b&&this.cache.delete(a)}async read(a,b){for(let[a,b]of this.cache)b.expiresAt<=Date.now()&&this.cache.delete(a);let c=b.sources?new Set(b.sources.map(f.LD)):null,d=new Map;for(let j of a){if("package"!==j.kind)continue;let a=(0,f.LD)(j.source),k=(0,f.ug)(j.source),l=k?(0,g.ey)(j.source,this.agentDir):null,m={updateTag:l,updateAvailable:null,availableVersion:null,updateError:null};d.set(j.source,m);let n=!0===b.checkUpdates&&(!c||c.has(a))&&(!b.tag||b.tag===l);if(k){if(!n&&![...this.cache.values()].some(b=>b.identity===a))continue;let b=null;try{let c=(0,g.to)(this.agentDir).downloadSource,e=await (0,h.qX)(k,{agentDir:this.agentDir,downloadSource:c});b=JSON.stringify([a,l,c.mode,e.registry,e.fallback]);let i=this.cache.get(b)?.value;if(n){if(!j.path||!j.version)throw Error("无法读取插件已安装版本");let d=await (0,h.dz)(`npm:${k}@${l}`,{downloadSource:c,agentDir:this.agentDir,signal:this.signal,cache:!1}),e=d.source.slice(d.source.lastIndexOf("@")+1);i={...m,availableVersion:e},this.store(b,a,i)}i&&d.set(j.source,{...i,updateAvailable:!i.updateError&&j.version&&i.availableVersion?(0,f.zj)(i.availableVersion,j.version):null})}catch(e){let c={...m,updateError:this.message(j.source,e)};d.set(j.source,c),b&&this.store(b,a,c)}}else if(/^(?:git:|https?:|git@)/.test(j.source)){let b=JSON.stringify([a,"git"]),c=this.cache.get(b)?.value;if(c&&d.set(j.source,c),!n)continue;try{let c=e.SettingsManager.inMemory({packages:[j.source]}),f=new e.DefaultPackageManager({agentDir:this.agentDir,cwd:this.cwd,settingsManager:c}),g=await (0,i.V)(()=>f.checkForAvailableUpdates()),h={...m,updateAvailable:g.some(a=>"user"===a.scope)};d.set(j.source,h),this.store(b,a,h)}catch(e){let c={...m,updateError:this.message(j.source,e)};d.set(j.source,c),this.store(b,a,c)}}}return d}store(a,b,c){for(this.cache.delete(a);this.cache.size>=128;){let a=this.cache.keys().next().value;if(void 0===a)break;this.cache.delete(a)}this.cache.set(a,{identity:b,expiresAt:Date.now()+3e5,value:c})}message(a,b){let c=(b instanceof Error?b.message:String(b)).slice(0,4e3);return console.warn("[Pi Desk][PluginManagement] 检查插件更新失败",{source:a,message:c}),this.clear(a),c}}d()}catch(a){d(a)}})},86148:(a,b,c)=>{function d(a){let b=a.replaceAll("\\","/");return"tsx"===b||/(?:^|\/)tsx(?:\/|$)/.test(b)}function e(a=process.execArgv){for(let b=0;b<a.length;b+=1){let c=a[b];if("--import"===c){let c=a[b+1];if(c&&d(c))return c;b+=1;continue}if(c.startsWith("--import=")){let a=c.slice(9);if(d(a))return a}}throw Error("Pi Desk 服务缺少 tsx loader,无法启动插件维护子进程")}c.d(b,{I:()=>e})},93951:(a,b,c)=>{c.d(b,{LC:()=>E,tA:()=>G,oP:()=>H});var d=c(36153),e=c(72497),f=c(76019),g=c(4287),h=c(69375);let i=g.SZ,j=g.w3;d.Ik({downloadSource:j,recommendedRegistry:i}).strict(),d.Ik({downloadSource:j}).strict(),d.Ik({query:d.Yj().trim().max(200).default(""),page:d.ai().int().min(1).max(100).default(1),kind:d.k5(["all","desk","pi"]).default("all"),registry:i.optional()}).strict(),d.Ik({name:d.Yj().trim().min(1).max(214).regex(/^(?:@[a-z0-9_.-]+\/)?[a-z0-9][a-z0-9_.-]*$/i),version:d.Yj().trim().min(1).max(128).optional(),registry:i.optional()}).strict();let k=d.Ik({name:d.Yj(),description:f.qf.nullable(),version:d.Yj(),publisher:d.Yj().nullable(),kind:d.k5(["desk","pi","unknown"]),official:d.zM(),registry:i}).strict();d.Ik({items:d.YO(k),hasMore:d.zM()}).strict(),k.extend({versions:d.YO(d.Yj()),readme:f.qf.nullable(),homepage:d.Yj().nullable(),repository:d.Yj().nullable(),compatible:d.zM().nullable(),compatibilityNote:d.Yj().nullable()}).strict();let l=d.Yj().trim().min(1).max(2048),m=g.mR,n=d.YO(l).min(1).max(32),o=d.Ik({phase:d.k5(["package","entry","setup","resources","resolve","native"]),message:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0)}).strict(),p=d.Yj().trim().min(1).max(4096),q=d.Yj().trim().min(1).max(256),r=d.Yj().max(32768),s=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,promptSnippet:r.nullable(),promptGuidelineCount:d.ai().int().nonnegative(),promptGuidelinePreview:r.nullable()}).strict(),t=d.Ik({name:q,label:r,state:d.k5(["active","inactive","shadowed"]),description:r,parameters:e.Dz,promptSnippet:r.nullable(),promptGuidelines:d.YO(r)}).strict(),u=d.Ik({path:p,events:d.YO(d.Ik({name:q,count:d.ai().int().positive()}).strict()),commands:d.YO(d.Ik({name:q,description:r.nullable()}).strict()),shortcuts:d.YO(d.Ik({shortcut:q,description:r.nullable()}).strict()),flags:d.YO(d.Ik({name:q,type:d.k5(["boolean","string"]),description:r.nullable(),default:d.KC([d.zM(),d.Yj(),d.ch()])}).strict()),messageRenderers:d.YO(q),entryRenderers:d.YO(q)}).strict(),v=d.Ik({name:q,description:r,path:p}).strict(),w=v.extend({modelVisible:d.zM()}).strict(),x=v.extend({content:d.Yj().max(65536),truncated:d.zM()}).strict(),y=x.extend({modelVisible:d.zM()}).strict(),z=d.Ik({name:q,path:p}).strict(),A=d.Ik({name:q,kind:d.k5(["config","native"])}).strict(),B=d.Ik({methods:d.YO(d.Ik({pluginName:q,method:q}).strict()),browserEntries:d.YO(d.Ik({pluginName:q}).strict()),messageDeclarations:d.YO(d.Ik({pluginName:q,declarationName:q,priority:d.ai().int().safe()}).strict())}).strict(),C=d.Ik({error:f.qf.refine(a=>"string"==typeof a?a.length<=32768:[a.default,...Object.values(a.translations)].every(a=>a.length<=32768)).nullable(),extensions:d.YO(u),tools:d.YO(s),skills:d.YO(w),prompts:d.YO(v),themes:d.YO(z),providers:d.YO(A),piDesk:B}).strict(),D=d.Ik({action:d.k5(["add","update","del","apply","enable","disable"]),phase:d.k5(["queued","checking","applying","waiting","failed"]),message:d.Yj().max(4e3).nullable()}).strict(),E=(0,h._G)({path:"plugins/management-update",bodySchema:d.Ik({}).strict()}),F=d.Ik({source:l,kind:d.k5(["package","extension"]).default("package"),operation:D.nullable().default(null),pluginName:d.Yj().trim().min(1).nullable(),description:f.qf.nullable().default(null),version:d.Yj().trim().min(1).nullable(),updateAvailable:d.zM().nullable(),updateTag:m.nullable().optional(),availableVersion:d.Yj().min(1).nullable().optional(),updateError:d.Yj().max(4e3).nullable().optional(),status:d.k5(["ready","available","disabled","failed"]),error:o.nullable(),capabilities:C}).strict(),G=d.Ik({source:l,readme:f.qf.nullable().default(null),tools:d.YO(t),skills:d.YO(y),prompts:d.YO(x)}).strict(),H=d.Ik({plugins:d.YO(F),restartRequired:d.zM(),loadError:f.qf.refine(a=>"string"==typeof a?a.length>0:a.default.length>0).nullable()}).strict();d.Ik({sources:d.YO(l).min(1).max(32).optional()}).strict(),d.Ik({}).strict().extend({mode:d.k5(["normal","basic"]).optional()}).strict(),d.Ik({checkUpdates:d.zM().optional(),sources:n.optional(),tag:m.optional()}).strict();let I=d.Ik({source:l}).strict(),J=I.extend({downloadSource:j.optional(),registry:i.optional(),tag:m.optional()}).strict();d.gM("action",[d.Ik({action:d.eu("add"),items:d.YO(J).min(1).max(32)}).strict(),d.Ik({action:d.eu("update"),sources:n}).strict(),d.Ik({action:d.eu("del"),sources:n}).strict(),d.Ik({action:d.eu("tag"),sources:n,tag:m}).strict()]),d.Ik({snapshot:H,results:d.YO(d.Ik({source:l,error:d.Yj().max(4e3).nullable()}).strict()).max(32)}).strict(),I.extend({enabled:d.zM()}).strict()},96783:(a,b,c)=>{c.d(b,{Y:()=>j});var d=c(76760),e=c(36153),f=c(86148),g=c(2472);let h="__PI_DESK_PLUGIN_PROBE__",i=e.Ik({packages:e.YO(e.Ik({source:e.Yj(),packageName:e.Yj().nullable(),version:e.Yj().nullable(),pluginName:e.Yj().nullable(),status:e.k5(["ready","failed"]),error:e.Ik({phase:e.k5(["package","entry","setup","resources","resolve"]),message:e.Yj()}).strict().nullable()}).strict()),loadError:e.Yj().nullable()}).strict();async function j(a,b,c=!1,e){let k=(0,f.I)(),l=(0,d.join)(process.cwd(),"src","server","l4_foundation","pi","l4-pi-plugin-probe-runner.mts"),{stdout:m,stderr:n,code:o}=await (0,g.i)({args:["--conditions=react-server","--import",k,l],agentDir:b,env:{PI_DESK_PLUGIN_PROBE_AGENT_DIR:b,PI_DESK_PLUGIN_PROBE_CWD:a,PI_DESK_PLUGIN_PROBE_NATIVE:c?"1":void 0},maxOutputBytes:1048576,timeoutMs:3e4,signal:e,timeoutError:()=>Error("插件预检超时")});if(0!==o)throw Error(n.trim()||`插件预检进程退出码 ${o??"null"}`);let p=m.lastIndexOf(h);if(p<0)throw Error("插件预检没有返回有效结果");let q=m.slice(p+h.length).split(/\r?\n/,1)[0];return i.parse(JSON.parse(q))}}};
|