@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.
Files changed (362) hide show
  1. package/docs/plugins.md +2 -2
  2. package/package.json +1 -1
  3. package/src/app/api/work-sessions/search/route.ts +1 -0
  4. package/src/app/project-preview/page.tsx +1 -3
  5. package/src/client/l1_entry/pages/l1-error-page.tsx +1 -1
  6. package/src/client/l1_entry/providers/l1-app-providers.tsx +2 -0
  7. package/src/client/l2_biz/auth/l2-login.module.css +1 -1
  8. package/src/client/l2_biz/plugin-host/l2-plugin-composer-panel.tsx +1 -1
  9. package/src/client/l2_biz/plugin-host/l2-plugin-contribution-host.tsx +1 -1
  10. package/src/client/l2_biz/plugin-host/l2-plugin-session-header-layout.ts +6 -3
  11. package/src/client/l2_biz/plugin-host/l2-plugin-session-header.tsx +75 -18
  12. package/src/client/l2_biz/project-preview/hooks/l2-use-project-preview.ts +1 -14
  13. package/src/client/l2_biz/project-preview/l2-project-preview-dialog.tsx +2 -3
  14. package/src/client/l2_biz/project-preview/l2-project-preview-page.tsx +1 -2
  15. package/src/client/l2_biz/project-preview/l2-project-preview.tsx +1 -4
  16. package/src/client/l2_biz/project-preview/views/l2-project-branch-select.tsx +42 -3
  17. package/src/client/l2_biz/settings/l2-settings.tsx +1 -1
  18. package/src/client/l2_biz/settings/l2-skills-settings.tsx +1 -1
  19. package/src/client/l2_biz/task-center/l2-task-center.tsx +1 -1
  20. package/src/client/l2_biz/workbench/file-workspace/l2-plugin-standalone-file-preview.tsx +1 -1
  21. package/src/client/l2_biz/workbench/file-workspace/l2-work-session-file-preview.tsx +1 -1
  22. package/src/client/l2_biz/workbench/git-workspace/l2-git-workspace-runtime.ts +11 -10
  23. package/src/client/l2_biz/workbench/hooks/l2-work-session-search.ts +52 -0
  24. package/src/client/l2_biz/workbench/hooks/l2-workbench-branch-picker.ts +42 -7
  25. package/src/client/l2_biz/workbench/hooks/l2-workbench-session-history.ts +143 -131
  26. package/src/client/l2_biz/workbench/hooks/l2-workbench-session-search.ts +97 -0
  27. package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +8 -0
  28. package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +129 -10
  29. package/src/client/l2_biz/workbench/l2-workbench-biz.ts +20 -2
  30. package/src/client/l2_biz/workbench/l2-workbench-branch-filter-preferences.ts +34 -0
  31. package/src/client/l2_biz/workbench/l2-workbench-branch-picker.tsx +34 -71
  32. package/src/client/l2_biz/workbench/l2-workbench-chat-input-runtime.ts +38 -1
  33. package/src/client/l2_biz/workbench/l2-workbench-chat-view.tsx +11 -1
  34. package/src/client/l2_biz/workbench/l2-workbench-picker-dialog.tsx +55 -215
  35. package/src/client/l2_biz/workbench/l2-workbench.tsx +21 -39
  36. package/src/client/l2_biz/workbench/views/l2-workbench-session-search.tsx +123 -0
  37. package/src/client/l3_modules/conversation/l3-conversation-messages.tsx +43 -4
  38. package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +1 -1
  39. package/src/client/l3_modules/project-files/l3-project-document-git.ts +13 -29
  40. package/src/client/l3_modules/project-files/l3-project-document-view.tsx +1 -4
  41. package/src/client/l3_modules/project-files/l3-project-file-browser.module.css +14 -18
  42. package/src/client/l3_modules/project-files/l3-project-file-browser.tsx +52 -95
  43. package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +52 -21
  44. package/src/client/l3_modules/project-files/l3-project-file-tabs.tsx +41 -62
  45. package/src/client/l3_modules/project-files/l3-project-git-runtime.ts +5 -4
  46. package/src/client/l3_modules/project-files/l3-use-project-refresh.ts +36 -0
  47. package/src/client/l3_modules/project-files/views/l3-project-search-results.tsx +2 -2
  48. package/src/client/l3_modules/project-files/views/l3-project-tree-folder.tsx +86 -0
  49. package/src/client/l4_foundation/desktop-window/l4-desktop-titlebar.tsx +188 -0
  50. package/src/client/l4_foundation/desktop-window/l4-desktop-window.css +107 -0
  51. package/src/client/l4_foundation/desktop-window/l4-desktop-window.ts +20 -0
  52. package/src/client/l4_foundation/ui/file-icons/README.md +1 -1
  53. package/src/client/l4_foundation/ui/file-icons/l4-file-icon.tsx +49 -2
  54. package/src/client/l4_foundation/ui/l4-app-dialog.tsx +2 -2
  55. package/src/common/l2_biz/pi-session/l2-pi-session-contract.ts +11 -24
  56. package/src/common/l2_biz/project-preview/l2-project-preview-navigation.ts +5 -12
  57. package/src/common/l2_biz/work-session/l2-work-session-search-contract.ts +26 -0
  58. package/src/common/l2_biz/work-session/l2-work-session-tree-contract.ts +9 -1
  59. package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +12 -0
  60. package/src/common/l2_biz/workbench/l2-workbench-picker-messages.ts +6 -2
  61. package/src/common/l3_modules/conversation/l3-conversation-locale-messages.ts +2 -0
  62. package/src/common/l3_modules/pi/l3-pi-session-search-contract.ts +26 -0
  63. package/src/common/l4_foundation/locale/l4-host-error-messages.ts +2 -0
  64. package/src/server/l1_entry/api/l1-work-session-branch-route.ts +21 -15
  65. package/src/server/l1_entry/api/l1-work-session-search-route.ts +38 -0
  66. package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +4 -2
  67. package/src/server/l2_biz/work-session/l2-work-session-manage.ts +46 -10
  68. package/src/server/l3_modules/work-session/l3-work-session.ts +11 -6
  69. package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +35 -2
  70. package/src/server/l4_foundation/pi/l4-pi-session-history-catalog.ts +62 -113
  71. package/src/server/l4_foundation/pi/l4-pi-session-search.ts +166 -0
  72. package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +66 -5
  73. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  74. package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +1 -0
  75. package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
  76. package/temp/build/pi-desk/release/.next/required-server-files.js +2 -2
  77. package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
  78. package/temp/build/pi-desk/release/.next/routes-manifest.json +6 -0
  79. package/temp/build/pi-desk/release/.next/server/app/_global-error/page.js +2 -2
  80. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  81. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  82. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +3 -3
  83. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
  84. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +3 -3
  85. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  86. package/temp/build/pi-desk/release/.next/server/app/_not-found/page.js +1 -1
  87. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  88. package/temp/build/pi-desk/release/.next/server/app/api/auth/login/route.js +2 -2
  89. package/temp/build/pi-desk/release/.next/server/app/api/auth/logout/route.js +1 -1
  90. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/get/route.js +1 -1
  91. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/replace/route.js +1 -1
  92. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/get/route.js +1 -1
  93. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/replace/route.js +1 -1
  94. package/temp/build/pi-desk/release/.next/server/app/api/chat/context/get/route.js +1 -1
  95. package/temp/build/pi-desk/release/.next/server/app/api/chat/images/get/route.js +1 -1
  96. package/temp/build/pi-desk/release/.next/server/app/api/chat/messages/get/route.js +1 -1
  97. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  98. package/temp/build/pi-desk/release/.next/server/app/api/mcp-check/get/route.js +1 -1
  99. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/del/route.js +1 -1
  100. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/get/route.js +1 -1
  101. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/replace/route.js +1 -1
  102. package/temp/build/pi-desk/release/.next/server/app/api/model-catalog/list/route.js +1 -1
  103. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/get/route.js +1 -1
  104. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/preview/route.js +1 -1
  105. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/replace/route.js +1 -1
  106. package/temp/build/pi-desk/release/.next/server/app/api/pi/directories/list/route.js +1 -1
  107. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-entries/list/route.js +1 -1
  108. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/list/route.js +1 -1
  109. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/replace/route.js +1 -1
  110. package/temp/build/pi-desk/release/.next/server/app/api/pi/models/list/route.js +1 -1
  111. package/temp/build/pi-desk/release/.next/server/app/api/pi/session-user-messages/list/route.js +1 -1
  112. package/temp/build/pi-desk/release/.next/server/app/api/pi/sessions/list/route.js +1 -1
  113. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/get/route.js +1 -1
  114. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/search/route.js +1 -1
  115. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-get/route.js +1 -1
  116. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-replace/route.js +1 -1
  117. package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
  118. package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
  119. package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
  120. package/temp/build/pi-desk/release/.next/server/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route.js +1 -1
  121. package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
  122. package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
  123. package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
  124. package/temp/build/pi-desk/release/.next/server/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route.js +1 -1
  125. package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
  126. package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
  127. package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
  128. package/temp/build/pi-desk/release/.next/server/app/api/project-files/get/route.js +2 -2
  129. package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +1 -1
  130. package/temp/build/pi-desk/release/.next/server/app/api/project-files/reveal/route.js +1 -1
  131. package/temp/build/pi-desk/release/.next/server/app/api/project-files/search/route.js +1 -1
  132. package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +2 -2
  133. package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +2 -2
  134. package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +1 -1
  135. package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +2 -2
  136. package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +1 -1
  137. package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +2 -2
  138. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/get/route.js +1 -1
  139. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/replace/route.js +1 -1
  140. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/get/route.js +1 -1
  141. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/list/route.js +1 -1
  142. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/replace/route.js +1 -1
  143. package/temp/build/pi-desk/release/.next/server/app/api/skills/list/route.js +1 -1
  144. package/temp/build/pi-desk/release/.next/server/app/api/task-center/images/get/route.js +1 -1
  145. package/temp/build/pi-desk/release/.next/server/app/api/task-center/messages/get/route.js +1 -1
  146. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/add/route.js +1 -1
  147. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/replace/route.js +1 -1
  148. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree/get/route.js +1 -1
  149. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree-entry/get/route.js +1 -1
  150. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/add/route.js +1 -1
  151. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/branch/route.js +1 -1
  152. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/del/route.js +1 -1
  153. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route.js +1 -1
  154. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/replace/route.js +1 -1
  155. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/search/route.js +1 -0
  156. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/search/route_client-reference-manifest.js +1 -0
  157. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/sort/route.js +1 -1
  158. package/temp/build/pi-desk/release/.next/server/app/favicon.ico/route.js +1 -1
  159. package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
  160. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  161. package/temp/build/pi-desk/release/.next/server/app/page.js +138 -138
  162. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  163. package/temp/build/pi-desk/release/.next/server/app/project-preview/page.js +1 -1
  164. package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -1
  165. package/temp/build/pi-desk/release/.next/server/app-paths-manifest.json +1 -0
  166. package/temp/build/pi-desk/release/.next/server/chunks/23054.js +2 -2
  167. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -8
  168. package/temp/build/pi-desk/release/.next/server/chunks/27344.js +3 -3
  169. package/temp/build/pi-desk/release/.next/server/chunks/3108.js +3 -3
  170. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +3 -3
  171. package/temp/build/pi-desk/release/.next/server/chunks/41856.js +1 -0
  172. package/temp/build/pi-desk/release/.next/server/chunks/62900.js +235 -0
  173. package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
  174. package/temp/build/pi-desk/release/.next/server/chunks/81363.js +1 -1
  175. package/temp/build/pi-desk/release/.next/server/chunks/81912.js +3 -0
  176. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +2 -2
  177. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  178. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  179. package/temp/build/pi-desk/release/.next/static/ErYBfYXAir5b-6rlacGvL/_buildManifest.js +1 -0
  180. package/temp/build/pi-desk/release/.next/static/chunks/10043-9d6c3735418ccaf9.js +238 -0
  181. package/temp/build/pi-desk/release/.next/static/chunks/11937-ac71fb0f7cef482a.js +1 -0
  182. package/temp/build/pi-desk/release/.next/static/chunks/30669-ffa76d39e0e25194.js +1 -0
  183. package/temp/build/pi-desk/release/.next/static/chunks/36643-f60e98278740073c.js +3 -0
  184. package/temp/build/pi-desk/release/.next/static/chunks/65232-f5b71cec787a30ec.js +15 -0
  185. package/temp/build/pi-desk/release/.next/static/chunks/{51474-8dc714cb76b2e60a.js → 65350-23bb961d87addf14.js} +3 -3
  186. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-295cb63da5f7262f.js +1 -0
  187. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-295cb63da5f7262f.js +1 -0
  188. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-295cb63da5f7262f.js +1 -0
  189. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-295cb63da5f7262f.js +1 -0
  190. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-295cb63da5f7262f.js +1 -0
  191. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-295cb63da5f7262f.js +1 -0
  192. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-295cb63da5f7262f.js +1 -0
  193. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-295cb63da5f7262f.js +1 -0
  194. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-295cb63da5f7262f.js +1 -0
  195. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-295cb63da5f7262f.js +1 -0
  196. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-295cb63da5f7262f.js +1 -0
  197. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-295cb63da5f7262f.js +1 -0
  198. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-295cb63da5f7262f.js +1 -0
  199. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-295cb63da5f7262f.js +1 -0
  200. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-295cb63da5f7262f.js +1 -0
  201. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-295cb63da5f7262f.js +1 -0
  202. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-295cb63da5f7262f.js +1 -0
  203. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-295cb63da5f7262f.js +1 -0
  204. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-295cb63da5f7262f.js +1 -0
  205. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-295cb63da5f7262f.js +1 -0
  206. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-295cb63da5f7262f.js +1 -0
  207. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-295cb63da5f7262f.js +1 -0
  208. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-295cb63da5f7262f.js +1 -0
  209. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-295cb63da5f7262f.js +1 -0
  210. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-295cb63da5f7262f.js +1 -0
  211. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-295cb63da5f7262f.js +1 -0
  212. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-295cb63da5f7262f.js +1 -0
  213. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-295cb63da5f7262f.js +1 -0
  214. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-295cb63da5f7262f.js +1 -0
  215. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-295cb63da5f7262f.js +1 -0
  216. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-295cb63da5f7262f.js +1 -0
  217. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-295cb63da5f7262f.js +1 -0
  218. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-295cb63da5f7262f.js +1 -0
  219. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-295cb63da5f7262f.js +1 -0
  220. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-295cb63da5f7262f.js +1 -0
  221. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-295cb63da5f7262f.js +1 -0
  222. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-295cb63da5f7262f.js +1 -0
  223. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-295cb63da5f7262f.js +1 -0
  224. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-295cb63da5f7262f.js +1 -0
  225. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-295cb63da5f7262f.js +1 -0
  226. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-295cb63da5f7262f.js +1 -0
  227. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-295cb63da5f7262f.js +1 -0
  228. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-295cb63da5f7262f.js +1 -0
  229. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-295cb63da5f7262f.js +1 -0
  230. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-295cb63da5f7262f.js +1 -0
  231. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-295cb63da5f7262f.js +1 -0
  232. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-295cb63da5f7262f.js +1 -0
  233. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-295cb63da5f7262f.js +1 -0
  234. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-295cb63da5f7262f.js +1 -0
  235. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-295cb63da5f7262f.js +1 -0
  236. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-295cb63da5f7262f.js +1 -0
  237. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-295cb63da5f7262f.js +1 -0
  238. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-295cb63da5f7262f.js +1 -0
  239. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-295cb63da5f7262f.js +1 -0
  240. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-295cb63da5f7262f.js +1 -0
  241. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-295cb63da5f7262f.js +1 -0
  242. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-295cb63da5f7262f.js +1 -0
  243. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-295cb63da5f7262f.js +1 -0
  244. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-295cb63da5f7262f.js +1 -0
  245. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-295cb63da5f7262f.js +1 -0
  246. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-295cb63da5f7262f.js +1 -0
  247. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-295cb63da5f7262f.js +1 -0
  248. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-295cb63da5f7262f.js +1 -0
  249. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-295cb63da5f7262f.js +1 -0
  250. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-295cb63da5f7262f.js +1 -0
  251. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-295cb63da5f7262f.js +1 -0
  252. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-295cb63da5f7262f.js +1 -0
  253. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-295cb63da5f7262f.js +1 -0
  254. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-295cb63da5f7262f.js +1 -0
  255. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/search/route-295cb63da5f7262f.js +1 -0
  256. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-295cb63da5f7262f.js +1 -0
  257. package/temp/build/pi-desk/release/.next/static/chunks/app/error-1ab62762c5f4144f.js +1 -0
  258. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-ca5ef5994165eb2e.js +1 -0
  259. package/temp/build/pi-desk/release/.next/static/chunks/app/login/{page-0d3d4827802108e5.js → page-0df9df996aa68060.js} +1 -1
  260. package/temp/build/pi-desk/release/.next/static/chunks/app/not-found-b8b9b7ef5ccb7601.js +1 -0
  261. package/temp/build/pi-desk/release/.next/static/chunks/app/page-978906de76a8dcfe.js +158 -0
  262. package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/{page-038b6c14e03ed878.js → page-aaa845016a934245.js} +1 -1
  263. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-295cb63da5f7262f.js +1 -0
  264. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-295cb63da5f7262f.js +1 -0
  265. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-295cb63da5f7262f.js +1 -0
  266. package/temp/build/pi-desk/release/.next/static/chunks/{webpack-c0b805df46fcf8b3.js → webpack-a84310d111797bef.js} +1 -1
  267. package/temp/build/pi-desk/release/.next/static/css/053a8d82c09326cd.css +1 -0
  268. package/temp/build/pi-desk/release/.next/static/css/1cc92eec583aa639.css +1 -0
  269. package/temp/build/pi-desk/release/.next/static/css/{1e780a4936aa6ba3.css → 2bb393927ba8f71d.css} +1 -1
  270. package/temp/build/pi-desk/release/.next/static/css/3a07dcc86ffdf88c.css +1 -0
  271. package/temp/build/pi-desk/release/.next/static/css/3c59ac068ae404da.css +1 -0
  272. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  273. package/temp/build/pi-desk/release/.next/server/chunks/35348.js +0 -3
  274. package/temp/build/pi-desk/release/.next/server/chunks/56830.js +0 -235
  275. package/temp/build/pi-desk/release/.next/server/chunks/80780.js +0 -1
  276. package/temp/build/pi-desk/release/.next/static/bj2dB_Z10YB_CqK_VNhDx/_buildManifest.js +0 -1
  277. package/temp/build/pi-desk/release/.next/static/chunks/11937-1d0a9822f2c7995b.js +0 -1
  278. package/temp/build/pi-desk/release/.next/static/chunks/14197-3d3ddd426ac06c9c.js +0 -3
  279. package/temp/build/pi-desk/release/.next/static/chunks/37313-d5970e2d0c270d22.js +0 -238
  280. package/temp/build/pi-desk/release/.next/static/chunks/65232-ef4e5a4174f62faf.js +0 -15
  281. package/temp/build/pi-desk/release/.next/static/chunks/79267-7d21d7cdbd7cfca1.js +0 -1
  282. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-9969fe0baa238786.js +0 -1
  283. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-9969fe0baa238786.js +0 -1
  284. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-9969fe0baa238786.js +0 -1
  285. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-9969fe0baa238786.js +0 -1
  286. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-9969fe0baa238786.js +0 -1
  287. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-9969fe0baa238786.js +0 -1
  288. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-9969fe0baa238786.js +0 -1
  289. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-9969fe0baa238786.js +0 -1
  290. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-9969fe0baa238786.js +0 -1
  291. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-9969fe0baa238786.js +0 -1
  292. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-9969fe0baa238786.js +0 -1
  293. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-9969fe0baa238786.js +0 -1
  294. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-9969fe0baa238786.js +0 -1
  295. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-9969fe0baa238786.js +0 -1
  296. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-9969fe0baa238786.js +0 -1
  297. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-9969fe0baa238786.js +0 -1
  298. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-9969fe0baa238786.js +0 -1
  299. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-9969fe0baa238786.js +0 -1
  300. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-9969fe0baa238786.js +0 -1
  301. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-9969fe0baa238786.js +0 -1
  302. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-9969fe0baa238786.js +0 -1
  303. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-9969fe0baa238786.js +0 -1
  304. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-9969fe0baa238786.js +0 -1
  305. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-9969fe0baa238786.js +0 -1
  306. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-9969fe0baa238786.js +0 -1
  307. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-9969fe0baa238786.js +0 -1
  308. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-9969fe0baa238786.js +0 -1
  309. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-9969fe0baa238786.js +0 -1
  310. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-9969fe0baa238786.js +0 -1
  311. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-9969fe0baa238786.js +0 -1
  312. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-9969fe0baa238786.js +0 -1
  313. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-9969fe0baa238786.js +0 -1
  314. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-9969fe0baa238786.js +0 -1
  315. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-9969fe0baa238786.js +0 -1
  316. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-9969fe0baa238786.js +0 -1
  317. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-9969fe0baa238786.js +0 -1
  318. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-9969fe0baa238786.js +0 -1
  319. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-9969fe0baa238786.js +0 -1
  320. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-9969fe0baa238786.js +0 -1
  321. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-9969fe0baa238786.js +0 -1
  322. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-9969fe0baa238786.js +0 -1
  323. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-9969fe0baa238786.js +0 -1
  324. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-9969fe0baa238786.js +0 -1
  325. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-9969fe0baa238786.js +0 -1
  326. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-9969fe0baa238786.js +0 -1
  327. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-9969fe0baa238786.js +0 -1
  328. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-9969fe0baa238786.js +0 -1
  329. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-9969fe0baa238786.js +0 -1
  330. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-9969fe0baa238786.js +0 -1
  331. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-9969fe0baa238786.js +0 -1
  332. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-9969fe0baa238786.js +0 -1
  333. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-9969fe0baa238786.js +0 -1
  334. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-9969fe0baa238786.js +0 -1
  335. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-9969fe0baa238786.js +0 -1
  336. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-9969fe0baa238786.js +0 -1
  337. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-9969fe0baa238786.js +0 -1
  338. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-9969fe0baa238786.js +0 -1
  339. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-9969fe0baa238786.js +0 -1
  340. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-9969fe0baa238786.js +0 -1
  341. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-9969fe0baa238786.js +0 -1
  342. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-9969fe0baa238786.js +0 -1
  343. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-9969fe0baa238786.js +0 -1
  344. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-9969fe0baa238786.js +0 -1
  345. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-9969fe0baa238786.js +0 -1
  346. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-9969fe0baa238786.js +0 -1
  347. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-9969fe0baa238786.js +0 -1
  348. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-9969fe0baa238786.js +0 -1
  349. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-9969fe0baa238786.js +0 -1
  350. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-9969fe0baa238786.js +0 -1
  351. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-9969fe0baa238786.js +0 -1
  352. package/temp/build/pi-desk/release/.next/static/chunks/app/error-216b14b5da089ed3.js +0 -1
  353. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-20718f1503910291.js +0 -1
  354. package/temp/build/pi-desk/release/.next/static/chunks/app/not-found-720cdf6a606b821a.js +0 -1
  355. package/temp/build/pi-desk/release/.next/static/chunks/app/page-ce2ebf7d8ea7a330.js +0 -158
  356. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-9969fe0baa238786.js +0 -1
  357. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-9969fe0baa238786.js +0 -1
  358. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9969fe0baa238786.js +0 -1
  359. package/temp/build/pi-desk/release/.next/static/css/2bdcf40eca12b794.css +0 -1
  360. package/temp/build/pi-desk/release/.next/static/css/2c3b0c0ff1f49c68.css +0 -1
  361. package/temp/build/pi-desk/release/.next/static/css/c43b04c244a64fb4.css +0 -1
  362. /package/temp/build/pi-desk/release/.next/static/{bj2dB_Z10YB_CqK_VNhDx → ErYBfYXAir5b-6rlacGvL}/_ssgManifest.js +0 -0
@@ -23,7 +23,10 @@ interface L2WorkbenchBranchPickerSource {
23
23
  }
24
24
 
25
25
  export type L2WorkbenchBranchIntent =
26
- { action: 'tree'; entryId: string } | { action: 'fork'; entryId: string } | { action: 'clone' }
26
+ | { action: 'tree'; entryId: string }
27
+ | { action: 'fork'; entryId: string }
28
+ | { action: 'resend'; entryId: string }
29
+ | { action: 'clone' }
27
30
 
28
31
  interface L2WorkbenchRunningConfirmation {
29
32
  intent: L2WorkbenchBranchIntent
@@ -57,6 +60,7 @@ interface UseL2WorkbenchBranchPickerResult {
57
60
  selectEntry: (entryId: string) => void
58
61
  requestAction: (entryId: string, action: 'tree' | 'fork') => void
59
62
  clone: (workId: string) => void
63
+ resend: (source: L2WorkbenchBranchPickerSource, entryId: string) => void
60
64
  confirmRunning: () => void
61
65
  cancelRunning: () => void
62
66
  pendingWorkId: string | null
@@ -92,6 +96,8 @@ function branchRequest(
92
96
  return { ...binding, action: 'tree', entryId: intent.entryId }
93
97
  case 'fork':
94
98
  return { ...binding, action: 'fork', entryId: intent.entryId }
99
+ case 'resend':
100
+ return { ...binding, action: 'resend', entryId: intent.entryId }
95
101
  case 'clone':
96
102
  return { ...binding, action: 'clone' }
97
103
  }
@@ -123,6 +129,7 @@ export function useL2WorkbenchBranchPicker({
123
129
  const detailAbortControllerRef = useRef<AbortController | null>(null)
124
130
  const detailCacheRef = useRef(new Map<string, L2WorkSessionTreeEntryGetResponse>())
125
131
  const operationStartRef = useRef<string | null>(null)
132
+ const executingRef = useRef(false)
126
133
 
127
134
  const resetPicker = useCallback((): void => {
128
135
  treeRequestIdRef.current += 1
@@ -270,12 +277,18 @@ export function useL2WorkbenchBranchPicker({
270
277
  operationSource: L2WorkbenchBranchPickerSource,
271
278
  intent: L2WorkbenchBranchIntent
272
279
  ): Promise<void> => {
273
- if (disabled) return
280
+ if (disabled || executingRef.current) return
281
+ executingRef.current = true
282
+ let releaseDraft: (() => void) | undefined
274
283
  const preservedTreeText =
275
284
  intent.action === 'tree' ? chatInputRuntime.getState(operationSource).text : null
276
285
  setOperation({ source: operationSource, intent, phase: 'executing' })
277
286
  setError(null)
278
287
  try {
288
+ if (intent.action === 'resend') {
289
+ await chatInputRuntime.loadSource(operationSource)
290
+ releaseDraft = chatInputRuntime.preserveDraftOnBranch(operationSource)
291
+ }
279
292
  const response = await workbenchBiz.branchWorkSession(
280
293
  branchRequest(operationSource, intent)
281
294
  )
@@ -290,7 +303,9 @@ export function useL2WorkbenchBranchPicker({
290
303
  if (!target) throw new Error(l2WorkbenchText('branchTargetMissing'))
291
304
 
292
305
  const targetSource = sourceFor(target)
293
- if (intent.action === 'tree') {
306
+ if (intent.action === 'resend') {
307
+ focusWorkSession(target.workId)
308
+ } else if (intent.action === 'tree') {
294
309
  focusWorkSession(target.workId)
295
310
  await chatInputRuntime.loadSource(targetSource)
296
311
  chatInputRuntime.setText(
@@ -312,6 +327,9 @@ export function useL2WorkbenchBranchPicker({
312
327
  operationStartRef.current = null
313
328
  setConfirmation((current) => (current ? { ...current, waiting: false } : null))
314
329
  reportOperationError(errorMessage(cause, l2WorkbenchText('branchOperationFailed')))
330
+ } finally {
331
+ releaseDraft?.()
332
+ executingRef.current = false
315
333
  }
316
334
  },
317
335
  [
@@ -347,7 +365,7 @@ export function useL2WorkbenchBranchPicker({
347
365
 
348
366
  const requestIntent = useCallback(
349
367
  (operationSource: L2WorkbenchBranchPickerSource, intent: L2WorkbenchBranchIntent): void => {
350
- if (disabled || operation) return
368
+ if (disabled || operation || confirmation || executingRef.current) return
351
369
  operationStartRef.current = null
352
370
  const current = workSessions.find(
353
371
  (workSession) => workSession.workId === operationSource.workId
@@ -374,7 +392,16 @@ export function useL2WorkbenchBranchPicker({
374
392
  setSource(operationSource)
375
393
  setError(null)
376
394
  },
377
- [disabled, execute, mobile, operation, reportOperationError, startAfterRunning, workSessions]
395
+ [
396
+ confirmation,
397
+ disabled,
398
+ execute,
399
+ mobile,
400
+ operation,
401
+ reportOperationError,
402
+ startAfterRunning,
403
+ workSessions
404
+ ]
378
405
  )
379
406
 
380
407
  const requestAction = useCallback(
@@ -385,6 +412,13 @@ export function useL2WorkbenchBranchPicker({
385
412
  [requestIntent, source]
386
413
  )
387
414
 
415
+ const resend = useCallback(
416
+ (messageSource: L2WorkbenchBranchPickerSource, entryId: string): void => {
417
+ requestIntent(messageSource, { action: 'resend', entryId })
418
+ },
419
+ [requestIntent]
420
+ )
421
+
388
422
  const clone = useCallback(
389
423
  (workId: string): void => {
390
424
  const current = workSessions.find((workSession) => workSession.workId === workId)
@@ -422,9 +456,9 @@ export function useL2WorkbenchBranchPicker({
422
456
 
423
457
  const cancelRunning = useCallback((): void => {
424
458
  if (confirmation?.waiting || operation) return
425
- const cloneOnly = confirmation?.intent.action === 'clone' && tree === null
459
+ const confirmationOnly = tree === null
426
460
  setConfirmation(null)
427
- if (cloneOnly) resetPicker()
461
+ if (confirmationOnly) resetPicker()
428
462
  }, [confirmation, operation, resetPicker, tree])
429
463
 
430
464
  useEffect(() => {
@@ -531,6 +565,7 @@ export function useL2WorkbenchBranchPicker({
531
565
  selectEntry,
532
566
  requestAction,
533
567
  clone,
568
+ resend,
534
569
  confirmRunning,
535
570
  cancelRunning,
536
571
  pendingWorkId: operation?.source.workId ?? null
@@ -1,153 +1,165 @@
1
1
  'use client'
2
2
 
3
- import { useCallback, useEffect, useRef, useState } from 'react'
3
+ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'
4
4
  import { useTranslation } from 'react-i18next'
5
5
  import type {
6
6
  L2PiSessionHistoryResponse,
7
- L2PiSessionHistorySearchScope
7
+ L2PiSessionUserMessageListResponse
8
8
  } from '@common/l2_biz/pi-session/l2-pi-session-contract'
9
+ import type {
10
+ L3PiSessionSearchQuery,
11
+ L3PiSessionSearchScope
12
+ } from '@common/l3_modules/pi/l3-pi-session-search-contract'
9
13
  import type { L2WorkbenchBiz } from '../l2-workbench-biz'
14
+ import { useL2WorkbenchSessionSearch } from './l2-workbench-session-search'
10
15
 
11
- const DEFAULT_SEARCH_IN: readonly L2PiSessionHistorySearchScope[] = ['title', 'user']
12
- const CACHE_CWD_LIMIT = 8
13
-
14
- type HistorySessions = L2PiSessionHistoryResponse['sessions']
15
-
16
- interface HistorySessionCache {
17
- base: HistorySessions | null
18
- recent: {
19
- query: string
20
- searchIn: readonly L2PiSessionHistorySearchScope[]
21
- sessions: HistorySessions
22
- } | null
16
+ interface L2ExpandedHistoryMessages {
17
+ sessionId: string
18
+ query: string
19
+ messages: L2PiSessionUserMessageListResponse['messages']
20
+ page: L2PiSessionUserMessageListResponse['page'] | null
21
+ loading: boolean
22
+ error: string | null
23
23
  }
24
24
 
25
- interface SessionHistoryResult {
26
- sessions: HistorySessions
25
+ interface L2WorkbenchSessionHistoryResult {
26
+ sessions: L2PiSessionHistoryResponse['sessions']
27
27
  loading: boolean
28
- load: (
29
- cwd: string,
30
- query?: string,
31
- searchIn?: readonly L2PiSessionHistorySearchScope[],
32
- forceRefresh?: boolean
28
+ error: string | null
29
+ refresh: () => void
30
+ expandedHistory: L2ExpandedHistoryMessages | null
31
+ toggleUserMessages: (session: L2PiSessionHistoryResponse['sessions'][number]) => void
32
+ loadUserMessages: (
33
+ sessionId: string,
34
+ query: string,
35
+ pageIndex: number,
36
+ append: boolean
33
37
  ) => Promise<void>
34
- cancel: () => void
35
- showCached: (cwd: string) => void
36
38
  }
37
39
 
38
- function isDefaultSearchIn(searchIn: readonly L2PiSessionHistorySearchScope[]): boolean {
39
- return (
40
- searchIn.length === DEFAULT_SEARCH_IN.length &&
41
- DEFAULT_SEARCH_IN.every((scope) => searchIn.includes(scope))
40
+ export function useL2WorkbenchSessionHistory({
41
+ active,
42
+ cwd,
43
+ query,
44
+ searchIn,
45
+ listSessionHistory,
46
+ listSessionUserMessages
47
+ }: {
48
+ active: boolean
49
+ cwd: string | null
50
+ query: string
51
+ searchIn: readonly L3PiSessionSearchScope[]
52
+ listSessionHistory: L2WorkbenchBiz['listSessionHistory']
53
+ listSessionUserMessages: L2WorkbenchBiz['listSessionUserMessages']
54
+ }): L2WorkbenchSessionHistoryResult {
55
+ const { t } = useTranslation('workbenchPicker')
56
+ const request = useCallback(
57
+ (input: L3PiSessionSearchQuery, signal: AbortSignal, forceRefresh: boolean) =>
58
+ listSessionHistory({ ...input, cwd: cwd!, forceRefresh }, signal),
59
+ [cwd, listSessionHistory]
42
60
  )
43
- }
44
-
45
- export function useL2WorkbenchSessionHistory(
46
- workbenchBiz: L2WorkbenchBiz,
47
- setError: (error: string | null) => void
48
- ): SessionHistoryResult {
49
- const { t } = useTranslation('workbench')
50
- const [sessions, setSessions] = useState<HistorySessions>([])
51
- const [loading, setLoading] = useState(false)
52
- const requestIdRef = useRef(0)
53
- const abortControllerRef = useRef<AbortController | null>(null)
54
- const cacheRef = useRef(new Map<string, HistorySessionCache>())
55
-
56
- useEffect(
57
- () => () => {
58
- requestIdRef.current += 1
59
- abortControllerRef.current?.abort()
60
- abortControllerRef.current = null
61
- },
62
- []
61
+ const search = useL2WorkbenchSessionSearch({
62
+ active: active && cwd !== null,
63
+ scope: cwd,
64
+ query,
65
+ searchIn,
66
+ request,
67
+ failureMessage: t('loadHistoryFailed')
68
+ })
69
+ const [expandedHistory, setExpandedHistory] = useState<L2ExpandedHistoryMessages | null>(null)
70
+ const messageContext = useMemo(
71
+ () => ({ active, cwd, query, searchIn }),
72
+ [active, cwd, query, searchIn]
63
73
  )
64
-
65
- const cancel = useCallback((): void => {
66
- requestIdRef.current += 1
67
- abortControllerRef.current?.abort()
68
- abortControllerRef.current = null
69
- setLoading(false)
70
- }, [])
71
-
72
- const showCached = useCallback((cwd: string): void => {
73
- setSessions(cacheRef.current.get(cwd)?.base ?? [])
74
+ const [previousMessageContext, setPreviousMessageContext] = useState(messageContext)
75
+ if (previousMessageContext !== messageContext) {
76
+ setPreviousMessageContext(messageContext)
77
+ setExpandedHistory(null)
78
+ }
79
+ const messageControllerRef = useRef<AbortController | null>(null)
80
+ const clearUserMessages = useCallback((): void => {
81
+ messageControllerRef.current?.abort()
82
+ messageControllerRef.current = null
83
+ setExpandedHistory(null)
74
84
  }, [])
75
85
 
76
- const load = useCallback(
77
- async (
78
- cwd: string,
79
- query = '',
80
- searchIn: readonly L2PiSessionHistorySearchScope[] = DEFAULT_SEARCH_IN,
81
- forceRefresh = false
82
- ): Promise<void> => {
83
- const requestId = ++requestIdRef.current
84
- abortControllerRef.current?.abort()
85
- abortControllerRef.current = null
86
- const normalizedQuery = query.trim()
87
- const cached = cacheRef.current.get(cwd)
88
- const cachedSessions =
89
- isDefaultSearchIn(searchIn) && !normalizedQuery
90
- ? cached?.base
91
- : cached?.recent?.query === normalizedQuery &&
92
- cached.recent.searchIn.length === searchIn.length &&
93
- cached.recent.searchIn.every((scope) => searchIn.includes(scope))
94
- ? cached.recent.sessions
95
- : null
96
- if (cachedSessions && !forceRefresh) {
97
- setSessions(cachedSessions)
98
- setLoading(false)
99
- setError(null)
100
- return
101
- }
102
- if (cachedSessions) setSessions(cachedSessions)
103
-
104
- const controller = new AbortController()
105
- abortControllerRef.current = controller
106
- setLoading(true)
107
- setError(null)
108
- try {
109
- const response = await workbenchBiz.listSessionHistory(
110
- { cwd, query: normalizedQuery, forceRefresh, searchIn: [...searchIn] },
111
- controller.signal
112
- )
113
- if (requestIdRef.current !== requestId) return
114
- const current = cacheRef.current.get(cwd) ?? { base: null, recent: null }
115
- if (isDefaultSearchIn(searchIn) && !normalizedQuery) {
116
- current.base = response.sessions
117
- } else {
118
- current.recent = {
119
- query: normalizedQuery,
120
- searchIn: [...searchIn],
121
- sessions: response.sessions
122
- }
123
- }
124
- cacheRef.current.delete(cwd)
125
- cacheRef.current.set(cwd, current)
126
- while (cacheRef.current.size > CACHE_CWD_LIMIT) {
127
- const oldestCwd = cacheRef.current.keys().next().value
128
- if (!oldestCwd) break
129
- cacheRef.current.delete(oldestCwd)
130
- }
131
- setSessions(response.sessions)
132
- } catch (cause) {
133
- if (
134
- requestIdRef.current !== requestId ||
135
- (cause instanceof Error && cause.name === 'AbortError')
136
- ) {
137
- return
138
- }
139
- setError(cause instanceof Error ? cause.message : t('historyFailed'))
140
- } finally {
141
- if (requestIdRef.current === requestId) {
142
- if (abortControllerRef.current === controller) {
143
- abortControllerRef.current = null
144
- }
145
- setLoading(false)
146
- }
147
- }
86
+ useLayoutEffect(
87
+ () => () => {
88
+ messageControllerRef.current?.abort()
89
+ messageControllerRef.current = null
148
90
  },
149
- [setError, workbenchBiz, t]
91
+ [active, cwd, query, searchIn]
150
92
  )
151
93
 
152
- return { sessions, loading, load, cancel, showCached }
94
+ const loadUserMessages = async (
95
+ sessionId: string,
96
+ messageQuery: string,
97
+ pageIndex: number,
98
+ append: boolean
99
+ ): Promise<void> => {
100
+ if (!active || !cwd) return
101
+ messageControllerRef.current?.abort()
102
+ const controller = new AbortController()
103
+ messageControllerRef.current = controller
104
+ setExpandedHistory((current) => ({
105
+ sessionId,
106
+ query: messageQuery,
107
+ messages: append && current?.sessionId === sessionId ? current.messages : [],
108
+ page: append && current?.sessionId === sessionId ? current.page : null,
109
+ loading: true,
110
+ error: null
111
+ }))
112
+ try {
113
+ const response = await listSessionUserMessages(
114
+ { cwd, sessionId, query: messageQuery, page: { index: pageIndex, size: 20 } },
115
+ controller.signal
116
+ )
117
+ if (controller.signal.aborted) return
118
+ setExpandedHistory((current) => ({
119
+ sessionId,
120
+ query: messageQuery,
121
+ messages:
122
+ append && current?.sessionId === sessionId
123
+ ? [...current.messages, ...response.messages]
124
+ : response.messages,
125
+ page: response.page,
126
+ loading: false,
127
+ error: null
128
+ }))
129
+ } catch (cause) {
130
+ if (controller.signal.aborted) return
131
+ setExpandedHistory((current) => ({
132
+ sessionId,
133
+ query: messageQuery,
134
+ messages: current?.sessionId === sessionId ? current.messages : [],
135
+ page: current?.sessionId === sessionId ? current.page : null,
136
+ loading: false,
137
+ error: cause instanceof Error ? cause.message : t('loadUserFailed')
138
+ }))
139
+ } finally {
140
+ if (messageControllerRef.current === controller) messageControllerRef.current = null
141
+ }
142
+ }
143
+
144
+ const toggleUserMessages = (session: L2PiSessionHistoryResponse['sessions'][number]): void => {
145
+ if (expandedHistory?.sessionId === session.sessionId) {
146
+ clearUserMessages()
147
+ return
148
+ }
149
+ const messageQuery = session.matches?.some((match) => match.scope === 'user') ? query : ''
150
+ void loadUserMessages(session.sessionId, messageQuery, 1, false)
151
+ }
152
+ const refresh = (): void => {
153
+ clearUserMessages()
154
+ search.refresh()
155
+ }
156
+ return {
157
+ sessions: search.data?.sessions ?? [],
158
+ loading: search.loading,
159
+ error: search.error,
160
+ refresh,
161
+ expandedHistory: active ? expandedHistory : null,
162
+ toggleUserMessages,
163
+ loadUserMessages
164
+ }
153
165
  }
@@ -0,0 +1,97 @@
1
+ 'use client'
2
+
3
+ import { useCallback, useLayoutEffect, useMemo, useRef, useState } from 'react'
4
+ import type {
5
+ L3PiSessionSearchQuery,
6
+ L3PiSessionSearchScope
7
+ } from '@common/l3_modules/pi/l3-pi-session-search-contract'
8
+
9
+ export const L2_WORKBENCH_DEFAULT_SEARCH_IN: readonly L3PiSessionSearchScope[] = ['title', 'user']
10
+
11
+ export interface L2WorkbenchSessionSearchResult<T> {
12
+ data: T | null
13
+ loading: boolean
14
+ error: string | null
15
+ refresh: () => void
16
+ }
17
+
18
+ export function useL2WorkbenchSessionSearch<T>({
19
+ active,
20
+ scope,
21
+ query,
22
+ searchIn,
23
+ request,
24
+ failureMessage
25
+ }: {
26
+ active: boolean
27
+ scope: unknown
28
+ query: string
29
+ searchIn: readonly L3PiSessionSearchScope[]
30
+ request: (input: L3PiSessionSearchQuery, signal: AbortSignal, forceRefresh: boolean) => Promise<T>
31
+ failureMessage: string
32
+ }): L2WorkbenchSessionSearchResult<T> {
33
+ const [attempt, setAttempt] = useState(0)
34
+ const forceRefreshRef = useRef(false)
35
+ const normalizedQuery = query.trim()
36
+ const key = useMemo(
37
+ () => ({ active, scope, query: normalizedQuery, searchIn, request, attempt, failureMessage }),
38
+ [active, scope, normalizedQuery, searchIn, request, attempt, failureMessage]
39
+ )
40
+ const [state, setState] = useState<{
41
+ key: typeof key
42
+ data: T | null
43
+ loading: boolean
44
+ error: string | null
45
+ } | null>(null)
46
+ if (state?.key !== key) {
47
+ setState({ key, data: null, loading: key.active, error: null })
48
+ }
49
+
50
+ useLayoutEffect(() => {
51
+ const forceRefresh = forceRefreshRef.current
52
+ forceRefreshRef.current = false
53
+ if (!key.active) return
54
+
55
+ const controller = new AbortController()
56
+ const timer = window.setTimeout(
57
+ () => {
58
+ void request(
59
+ { query: key.query, searchIn: [...key.searchIn] },
60
+ controller.signal,
61
+ forceRefresh
62
+ ).then(
63
+ (data) => {
64
+ if (!controller.signal.aborted) setState({ key, data, loading: false, error: null })
65
+ },
66
+ (cause: unknown) => {
67
+ if (controller.signal.aborted) return
68
+ setState({
69
+ key,
70
+ data: null,
71
+ loading: false,
72
+ error: cause instanceof Error ? cause.message : key.failureMessage
73
+ })
74
+ }
75
+ )
76
+ },
77
+ key.query && !forceRefresh ? 300 : 0
78
+ )
79
+
80
+ return () => {
81
+ window.clearTimeout(timer)
82
+ controller.abort()
83
+ }
84
+ }, [key, request])
85
+
86
+ const refresh = useCallback((): void => {
87
+ forceRefreshRef.current = true
88
+ setAttempt((current) => current + 1)
89
+ }, [])
90
+ const current = state?.key === key ? state : null
91
+ return {
92
+ data: current?.data ?? null,
93
+ loading: active && (current?.loading ?? true),
94
+ error: current?.error ?? null,
95
+ refresh
96
+ }
97
+ }
@@ -77,6 +77,7 @@ interface L2WorkSessionColumnsProps
77
77
  setChatCapabilityMode: L2WorkbenchBiz['setChatCapabilityMode']
78
78
  branchPicker: L2WorkbenchBranchPickerModel | null
79
79
  branchPendingWorkId: string | null
80
+ onResendMessage: (source: L2ChatSource, entryId: string) => void
80
81
  fileRuntime: L2FileWorkspaceRuntime
81
82
  onOpenFileSidebar: (workId: string) => void
82
83
  onPreviewFile: (source: L2ChatSource, path: string) => void
@@ -148,6 +149,7 @@ interface WorkSessionColumnProps extends L2WorkbenchComposerSlots, L2WorkbenchPl
148
149
  setChatCapabilityMode: L2WorkbenchBiz['setChatCapabilityMode']
149
150
  branchPicker: L2WorkbenchBranchPickerModel | null
150
151
  branchPending: boolean
152
+ onResendMessage: (source: L2ChatSource, entryId: string) => void
151
153
  mobile: boolean
152
154
  fileRuntime: L2FileWorkspaceRuntime
153
155
  onOpenFileSidebar: (workId: string) => void
@@ -193,6 +195,7 @@ const WorkSessionColumn = memo(function WorkSessionColumn({
193
195
  setChatCapabilityMode,
194
196
  branchPicker,
195
197
  branchPending,
198
+ onResendMessage,
196
199
  mobile,
197
200
  fileRuntime,
198
201
  onOpenFileSidebar,
@@ -360,6 +363,8 @@ const WorkSessionColumn = memo(function WorkSessionColumn({
360
363
  chatRuntime={chatRuntime}
361
364
  inputRuntime={chatInputRuntime}
362
365
  onPreviewFile={onPreviewFile}
366
+ onResend={onResendMessage}
367
+ resendDisabled={replacementDisabled || branchPending || branchPicker !== null}
363
368
  />
364
369
  <footer className="bg-background pt-3" data-carousel-swipe-lock>
365
370
  <L2WorkbenchChatComposer
@@ -516,6 +521,7 @@ export function L2WorkSessionColumns({
516
521
  setChatCapabilityMode,
517
522
  branchPicker,
518
523
  branchPendingWorkId,
524
+ onResendMessage,
519
525
  fileRuntime,
520
526
  onOpenFileSidebar,
521
527
  onPreviewFile,
@@ -705,6 +711,7 @@ export function L2WorkSessionColumns({
705
711
  setChatCapabilityMode={setChatCapabilityMode}
706
712
  branchPicker={branchPicker?.workId === workSession.workId ? branchPicker : null}
707
713
  branchPending={branchPendingWorkId === workSession.workId}
714
+ onResendMessage={onResendMessage}
708
715
  mobile
709
716
  fileRuntime={fileRuntime}
710
717
  onOpenFileSidebar={onOpenFileSidebar}
@@ -805,6 +812,7 @@ export function L2WorkSessionColumns({
805
812
  setChatCapabilityMode={setChatCapabilityMode}
806
813
  branchPicker={branchPicker?.workId === workSession.workId ? branchPicker : null}
807
814
  branchPending={branchPendingWorkId === workSession.workId}
815
+ onResendMessage={onResendMessage}
808
816
  mobile={mobile}
809
817
  fileRuntime={fileRuntime}
810
818
  onOpenFileSidebar={onOpenFileSidebar}