@jetcrab/pi-desk 1.1.25 → 1.1.29-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.
Files changed (340) hide show
  1. package/package.json +1 -1
  2. package/src/app/api/work-sessions/search/route.ts +1 -0
  3. package/src/app/project-preview/page.tsx +1 -3
  4. package/src/client/l2_biz/project-preview/hooks/l2-use-project-preview.ts +1 -14
  5. package/src/client/l2_biz/project-preview/l2-project-preview-dialog.tsx +0 -1
  6. package/src/client/l2_biz/project-preview/l2-project-preview-page.tsx +0 -1
  7. package/src/client/l2_biz/project-preview/l2-project-preview.tsx +1 -4
  8. package/src/client/l2_biz/project-preview/views/l2-project-branch-select.tsx +42 -3
  9. package/src/client/l2_biz/workbench/git-workspace/l2-git-workspace-runtime.ts +11 -10
  10. package/src/client/l2_biz/workbench/hooks/l2-work-session-search.ts +52 -0
  11. package/src/client/l2_biz/workbench/hooks/l2-workbench-branch-picker.ts +42 -7
  12. package/src/client/l2_biz/workbench/hooks/l2-workbench-session-history.ts +143 -131
  13. package/src/client/l2_biz/workbench/hooks/l2-workbench-session-search.ts +97 -0
  14. package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +8 -0
  15. package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +129 -10
  16. package/src/client/l2_biz/workbench/l2-workbench-biz.ts +20 -2
  17. package/src/client/l2_biz/workbench/l2-workbench-branch-filter-preferences.ts +34 -0
  18. package/src/client/l2_biz/workbench/l2-workbench-branch-picker.tsx +34 -71
  19. package/src/client/l2_biz/workbench/l2-workbench-chat-input-runtime.ts +38 -1
  20. package/src/client/l2_biz/workbench/l2-workbench-chat-view.tsx +11 -1
  21. package/src/client/l2_biz/workbench/l2-workbench-picker-dialog.tsx +55 -215
  22. package/src/client/l2_biz/workbench/l2-workbench.tsx +20 -38
  23. package/src/client/l2_biz/workbench/views/l2-workbench-session-search.tsx +123 -0
  24. package/src/client/l3_modules/conversation/l3-conversation-messages.tsx +43 -4
  25. package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +1 -1
  26. package/src/client/l3_modules/project-files/l3-project-document-git.ts +13 -29
  27. package/src/client/l3_modules/project-files/l3-project-document-view.tsx +1 -4
  28. package/src/client/l3_modules/project-files/l3-project-file-browser.module.css +14 -18
  29. package/src/client/l3_modules/project-files/l3-project-file-browser.tsx +52 -95
  30. package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +52 -21
  31. package/src/client/l3_modules/project-files/l3-project-file-tabs.tsx +41 -62
  32. package/src/client/l3_modules/project-files/l3-project-git-runtime.ts +5 -4
  33. package/src/client/l3_modules/project-files/l3-use-project-refresh.ts +36 -0
  34. package/src/client/l3_modules/project-files/views/l3-project-search-results.tsx +2 -2
  35. package/src/client/l3_modules/project-files/views/l3-project-tree-folder.tsx +86 -0
  36. package/src/client/l4_foundation/ui/file-icons/README.md +1 -1
  37. package/src/client/l4_foundation/ui/file-icons/l4-file-icon.tsx +49 -2
  38. package/src/common/l2_biz/pi-session/l2-pi-session-contract.ts +11 -24
  39. package/src/common/l2_biz/project-preview/l2-project-preview-navigation.ts +5 -12
  40. package/src/common/l2_biz/work-session/l2-work-session-search-contract.ts +26 -0
  41. package/src/common/l2_biz/work-session/l2-work-session-tree-contract.ts +9 -1
  42. package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +12 -0
  43. package/src/common/l2_biz/workbench/l2-workbench-picker-messages.ts +6 -2
  44. package/src/common/l3_modules/conversation/l3-conversation-locale-messages.ts +2 -0
  45. package/src/common/l3_modules/pi/l3-pi-session-search-contract.ts +26 -0
  46. package/src/common/l4_foundation/locale/l4-host-error-messages.ts +2 -0
  47. package/src/server/l1_entry/api/l1-work-session-branch-route.ts +21 -15
  48. package/src/server/l1_entry/api/l1-work-session-search-route.ts +38 -0
  49. package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +4 -2
  50. package/src/server/l2_biz/work-session/l2-work-session-manage.ts +46 -10
  51. package/src/server/l3_modules/work-session/l3-work-session.ts +11 -6
  52. package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +35 -2
  53. package/src/server/l4_foundation/pi/l4-pi-session-history-catalog.ts +62 -113
  54. package/src/server/l4_foundation/pi/l4-pi-session-search.ts +166 -0
  55. package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +66 -5
  56. package/src/server/l4_foundation/process/l4-process-tree.js +159 -40
  57. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  58. package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +1 -0
  59. package/temp/build/pi-desk/release/.next/build-manifest.json +2 -2
  60. package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
  61. package/temp/build/pi-desk/release/.next/required-server-files.js +3 -3
  62. package/temp/build/pi-desk/release/.next/required-server-files.json +3 -3
  63. package/temp/build/pi-desk/release/.next/routes-manifest.json +6 -0
  64. package/temp/build/pi-desk/release/.next/server/app/_global-error/page.js +1 -1
  65. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  66. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  67. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
  68. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  69. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  70. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  71. package/temp/build/pi-desk/release/.next/server/app/_not-found/page.js +1 -1
  72. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  73. package/temp/build/pi-desk/release/.next/server/app/api/auth/login/route.js +2 -2
  74. package/temp/build/pi-desk/release/.next/server/app/api/auth/logout/route.js +1 -1
  75. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/get/route.js +1 -1
  76. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/replace/route.js +1 -1
  77. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/get/route.js +1 -1
  78. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/replace/route.js +1 -1
  79. package/temp/build/pi-desk/release/.next/server/app/api/chat/context/get/route.js +1 -1
  80. package/temp/build/pi-desk/release/.next/server/app/api/chat/images/get/route.js +1 -1
  81. package/temp/build/pi-desk/release/.next/server/app/api/chat/messages/get/route.js +1 -1
  82. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  83. package/temp/build/pi-desk/release/.next/server/app/api/mcp-check/get/route.js +1 -1
  84. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/del/route.js +1 -1
  85. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/get/route.js +1 -1
  86. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/replace/route.js +1 -1
  87. package/temp/build/pi-desk/release/.next/server/app/api/model-catalog/list/route.js +1 -1
  88. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/get/route.js +1 -1
  89. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/preview/route.js +1 -1
  90. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/replace/route.js +1 -1
  91. package/temp/build/pi-desk/release/.next/server/app/api/pi/directories/list/route.js +1 -1
  92. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-entries/list/route.js +1 -1
  93. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/list/route.js +1 -1
  94. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/replace/route.js +1 -1
  95. package/temp/build/pi-desk/release/.next/server/app/api/pi/models/list/route.js +1 -1
  96. package/temp/build/pi-desk/release/.next/server/app/api/pi/session-user-messages/list/route.js +1 -1
  97. package/temp/build/pi-desk/release/.next/server/app/api/pi/sessions/list/route.js +1 -1
  98. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/get/route.js +1 -1
  99. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/search/route.js +1 -1
  100. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-get/route.js +1 -1
  101. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-replace/route.js +1 -1
  102. package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
  103. package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
  104. package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
  105. package/temp/build/pi-desk/release/.next/server/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route.js +1 -1
  106. package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
  107. package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
  108. package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
  109. package/temp/build/pi-desk/release/.next/server/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route.js +1 -1
  110. package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
  111. package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
  112. package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
  113. package/temp/build/pi-desk/release/.next/server/app/api/project-files/get/route.js +2 -2
  114. package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +1 -1
  115. package/temp/build/pi-desk/release/.next/server/app/api/project-files/reveal/route.js +1 -1
  116. package/temp/build/pi-desk/release/.next/server/app/api/project-files/search/route.js +1 -1
  117. package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +2 -2
  118. package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +2 -2
  119. package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +1 -1
  120. package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +2 -2
  121. package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +1 -1
  122. package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +2 -2
  123. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/get/route.js +1 -1
  124. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/replace/route.js +1 -1
  125. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/get/route.js +1 -1
  126. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/list/route.js +1 -1
  127. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/replace/route.js +1 -1
  128. package/temp/build/pi-desk/release/.next/server/app/api/skills/list/route.js +1 -1
  129. package/temp/build/pi-desk/release/.next/server/app/api/task-center/images/get/route.js +1 -1
  130. package/temp/build/pi-desk/release/.next/server/app/api/task-center/messages/get/route.js +1 -1
  131. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/add/route.js +1 -1
  132. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/replace/route.js +1 -1
  133. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree/get/route.js +1 -1
  134. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree-entry/get/route.js +1 -1
  135. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/add/route.js +1 -1
  136. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/branch/route.js +1 -1
  137. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/del/route.js +1 -1
  138. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route.js +1 -1
  139. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/replace/route.js +1 -1
  140. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/search/route.js +1 -0
  141. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/search/route_client-reference-manifest.js +1 -0
  142. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/sort/route.js +1 -1
  143. package/temp/build/pi-desk/release/.next/server/app/favicon.ico/route.js +1 -1
  144. package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
  145. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  146. package/temp/build/pi-desk/release/.next/server/app/page.js +138 -138
  147. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  148. package/temp/build/pi-desk/release/.next/server/app/project-preview/page.js +1 -1
  149. package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
  150. package/temp/build/pi-desk/release/.next/server/app-paths-manifest.json +1 -0
  151. package/temp/build/pi-desk/release/.next/server/chunks/23054.js +2 -2
  152. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -8
  153. package/temp/build/pi-desk/release/.next/server/chunks/27344.js +3 -3
  154. package/temp/build/pi-desk/release/.next/server/chunks/3108.js +3 -3
  155. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +2 -2
  156. package/temp/build/pi-desk/release/.next/server/chunks/41856.js +1 -0
  157. package/temp/build/pi-desk/release/.next/server/chunks/62900.js +235 -0
  158. package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
  159. package/temp/build/pi-desk/release/.next/server/chunks/81363.js +1 -1
  160. package/temp/build/pi-desk/release/.next/server/chunks/81912.js +3 -0
  161. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +2 -2
  162. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  163. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  164. package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
  165. package/temp/build/pi-desk/release/.next/static/Yyfg-r17aYmEzlYYlIwDo/_buildManifest.js +1 -0
  166. package/temp/build/pi-desk/release/.next/static/chunks/10043-9d6c3735418ccaf9.js +238 -0
  167. package/temp/build/pi-desk/release/.next/static/chunks/11937-ac71fb0f7cef482a.js +1 -0
  168. package/temp/build/pi-desk/release/.next/static/chunks/30669-ffa76d39e0e25194.js +1 -0
  169. package/temp/build/pi-desk/release/.next/static/chunks/36643-f60e98278740073c.js +3 -0
  170. package/temp/build/pi-desk/release/.next/static/chunks/65232-a8571f78020eede2.js +15 -0
  171. package/temp/build/pi-desk/release/.next/static/chunks/{51474-8dc714cb76b2e60a.js → 65350-23bb961d87addf14.js} +3 -3
  172. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-295cb63da5f7262f.js +1 -0
  173. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-295cb63da5f7262f.js +1 -0
  174. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-295cb63da5f7262f.js +1 -0
  175. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-295cb63da5f7262f.js +1 -0
  176. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-295cb63da5f7262f.js +1 -0
  177. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-295cb63da5f7262f.js +1 -0
  178. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-295cb63da5f7262f.js +1 -0
  179. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-295cb63da5f7262f.js +1 -0
  180. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-295cb63da5f7262f.js +1 -0
  181. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-295cb63da5f7262f.js +1 -0
  182. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-295cb63da5f7262f.js +1 -0
  183. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-295cb63da5f7262f.js +1 -0
  184. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-295cb63da5f7262f.js +1 -0
  185. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-295cb63da5f7262f.js +1 -0
  186. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-295cb63da5f7262f.js +1 -0
  187. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-295cb63da5f7262f.js +1 -0
  188. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-295cb63da5f7262f.js +1 -0
  189. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-295cb63da5f7262f.js +1 -0
  190. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-295cb63da5f7262f.js +1 -0
  191. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-295cb63da5f7262f.js +1 -0
  192. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-295cb63da5f7262f.js +1 -0
  193. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-295cb63da5f7262f.js +1 -0
  194. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-295cb63da5f7262f.js +1 -0
  195. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-295cb63da5f7262f.js +1 -0
  196. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-295cb63da5f7262f.js +1 -0
  197. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-295cb63da5f7262f.js +1 -0
  198. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-295cb63da5f7262f.js +1 -0
  199. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-295cb63da5f7262f.js +1 -0
  200. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-295cb63da5f7262f.js +1 -0
  201. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-295cb63da5f7262f.js +1 -0
  202. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-295cb63da5f7262f.js +1 -0
  203. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-295cb63da5f7262f.js +1 -0
  204. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-295cb63da5f7262f.js +1 -0
  205. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-295cb63da5f7262f.js +1 -0
  206. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-295cb63da5f7262f.js +1 -0
  207. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-295cb63da5f7262f.js +1 -0
  208. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-295cb63da5f7262f.js +1 -0
  209. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-295cb63da5f7262f.js +1 -0
  210. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-295cb63da5f7262f.js +1 -0
  211. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-295cb63da5f7262f.js +1 -0
  212. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-295cb63da5f7262f.js +1 -0
  213. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-295cb63da5f7262f.js +1 -0
  214. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-295cb63da5f7262f.js +1 -0
  215. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-295cb63da5f7262f.js +1 -0
  216. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-295cb63da5f7262f.js +1 -0
  217. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-295cb63da5f7262f.js +1 -0
  218. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-295cb63da5f7262f.js +1 -0
  219. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-295cb63da5f7262f.js +1 -0
  220. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-295cb63da5f7262f.js +1 -0
  221. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-295cb63da5f7262f.js +1 -0
  222. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-295cb63da5f7262f.js +1 -0
  223. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-295cb63da5f7262f.js +1 -0
  224. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-295cb63da5f7262f.js +1 -0
  225. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-295cb63da5f7262f.js +1 -0
  226. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-295cb63da5f7262f.js +1 -0
  227. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-295cb63da5f7262f.js +1 -0
  228. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-295cb63da5f7262f.js +1 -0
  229. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-295cb63da5f7262f.js +1 -0
  230. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-295cb63da5f7262f.js +1 -0
  231. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-295cb63da5f7262f.js +1 -0
  232. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-295cb63da5f7262f.js +1 -0
  233. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-295cb63da5f7262f.js +1 -0
  234. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-295cb63da5f7262f.js +1 -0
  235. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-295cb63da5f7262f.js +1 -0
  236. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-295cb63da5f7262f.js +1 -0
  237. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-295cb63da5f7262f.js +1 -0
  238. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-295cb63da5f7262f.js +1 -0
  239. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-295cb63da5f7262f.js +1 -0
  240. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-295cb63da5f7262f.js +1 -0
  241. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/search/route-295cb63da5f7262f.js +1 -0
  242. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-295cb63da5f7262f.js +1 -0
  243. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-2c6a573d3004516e.js +1 -0
  244. package/temp/build/pi-desk/release/.next/static/chunks/app/login/{page-0d3d4827802108e5.js → page-0df9df996aa68060.js} +1 -1
  245. package/temp/build/pi-desk/release/.next/static/chunks/app/page-f78be007d97f0d95.js +158 -0
  246. package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/{page-038b6c14e03ed878.js → page-e1dbfcfc0f333e01.js} +1 -1
  247. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-295cb63da5f7262f.js +1 -0
  248. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-295cb63da5f7262f.js +1 -0
  249. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-295cb63da5f7262f.js +1 -0
  250. package/temp/build/pi-desk/release/.next/static/css/{1e780a4936aa6ba3.css → 2bb393927ba8f71d.css} +1 -1
  251. package/temp/build/pi-desk/release/.next/static/css/3a07dcc86ffdf88c.css +1 -0
  252. package/temp/build/pi-desk/release/.next/static/css/a677e7fbf6e2173e.css +1 -0
  253. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  254. package/temp/build/pi-desk/release/.next/server/chunks/35348.js +0 -3
  255. package/temp/build/pi-desk/release/.next/server/chunks/56830.js +0 -235
  256. package/temp/build/pi-desk/release/.next/server/chunks/80780.js +0 -1
  257. package/temp/build/pi-desk/release/.next/static/6a4eIEjmpW5l8Qlgtzzzg/_buildManifest.js +0 -1
  258. package/temp/build/pi-desk/release/.next/static/chunks/11937-1d0a9822f2c7995b.js +0 -1
  259. package/temp/build/pi-desk/release/.next/static/chunks/14197-3d3ddd426ac06c9c.js +0 -3
  260. package/temp/build/pi-desk/release/.next/static/chunks/37313-d5970e2d0c270d22.js +0 -238
  261. package/temp/build/pi-desk/release/.next/static/chunks/65232-ef4e5a4174f62faf.js +0 -15
  262. package/temp/build/pi-desk/release/.next/static/chunks/79267-7d21d7cdbd7cfca1.js +0 -1
  263. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-9969fe0baa238786.js +0 -1
  264. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-9969fe0baa238786.js +0 -1
  265. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-9969fe0baa238786.js +0 -1
  266. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-9969fe0baa238786.js +0 -1
  267. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-9969fe0baa238786.js +0 -1
  268. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-9969fe0baa238786.js +0 -1
  269. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-9969fe0baa238786.js +0 -1
  270. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-9969fe0baa238786.js +0 -1
  271. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-9969fe0baa238786.js +0 -1
  272. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-9969fe0baa238786.js +0 -1
  273. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-9969fe0baa238786.js +0 -1
  274. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-9969fe0baa238786.js +0 -1
  275. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-9969fe0baa238786.js +0 -1
  276. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-9969fe0baa238786.js +0 -1
  277. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-9969fe0baa238786.js +0 -1
  278. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-9969fe0baa238786.js +0 -1
  279. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-9969fe0baa238786.js +0 -1
  280. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-9969fe0baa238786.js +0 -1
  281. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-9969fe0baa238786.js +0 -1
  282. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-9969fe0baa238786.js +0 -1
  283. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-9969fe0baa238786.js +0 -1
  284. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-9969fe0baa238786.js +0 -1
  285. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-9969fe0baa238786.js +0 -1
  286. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-9969fe0baa238786.js +0 -1
  287. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-9969fe0baa238786.js +0 -1
  288. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-9969fe0baa238786.js +0 -1
  289. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-9969fe0baa238786.js +0 -1
  290. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-9969fe0baa238786.js +0 -1
  291. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-9969fe0baa238786.js +0 -1
  292. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-9969fe0baa238786.js +0 -1
  293. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-9969fe0baa238786.js +0 -1
  294. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-9969fe0baa238786.js +0 -1
  295. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-9969fe0baa238786.js +0 -1
  296. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-9969fe0baa238786.js +0 -1
  297. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-9969fe0baa238786.js +0 -1
  298. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-9969fe0baa238786.js +0 -1
  299. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-9969fe0baa238786.js +0 -1
  300. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-9969fe0baa238786.js +0 -1
  301. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-9969fe0baa238786.js +0 -1
  302. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-9969fe0baa238786.js +0 -1
  303. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-9969fe0baa238786.js +0 -1
  304. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-9969fe0baa238786.js +0 -1
  305. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-9969fe0baa238786.js +0 -1
  306. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-9969fe0baa238786.js +0 -1
  307. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-9969fe0baa238786.js +0 -1
  308. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-9969fe0baa238786.js +0 -1
  309. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-9969fe0baa238786.js +0 -1
  310. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-9969fe0baa238786.js +0 -1
  311. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-9969fe0baa238786.js +0 -1
  312. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-9969fe0baa238786.js +0 -1
  313. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-9969fe0baa238786.js +0 -1
  314. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-9969fe0baa238786.js +0 -1
  315. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-9969fe0baa238786.js +0 -1
  316. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-9969fe0baa238786.js +0 -1
  317. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-9969fe0baa238786.js +0 -1
  318. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-9969fe0baa238786.js +0 -1
  319. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-9969fe0baa238786.js +0 -1
  320. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-9969fe0baa238786.js +0 -1
  321. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-9969fe0baa238786.js +0 -1
  322. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-9969fe0baa238786.js +0 -1
  323. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-9969fe0baa238786.js +0 -1
  324. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-9969fe0baa238786.js +0 -1
  325. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-9969fe0baa238786.js +0 -1
  326. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-9969fe0baa238786.js +0 -1
  327. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-9969fe0baa238786.js +0 -1
  328. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-9969fe0baa238786.js +0 -1
  329. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-9969fe0baa238786.js +0 -1
  330. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-9969fe0baa238786.js +0 -1
  331. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-9969fe0baa238786.js +0 -1
  332. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-9969fe0baa238786.js +0 -1
  333. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-20718f1503910291.js +0 -1
  334. package/temp/build/pi-desk/release/.next/static/chunks/app/page-18d63fd3920dfae0.js +0 -158
  335. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-9969fe0baa238786.js +0 -1
  336. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-9969fe0baa238786.js +0 -1
  337. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9969fe0baa238786.js +0 -1
  338. package/temp/build/pi-desk/release/.next/static/css/2c3b0c0ff1f49c68.css +0 -1
  339. package/temp/build/pi-desk/release/.next/static/css/c43b04c244a64fb4.css +0 -1
  340. /package/temp/build/pi-desk/release/.next/static/{6a4eIEjmpW5l8Qlgtzzzg → Yyfg-r17aYmEzlYYlIwDo}/_ssgManifest.js +0 -0
@@ -1,19 +1,12 @@
1
- import type { L4Locale } from '@common/l4_foundation/locale/l4-locale'
2
- import { L2_PROJECT_HISTORY_MESSAGES } from './l2-project-history-messages'
3
-
4
1
  export const L2_PROJECT_PREVIEW_PATH = '/project-preview'
5
2
 
6
3
  export function buildL2ProjectPreviewHref(cwd?: string | null): string {
7
4
  return cwd ? `${L2_PROJECT_PREVIEW_PATH}?cwd=${encodeURIComponent(cwd)}` : L2_PROJECT_PREVIEW_PATH
8
5
  }
9
6
 
10
- export function buildL2ProjectPreviewTitle(
11
- cwd: string | null | undefined,
12
- locale: L4Locale
13
- ): string {
14
- const directory = cwd?.trim() || null
15
- const name = directory?.replaceAll('\\', '/').split('/').filter(Boolean).at(-1) ?? directory
16
- return [name, L2_PROJECT_HISTORY_MESSAGES[locale].previewTitle, 'Pi Desk']
17
- .filter(Boolean)
18
- .join(' · ')
7
+ export function buildL2ProjectPreviewTitle(cwd: string | null | undefined): string {
8
+ const directory = cwd?.trim()
9
+ if (!directory) return 'Pi Desk'
10
+ const name = directory.replaceAll('\\', '/').split('/').filter(Boolean).at(-1) ?? directory
11
+ return name === directory ? directory : `${name} – ${directory}`
19
12
  }
@@ -0,0 +1,26 @@
1
+ import { z } from 'zod'
2
+ import {
3
+ L3PiSessionSearchMatchSchema,
4
+ L3PiSessionSearchQuerySchema
5
+ } from '@common/l3_modules/pi/l3-pi-session-search-contract'
6
+ import { L2WorkIdSchema } from './l2-work-session-contract'
7
+
8
+ export const L2WorkSessionSearchRequestSchema = L3PiSessionSearchQuerySchema.extend({
9
+ query: z.string().trim().min(1).max(120)
10
+ })
11
+
12
+ export const L2WorkSessionSearchResponseSchema = z
13
+ .object({
14
+ sessions: z.array(
15
+ z
16
+ .object({
17
+ workId: L2WorkIdSchema,
18
+ matches: z.array(L3PiSessionSearchMatchSchema).min(1).max(4)
19
+ })
20
+ .strict()
21
+ )
22
+ })
23
+ .strict()
24
+
25
+ export type L2WorkSessionSearchRequest = z.infer<typeof L2WorkSessionSearchRequestSchema>
26
+ export type L2WorkSessionSearchResponse = z.infer<typeof L2WorkSessionSearchResponseSchema>
@@ -86,7 +86,7 @@ export const L2WorkSessionTreeEntryGetResponseSchema = z
86
86
  })
87
87
  .strict()
88
88
 
89
- export const L2WorkSessionBranchActionSchema = z.enum(['tree', 'fork', 'clone'])
89
+ export const L2WorkSessionBranchActionSchema = z.enum(['tree', 'fork', 'clone', 'resend'])
90
90
 
91
91
  export const L2WorkSessionBranchRequestSchema = z.discriminatedUnion('action', [
92
92
  z
@@ -97,6 +97,14 @@ export const L2WorkSessionBranchRequestSchema = z.discriminatedUnion('action', [
97
97
  entryId: L2PiEntryIdSchema
98
98
  })
99
99
  .strict(),
100
+ z
101
+ .object({
102
+ action: z.literal('resend'),
103
+ workId: L2WorkIdSchema,
104
+ sessionId: L2PiSessionIdSchema,
105
+ entryId: L2PiEntryIdSchema
106
+ })
107
+ .strict(),
100
108
  z
101
109
  .object({
102
110
  action: z.literal('fork'),
@@ -4,6 +4,12 @@ export const L2_WORKBENCH_LOCALE_MESSAGES = {
4
4
  en: {
5
5
  ...L2_TERMINAL_LOCALE_MESSAGES.en,
6
6
  toolsAndContext: 'Tools and context',
7
+ searchWorkSessions: 'Search work sessions',
8
+ clearSessionSearch: 'Clear search',
9
+ searchingSessions: 'Searching…',
10
+ noSessionSearchMatches: 'No matching work sessions',
11
+ sessionSearchFailed: 'Could not search work sessions',
12
+ retrySessionSearch: 'Retry',
7
13
  sessionContextDescription: 'Tools, system instructions and services for this session',
8
14
  mcpSession: 'Session MCP',
9
15
  modelAutomaticRouting: 'Automatic routing',
@@ -453,6 +459,12 @@ export const L2_WORKBENCH_LOCALE_MESSAGES = {
453
459
  'zh-CN': {
454
460
  ...L2_TERMINAL_LOCALE_MESSAGES['zh-CN'],
455
461
  toolsAndContext: '工具与上下文',
462
+ searchWorkSessions: '搜索工作会话',
463
+ clearSessionSearch: '清空搜索',
464
+ searchingSessions: '正在搜索…',
465
+ noSessionSearchMatches: '没有匹配的工作会话',
466
+ sessionSearchFailed: '搜索工作会话失败',
467
+ retrySessionSearch: '重试',
456
468
  sessionContextDescription: '当前会话的工具、系统提示词和服务',
457
469
  mcpSession: '会话 MCP',
458
470
  modelAutomaticRouting: '自动路由',
@@ -8,6 +8,7 @@ export const L2_WORKBENCH_PICKER_MESSAGES = {
8
8
  scopeUserMatches: 'User messages {{count}}',
9
9
  scopeAssistantMatches: 'AI replies {{count}}',
10
10
  loadUserFailed: 'Could not load user messages',
11
+ loadHistoryFailed: 'Could not load past sessions',
11
12
  ignoredRestoreTitle: 'Restore ignored folder',
12
13
  browseOtherTitle: 'Choose a project folder',
13
14
  replaceTitle: 'Replace work session',
@@ -109,6 +110,7 @@ export const L2_WORKBENCH_PICKER_MESSAGES = {
109
110
  kindSession: 'Session',
110
111
  kindLabel: 'Label',
111
112
  treeIntent: 'Switch the current session branch',
113
+ resendIntent: 'Resend this message in a new branch',
112
114
  forkIntent: 'Start a session from a user message',
113
115
  cloneIntent: 'Clone the current session',
114
116
  runningTitle: 'The current session is running',
@@ -124,7 +126,7 @@ export const L2_WORKBENCH_PICKER_MESSAGES = {
124
126
  closeBranchPicker: 'Close session branch picker',
125
127
  branchSearch: 'Search session branches',
126
128
  branchSearchPlaceholder: 'Search messages, tools or labels',
127
- branchFilter: 'Filter session tree, current: {{filter}}',
129
+ branchFilters: 'Filter',
128
130
  loadingEntry: 'Loading full content…',
129
131
  entryEmpty: 'No text available for this entry',
130
132
  entryTruncated: 'Long content has been truncated.',
@@ -151,6 +153,7 @@ export const L2_WORKBENCH_PICKER_MESSAGES = {
151
153
  scopeUserMatches: '用户消息 {{count}}',
152
154
  scopeAssistantMatches: 'AI 回复 {{count}}',
153
155
  loadUserFailed: '加载用户消息失败',
156
+ loadHistoryFailed: '加载历史会话失败',
154
157
  ignoredRestoreTitle: '恢复忽略目录',
155
158
  browseOtherTitle: '选择项目目录',
156
159
  replaceTitle: '替换工作会话',
@@ -249,6 +252,7 @@ export const L2_WORKBENCH_PICKER_MESSAGES = {
249
252
  kindSession: '会话',
250
253
  kindLabel: '标签',
251
254
  treeIntent: '切换当前会话分支',
255
+ resendIntent: '从这条消息重新发送',
252
256
  forkIntent: '从用户消息新开会话',
253
257
  cloneIntent: '克隆当前会话',
254
258
  runningTitle: '当前工作会话正在运行',
@@ -263,7 +267,7 @@ export const L2_WORKBENCH_PICKER_MESSAGES = {
263
267
  closeBranchPicker: '关闭会话分支选择器',
264
268
  branchSearch: '搜索会话分支',
265
269
  branchSearchPlaceholder: '搜索消息、工具或标签',
266
- branchFilter: '过滤会话树,当前:{{filter}}',
270
+ branchFilters: '筛选',
267
271
  loadingEntry: '正在读取完整内容…',
268
272
  entryEmpty: '该节点没有可展示的文字内容',
269
273
  entryTruncated: '内容较长,已截断显示。',
@@ -27,6 +27,7 @@ export const L3_CONVERSATION_LOCALE_MESSAGES = {
27
27
  messageCopyFailed: 'Could not copy the message. Please copy it manually.',
28
28
  copied: 'Copied',
29
29
  copyMessage: 'Copy message',
30
+ resendMessage: 'Resend',
30
31
  usage: 'Input {{input}} / Output {{output}} / Cached input {{cached}} / {{cost}}',
31
32
  chatImage: 'Chat image {{count}}',
32
33
  imageLoading: 'Loading image…',
@@ -174,6 +175,7 @@ export const L3_CONVERSATION_LOCALE_MESSAGES = {
174
175
  messageCopyFailed: '复制消息失败,请手动复制。',
175
176
  copied: '已复制',
176
177
  copyMessage: '复制消息',
178
+ resendMessage: '重发',
177
179
  usage: '输入 {{input}} / 输出 {{output}} / 输入缓存 {{cached}} / {{cost}}',
178
180
  chatImage: '聊天图片 {{count}}',
179
181
  imageLoading: '加载图片…',
@@ -0,0 +1,26 @@
1
+ import { z } from 'zod'
2
+ import { L3PiEntryIdSchema } from './l3-pi-contract'
3
+ import { L4TimestampMsSchema } from '@common/l4_foundation/l4-timestamp-contract'
4
+
5
+ export const L3PiSessionSearchScopeSchema = z.enum(['title', 'user', 'assistant', 'sessionId'])
6
+
7
+ export const L3PiSessionSearchMatchSchema = z
8
+ .object({
9
+ scope: L3PiSessionSearchScopeSchema,
10
+ count: z.number().int().positive(),
11
+ entryId: L3PiEntryIdSchema.nullable(),
12
+ timestampMs: L4TimestampMsSchema.nullable(),
13
+ preview: z.string().min(1).max(160)
14
+ })
15
+ .strict()
16
+
17
+ export const L3PiSessionSearchQuerySchema = z
18
+ .object({
19
+ query: z.string().trim().max(120).default(''),
20
+ searchIn: z.array(L3PiSessionSearchScopeSchema).min(1).max(4).default(['title', 'user'])
21
+ })
22
+ .strict()
23
+
24
+ export type L3PiSessionSearchScope = z.infer<typeof L3PiSessionSearchScopeSchema>
25
+ export type L3PiSessionSearchMatch = z.infer<typeof L3PiSessionSearchMatchSchema>
26
+ export type L3PiSessionSearchQuery = z.infer<typeof L3PiSessionSearchQuerySchema>
@@ -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(data, input.data.action === 'tree' ? 200 : 201)
29
+ return createL4ApiSuccessResponse(
30
+ data,
31
+ input.data.action === 'tree' || input.data.action === 'resend' ? 200 : 201
32
+ )
37
33
  } catch (error) {
38
- if (error instanceof WorkSessionNotFoundError) {
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 (error instanceof WorkSessionBranchInvalidError) {
43
+ if (
44
+ error instanceof Error &&
45
+ error.name === 'WorkSessionBranchInvalidError' &&
46
+ 'kind' in error
47
+ ) {
47
48
  return createL4ApiErrorResponse(400, error.message, {
48
- key: error.kind === 'fork-target' ? 'errors:branchForkUserOnly' : 'errors:branchCloneEmpty'
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
- this.recordsByWorkId.set(workSession.workId, this.buildRecord(workSession))
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
- result = await source.branch(input.entryId)
690
- if (result.changed) await this.chat.refreshWorkSession(source)
691
- else this.chat.resumeWorkSession(source.workId)
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 { L4PiWorkSessionRuntime } from '@server/l4_foundation/pi/l4-pi-work-session-runtime'
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 interface WorkSessionSendInput {
14
- mode: 'auto' | 'follow_up'
15
- text: string
16
- images: WorkSessionInputImage[]
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 = await session.navigateTree(entryId, { summarize: false })
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()