@jetcrab/pi-desk 1.1.18-dev → 1.1.21

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 (250) hide show
  1. package/docs/plugins.md +82 -2
  2. package/next.config.ts +1 -0
  3. package/package.json +4 -3
  4. package/src/app/page.tsx +6 -1
  5. package/src/app/project-preview/page.tsx +10 -0
  6. package/src/client/l1_entry/pages/l1-home-page.tsx +30 -0
  7. package/src/client/l1_entry/pages/l1-project-preview-page.tsx +33 -0
  8. package/src/client/l1_entry/providers/l1-app-providers.tsx +18 -15
  9. package/src/client/l1_entry/providers/l1-app-runtime-provider.tsx +2 -2
  10. package/src/client/l2_biz/auth/l2-login-biz.ts +3 -0
  11. package/src/client/l2_biz/auth/l2-login.tsx +2 -3
  12. package/src/client/l2_biz/plugin-host/l2-plugin-capability-details.tsx +6 -1
  13. package/src/client/l2_biz/plugin-host/l2-plugin-contribution-host.tsx +71 -10
  14. package/src/client/l2_biz/plugin-host/l2-plugin-management-controls.tsx +9 -0
  15. package/src/client/l2_biz/plugin-host/l2-plugin-session-header-layout.ts +18 -0
  16. package/src/client/l2_biz/plugin-host/l2-plugin-session-header.tsx +247 -0
  17. package/src/client/l2_biz/plugin-host/l2-plugin-widgets.tsx +50 -0
  18. package/src/client/l2_biz/plugin-host/views/l2-plugin-session-header-action.tsx +112 -0
  19. package/src/client/l2_biz/project-preview/hooks/l2-use-project-picker.ts +76 -0
  20. package/src/client/l2_biz/project-preview/hooks/l2-use-project-preview.ts +214 -0
  21. package/src/client/l2_biz/project-preview/l2-project-preview-biz.ts +49 -4
  22. package/src/client/l2_biz/project-preview/l2-project-preview-dialog.tsx +42 -450
  23. package/src/client/l2_biz/project-preview/l2-project-preview-page.tsx +61 -0
  24. package/src/client/l2_biz/project-preview/l2-project-preview.tsx +342 -0
  25. package/src/client/l2_biz/project-preview/runtime/l2-project-history-runtime.ts +9 -3
  26. package/src/client/l2_biz/project-preview/views/l2-project-picker.tsx +168 -0
  27. package/src/client/l2_biz/settings/hooks/l2-use-model-settings.ts +34 -31
  28. package/src/client/l2_biz/settings/views/l2-model-replacement-preview.tsx +7 -1
  29. package/src/client/l2_biz/workbench/file-workspace/l2-file-workspace-runtime.ts +1 -1
  30. package/src/client/l2_biz/workbench/file-workspace/l2-project-preview-biz.ts +4 -3
  31. package/src/client/l2_biz/workbench/hooks/l2-workbench-chat-reload.ts +42 -0
  32. package/src/client/l2_biz/workbench/hooks/l2-workbench-chat-viewport.ts +28 -21
  33. package/src/client/l2_biz/workbench/l2-work-session-columns.module.css +32 -0
  34. package/src/client/l2_biz/workbench/l2-work-session-columns.tsx +55 -16
  35. package/src/client/l2_biz/workbench/l2-work-session-sidebar.tsx +38 -9
  36. package/src/client/l2_biz/workbench/l2-workbench-chat-composer.tsx +12 -1
  37. package/src/client/l2_biz/workbench/l2-workbench-chat.ts +45 -0
  38. package/src/client/l2_biz/workbench/l2-workbench-initialization-notice.tsx +8 -3
  39. package/src/client/l2_biz/workbench/l2-workbench-plugin-slots.ts +13 -0
  40. package/src/client/l2_biz/workbench/l2-workbench.tsx +19 -2
  41. package/src/client/l3_modules/conversation/l3-conversation-markdown.tsx +10 -1
  42. package/src/client/l3_modules/conversation/l3-conversation-viewport.tsx +12 -6
  43. package/src/client/l3_modules/project-files/l3-markdown-preview.module.css +1 -1
  44. package/src/client/l3_modules/project-files/l3-markdown-preview.tsx +10 -1
  45. package/src/client/l3_modules/project-files/l3-project-document-git.ts +4 -3
  46. package/src/client/l3_modules/project-files/l3-project-document-view.tsx +6 -1
  47. package/src/client/l3_modules/project-files/l3-project-file-browser.tsx +171 -229
  48. package/src/client/l3_modules/project-files/l3-project-file-runtime.ts +133 -70
  49. package/src/client/l3_modules/project-files/l3-project-reader.ts +26 -37
  50. package/src/client/l3_modules/project-files/views/l3-project-search-controls.tsx +201 -0
  51. package/src/client/l3_modules/project-files/views/l3-project-search-results.tsx +333 -0
  52. package/src/client/l4_foundation/lib/l4-client-id.tsx +11 -0
  53. package/src/client/l4_foundation/plugin-host/l4-plugin-host-runtime.ts +316 -35
  54. package/src/client/l4_foundation/ui/code/l4-code-preview.tsx +47 -3
  55. package/src/client/l4_foundation/ui/markdown/l4-markdown-remark.ts +89 -0
  56. package/src/client/l4_foundation/ui/markdown/l4-markdown.module.css +58 -0
  57. package/src/client/l4_foundation/ui/markdown/l4-markdown.tsx +108 -0
  58. package/src/common/l2_biz/auth/l2-auth-return-to.ts +41 -0
  59. package/src/common/l2_biz/model-settings/l2-model-settings-contract.ts +5 -1
  60. package/src/common/l2_biz/plugin/l2-plugin-management-messages.ts +4 -0
  61. package/src/common/l2_biz/project-preview/l2-project-history-messages.ts +28 -0
  62. package/src/common/l2_biz/project-preview/l2-project-preview-navigation.ts +5 -0
  63. package/src/common/l2_biz/settings/l2-settings-messages.ts +4 -3
  64. package/src/common/l2_biz/work-session/l2-work-session-file-contract.ts +4 -3
  65. package/src/common/l2_biz/workbench/l2-workbench-locale-messages.ts +8 -0
  66. package/src/common/l3_modules/project-files/l3-project-files-contract.ts +2 -3
  67. package/src/common/l3_modules/project-files/l3-project-files-locale-messages.ts +56 -10
  68. package/src/common/l4_foundation/file/l4-project-file-contract.ts +51 -1
  69. package/src/common/l4_foundation/locale/l4-host-error-messages.ts +11 -0
  70. package/src/common/l4_foundation/locale/l4-locale-messages.ts +16 -0
  71. package/src/instrumentation.ts +0 -2
  72. package/src/server/l1_entry/api/l1-project-read-routes.ts +6 -4
  73. package/src/server/l1_entry/api/l1-project-route.ts +9 -8
  74. package/src/server/l1_entry/api/l1-work-session-file-error.ts +23 -0
  75. package/src/server/l1_entry/node/l1-server.ts +8 -4
  76. package/src/server/l2_biz/plugin-management/l2-plugin-management.ts +0 -3
  77. package/src/server/l2_biz/work-session/l2-work-session-chat-runtime.ts +30 -58
  78. package/src/server/l2_biz/work-session/l2-work-session-manage.ts +0 -4
  79. package/src/server/l4_foundation/file/l4-project-file-index.ts +276 -0
  80. package/src/server/l4_foundation/file/l4-project-search.ts +399 -0
  81. package/src/server/l4_foundation/file/l4-ripgrep-search.ts +192 -0
  82. package/src/server/l4_foundation/file/l4-work-session-project-file.ts +8 -332
  83. package/src/server/l4_foundation/model-settings/l4-model-settings-store.ts +29 -20
  84. package/src/server/l4_foundation/model-settings/l4-model-settings-types.ts +1 -1
  85. package/src/server/l4_foundation/pi/l4-pi-chat-worker.ts +22 -5
  86. package/src/server/l4_foundation/pi/l4-pi-package-maintenance.ts +0 -6
  87. package/src/server/l4_foundation/pi/l4-pi-plugin-capability-probe.ts +1 -3
  88. package/src/server/l4_foundation/pi/l4-pi-plugin-owner-runtime.ts +133 -13
  89. package/src/server/l4_foundation/pi/l4-pi-plugin-probe.ts +1 -3
  90. package/src/server/l4_foundation/pi/l4-pi-runner-process.ts +2 -2
  91. package/src/server/l4_foundation/pi/l4-pi-session-initialization.ts +9 -0
  92. package/src/server/l4_foundation/process/l4-process-tree.js +23 -4
  93. package/temp/build/pi-desk/release/.next/BUILD_ID +1 -1
  94. package/temp/build/pi-desk/release/.next/app-path-routes-manifest.json +3 -2
  95. package/temp/build/pi-desk/release/.next/build-manifest.json +3 -3
  96. package/temp/build/pi-desk/release/.next/prerender-manifest.json +3 -3
  97. package/temp/build/pi-desk/release/.next/react-loadable-manifest.json +1 -2
  98. package/temp/build/pi-desk/release/.next/required-server-files.js +4 -3
  99. package/temp/build/pi-desk/release/.next/required-server-files.json +4 -3
  100. package/temp/build/pi-desk/release/.next/routes-manifest.json +6 -0
  101. package/temp/build/pi-desk/release/.next/server/app/_global-error/page.js +1 -1
  102. package/temp/build/pi-desk/release/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  103. package/temp/build/pi-desk/release/.next/server/app/_global-error.html +1 -1
  104. package/temp/build/pi-desk/release/.next/server/app/_global-error.rsc +3 -3
  105. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_full.segment.rsc +3 -3
  106. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +3 -3
  107. package/temp/build/pi-desk/release/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  108. package/temp/build/pi-desk/release/.next/server/app/_not-found/page.js +1 -1
  109. package/temp/build/pi-desk/release/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  110. package/temp/build/pi-desk/release/.next/server/app/api/auth/login/route.js +1 -1
  111. package/temp/build/pi-desk/release/.next/server/app/api/auth/logout/route.js +1 -1
  112. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/get/route.js +1 -1
  113. package/temp/build/pi-desk/release/.next/server/app/api/auth-settings/replace/route.js +1 -1
  114. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/get/route.js +1 -1
  115. package/temp/build/pi-desk/release/.next/server/app/api/capability-modes/replace/route.js +1 -1
  116. package/temp/build/pi-desk/release/.next/server/app/api/chat/context/get/route.js +1 -1
  117. package/temp/build/pi-desk/release/.next/server/app/api/chat/images/get/route.js +1 -1
  118. package/temp/build/pi-desk/release/.next/server/app/api/chat/messages/get/route.js +1 -1
  119. package/temp/build/pi-desk/release/.next/server/app/api/health/route.js +1 -1
  120. package/temp/build/pi-desk/release/.next/server/app/api/mcp-check/get/route.js +1 -1
  121. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/del/route.js +1 -1
  122. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/get/route.js +1 -1
  123. package/temp/build/pi-desk/release/.next/server/app/api/mcp-settings/replace/route.js +1 -1
  124. package/temp/build/pi-desk/release/.next/server/app/api/model-catalog/list/route.js +1 -1
  125. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/get/route.js +1 -1
  126. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/preview/route.js +1 -1
  127. package/temp/build/pi-desk/release/.next/server/app/api/model-settings/replace/route.js +1 -1
  128. package/temp/build/pi-desk/release/.next/server/app/api/pi/directories/list/route.js +1 -1
  129. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-entries/list/route.js +1 -1
  130. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/list/route.js +1 -1
  131. package/temp/build/pi-desk/release/.next/server/app/api/pi/directory-ignores/replace/route.js +1 -1
  132. package/temp/build/pi-desk/release/.next/server/app/api/pi/models/list/route.js +1 -1
  133. package/temp/build/pi-desk/release/.next/server/app/api/pi/session-user-messages/list/route.js +1 -1
  134. package/temp/build/pi-desk/release/.next/server/app/api/pi/sessions/list/route.js +1 -1
  135. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/get/route.js +1 -1
  136. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/search/route.js +1 -1
  137. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-get/route.js +1 -1
  138. package/temp/build/pi-desk/release/.next/server/app/api/plugin-catalog/settings-replace/route.js +1 -1
  139. package/temp/build/pi-desk/release/.next/server/app/api/plugins/add/route.js +1 -1
  140. package/temp/build/pi-desk/release/.next/server/app/api/plugins/apply/route.js +1 -1
  141. package/temp/build/pi-desk/release/.next/server/app/api/plugins/batch/route.js +1 -1
  142. package/temp/build/pi-desk/release/.next/server/app/api/plugins/browser-resources/[resourceGroup]/[...resourcePath]/route.js +1 -1
  143. package/temp/build/pi-desk/release/.next/server/app/api/plugins/del/route.js +1 -1
  144. package/temp/build/pi-desk/release/.next/server/app/api/plugins/enabled-set/route.js +1 -1
  145. package/temp/build/pi-desk/release/.next/server/app/api/plugins/get/route.js +1 -1
  146. package/temp/build/pi-desk/release/.next/server/app/api/plugins/host-runtime/[runtimeVersion]/[...resourcePath]/route.js +1 -1
  147. package/temp/build/pi-desk/release/.next/server/app/api/plugins/list/route.js +1 -1
  148. package/temp/build/pi-desk/release/.next/server/app/api/plugins/reload/route.js +1 -1
  149. package/temp/build/pi-desk/release/.next/server/app/api/plugins/update/route.js +1 -1
  150. package/temp/build/pi-desk/release/.next/server/app/api/project-files/get/route.js +2 -1
  151. package/temp/build/pi-desk/release/.next/server/app/api/project-files/list/route.js +2 -1
  152. package/temp/build/pi-desk/release/.next/server/app/api/project-files/reveal/route.js +1 -1
  153. package/temp/build/pi-desk/release/.next/server/app/api/project-files/search/route.js +2 -1
  154. package/temp/build/pi-desk/release/.next/server/app/api/project-git/get/route.js +2 -1
  155. package/temp/build/pi-desk/release/.next/server/app/api/project-git-branches/list/route.js +2 -1
  156. package/temp/build/pi-desk/release/.next/server/app/api/project-git-changes/list/route.js +2 -1
  157. package/temp/build/pi-desk/release/.next/server/app/api/project-git-diff/get/route.js +2 -1
  158. package/temp/build/pi-desk/release/.next/server/app/api/project-git-heads/get/route.js +2 -1
  159. package/temp/build/pi-desk/release/.next/server/app/api/project-git-log/list/route.js +2 -1
  160. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/get/route.js +1 -1
  161. package/temp/build/pi-desk/release/.next/server/app/api/project-model-default/replace/route.js +1 -1
  162. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/get/route.js +1 -1
  163. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/list/route.js +1 -1
  164. package/temp/build/pi-desk/release/.next/server/app/api/skill-files/replace/route.js +1 -1
  165. package/temp/build/pi-desk/release/.next/server/app/api/skills/list/route.js +1 -1
  166. package/temp/build/pi-desk/release/.next/server/app/api/task-center/images/get/route.js +1 -1
  167. package/temp/build/pi-desk/release/.next/server/app/api/task-center/messages/get/route.js +1 -1
  168. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/add/route.js +1 -1
  169. package/temp/build/pi-desk/release/.next/server/app/api/work-session-git-branch/replace/route.js +1 -1
  170. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree/get/route.js +1 -1
  171. package/temp/build/pi-desk/release/.next/server/app/api/work-session-tree-entry/get/route.js +1 -1
  172. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/add/route.js +1 -1
  173. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/branch/route.js +1 -1
  174. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/del/route.js +1 -1
  175. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/rename/route.js +1 -1
  176. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/replace/route.js +1 -1
  177. package/temp/build/pi-desk/release/.next/server/app/api/work-sessions/sort/route.js +1 -1
  178. package/temp/build/pi-desk/release/.next/server/app/favicon.ico/route.js +1 -1
  179. package/temp/build/pi-desk/release/.next/server/app/login/page.js +1 -1
  180. package/temp/build/pi-desk/release/.next/server/app/login/page_client-reference-manifest.js +1 -1
  181. package/temp/build/pi-desk/release/.next/server/app/page.js +72 -72
  182. package/temp/build/pi-desk/release/.next/server/app/page_client-reference-manifest.js +1 -1
  183. package/temp/build/pi-desk/release/.next/server/app/project-preview/page.js +1 -0
  184. package/temp/build/pi-desk/release/.next/server/app/project-preview/page_client-reference-manifest.js +1 -0
  185. package/temp/build/pi-desk/release/.next/server/app-paths-manifest.json +3 -2
  186. package/temp/build/pi-desk/release/.next/server/chunks/10912.js +2 -2
  187. package/temp/build/pi-desk/release/.next/server/chunks/20460.js +15 -0
  188. package/temp/build/pi-desk/release/.next/server/chunks/23054.js +1 -1
  189. package/temp/build/pi-desk/release/.next/server/chunks/25406.js +10 -10
  190. package/temp/build/pi-desk/release/.next/server/chunks/35985.js +3 -17
  191. package/temp/build/pi-desk/release/.next/server/chunks/36361.js +1 -1
  192. package/temp/build/pi-desk/release/.next/server/chunks/48180.js +1 -1
  193. package/temp/build/pi-desk/release/.next/server/chunks/50520.js +2 -4
  194. package/temp/build/pi-desk/release/.next/server/chunks/56830.js +235 -0
  195. package/temp/build/pi-desk/release/.next/server/chunks/6917.js +1 -1
  196. package/temp/build/pi-desk/release/.next/server/chunks/70780.js +1 -0
  197. package/temp/build/pi-desk/release/.next/server/chunks/74528.js +1 -1
  198. package/temp/build/pi-desk/release/.next/server/chunks/78262.js +1 -1
  199. package/temp/build/pi-desk/release/.next/server/chunks/79686.js +62 -0
  200. package/temp/build/pi-desk/release/.next/server/chunks/80780.js +1 -0
  201. package/temp/build/pi-desk/release/.next/server/chunks/81363.js +1 -1
  202. package/temp/build/pi-desk/release/.next/server/chunks/82499.js +4 -4
  203. package/temp/build/pi-desk/release/.next/server/chunks/92386.js +8 -8
  204. package/temp/build/pi-desk/release/.next/server/instrumentation.js +1 -1
  205. package/temp/build/pi-desk/release/.next/server/middleware-build-manifest.js +1 -1
  206. package/temp/build/pi-desk/release/.next/server/middleware-react-loadable-manifest.js +1 -1
  207. package/temp/build/pi-desk/release/.next/server/pages/500.html +1 -1
  208. package/temp/build/pi-desk/release/.next/server/server-reference-manifest.json +1 -1
  209. package/temp/build/pi-desk/release/.next/static/8Yd33M0zPi4tbRn4xCaRY/_buildManifest.js +1 -0
  210. package/temp/build/pi-desk/release/.next/static/chunks/11937-1d0a9822f2c7995b.js +1 -0
  211. package/temp/build/pi-desk/release/.next/static/chunks/14825-5579aed34a631ad7.js +62 -0
  212. package/temp/build/pi-desk/release/.next/static/chunks/15302-9c807afc6c60de0c.js +1 -0
  213. package/temp/build/pi-desk/release/.next/static/chunks/19991.8aa2e4b6df15fad6.js +1 -0
  214. package/temp/build/pi-desk/release/.next/static/chunks/22092-6d1bfbefa825ec03.js +1 -0
  215. package/temp/build/pi-desk/release/.next/static/chunks/37313-d5970e2d0c270d22.js +238 -0
  216. package/temp/build/pi-desk/release/.next/static/chunks/{49516-cc4dcd84d64ab4fe.js → 51474-8dc714cb76b2e60a.js} +2 -2
  217. package/temp/build/pi-desk/release/.next/static/chunks/57235-03ba1044f22b6c84.js +1 -0
  218. package/temp/build/pi-desk/release/.next/static/chunks/79267-7d21d7cdbd7cfca1.js +1 -0
  219. package/temp/build/pi-desk/release/.next/static/chunks/82371-f7ba4a07a5dbcf34.js +1 -0
  220. package/temp/build/pi-desk/release/.next/static/chunks/9038-03144ed96d613f75.js +15 -0
  221. package/temp/build/pi-desk/release/.next/static/chunks/app/{error-0296a3b20cd1bf00.js → error-216b14b5da089ed3.js} +1 -1
  222. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-20718f1503910291.js +1 -0
  223. package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-0d3d4827802108e5.js +1 -0
  224. package/temp/build/pi-desk/release/.next/static/chunks/app/{not-found-2aab8b33ebbf3257.js → not-found-720cdf6a606b821a.js} +1 -1
  225. package/temp/build/pi-desk/release/.next/static/chunks/app/page-6ebc1c877f6025dd.js +158 -0
  226. package/temp/build/pi-desk/release/.next/static/chunks/app/project-preview/page-d70ee4e9409b970a.js +1 -0
  227. package/temp/build/pi-desk/release/.next/static/chunks/webpack-b60891a214e0925d.js +1 -0
  228. package/temp/build/pi-desk/release/.next/static/css/1e780a4936aa6ba3.css +1 -0
  229. package/temp/build/pi-desk/release/.next/static/css/6dbae2922f88ca31.css +1 -0
  230. package/temp/build/pi-desk/release/.next/static/css/f646ca6c07245c4c.css +1 -0
  231. package/temp/build/pi-desk/release/.next/trace-build +1 -1
  232. package/temp/build/pi-desk/release/.next/server/chunks/33658.js +0 -296
  233. package/temp/build/pi-desk/release/.next/server/chunks/8584.js +0 -2
  234. package/temp/build/pi-desk/release/.next/static/chunks/31087-ba426d09d6f68bfd.js +0 -1
  235. package/temp/build/pi-desk/release/.next/static/chunks/3814-35cfab0ce3aa7c41.js +0 -1
  236. package/temp/build/pi-desk/release/.next/static/chunks/39654-b5fedd762ea0312e.js +0 -238
  237. package/temp/build/pi-desk/release/.next/static/chunks/70669.07f3670bfb7d6dd2.js +0 -1
  238. package/temp/build/pi-desk/release/.next/static/chunks/74220-795a2e7185bd66cb.js +0 -1
  239. package/temp/build/pi-desk/release/.next/static/chunks/75130-d2ca74894aff8085.js +0 -13
  240. package/temp/build/pi-desk/release/.next/static/chunks/78923-17a9c337b29dcecd.js +0 -1
  241. package/temp/build/pi-desk/release/.next/static/chunks/81881-f11dbe7dc0d04ed9.js +0 -1
  242. package/temp/build/pi-desk/release/.next/static/chunks/96995-8f8313ea2ac3abd7.js +0 -62
  243. package/temp/build/pi-desk/release/.next/static/chunks/app/layout-c0e1c5cef8620cf8.js +0 -3
  244. package/temp/build/pi-desk/release/.next/static/chunks/app/login/page-84892b06243891f0.js +0 -1
  245. package/temp/build/pi-desk/release/.next/static/chunks/app/page-a984139e99586041.js +0 -158
  246. package/temp/build/pi-desk/release/.next/static/chunks/webpack-40a782fc8a3535b9.js +0 -1
  247. package/temp/build/pi-desk/release/.next/static/css/6427d02b6edf406f.css +0 -1
  248. package/temp/build/pi-desk/release/.next/static/css/79e06f05df9edff0.css +0 -1
  249. package/temp/build/pi-desk/release/.next/static/n2LrXQgq8UkbH_AzhR3fw/_buildManifest.js +0 -1
  250. /package/temp/build/pi-desk/release/.next/static/{n2LrXQgq8UkbH_AzhR3fw → 8Yd33M0zPi4tbRn4xCaRY}/_ssgManifest.js +0 -0
@@ -0,0 +1,89 @@
1
+ export const L4_MARKDOWN_ALLOWED_TAGS = {
2
+ input: ['dataPiMarkdownProgress'],
3
+ blockquote: ['dataPiMarkdownAlert']
4
+ }
5
+
6
+ // 仅描述本转换读取的 mdast 字段,不引入另一套解析器或运行依赖。
7
+ interface MarkdownNode {
8
+ type: string
9
+ value?: string
10
+ children?: MarkdownNode[]
11
+ position?: { start: { offset?: number } }
12
+ data?: {
13
+ hName?: string
14
+ hProperties?: Record<string, string | boolean | string[]>
15
+ }
16
+ }
17
+
18
+ function statusNode(marker: string): MarkdownNode {
19
+ return {
20
+ type: 'paragraph',
21
+ children: [],
22
+ data: {
23
+ hName: 'input',
24
+ hProperties: {
25
+ type: 'checkbox',
26
+ disabled: true,
27
+ checked: marker.toLowerCase() === '[x]',
28
+ ...(marker === '[-]' ? { dataPiMarkdownProgress: 'true' } : {})
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ export function remarkL4Markdown(): (tree: MarkdownNode, file: { value: unknown }) => void {
35
+ return (tree, file): void => {
36
+ const source = String(file.value)
37
+ const isLiteral = (node: MarkdownNode, marker: string): boolean => {
38
+ const start = node.position?.start.offset
39
+ return start !== undefined && source.slice(start, start + marker.length) === marker
40
+ }
41
+
42
+ const visit = (node: MarkdownNode): void => {
43
+ const first = node.children?.[0]
44
+ if (node.type === 'tableCell' && node.children?.length === 1 && first?.type === 'text') {
45
+ const marker = first.value ?? ''
46
+ if (/^\[[ xX-]\]$/.test(marker) && isLiteral(first, marker)) {
47
+ node.children = [statusNode(marker)]
48
+ }
49
+ } else if (node.type === 'listItem' && first?.type === 'paragraph') {
50
+ const text = first.children?.[0]
51
+ if (
52
+ text?.type === 'text' &&
53
+ /^\[-\](?:\s|$)/.test(text.value ?? '') &&
54
+ isLiteral(text, '[-]')
55
+ ) {
56
+ text.value = text.value!.slice(3)
57
+ first.children!.unshift(statusNode('[-]'))
58
+ node.data = { ...node.data, hProperties: { className: ['task-list-item'] } }
59
+ }
60
+ } else if (node.type === 'blockquote' && first?.type === 'paragraph') {
61
+ const text = first.children?.[0]
62
+ const match = text?.value?.match(
63
+ /^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\][ \t]*(?:\r?\n|$)/
64
+ )
65
+ if (
66
+ text?.type === 'text' &&
67
+ match &&
68
+ isLiteral(text, `[!${match[1]}]`) &&
69
+ (match[0].endsWith('\n') ||
70
+ first.children!.length === 1 ||
71
+ first.children![1]?.type === 'break')
72
+ ) {
73
+ text.value = text.value!.slice(match[0].length)
74
+ if (!text.value) {
75
+ first.children!.shift()
76
+ if (first.children![0]?.type === 'break') first.children!.shift()
77
+ }
78
+ if (first.children!.length === 0) node.children!.shift()
79
+ node.data = {
80
+ ...node.data,
81
+ hProperties: { dataPiMarkdownAlert: match[1]!.toLowerCase() }
82
+ }
83
+ }
84
+ }
85
+ for (const child of node.children ?? []) visit(child)
86
+ }
87
+ visit(tree)
88
+ }
89
+ }
@@ -0,0 +1,58 @@
1
+ .markdown :global(.task-list-item) {
2
+ list-style: none;
3
+ }
4
+
5
+ .status {
6
+ display: inline-flex;
7
+ position: relative;
8
+ width: 1rem;
9
+ height: 1rem;
10
+ align-items: center;
11
+ justify-content: center;
12
+ border: 1px solid var(--muted-foreground);
13
+ border-radius: 0.25rem;
14
+ vertical-align: -0.125rem;
15
+ color: var(--foreground);
16
+ }
17
+
18
+ .status[data-state='completed'] {
19
+ border-color: var(--foreground);
20
+ background: var(--foreground);
21
+ color: var(--background);
22
+ }
23
+
24
+ .status svg {
25
+ width: 0.875rem;
26
+ height: 0.875rem;
27
+ stroke-width: 2;
28
+ }
29
+
30
+ .alert {
31
+ margin-block: 0.75rem;
32
+ border-left: 3px solid var(--muted-foreground);
33
+ padding: 0.5rem 0.875rem;
34
+ color: var(--foreground);
35
+ font-style: normal;
36
+ }
37
+
38
+ .alertTitle {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: 0.5rem;
42
+ margin-bottom: 0.375rem;
43
+ font-weight: 600;
44
+ }
45
+
46
+ .alertTitle svg {
47
+ width: 1rem;
48
+ height: 1rem;
49
+ flex: none;
50
+ }
51
+
52
+ .alertBody > * {
53
+ margin-block: 0;
54
+ }
55
+
56
+ .alertBody > * + * {
57
+ margin-block-start: 0.5rem;
58
+ }
@@ -0,0 +1,108 @@
1
+ 'use client'
2
+
3
+ import {
4
+ CheckIcon,
5
+ InfoIcon,
6
+ LightbulbIcon,
7
+ MessageSquareWarningIcon,
8
+ MinusIcon,
9
+ OctagonAlertIcon,
10
+ TriangleAlertIcon
11
+ } from 'lucide-react'
12
+ import type { ComponentProps } from 'react'
13
+ import { useTranslation } from 'react-i18next'
14
+ import { defaultRemarkPlugins, type Components, type StreamdownProps } from 'streamdown'
15
+ import { cn } from '@client/l4_foundation/lib/l4-utils'
16
+ import { remarkL4Markdown } from './l4-markdown-remark'
17
+ import styles from './l4-markdown.module.css'
18
+
19
+ export { L4_MARKDOWN_ALLOWED_TAGS } from './l4-markdown-remark'
20
+
21
+ export const L4_MARKDOWN_REMARK_PLUGINS: NonNullable<StreamdownProps['remarkPlugins']> = [
22
+ ...Object.values(defaultRemarkPlugins),
23
+ remarkL4Markdown
24
+ ]
25
+ export const L4_MARKDOWN_CLASS_NAME = styles.markdown
26
+
27
+ const alerts = {
28
+ note: { icon: InfoIcon, label: 'markdownNote' },
29
+ tip: { icon: LightbulbIcon, label: 'markdownTip' },
30
+ important: { icon: MessageSquareWarningIcon, label: 'markdownImportant' },
31
+ warning: { icon: TriangleAlertIcon, label: 'markdownWarning' },
32
+ caution: { icon: OctagonAlertIcon, label: 'markdownCaution' }
33
+ } as const
34
+
35
+ function MarkdownStatus({
36
+ 'data-pi-markdown-progress': progress,
37
+ ...props
38
+ }: ComponentProps<'input'> & {
39
+ node?: unknown
40
+ 'data-pi-markdown-progress'?: string
41
+ }): React.JSX.Element {
42
+ const { t } = useTranslation('common')
43
+ delete props.node
44
+ if (props.type !== 'checkbox') return <input {...props} />
45
+ const state = progress ? 'progress' : props.checked ? 'completed' : 'pending'
46
+ const marker = progress ? '[-]' : props.checked ? '[x]' : '[ ]'
47
+ const label = t(
48
+ progress ? 'markdownProgress' : props.checked ? 'markdownCompleted' : 'markdownPending'
49
+ )
50
+
51
+ return (
52
+ <span className={styles.status} data-state={state} role="img" aria-label={label} title={label}>
53
+ {progress ? (
54
+ <MinusIcon aria-hidden="true" />
55
+ ) : props.checked ? (
56
+ <CheckIcon aria-hidden="true" />
57
+ ) : null}
58
+ <span className="sr-only" aria-hidden="true">
59
+ {marker}
60
+ </span>
61
+ </span>
62
+ )
63
+ }
64
+
65
+ function MarkdownBlockquote({
66
+ 'data-pi-markdown-alert': kind,
67
+ className,
68
+ children,
69
+ ...props
70
+ }: ComponentProps<'blockquote'> & {
71
+ node?: unknown
72
+ 'data-pi-markdown-alert'?: string
73
+ }): React.JSX.Element {
74
+ const { t } = useTranslation('common')
75
+ delete props.node
76
+ const alert = Object.entries(alerts).find(([name]) => name === kind)?.[1]
77
+
78
+ if (!alert) {
79
+ return (
80
+ <blockquote
81
+ {...props}
82
+ data-streamdown="blockquote"
83
+ className={cn(
84
+ 'my-4 border-muted-foreground/30 border-l-4 pl-4 text-muted-foreground italic',
85
+ className
86
+ )}
87
+ >
88
+ {children}
89
+ </blockquote>
90
+ )
91
+ }
92
+
93
+ const Icon = alert.icon
94
+ return (
95
+ <aside className={styles.alert} role="note" aria-label={t(alert.label)}>
96
+ <div className={styles.alertTitle}>
97
+ <Icon aria-hidden="true" />
98
+ {t(alert.label)}
99
+ </div>
100
+ <div className={styles.alertBody}>{children}</div>
101
+ </aside>
102
+ )
103
+ }
104
+
105
+ export const L4_MARKDOWN_COMPONENTS: Components = {
106
+ input: MarkdownStatus,
107
+ blockquote: MarkdownBlockquote
108
+ }
@@ -0,0 +1,41 @@
1
+ function hasControlCharacters(value: string): boolean {
2
+ return Array.from(value).some((character) => {
3
+ const code = character.charCodeAt(0)
4
+ return code <= 0x1f || (code >= 0x7f && code <= 0x9f)
5
+ })
6
+ }
7
+
8
+ export function L2ResolveAuthReturnTo(value: unknown): string {
9
+ if (
10
+ typeof value !== 'string' ||
11
+ !value.startsWith('/') ||
12
+ value.startsWith('//') ||
13
+ value.includes('\\') ||
14
+ hasControlCharacters(value)
15
+ ) {
16
+ return '/'
17
+ }
18
+
19
+ let pathname: string
20
+ try {
21
+ pathname = decodeURIComponent(value.split(/[?#]/, 1)[0])
22
+ if (hasControlCharacters(decodeURIComponent(value))) return '/'
23
+ } catch {
24
+ return '/'
25
+ }
26
+ if (pathname.startsWith('//') || pathname.includes('\\')) return '/'
27
+
28
+ const segments: string[] = []
29
+ for (const segment of pathname.split('/')) {
30
+ if (segment === '..') segments.pop()
31
+ else if (segment !== '' && segment !== '.') segments.push(segment)
32
+ }
33
+ if (segments.join('/').toLowerCase() === 'login') return '/'
34
+
35
+ return value
36
+ }
37
+
38
+ export function L2BuildLoginHref(returnTo: unknown): string {
39
+ const target = L2ResolveAuthReturnTo(returnTo)
40
+ return target === '/' ? '/login' : `/login?returnTo=${encodeURIComponent(target)}`
41
+ }
@@ -222,7 +222,11 @@ export const L2ModelSettingsPreviewResponseSchema = z
222
222
  .object({
223
223
  projectDefaults: z.array(
224
224
  z
225
- .object({ cwd: L3PiCwdSchema, from: L2ModelSelectionSchema, to: L2ModelSelectionSchema })
225
+ .object({
226
+ cwd: L3PiCwdSchema,
227
+ from: L2ModelSelectionSchema,
228
+ to: L2ModelSelectionSchema.nullable()
229
+ })
226
230
  .strict()
227
231
  )
228
232
  })
@@ -87,6 +87,8 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
87
87
  contributionSettings: 'Settings page',
88
88
  contributionMessage: 'Message view',
89
89
  contributionSidebar: 'Session sidebar',
90
+ contributionWidget: 'Composer widget',
91
+ contributionSessionHeader: 'Session header item',
90
92
  tagTools: '{{count}} tools',
91
93
  tagFixed: '{{count}} fixed prompts',
92
94
  tagDynamic: '{{count}} dynamic hooks',
@@ -324,6 +326,8 @@ export const L2_PLUGIN_MANAGEMENT_MESSAGES = {
324
326
  contributionSettings: '设置页',
325
327
  contributionMessage: '消息视图',
326
328
  contributionSidebar: '会话侧栏',
329
+ contributionWidget: '输入区挂件',
330
+ contributionSessionHeader: '会话标题项',
327
331
  tagTools: '工具 {{count}}',
328
332
  tagFixed: '固定提示 {{count}}',
329
333
  tagDynamic: '动态影响 {{count}}',
@@ -1,5 +1,19 @@
1
1
  export const L2_PROJECT_HISTORY_MESSAGES = {
2
2
  en: {
3
+ chooseProject: 'Open a project',
4
+ switchProject: 'Switch project',
5
+ directoryPath: 'Directory path',
6
+ directoryPlaceholder: 'Enter an absolute directory path',
7
+ serverDirectoryHint: 'Browse directories on the connected server.',
8
+ openProject: 'Open',
9
+ recentProjects: 'Project history',
10
+ browseDirectories: 'Browse directories',
11
+ loadingDirectories: 'Loading directories…',
12
+ parentDirectory: 'Parent directory',
13
+ directoryRoots: 'Directories',
14
+ openThisDirectory: 'Open this directory',
15
+ noSubdirectories: 'No subdirectories',
16
+ noRecentProjects: 'No project history. Enter a path or browse directories.',
3
17
  currentHead: 'Current HEAD',
4
18
  localBranch: 'Local branch',
5
19
  remoteBranch: 'Remote branch · local record',
@@ -76,6 +90,20 @@ export const L2_PROJECT_HISTORY_MESSAGES = {
76
90
  historyReadFailed: 'Could not read Git history'
77
91
  },
78
92
  'zh-CN': {
93
+ chooseProject: '打开项目',
94
+ switchProject: '切换项目',
95
+ directoryPath: '目录路径',
96
+ directoryPlaceholder: '输入完整目录路径',
97
+ serverDirectoryHint: '选择所连接服务上的目录。',
98
+ openProject: '打开',
99
+ recentProjects: '历史项目',
100
+ browseDirectories: '浏览目录',
101
+ loadingDirectories: '正在读取目录…',
102
+ parentDirectory: '上级目录',
103
+ directoryRoots: '目录',
104
+ openThisDirectory: '打开此目录',
105
+ noSubdirectories: '没有子目录',
106
+ noRecentProjects: '没有历史项目,可输入路径或浏览目录。',
79
107
  currentHead: '当前 HEAD',
80
108
  localBranch: '本地分支',
81
109
  remoteBranch: '远程分支 · 本地记录',
@@ -0,0 +1,5 @@
1
+ export const L2_PROJECT_PREVIEW_PATH = '/project-preview'
2
+
3
+ export function buildL2ProjectPreviewHref(cwd?: string | null): string {
4
+ return cwd ? `${L2_PROJECT_PREVIEW_PATH}?cwd=${encodeURIComponent(cwd)}` : L2_PROJECT_PREVIEW_PATH
5
+ }
@@ -110,7 +110,8 @@ export const L2_SETTINGS_MESSAGES = {
110
110
  removeAndSave: 'Remove and save',
111
111
  replaceProjectDefaultsTitle: 'Update project default models',
112
112
  replaceProjectDefaultsDescription:
113
- 'The following projects will use the new model settings. Confirm to save all changes together.',
113
+ 'The following project defaults will be updated or cleared. Confirm to save all changes together.',
114
+ clearProjectDefault: 'Clear project default',
114
115
  confirmAndSaveModels: 'Confirm and save',
115
116
  modelSaved: 'Model configuration saved.',
116
117
  modelSaveFailed: 'Could not save the model configuration',
@@ -405,8 +406,8 @@ export const L2_SETTINGS_MESSAGES = {
405
406
  '有 {{count}} 个常用组合引用了已删除模型,保存配置将同时删除这些组合。',
406
407
  removeAndSave: '删除并保存',
407
408
  replaceProjectDefaultsTitle: '同步项目默认模型',
408
- replaceProjectDefaultsDescription:
409
- '以下项目的默认模型将替换为本次设置的新模型,确认后一起保存。',
409
+ replaceProjectDefaultsDescription: '以下项目默认将更新或清除,确认后一起保存。',
410
+ clearProjectDefault: '清除项目默认',
410
411
  confirmAndSaveModels: '确认并保存',
411
412
  modelSaved: '模型配置已保存。',
412
413
  modelSaveFailed: '模型配置保存失败',
@@ -10,6 +10,7 @@ import {
10
10
  L4ProjectFileEntrySchema,
11
11
  L4ProjectFileListSchema,
12
12
  L4ProjectFileSearchSchema,
13
+ L4ProjectSearchInputSchema,
13
14
  L4ProjectFileContentSchema,
14
15
  L4ProjectDirectoryPathSchema,
15
16
  L4ProjectFileImageMimeTypeSchema,
@@ -47,9 +48,9 @@ export const L2WorkSessionFileListRequestSchema = L2WorkSessionFileProjectRefSch
47
48
 
48
49
  export const L2WorkSessionFileListResponseSchema = L4ProjectFileListSchema
49
50
 
50
- export const L2WorkSessionFileSearchRequestSchema = L2WorkSessionFileProjectRefSchema.extend({
51
- query: z.string().trim().min(1).max(200)
52
- }).strict()
51
+ export const L2WorkSessionFileSearchRequestSchema = L2WorkSessionFileProjectRefSchema.extend(
52
+ L4ProjectSearchInputSchema.shape
53
+ ).strict()
53
54
 
54
55
  export const L2WorkSessionFileSearchResponseSchema = L4ProjectFileSearchSchema
55
56
 
@@ -202,6 +202,9 @@ export const L2_WORKBENCH_LOCALE_MESSAGES = {
202
202
  deleteSessionTitle: 'Delete work session',
203
203
  copyProjectPath: 'Copy project path',
204
204
  renameSessionTitle: 'Edit title',
205
+ reloadChatData: 'Reload chat data',
206
+ reloadChatDataFailed: 'Could not reload chat data',
207
+ reloadChatSourceChanged: 'The session has changed. Select it again.',
205
208
  sessionTitleLabel: 'Session title',
206
209
  renameSessionFailed: 'Could not save the session title',
207
210
  sidebarSessions: 'Work sessions',
@@ -209,6 +212,7 @@ export const L2_WORKBENCH_LOCALE_MESSAGES = {
209
212
  sidebarReplaceSession: 'Replace work session',
210
213
  createSession: 'Create work session',
211
214
  projectPreview: 'Project preview',
215
+ projectPreviewWindow: 'Open in new window',
212
216
  refreshFiles: 'Refresh project files',
213
217
  pinnedBelow: 'Pinned below',
214
218
  settings: 'Settings',
@@ -645,6 +649,9 @@ export const L2_WORKBENCH_LOCALE_MESSAGES = {
645
649
  deleteSessionTitle: '删除工作会话',
646
650
  copyProjectPath: '复制项目路径',
647
651
  renameSessionTitle: '修改标题',
652
+ reloadChatData: '重新加载聊天数据',
653
+ reloadChatDataFailed: '重新加载聊天数据失败',
654
+ reloadChatSourceChanged: '会话已变化,请重新选择会话',
648
655
  sessionTitleLabel: '会话标题',
649
656
  renameSessionFailed: '保存会话标题失败',
650
657
  sidebarSessions: '工作会话',
@@ -652,6 +659,7 @@ export const L2_WORKBENCH_LOCALE_MESSAGES = {
652
659
  sidebarReplaceSession: '替换工作会话',
653
660
  createSession: '新建工作会话',
654
661
  projectPreview: '项目预览',
662
+ projectPreviewWindow: '在新窗口打开',
655
663
  refreshFiles: '刷新项目文件',
656
664
  pinnedBelow: '以下固定',
657
665
  settings: '设置',
@@ -6,6 +6,7 @@ import {
6
6
  L4ProjectFileImagePreviewModeSchema,
7
7
  L4ProjectFileListSchema,
8
8
  L4ProjectFileSearchSchema,
9
+ L4ProjectSearchInputSchema,
9
10
  L4ProjectFileContentSchema
10
11
  } from '@common/l4_foundation/file/l4-project-file-contract'
11
12
  import {
@@ -67,9 +68,7 @@ export const L3ProjectFileList = {
67
68
  } as const
68
69
  export const L3ProjectFileSearch = {
69
70
  path: '/api/project-files/search',
70
- request: L3ProjectReadContextSchema.extend({
71
- query: z.string().trim().min(1).max(200)
72
- }).strict(),
71
+ request: L3ProjectReadContextSchema.extend(L4ProjectSearchInputSchema.shape).strict(),
73
72
  response: L4ProjectFileSearchSchema
74
73
  } as const
75
74
  export const L3ProjectFileGet = {
@@ -19,16 +19,39 @@ export const L3_PROJECT_FILES_LOCALE_MESSAGES = {
19
19
  sessionDirectory: 'Original folder',
20
20
  unavailable: 'Unavailable',
21
21
  projectFiles: '{{name}} project files',
22
- searchFiles: 'Search filenames',
23
- closeSearch: 'Close file search',
22
+ searchFiles: 'Search filenames or paths',
23
+ searchAll: 'Search files or content',
24
+ searchContent: 'Search file content',
25
+ searchScope: 'Search scope',
26
+ searchScopeAll: 'All',
27
+ searchScopeFiles: 'Files',
28
+ searchScopeContent: 'Content',
29
+ searchCaseSensitive: 'Match case',
30
+ searchWholeWord: 'Match whole word',
31
+ searchRegex: 'Use regular expression',
32
+ searchResults: 'Search results',
33
+ searchStart: 'Search this project',
34
+ searchTryOptions: 'Try another query or adjust the search options.',
35
+ searchFailed: 'Could not search the project. Please try again.',
36
+ searchCounts: '{{files}} files · {{lines}} matching lines',
37
+ searchShownCounts: 'Shown: {{counts}}',
38
+ searchFileHeading: 'Filenames',
39
+ searchContentHeading: 'Content',
40
+ searchContentCounts: '{{lines}} matching lines · {{files}} files',
41
+ searchProjectRoot: 'Project root',
42
+ searchExpandFiles: 'Show {{count}} more files',
43
+ searchOpenLine: 'Open {{path}}, line {{line}}',
44
+ searchLineUnavailable: 'The file content has changed and the matching line no longer exists.',
45
+ searchTextLimit: 'Content search: previewable UTF-8 text up to 5 MiB.',
46
+ closeSearch: 'Exit search',
24
47
  layout: 'File organization',
25
48
  directory: 'Folders',
26
49
  repository: 'Repositories',
27
50
  changesOnly: 'Changes only',
28
- searchProject: 'Search project files',
29
- noMatches: 'No matching files',
51
+ searchProject: 'Search project',
52
+ noMatches: 'No matching results',
30
53
  searching: 'Searching…',
31
- resultLimit: 'Showing the first 100 results.',
54
+ resultLimit: 'Results are limited. Refine your query or narrow the search scope.',
32
55
  copied: 'Copied.',
33
56
  copyFailed: 'Could not copy. Please try again.',
34
57
  revealRequested: 'Opened the system file manager.',
@@ -119,16 +142,39 @@ export const L3_PROJECT_FILES_LOCALE_MESSAGES = {
119
142
  sessionDirectory: '原目录',
120
143
  unavailable: '不可用',
121
144
  projectFiles: '{{name}} 项目文件',
122
- searchFiles: '搜索文件名',
123
- closeSearch: '关闭文件搜索',
145
+ searchFiles: '搜索文件名或路径',
146
+ searchAll: '搜索文件或内容',
147
+ searchContent: '搜索文件内容',
148
+ searchScope: '搜索范围',
149
+ searchScopeAll: '全部',
150
+ searchScopeFiles: '文件',
151
+ searchScopeContent: '内容',
152
+ searchCaseSensitive: '区分大小写',
153
+ searchWholeWord: '全词匹配',
154
+ searchRegex: '使用正则表达式',
155
+ searchResults: '搜索结果',
156
+ searchStart: '搜索这个项目',
157
+ searchTryOptions: '试试其他关键词,或调整搜索选项。',
158
+ searchFailed: '项目搜索失败,请重试。',
159
+ searchCounts: '{{files}} 个文件 · {{lines}} 个命中行',
160
+ searchShownCounts: '已显示:{{counts}}',
161
+ searchFileHeading: '文件名',
162
+ searchContentHeading: '内容',
163
+ searchContentCounts: '{{lines}} 个命中行 · {{files}} 个文件',
164
+ searchProjectRoot: '项目根目录',
165
+ searchExpandFiles: '展开其余 {{count}} 个文件',
166
+ searchOpenLine: '打开 {{path}} 第 {{line}} 行',
167
+ searchLineUnavailable: '文件内容已变化,搜索命中行已不存在',
168
+ searchTextLimit: '正文搜索:可预览的 UTF-8 文本,不超过 5 MiB。',
169
+ closeSearch: '退出搜索',
124
170
  layout: '文件组织方式',
125
171
  directory: '目录',
126
172
  repository: '仓库',
127
173
  changesOnly: '只看变更',
128
- searchProject: '搜索项目文件',
129
- noMatches: '没有匹配文件',
174
+ searchProject: '搜索项目',
175
+ noMatches: '没有匹配结果',
130
176
  searching: '正在搜索…',
131
- resultLimit: '结果较多,仅显示前 100 条。',
177
+ resultLimit: '结果较多,已截断显示。请细化关键词或缩小搜索范围。',
132
178
  copied: '已复制。',
133
179
  copyFailed: '复制失败,请重试。',
134
180
  revealRequested: '已请求运行端文件管理器定位。',
@@ -3,6 +3,8 @@ import { z } from 'zod'
3
3
  export const L4_PROJECT_FILE_PATH_MAX_LENGTH = 4096
4
4
  export const L4_PROJECT_FILE_LIST_MAX_ENTRIES = 5000
5
5
  export const L4_PROJECT_FILE_SEARCH_MAX_RESULTS = 100
6
+ export const L4_PROJECT_CONTENT_SEARCH_MAX_RESULTS = 200
7
+ export const L4_PROJECT_SEARCH_TEXT_MAX_LENGTH = 1000
6
8
  export const L4_PROJECT_TEXT_FILE_MAX_BYTES = 5 * 1024 * 1024
7
9
  export const L4_PROJECT_CODE_PARSE_MAX_BYTES = 1024 * 1024
8
10
  export const L4_PROJECT_IMAGE_FILE_MAX_BYTES = 10 * 1024 * 1024
@@ -76,9 +78,53 @@ export const L4ProjectFileListSchema = z
76
78
  })
77
79
  .strict()
78
80
 
81
+ export const L4ProjectSearchInputSchema = z
82
+ .object({
83
+ query: z
84
+ .string()
85
+ .min(1)
86
+ .max(200)
87
+ .refine(
88
+ (value) => value.trim().length > 0 && !/[\0\r\n]/.test(value),
89
+ '搜索词必须是非空单行文本'
90
+ ),
91
+ scope: z.enum(['all', 'files', 'content']).default('all'),
92
+ caseSensitive: z.boolean().default(false),
93
+ wholeWord: z.boolean().default(false),
94
+ regex: z.boolean().default(false)
95
+ })
96
+ .strict()
97
+
98
+ export const L4ProjectSearchRangeSchema = z
99
+ .object({ start: z.number().int().nonnegative(), end: z.number().int().nonnegative() })
100
+ .strict()
101
+ .refine((range) => range.start <= range.end, '搜索命中区间无效')
102
+
103
+ export const L4ProjectFileMatchSchema = z
104
+ .object({ path: L4ProjectFilePathSchema, ranges: z.array(L4ProjectSearchRangeSchema) })
105
+ .strict()
106
+ .refine(
107
+ (match) => match.ranges.every((range) => range.end <= match.path.length),
108
+ '文件名命中区间越界'
109
+ )
110
+
111
+ export const L4ProjectContentMatchSchema = z
112
+ .object({
113
+ path: L4ProjectFilePathSchema,
114
+ line: z.number().int().positive(),
115
+ text: z.string().max(L4_PROJECT_SEARCH_TEXT_MAX_LENGTH),
116
+ ranges: z.array(L4ProjectSearchRangeSchema)
117
+ })
118
+ .strict()
119
+ .refine(
120
+ (match) => match.ranges.every((range) => range.end <= match.text.length),
121
+ '正文命中区间越界'
122
+ )
123
+
79
124
  export const L4ProjectFileSearchSchema = z
80
125
  .object({
81
- matches: z.array(L4ProjectFilePathSchema).max(L4_PROJECT_FILE_SEARCH_MAX_RESULTS),
126
+ fileMatches: z.array(L4ProjectFileMatchSchema).max(L4_PROJECT_FILE_SEARCH_MAX_RESULTS),
127
+ contentMatches: z.array(L4ProjectContentMatchSchema).max(L4_PROJECT_CONTENT_SEARCH_MAX_RESULTS),
82
128
  truncated: z.boolean()
83
129
  })
84
130
  .strict()
@@ -103,6 +149,10 @@ export const L4ProjectFileContentSchema = z.discriminatedUnion('kind', [
103
149
 
104
150
  export type L4ProjectFileEntry = z.infer<typeof L4ProjectFileEntrySchema>
105
151
  export type L4ProjectFileList = z.infer<typeof L4ProjectFileListSchema>
152
+ export type L4ProjectSearchInput = z.infer<typeof L4ProjectSearchInputSchema>
153
+ export type L4ProjectSearchRange = z.infer<typeof L4ProjectSearchRangeSchema>
154
+ export type L4ProjectFileMatch = z.infer<typeof L4ProjectFileMatchSchema>
155
+ export type L4ProjectContentMatch = z.infer<typeof L4ProjectContentMatchSchema>
106
156
  export type L4ProjectFileSearch = z.infer<typeof L4ProjectFileSearchSchema>
107
157
  export type L4ProjectFileContent = z.infer<typeof L4ProjectFileContentSchema>
108
158
  export type L4ProjectFileImagePreviewMode = z.infer<typeof L4ProjectFileImagePreviewModeSchema>
@@ -15,6 +15,12 @@ export const L4_HOST_ERROR_MESSAGES = {
15
15
  imageTooLarge: 'This image is too large for online preview',
16
16
  previewUnsupported: 'This file type cannot be previewed online',
17
17
  fileReadFailed: 'Could not read the project file',
18
+ projectSearchPatternInvalid: 'The search expression is invalid or uses unsupported syntax',
19
+ projectSearchUnavailable:
20
+ 'The project search engine is unavailable. Reinstall the complete runtime dependencies',
21
+ projectSearchTimeout: 'Project search timed out. Narrow the search scope and try again',
22
+ projectSearchReadFailed: 'Could not read project search files or results',
23
+ projectSearchCancelled: 'Project search was cancelled',
18
24
  revealFailed: 'Could not open the file location',
19
25
  repositoryMissing: 'Git repository not found',
20
26
  gitOutsideProject: 'The Git target is outside the current project',
@@ -169,6 +175,11 @@ export const L4_HOST_ERROR_MESSAGES = {
169
175
  imageTooLarge: '图片过大,暂不支持在线预览',
170
176
  previewUnsupported: '当前文件类型不支持在线预览',
171
177
  fileReadFailed: '读取项目文件失败',
178
+ projectSearchPatternInvalid: '搜索表达式无效或包含不支持的语法',
179
+ projectSearchUnavailable: '项目搜索引擎不可用,请重新安装完整运行依赖',
180
+ projectSearchTimeout: '项目搜索超时,请缩小搜索范围后重试',
181
+ projectSearchReadFailed: '无法读取项目搜索文件或结果',
182
+ projectSearchCancelled: '项目搜索已取消',
172
183
  revealFailed: '打开所在文件夹失败',
173
184
  repositoryMissing: 'Git 仓库不存在',
174
185
  gitOutsideProject: 'Git 目标不在当前项目目录内',