@jetcrab/pi-desk 1.1.12 → 1.1.16
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 +21 -1
- package/package.json +2 -2
- package/src/app/api/model-settings/preview/route.ts +1 -0
- package/src/app/api/work-sessions/rename/route.ts +1 -0
- package/src/client/l2_biz/auth/l2-login.tsx +1 -1
- package/src/client/l2_biz/plugin-host/l2-plugin-session-sidebar-tab.tsx +6 -2
- package/src/client/l2_biz/settings/hooks/l2-use-model-provider-settings.ts +54 -10
- package/src/client/l2_biz/settings/hooks/l2-use-model-settings.ts +37 -9
- package/src/client/l2_biz/settings/l2-auth-settings.tsx +1 -1
- package/src/client/l2_biz/settings/l2-model-settings-biz.ts +26 -12
- package/src/client/l2_biz/settings/views/l2-appearance-settings.tsx +1 -16
- package/src/client/l2_biz/settings/views/l2-model-provider-settings.tsx +3 -2
- package/src/client/l2_biz/settings/views/l2-model-replacement-preview.tsx +34 -0
- package/src/client/l2_biz/task-center/l2-task-center.tsx +4 -30
- package/src/client/l2_biz/workbench/file-workspace/l2-plugin-standalone-file-preview.tsx +45 -7
- package/src/client/l2_biz/workbench/hooks/l2-work-session-rename.ts +57 -0
- package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +0 -11
- package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +107 -6
- package/src/client/l2_biz/workbench/l2-workbench-biz.ts +5 -0
- package/src/client/l2_biz/workbench/l2-workbench-chat-composer.tsx +333 -350
- package/src/client/l2_biz/workbench/l2-workbench.tsx +46 -1
- package/src/client/l2_biz/workbench/views/l2-work-session-rename-dialog.tsx +88 -0
- package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +81 -0
- package/src/client/l3_modules/project-files/l3-markdown-preview.tsx +52 -0
- package/src/client/l3_modules/project-files/l3-project-document-view.tsx +26 -8
- package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +16 -1
- package/src/client/l3_modules/project-files/l3-project-text-preview.ts +5 -0
- package/src/client/l3_modules/work-session-visual/l3-work-session-visual-effects.module.css +0 -36
- package/src/client/l3_modules/work-session-visual/l3-work-session-visual-view.tsx +0 -5
- package/src/client/l4_foundation/plugin-host/l4-plugin-host-runtime.ts +71 -1
- package/src/client/l4_foundation/styles/l4-globals.css +0 -19
- package/src/client/l4_foundation/ui/code/l4-code-preview.tsx +2 -1
- package/src/client/l4_foundation/ui/l4-confirm-dialog.tsx +9 -1
- package/src/common/l2_biz/auth/l2-auth-contract.ts +2 -2
- package/src/common/l2_biz/auth/l2-auth-messages.ts +2 -2
- package/src/common/l2_biz/model-settings/l2-model-settings-contract.ts +23 -1
- package/src/common/l2_biz/settings/l2-settings-messages.ts +8 -6
- package/src/common/l2_biz/work-session/l2-work-session-contract.ts +9 -0
- package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +6 -0
- package/src/common/l3_modules/project-files/l3-project-files-locale-messages.ts +4 -0
- package/src/common/l4_foundation/locale/l4-host-error-messages.ts +6 -0
- package/src/server/l1_entry/api/l1-model-settings-preview-route.ts +32 -0
- package/src/server/l1_entry/api/l1-work-session-rename-route.ts +52 -0
- package/src/server/l2_biz/model-settings/l2-model-settings.ts +9 -0
- package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +159 -52
- package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +5 -0
- package/src/server/l2_biz/work-session/l2-work-session-manage.ts +13 -0
- package/src/server/l3_modules/work-session/l3-work-session.ts +4 -0
- package/src/server/l4_foundation/model-settings/l4-model-settings-store.ts +161 -38
- package/src/server/l4_foundation/model-settings/l4-model-settings-types.ts +11 -0
- package/src/server/l4_foundation/model-settings/l4-model-settings.ts +1 -0
- package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +12 -1
- package/src/server/l4_foundation/pi/l4-pi-package-maintenance-runner.mts +56 -65
- package/src/server/l4_foundation/pi/l4-pi-package-maintenance.ts +2 -0
- package/src/server/l4_foundation/pi/l4-pi-package-reinstall-runner.mts +49 -0
- package/src/server/l4_foundation/pi/l4-pi-package-root-consistency.ts +6 -2
- package/src/server/l4_foundation/pi/l4-pi-plugin-probe.ts +3 -1
- package/src/server/l4_foundation/pi/l4-pi-runner-process.ts +9 -0
- package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +5 -0
- package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
- package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +2 -0
- 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 +2 -2
- package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
- package/temp/build/pi-desk/release/.next/routes-manifest.json +12 -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 +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- 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 +2 -2
- 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 -0
- package/temp/build/pi-desk/release/.next/server/app/api/model-settings/preview/route_client-reference-manifest.js +1 -0
- package/temp/build/pi-desk/release/.next/server/app/api/model-settings/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directories/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-entries/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/models/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/session-user-messages/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/pi/sessions/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/search/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/reveal/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-files/search/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +1 -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 -0
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route_client-reference-manifest.js +1 -0
- 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 -306
- 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-paths-manifest.json +2 -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 +8 -8
- package/temp/build/pi-desk/release/.next/server/chunks/33658.js +296 -0
- package/temp/build/pi-desk/release/.next/server/chunks/35985.js +5 -5
- package/temp/build/pi-desk/release/.next/server/chunks/48180.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/49900.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/50520.js +5 -5
- package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/78262.js +3 -3
- package/temp/build/pi-desk/release/.next/server/chunks/82499.js +6 -6
- package/temp/build/pi-desk/release/.next/server/chunks/92386.js +3 -3
- package/temp/build/pi-desk/release/.next/server/chunks/94296.js +2 -2
- 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/DqamF28k0ShQLbNVzXDIj/_buildManifest.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/31087-ba426d09d6f68bfd.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/39654-b5fedd762ea0312e.js +238 -0
- package/temp/build/pi-desk/release/.next/static/chunks/49516-cc4dcd84d64ab4fe.js +81 -0
- package/temp/build/pi-desk/release/.next/static/chunks/75130-d2ca74894aff8085.js +13 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-c0e1c5cef8620cf8.js +3 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-84892b06243891f0.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-0069319a4fb97211.js +158 -0
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9969fe0baa238786.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/webpack-40a782fc8a3535b9.js +1 -0
- package/temp/build/pi-desk/release/.next/static/css/6427d02b6edf406f.css +1 -0
- package/temp/build/pi-desk/release/.next/static/css/{adb1d4e48dd43c0a.css → 949d0d1a99d5de92.css} +1 -1
- package/temp/build/pi-desk/release/.next/trace-build +1 -1
- package/src/client/l2_biz/workbench/hooks/l2-work-session-column-motion.ts +0 -87
- package/src/client/l3_modules/work-session-visual/l3-work-session-status-border.tsx +0 -66
- package/src/client/l4_foundation/ui/l4-power-saving.ts +0 -45
- package/src/client/l4_foundation/ui/l4-window-reveal.ts +0 -30
- package/temp/build/pi-desk/release/.next/server/chunks/56284.js +0 -62
- package/temp/build/pi-desk/release/.next/static/96geGVI-j_dC6I3k-XFCB/_buildManifest.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/31087-333cae396a52f232.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/45992-92d8b8b10fcfbb6b.js +0 -13
- package/temp/build/pi-desk/release/.next/static/chunks/47340-c1c09c77c1a88514.js +0 -318
- package/temp/build/pi-desk/release/.next/static/chunks/57208-d6d38167dabb91e4.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-839162b6cfae8347.js +0 -3
- package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-4532a3bbee48e219.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-4b6367cde5c04597.js +0 -158
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-dde4fd973791f7f7.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/webpack-735430d61da52e9d.js +0 -1
- package/temp/build/pi-desk/release/.next/static/css/4a5dda7ff3a82c4a.css +0 -1
- /package/temp/build/pi-desk/release/.next/static/{96geGVI-j_dC6I3k-XFCB → DqamF28k0ShQLbNVzXDIj}/_ssgManifest.js +0 -0
|
@@ -97,6 +97,20 @@ interface L2PluginPackageMetadata {
|
|
|
97
97
|
|
|
98
98
|
type L2PluginMutation = 'add' | 'update' | 'del' | 'enable' | 'disable'
|
|
99
99
|
|
|
100
|
+
interface L2PluginMutationInput {
|
|
101
|
+
mutation: L2PluginMutation
|
|
102
|
+
source: string
|
|
103
|
+
operationSource: string
|
|
104
|
+
reinstall: boolean
|
|
105
|
+
options: Omit<L2PluginManagementInstallRequest, 'source'>
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
interface L2PluginPreparedMutation {
|
|
109
|
+
request: L4PiDeskPackageMaintenanceRequest | null
|
|
110
|
+
updateTag: string | null
|
|
111
|
+
pluginName: string | null
|
|
112
|
+
}
|
|
113
|
+
|
|
100
114
|
export interface L2PluginManagementWorkSessions {
|
|
101
115
|
refreshPluginMessages: () => void
|
|
102
116
|
runPluginRestart: <T>(operation: () => Promise<T>) => Promise<T>
|
|
@@ -402,6 +416,9 @@ export class L2PluginManagement {
|
|
|
402
416
|
this.assertOpen()
|
|
403
417
|
const results: L2PluginManagementBatchResponse['results'] = []
|
|
404
418
|
const seen = new Set<string>()
|
|
419
|
+
const snapshot =
|
|
420
|
+
input.action === 'add' || input.action === 'update' ? await this.readSources() : null
|
|
421
|
+
const mutations: L2PluginMutationInput[] = []
|
|
405
422
|
const items = input.action === 'add' ? input.items : input.sources.map((source) => ({ source }))
|
|
406
423
|
for (const item of items) {
|
|
407
424
|
try {
|
|
@@ -413,9 +430,9 @@ export class L2PluginManagement {
|
|
|
413
430
|
seen.add(identity)
|
|
414
431
|
if (input.action === 'add') {
|
|
415
432
|
const { source: _source, ...options } = item
|
|
416
|
-
|
|
433
|
+
mutations.push(this.acceptMutation('add', source, snapshot!, true, undefined, options))
|
|
417
434
|
} else if (input.action === 'update') {
|
|
418
|
-
|
|
435
|
+
mutations.push(this.acceptMutation('update', source, snapshot!))
|
|
419
436
|
} else if (input.action === 'del') {
|
|
420
437
|
await this.del(source)
|
|
421
438
|
} else {
|
|
@@ -426,6 +443,7 @@ export class L2PluginManagement {
|
|
|
426
443
|
results.push({ source: item.source, error: errorMessage(error).slice(0, 4000) })
|
|
427
444
|
}
|
|
428
445
|
}
|
|
446
|
+
if (mutations.length > 0) this.enqueueMutations(mutations)
|
|
429
447
|
return { snapshot: await this.readSnapshot(false), results }
|
|
430
448
|
}
|
|
431
449
|
|
|
@@ -673,7 +691,13 @@ export class L2PluginManagement {
|
|
|
673
691
|
}
|
|
674
692
|
|
|
675
693
|
reload(mode?: 'normal' | 'basic'): Promise<L2PluginManagementSnapshot> {
|
|
676
|
-
if (
|
|
694
|
+
if (
|
|
695
|
+
this.activeSource ||
|
|
696
|
+
[...this.operations].some(
|
|
697
|
+
([source, operation]) =>
|
|
698
|
+
operation.phase !== 'failed' && !this.deferredMaintenance.has(source)
|
|
699
|
+
)
|
|
700
|
+
) {
|
|
677
701
|
return Promise.reject(
|
|
678
702
|
new L2PluginManagementOperationConflictError('维护仍在执行或等待,请先完成当前操作')
|
|
679
703
|
)
|
|
@@ -691,14 +715,34 @@ export class L2PluginManagement {
|
|
|
691
715
|
previousSource?: string,
|
|
692
716
|
options: Omit<L2PluginManagementInstallRequest, 'source'> = {}
|
|
693
717
|
): Promise<L2PluginManagementSnapshot> {
|
|
718
|
+
this.assertOpen()
|
|
719
|
+
const snapshot = await this.readSources()
|
|
720
|
+
const input = this.acceptMutation(
|
|
721
|
+
mutation,
|
|
722
|
+
source,
|
|
723
|
+
snapshot,
|
|
724
|
+
reinstall,
|
|
725
|
+
previousSource,
|
|
726
|
+
options
|
|
727
|
+
)
|
|
728
|
+
this.enqueueMutations([input])
|
|
729
|
+
return this.readSnapshot(false)
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
private acceptMutation(
|
|
733
|
+
mutation: L2PluginMutation,
|
|
734
|
+
source: string,
|
|
735
|
+
snapshot: L4PiPluginSourceSnapshot,
|
|
736
|
+
reinstall = false,
|
|
737
|
+
previousSource?: string,
|
|
738
|
+
options: Omit<L2PluginManagementInstallRequest, 'source'> = {}
|
|
739
|
+
): L2PluginMutationInput {
|
|
694
740
|
this.assertOpen()
|
|
695
741
|
if (isL4PiDeskSafeMode()) {
|
|
696
742
|
throw new L2PluginManagementOperationConflictError(
|
|
697
743
|
'基础模式不执行插件维护,请通过基础聊天修复或正常启动后维护'
|
|
698
744
|
)
|
|
699
745
|
}
|
|
700
|
-
const snapshot = await this.readSources()
|
|
701
|
-
this.assertOpen()
|
|
702
746
|
const existing = snapshot.sources.find(
|
|
703
747
|
(item) => l2PluginSourceIdentity(item.source) === l2PluginSourceIdentity(source)
|
|
704
748
|
)
|
|
@@ -733,36 +777,66 @@ export class L2PluginManagement {
|
|
|
733
777
|
this.operations.set(operationSource, { action: mutation, phase: 'queued', message: null })
|
|
734
778
|
this.updates.clear(operationSource)
|
|
735
779
|
this.updates.clear(source)
|
|
736
|
-
|
|
780
|
+
return { mutation, source, operationSource, reinstall, options }
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
private enqueueMutations(inputs: readonly L2PluginMutationInput[]): void {
|
|
737
784
|
void this.runExclusive(async () => {
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
785
|
+
const startedAt = performance.now()
|
|
786
|
+
// 本批全部准备收尾后才写正式目录;错误按项收集,不让早退遗留预检进程。
|
|
787
|
+
const candidates = await Promise.all(
|
|
788
|
+
inputs.map(async (input) => {
|
|
789
|
+
try {
|
|
790
|
+
const prepared = await this.prepareMutation(input)
|
|
791
|
+
this.assertOpen()
|
|
792
|
+
this.setOperation(input.operationSource, 'queued', '候选检查完成,等待应用')
|
|
793
|
+
return { input, prepared }
|
|
794
|
+
} catch (error) {
|
|
795
|
+
this.setOperation(input.operationSource, 'failed', errorMessage(error))
|
|
796
|
+
return null
|
|
797
|
+
}
|
|
798
|
+
})
|
|
799
|
+
)
|
|
800
|
+
if (inputs.length > 1) {
|
|
801
|
+
console.info('[Pi Desk][PluginManagement] 批量并行准备收尾', {
|
|
802
|
+
count: inputs.length,
|
|
803
|
+
failedCount: candidates.filter((item) => item === null).length,
|
|
804
|
+
durationMs: Math.round(performance.now() - startedAt)
|
|
805
|
+
})
|
|
806
|
+
}
|
|
807
|
+
for (const candidate of candidates) {
|
|
808
|
+
if (!candidate) continue
|
|
809
|
+
const { input, prepared } = candidate
|
|
810
|
+
const { source, operationSource } = input
|
|
811
|
+
this.activeSource = operationSource
|
|
812
|
+
try {
|
|
813
|
+
this.assertOpen()
|
|
814
|
+
if (prepared) await this.executeMutation(input, prepared)
|
|
815
|
+
if (!this.deferredMaintenance.has(operationSource))
|
|
816
|
+
this.operations.delete(operationSource)
|
|
817
|
+
} catch (error) {
|
|
818
|
+
this.setOperation(operationSource, 'failed', errorMessage(error))
|
|
819
|
+
} finally {
|
|
820
|
+
this.updates.clear(operationSource)
|
|
821
|
+
this.updates.clear(source)
|
|
822
|
+
this.sourceCache = null
|
|
823
|
+
this.activeSource = null
|
|
824
|
+
this.publish()
|
|
825
|
+
}
|
|
750
826
|
}
|
|
751
827
|
}).catch((error: unknown) => {
|
|
752
|
-
if (
|
|
828
|
+
if (this.disposed) return
|
|
829
|
+
for (const input of inputs)
|
|
830
|
+
this.setOperation(input.operationSource, 'failed', errorMessage(error))
|
|
753
831
|
})
|
|
754
|
-
|
|
832
|
+
this.publish()
|
|
755
833
|
}
|
|
756
834
|
|
|
757
|
-
private async
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
operationSource
|
|
761
|
-
|
|
762
|
-
options: Omit<L2PluginManagementInstallRequest, 'source'>
|
|
763
|
-
): Promise<void> {
|
|
764
|
-
const runtime = getL4PiGlobalPluginRuntime()
|
|
765
|
-
const waiting = (reason: string): void => this.setOperation(operationSource, 'waiting', reason)
|
|
835
|
+
private async prepareMutation(
|
|
836
|
+
input: L2PluginMutationInput
|
|
837
|
+
): Promise<L2PluginPreparedMutation | null> {
|
|
838
|
+
const { mutation, source, operationSource, reinstall, options } = input
|
|
839
|
+
this.assertOpen()
|
|
766
840
|
const current = this.createPackageManager()
|
|
767
841
|
this.throwSettingsErrors(current.settingsManager)
|
|
768
842
|
const configured = current.packageManager
|
|
@@ -771,10 +845,12 @@ export class L2PluginManagement {
|
|
|
771
845
|
const target = configured.find((item) => item.source === operationSource)
|
|
772
846
|
let request: L4PiDeskPackageMaintenanceRequest | null = null
|
|
773
847
|
let updateTag: string | null = null
|
|
848
|
+
let pluginName: string | null = null
|
|
774
849
|
if (mutation !== 'enable' && mutation !== 'disable') {
|
|
775
850
|
const packageRootError = await readL4PiPackageRootConsistencyError({
|
|
776
851
|
agentDir: this.agentDir,
|
|
777
|
-
configured
|
|
852
|
+
configured,
|
|
853
|
+
repairSource: mutation === 'add' && reinstall ? operationSource : undefined
|
|
778
854
|
})
|
|
779
855
|
if (packageRootError) throw new L2PluginManagementPackageRootError(packageRootError)
|
|
780
856
|
if (mutation !== 'add' && !target) throw new L2PluginManagementNotFoundError(source)
|
|
@@ -796,7 +872,7 @@ export class L2PluginManagement {
|
|
|
796
872
|
const version = resolved.source.slice(resolved.source.lastIndexOf('@') + 1)
|
|
797
873
|
if (!installed.version)
|
|
798
874
|
throw new L2PluginManagementInvalidPackageError('无法读取插件已安装版本')
|
|
799
|
-
if (!isL2PluginNewerVersion(version, installed.version)) return
|
|
875
|
+
if (!isL2PluginNewerVersion(version, installed.version)) return null
|
|
800
876
|
}
|
|
801
877
|
request = {
|
|
802
878
|
...(npmName && mutation !== 'del' && (reinstall || target || mutation === 'update')
|
|
@@ -805,7 +881,22 @@ export class L2PluginManagement {
|
|
|
805
881
|
...('registry' in resolved && resolved.registry ? { registry: resolved.registry } : {})
|
|
806
882
|
}
|
|
807
883
|
if (mutation !== 'del')
|
|
808
|
-
await this.probeCandidate(resolved.source,
|
|
884
|
+
pluginName = await this.probeCandidate(resolved.source, request.registry)
|
|
885
|
+
}
|
|
886
|
+
return { request, updateTag, pluginName }
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
private async executeMutation(
|
|
890
|
+
input: L2PluginMutationInput,
|
|
891
|
+
prepared: L2PluginPreparedMutation
|
|
892
|
+
): Promise<void> {
|
|
893
|
+
const { mutation, source, operationSource } = input
|
|
894
|
+
const { request, updateTag, pluginName } = prepared
|
|
895
|
+
const runtime = getL4PiGlobalPluginRuntime()
|
|
896
|
+
const waiting = (reason: string): void => this.setOperation(operationSource, 'waiting', reason)
|
|
897
|
+
if (request) {
|
|
898
|
+
// 先前项可能安装失败或注册同名插件,不能依赖并行准备时的旧结论。
|
|
899
|
+
this.assertPluginNameAvailable(pluginName, operationSource)
|
|
809
900
|
if (updateTag) {
|
|
810
901
|
setL4PiPluginUpdateTag(operationSource, updateTag, this.agentDir)
|
|
811
902
|
this.updates.clear(operationSource)
|
|
@@ -820,6 +911,20 @@ export class L2PluginManagement {
|
|
|
820
911
|
await runtime.withSourceIdle(
|
|
821
912
|
operationSource,
|
|
822
913
|
async () => {
|
|
914
|
+
if (request) {
|
|
915
|
+
const current = this.createPackageManager()
|
|
916
|
+
this.throwSettingsErrors(current.settingsManager)
|
|
917
|
+
const configured = current.packageManager
|
|
918
|
+
.listConfiguredPackages()
|
|
919
|
+
.filter((item) => item.scope === 'user')
|
|
920
|
+
const rootError = await readL4PiPackageRootConsistencyError({
|
|
921
|
+
agentDir: this.agentDir,
|
|
922
|
+
configured,
|
|
923
|
+
repairSource: mutation === 'add' && input.reinstall ? operationSource : undefined
|
|
924
|
+
})
|
|
925
|
+
if (rootError) throw new L2PluginManagementPackageRootError(rootError)
|
|
926
|
+
}
|
|
927
|
+
this.assertOpen()
|
|
823
928
|
this.setOperation(
|
|
824
929
|
operationSource,
|
|
825
930
|
'applying',
|
|
@@ -997,11 +1102,7 @@ export class L2PluginManagement {
|
|
|
997
1102
|
return writing() && this.sourceCache ? this.sourceCache : snapshot
|
|
998
1103
|
}
|
|
999
1104
|
|
|
1000
|
-
private async probeCandidate(
|
|
1001
|
-
source: string,
|
|
1002
|
-
activeSource: string,
|
|
1003
|
-
registry?: string
|
|
1004
|
-
): Promise<void> {
|
|
1105
|
+
private async probeCandidate(source: string, registry?: string): Promise<string | null> {
|
|
1005
1106
|
const root = join(this.stagingRoot, randomUUID())
|
|
1006
1107
|
const stagingAgentDir = join(root, 'agent')
|
|
1007
1108
|
const stagingCwd = join(root, 'workspace')
|
|
@@ -1031,7 +1132,8 @@ export class L2PluginManagement {
|
|
|
1031
1132
|
await runL4PiPackageMaintenance({
|
|
1032
1133
|
maintenance: { action: 'install', source, ...(registry ? { registry } : {}) },
|
|
1033
1134
|
agentDir: stagingAgentDir,
|
|
1034
|
-
cwd: stagingCwd
|
|
1135
|
+
cwd: stagingCwd,
|
|
1136
|
+
signal: this.lifetime.signal
|
|
1035
1137
|
})
|
|
1036
1138
|
|
|
1037
1139
|
this.assertOpen()
|
|
@@ -1047,7 +1149,12 @@ export class L2PluginManagement {
|
|
|
1047
1149
|
|
|
1048
1150
|
await this.verifyPackageVersion(source, candidate.installedPath)
|
|
1049
1151
|
|
|
1050
|
-
const diagnostics = await runL4PiPluginProbe(
|
|
1152
|
+
const diagnostics = await runL4PiPluginProbe(
|
|
1153
|
+
stagingCwd,
|
|
1154
|
+
stagingAgentDir,
|
|
1155
|
+
true,
|
|
1156
|
+
this.lifetime.signal
|
|
1157
|
+
)
|
|
1051
1158
|
if (diagnostics.loadError) {
|
|
1052
1159
|
throw new L2PluginManagementInvalidPackageError(diagnostics.loadError)
|
|
1053
1160
|
}
|
|
@@ -1056,21 +1163,10 @@ export class L2PluginManagement {
|
|
|
1056
1163
|
throw new L2PluginManagementInvalidPackageError(failed.error.message)
|
|
1057
1164
|
}
|
|
1058
1165
|
|
|
1059
|
-
const candidatePluginName = diagnostics.packages[0]?.pluginName
|
|
1060
|
-
if (candidatePluginName) {
|
|
1061
|
-
const conflict = getL4PiGlobalPluginRuntime()
|
|
1062
|
-
.readDiagnostics()
|
|
1063
|
-
.packages.find(
|
|
1064
|
-
(item) => item.source !== activeSource && item.pluginName === candidatePluginName
|
|
1065
|
-
)
|
|
1066
|
-
if (conflict) {
|
|
1067
|
-
throw new L2PluginManagementInvalidPackageError(
|
|
1068
|
-
`pluginName 已由其他 Package 注册:${candidatePluginName}`
|
|
1069
|
-
)
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1166
|
+
const candidatePluginName = diagnostics.packages[0]?.pluginName ?? null
|
|
1072
1167
|
this.assertOpen()
|
|
1073
1168
|
console.info('[Pi Desk][PluginManagement] 候选插件隔离预检通过', { source })
|
|
1169
|
+
return candidatePluginName
|
|
1074
1170
|
} catch (error) {
|
|
1075
1171
|
if (error instanceof L2PluginManagementInvalidPackageError) throw error
|
|
1076
1172
|
throw new L2PluginManagementInvalidPackageError(errorMessage(error))
|
|
@@ -1084,6 +1180,17 @@ export class L2PluginManagement {
|
|
|
1084
1180
|
}
|
|
1085
1181
|
}
|
|
1086
1182
|
|
|
1183
|
+
private assertPluginNameAvailable(pluginName: string | null, source: string): void {
|
|
1184
|
+
if (!pluginName) return
|
|
1185
|
+
const conflict = getL4PiGlobalPluginRuntime()
|
|
1186
|
+
.readDiagnostics()
|
|
1187
|
+
.packages.some((item) => item.source !== source && item.pluginName === pluginName)
|
|
1188
|
+
if (conflict)
|
|
1189
|
+
throw new L2PluginManagementInvalidPackageError(
|
|
1190
|
+
`pluginName 已由其他 Package 注册:${pluginName}`
|
|
1191
|
+
)
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1087
1194
|
private restartWhenQuiet(mode?: 'normal' | 'basic'): Promise<L2PluginManagementSnapshot> {
|
|
1088
1195
|
return this.workSessions.runPluginRestart(async () => {
|
|
1089
1196
|
const runtime = getL4PiGlobalPluginRuntime()
|
|
@@ -564,6 +564,11 @@ export class L2WorkSessionChatRuntime {
|
|
|
564
564
|
return this.enqueueCommand(record, () => record.workSession.restoreQueuedMessages())
|
|
565
565
|
}
|
|
566
566
|
|
|
567
|
+
setTitle(workSession: WorkSession, title: string): Promise<void> {
|
|
568
|
+
const record = this.recordFor(workSession)
|
|
569
|
+
return this.enqueueCommand(record, () => record.workSession.setTitle(title))
|
|
570
|
+
}
|
|
571
|
+
|
|
567
572
|
setModel(input: L2ChatModelSetRequest): Promise<void> {
|
|
568
573
|
const record = this.currentRecord(input.source)
|
|
569
574
|
return this.enqueueCommand(record, () => record.workSession.setModel(input.model))
|
|
@@ -59,12 +59,14 @@ import {
|
|
|
59
59
|
import {
|
|
60
60
|
L2CwdSchema,
|
|
61
61
|
L2PiSessionIdSchema,
|
|
62
|
+
L2RenameWorkSessionRequestSchema,
|
|
62
63
|
L2WorkIdSchema,
|
|
63
64
|
L2WorkSessionListItemSchema,
|
|
64
65
|
L2WorkSessionListResponseSchema,
|
|
65
66
|
L2WorkSessionPinnedCountSchema,
|
|
66
67
|
L2WorkSessionRecordSchema,
|
|
67
68
|
L2WorkSessionRecordsSchema,
|
|
69
|
+
type L2RenameWorkSessionRequest,
|
|
68
70
|
type L2WorkSessionListItem,
|
|
69
71
|
type L2WorkSessionListResponse,
|
|
70
72
|
type L2WorkSessionRecord,
|
|
@@ -560,6 +562,17 @@ export class WorkSessionManage {
|
|
|
560
562
|
})
|
|
561
563
|
}
|
|
562
564
|
|
|
565
|
+
renameWorkSession(inputValue: L2RenameWorkSessionRequest): Promise<void> {
|
|
566
|
+
const input = L2RenameWorkSessionRequestSchema.parse(inputValue)
|
|
567
|
+
return this.runExclusive(async () => {
|
|
568
|
+
await this.ensureHydrated()
|
|
569
|
+
const current = this.workSessionsById.get(input.workId)
|
|
570
|
+
if (!current) throw new WorkSessionNotFoundError(input.workId)
|
|
571
|
+
this.assertSessionBinding(current, input.sessionId)
|
|
572
|
+
await this.chat.setTitle(current, input.title)
|
|
573
|
+
})
|
|
574
|
+
}
|
|
575
|
+
|
|
563
576
|
replaceWorkSession(
|
|
564
577
|
workIdInput: string,
|
|
565
578
|
historySessionInput?: { cwd: string; sessionId: string }
|
|
@@ -91,6 +91,10 @@ export class WorkSession {
|
|
|
91
91
|
return this.runtime.restoreQueuedMessages()
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
async setTitle(title: string): Promise<void> {
|
|
95
|
+
await this.runtime.setTitle(title)
|
|
96
|
+
}
|
|
97
|
+
|
|
94
98
|
async setModel(input: WorkSessionModelInput): Promise<void> {
|
|
95
99
|
await this.runtime.setModel(input)
|
|
96
100
|
}
|
|
@@ -31,6 +31,7 @@ import type {
|
|
|
31
31
|
L4ModelPreset,
|
|
32
32
|
L4ModelProviderConfig,
|
|
33
33
|
L4ModelSelection,
|
|
34
|
+
L4ModelSettingsPreview,
|
|
34
35
|
L4ModelSettingsReplaceInput
|
|
35
36
|
} from './l4-model-settings-types'
|
|
36
37
|
|
|
@@ -99,17 +100,47 @@ function readJsonRecord(path: string): JsonRecord {
|
|
|
99
100
|
return value
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
function
|
|
103
|
+
function writeTextAtomic(path: string, content: string): void {
|
|
103
104
|
mkdirSync(dirname(path), { recursive: true })
|
|
104
105
|
const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`
|
|
105
106
|
try {
|
|
106
|
-
writeFileSync(temporaryPath,
|
|
107
|
+
writeFileSync(temporaryPath, content, 'utf8')
|
|
107
108
|
renameSync(temporaryPath, path)
|
|
108
109
|
} finally {
|
|
109
110
|
if (existsSync(temporaryPath)) unlinkSync(temporaryPath)
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
|
|
114
|
+
function writeJsonRecordAtomic(path: string, value: JsonRecord): void {
|
|
115
|
+
writeTextAtomic(path, `${JSON.stringify(value, null, 2)}\n`)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function writeRecordsWithRollback(files: Array<{ path: string; value: JsonRecord }>): void {
|
|
119
|
+
const originals = files.map(({ path }) => (existsSync(path) ? readFileSync(path, 'utf8') : null))
|
|
120
|
+
let written = 0
|
|
121
|
+
try {
|
|
122
|
+
for (const { path, value } of files) {
|
|
123
|
+
writeJsonRecordAtomic(path, value)
|
|
124
|
+
written += 1
|
|
125
|
+
}
|
|
126
|
+
} catch (cause) {
|
|
127
|
+
for (let index = written - 1; index >= 0; index -= 1) {
|
|
128
|
+
const path = files[index].path
|
|
129
|
+
const content = originals[index]
|
|
130
|
+
try {
|
|
131
|
+
if (content === null) unlinkSync(path)
|
|
132
|
+
else writeTextAtomic(path, content)
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.error('[Pi Desk][ModelSettings] 配置文件回滚失败', {
|
|
135
|
+
path,
|
|
136
|
+
message: error instanceof Error ? error.message : String(error)
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
throw cause
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
113
144
|
function serializeWrite<T>(task: () => Promise<T>): Promise<T> {
|
|
114
145
|
const result = writeQueue.then(task, task)
|
|
115
146
|
writeQueue = result.then(
|
|
@@ -592,10 +623,41 @@ async function assertConnectionCredentials(
|
|
|
592
623
|
}
|
|
593
624
|
}
|
|
594
625
|
|
|
595
|
-
async function
|
|
626
|
+
async function prepareProjectDefaultChanges(
|
|
627
|
+
current: JsonRecord,
|
|
628
|
+
candidate: JsonRecord,
|
|
629
|
+
input: L4ModelSettingsReplaceInput,
|
|
630
|
+
runtime: ModelRuntime,
|
|
631
|
+
models: L4ModelOption[]
|
|
632
|
+
): Promise<{
|
|
633
|
+
projectDefaults: L4ModelSettingsPreview['projectDefaults']
|
|
634
|
+
files: Array<{ path: string; value: JsonRecord }>
|
|
635
|
+
}> {
|
|
636
|
+
const previousKeys = collectedModelKeys(current)
|
|
596
637
|
const nextKeys = collectedModelKeys(candidate)
|
|
597
|
-
const removed = new Set([...
|
|
598
|
-
|
|
638
|
+
const removed = new Set([...previousKeys].filter((key) => !nextKeys.has(key)))
|
|
639
|
+
const replacements = new Map<string, L4ModelOption>()
|
|
640
|
+
for (const { from, to } of input.modelReplacements ?? []) {
|
|
641
|
+
const fromKey = collectedModelKey(from.provider, from.modelId)
|
|
642
|
+
const toKey = collectedModelKey(to.provider, to.modelId)
|
|
643
|
+
if (fromKey === toKey) throw new Error('模型替换来源和目标不能相同')
|
|
644
|
+
if (replacements.has(fromKey)) throw new Error('模型替换来源不能重复')
|
|
645
|
+
if (!previousKeys.has(fromKey) || !removed.has(fromKey)) {
|
|
646
|
+
throw new Error(`替换来源 ${from.provider}/${from.modelId} 必须是本次移除的已收录模型`)
|
|
647
|
+
}
|
|
648
|
+
const target = models.find(
|
|
649
|
+
(model) => model.provider === to.provider && model.modelId === to.modelId
|
|
650
|
+
)
|
|
651
|
+
if (!nextKeys.has(toKey) || !target) {
|
|
652
|
+
throw new Error(`替换目标 ${to.provider}/${to.modelId} 未收录或不可用`)
|
|
653
|
+
}
|
|
654
|
+
replacements.set(fromKey, target)
|
|
655
|
+
}
|
|
656
|
+
const result: {
|
|
657
|
+
projectDefaults: L4ModelSettingsPreview['projectDefaults']
|
|
658
|
+
files: Array<{ path: string; value: JsonRecord }>
|
|
659
|
+
} = { projectDefaults: [], files: [] }
|
|
660
|
+
if (!removed.size) return result
|
|
599
661
|
for (const preset of normalizePresets(candidate)) {
|
|
600
662
|
if (removed.has(collectedModelKey(preset.provider, preset.modelId))) {
|
|
601
663
|
throw new Error(
|
|
@@ -606,17 +668,60 @@ async function assertRemovalReferences(current: JsonRecord, candidate: JsonRecor
|
|
|
606
668
|
// 仅在移除模型时检查已知项目,不扫描文件系统寻找任意项目配置。
|
|
607
669
|
const projects = await listL4PiDirectorySummaries(true)
|
|
608
670
|
for (const { cwd } of projects) {
|
|
609
|
-
const
|
|
671
|
+
const path = join(cwd, CONFIG_DIR_NAME, 'settings.json')
|
|
672
|
+
const settings = readJsonRecord(path)
|
|
610
673
|
if (
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
674
|
+
!['defaultProvider', 'defaultModel', 'defaultThinkingLevel'].some((key) =>
|
|
675
|
+
Object.hasOwn(settings, key)
|
|
676
|
+
)
|
|
614
677
|
) {
|
|
678
|
+
continue
|
|
679
|
+
}
|
|
680
|
+
const merged = SettingsManager.create(cwd, getAgentDir())
|
|
681
|
+
const provider = merged.getDefaultProvider()
|
|
682
|
+
const modelId = merged.getDefaultModel()
|
|
683
|
+
if (!provider || !modelId || !removed.has(collectedModelKey(provider, modelId))) continue
|
|
684
|
+
const target = replacements.get(collectedModelKey(provider, modelId))
|
|
685
|
+
if (!target) {
|
|
615
686
|
throw new Error(
|
|
616
|
-
`项目“${cwd}”仍将 ${
|
|
687
|
+
`项目“${cwd}”仍将 ${provider}/${modelId} 设为默认模型,请先在“项目默认”中调整`
|
|
617
688
|
)
|
|
618
689
|
}
|
|
690
|
+
const projectModels = await availableModelOptions(runtime, cwd, candidate)
|
|
691
|
+
if (
|
|
692
|
+
!projectModels.some(
|
|
693
|
+
(model) => model.provider === target.provider && model.modelId === target.modelId
|
|
694
|
+
)
|
|
695
|
+
) {
|
|
696
|
+
throw new Error(`替换目标 ${target.provider}/${target.modelId} 在项目“${cwd}”中不可用`)
|
|
697
|
+
}
|
|
698
|
+
const from: L4ModelSelection = {
|
|
699
|
+
provider,
|
|
700
|
+
modelId,
|
|
701
|
+
thinkingLevel: merged.getDefaultThinkingLevel() ?? 'off'
|
|
702
|
+
}
|
|
703
|
+
const thinkingLevel = target.thinkingLevels.includes(from.thinkingLevel)
|
|
704
|
+
? from.thinkingLevel
|
|
705
|
+
: target.thinkingLevels[0]
|
|
706
|
+
if (!thinkingLevel)
|
|
707
|
+
throw new Error(`替换目标 ${target.provider}/${target.modelId} 没有可用思考等级`)
|
|
708
|
+
const to: L4ModelSelection = {
|
|
709
|
+
provider: target.provider,
|
|
710
|
+
modelId: target.modelId,
|
|
711
|
+
thinkingLevel
|
|
712
|
+
}
|
|
713
|
+
result.projectDefaults.push({ cwd, from, to })
|
|
714
|
+
result.files.push({
|
|
715
|
+
path,
|
|
716
|
+
value: {
|
|
717
|
+
...settings,
|
|
718
|
+
defaultProvider: to.provider,
|
|
719
|
+
defaultModel: to.modelId,
|
|
720
|
+
defaultThinkingLevel: to.thinkingLevel
|
|
721
|
+
}
|
|
722
|
+
})
|
|
619
723
|
}
|
|
724
|
+
return result
|
|
620
725
|
}
|
|
621
726
|
|
|
622
727
|
export async function readL4ModelSettings(): Promise<{
|
|
@@ -654,37 +759,55 @@ export async function readL4ModelSettings(): Promise<{
|
|
|
654
759
|
return result
|
|
655
760
|
}
|
|
656
761
|
|
|
762
|
+
async function prepareModelSettings(input: L4ModelSettingsReplaceInput): Promise<{
|
|
763
|
+
projectDefaults: L4ModelSettingsPreview['projectDefaults']
|
|
764
|
+
files: Array<{ path: string; value: JsonRecord }>
|
|
765
|
+
}> {
|
|
766
|
+
const path = modelsPath()
|
|
767
|
+
let current: JsonRecord
|
|
768
|
+
try {
|
|
769
|
+
current = readJsonRecord(path)
|
|
770
|
+
} catch (error) {
|
|
771
|
+
if (input.nativeConfig === undefined) throw error
|
|
772
|
+
// 原生编辑是损坏配置的修复入口,不能要求旧文件先成功解析。
|
|
773
|
+
current = {}
|
|
774
|
+
}
|
|
775
|
+
let candidate: JsonRecord
|
|
776
|
+
if (input.nativeConfig !== undefined) {
|
|
777
|
+
candidate = input.nativeConfig
|
|
778
|
+
} else {
|
|
779
|
+
const currentRuntime = await ModelRuntime.create({ allowModelNetwork: false })
|
|
780
|
+
const error = currentRuntime.getError()
|
|
781
|
+
if (error) throw new Error(`当前模型配置不可用,请先通过原生配置修正:${error}`)
|
|
782
|
+
const defaults =
|
|
783
|
+
input.accountModels === undefined
|
|
784
|
+
? currentRuntime
|
|
785
|
+
: await ModelRuntime.create({ modelsPath: null, allowModelNetwork: false })
|
|
786
|
+
candidate = mergeModelsRoot(current, input, currentRuntime, defaults)
|
|
787
|
+
}
|
|
788
|
+
const runtime = await validateModelsRoot(candidate)
|
|
789
|
+
const models = await availableModelOptions(runtime, undefined, candidate)
|
|
790
|
+
await assertConnectionCredentials(current, candidate, runtime)
|
|
791
|
+
assertPresetsValid(normalizePresets(candidate), models, normalizePresets(current))
|
|
792
|
+
const result = await prepareProjectDefaultChanges(current, candidate, input, runtime, models)
|
|
793
|
+
result.files.push({ path, value: candidate })
|
|
794
|
+
return result
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
export async function previewL4ModelSettings(
|
|
798
|
+
input: L4ModelSettingsReplaceInput
|
|
799
|
+
): Promise<L4ModelSettingsPreview> {
|
|
800
|
+
return serializeWrite(async () => {
|
|
801
|
+
const { projectDefaults } = await prepareModelSettings(input)
|
|
802
|
+
return { projectDefaults }
|
|
803
|
+
})
|
|
804
|
+
}
|
|
805
|
+
|
|
657
806
|
export async function replaceL4ModelSettings(input: L4ModelSettingsReplaceInput): Promise<void> {
|
|
658
807
|
await serializeWrite(async () => {
|
|
659
|
-
const path = modelsPath()
|
|
660
808
|
try {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
current = readJsonRecord(path)
|
|
664
|
-
} catch (error) {
|
|
665
|
-
if (input.nativeConfig === undefined) throw error
|
|
666
|
-
// 原生编辑是损坏配置的修复入口,不能要求旧文件先成功解析。
|
|
667
|
-
current = {}
|
|
668
|
-
}
|
|
669
|
-
let candidate: JsonRecord
|
|
670
|
-
if (input.nativeConfig !== undefined) {
|
|
671
|
-
candidate = input.nativeConfig
|
|
672
|
-
} else {
|
|
673
|
-
const currentRuntime = await ModelRuntime.create({ allowModelNetwork: false })
|
|
674
|
-
const error = currentRuntime.getError()
|
|
675
|
-
if (error) throw new Error(`当前模型配置不可用,请先通过原生配置修正:${error}`)
|
|
676
|
-
const defaults =
|
|
677
|
-
input.accountModels === undefined
|
|
678
|
-
? currentRuntime
|
|
679
|
-
: await ModelRuntime.create({ modelsPath: null, allowModelNetwork: false })
|
|
680
|
-
candidate = mergeModelsRoot(current, input, currentRuntime, defaults)
|
|
681
|
-
}
|
|
682
|
-
const runtime = await validateModelsRoot(candidate)
|
|
683
|
-
const models = await availableModelOptions(runtime, undefined, candidate)
|
|
684
|
-
await assertConnectionCredentials(current, candidate, runtime)
|
|
685
|
-
await assertRemovalReferences(current, candidate)
|
|
686
|
-
assertPresetsValid(normalizePresets(candidate), models, normalizePresets(current))
|
|
687
|
-
writeJsonRecordAtomic(path, candidate)
|
|
809
|
+
const { files } = await prepareModelSettings(input)
|
|
810
|
+
writeRecordsWithRollback(files)
|
|
688
811
|
} catch (cause) {
|
|
689
812
|
console.error('[Pi Desk][ModelSettings] 模型配置保存失败', {
|
|
690
813
|
message: cause instanceof Error ? cause.message : String(cause)
|
|
@@ -91,11 +91,21 @@ export interface L4ModelAccount {
|
|
|
91
91
|
models: L4ModelConfig[]
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
export interface L4ModelReplacement {
|
|
95
|
+
from: { provider: string; modelId: string }
|
|
96
|
+
to: { provider: string; modelId: string }
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface L4ModelSettingsPreview {
|
|
100
|
+
projectDefaults: Array<{ cwd: string; from: L4ModelSelection; to: L4ModelSelection }>
|
|
101
|
+
}
|
|
102
|
+
|
|
94
103
|
export type L4ModelSettingsReplaceInput =
|
|
95
104
|
| {
|
|
96
105
|
providers?: L4ModelProviderConfig[]
|
|
97
106
|
presets?: L4ModelPreset[]
|
|
98
107
|
accountModels?: L4AccountModelSelection[]
|
|
108
|
+
modelReplacements?: L4ModelReplacement[]
|
|
99
109
|
nativeConfig?: never
|
|
100
110
|
}
|
|
101
111
|
| {
|
|
@@ -103,6 +113,7 @@ export type L4ModelSettingsReplaceInput =
|
|
|
103
113
|
providers?: never
|
|
104
114
|
presets?: never
|
|
105
115
|
accountModels?: never
|
|
116
|
+
modelReplacements?: never
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
export interface L4ModelCatalogRequest {
|