@jetcrab/pi-desk 1.1.12 → 1.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. package/docs/plugins.md +21 -1
  2. package/package.json +2 -2
  3. package/src/app/api/model-settings/preview/route.ts +1 -0
  4. package/src/app/api/work-sessions/rename/route.ts +1 -0
  5. package/src/client/l2_biz/auth/l2-login.tsx +1 -1
  6. package/src/client/l2_biz/plugin-host/l2-plugin-session-sidebar-tab.tsx +6 -2
  7. package/src/client/l2_biz/settings/hooks/l2-use-model-provider-settings.ts +54 -10
  8. package/src/client/l2_biz/settings/hooks/l2-use-model-settings.ts +37 -9
  9. package/src/client/l2_biz/settings/l2-auth-settings.tsx +1 -1
  10. package/src/client/l2_biz/settings/l2-model-settings-biz.ts +26 -12
  11. package/src/client/l2_biz/settings/views/l2-appearance-settings.tsx +1 -16
  12. package/src/client/l2_biz/settings/views/l2-model-provider-settings.tsx +3 -2
  13. package/src/client/l2_biz/settings/views/l2-model-replacement-preview.tsx +34 -0
  14. package/src/client/l2_biz/task-center/l2-task-center.tsx +4 -30
  15. package/src/client/l2_biz/workbench/file-workspace/l2-plugin-standalone-file-preview.tsx +45 -7
  16. package/src/client/l2_biz/workbench/hooks/l2-work-session-rename.ts +57 -0
  17. package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +0 -11
  18. package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +107 -6
  19. package/src/client/l2_biz/workbench/l2-workbench-biz.ts +5 -0
  20. package/src/client/l2_biz/workbench/l2-workbench-chat-composer.tsx +333 -350
  21. package/src/client/l2_biz/workbench/l2-workbench.tsx +46 -1
  22. package/src/client/l2_biz/workbench/views/l2-work-session-rename-dialog.tsx +88 -0
  23. package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +81 -0
  24. package/src/client/l3_modules/project-files/l3-markdown-preview.tsx +52 -0
  25. package/src/client/l3_modules/project-files/l3-project-document-view.tsx +26 -8
  26. package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +16 -1
  27. package/src/client/l3_modules/project-files/l3-project-text-preview.ts +5 -0
  28. package/src/client/l3_modules/work-session-visual/l3-work-session-visual-effects.module.css +0 -36
  29. package/src/client/l3_modules/work-session-visual/l3-work-session-visual-view.tsx +0 -5
  30. package/src/client/l4_foundation/plugin-host/l4-plugin-host-runtime.ts +71 -1
  31. package/src/client/l4_foundation/styles/l4-globals.css +0 -19
  32. package/src/client/l4_foundation/ui/code/l4-code-preview.tsx +2 -1
  33. package/src/client/l4_foundation/ui/l4-confirm-dialog.tsx +9 -1
  34. package/src/common/l2_biz/auth/l2-auth-contract.ts +2 -2
  35. package/src/common/l2_biz/auth/l2-auth-messages.ts +2 -2
  36. package/src/common/l2_biz/model-settings/l2-model-settings-contract.ts +23 -1
  37. package/src/common/l2_biz/settings/l2-settings-messages.ts +8 -6
  38. package/src/common/l2_biz/work-session/l2-work-session-contract.ts +9 -0
  39. package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +6 -0
  40. package/src/common/l3_modules/project-files/l3-project-files-locale-messages.ts +4 -0
  41. package/src/common/l4_foundation/locale/l4-host-error-messages.ts +6 -0
  42. package/src/server/l1_entry/api/l1-model-settings-preview-route.ts +32 -0
  43. package/src/server/l1_entry/api/l1-work-session-rename-route.ts +52 -0
  44. package/src/server/l2_biz/model-settings/l2-model-settings.ts +9 -0
  45. package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +159 -52
  46. package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +5 -0
  47. package/src/server/l2_biz/work-session/l2-work-session-manage.ts +13 -0
  48. package/src/server/l3_modules/work-session/l3-work-session.ts +4 -0
  49. package/src/server/l4_foundation/model-settings/l4-model-settings-store.ts +161 -38
  50. package/src/server/l4_foundation/model-settings/l4-model-settings-types.ts +11 -0
  51. package/src/server/l4_foundation/model-settings/l4-model-settings.ts +1 -0
  52. package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +12 -1
  53. package/src/server/l4_foundation/pi/l4-pi-package-maintenance-runner.mts +56 -65
  54. package/src/server/l4_foundation/pi/l4-pi-package-maintenance.ts +2 -0
  55. package/src/server/l4_foundation/pi/l4-pi-package-reinstall-runner.mts +49 -0
  56. package/src/server/l4_foundation/pi/l4-pi-package-root-consistency.ts +6 -2
  57. package/src/server/l4_foundation/pi/l4-pi-plugin-probe.ts +3 -1
  58. package/src/server/l4_foundation/pi/l4-pi-runner-process.ts +9 -0
  59. package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +5 -0
  60. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  61. package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +2 -0
  62. package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
  63. package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
  64. package/temp/build/pi-desk/release/.next/react-loadable-manifest.json +1 -2
  65. package/temp/build/pi-desk/release/.next/required-server-files.js +2 -2
  66. package/temp/build/pi-desk/release/.next/required-server-files.json +2 -2
  67. package/temp/build/pi-desk/release/.next/routes-manifest.json +12 -0
  68. package/temp/build/pi-desk/release/.next/server/app/_global-error/page.js +1 -1
  69. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  70. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  71. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
  72. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  73. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  74. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  75. package/temp/build/pi-desk/release/.next/server/app/_not-found/page.js +1 -1
  76. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  77. package/temp/build/pi-desk/release/.next/server/app/api/auth/login/route.js +2 -2
  78. package/temp/build/pi-desk/release/.next/server/app/api/auth/logout/route.js +1 -1
  79. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/get/route.js +1 -1
  80. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/replace/route.js +1 -1
  81. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/get/route.js +1 -1
  82. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/replace/route.js +1 -1
  83. package/temp/build/pi-desk/release/.next/server/app/api/chat/context/get/route.js +1 -1
  84. package/temp/build/pi-desk/release/.next/server/app/api/chat/images/get/route.js +1 -1
  85. package/temp/build/pi-desk/release/.next/server/app/api/chat/messages/get/route.js +1 -1
  86. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  87. package/temp/build/pi-desk/release/.next/server/app/api/mcp-check/get/route.js +1 -1
  88. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/del/route.js +1 -1
  89. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/get/route.js +1 -1
  90. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/replace/route.js +1 -1
  91. package/temp/build/pi-desk/release/.next/server/app/api/model-catalog/list/route.js +1 -1
  92. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/get/route.js +1 -1
  93. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/preview/route.js +1 -0
  94. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/preview/route_client-reference-manifest.js +1 -0
  95. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/replace/route.js +1 -1
  96. package/temp/build/pi-desk/release/.next/server/app/api/pi/directories/list/route.js +1 -1
  97. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-entries/list/route.js +1 -1
  98. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/list/route.js +1 -1
  99. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/replace/route.js +1 -1
  100. package/temp/build/pi-desk/release/.next/server/app/api/pi/models/list/route.js +1 -1
  101. package/temp/build/pi-desk/release/.next/server/app/api/pi/session-user-messages/list/route.js +1 -1
  102. package/temp/build/pi-desk/release/.next/server/app/api/pi/sessions/list/route.js +1 -1
  103. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/get/route.js +1 -1
  104. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/search/route.js +1 -1
  105. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-get/route.js +1 -1
  106. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-replace/route.js +1 -1
  107. package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
  108. package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
  109. package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
  110. package/temp/build/pi-desk/release/.next/server/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route.js +1 -1
  111. package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
  112. package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
  113. package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
  114. package/temp/build/pi-desk/release/.next/server/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route.js +1 -1
  115. package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
  116. package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
  117. package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
  118. package/temp/build/pi-desk/release/.next/server/app/api/project-files/get/route.js +1 -1
  119. package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +1 -1
  120. package/temp/build/pi-desk/release/.next/server/app/api/project-files/reveal/route.js +1 -1
  121. package/temp/build/pi-desk/release/.next/server/app/api/project-files/search/route.js +1 -1
  122. package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +1 -1
  123. package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +1 -1
  124. package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +1 -1
  125. package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +1 -1
  126. package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +1 -1
  127. package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +1 -1
  128. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/get/route.js +1 -1
  129. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/replace/route.js +1 -1
  130. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/get/route.js +1 -1
  131. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/list/route.js +1 -1
  132. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/replace/route.js +1 -1
  133. package/temp/build/pi-desk/release/.next/server/app/api/skills/list/route.js +1 -1
  134. package/temp/build/pi-desk/release/.next/server/app/api/task-center/images/get/route.js +1 -1
  135. package/temp/build/pi-desk/release/.next/server/app/api/task-center/messages/get/route.js +1 -1
  136. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/add/route.js +1 -1
  137. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/replace/route.js +1 -1
  138. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree/get/route.js +1 -1
  139. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree-entry/get/route.js +1 -1
  140. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/add/route.js +1 -1
  141. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/branch/route.js +1 -1
  142. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/del/route.js +1 -1
  143. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route.js +1 -0
  144. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route_client-reference-manifest.js +1 -0
  145. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/replace/route.js +1 -1
  146. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/sort/route.js +1 -1
  147. package/temp/build/pi-desk/release/.next/server/app/favicon.ico/route.js +1 -1
  148. package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
  149. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  150. package/temp/build/pi-desk/release/.next/server/app/page.js +72 -306
  151. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  152. package/temp/build/pi-desk/release/.next/server/app-paths-manifest.json +2 -0
  153. package/temp/build/pi-desk/release/.next/server/chunks/23054.js +1 -1
  154. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -8
  155. package/temp/build/pi-desk/release/.next/server/chunks/33658.js +296 -0
  156. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +5 -5
  157. package/temp/build/pi-desk/release/.next/server/chunks/48180.js +1 -1
  158. package/temp/build/pi-desk/release/.next/server/chunks/49900.js +2 -2
  159. package/temp/build/pi-desk/release/.next/server/chunks/50520.js +5 -5
  160. package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
  161. package/temp/build/pi-desk/release/.next/server/chunks/78262.js +3 -3
  162. package/temp/build/pi-desk/release/.next/server/chunks/82499.js +6 -6
  163. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +3 -3
  164. package/temp/build/pi-desk/release/.next/server/chunks/94296.js +2 -2
  165. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  166. package/temp/build/pi-desk/release/.next/server/middleware-react-loadable-manifest.js +1 -1
  167. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  168. package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
  169. package/temp/build/pi-desk/release/.next/static/DqamF28k0ShQLbNVzXDIj/_buildManifest.js +1 -0
  170. package/temp/build/pi-desk/release/.next/static/chunks/31087-ba426d09d6f68bfd.js +1 -0
  171. package/temp/build/pi-desk/release/.next/static/chunks/39654-b5fedd762ea0312e.js +238 -0
  172. package/temp/build/pi-desk/release/.next/static/chunks/49516-cc4dcd84d64ab4fe.js +81 -0
  173. package/temp/build/pi-desk/release/.next/static/chunks/75130-d2ca74894aff8085.js +13 -0
  174. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-9969fe0baa238786.js +1 -0
  175. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-9969fe0baa238786.js +1 -0
  176. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-9969fe0baa238786.js +1 -0
  177. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-9969fe0baa238786.js +1 -0
  178. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-9969fe0baa238786.js +1 -0
  179. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-9969fe0baa238786.js +1 -0
  180. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-9969fe0baa238786.js +1 -0
  181. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-9969fe0baa238786.js +1 -0
  182. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-9969fe0baa238786.js +1 -0
  183. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-9969fe0baa238786.js +1 -0
  184. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-9969fe0baa238786.js +1 -0
  185. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-9969fe0baa238786.js +1 -0
  186. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-9969fe0baa238786.js +1 -0
  187. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-9969fe0baa238786.js +1 -0
  188. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-9969fe0baa238786.js +1 -0
  189. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-9969fe0baa238786.js +1 -0
  190. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-9969fe0baa238786.js +1 -0
  191. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-9969fe0baa238786.js +1 -0
  192. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/preview/route-9969fe0baa238786.js +1 -0
  193. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-9969fe0baa238786.js +1 -0
  194. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-9969fe0baa238786.js +1 -0
  195. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-9969fe0baa238786.js +1 -0
  196. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-9969fe0baa238786.js +1 -0
  197. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-9969fe0baa238786.js +1 -0
  198. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-9969fe0baa238786.js +1 -0
  199. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-9969fe0baa238786.js +1 -0
  200. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-9969fe0baa238786.js +1 -0
  201. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-9969fe0baa238786.js +1 -0
  202. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-9969fe0baa238786.js +1 -0
  203. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-9969fe0baa238786.js +1 -0
  204. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-9969fe0baa238786.js +1 -0
  205. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-9969fe0baa238786.js +1 -0
  206. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-9969fe0baa238786.js +1 -0
  207. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-9969fe0baa238786.js +1 -0
  208. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-9969fe0baa238786.js +1 -0
  209. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-9969fe0baa238786.js +1 -0
  210. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-9969fe0baa238786.js +1 -0
  211. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-9969fe0baa238786.js +1 -0
  212. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-9969fe0baa238786.js +1 -0
  213. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-9969fe0baa238786.js +1 -0
  214. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-9969fe0baa238786.js +1 -0
  215. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-9969fe0baa238786.js +1 -0
  216. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-9969fe0baa238786.js +1 -0
  217. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-9969fe0baa238786.js +1 -0
  218. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-9969fe0baa238786.js +1 -0
  219. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-9969fe0baa238786.js +1 -0
  220. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-9969fe0baa238786.js +1 -0
  221. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-9969fe0baa238786.js +1 -0
  222. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-9969fe0baa238786.js +1 -0
  223. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-9969fe0baa238786.js +1 -0
  224. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-9969fe0baa238786.js +1 -0
  225. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-9969fe0baa238786.js +1 -0
  226. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-9969fe0baa238786.js +1 -0
  227. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-9969fe0baa238786.js +1 -0
  228. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-9969fe0baa238786.js +1 -0
  229. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-9969fe0baa238786.js +1 -0
  230. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-9969fe0baa238786.js +1 -0
  231. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-9969fe0baa238786.js +1 -0
  232. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-9969fe0baa238786.js +1 -0
  233. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-9969fe0baa238786.js +1 -0
  234. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-9969fe0baa238786.js +1 -0
  235. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-9969fe0baa238786.js +1 -0
  236. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-9969fe0baa238786.js +1 -0
  237. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-9969fe0baa238786.js +1 -0
  238. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-9969fe0baa238786.js +1 -0
  239. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-9969fe0baa238786.js +1 -0
  240. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-9969fe0baa238786.js +1 -0
  241. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-9969fe0baa238786.js +1 -0
  242. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-9969fe0baa238786.js +1 -0
  243. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-9969fe0baa238786.js +1 -0
  244. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-c0e1c5cef8620cf8.js +3 -0
  245. package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-84892b06243891f0.js +1 -0
  246. package/temp/build/pi-desk/release/.next/static/chunks/app/page-0069319a4fb97211.js +158 -0
  247. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-9969fe0baa238786.js +1 -0
  248. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-9969fe0baa238786.js +1 -0
  249. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-9969fe0baa238786.js +1 -0
  250. package/temp/build/pi-desk/release/.next/static/chunks/webpack-40a782fc8a3535b9.js +1 -0
  251. package/temp/build/pi-desk/release/.next/static/css/6427d02b6edf406f.css +1 -0
  252. package/temp/build/pi-desk/release/.next/static/css/{adb1d4e48dd43c0a.css → 949d0d1a99d5de92.css} +1 -1
  253. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  254. package/src/client/l2_biz/workbench/hooks/l2-work-session-column-motion.ts +0 -87
  255. package/src/client/l3_modules/work-session-visual/l3-work-session-status-border.tsx +0 -66
  256. package/src/client/l4_foundation/ui/l4-power-saving.ts +0 -45
  257. package/src/client/l4_foundation/ui/l4-window-reveal.ts +0 -30
  258. package/temp/build/pi-desk/release/.next/server/chunks/56284.js +0 -62
  259. package/temp/build/pi-desk/release/.next/static/96geGVI-j_dC6I3k-XFCB/_buildManifest.js +0 -1
  260. package/temp/build/pi-desk/release/.next/static/chunks/31087-333cae396a52f232.js +0 -1
  261. package/temp/build/pi-desk/release/.next/static/chunks/45992-92d8b8b10fcfbb6b.js +0 -13
  262. package/temp/build/pi-desk/release/.next/static/chunks/47340-c1c09c77c1a88514.js +0 -318
  263. package/temp/build/pi-desk/release/.next/static/chunks/57208-d6d38167dabb91e4.js +0 -1
  264. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-dde4fd973791f7f7.js +0 -1
  265. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-dde4fd973791f7f7.js +0 -1
  266. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-dde4fd973791f7f7.js +0 -1
  267. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-dde4fd973791f7f7.js +0 -1
  268. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-dde4fd973791f7f7.js +0 -1
  269. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-dde4fd973791f7f7.js +0 -1
  270. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-dde4fd973791f7f7.js +0 -1
  271. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-dde4fd973791f7f7.js +0 -1
  272. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-dde4fd973791f7f7.js +0 -1
  273. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-dde4fd973791f7f7.js +0 -1
  274. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-dde4fd973791f7f7.js +0 -1
  275. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-dde4fd973791f7f7.js +0 -1
  276. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-dde4fd973791f7f7.js +0 -1
  277. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-dde4fd973791f7f7.js +0 -1
  278. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-dde4fd973791f7f7.js +0 -1
  279. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-dde4fd973791f7f7.js +0 -1
  280. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-dde4fd973791f7f7.js +0 -1
  281. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-dde4fd973791f7f7.js +0 -1
  282. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-dde4fd973791f7f7.js +0 -1
  283. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-dde4fd973791f7f7.js +0 -1
  284. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-dde4fd973791f7f7.js +0 -1
  285. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-dde4fd973791f7f7.js +0 -1
  286. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-dde4fd973791f7f7.js +0 -1
  287. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-dde4fd973791f7f7.js +0 -1
  288. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-dde4fd973791f7f7.js +0 -1
  289. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-dde4fd973791f7f7.js +0 -1
  290. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-dde4fd973791f7f7.js +0 -1
  291. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-dde4fd973791f7f7.js +0 -1
  292. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-dde4fd973791f7f7.js +0 -1
  293. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-dde4fd973791f7f7.js +0 -1
  294. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-dde4fd973791f7f7.js +0 -1
  295. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-dde4fd973791f7f7.js +0 -1
  296. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-dde4fd973791f7f7.js +0 -1
  297. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-dde4fd973791f7f7.js +0 -1
  298. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-dde4fd973791f7f7.js +0 -1
  299. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-dde4fd973791f7f7.js +0 -1
  300. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-dde4fd973791f7f7.js +0 -1
  301. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-dde4fd973791f7f7.js +0 -1
  302. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-dde4fd973791f7f7.js +0 -1
  303. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-dde4fd973791f7f7.js +0 -1
  304. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-dde4fd973791f7f7.js +0 -1
  305. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-dde4fd973791f7f7.js +0 -1
  306. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-dde4fd973791f7f7.js +0 -1
  307. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-dde4fd973791f7f7.js +0 -1
  308. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-dde4fd973791f7f7.js +0 -1
  309. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-dde4fd973791f7f7.js +0 -1
  310. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-dde4fd973791f7f7.js +0 -1
  311. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-dde4fd973791f7f7.js +0 -1
  312. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-dde4fd973791f7f7.js +0 -1
  313. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-dde4fd973791f7f7.js +0 -1
  314. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-dde4fd973791f7f7.js +0 -1
  315. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-dde4fd973791f7f7.js +0 -1
  316. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-dde4fd973791f7f7.js +0 -1
  317. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-dde4fd973791f7f7.js +0 -1
  318. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-dde4fd973791f7f7.js +0 -1
  319. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-dde4fd973791f7f7.js +0 -1
  320. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-dde4fd973791f7f7.js +0 -1
  321. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-dde4fd973791f7f7.js +0 -1
  322. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-dde4fd973791f7f7.js +0 -1
  323. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-dde4fd973791f7f7.js +0 -1
  324. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-dde4fd973791f7f7.js +0 -1
  325. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-dde4fd973791f7f7.js +0 -1
  326. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-dde4fd973791f7f7.js +0 -1
  327. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-dde4fd973791f7f7.js +0 -1
  328. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-dde4fd973791f7f7.js +0 -1
  329. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-dde4fd973791f7f7.js +0 -1
  330. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-dde4fd973791f7f7.js +0 -1
  331. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-dde4fd973791f7f7.js +0 -1
  332. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-839162b6cfae8347.js +0 -3
  333. package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-4532a3bbee48e219.js +0 -1
  334. package/temp/build/pi-desk/release/.next/static/chunks/app/page-4b6367cde5c04597.js +0 -158
  335. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-dde4fd973791f7f7.js +0 -1
  336. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-dde4fd973791f7f7.js +0 -1
  337. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-dde4fd973791f7f7.js +0 -1
  338. package/temp/build/pi-desk/release/.next/static/chunks/webpack-735430d61da52e9d.js +0 -1
  339. package/temp/build/pi-desk/release/.next/static/css/4a5dda7ff3a82c4a.css +0 -1
  340. /package/temp/build/pi-desk/release/.next/static/{96geGVI-j_dC6I3k-XFCB → DqamF28k0ShQLbNVzXDIj}/_ssgManifest.js +0 -0
@@ -7,7 +7,12 @@ import type { PluginSource } from '@jetcrab/pi-desk-sdk/browser'
7
7
  import type { L2WorkSessionFileGetResponse } from '@common/l2_biz/work-session/l2-work-session-file-contract'
8
8
  import { createL4Base64ImageBlob } from '@client/l4_foundation/media/l4-base64-image'
9
9
  import { readL3ImagePreviewMode } from '@client/l3_modules/preferences/l3-work-session-file-preferences'
10
- import { L4CodePreview } from '@client/l4_foundation/ui/code/l4-code-preview'
10
+ import {
11
+ L4CodePreview,
12
+ type L4CodePreviewState
13
+ } from '@client/l4_foundation/ui/code/l4-code-preview'
14
+ import { L3MarkdownPreview } from '@client/l3_modules/project-files/l3-markdown-preview'
15
+ import { getL3ProjectTextPreviewKind } from '@client/l3_modules/project-files/l3-project-text-preview'
11
16
  import {
12
17
  L4AppDialogContent,
13
18
  L4AppDialogRoot,
@@ -56,7 +61,14 @@ export function L2PluginStandaloneFilePreview({
56
61
  onClose: () => void
57
62
  }): React.JSX.Element | null {
58
63
  const { t } = useTranslation('workbench')
64
+ const { t: filesT } = useTranslation('projectFiles')
59
65
  const iframeRef = useRef<HTMLIFrameElement>(null)
66
+ const [view, setView] = useState<{ mode: 'preview' | 'source'; scrollTop: number }>({
67
+ mode: 'preview',
68
+ scrollTop: 0
69
+ })
70
+ const previewScrollTop = useRef(0)
71
+ const [editorState, setEditorState] = useState<L4CodePreviewState | null>(null)
60
72
  const [retry, setRetry] = useState(0)
61
73
  const [document, setDocument] = useState<StandaloneFileDocument>(() => {
62
74
  const url =
@@ -129,7 +141,7 @@ export function L2PluginStandaloneFilePreview({
129
141
 
130
142
  if (!target) return null
131
143
  const path = target.imagePaths?.[imageIndex] ?? target.path
132
- const isHtml = /\.html?$/i.test(path)
144
+ const previewKind = getL3ProjectTextPreviewKind(path)
133
145
  return (
134
146
  <L4AppDialogRoot
135
147
  open
@@ -150,8 +162,8 @@ export function L2PluginStandaloneFilePreview({
150
162
  className="flex size-full min-h-0 min-w-0 flex-col overflow-hidden bg-background"
151
163
  aria-label={t('standaloneViewer', { name: target.projectName })}
152
164
  >
153
- <header className="flex min-h-14 shrink-0 items-center border-b pl-3 pr-14 pt-[env(safe-area-inset-top)]">
154
- <div className="min-w-0">
165
+ <header className="flex min-h-14 shrink-0 items-center gap-3 border-b pl-3 pr-14 pt-[env(safe-area-inset-top)]">
166
+ <div className="min-w-0 flex-1">
155
167
  <p className="truncate text-sm font-semibold" title={fileName(path)}>
156
168
  {fileName(path)}
157
169
  </p>
@@ -162,6 +174,23 @@ export function L2PluginStandaloneFilePreview({
162
174
  {target.projectName} · {path}
163
175
  </p>
164
176
  </div>
177
+ {previewKind === 'markdown' && document.status === 'text' ? (
178
+ <div className="flex shrink-0" role="group" aria-label={filesT('markdownMode')}>
179
+ {(['preview', 'source'] as const).map((mode) => (
180
+ <Button
181
+ key={mode}
182
+ size="sm"
183
+ variant={view.mode === mode ? 'secondary' : 'ghost'}
184
+ aria-pressed={view.mode === mode}
185
+ onClick={() => {
186
+ if (view.mode !== mode) setView({ mode, scrollTop: previewScrollTop.current })
187
+ }}
188
+ >
189
+ {filesT(mode === 'preview' ? 'previewMode' : 'sourceMode')}
190
+ </Button>
191
+ ))}
192
+ </div>
193
+ ) : null}
165
194
  </header>
166
195
  <div className="min-h-0 flex-1 overflow-hidden pb-[env(safe-area-inset-bottom)]">
167
196
  {target.imagePaths ? (
@@ -197,7 +226,16 @@ export function L2PluginStandaloneFilePreview({
197
226
  slides={[{ src: document.objectUrl, alt: target.path }]}
198
227
  ariaLabel={t('standaloneImage', { name: fileName(target.path) })}
199
228
  />
200
- ) : isHtml ? (
229
+ ) : previewKind === 'markdown' && view.mode === 'preview' ? (
230
+ <L3MarkdownPreview
231
+ content={document.content}
232
+ label={filesT('markdownPreview', { name: path })}
233
+ savedScrollTop={view.scrollTop}
234
+ onScroll={(scrollTop) => {
235
+ previewScrollTop.current = scrollTop
236
+ }}
237
+ />
238
+ ) : previewKind === 'html' ? (
201
239
  <iframe
202
240
  ref={iframeRef}
203
241
  className="block size-full border-0 bg-white"
@@ -210,8 +248,8 @@ export function L2PluginStandaloneFilePreview({
210
248
  path={target.path}
211
249
  content={document.content}
212
250
  size={document.size}
213
- savedState={null}
214
- onSaveState={() => undefined}
251
+ savedState={editorState}
252
+ onSaveState={(_path, state) => setEditorState(state)}
215
253
  onEscape={onClose}
216
254
  />
217
255
  )}
@@ -0,0 +1,57 @@
1
+ 'use client'
2
+
3
+ import { useCallback, useState } from 'react'
4
+ import { useTranslation } from 'react-i18next'
5
+ import type { L2WorkSessionListItem } from '@common/l2_biz/work-session/l2-work-session-contract'
6
+ import type { L2WorkbenchBiz } from '../l2-workbench-biz'
7
+
8
+ interface L2WorkSessionRename {
9
+ open: boolean
10
+ title: string
11
+ saving: boolean
12
+ error: string | null
13
+ show: (workSession: L2WorkSessionListItem) => void
14
+ close: () => void
15
+ setTitle: (title: string) => void
16
+ save: () => Promise<void>
17
+ }
18
+
19
+ export function useL2WorkSessionRename(
20
+ biz: Pick<L2WorkbenchBiz, 'renameWorkSession'>,
21
+ disabled: boolean
22
+ ): L2WorkSessionRename {
23
+ const { t } = useTranslation('workbench')
24
+ const [target, setTarget] = useState<Pick<L2WorkSessionListItem, 'workId' | 'sessionId'> | null>(
25
+ null
26
+ )
27
+ const [title, setTitle] = useState('')
28
+ const [saving, setSaving] = useState(false)
29
+ const [error, setError] = useState<string | null>(null)
30
+
31
+ const show = useCallback((workSession: L2WorkSessionListItem): void => {
32
+ setTarget({ workId: workSession.workId, sessionId: workSession.sessionId })
33
+ setTitle(workSession.sessionTitle ?? '')
34
+ setError(null)
35
+ }, [])
36
+
37
+ const close = (): void => {
38
+ if (!saving) setTarget(null)
39
+ }
40
+
41
+ const save = async (): Promise<void> => {
42
+ const trimmedTitle = title.trim()
43
+ if (!target || saving || disabled || !trimmedTitle) return
44
+ setSaving(true)
45
+ setError(null)
46
+ try {
47
+ await biz.renameWorkSession({ ...target, title: trimmedTitle })
48
+ setTarget(null)
49
+ } catch (cause) {
50
+ setError(cause instanceof Error ? cause.message : t('renameSessionFailed'))
51
+ } finally {
52
+ setSaving(false)
53
+ }
54
+ }
55
+
56
+ return { open: target !== null, title, saving, error, show, close, setTitle, save }
57
+ }
@@ -16,7 +16,6 @@ import type { L2ChatSource } from '@common/l2_biz/chat/l2-chat-contract'
16
16
  import type { L3CapabilityModeNames } from '@common/l3_modules/capability-modes/l3-capability-modes-contract'
17
17
  import type { L2WorkSessionListItem } from '@common/l2_biz/work-session/l2-work-session-contract'
18
18
  import { cn } from '@client/l4_foundation/lib/l4-utils'
19
- import { useL4WindowReveal } from '@client/l4_foundation/ui/l4-window-reveal'
20
19
  import {
21
20
  ResizableHandle,
22
21
  ResizablePanel,
@@ -52,7 +51,6 @@ import {
52
51
  import styles from './l2-work-session-columns.module.css'
53
52
  import motionStyles from './l2-workbench-motion.module.css'
54
53
  import { useL2WorkSessionColumnCapacity } from './hooks/l2-work-session-column-capacity'
55
- import { useL2WorkSessionColumnMotion } from './hooks/l2-work-session-column-motion'
56
54
  import type { L2FileWorkspaceRuntime } from './file-workspace/l2-file-workspace-runtime'
57
55
  import { L2WorkSessionFileLayout } from './file-workspace/l2-work-session-file-layout'
58
56
  import { Button, buttonVariants } from '@client/l4_foundation/ui/shadcn/button'
@@ -212,10 +210,6 @@ const WorkSessionColumn = memo(function WorkSessionColumn({
212
210
  }: WorkSessionColumnProps): React.JSX.Element {
213
211
  const { t } = useTranslation('workbench')
214
212
  const columnRef = useRef<HTMLElement>(null)
215
- useL4WindowReveal(
216
- columnRef,
217
- `${workSession.workId}:${workSession.sessionId}:${workSession.branchId}`
218
- )
219
213
  const initializationIssue = useL2WorkbenchInitializationIssue(workSession, chatRuntime)
220
214
  useSyncExternalStore(fileRuntime.subscribe, fileRuntime.getRevision, fileRuntime.getRevision)
221
215
  const fileWorkspace = fileRuntime.getWorkspace(workSession.workId)
@@ -566,11 +560,6 @@ export function L2WorkSessionColumns({
566
560
  const panelGroupRef = useGroupRef()
567
561
  const panelIdsJson = JSON.stringify(columnItems.map((item) => item.key))
568
562
  const columnModesKey = columnModes.map((mode) => (mode === 'expanded' ? 'e' : 'c')).join('')
569
- useL2WorkSessionColumnMotion(
570
- containerRef,
571
- `${panelIdsJson}:${columnModesKey}:${primaryWorkId}`,
572
- !mobile
573
- )
574
563
 
575
564
  useLayoutEffect(() => {
576
565
  const panelIds = JSON.parse(panelIdsJson) as string[]
@@ -25,6 +25,7 @@ import {
25
25
  MessageSquareTextIcon,
26
26
  PinIcon,
27
27
  PinOffIcon,
28
+ PencilIcon,
28
29
  PlusIcon,
29
30
  RefreshCwIcon,
30
31
  Repeat2Icon,
@@ -43,7 +44,10 @@ import {
43
44
  useState,
44
45
  type ReactNode
45
46
  } from 'react'
46
- import type { BrowserContributionIcon } from '@jetcrab/pi-desk-sdk/browser'
47
+ import type {
48
+ BrowserContributionIcon,
49
+ BrowserSessionSidebarHeaderAction
50
+ } from '@jetcrab/pi-desk-sdk/browser'
47
51
  import type { L2WorkSessionListItem } from '@common/l2_biz/work-session/l2-work-session-contract'
48
52
  import type { L3AppNotification } from '@common/l3_modules/app-runtime/l3-app-runtime-contract'
49
53
  import { copyL4BrowserText } from '@client/l4_foundation/lib/l4-browser-clipboard'
@@ -108,6 +112,7 @@ interface L2WorkSessionSidebarProps {
108
112
  mobile: boolean
109
113
  fileBrowser: ReactNode
110
114
  pluginTabContent: ReactNode
115
+ pluginHeaderActions?: readonly BrowserSessionSidebarHeaderAction[]
111
116
  pluginSessionTabs: readonly L2SidebarPluginSessionTab[]
112
117
  fileRefreshLoading: boolean
113
118
  canBrowseFiles: boolean
@@ -134,6 +139,7 @@ interface L2WorkSessionSidebarProps {
134
139
  onSelect: (workId: string) => void
135
140
  onTogglePin: (workId: string) => void
136
141
  onDelete: (workId: string) => void
142
+ onRename: (workSession: L2WorkSessionListItem) => void
137
143
  onArrangementChange: (arrangement: L2WorkSessionArrangement, movedWorkId: string) => void
138
144
  }
139
145
 
@@ -209,19 +215,22 @@ function SidebarHeaderGroup({
209
215
  className?: string
210
216
  }): React.JSX.Element {
211
217
  const { t } = useTranslation('workbench')
218
+ const overflow = appearance === 'action' && items.length > 3 ? items.slice(2) : []
219
+ const visibleItems = overflow.length > 0 ? items.slice(0, 2) : items
212
220
  return (
213
221
  <div
214
222
  className={cn('flex min-w-0 items-center gap-0', className)}
215
223
  role="group"
216
224
  aria-label={label}
217
225
  >
218
- {items.map((item) => (
226
+ {visibleItems.map((item) => (
219
227
  <button
220
228
  key={item.key}
221
229
  data-testid={item.testId}
222
230
  type="button"
223
231
  disabled={item.disabled}
224
232
  aria-pressed={item.pressed}
233
+ aria-busy={item.busy || undefined}
225
234
  aria-label={
226
235
  appearance === 'mode' ? t('showSidebarMode', { name: item.label }) : item.label
227
236
  }
@@ -243,6 +252,30 @@ function SidebarHeaderGroup({
243
252
  </span>
244
253
  </button>
245
254
  ))}
255
+ {overflow.length > 0 ? (
256
+ <DropdownMenu>
257
+ <DropdownMenuTrigger
258
+ render={
259
+ <button
260
+ type="button"
261
+ aria-label={label}
262
+ title={label}
263
+ className={SIDEBAR_HEADER_ACTION_BUTTON_CLASS}
264
+ >
265
+ <EllipsisIcon className="size-4" />
266
+ </button>
267
+ }
268
+ />
269
+ <DropdownMenuContent align="end">
270
+ {overflow.map((item) => (
271
+ <DropdownMenuItem key={item.key} disabled={item.disabled} onClick={item.onSelect}>
272
+ <span className="shrink-0 [&_svg]:size-4">{item.icon}</span>
273
+ {item.label}
274
+ </DropdownMenuItem>
275
+ ))}
276
+ </DropdownMenuContent>
277
+ </DropdownMenu>
278
+ ) : null}
246
279
  </div>
247
280
  )
248
281
  }
@@ -309,7 +342,8 @@ const SortableWorkSessionRow = memo(function SortableWorkSessionRow({
309
342
  now,
310
343
  onSelect,
311
344
  onTogglePin,
312
- onDelete
345
+ onDelete,
346
+ onRename
313
347
  }: {
314
348
  workSession: L2WorkSessionListItem
315
349
  mobile: boolean
@@ -322,7 +356,10 @@ const SortableWorkSessionRow = memo(function SortableWorkSessionRow({
322
356
  onSelect: (workId: string) => void
323
357
  onTogglePin: (workId: string) => void
324
358
  onDelete: (workId: string) => void
359
+ onRename: (workSession: L2WorkSessionListItem) => void
325
360
  }): React.JSX.Element {
361
+ const suppressTouchClick = useRef(false)
362
+ const lastPointer = useRef('')
326
363
  const actionsDisabled = disabled || ordering
327
364
  const {
328
365
  attributes,
@@ -518,9 +555,57 @@ const SortableWorkSessionRow = memo(function SortableWorkSessionRow({
518
555
  )
519
556
 
520
557
  return (
521
- <ContextMenu>
522
- <ContextMenuTrigger render={row} />
558
+ <ContextMenu
559
+ onOpenChange={(open, details) => {
560
+ if (open && (lastPointer.current === 'touch' || details.event.type.startsWith('touch'))) {
561
+ suppressTouchClick.current = true
562
+ }
563
+ }}
564
+ >
565
+ <ContextMenuTrigger
566
+ render={row}
567
+ onPointerDown={(event) => {
568
+ lastPointer.current = event.pointerType
569
+ suppressTouchClick.current = false
570
+ }}
571
+ onTouchEndCapture={(event) => {
572
+ // 长按打开菜单后,松手不能派生为选择会话的点击。
573
+ if (suppressTouchClick.current && event.cancelable) event.preventDefault()
574
+ }}
575
+ onClickCapture={(event) => {
576
+ if (!suppressTouchClick.current) return
577
+ event.preventDefault()
578
+ event.stopPropagation()
579
+ suppressTouchClick.current = false
580
+ }}
581
+ onKeyDownCapture={(event) => {
582
+ if (event.target !== event.currentTarget || event.nativeEvent.isComposing) return
583
+ lastPointer.current = 'keyboard'
584
+ suppressTouchClick.current = false
585
+ if (event.key !== 'ContextMenu' && !(event.key === 'F10' && event.shiftKey)) return
586
+ event.preventDefault()
587
+ event.stopPropagation()
588
+ const rect = event.currentTarget.getBoundingClientRect()
589
+ event.currentTarget.dispatchEvent(
590
+ new MouseEvent('contextmenu', {
591
+ bubbles: true,
592
+ cancelable: true,
593
+ button: 2,
594
+ clientX: rect.left + rect.width / 2,
595
+ clientY: rect.top + rect.height / 2
596
+ })
597
+ )
598
+ }}
599
+ />
523
600
  <ContextMenuContent>
601
+ <ContextMenuItem
602
+ data-testid={`work-session-rename-${workSession.workId}`}
603
+ disabled={actionsDisabled || deleting}
604
+ onClick={() => onRename(workSession)}
605
+ >
606
+ <PencilIcon />
607
+ {t('renameSessionTitle')}
608
+ </ContextMenuItem>
524
609
  <ContextMenuItem
525
610
  data-testid={`work-session-copy-project-path-${workSession.workId}`}
526
611
  onClick={copyProjectPath}
@@ -562,6 +647,7 @@ function L2WorkSessionSidebarComponent({
562
647
  mobile,
563
648
  fileBrowser,
564
649
  pluginTabContent,
650
+ pluginHeaderActions = [],
565
651
  pluginSessionTabs,
566
652
  fileRefreshLoading,
567
653
  canBrowseFiles,
@@ -588,6 +674,7 @@ function L2WorkSessionSidebarComponent({
588
674
  onSelect,
589
675
  onTogglePin,
590
676
  onDelete,
677
+ onRename,
591
678
  onArrangementChange
592
679
  }: L2WorkSessionSidebarProps): React.JSX.Element {
593
680
  const { t } = useTranslation('workbench')
@@ -696,7 +783,20 @@ function L2WorkSessionSidebarComponent({
696
783
  onSelect: onRefreshFiles
697
784
  }
698
785
  ]
699
- : []
786
+ : pluginHeaderActions.map((action, index) => ({
787
+ key: String(index),
788
+ label: action.label,
789
+ icon: action.busy ? (
790
+ <LoaderCircleIcon className="animate-spin" />
791
+ ) : (
792
+ <L4PluginIcon icon={action.icon} />
793
+ ),
794
+ disabled: action.disabled || action.busy,
795
+ busy: action.busy,
796
+ onSelect: () => {
797
+ void action.onSelect()
798
+ }
799
+ }))
700
800
 
701
801
  useLayoutEffect(() => {
702
802
  const container = shortcutContainerRef.current
@@ -787,6 +887,7 @@ function L2WorkSessionSidebarComponent({
787
887
  onSelect={onSelect}
788
888
  onTogglePin={onTogglePin}
789
889
  onDelete={onDelete}
890
+ onRename={onRename}
790
891
  />
791
892
  )
792
893
  })
@@ -40,6 +40,7 @@ import type {
40
40
  L2CreateWorkSessionRequest,
41
41
  L2CreateWorkSessionResponse,
42
42
  L2ReplaceWorkSessionRequest,
43
+ L2RenameWorkSessionRequest,
43
44
  L2SortWorkSessionsRequest,
44
45
  L2WorkSessionListResponse
45
46
  } from '@common/l2_biz/work-session/l2-work-session-contract'
@@ -110,6 +111,7 @@ export interface L2WorkbenchBiz {
110
111
  applyAppRuntimeUpdate: (input: L3AppRuntimeApplyRequest) => Promise<void>
111
112
  sortWorkSessions: (input: L2SortWorkSessionsRequest) => Promise<L2WorkSessionListResponse>
112
113
  deleteWorkSession: (workId: string) => Promise<L2WorkSessionListResponse>
114
+ renameWorkSession: (input: L2RenameWorkSessionRequest) => Promise<void>
113
115
  listDirectories: (forceRefresh: boolean) => Promise<L2PiDirectoryListResponse>
114
116
  listIgnoredDirectories: (forceRefresh: boolean) => Promise<L2PiDirectoryIgnoreListResponse>
115
117
  replaceDirectoryIgnore: (input: L2PiDirectoryIgnoreReplaceRequest) => Promise<void>
@@ -205,6 +207,9 @@ export function createL2WorkbenchBiz(
205
207
  request<L2WorkSessionListResponse>('/api/work-sessions/sort', input),
206
208
  deleteWorkSession: (workId) =>
207
209
  request<L2WorkSessionListResponse>('/api/work-sessions/del', { workId }),
210
+ async renameWorkSession(input): Promise<void> {
211
+ await request<Record<string, never>>('/api/work-sessions/rename', input)
212
+ },
208
213
  async listDirectories(forceRefresh): Promise<L2PiDirectoryListResponse> {
209
214
  const response = await request<L2PiDirectoryListResponse>('/api/pi/directories/list', {
210
215
  forceRefresh