@jetcrab/pi-desk 1.1.28-dev → 1.1.30-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/plugins.md +2 -2
- package/package.json +1 -1
- package/src/app/api/work-sessions/search/route.ts +1 -0
- package/src/app/project-preview/page.tsx +1 -3
- package/src/client/l1_entry/pages/l1-error-page.tsx +1 -1
- package/src/client/l1_entry/providers/l1-app-providers.tsx +2 -0
- package/src/client/l2_biz/auth/l2-login.module.css +1 -1
- package/src/client/l2_biz/plugin-host/l2-plugin-composer-panel.tsx +1 -1
- package/src/client/l2_biz/plugin-host/l2-plugin-contribution-host.tsx +1 -1
- package/src/client/l2_biz/plugin-host/l2-plugin-session-header-layout.ts +6 -3
- package/src/client/l2_biz/plugin-host/l2-plugin-session-header.tsx +75 -18
- package/src/client/l2_biz/project-preview/hooks/l2-use-project-preview.ts +1 -14
- package/src/client/l2_biz/project-preview/l2-project-preview-dialog.tsx +2 -3
- package/src/client/l2_biz/project-preview/l2-project-preview-page.tsx +1 -2
- package/src/client/l2_biz/project-preview/l2-project-preview.tsx +1 -4
- package/src/client/l2_biz/project-preview/views/l2-project-branch-select.tsx +42 -3
- package/src/client/l2_biz/settings/l2-settings.tsx +1 -1
- package/src/client/l2_biz/settings/l2-skills-settings.tsx +1 -1
- package/src/client/l2_biz/task-center/l2-task-center.tsx +1 -1
- package/src/client/l2_biz/workbench/file-workspace/l2-plugin-standalone-file-preview.tsx +1 -1
- package/src/client/l2_biz/workbench/file-workspace/l2-work-session-file-preview.tsx +1 -1
- package/src/client/l2_biz/workbench/git-workspace/l2-git-workspace-runtime.ts +11 -10
- package/src/client/l2_biz/workbench/hooks/l2-work-session-search.ts +52 -0
- package/src/client/l2_biz/workbench/hooks/l2-workbench-branch-picker.ts +42 -7
- package/src/client/l2_biz/workbench/hooks/l2-workbench-session-history.ts +143 -131
- package/src/client/l2_biz/workbench/hooks/l2-workbench-session-search.ts +97 -0
- package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +8 -0
- package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +129 -10
- package/src/client/l2_biz/workbench/l2-workbench-biz.ts +20 -2
- package/src/client/l2_biz/workbench/l2-workbench-branch-filter-preferences.ts +34 -0
- package/src/client/l2_biz/workbench/l2-workbench-branch-picker.tsx +34 -71
- package/src/client/l2_biz/workbench/l2-workbench-chat-input-runtime.ts +38 -1
- package/src/client/l2_biz/workbench/l2-workbench-chat-view.tsx +11 -1
- package/src/client/l2_biz/workbench/l2-workbench-picker-dialog.tsx +55 -215
- package/src/client/l2_biz/workbench/l2-workbench.tsx +21 -39
- package/src/client/l2_biz/workbench/views/l2-workbench-session-search.tsx +123 -0
- package/src/client/l3_modules/conversation/l3-conversation-messages.tsx +43 -4
- package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +1 -1
- package/src/client/l3_modules/project-files/l3-project-document-git.ts +13 -29
- package/src/client/l3_modules/project-files/l3-project-document-view.tsx +1 -4
- package/src/client/l3_modules/project-files/l3-project-file-browser.module.css +14 -18
- package/src/client/l3_modules/project-files/l3-project-file-browser.tsx +52 -95
- package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +52 -21
- package/src/client/l3_modules/project-files/l3-project-file-tabs.tsx +41 -62
- package/src/client/l3_modules/project-files/l3-project-git-runtime.ts +5 -4
- package/src/client/l3_modules/project-files/l3-use-project-refresh.ts +36 -0
- package/src/client/l3_modules/project-files/views/l3-project-search-results.tsx +2 -2
- package/src/client/l3_modules/project-files/views/l3-project-tree-folder.tsx +86 -0
- package/src/client/l4_foundation/desktop-window/l4-desktop-titlebar.tsx +188 -0
- package/src/client/l4_foundation/desktop-window/l4-desktop-window.css +107 -0
- package/src/client/l4_foundation/desktop-window/l4-desktop-window.ts +20 -0
- package/src/client/l4_foundation/ui/file-icons/README.md +1 -1
- package/src/client/l4_foundation/ui/file-icons/l4-file-icon.tsx +49 -2
- package/src/client/l4_foundation/ui/l4-app-dialog.tsx +2 -2
- package/src/common/l2_biz/pi-session/l2-pi-session-contract.ts +11 -24
- package/src/common/l2_biz/project-preview/l2-project-preview-navigation.ts +5 -12
- package/src/common/l2_biz/work-session/l2-work-session-search-contract.ts +26 -0
- package/src/common/l2_biz/work-session/l2-work-session-tree-contract.ts +9 -1
- package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +12 -0
- package/src/common/l2_biz/workbench/l2-workbench-picker-messages.ts +6 -2
- package/src/common/l3_modules/conversation/l3-conversation-locale-messages.ts +2 -0
- package/src/common/l3_modules/pi/l3-pi-session-search-contract.ts +26 -0
- package/src/common/l4_foundation/locale/l4-host-error-messages.ts +2 -0
- package/src/server/l1_entry/api/l1-work-session-branch-route.ts +21 -15
- package/src/server/l1_entry/api/l1-work-session-search-route.ts +38 -0
- package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +4 -2
- package/src/server/l2_biz/work-session/l2-work-session-manage.ts +46 -10
- package/src/server/l3_modules/work-session/l3-work-session.ts +11 -6
- package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +35 -2
- package/src/server/l4_foundation/pi/l4-pi-session-history-catalog.ts +62 -113
- package/src/server/l4_foundation/pi/l4-pi-session-search.ts +166 -0
- package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +66 -5
- package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
- package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +1 -0
- package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
- package/temp/build/pi-desk/release/.next/required-server-files.js +2 -2
- package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
- package/temp/build/pi-desk/release/.next/routes-manifest.json +6 -0
- package/temp/build/pi-desk/release/.next/server/app/_global-error/page.js +2 -2
- 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 +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 -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 -2
- 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 +2 -2
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +2 -2
- package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skill-files/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skill-files/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skill-files/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/skills/list/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/task-center/images/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/task-center/messages/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/add/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree-entry/get/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/add/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/branch/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/del/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/replace/route.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/search/route.js +1 -0
- package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/search/route_client-reference-manifest.js +1 -0
- 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 +138 -138
- 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 -1
- package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
- package/temp/build/pi-desk/release/.next/server/app-paths-manifest.json +1 -0
- package/temp/build/pi-desk/release/.next/server/chunks/23054.js +2 -2
- package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -8
- package/temp/build/pi-desk/release/.next/server/chunks/27344.js +3 -3
- package/temp/build/pi-desk/release/.next/server/chunks/3108.js +3 -3
- package/temp/build/pi-desk/release/.next/server/chunks/35985.js +3 -3
- package/temp/build/pi-desk/release/.next/server/chunks/41856.js +1 -0
- package/temp/build/pi-desk/release/.next/server/chunks/62900.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/81363.js +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/81912.js +3 -0
- package/temp/build/pi-desk/release/.next/server/chunks/92386.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/pages/500.html +1 -1
- package/temp/build/pi-desk/release/.next/static/ErYBfYXAir5b-6rlacGvL/_buildManifest.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/10043-9d6c3735418ccaf9.js +238 -0
- package/temp/build/pi-desk/release/.next/static/chunks/11937-ac71fb0f7cef482a.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/30669-ffa76d39e0e25194.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/36643-f60e98278740073c.js +3 -0
- package/temp/build/pi-desk/release/.next/static/chunks/65232-f5b71cec787a30ec.js +15 -0
- package/temp/build/pi-desk/release/.next/static/chunks/{51474-8dc714cb76b2e60a.js → 65350-23bb961d87addf14.js} +3 -3
- package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/search/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/error-1ab62762c5f4144f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-ca5ef5994165eb2e.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/login/{page-0d3d4827802108e5.js → page-0df9df996aa68060.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/not-found-b8b9b7ef5ccb7601.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-978906de76a8dcfe.js +158 -0
- package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/{page-038b6c14e03ed878.js → page-aaa845016a934245.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-295cb63da5f7262f.js +1 -0
- package/temp/build/pi-desk/release/.next/static/chunks/{webpack-c0b805df46fcf8b3.js → webpack-a84310d111797bef.js} +1 -1
- package/temp/build/pi-desk/release/.next/static/css/053a8d82c09326cd.css +1 -0
- package/temp/build/pi-desk/release/.next/static/css/1cc92eec583aa639.css +1 -0
- package/temp/build/pi-desk/release/.next/static/css/{1e780a4936aa6ba3.css → 2bb393927ba8f71d.css} +1 -1
- package/temp/build/pi-desk/release/.next/static/css/3a07dcc86ffdf88c.css +1 -0
- package/temp/build/pi-desk/release/.next/static/css/3c59ac068ae404da.css +1 -0
- package/temp/build/pi-desk/release/.next/trace-build +1 -1
- package/temp/build/pi-desk/release/.next/server/chunks/35348.js +0 -3
- package/temp/build/pi-desk/release/.next/server/chunks/56830.js +0 -235
- package/temp/build/pi-desk/release/.next/server/chunks/80780.js +0 -1
- package/temp/build/pi-desk/release/.next/static/bj2dB_Z10YB_CqK_VNhDx/_buildManifest.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/11937-1d0a9822f2c7995b.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/14197-3d3ddd426ac06c9c.js +0 -3
- package/temp/build/pi-desk/release/.next/static/chunks/37313-d5970e2d0c270d22.js +0 -238
- package/temp/build/pi-desk/release/.next/static/chunks/65232-ef4e5a4174f62faf.js +0 -15
- package/temp/build/pi-desk/release/.next/static/chunks/79267-7d21d7cdbd7cfca1.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/error-216b14b5da089ed3.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/layout-20718f1503910291.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/not-found-720cdf6a606b821a.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/app/page-ce2ebf7d8ea7a330.js +0 -158
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9969fe0baa238786.js +0 -1
- package/temp/build/pi-desk/release/.next/static/css/2bdcf40eca12b794.css +0 -1
- package/temp/build/pi-desk/release/.next/static/css/2c3b0c0ff1f49c68.css +0 -1
- package/temp/build/pi-desk/release/.next/static/css/c43b04c244a64fb4.css +0 -1
- /package/temp/build/pi-desk/release/.next/static/{bj2dB_Z10YB_CqK_VNhDx → ErYBfYXAir5b-6rlacGvL}/_ssgManifest.js +0 -0
|
@@ -103,6 +103,7 @@ export const L4_HOST_ERROR_MESSAGES = {
|
|
|
103
103
|
branchInputInvalid: 'Invalid branch operation request',
|
|
104
104
|
branchEntryMissing: 'Branch entry not found or no longer available',
|
|
105
105
|
branchForkUserOnly: 'Only user messages can start a new session',
|
|
106
|
+
branchResendUserOnly: 'Only user messages can be resent',
|
|
106
107
|
branchCloneEmpty: 'There are no messages to clone yet',
|
|
107
108
|
branchFailed: 'Could not perform branch operation',
|
|
108
109
|
taskDetailInvalid: 'Invalid task detail request',
|
|
@@ -262,6 +263,7 @@ export const L4_HOST_ERROR_MESSAGES = {
|
|
|
262
263
|
branchInputInvalid: '分支操作参数无效',
|
|
263
264
|
branchEntryMissing: '分支节点不存在或已失效',
|
|
264
265
|
branchForkUserOnly: '只有用户消息可以 Fork',
|
|
266
|
+
branchResendUserOnly: '只有用户消息可以重发',
|
|
265
267
|
branchCloneEmpty: '当前会话还没有可克隆的消息',
|
|
266
268
|
branchFailed: '执行分支操作失败',
|
|
267
269
|
taskDetailInvalid: '任务详情参数无效',
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import 'server-only'
|
|
2
2
|
|
|
3
3
|
import { L2WorkSessionBranchRequestSchema } from '@common/l2_biz/work-session/l2-work-session-tree-contract'
|
|
4
|
-
import {
|
|
5
|
-
getL2WorkSessionManage,
|
|
6
|
-
WorkSessionBindingChangedError,
|
|
7
|
-
WorkSessionBranchBlockedError,
|
|
8
|
-
WorkSessionBranchEntryNotFoundError,
|
|
9
|
-
WorkSessionBranchInvalidError,
|
|
10
|
-
WorkSessionNotFoundError
|
|
11
|
-
} from '@server/l2_biz/work-session/l2-work-session-manage'
|
|
4
|
+
import { getL2WorkSessionManage } from '@server/l2_biz/work-session/l2-work-session-manage'
|
|
12
5
|
import { readL4ClientId } from '@server/l4_foundation/http/l4-client-id'
|
|
13
6
|
import {
|
|
14
7
|
createL4ApiErrorResponse,
|
|
@@ -33,27 +26,40 @@ export async function POST(request: Request): Promise<Response> {
|
|
|
33
26
|
|
|
34
27
|
try {
|
|
35
28
|
const data = await getL2WorkSessionManage().branchWorkSession(input.data)
|
|
36
|
-
return createL4ApiSuccessResponse(
|
|
29
|
+
return createL4ApiSuccessResponse(
|
|
30
|
+
data,
|
|
31
|
+
input.data.action === 'tree' || input.data.action === 'resend' ? 200 : 201
|
|
32
|
+
)
|
|
37
33
|
} catch (error) {
|
|
38
|
-
|
|
34
|
+
// 管理器由 Node 与 Next 共享,业务异常构造器并非同一实例。
|
|
35
|
+
if (error instanceof Error && error.name === 'WorkSessionNotFoundError') {
|
|
39
36
|
return createL4ApiErrorResponse(404, '工作会话不存在', { key: 'errors:sessionMissing' })
|
|
40
37
|
}
|
|
41
|
-
if (error instanceof WorkSessionBranchEntryNotFoundError) {
|
|
38
|
+
if (error instanceof Error && error.name === 'WorkSessionBranchEntryNotFoundError') {
|
|
42
39
|
return createL4ApiErrorResponse(404, '分支节点不存在或已失效', {
|
|
43
40
|
key: 'errors:branchEntryMissing'
|
|
44
41
|
})
|
|
45
42
|
}
|
|
46
|
-
if (
|
|
43
|
+
if (
|
|
44
|
+
error instanceof Error &&
|
|
45
|
+
error.name === 'WorkSessionBranchInvalidError' &&
|
|
46
|
+
'kind' in error
|
|
47
|
+
) {
|
|
47
48
|
return createL4ApiErrorResponse(400, error.message, {
|
|
48
|
-
key:
|
|
49
|
+
key:
|
|
50
|
+
error.kind === 'fork-target'
|
|
51
|
+
? 'errors:branchForkUserOnly'
|
|
52
|
+
: error.kind === 'resend-target'
|
|
53
|
+
? 'errors:branchResendUserOnly'
|
|
54
|
+
: 'errors:branchCloneEmpty'
|
|
49
55
|
})
|
|
50
56
|
}
|
|
51
|
-
if (error instanceof WorkSessionBindingChangedError) {
|
|
57
|
+
if (error instanceof Error && error.name === 'WorkSessionBindingChangedError') {
|
|
52
58
|
return createL4ApiErrorResponse(409, '工作会话已切换,请重新打开会话树', {
|
|
53
59
|
key: 'errors:sessionTreeChanged'
|
|
54
60
|
})
|
|
55
61
|
}
|
|
56
|
-
if (error instanceof WorkSessionBranchBlockedError) {
|
|
62
|
+
if (error instanceof Error && error.name === 'WorkSessionBranchBlockedError') {
|
|
57
63
|
return createL4ApiErrorResponse(409, error.message)
|
|
58
64
|
}
|
|
59
65
|
console.error('[Pi Desk][WorkSessionBranchApi] 执行分支操作失败', {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import 'server-only'
|
|
2
|
+
|
|
3
|
+
import { L2WorkSessionSearchRequestSchema } from '@common/l2_biz/work-session/l2-work-session-search-contract'
|
|
4
|
+
import { getL2WorkSessionManage } from '@server/l2_biz/work-session/l2-work-session-manage'
|
|
5
|
+
import { readL4ClientId } from '@server/l4_foundation/http/l4-client-id'
|
|
6
|
+
import {
|
|
7
|
+
createL4ApiErrorResponse,
|
|
8
|
+
createL4ApiSuccessResponse
|
|
9
|
+
} from '@server/l4_foundation/http/l4-api-response'
|
|
10
|
+
|
|
11
|
+
export async function POST(request: Request): Promise<Response> {
|
|
12
|
+
const clientId = readL4ClientId(request)
|
|
13
|
+
if (!clientId)
|
|
14
|
+
return createL4ApiErrorResponse(400, '客户端标识无效', { key: 'errors:invalidClient' })
|
|
15
|
+
|
|
16
|
+
let payload: unknown
|
|
17
|
+
try {
|
|
18
|
+
payload = await request.json()
|
|
19
|
+
} catch {
|
|
20
|
+
return createL4ApiErrorResponse(400, '请求 JSON 格式无效', { key: 'errors:invalidJson' })
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const input = L2WorkSessionSearchRequestSchema.safeParse(payload)
|
|
24
|
+
if (!input.success) return createL4ApiErrorResponse(400, '工作会话搜索参数无效')
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
return createL4ApiSuccessResponse(await getL2WorkSessionManage().searchWorkSessions(input.data))
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error('[Pi Desk][WorkSessionSearchApi] 搜索工作会话失败', {
|
|
30
|
+
clientId,
|
|
31
|
+
queryLength: input.data.query.length,
|
|
32
|
+
searchIn: input.data.searchIn,
|
|
33
|
+
errorName: error instanceof Error ? error.name : 'UnknownError',
|
|
34
|
+
errorMessage: error instanceof Error ? error.message : String(error)
|
|
35
|
+
})
|
|
36
|
+
return createL4ApiErrorResponse(500, '搜索工作会话失败')
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -190,11 +190,13 @@ export class L2WorkSessionChatRuntime {
|
|
|
190
190
|
await disposeL4PiWorkSessionRuntime(previous.sessionId)
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
async refreshWorkSession(workSession: WorkSession): Promise<void> {
|
|
193
|
+
async refreshWorkSession(workSession: WorkSession, acceptingCommands = true): Promise<void> {
|
|
194
194
|
const previousSource = this.recordsByWorkId.get(workSession.workId)?.source
|
|
195
195
|
await this.closeRecord(workSession.workId)
|
|
196
196
|
if (previousSource) this.publish({ type: 'source_invalidated', source: previousSource })
|
|
197
|
-
|
|
197
|
+
const record = this.buildRecord(workSession)
|
|
198
|
+
record.acceptingCommands = acceptingCommands
|
|
199
|
+
this.recordsByWorkId.set(workSession.workId, record)
|
|
198
200
|
}
|
|
199
201
|
|
|
200
202
|
async removeWorkSession(workSession: WorkSession): Promise<void> {
|
|
@@ -72,6 +72,12 @@ import {
|
|
|
72
72
|
type L2WorkSessionRecord,
|
|
73
73
|
type L2WorkSessionStatus
|
|
74
74
|
} from '@common/l2_biz/work-session/l2-work-session-contract'
|
|
75
|
+
import {
|
|
76
|
+
L2WorkSessionSearchRequestSchema,
|
|
77
|
+
L2WorkSessionSearchResponseSchema,
|
|
78
|
+
type L2WorkSessionSearchRequest,
|
|
79
|
+
type L2WorkSessionSearchResponse
|
|
80
|
+
} from '@common/l2_biz/work-session/l2-work-session-search-contract'
|
|
75
81
|
import {
|
|
76
82
|
L2WorkSessionChangesSchema,
|
|
77
83
|
L2WorkSessionsUpdateSchema,
|
|
@@ -102,7 +108,8 @@ import { resolveL4PiSessionPath } from '@server/l4_foundation/pi/l4-pi-session-c
|
|
|
102
108
|
import {
|
|
103
109
|
getL4PiWorkSessionRuntime,
|
|
104
110
|
L4PiSessionBranchBlockedError,
|
|
105
|
-
L4PiSessionCloneEmptyError
|
|
111
|
+
L4PiSessionCloneEmptyError,
|
|
112
|
+
L4PiSessionResendTargetError
|
|
106
113
|
} from '@server/l4_foundation/pi/l4-pi-work-session-runtime'
|
|
107
114
|
import {
|
|
108
115
|
L4PiSessionEntryNotFoundError,
|
|
@@ -196,7 +203,7 @@ export class WorkSessionBranchBlockedError extends Error {
|
|
|
196
203
|
|
|
197
204
|
export class WorkSessionBranchInvalidError extends Error {
|
|
198
205
|
constructor(
|
|
199
|
-
readonly kind: 'fork-target' | 'clone-empty',
|
|
206
|
+
readonly kind: 'fork-target' | 'clone-empty' | 'resend-target',
|
|
200
207
|
message: string
|
|
201
208
|
) {
|
|
202
209
|
super(message)
|
|
@@ -250,6 +257,19 @@ export class WorkSessionManage {
|
|
|
250
257
|
})
|
|
251
258
|
}
|
|
252
259
|
|
|
260
|
+
searchWorkSessions(inputValue: L2WorkSessionSearchRequest): Promise<L2WorkSessionSearchResponse> {
|
|
261
|
+
const input = L2WorkSessionSearchRequestSchema.parse(inputValue)
|
|
262
|
+
return this.runExclusive(async () => {
|
|
263
|
+
await this.ensureHydrated()
|
|
264
|
+
return L2WorkSessionSearchResponseSchema.parse({
|
|
265
|
+
sessions: this.orderedWorkSessions().flatMap((workSession) => {
|
|
266
|
+
const matches = getL4PiWorkSessionRuntime(workSession.sessionId).search(input)
|
|
267
|
+
return matches.length > 0 ? [{ workId: workSession.workId, matches }] : []
|
|
268
|
+
})
|
|
269
|
+
})
|
|
270
|
+
})
|
|
271
|
+
}
|
|
272
|
+
|
|
253
273
|
runPluginRestart<T>(operation: () => Promise<T>): Promise<T> {
|
|
254
274
|
return this.runExclusive(async () => {
|
|
255
275
|
await this.ensureHydrated()
|
|
@@ -681,23 +701,35 @@ export class WorkSessionManage {
|
|
|
681
701
|
if (!source) throw new WorkSessionNotFoundError(input.workId)
|
|
682
702
|
this.assertSessionBinding(source, input.sessionId)
|
|
683
703
|
|
|
684
|
-
if (input.action === 'tree') {
|
|
704
|
+
if (input.action === 'tree' || input.action === 'resend') {
|
|
685
705
|
const previousItem = this.toListItem(source)
|
|
686
706
|
await this.chat.pauseWorkSession(source.workId)
|
|
707
|
+
let refreshed = false
|
|
687
708
|
let result: Awaited<ReturnType<WorkSession['branch']>>
|
|
688
709
|
try {
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
710
|
+
if (input.action === 'resend') {
|
|
711
|
+
await source.send({
|
|
712
|
+
mode: 'resend',
|
|
713
|
+
entryId: input.entryId,
|
|
714
|
+
onBranchChanged: async () => {
|
|
715
|
+
await this.chat.refreshWorkSession(source, false)
|
|
716
|
+
refreshed = true
|
|
717
|
+
}
|
|
718
|
+
})
|
|
719
|
+
result = { changed: true, editorText: null }
|
|
720
|
+
} else {
|
|
721
|
+
result = await source.branch(input.entryId)
|
|
722
|
+
if (result.changed) await this.chat.refreshWorkSession(source)
|
|
723
|
+
}
|
|
692
724
|
} catch (error) {
|
|
693
|
-
if (source.branchId !== previousItem.branchId) {
|
|
694
|
-
await this.chat.refreshWorkSession(source)
|
|
725
|
+
if (source.branchId !== previousItem.branchId || refreshed) {
|
|
726
|
+
if (!refreshed) await this.chat.refreshWorkSession(source, false)
|
|
695
727
|
const changes = this.toChanges(previousItem, this.toListItem(source))
|
|
696
728
|
if (changes) this.publishUpdate({ type: 'update', workId: source.workId, changes })
|
|
697
|
-
} else {
|
|
698
|
-
this.chat.resumeWorkSession(source.workId)
|
|
699
729
|
}
|
|
700
730
|
this.throwBranchError(error, input.entryId)
|
|
731
|
+
} finally {
|
|
732
|
+
this.chat.resumeWorkSession(source.workId)
|
|
701
733
|
}
|
|
702
734
|
|
|
703
735
|
const item = this.toListItem(source)
|
|
@@ -710,6 +742,7 @@ export class WorkSessionManage {
|
|
|
710
742
|
sessionId: source.sessionId,
|
|
711
743
|
entryId: input.entryId,
|
|
712
744
|
branchId: source.branchId,
|
|
745
|
+
action: input.action,
|
|
713
746
|
changed: result.changed
|
|
714
747
|
})
|
|
715
748
|
return L2WorkSessionBranchResponseSchema.parse({
|
|
@@ -857,6 +890,9 @@ export class WorkSessionManage {
|
|
|
857
890
|
if (error instanceof L4PiSessionForkTargetError) {
|
|
858
891
|
throw new WorkSessionBranchInvalidError('fork-target', '只有用户消息可以 Fork')
|
|
859
892
|
}
|
|
893
|
+
if (error instanceof L4PiSessionResendTargetError) {
|
|
894
|
+
throw new WorkSessionBranchInvalidError('resend-target', '只有用户消息可以重发')
|
|
895
|
+
}
|
|
860
896
|
if (error instanceof L4PiSessionCloneEmptyError) {
|
|
861
897
|
throw new WorkSessionBranchInvalidError('clone-empty', '当前会话还没有可克隆的消息')
|
|
862
898
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import 'server-only'
|
|
2
2
|
|
|
3
3
|
import type { ThinkingLevel } from '@earendil-works/pi-agent-core'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
L4PiWorkSessionRuntime,
|
|
6
|
+
type L4PiResendInput
|
|
7
|
+
} from '@server/l4_foundation/pi/l4-pi-work-session-runtime'
|
|
5
8
|
|
|
6
9
|
export interface WorkSessionInputImage {
|
|
7
10
|
mimeType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif'
|
|
@@ -10,11 +13,13 @@ export interface WorkSessionInputImage {
|
|
|
10
13
|
height: number
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
export type WorkSessionSendInput =
|
|
17
|
+
| {
|
|
18
|
+
mode: 'auto' | 'follow_up'
|
|
19
|
+
text: string
|
|
20
|
+
images: WorkSessionInputImage[]
|
|
21
|
+
}
|
|
22
|
+
| L4PiResendInput
|
|
18
23
|
|
|
19
24
|
export interface WorkSessionModelInput {
|
|
20
25
|
provider: string
|
|
@@ -899,7 +899,7 @@ export class L4PiChatWorker {
|
|
|
899
899
|
await session.abort()
|
|
900
900
|
}
|
|
901
901
|
|
|
902
|
-
async navigateTree(entryId: string): Promise<boolean> {
|
|
902
|
+
async navigateTree(entryId: string, beforeUserMessage = false): Promise<boolean> {
|
|
903
903
|
const session = await this.ensureSession()
|
|
904
904
|
this.assertIdle()
|
|
905
905
|
if (this.treeResumeImmediate) clearImmediate(this.treeResumeImmediate)
|
|
@@ -913,7 +913,10 @@ export class L4PiChatWorker {
|
|
|
913
913
|
this.messageGate.pause()
|
|
914
914
|
try {
|
|
915
915
|
this.initialization.setStage('切换会话树')
|
|
916
|
-
const result =
|
|
916
|
+
const result =
|
|
917
|
+
beforeUserMessage && previousLeaf === entryId
|
|
918
|
+
? await this.navigateLeafUserMessage(session, entryId)
|
|
919
|
+
: await session.navigateTree(entryId, { summarize: false })
|
|
917
920
|
changed = !result.cancelled
|
|
918
921
|
if (changed) await this.capabilityRuntime.apply()
|
|
919
922
|
} catch (error) {
|
|
@@ -948,6 +951,36 @@ export class L4PiChatWorker {
|
|
|
948
951
|
}
|
|
949
952
|
}
|
|
950
953
|
|
|
954
|
+
private async navigateLeafUserMessage(
|
|
955
|
+
session: AgentSession,
|
|
956
|
+
entryId: string
|
|
957
|
+
): Promise<{ cancelled: boolean }> {
|
|
958
|
+
const entry = this.sessionManager.getEntry(entryId)!
|
|
959
|
+
// SDK 对当前 leaf 直接 no-op;重发仍需执行导航钩子并回到该用户消息之前。
|
|
960
|
+
const result = await session.extensionRunner.emit({
|
|
961
|
+
type: 'session_before_tree',
|
|
962
|
+
preparation: {
|
|
963
|
+
targetId: entryId,
|
|
964
|
+
oldLeafId: entryId,
|
|
965
|
+
commonAncestorId: entryId,
|
|
966
|
+
entriesToSummarize: [],
|
|
967
|
+
userWantsSummary: false
|
|
968
|
+
},
|
|
969
|
+
signal: this.commandLifetime.signal
|
|
970
|
+
})
|
|
971
|
+
if (result?.cancel || this.commandLifetime.signal.aborted) return { cancelled: true }
|
|
972
|
+
if (entry.parentId === null) this.sessionManager.resetLeaf()
|
|
973
|
+
else this.sessionManager.branch(entry.parentId)
|
|
974
|
+
if (result?.label) this.sessionManager.appendLabelChange(entryId, result.label)
|
|
975
|
+
session.refreshContext()
|
|
976
|
+
await session.extensionRunner.emit({
|
|
977
|
+
type: 'session_tree',
|
|
978
|
+
oldLeafId: entryId,
|
|
979
|
+
newLeafId: this.sessionManager.getLeafId()
|
|
980
|
+
})
|
|
981
|
+
return { cancelled: false }
|
|
982
|
+
}
|
|
983
|
+
|
|
951
984
|
private resetBranchRuntime(): void {
|
|
952
985
|
if (this.treeNavigation) this.treeNavigation.committed = true
|
|
953
986
|
this.commandLifetime.abort()
|
|
@@ -26,13 +26,20 @@ import {
|
|
|
26
26
|
} from '@earendil-works/pi-coding-agent'
|
|
27
27
|
import { z } from 'zod'
|
|
28
28
|
import { findL4PiSessionFile } from './l4-pi-session-discovery'
|
|
29
|
+
import {
|
|
30
|
+
compactL4PiSessionPreview as compactPreview,
|
|
31
|
+
matchL4PiSessionSearch,
|
|
32
|
+
normalizeL4PiSessionSearch as normalizeSearch,
|
|
33
|
+
readL4PiSessionMessageText as messageText,
|
|
34
|
+
readL4PiSessionTimestamp as timestampMs,
|
|
35
|
+
type L4PiSessionSearchMatch,
|
|
36
|
+
type L4PiSessionSearchScope
|
|
37
|
+
} from './l4-pi-session-search'
|
|
29
38
|
|
|
30
39
|
const SCAN_CONCURRENCY = 10
|
|
31
|
-
const MATCH_PREVIEW_MAX_LENGTH = 120
|
|
32
|
-
const MATCH_PREVIEW_PREFIX_LENGTH = 16
|
|
33
40
|
const FIRST_MESSAGE_PREVIEW_MAX_LENGTH = 160
|
|
34
41
|
const CACHE_VALIDATION_INTERVAL_MS = 2_000
|
|
35
|
-
const CACHE_IDLE_MS =
|
|
42
|
+
const CACHE_IDLE_MS = 60_000
|
|
36
43
|
const CACHE_CWD_LIMIT = 8
|
|
37
44
|
const CACHE_TEXT_BYTES_LIMIT = 32 * 1024 * 1024
|
|
38
45
|
const CACHE_FILE_LIMIT = 4_096
|
|
@@ -41,7 +48,7 @@ const LEGACY_CACHE_FILE_NAME = 'pi-session-history.json'
|
|
|
41
48
|
const PERSISTED_CACHE_VERSION = 2
|
|
42
49
|
const CACHE_DISK_BYTES_LIMIT = 64 * 1024 * 1024
|
|
43
50
|
|
|
44
|
-
export type L4PiSessionHistorySearchScope =
|
|
51
|
+
export type L4PiSessionHistorySearchScope = L4PiSessionSearchScope
|
|
45
52
|
|
|
46
53
|
const DEFAULT_SEARCH_IN: readonly L4PiSessionHistorySearchScope[] = ['title', 'user']
|
|
47
54
|
|
|
@@ -72,13 +79,7 @@ interface L4PiSessionAssistantMessage {
|
|
|
72
79
|
text: string
|
|
73
80
|
}
|
|
74
81
|
|
|
75
|
-
export
|
|
76
|
-
scope: L4PiSessionHistorySearchScope
|
|
77
|
-
count: number
|
|
78
|
-
entryId: string | null
|
|
79
|
-
timestampMs: number | null
|
|
80
|
-
preview: string
|
|
81
|
-
}
|
|
82
|
+
export type L4PiSessionHistoryMatch = L4PiSessionSearchMatch
|
|
82
83
|
|
|
83
84
|
export interface L4PiSessionHistoryItem {
|
|
84
85
|
sessionId: string
|
|
@@ -184,6 +185,7 @@ interface L4PiSessionHistoryCatalogState {
|
|
|
184
185
|
epochs: Map<string, number>
|
|
185
186
|
activeLoads: Map<string, L4PiSessionHistoryCatalogLoad>
|
|
186
187
|
catalogs: Map<string, L4PiSessionHistoryCatalog>
|
|
188
|
+
cleanupTimer: ReturnType<typeof setTimeout> | null
|
|
187
189
|
}
|
|
188
190
|
|
|
189
191
|
interface L4PiSessionScanState {
|
|
@@ -365,7 +367,8 @@ function historyCatalogState(): L4PiSessionHistoryCatalogState {
|
|
|
365
367
|
globalThis.__piDeskPiSessionHistoryCatalogState = {
|
|
366
368
|
epochs: new Map(),
|
|
367
369
|
activeLoads: new Map(),
|
|
368
|
-
catalogs: new Map()
|
|
370
|
+
catalogs: new Map(),
|
|
371
|
+
cleanupTimer: null
|
|
369
372
|
}
|
|
370
373
|
}
|
|
371
374
|
return globalThis.__piDeskPiSessionHistoryCatalogState
|
|
@@ -375,37 +378,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
|
|
|
375
378
|
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
376
379
|
}
|
|
377
380
|
|
|
378
|
-
function timestampMs(value: unknown): number | null {
|
|
379
|
-
if (typeof value === 'number' && Number.isSafeInteger(value) && value >= 0) return value
|
|
380
|
-
if (typeof value !== 'string') return null
|
|
381
|
-
const parsed = Date.parse(value)
|
|
382
|
-
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function normalizeSearch(value: string): string {
|
|
386
|
-
return value.trim().toLowerCase()
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
function compactPreview(text: string, maxLength: number): string {
|
|
390
|
-
const content = text.replace(/\s+/g, ' ').trim()
|
|
391
|
-
if (content.length <= maxLength) return content
|
|
392
|
-
return `${content.slice(0, maxLength - 1).trimEnd()}…`
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
function messageText(message: unknown): string {
|
|
396
|
-
if (!isRecord(message)) return ''
|
|
397
|
-
const content = message.content
|
|
398
|
-
if (typeof content === 'string') return content
|
|
399
|
-
if (!Array.isArray(content)) return ''
|
|
400
|
-
|
|
401
|
-
return content
|
|
402
|
-
.flatMap((part) => {
|
|
403
|
-
if (!isRecord(part) || part.type !== 'text' || typeof part.text !== 'string') return []
|
|
404
|
-
return [part.text]
|
|
405
|
-
})
|
|
406
|
-
.join('\n')
|
|
407
|
-
}
|
|
408
|
-
|
|
409
381
|
function messageTimestamp(entry: Record<string, unknown>, fallback: number): number {
|
|
410
382
|
const entryTimestamp = timestampMs(entry.timestamp)
|
|
411
383
|
if (entryTimestamp !== null) return entryTimestamp
|
|
@@ -696,11 +668,31 @@ async function refreshCatalog(
|
|
|
696
668
|
}
|
|
697
669
|
}
|
|
698
670
|
|
|
699
|
-
function
|
|
700
|
-
|
|
671
|
+
function scheduleCatalogRelease(state: L4PiSessionHistoryCatalogState): void {
|
|
672
|
+
if (state.cleanupTimer) clearTimeout(state.cleanupTimer)
|
|
673
|
+
state.cleanupTimer = null
|
|
674
|
+
if (state.catalogs.size === 0) return
|
|
675
|
+
const expiresAt = Math.min(
|
|
676
|
+
...Array.from(state.catalogs.values(), (catalog) => catalog.lastAccessedAt + CACHE_IDLE_MS)
|
|
677
|
+
)
|
|
678
|
+
state.cleanupTimer = setTimeout(
|
|
679
|
+
() => {
|
|
680
|
+
state.cleanupTimer = null
|
|
681
|
+
pruneCatalogs(Date.now(), state)
|
|
682
|
+
},
|
|
683
|
+
Math.max(0, expiresAt - Date.now())
|
|
684
|
+
)
|
|
685
|
+
state.cleanupTimer.unref()
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
function pruneCatalogs(
|
|
689
|
+
now: number,
|
|
690
|
+
state: L4PiSessionHistoryCatalogState = historyCatalogState()
|
|
691
|
+
): void {
|
|
701
692
|
for (const [cwd, catalog] of state.catalogs) {
|
|
702
|
-
if (now - catalog.lastAccessedAt
|
|
693
|
+
if (now - catalog.lastAccessedAt >= CACHE_IDLE_MS) state.catalogs.delete(cwd)
|
|
703
694
|
}
|
|
695
|
+
scheduleCatalogRelease(state)
|
|
704
696
|
}
|
|
705
697
|
|
|
706
698
|
function touchCatalog(catalog: L4PiSessionHistoryCatalog, now: number): L4PiSessionHistoryCatalog {
|
|
@@ -708,6 +700,7 @@ function touchCatalog(catalog: L4PiSessionHistoryCatalog, now: number): L4PiSess
|
|
|
708
700
|
const state = historyCatalogState()
|
|
709
701
|
state.catalogs.delete(catalog.cwd)
|
|
710
702
|
state.catalogs.set(catalog.cwd, catalog)
|
|
703
|
+
scheduleCatalogRelease(state)
|
|
711
704
|
return catalog
|
|
712
705
|
}
|
|
713
706
|
|
|
@@ -715,6 +708,7 @@ function storeCatalog(catalog: L4PiSessionHistoryCatalog, persist: boolean): voi
|
|
|
715
708
|
const state = historyCatalogState()
|
|
716
709
|
if (catalog.files.size > CACHE_FILE_LIMIT || catalog.textBytes > CACHE_TEXT_BYTES_LIMIT) {
|
|
717
710
|
state.catalogs.delete(catalog.cwd)
|
|
711
|
+
scheduleCatalogRelease(state)
|
|
718
712
|
if (persist) {
|
|
719
713
|
const path = persistedHistoryCachePath(catalog.cwd)
|
|
720
714
|
try {
|
|
@@ -747,6 +741,7 @@ function storeCatalog(catalog: L4PiSessionHistoryCatalog, persist: boolean): voi
|
|
|
747
741
|
state.catalogs.delete(oldest[0])
|
|
748
742
|
totalBytes -= oldest[1].textBytes
|
|
749
743
|
}
|
|
744
|
+
scheduleCatalogRelease(state)
|
|
750
745
|
if (persist) persistHistoryCatalog(catalog)
|
|
751
746
|
}
|
|
752
747
|
|
|
@@ -768,8 +763,9 @@ async function getCatalog(
|
|
|
768
763
|
const state = historyCatalogState()
|
|
769
764
|
const now = Date.now()
|
|
770
765
|
pruneCatalogs(now)
|
|
771
|
-
const
|
|
772
|
-
const
|
|
766
|
+
const cached = state.catalogs.get(cwd)
|
|
767
|
+
const catalog = cached ? touchCatalog(cached, now) : readPersistedHistoryCatalog(cwd)
|
|
768
|
+
const epoch = forceRefresh && state.activeLoads.has(cwd) ? incrementEpoch(cwd) : currentEpoch(cwd)
|
|
773
769
|
if (forceRefresh && catalog) catalog.dirty = true
|
|
774
770
|
const active = state.activeLoads.get(cwd)
|
|
775
771
|
if (active && active.epoch === epoch) return active.promise
|
|
@@ -783,10 +779,12 @@ async function getCatalog(
|
|
|
783
779
|
return touchCatalog(catalog, now)
|
|
784
780
|
}
|
|
785
781
|
|
|
786
|
-
const load = (async ()
|
|
782
|
+
const load: Promise<L4PiSessionHistoryCatalog> = Promise.resolve().then(async () => {
|
|
787
783
|
const refresh = await refreshCatalog(cwd, catalog)
|
|
788
784
|
const refreshed = refresh.catalog
|
|
789
|
-
if (currentEpoch(cwd) === epoch)
|
|
785
|
+
if (state.activeLoads.get(cwd)?.promise === load && currentEpoch(cwd) === epoch) {
|
|
786
|
+
storeCatalog(refreshed, refresh.changed)
|
|
787
|
+
}
|
|
790
788
|
console.info('[Pi Desk][PiSessionHistoryCatalog] 已更新历史会话内存投影', {
|
|
791
789
|
cwd,
|
|
792
790
|
sessionCount: refreshed.sessions.length,
|
|
@@ -795,43 +793,15 @@ async function getCatalog(
|
|
|
795
793
|
forceRefresh
|
|
796
794
|
})
|
|
797
795
|
return refreshed
|
|
798
|
-
})
|
|
796
|
+
})
|
|
799
797
|
state.activeLoads.set(cwd, { epoch, promise: load })
|
|
800
798
|
try {
|
|
801
799
|
return await load
|
|
802
800
|
} finally {
|
|
803
|
-
if (state.activeLoads.get(cwd)?.promise === load)
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
function previewForMatch(text: string, normalizedQuery: string): string {
|
|
808
|
-
const normalizedText = text.toLowerCase()
|
|
809
|
-
const matchIndex = normalizedText.indexOf(normalizedQuery)
|
|
810
|
-
if (matchIndex < 0) return ''
|
|
811
|
-
|
|
812
|
-
const start = Math.max(0, matchIndex - MATCH_PREVIEW_PREFIX_LENGTH)
|
|
813
|
-
const requiredEnd = matchIndex + normalizedQuery.length
|
|
814
|
-
const end = Math.min(text.length, Math.max(start + MATCH_PREVIEW_MAX_LENGTH, requiredEnd))
|
|
815
|
-
const content = text.slice(start, end).replace(/\s+/g, ' ').trim()
|
|
816
|
-
return `${start > 0 ? '…' : ''}${content}${end < text.length ? '…' : ''}`
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
function messageMatch(
|
|
820
|
-
scope: 'user' | 'assistant',
|
|
821
|
-
messages: readonly L4PiSessionUserMessage[] | readonly L4PiSessionAssistantMessage[],
|
|
822
|
-
normalizedQuery: string
|
|
823
|
-
): L4PiSessionHistoryMatch | null {
|
|
824
|
-
const matching = messages.filter((message) =>
|
|
825
|
-
message.text.toLowerCase().includes(normalizedQuery)
|
|
826
|
-
)
|
|
827
|
-
if (matching.length === 0) return null
|
|
828
|
-
const latest = matching.at(-1)!
|
|
829
|
-
return {
|
|
830
|
-
scope,
|
|
831
|
-
count: matching.length,
|
|
832
|
-
entryId: latest.entryId,
|
|
833
|
-
timestampMs: latest.timestampMs,
|
|
834
|
-
preview: previewForMatch(latest.text, normalizedQuery)
|
|
801
|
+
if (state.activeLoads.get(cwd)?.promise === load) {
|
|
802
|
+
state.activeLoads.delete(cwd)
|
|
803
|
+
state.epochs.delete(cwd)
|
|
804
|
+
}
|
|
835
805
|
}
|
|
836
806
|
}
|
|
837
807
|
|
|
@@ -854,33 +824,7 @@ function projectHistoryItem(
|
|
|
854
824
|
}
|
|
855
825
|
}
|
|
856
826
|
|
|
857
|
-
const matches
|
|
858
|
-
if (searchIn.has('title') && session.name?.toLowerCase().includes(normalizedQuery)) {
|
|
859
|
-
matches.push({
|
|
860
|
-
scope: 'title',
|
|
861
|
-
count: 1,
|
|
862
|
-
entryId: null,
|
|
863
|
-
timestampMs: null,
|
|
864
|
-
preview: compactPreview(session.name, FIRST_MESSAGE_PREVIEW_MAX_LENGTH)
|
|
865
|
-
})
|
|
866
|
-
}
|
|
867
|
-
if (searchIn.has('user')) {
|
|
868
|
-
const match = messageMatch('user', session.userMessages, normalizedQuery)
|
|
869
|
-
if (match) matches.push(match)
|
|
870
|
-
}
|
|
871
|
-
if (searchIn.has('assistant')) {
|
|
872
|
-
const match = messageMatch('assistant', session.assistantMessages, normalizedQuery)
|
|
873
|
-
if (match) matches.push(match)
|
|
874
|
-
}
|
|
875
|
-
if (searchIn.has('sessionId') && session.sessionId.toLowerCase().includes(normalizedQuery)) {
|
|
876
|
-
matches.push({
|
|
877
|
-
scope: 'sessionId',
|
|
878
|
-
count: 1,
|
|
879
|
-
entryId: null,
|
|
880
|
-
timestampMs: null,
|
|
881
|
-
preview: session.sessionId
|
|
882
|
-
})
|
|
883
|
-
}
|
|
827
|
+
const matches = matchL4PiSessionSearch(session, normalizedQuery, searchIn)
|
|
884
828
|
if (matches.length === 0) return null
|
|
885
829
|
|
|
886
830
|
return {
|
|
@@ -917,7 +861,10 @@ async function getSessionRecord(
|
|
|
917
861
|
): Promise<L4PiSessionHistoryRecord | null> {
|
|
918
862
|
const cwd = resolve(cwdInput)
|
|
919
863
|
pruneCatalogs(Date.now())
|
|
920
|
-
const
|
|
864
|
+
const memoryCatalog = historyCatalogState().catalogs.get(cwd)
|
|
865
|
+
const catalog = memoryCatalog
|
|
866
|
+
? touchCatalog(memoryCatalog, Date.now())
|
|
867
|
+
: readPersistedHistoryCatalog(cwd)
|
|
921
868
|
const previous = catalog?.sessions.find((session) => session.sessionId === sessionId)
|
|
922
869
|
const path = await findL4PiSessionFile(cwd, sessionId, previous?.path)
|
|
923
870
|
if (!path) return null
|
|
@@ -972,8 +919,10 @@ export function resolveCachedL4PiSessionHistoryPath(
|
|
|
972
919
|
cwd: string,
|
|
973
920
|
sessionId: string
|
|
974
921
|
): string | undefined {
|
|
922
|
+
pruneCatalogs(Date.now())
|
|
975
923
|
const catalog = historyCatalogState().catalogs.get(resolve(cwd))
|
|
976
924
|
if (!catalog || catalog.dirty) return undefined
|
|
925
|
+
touchCatalog(catalog, Date.now())
|
|
977
926
|
return catalog.sessions.find((session) => session.sessionId === sessionId)?.path
|
|
978
927
|
}
|
|
979
928
|
|
|
@@ -981,7 +930,7 @@ export function invalidateL4PiSessionHistoryCache(cwd?: string): void {
|
|
|
981
930
|
const state = historyCatalogState()
|
|
982
931
|
if (cwd) {
|
|
983
932
|
const normalizedCwd = resolve(cwd)
|
|
984
|
-
incrementEpoch(normalizedCwd)
|
|
933
|
+
if (state.activeLoads.has(normalizedCwd)) incrementEpoch(normalizedCwd)
|
|
985
934
|
const catalog = state.catalogs.get(normalizedCwd)
|
|
986
935
|
if (catalog) catalog.dirty = true
|
|
987
936
|
return
|
|
@@ -989,7 +938,7 @@ export function invalidateL4PiSessionHistoryCache(cwd?: string): void {
|
|
|
989
938
|
|
|
990
939
|
const affectedCwds = new Set([...state.catalogs.keys(), ...state.activeLoads.keys()])
|
|
991
940
|
for (const catalogCwd of affectedCwds) {
|
|
992
|
-
incrementEpoch(catalogCwd)
|
|
941
|
+
if (state.activeLoads.has(catalogCwd)) incrementEpoch(catalogCwd)
|
|
993
942
|
const catalog = state.catalogs.get(catalogCwd)
|
|
994
943
|
if (catalog) catalog.dirty = true
|
|
995
944
|
}
|