@jetcrab/pi-desk 1.1.12 → 1.1.13-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 (315) hide show
  1. package/docs/plugins.md +21 -1
  2. package/package.json +2 -2
  3. package/src/app/api/work-sessions/rename/route.ts +1 -0
  4. package/src/client/l2_biz/auth/l2-login.tsx +1 -1
  5. package/src/client/l2_biz/plugin-host/l2-plugin-session-sidebar-tab.tsx +6 -2
  6. package/src/client/l2_biz/settings/l2-auth-settings.tsx +1 -1
  7. package/src/client/l2_biz/settings/views/l2-appearance-settings.tsx +1 -16
  8. package/src/client/l2_biz/task-center/l2-task-center.tsx +4 -30
  9. package/src/client/l2_biz/workbench/file-workspace/l2-plugin-standalone-file-preview.tsx +45 -7
  10. package/src/client/l2_biz/workbench/hooks/l2-work-session-rename.ts +57 -0
  11. package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +0 -11
  12. package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +107 -6
  13. package/src/client/l2_biz/workbench/l2-workbench-biz.ts +5 -0
  14. package/src/client/l2_biz/workbench/l2-workbench-chat-composer.tsx +333 -350
  15. package/src/client/l2_biz/workbench/l2-workbench.tsx +46 -1
  16. package/src/client/l2_biz/workbench/views/l2-work-session-rename-dialog.tsx +88 -0
  17. package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +81 -0
  18. package/src/client/l3_modules/project-files/l3-markdown-preview.tsx +52 -0
  19. package/src/client/l3_modules/project-files/l3-project-document-view.tsx +26 -8
  20. package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +16 -1
  21. package/src/client/l3_modules/project-files/l3-project-text-preview.ts +5 -0
  22. package/src/client/l3_modules/work-session-visual/l3-work-session-visual-effects.module.css +0 -36
  23. package/src/client/l3_modules/work-session-visual/l3-work-session-visual-view.tsx +0 -5
  24. package/src/client/l4_foundation/plugin-host/l4-plugin-host-runtime.ts +71 -1
  25. package/src/client/l4_foundation/styles/l4-globals.css +0 -19
  26. package/src/client/l4_foundation/ui/code/l4-code-preview.tsx +2 -1
  27. package/src/common/l2_biz/auth/l2-auth-contract.ts +2 -2
  28. package/src/common/l2_biz/auth/l2-auth-messages.ts +2 -2
  29. package/src/common/l2_biz/settings/l2-settings-messages.ts +0 -6
  30. package/src/common/l2_biz/work-session/l2-work-session-contract.ts +9 -0
  31. package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +6 -0
  32. package/src/common/l3_modules/project-files/l3-project-files-locale-messages.ts +4 -0
  33. package/src/common/l4_foundation/locale/l4-host-error-messages.ts +6 -0
  34. package/src/server/l1_entry/api/l1-work-session-rename-route.ts +52 -0
  35. package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +5 -0
  36. package/src/server/l2_biz/work-session/l2-work-session-manage.ts +13 -0
  37. package/src/server/l3_modules/work-session/l3-work-session.ts +4 -0
  38. package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +12 -1
  39. package/src/server/l4_foundation/pi/l4-pi-work-session-runtime.ts +5 -0
  40. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  41. package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +1 -0
  42. package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
  43. package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
  44. package/temp/build/pi-desk/release/.next/react-loadable-manifest.json +1 -2
  45. package/temp/build/pi-desk/release/.next/required-server-files.js +3 -3
  46. package/temp/build/pi-desk/release/.next/required-server-files.json +3 -3
  47. package/temp/build/pi-desk/release/.next/routes-manifest.json +6 -0
  48. package/temp/build/pi-desk/release/.next/server/app/_global-error/page.js +1 -1
  49. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  50. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  51. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +1 -1
  52. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  53. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  54. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  55. package/temp/build/pi-desk/release/.next/server/app/_not-found/page.js +1 -1
  56. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  57. package/temp/build/pi-desk/release/.next/server/app/api/auth/login/route.js +2 -2
  58. package/temp/build/pi-desk/release/.next/server/app/api/auth/logout/route.js +1 -1
  59. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/get/route.js +1 -1
  60. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/replace/route.js +1 -1
  61. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/get/route.js +1 -1
  62. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/replace/route.js +1 -1
  63. package/temp/build/pi-desk/release/.next/server/app/api/chat/context/get/route.js +1 -1
  64. package/temp/build/pi-desk/release/.next/server/app/api/chat/images/get/route.js +1 -1
  65. package/temp/build/pi-desk/release/.next/server/app/api/chat/messages/get/route.js +1 -1
  66. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  67. package/temp/build/pi-desk/release/.next/server/app/api/mcp-check/get/route.js +1 -1
  68. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/del/route.js +1 -1
  69. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/get/route.js +1 -1
  70. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/replace/route.js +1 -1
  71. package/temp/build/pi-desk/release/.next/server/app/api/model-catalog/list/route.js +1 -1
  72. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/get/route.js +1 -1
  73. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/replace/route.js +1 -1
  74. package/temp/build/pi-desk/release/.next/server/app/api/pi/directories/list/route.js +1 -1
  75. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-entries/list/route.js +1 -1
  76. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/list/route.js +1 -1
  77. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/replace/route.js +1 -1
  78. package/temp/build/pi-desk/release/.next/server/app/api/pi/models/list/route.js +1 -1
  79. package/temp/build/pi-desk/release/.next/server/app/api/pi/session-user-messages/list/route.js +1 -1
  80. package/temp/build/pi-desk/release/.next/server/app/api/pi/sessions/list/route.js +1 -1
  81. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/get/route.js +1 -1
  82. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/search/route.js +1 -1
  83. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-get/route.js +1 -1
  84. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-replace/route.js +1 -1
  85. package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
  86. package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
  87. package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
  88. package/temp/build/pi-desk/release/.next/server/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route.js +1 -1
  89. package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
  90. package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
  91. package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
  92. package/temp/build/pi-desk/release/.next/server/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route.js +1 -1
  93. package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
  94. package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
  95. package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
  96. package/temp/build/pi-desk/release/.next/server/app/api/project-files/get/route.js +1 -1
  97. package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +1 -1
  98. package/temp/build/pi-desk/release/.next/server/app/api/project-files/reveal/route.js +1 -1
  99. package/temp/build/pi-desk/release/.next/server/app/api/project-files/search/route.js +1 -1
  100. package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +1 -1
  101. package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +1 -1
  102. package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +1 -1
  103. package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +1 -1
  104. package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +1 -1
  105. package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +1 -1
  106. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/get/route.js +1 -1
  107. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/replace/route.js +1 -1
  108. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/get/route.js +1 -1
  109. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/list/route.js +1 -1
  110. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/replace/route.js +1 -1
  111. package/temp/build/pi-desk/release/.next/server/app/api/skills/list/route.js +1 -1
  112. package/temp/build/pi-desk/release/.next/server/app/api/task-center/images/get/route.js +1 -1
  113. package/temp/build/pi-desk/release/.next/server/app/api/task-center/messages/get/route.js +1 -1
  114. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/add/route.js +1 -1
  115. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/replace/route.js +1 -1
  116. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree/get/route.js +1 -1
  117. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree-entry/get/route.js +1 -1
  118. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/add/route.js +1 -1
  119. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/branch/route.js +1 -1
  120. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/del/route.js +1 -1
  121. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route.js +1 -0
  122. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route_client-reference-manifest.js +1 -0
  123. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/replace/route.js +1 -1
  124. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/sort/route.js +1 -1
  125. package/temp/build/pi-desk/release/.next/server/app/favicon.ico/route.js +1 -1
  126. package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
  127. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  128. package/temp/build/pi-desk/release/.next/server/app/page.js +80 -314
  129. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  130. package/temp/build/pi-desk/release/.next/server/app-paths-manifest.json +1 -0
  131. package/temp/build/pi-desk/release/.next/server/chunks/23054.js +1 -1
  132. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +8 -8
  133. package/temp/build/pi-desk/release/.next/server/chunks/33658.js +296 -0
  134. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +5 -5
  135. package/temp/build/pi-desk/release/.next/server/chunks/48180.js +1 -1
  136. package/temp/build/pi-desk/release/.next/server/chunks/49900.js +2 -2
  137. package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
  138. package/temp/build/pi-desk/release/.next/server/chunks/82499.js +3 -3
  139. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +3 -3
  140. package/temp/build/pi-desk/release/.next/server/chunks/94296.js +2 -2
  141. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  142. package/temp/build/pi-desk/release/.next/server/middleware-react-loadable-manifest.js +1 -1
  143. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  144. package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
  145. package/temp/build/pi-desk/release/.next/static/YdOQ7klRBI5tJb5NpDVLW/_buildManifest.js +1 -0
  146. package/temp/build/pi-desk/release/.next/static/chunks/31087-ba426d09d6f68bfd.js +1 -0
  147. package/temp/build/pi-desk/release/.next/static/chunks/39654-b5fedd762ea0312e.js +238 -0
  148. package/temp/build/pi-desk/release/.next/static/chunks/49516-cc4dcd84d64ab4fe.js +81 -0
  149. package/temp/build/pi-desk/release/.next/static/chunks/75130-d2ca74894aff8085.js +13 -0
  150. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-5137efe26947191b.js +1 -0
  151. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-5137efe26947191b.js +1 -0
  152. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-5137efe26947191b.js +1 -0
  153. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-5137efe26947191b.js +1 -0
  154. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-5137efe26947191b.js +1 -0
  155. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-5137efe26947191b.js +1 -0
  156. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-5137efe26947191b.js +1 -0
  157. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-5137efe26947191b.js +1 -0
  158. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-5137efe26947191b.js +1 -0
  159. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-5137efe26947191b.js +1 -0
  160. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-5137efe26947191b.js +1 -0
  161. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-5137efe26947191b.js +1 -0
  162. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-5137efe26947191b.js +1 -0
  163. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-5137efe26947191b.js +1 -0
  164. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-5137efe26947191b.js +1 -0
  165. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-5137efe26947191b.js +1 -0
  166. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-5137efe26947191b.js +1 -0
  167. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-5137efe26947191b.js +1 -0
  168. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-5137efe26947191b.js +1 -0
  169. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-5137efe26947191b.js +1 -0
  170. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-5137efe26947191b.js +1 -0
  171. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-5137efe26947191b.js +1 -0
  172. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-5137efe26947191b.js +1 -0
  173. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-5137efe26947191b.js +1 -0
  174. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-5137efe26947191b.js +1 -0
  175. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-5137efe26947191b.js +1 -0
  176. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-5137efe26947191b.js +1 -0
  177. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-5137efe26947191b.js +1 -0
  178. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-5137efe26947191b.js +1 -0
  179. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-5137efe26947191b.js +1 -0
  180. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-5137efe26947191b.js +1 -0
  181. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-5137efe26947191b.js +1 -0
  182. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-5137efe26947191b.js +1 -0
  183. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-5137efe26947191b.js +1 -0
  184. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-5137efe26947191b.js +1 -0
  185. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-5137efe26947191b.js +1 -0
  186. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-5137efe26947191b.js +1 -0
  187. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-5137efe26947191b.js +1 -0
  188. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-5137efe26947191b.js +1 -0
  189. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-5137efe26947191b.js +1 -0
  190. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-5137efe26947191b.js +1 -0
  191. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-5137efe26947191b.js +1 -0
  192. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-5137efe26947191b.js +1 -0
  193. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-5137efe26947191b.js +1 -0
  194. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-5137efe26947191b.js +1 -0
  195. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-5137efe26947191b.js +1 -0
  196. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-5137efe26947191b.js +1 -0
  197. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-5137efe26947191b.js +1 -0
  198. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-5137efe26947191b.js +1 -0
  199. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-5137efe26947191b.js +1 -0
  200. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-5137efe26947191b.js +1 -0
  201. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-5137efe26947191b.js +1 -0
  202. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-5137efe26947191b.js +1 -0
  203. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-5137efe26947191b.js +1 -0
  204. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-5137efe26947191b.js +1 -0
  205. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-5137efe26947191b.js +1 -0
  206. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-5137efe26947191b.js +1 -0
  207. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-5137efe26947191b.js +1 -0
  208. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-5137efe26947191b.js +1 -0
  209. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-5137efe26947191b.js +1 -0
  210. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-5137efe26947191b.js +1 -0
  211. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-5137efe26947191b.js +1 -0
  212. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-5137efe26947191b.js +1 -0
  213. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-5137efe26947191b.js +1 -0
  214. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-5137efe26947191b.js +1 -0
  215. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-5137efe26947191b.js +1 -0
  216. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/rename/route-5137efe26947191b.js +1 -0
  217. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-5137efe26947191b.js +1 -0
  218. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-5137efe26947191b.js +1 -0
  219. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-358978b7cfe69a5f.js +3 -0
  220. package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-84892b06243891f0.js +1 -0
  221. package/temp/build/pi-desk/release/.next/static/chunks/app/page-cc05e71bf51adb57.js +158 -0
  222. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-5137efe26947191b.js +1 -0
  223. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-5137efe26947191b.js +1 -0
  224. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-5137efe26947191b.js +1 -0
  225. package/temp/build/pi-desk/release/.next/static/chunks/webpack-40a782fc8a3535b9.js +1 -0
  226. package/temp/build/pi-desk/release/.next/static/css/095a062e18f96657.css +1 -0
  227. package/temp/build/pi-desk/release/.next/static/css/{adb1d4e48dd43c0a.css → 949d0d1a99d5de92.css} +1 -1
  228. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  229. package/src/client/l2_biz/workbench/hooks/l2-work-session-column-motion.ts +0 -87
  230. package/src/client/l3_modules/work-session-visual/l3-work-session-status-border.tsx +0 -66
  231. package/src/client/l4_foundation/ui/l4-power-saving.ts +0 -45
  232. package/src/client/l4_foundation/ui/l4-window-reveal.ts +0 -30
  233. package/temp/build/pi-desk/release/.next/server/chunks/56284.js +0 -62
  234. package/temp/build/pi-desk/release/.next/static/96geGVI-j_dC6I3k-XFCB/_buildManifest.js +0 -1
  235. package/temp/build/pi-desk/release/.next/static/chunks/31087-333cae396a52f232.js +0 -1
  236. package/temp/build/pi-desk/release/.next/static/chunks/45992-92d8b8b10fcfbb6b.js +0 -13
  237. package/temp/build/pi-desk/release/.next/static/chunks/47340-c1c09c77c1a88514.js +0 -318
  238. package/temp/build/pi-desk/release/.next/static/chunks/57208-d6d38167dabb91e4.js +0 -1
  239. package/temp/build/pi-desk/release/.next/static/chunks/app/_global-error/page-dde4fd973791f7f7.js +0 -1
  240. package/temp/build/pi-desk/release/.next/static/chunks/app/_not-found/page-dde4fd973791f7f7.js +0 -1
  241. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/login/route-dde4fd973791f7f7.js +0 -1
  242. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth/logout/route-dde4fd973791f7f7.js +0 -1
  243. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/get/route-dde4fd973791f7f7.js +0 -1
  244. package/temp/build/pi-desk/release/.next/static/chunks/app/api/auth-settings/replace/route-dde4fd973791f7f7.js +0 -1
  245. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/get/route-dde4fd973791f7f7.js +0 -1
  246. package/temp/build/pi-desk/release/.next/static/chunks/app/api/capability-modes/replace/route-dde4fd973791f7f7.js +0 -1
  247. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/context/get/route-dde4fd973791f7f7.js +0 -1
  248. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/images/get/route-dde4fd973791f7f7.js +0 -1
  249. package/temp/build/pi-desk/release/.next/static/chunks/app/api/chat/messages/get/route-dde4fd973791f7f7.js +0 -1
  250. package/temp/build/pi-desk/release/.next/static/chunks/app/api/health/route-dde4fd973791f7f7.js +0 -1
  251. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-check/get/route-dde4fd973791f7f7.js +0 -1
  252. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/del/route-dde4fd973791f7f7.js +0 -1
  253. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/get/route-dde4fd973791f7f7.js +0 -1
  254. package/temp/build/pi-desk/release/.next/static/chunks/app/api/mcp-settings/replace/route-dde4fd973791f7f7.js +0 -1
  255. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-catalog/list/route-dde4fd973791f7f7.js +0 -1
  256. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/get/route-dde4fd973791f7f7.js +0 -1
  257. package/temp/build/pi-desk/release/.next/static/chunks/app/api/model-settings/replace/route-dde4fd973791f7f7.js +0 -1
  258. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directories/list/route-dde4fd973791f7f7.js +0 -1
  259. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-entries/list/route-dde4fd973791f7f7.js +0 -1
  260. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/list/route-dde4fd973791f7f7.js +0 -1
  261. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/directory-ignores/replace/route-dde4fd973791f7f7.js +0 -1
  262. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/models/list/route-dde4fd973791f7f7.js +0 -1
  263. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/session-user-messages/list/route-dde4fd973791f7f7.js +0 -1
  264. package/temp/build/pi-desk/release/.next/static/chunks/app/api/pi/sessions/list/route-dde4fd973791f7f7.js +0 -1
  265. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/get/route-dde4fd973791f7f7.js +0 -1
  266. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/search/route-dde4fd973791f7f7.js +0 -1
  267. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-get/route-dde4fd973791f7f7.js +0 -1
  268. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugin-catalog/settings-replace/route-dde4fd973791f7f7.js +0 -1
  269. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/add/route-dde4fd973791f7f7.js +0 -1
  270. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/apply/route-dde4fd973791f7f7.js +0 -1
  271. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/batch/route-dde4fd973791f7f7.js +0 -1
  272. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route-dde4fd973791f7f7.js +0 -1
  273. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/del/route-dde4fd973791f7f7.js +0 -1
  274. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/enabled-set/route-dde4fd973791f7f7.js +0 -1
  275. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/get/route-dde4fd973791f7f7.js +0 -1
  276. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route-dde4fd973791f7f7.js +0 -1
  277. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/list/route-dde4fd973791f7f7.js +0 -1
  278. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/reload/route-dde4fd973791f7f7.js +0 -1
  279. package/temp/build/pi-desk/release/.next/static/chunks/app/api/plugins/update/route-dde4fd973791f7f7.js +0 -1
  280. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/get/route-dde4fd973791f7f7.js +0 -1
  281. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/list/route-dde4fd973791f7f7.js +0 -1
  282. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/reveal/route-dde4fd973791f7f7.js +0 -1
  283. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-files/search/route-dde4fd973791f7f7.js +0 -1
  284. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git/get/route-dde4fd973791f7f7.js +0 -1
  285. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-branches/list/route-dde4fd973791f7f7.js +0 -1
  286. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-changes/list/route-dde4fd973791f7f7.js +0 -1
  287. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-diff/get/route-dde4fd973791f7f7.js +0 -1
  288. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-heads/get/route-dde4fd973791f7f7.js +0 -1
  289. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-git-log/list/route-dde4fd973791f7f7.js +0 -1
  290. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/get/route-dde4fd973791f7f7.js +0 -1
  291. package/temp/build/pi-desk/release/.next/static/chunks/app/api/project-model-default/replace/route-dde4fd973791f7f7.js +0 -1
  292. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/get/route-dde4fd973791f7f7.js +0 -1
  293. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/list/route-dde4fd973791f7f7.js +0 -1
  294. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skill-files/replace/route-dde4fd973791f7f7.js +0 -1
  295. package/temp/build/pi-desk/release/.next/static/chunks/app/api/skills/list/route-dde4fd973791f7f7.js +0 -1
  296. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/images/get/route-dde4fd973791f7f7.js +0 -1
  297. package/temp/build/pi-desk/release/.next/static/chunks/app/api/task-center/messages/get/route-dde4fd973791f7f7.js +0 -1
  298. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/add/route-dde4fd973791f7f7.js +0 -1
  299. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-git-branch/replace/route-dde4fd973791f7f7.js +0 -1
  300. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree/get/route-dde4fd973791f7f7.js +0 -1
  301. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-session-tree-entry/get/route-dde4fd973791f7f7.js +0 -1
  302. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/add/route-dde4fd973791f7f7.js +0 -1
  303. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/branch/route-dde4fd973791f7f7.js +0 -1
  304. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/del/route-dde4fd973791f7f7.js +0 -1
  305. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/replace/route-dde4fd973791f7f7.js +0 -1
  306. package/temp/build/pi-desk/release/.next/static/chunks/app/api/work-sessions/sort/route-dde4fd973791f7f7.js +0 -1
  307. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-839162b6cfae8347.js +0 -3
  308. package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-4532a3bbee48e219.js +0 -1
  309. package/temp/build/pi-desk/release/.next/static/chunks/app/page-4b6367cde5c04597.js +0 -158
  310. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/app-error-dde4fd973791f7f7.js +0 -1
  311. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/forbidden-dde4fd973791f7f7.js +0 -1
  312. package/temp/build/pi-desk/release/.next/static/chunks/next/dist/client/components/builtin/unauthorized-dde4fd973791f7f7.js +0 -1
  313. package/temp/build/pi-desk/release/.next/static/chunks/webpack-735430d61da52e9d.js +0 -1
  314. package/temp/build/pi-desk/release/.next/static/css/4a5dda7ff3a82c4a.css +0 -1
  315. /package/temp/build/pi-desk/release/.next/static/{96geGVI-j_dC6I3k-XFCB → YdOQ7klRBI5tJb5NpDVLW}/_ssgManifest.js +0 -0
package/docs/plugins.md CHANGED
@@ -77,7 +77,7 @@ plugin.addPreviewDirectory(directory, { default: true })
77
77
 
78
78
  `directory` 为服务端绝对目录;省略第二个参数只登记,`default: true` 同时设为默认预览目录,后登记的默认生效。原 CWD 始终可选;目录规范化后去重,最多登记 32 个。重复快照不会覆盖用户的手动选择。登记只在当前会话运行态内,插件在 `session_start`、`session_tree` 从自身数据恢复后重新登记;不要在普通查询时重复请求默认选择。
79
79
 
80
- 调用不等待回执;非法路径或超限由宿主拒绝并记日志,实际目录内容按需读取。旧宿主或独立 Pi 不处理该登记;兼容旧 SDK 时使用 `plugin.addPreviewDirectory?.(...)`。`files.preview/reveal` 支持会话 CWD 下规范相对路径或服务端绝对文件路径(包括项目外文件);`preview` 的 `imagePaths` 使用相同路径规则。宿主仍校验当前 Source,目录浏览边界不变。依赖项目外文件的插件需要同步更新宿主,旧宿主只接受项目内相对路径。`readImage` 仍只接受会话 CWD 下规范相对路径。
80
+ 调用不等待回执;非法路径或超限由宿主拒绝并记日志,实际目录内容按需读取。旧宿主或独立 Pi 不处理该登记;兼容旧 SDK 时使用 `plugin.addPreviewDirectory?.(...)`。`files.preview/reveal` 支持会话 CWD 下规范相对路径或服务端绝对文件路径(包括项目外文件);`preview` 的 `imagePaths` 使用相同路径规则。宿主仍校验当前 Source,目录浏览边界不变。依赖项目外文件的插件需要同步更新宿主,旧宿主只接受项目内相对路径。`readImage` 仍只接受会话 CWD 下规范相对路径。`.md`、`.markdown` 在宿主文件查看器中默认以 Markdown 排版预览,可点击“源码”切换;会话文件视图与 `mode: 'standalone'` 独立查看器均支持,插件无需增加参数或自行渲染。
81
81
 
82
82
  ## Browser Entry 与懒界面
83
83
 
@@ -105,6 +105,26 @@ Application 使用 `chrome: 'host'` 让宿主负责 Dialog、标题、关闭、
105
105
 
106
106
  界面继承宿主明暗主题与字号,布局使用 `rem`、合理内边距和自身滚动;窄屏与触控可用,不以裁切或只靠 hover 隐藏必要操作。按钮、表单、加载/错误/重试优先复用 `/react/base`;需要 Markdown 时才加载 `/react/markdown`。
107
107
 
108
+ ### 侧栏顶部操作
109
+
110
+ `session-sidebar-tab` 的 Lazy `mount({ target, host })` 内可为当前 Tab 设置顶部右侧按钮:
111
+
112
+ ```ts
113
+ target.setHeaderActions?.([
114
+ {
115
+ label: '预览项目',
116
+ icon: { type: 'builtin', name: 'folder' },
117
+ onSelect: () => host.projects.preview(target.cwd)
118
+ }
119
+ ])
120
+ ```
121
+
122
+ 每次调用整体替换,`[]` 清空。按钮使用 `label` 作为可访问名称和提示,`icon` 复用 Contribution 图标;可选 `disabled` 禁用,`busy` 显示忙碌并禁用。状态变化时重新设置完整列表,不修改已提交对象。宿主保持列表顺序,超过三个操作时保留前两个,其余收进菜单。
123
+
124
+ `onSelect` 可返回 `Promise<void>`;同一按钮回调尚未完成时不重复执行,异常由宿主记录并在当前挂载仍有效时提示。插件负责业务加载状态和结果展示;请求已经产生的副作用不因 Tab 关闭而回滚。
125
+
126
+ 按钮只属于当前挂载,切换 Tab、关闭侧栏/移动抽屉、Source 或 CWD 变化、挂载失败及插件重载时自动清空;旧按钮、迟到更新和旧 disposer 均不能操作新挂载。旧宿主可能没有此方法,使用可选调用,不自行访问宿主 DOM。`PluginPanelHeader.actions` 仍只作用于插件内容区标题,不是此顶栏入口。
127
+
108
128
  ## 通信、通知与后台
109
129
 
110
130
  Browser Method 示例:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jetcrab/pi-desk",
3
- "version": "1.1.12",
3
+ "version": "1.1.13-dev",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -69,7 +69,7 @@
69
69
  "viewerjs": "^1.11.8",
70
70
  "ws": "^8.21.3",
71
71
  "zod": "^4.4.3",
72
- "@jetcrab/pi-desk-sdk": "^1.1.3"
72
+ "@jetcrab/pi-desk-sdk": "^1.1.4-dev"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@earendil-works/pi-agent-core": "1.2.0",
@@ -0,0 +1 @@
1
+ export { POST } from '@server/l1_entry/api/l1-work-session-rename-route'
@@ -96,7 +96,7 @@ export function L2Login(): React.JSX.Element {
96
96
  name="password"
97
97
  value={password}
98
98
  autoComplete="current-password"
99
- maxLength={256}
99
+ maxLength={64}
100
100
  disabled={submitting}
101
101
  aria-describedby={error ? 'login-error' : undefined}
102
102
  onChange={(event) => setPassword(event.target.value)}
@@ -2,6 +2,7 @@
2
2
 
3
3
  import type {
4
4
  BrowserFilePreviewOptions,
5
+ BrowserSessionSidebarHeaderAction,
5
6
  BrowserSessionSidebarTabTarget,
6
7
  PluginSource
7
8
  } from '@jetcrab/pi-desk-sdk/browser'
@@ -15,6 +16,7 @@ interface L2PluginSessionSidebarTabProps {
15
16
  cwd: string
16
17
  onPreviewFile: (path: string, options?: BrowserFilePreviewOptions) => void
17
18
  onRevealFile: (path: string) => Promise<void>
19
+ onHeaderActionsChange: (actions: readonly BrowserSessionSidebarHeaderAction[]) => void
18
20
  }
19
21
 
20
22
  export function L2PluginSessionSidebarTab({
@@ -23,13 +25,15 @@ export function L2PluginSessionSidebarTab({
23
25
  source,
24
26
  cwd,
25
27
  onPreviewFile,
26
- onRevealFile
28
+ onRevealFile,
29
+ onHeaderActionsChange
27
30
  }: L2PluginSessionSidebarTabProps): React.JSX.Element {
28
31
  const target: BrowserSessionSidebarTabTarget = {
29
32
  kind: 'session-sidebar-tab',
30
33
  source,
31
34
  cwd,
32
- files: { preview: onPreviewFile, reveal: onRevealFile }
35
+ files: { preview: onPreviewFile, reveal: onRevealFile },
36
+ setHeaderActions: onHeaderActionsChange
33
37
  }
34
38
  const targetKey = `${source.workId}\u0000${source.sessionId}\u0000${source.branchId}\u0000${cwd}`
35
39
 
@@ -99,7 +99,7 @@ export function L2AuthSettings(): React.JSX.Element {
99
99
  className="[&::-ms-reveal]:hidden"
100
100
  autoComplete="new-password"
101
101
  minLength={12}
102
- maxLength={256}
102
+ maxLength={64}
103
103
  required
104
104
  disabled={busy}
105
105
  value={state.password}
@@ -17,7 +17,6 @@ import {
17
17
  subscribeL4DisplaySize
18
18
  } from '@client/l4_foundation/ui/l4-display-size-provider'
19
19
  import { L3ConversationMarkdown } from '@client/l3_modules/conversation/l3-conversation-markdown'
20
- import { saveL4PowerSaving, useL4PowerSaving } from '@client/l4_foundation/ui/l4-power-saving'
21
20
 
22
21
  const THEME_OPTIONS = [
23
22
  { value: 'system', label: 'common:system', icon: MonitorIcon },
@@ -34,7 +33,6 @@ const DISPLAY_SIZE_OPTIONS = [
34
33
  export function L2AppearanceSettings(): React.JSX.Element {
35
34
  const { t } = useTranslation('settings')
36
35
  const theme = useSyncExternalStore(subscribeL4Theme, readL4Theme, () => L4_DEFAULT_THEME)
37
- const powerSaving = useL4PowerSaving()
38
36
  const size = useSyncExternalStore(
39
37
  subscribeL4DisplaySize,
40
38
  readL4DisplaySize,
@@ -58,7 +56,7 @@ export function L2AppearanceSettings(): React.JSX.Element {
58
56
  onChange={saveL4Theme}
59
57
  />
60
58
  </div>
61
- <div className="space-y-2 border-b pb-4">
59
+ <div className="space-y-2">
62
60
  <h3 className="text-sm font-medium">{t('displaySize')}</h3>
63
61
  <L4ChoiceGroup<L4DisplaySize>
64
62
  label={t('displaySize')}
@@ -71,19 +69,6 @@ export function L2AppearanceSettings(): React.JSX.Element {
71
69
  onChange={saveL4DisplaySize}
72
70
  />
73
71
  </div>
74
- <div className="space-y-2">
75
- <h3 className="text-sm font-medium">{t('powerSaving')}</h3>
76
- <L4ChoiceGroup<'off' | 'on'>
77
- label={t('powerSaving')}
78
- layout="segmented"
79
- value={powerSaving ? 'on' : 'off'}
80
- options={[
81
- { value: 'off', label: t('powerSavingOff'), testId: 'power-saving-off' },
82
- { value: 'on', label: t('powerSavingOn'), testId: 'power-saving-on' }
83
- ]}
84
- onChange={(value) => saveL4PowerSaving(value === 'on')}
85
- />
86
- </div>
87
72
  </div>
88
73
  <div className="min-w-0 space-y-2">
89
74
  <h3 className="text-sm font-medium">{t('displayPreview')}</h3>
@@ -14,7 +14,7 @@ import {
14
14
  XCircleIcon,
15
15
  XIcon
16
16
  } from 'lucide-react'
17
- import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from 'react'
17
+ import { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from 'react'
18
18
  import { useTranslation } from 'react-i18next'
19
19
  import {
20
20
  type L2TaskDetailBody,
@@ -50,7 +50,6 @@ import {
50
50
  } from '@client/l3_modules/conversation/l3-conversation-messages'
51
51
  import { L3ConversationTailSpacerObserver } from '@client/l3_modules/conversation/l3-conversation-viewport'
52
52
  import { useL4AppToast } from '@client/l4_foundation/ui/l4-app-toast'
53
- import { useL4WindowReveal } from '@client/l4_foundation/ui/l4-window-reveal'
54
53
  import type { L2TaskCenterRuntime } from './l2-task-center-runtime'
55
54
 
56
55
  interface L2TaskCenterProps {
@@ -443,8 +442,6 @@ function TaskCenterPanel({
443
442
  }, [runtime])
444
443
  useSyncExternalStore(runtime.subscribe, getPanelSnapshot, getPanelSnapshot)
445
444
  const state = runtime.getState()
446
- const closeButtonRef = useRef<HTMLButtonElement>(null)
447
- const desktopCloseButtonRef = useRef<HTMLButtonElement>(null)
448
445
  const [mobileDetail, setMobileDetail] = useState(false)
449
446
  const selectedTask = tasks.find((task) => task.taskId === state.selectedTaskId) ?? null
450
447
 
@@ -455,17 +452,6 @@ function TaskCenterPanel({
455
452
 
456
453
  const showMobileDetail = mobileDetail && state.selectedTaskId !== null
457
454
  const panelOpen = state.open && sameSource(state.source, source)
458
- const listRef = useRef<HTMLDivElement>(null)
459
- const detailRef = useRef<HTMLDivElement>(null)
460
- useL4WindowReveal(listRef, panelOpen && !showMobileDetail ? 'task-list' : null)
461
- useL4WindowReveal(
462
- detailRef,
463
- panelOpen ? `${state.selectedTaskId ?? 'no-task'}:${showMobileDetail}` : null
464
- )
465
-
466
- if (!state.open || !sameSource(state.source, source) || typeof document === 'undefined') {
467
- return null
468
- }
469
455
 
470
456
  const select = (taskId: string): void => {
471
457
  runtime.selectTask(taskId)
@@ -474,23 +460,17 @@ function TaskCenterPanel({
474
460
 
475
461
  return (
476
462
  <L4AppDialogRoot
477
- open
463
+ open={panelOpen}
478
464
  onOpenChange={(open) => {
479
465
  if (!open) runtime.close()
480
466
  }}
481
467
  >
482
468
  <L4AppDialogContent
483
469
  aria-label={t('title')}
484
- initialFocus={() =>
485
- desktopCloseButtonRef.current?.getClientRects().length
486
- ? desktopCloseButtonRef.current
487
- : closeButtonRef.current
488
- }
489
470
  showCloseButton={false}
490
- className="h-[calc(100dvh-2rem)] max-w-[70rem] flex-row bg-background data-open:animate-none max-lg:h-dvh max-lg:max-h-dvh max-lg:w-dvw max-lg:max-w-none max-lg:rounded-none max-lg:border-0"
471
+ className="h-[calc(100dvh-2rem)] max-w-[70rem] flex-row bg-background max-lg:h-dvh max-lg:max-h-dvh max-lg:w-dvw max-lg:max-w-none max-lg:rounded-none max-lg:border-0"
491
472
  >
492
473
  <div
493
- ref={listRef}
494
474
  className={cn(
495
475
  'flex min-w-0 flex-1 flex-col border-r bg-sidebar lg:max-w-80',
496
476
  showMobileDetail && 'hidden lg:flex'
@@ -505,7 +485,6 @@ function TaskCenterPanel({
505
485
  </p>
506
486
  </div>
507
487
  <Button
508
- ref={showMobileDetail ? undefined : closeButtonRef}
509
488
  className="lg:hidden"
510
489
  type="button"
511
490
  variant="ghost"
@@ -576,10 +555,7 @@ function TaskCenterPanel({
576
555
  </div>
577
556
  </div>
578
557
 
579
- <div
580
- ref={detailRef}
581
- className={cn('min-w-0 flex-1', !showMobileDetail && 'hidden lg:block')}
582
- >
558
+ <div className={cn('min-w-0 flex-1', !showMobileDetail && 'hidden lg:block')}>
583
559
  <div className="flex h-full min-h-0 flex-col">
584
560
  <div className="flex min-h-12 items-center gap-2 border-b bg-muted/10 px-3 lg:hidden">
585
561
  <Button
@@ -595,7 +571,6 @@ function TaskCenterPanel({
595
571
  {selectedTask?.title ?? t('detail')}
596
572
  </span>
597
573
  <Button
598
- ref={showMobileDetail ? closeButtonRef : undefined}
599
574
  type="button"
600
575
  variant="ghost"
601
576
  size="icon"
@@ -616,7 +591,6 @@ function TaskCenterPanel({
616
591
  </div>
617
592
  </div>
618
593
  <Button
619
- ref={desktopCloseButtonRef}
620
594
  className="absolute right-4 top-3 z-10 hidden lg:inline-flex"
621
595
  type="button"
622
596
  variant="ghost"
@@ -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
  })