@rexvane/piweb 0.3.25 → 0.3.26

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 (345) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +6 -5
  3. package/.next/build-manifest.json +4 -4
  4. package/.next/next-server.js.nft.json +1 -1
  5. package/.next/prerender-manifest.json +4 -4
  6. package/.next/react-loadable-manifest.json +14 -26
  7. package/.next/required-server-files.js +26 -26
  8. package/.next/required-server-files.json +26 -26
  9. package/.next/routes-manifest.json +6 -0
  10. package/.next/server/app/_global-error/page.js +2 -2
  11. package/.next/server/app/_global-error/page.js.nft.json +1 -1
  12. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/_global-error.html +1 -1
  14. package/.next/server/app/_global-error.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  16. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  17. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/server/app/_not-found/page.js +1 -1
  19. package/.next/server/app/_not-found/page.js.nft.json +1 -1
  20. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  21. package/.next/server/app/_not-found.html +1 -1
  22. package/.next/server/app/_not-found.rsc +2 -2
  23. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  24. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  25. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  26. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  27. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  28. package/.next/server/app/api/agent/[id]/events/route_client-reference-manifest.js +1 -1
  29. package/.next/server/app/api/agent/[id]/route.js +1 -1
  30. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  31. package/.next/server/app/api/agent/[id]/route_client-reference-manifest.js +1 -1
  32. package/.next/server/app/api/agent/[id]/tree/route.js +1 -1
  33. package/.next/server/app/api/agent/[id]/tree/route.js.nft.json +1 -1
  34. package/.next/server/app/api/agent/[id]/tree/route_client-reference-manifest.js +1 -1
  35. package/.next/server/app/api/agent/new/route.js +1 -1
  36. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  37. package/.next/server/app/api/agent/new/route_client-reference-manifest.js +1 -1
  38. package/.next/server/app/api/agent/resources/route.js +1 -0
  39. package/.next/server/app/api/agent/resources/route.js.nft.json +1 -0
  40. package/.next/server/app/api/agent/resources/route_client-reference-manifest.js +1 -0
  41. package/.next/server/app/api/config/route.js +1 -1
  42. package/.next/server/app/api/config/route.js.nft.json +1 -1
  43. package/.next/server/app/api/config/route_client-reference-manifest.js +1 -1
  44. package/.next/server/app/api/files/route.js +1 -1
  45. package/.next/server/app/api/files/route.js.nft.json +1 -1
  46. package/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  47. package/.next/server/app/api/fs/route.js +1 -1
  48. package/.next/server/app/api/fs/route.js.nft.json +1 -1
  49. package/.next/server/app/api/fs/route_client-reference-manifest.js +1 -1
  50. package/.next/server/app/api/git/route.js +4 -4
  51. package/.next/server/app/api/git/route.js.nft.json +1 -1
  52. package/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  53. package/.next/server/app/api/github/route.js +4 -4
  54. package/.next/server/app/api/github/route.js.nft.json +1 -1
  55. package/.next/server/app/api/github/route_client-reference-manifest.js +1 -1
  56. package/.next/server/app/api/growth/route.js +1 -1
  57. package/.next/server/app/api/growth/route.js.nft.json +1 -1
  58. package/.next/server/app/api/growth/route_client-reference-manifest.js +1 -1
  59. package/.next/server/app/api/health/route.js +1 -1
  60. package/.next/server/app/api/health/route.js.nft.json +1 -1
  61. package/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
  62. package/.next/server/app/api/models/defaults/route.js +1 -1
  63. package/.next/server/app/api/models/defaults/route.js.nft.json +1 -1
  64. package/.next/server/app/api/models/defaults/route_client-reference-manifest.js +1 -1
  65. package/.next/server/app/api/models/route.js +1 -1
  66. package/.next/server/app/api/models/route.js.nft.json +1 -1
  67. package/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  68. package/.next/server/app/api/pi-settings/route.js +1 -1
  69. package/.next/server/app/api/pi-settings/route.js.nft.json +1 -1
  70. package/.next/server/app/api/pi-settings/route_client-reference-manifest.js +1 -1
  71. package/.next/server/app/api/plugins/route.js +1 -1
  72. package/.next/server/app/api/plugins/route.js.nft.json +1 -1
  73. package/.next/server/app/api/plugins/route_client-reference-manifest.js +1 -1
  74. package/.next/server/app/api/prompts/route.js +1 -1
  75. package/.next/server/app/api/prompts/route.js.nft.json +1 -1
  76. package/.next/server/app/api/prompts/route_client-reference-manifest.js +1 -1
  77. package/.next/server/app/api/remote/route.js +2 -2
  78. package/.next/server/app/api/remote/route.js.nft.json +1 -1
  79. package/.next/server/app/api/remote/route_client-reference-manifest.js +1 -1
  80. package/.next/server/app/api/security/route.js +1 -1
  81. package/.next/server/app/api/security/route.js.nft.json +1 -1
  82. package/.next/server/app/api/security/route_client-reference-manifest.js +1 -1
  83. package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
  84. package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -1
  85. package/.next/server/app/api/sessions/[id]/export/route_client-reference-manifest.js +1 -1
  86. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  87. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  88. package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -1
  89. package/.next/server/app/api/sessions/import/route.js +2 -2
  90. package/.next/server/app/api/sessions/import/route.js.nft.json +1 -1
  91. package/.next/server/app/api/sessions/import/route_client-reference-manifest.js +1 -1
  92. package/.next/server/app/api/sessions/route.js +1 -1
  93. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  94. package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
  95. package/.next/server/app/api/skills/route.js +2 -2
  96. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  97. package/.next/server/app/api/skills/route_client-reference-manifest.js +1 -1
  98. package/.next/server/app/api/update/route.js +2 -2
  99. package/.next/server/app/api/update/route.js.nft.json +1 -1
  100. package/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  101. package/.next/server/app/api/version/route.js +1 -1
  102. package/.next/server/app/api/version/route.js.nft.json +1 -1
  103. package/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
  104. package/.next/server/app/api/web-auth/route.js +2 -2
  105. package/.next/server/app/api/web-auth/route.js.nft.json +1 -1
  106. package/.next/server/app/api/web-auth/route_client-reference-manifest.js +1 -1
  107. package/.next/server/app/api/workspaces/route.js +1 -1
  108. package/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  109. package/.next/server/app/api/workspaces/route_client-reference-manifest.js +1 -1
  110. package/.next/server/app/icon.svg/route.js +1 -1
  111. package/.next/server/app/icon.svg/route.js.nft.json +1 -1
  112. package/.next/server/app/index.html +1 -1
  113. package/.next/server/app/index.rsc +5 -5
  114. package/.next/server/app/index.segments/__PAGE__.segment.rsc +5 -5
  115. package/.next/server/app/index.segments/_full.segment.rsc +5 -5
  116. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  117. package/.next/server/app/login/page.js +1 -1
  118. package/.next/server/app/login/page.js.nft.json +1 -1
  119. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  120. package/.next/server/app/login.html +1 -1
  121. package/.next/server/app/login.rsc +4 -4
  122. package/.next/server/app/login.segments/_full.segment.rsc +4 -4
  123. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  124. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  125. package/.next/server/app/page.js +1 -1
  126. package/.next/server/app/page.js.nft.json +1 -1
  127. package/.next/server/app/page_client-reference-manifest.js +1 -1
  128. package/.next/server/app-paths-manifest.json +6 -5
  129. package/.next/server/chunks/{813.js → 1813.js} +1 -1
  130. package/.next/server/chunks/{430.js → 2430.js} +5 -5
  131. package/.next/server/chunks/{970.js → 2970.js} +1 -1
  132. package/.next/server/chunks/3924.js +6 -0
  133. package/.next/server/chunks/4807.js +1 -0
  134. package/.next/server/chunks/5393.js +1 -0
  135. package/.next/server/chunks/5802.js +2 -0
  136. package/.next/server/chunks/620.js +1 -1
  137. package/.next/server/chunks/6229.js +1 -0
  138. package/.next/server/chunks/7496.js +1 -0
  139. package/.next/server/chunks/7662.js +2 -0
  140. package/.next/server/chunks/8686.js +1 -0
  141. package/.next/server/chunks/{593.js → 974.js} +1 -1
  142. package/.next/server/chunks/{920.js → 9920.js} +1 -1
  143. package/.next/server/instrumentation.js +1 -1
  144. package/.next/server/instrumentation.js.nft.json +1 -1
  145. package/.next/server/middleware-build-manifest.js +1 -1
  146. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  147. package/.next/server/middleware.js +5 -5
  148. package/.next/server/pages/404.html +1 -1
  149. package/.next/server/pages/500.html +1 -1
  150. package/.next/server/preview-props.json +3 -3
  151. package/.next/server/server-reference-manifest.json +1 -1
  152. package/.next/server/webpack-runtime.js +1 -1
  153. package/.next/static/QJCtqgDKzGS2BdKABd9ch/_buildManifest.js +1 -0
  154. package/.next/static/chunks/2577.86c8538fbf05a8b2.js +1 -0
  155. package/.next/static/chunks/2716.fa561519675a3ff1.js +1 -0
  156. package/.next/static/chunks/2906.8a0e09bb47605cf1.js +1 -0
  157. package/.next/static/chunks/4673.ea36e55005c0f82f.js +1 -0
  158. package/.next/static/chunks/4686-4dc565817a160351.js +1 -0
  159. package/.next/static/chunks/4778.0d2c5d75b791d352.js +1 -0
  160. package/.next/static/chunks/app/_global-error/page-f2d93969c0bcf406.js +1 -0
  161. package/.next/static/chunks/app/_not-found/page-2d40d1d7d916666a.js +1 -0
  162. package/.next/static/chunks/app/api/agent/[id]/events/route-f2d93969c0bcf406.js +1 -0
  163. package/.next/static/chunks/app/api/agent/[id]/route-f2d93969c0bcf406.js +1 -0
  164. package/.next/static/chunks/app/api/agent/[id]/tree/route-f2d93969c0bcf406.js +1 -0
  165. package/.next/static/chunks/app/api/agent/new/route-f2d93969c0bcf406.js +1 -0
  166. package/.next/static/chunks/app/api/agent/resources/route-f2d93969c0bcf406.js +1 -0
  167. package/.next/static/chunks/app/api/config/route-f2d93969c0bcf406.js +1 -0
  168. package/.next/static/chunks/app/api/files/route-f2d93969c0bcf406.js +1 -0
  169. package/.next/static/chunks/app/api/fs/route-f2d93969c0bcf406.js +1 -0
  170. package/.next/static/chunks/app/api/git/route-f2d93969c0bcf406.js +1 -0
  171. package/.next/static/chunks/app/api/github/route-f2d93969c0bcf406.js +1 -0
  172. package/.next/static/chunks/app/api/growth/route-f2d93969c0bcf406.js +1 -0
  173. package/.next/static/chunks/app/api/health/route-f2d93969c0bcf406.js +1 -0
  174. package/.next/static/chunks/app/api/models/defaults/route-f2d93969c0bcf406.js +1 -0
  175. package/.next/static/chunks/app/api/models/route-f2d93969c0bcf406.js +1 -0
  176. package/.next/static/chunks/app/api/pi-settings/route-f2d93969c0bcf406.js +1 -0
  177. package/.next/static/chunks/app/api/plugins/route-f2d93969c0bcf406.js +1 -0
  178. package/.next/static/chunks/app/api/prompts/route-f2d93969c0bcf406.js +1 -0
  179. package/.next/static/chunks/app/api/remote/route-f2d93969c0bcf406.js +1 -0
  180. package/.next/static/chunks/app/api/security/route-f2d93969c0bcf406.js +1 -0
  181. package/.next/static/chunks/app/api/sessions/[id]/export/route-f2d93969c0bcf406.js +1 -0
  182. package/.next/static/chunks/app/api/sessions/[id]/route-f2d93969c0bcf406.js +1 -0
  183. package/.next/static/chunks/app/api/sessions/import/route-f2d93969c0bcf406.js +1 -0
  184. package/.next/static/chunks/app/api/sessions/route-f2d93969c0bcf406.js +1 -0
  185. package/.next/static/chunks/app/api/skills/route-f2d93969c0bcf406.js +1 -0
  186. package/.next/static/chunks/app/api/update/route-f2d93969c0bcf406.js +1 -0
  187. package/.next/static/chunks/app/api/version/route-f2d93969c0bcf406.js +1 -0
  188. package/.next/static/chunks/app/api/web-auth/route-f2d93969c0bcf406.js +1 -0
  189. package/.next/static/chunks/app/api/workspaces/route-f2d93969c0bcf406.js +1 -0
  190. package/.next/static/chunks/app/{layout-7f64fa67ea6ce980.js → layout-50d06e2078d6ce76.js} +1 -1
  191. package/.next/static/chunks/app/login/{page-00dbd2f395b364d5.js → page-5e276a1eeb8867df.js} +1 -1
  192. package/.next/static/chunks/app/page-71f2d3b3ed864b3d.js +1 -0
  193. package/.next/static/chunks/main-5403f0764579e5fe.js +5 -0
  194. package/.next/static/chunks/{main-app-56863ace24eb152f.js → main-app-e9b53f0e1c6591b2.js} +1 -1
  195. package/.next/static/chunks/next/dist/client/components/builtin/app-error-f2d93969c0bcf406.js +1 -0
  196. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-f2d93969c0bcf406.js +1 -0
  197. package/.next/static/chunks/next/dist/client/components/builtin/global-error-a7e260f8cc2582d7.js +1 -0
  198. package/.next/static/chunks/next/dist/client/components/builtin/not-found-f2d93969c0bcf406.js +1 -0
  199. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-f2d93969c0bcf406.js +1 -0
  200. package/.next/static/chunks/webpack-ffc09b5fcc8aaa6d.js +1 -0
  201. package/.next/static/css/7e3caf797e4cb19a.css +1 -0
  202. package/.next/types/app/api/agent/[id]/events/route.ts +1 -1
  203. package/.next/types/app/api/agent/[id]/route.ts +1 -1
  204. package/.next/types/app/api/agent/[id]/tree/route.ts +1 -1
  205. package/.next/types/app/api/agent/new/route.ts +1 -1
  206. package/.next/types/app/api/agent/resources/route.ts +355 -0
  207. package/.next/types/app/api/config/route.ts +1 -1
  208. package/.next/types/app/api/files/route.ts +1 -1
  209. package/.next/types/app/api/fs/route.ts +1 -1
  210. package/.next/types/app/api/git/route.ts +1 -1
  211. package/.next/types/app/api/github/route.ts +1 -1
  212. package/.next/types/app/api/growth/route.ts +1 -1
  213. package/.next/types/app/api/health/route.ts +1 -1
  214. package/.next/types/app/api/models/defaults/route.ts +1 -1
  215. package/.next/types/app/api/models/route.ts +1 -1
  216. package/.next/types/app/api/pi-settings/route.ts +1 -1
  217. package/.next/types/app/api/plugins/route.ts +1 -1
  218. package/.next/types/app/api/prompts/route.ts +1 -1
  219. package/.next/types/app/api/remote/route.ts +1 -1
  220. package/.next/types/app/api/security/route.ts +1 -1
  221. package/.next/types/app/api/sessions/[id]/export/route.ts +1 -1
  222. package/.next/types/app/api/sessions/[id]/route.ts +1 -1
  223. package/.next/types/app/api/sessions/import/route.ts +1 -1
  224. package/.next/types/app/api/sessions/route.ts +1 -1
  225. package/.next/types/app/api/skills/route.ts +1 -1
  226. package/.next/types/app/api/update/route.ts +1 -1
  227. package/.next/types/app/api/version/route.ts +1 -1
  228. package/.next/types/app/api/web-auth/route.ts +1 -1
  229. package/.next/types/app/api/workspaces/route.ts +1 -1
  230. package/.next/types/app/layout.ts +1 -1
  231. package/.next/types/app/login/page.ts +1 -1
  232. package/.next/types/app/page.ts +1 -1
  233. package/.next/types/routes.d.ts +2 -1
  234. package/.next/types/validator.ts +10 -0
  235. package/LICENSE +1 -1
  236. package/README.md +1 -1
  237. package/bin/pi.js +0 -0
  238. package/bin/piweb.js +0 -0
  239. package/package.json +1 -1
  240. package/scripts/build-output.mjs +0 -0
  241. package/scripts/dev.mjs +0 -0
  242. package/scripts/entrypoint.mjs +0 -0
  243. package/scripts/install-build.mjs +0 -0
  244. package/scripts/launcher.mjs +0 -0
  245. package/scripts/pick-folder.ps1 +0 -0
  246. package/scripts/postinstall.mjs +0 -0
  247. package/scripts/process-runner.mjs +0 -0
  248. package/scripts/release.mjs +0 -0
  249. package/scripts/sync-file-icons.mjs +0 -0
  250. package/scripts/sync-provider-icons.mjs +0 -0
  251. package/src/app/api/agent/resources/route.ts +18 -0
  252. package/src/app/api/remote/route.ts +5 -7
  253. package/src/app/api/sessions/[id]/export/route.ts +3 -1
  254. package/src/app/globals.css +16 -0
  255. package/src/components/AppShell.tsx +68 -21
  256. package/src/components/ChatInput.tsx +98 -27
  257. package/src/components/ChatWindow.tsx +68 -11
  258. package/src/components/ContextMeter.tsx +24 -4
  259. package/src/components/ExtensionUI.tsx +9 -3
  260. package/src/components/FileViewer.tsx +24 -21
  261. package/src/components/GitPanel.tsx +449 -449
  262. package/src/components/GrowthTree.tsx +3 -1
  263. package/src/components/ImageViewer.tsx +72 -0
  264. package/src/components/MarkdownBlock.tsx +6 -3
  265. package/src/components/PreviewImage.tsx +33 -0
  266. package/src/components/ProjectPanel.tsx +5 -3
  267. package/src/components/PromptPanel.tsx +322 -313
  268. package/src/components/RemoteSection.tsx +2 -1
  269. package/src/components/SessionSidebar.tsx +22 -4
  270. package/src/components/SettingsPanel.tsx +2654 -2639
  271. package/src/components/composer/ComposerImages.tsx +1 -79
  272. package/src/hooks/usePiWeb.ts +47 -2
  273. package/src/i18n.tsx +24 -0
  274. package/src/lib/agent-manager.ts +275 -18
  275. package/src/lib/chat/skill-expansion.ts +10 -0
  276. package/src/lib/extension-ui.ts +25 -1
  277. package/src/lib/git-service.ts +291 -289
  278. package/src/lib/github-identity.ts +245 -245
  279. package/src/lib/growth-turns.ts +3 -1
  280. package/src/lib/session-reader.ts +25 -13
  281. package/src/lib/session-retention.ts +11 -8
  282. package/src/lib/slash-command-token.ts +14 -0
  283. package/src/lib/trajectory.ts +17 -6
  284. package/src/lib/types.ts +24 -2
  285. package/src/lib/workspace-store.ts +36 -1
  286. package/.next/diagnostics/build-diagnostics.json +0 -6
  287. package/.next/diagnostics/framework.json +0 -1
  288. package/.next/server/chunks/229.js +0 -1
  289. package/.next/server/chunks/393.js +0 -1
  290. package/.next/server/chunks/612.js +0 -1
  291. package/.next/server/chunks/662.js +0 -2
  292. package/.next/server/chunks/686.js +0 -1
  293. package/.next/server/chunks/802.js +0 -2
  294. package/.next/server/chunks/807.js +0 -1
  295. package/.next/server/chunks/924.js +0 -6
  296. package/.next/static/4snUelZTEIiQYCkB5nTW7/_buildManifest.js +0 -1
  297. package/.next/static/chunks/1966.1560d0f43ac9a41a.js +0 -1
  298. package/.next/static/chunks/2577.eebf2cf291a811ad.js +0 -1
  299. package/.next/static/chunks/2716.a5228b0eeedbe4c8.js +0 -1
  300. package/.next/static/chunks/2906.546a64377e12dfbc.js +0 -1
  301. package/.next/static/chunks/3899.55a0943bf5e7fec7.js +0 -1
  302. package/.next/static/chunks/4673.8eff281cb63e2799.js +0 -1
  303. package/.next/static/chunks/4686-f03275819a719fd8.js +0 -1
  304. package/.next/static/chunks/4778.2dae0c6a9e396326.js +0 -1
  305. package/.next/static/chunks/app/_global-error/page-f977af7f858990a2.js +0 -1
  306. package/.next/static/chunks/app/_not-found/page-851dc3883a1937aa.js +0 -1
  307. package/.next/static/chunks/app/api/agent/[id]/events/route-f977af7f858990a2.js +0 -1
  308. package/.next/static/chunks/app/api/agent/[id]/route-f977af7f858990a2.js +0 -1
  309. package/.next/static/chunks/app/api/agent/[id]/tree/route-f977af7f858990a2.js +0 -1
  310. package/.next/static/chunks/app/api/agent/new/route-f977af7f858990a2.js +0 -1
  311. package/.next/static/chunks/app/api/config/route-f977af7f858990a2.js +0 -1
  312. package/.next/static/chunks/app/api/files/route-f977af7f858990a2.js +0 -1
  313. package/.next/static/chunks/app/api/fs/route-f977af7f858990a2.js +0 -1
  314. package/.next/static/chunks/app/api/git/route-f977af7f858990a2.js +0 -1
  315. package/.next/static/chunks/app/api/github/route-f977af7f858990a2.js +0 -1
  316. package/.next/static/chunks/app/api/growth/route-f977af7f858990a2.js +0 -1
  317. package/.next/static/chunks/app/api/health/route-f977af7f858990a2.js +0 -1
  318. package/.next/static/chunks/app/api/models/defaults/route-f977af7f858990a2.js +0 -1
  319. package/.next/static/chunks/app/api/models/route-f977af7f858990a2.js +0 -1
  320. package/.next/static/chunks/app/api/pi-settings/route-f977af7f858990a2.js +0 -1
  321. package/.next/static/chunks/app/api/plugins/route-f977af7f858990a2.js +0 -1
  322. package/.next/static/chunks/app/api/prompts/route-f977af7f858990a2.js +0 -1
  323. package/.next/static/chunks/app/api/remote/route-f977af7f858990a2.js +0 -1
  324. package/.next/static/chunks/app/api/security/route-f977af7f858990a2.js +0 -1
  325. package/.next/static/chunks/app/api/sessions/[id]/export/route-f977af7f858990a2.js +0 -1
  326. package/.next/static/chunks/app/api/sessions/[id]/route-f977af7f858990a2.js +0 -1
  327. package/.next/static/chunks/app/api/sessions/import/route-f977af7f858990a2.js +0 -1
  328. package/.next/static/chunks/app/api/sessions/route-f977af7f858990a2.js +0 -1
  329. package/.next/static/chunks/app/api/skills/route-f977af7f858990a2.js +0 -1
  330. package/.next/static/chunks/app/api/update/route-f977af7f858990a2.js +0 -1
  331. package/.next/static/chunks/app/api/version/route-f977af7f858990a2.js +0 -1
  332. package/.next/static/chunks/app/api/web-auth/route-f977af7f858990a2.js +0 -1
  333. package/.next/static/chunks/app/api/workspaces/route-f977af7f858990a2.js +0 -1
  334. package/.next/static/chunks/app/page-0159987118376f42.js +0 -1
  335. package/.next/static/chunks/main-22ccebc2da4d291e.js +0 -5
  336. package/.next/static/chunks/next/dist/client/components/builtin/app-error-f977af7f858990a2.js +0 -1
  337. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-f977af7f858990a2.js +0 -1
  338. package/.next/static/chunks/next/dist/client/components/builtin/global-error-c37b7707077f50ce.js +0 -1
  339. package/.next/static/chunks/next/dist/client/components/builtin/not-found-f977af7f858990a2.js +0 -1
  340. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-f977af7f858990a2.js +0 -1
  341. package/.next/static/chunks/webpack-c1b43c269867b64f.js +0 -1
  342. package/.next/static/css/93ed3daa6f3fbc35.css +0 -1
  343. package/.next/trace +0 -58
  344. package/.next/trace-build +0 -1
  345. /package/.next/static/{4snUelZTEIiQYCkB5nTW7 → QJCtqgDKzGS2BdKABd9ch}/_ssgManifest.js +0 -0
@@ -1,313 +1,322 @@
1
- "use client";
2
- /**
3
- * 提示词面板:把"发给模型的提示词从哪来"集中列出来,点某一项查看原文。
4
- *
5
- * 只读:文件类来源的路径来自 Pi 资源加载器(项目记忆 / 系统提示词覆盖 / 追加提示词 /
6
- * 技能 / 提示模板,含扩展与 npm 包提供的那些);热会话额外给出"组装后的系统提示词"
7
- * 与每个工具的定义,它们不是文件、没有路径,直接在本面板内展开查看。
8
- */
9
- import { useCallback, useEffect, useState } from "react";
10
- import { useI18n } from "@/i18n";
11
- import { fmtBytes } from "@/lib/format";
12
- import { IconRefreshOutline14, IconCloseOutline14 } from "@/components/icons";
13
-
14
- export type PromptSourceKind = "system" | "append" | "agents" | "skill" | "template" | "tool" | "assembled";
15
-
16
- export interface PromptSourceOrigin {
17
- scope: "project" | "agent" | "package" | "extension";
18
- name?: string;
19
- }
20
-
21
- export interface PromptSource {
22
- kind: PromptSourceKind;
23
- name: string;
24
- path?: string;
25
- origin: PromptSourceOrigin;
26
- bytes?: number;
27
- }
28
-
29
- export interface PromptToolView {
30
- name: string;
31
- description?: string;
32
- parameters?: unknown;
33
- promptGuidelines?: string[];
34
- source: "builtin" | "extension";
35
- }
36
-
37
- export interface PromptSourcesData {
38
- sources: PromptSource[];
39
- assembledSystemPrompt?: string;
40
- /** 压缩摘要(同样进入上下文) */
41
- compactedSummary?: string;
42
- tools?: PromptToolView[];
43
- sessionReady: boolean;
44
- }
45
-
46
- const GROUP_KINDS: PromptSourceKind[] = ["system", "append", "agents", "skill", "template", "tool", "assembled"];
47
-
48
- function formatBytes(bytes: number | undefined): string {
49
- return bytes ? fmtBytes(bytes) : "";
50
- }
51
-
52
- export function PromptPanel({
53
- cwd,
54
- sessionId,
55
- refreshKey,
56
- onOpenContent,
57
- onClose,
58
- }: {
59
- cwd: string;
60
- sessionId: string | null;
61
- /** 变化即重新拉取(例如切换会话) */
62
- refreshKey?: string | number | null;
63
- /** 打开查看器显示内容(复用应用现有的文件查看器) */
64
- onOpenContent?: (path: string, content: string) => void;
65
- onClose: () => void;
66
- }) {
67
- const { t } = useI18n();
68
- const [data, setData] = useState<PromptSourcesData | null>(null);
69
- const [error, setError] = useState<string | null>(null);
70
- const [busy, setBusy] = useState(false);
71
- const [opening, setOpening] = useState<string | null>(null);
72
-
73
- const load = useCallback(async () => {
74
- setBusy(true);
75
- setError(null);
76
- try {
77
- const query = new URLSearchParams({ cwd });
78
- if (sessionId) query.set("session", sessionId);
79
- const response = await fetch(`/api/prompts?${query.toString()}`);
80
- const body = await response.json();
81
- if (!response.ok || !body.success) throw new Error(body.error || `request failed (${response.status})`);
82
- setData(body.data as PromptSourcesData);
83
- } catch (err) {
84
- setError(err instanceof Error ? err.message : String(err));
85
- } finally {
86
- setBusy(false);
87
- }
88
- }, [cwd, sessionId]);
89
-
90
- useEffect(() => {
91
- void load();
92
- }, [load, refreshKey]);
93
-
94
- const originLabel = (origin: PromptSourceOrigin): string => {
95
- if (origin.scope === "project") return t.promptOriginProject;
96
- if (origin.scope === "agent") return t.promptOriginAgent;
97
- if (origin.scope === "package") return `${t.promptOriginPackage} ${origin.name ?? ""}`.trim();
98
- return `${t.promptOriginExtension} ${origin.name ?? ""}`.trim();
99
- };
100
-
101
- const kindLabel = (kind: PromptSourceKind): string => {
102
- switch (kind) {
103
- case "system": return t.promptKindSystem;
104
- case "append": return t.promptKindAppend;
105
- case "agents": return t.promptKindAgents;
106
- case "skill": return t.promptKindSkill;
107
- case "template": return t.promptKindTemplate;
108
- case "tool": return t.promptKindTool;
109
- case "assembled": return t.promptKindAssembled;
110
- }
111
- };
112
-
113
- /** 文件类:按需读内容,交给外部查看器 */
114
- const openFile = async (source: PromptSource) => {
115
- if (!source.path || !onOpenContent) return;
116
- setOpening(source.path);
117
- setError(null);
118
- try {
119
- const response = await fetch("/api/prompts", {
120
- method: "POST",
121
- headers: { "Content-Type": "application/json" },
122
- body: JSON.stringify({ action: "read", filePath: source.path, cwd }),
123
- });
124
- const body = await response.json();
125
- if (!response.ok || !body.success) throw new Error(body.error || "read failed");
126
- onOpenContent(source.path, body.data.content as string);
127
- } catch (err) {
128
- setError(err instanceof Error ? err.message : String(err));
129
- } finally {
130
- setOpening(null);
131
- }
132
- };
133
-
134
- const groups = GROUP_KINDS.map((kind) => ({ kind, items: (data?.sources ?? []).filter((source) => source.kind === kind) })).filter(
135
- (group) => group.items.length > 0,
136
- );
137
- const hasTools = (data?.tools?.length ?? 0) > 0;
138
-
139
- return (
140
- <div className="flex min-h-0 flex-1 flex-col">
141
- <div className="hairline-b flex items-center gap-2 px-4 py-2.5">
142
- <span className="min-w-0 flex-1 truncate" style={{ fontSize: 13.5, fontWeight: 600 }}>{t.promptPanel}</span>
143
- <button type="button" className="icon-btn" style={{ width: 26, height: 26 }} title={t.promptRefresh} aria-label={t.promptRefresh} onClick={() => void load()}>
144
- <span className={busy ? "piweb-spin" : undefined} style={{ display: "inline-flex" }}>
145
- <IconRefreshOutline14 size={14} />
146
- </span>
147
- </button>
148
- <button type="button" className="icon-btn" style={{ width: 26, height: 26 }} title={t.close} aria-label={t.close} onClick={onClose}>
149
- <IconCloseOutline14 size={14} />
150
- </button>
151
- </div>
152
- <div className="min-h-0 flex-1 overflow-auto px-3 py-3" style={{ fontSize: 12.5 }}>
153
- {error && (
154
- <div className="mb-2 rounded-lg px-2 py-1.5" style={{ background: "var(--dsw-hover)", color: "var(--dsw-danger)" }} role="alert">
155
- {error}
156
- </div>
157
- )}
158
- {!data && busy && <div style={{ color: "var(--dsw-label-tertiary)" }}>{t.promptLoading}</div>}
159
- {data && !data.sessionReady && (
160
- <div className="mb-2 rounded-lg px-2 py-1.5" style={{ background: "var(--dsw-hover)", color: "var(--dsw-label-caption)" }} role="status">
161
- {t.promptColdHint}
162
- </div>
163
- )}
164
-
165
- {groups.map((group) => (
166
- <section key={group.kind} className="mb-3">
167
- <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{kindLabel(group.kind)}</div>
168
- <div className="flex flex-col gap-1.5">
169
- {group.items.map((source) => (
170
- <button
171
- key={`${source.kind}:${source.path ?? source.name}`}
172
- type="button"
173
- className="flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left transition-all"
174
- style={{
175
- background: opening === source.path ? "var(--dsw-active)" : "var(--dsw-bg-elevated)",
176
- border: "1px solid var(--dsw-border-l2)",
177
- transition: "all 0.2s var(--isx-ease)",
178
- }}
179
- title={source.path ?? source.name}
180
- onMouseEnter={(e) => {
181
- e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
182
- e.currentTarget.style.background = "var(--dsw-hover)";
183
- e.currentTarget.style.transform = "translateY(-1px)";
184
- }}
185
- onMouseLeave={(e) => {
186
- e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
187
- e.currentTarget.style.background = opening === source.path ? "var(--dsw-active)" : "var(--dsw-bg-elevated)";
188
- e.currentTarget.style.transform = "none";
189
- }}
190
- onClick={() => void openFile(source)}
191
- >
192
- <span className="min-w-0 flex-1 truncate font-medium" style={{ color: "var(--dsw-label-primary)" }}>{source.name}</span>
193
- <span className="flex-none font-mono" style={{ fontSize: 10.5, color: "var(--dsw-label-tertiary)" }}>{formatBytes(source.bytes)}</span>
194
- <span className="flex-none rounded-full px-2 py-0.5" style={{ fontSize: 10.5, border: "1px solid var(--dsw-border-l2)", color: "var(--dsw-label-tertiary)", background: "var(--dsw-bg-base)" }}>
195
- {originLabel(source.origin)}
196
- </span>
197
- </button>
198
- ))}
199
- </div>
200
- </section>
201
- ))}
202
-
203
- {hasTools && (
204
- <section className="mb-3">
205
- <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{t.promptKindTool}</div>
206
- <div className="flex flex-col gap-1.5">
207
- {data!.tools!.map((tool) => (
208
- <button
209
- key={`tool:${tool.name}`}
210
- type="button"
211
- className="flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left transition-all"
212
- style={{
213
- border: "1px solid var(--dsw-border-l2)",
214
- background: "var(--dsw-bg-elevated)",
215
- transition: "all 0.2s var(--isx-ease)",
216
- }}
217
- title={tool.name}
218
- onMouseEnter={(e) => {
219
- e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
220
- e.currentTarget.style.background = "var(--dsw-hover)";
221
- e.currentTarget.style.transform = "translateY(-1px)";
222
- }}
223
- onMouseLeave={(e) => {
224
- e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
225
- e.currentTarget.style.background = "var(--dsw-bg-elevated)";
226
- e.currentTarget.style.transform = "none";
227
- }}
228
- onClick={() =>
229
- onOpenContent?.(
230
- `tool-${tool.name}.md`,
231
- [
232
- `# ${tool.name}`,
233
- tool.source === "builtin" ? t.promptToolBuiltin : t.promptToolExtension,
234
- tool.description ?? "",
235
- ...(tool.promptGuidelines?.length ? [t.promptGuidelines, ...tool.promptGuidelines.map((line) => `- ${line}`)] : []),
236
- ...(tool.parameters ? [t.promptParameters, "```json", JSON.stringify(tool.parameters, null, 2), "```"] : []),
237
- ]
238
- .filter(Boolean)
239
- .join("\n\n"),
240
- )
241
- }
242
- >
243
- <span className="min-w-0 flex-1 truncate font-mono text-[12px] font-semibold" style={{ color: "var(--dsw-label-primary)" }}>{tool.name}</span>
244
- <span className="flex-none rounded-full px-2 py-0.5" style={{ fontSize: 10.5, border: "1px solid var(--dsw-border-l2)", color: "var(--dsw-label-tertiary)", background: "var(--dsw-bg-base)" }}>
245
- {tool.source === "builtin" ? t.promptToolBuiltin : t.promptToolExtension}
246
- </span>
247
- </button>
248
- ))}
249
- </div>
250
- </section>
251
- )}
252
-
253
- {data?.assembledSystemPrompt && (
254
- <section className="mb-3">
255
- <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{t.promptKindAssembled}</div>
256
- <button
257
- type="button"
258
- className="w-full rounded-xl px-2.5 py-2 text-left transition-all"
259
- style={{
260
- border: "1px solid var(--dsw-border-l2)",
261
- background: "var(--dsw-bg-elevated)",
262
- transition: "all 0.2s var(--isx-ease)",
263
- }}
264
- title={t.promptAssembledKey}
265
- onMouseEnter={(e) => {
266
- e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
267
- e.currentTarget.style.background = "var(--dsw-hover)";
268
- e.currentTarget.style.transform = "translateY(-1px)";
269
- }}
270
- onMouseLeave={(e) => {
271
- e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
272
- e.currentTarget.style.background = "var(--dsw-bg-elevated)";
273
- e.currentTarget.style.transform = "none";
274
- }}
275
- onClick={() => onOpenContent?.("system-prompt.md", data.assembledSystemPrompt ?? "")}
276
- >
277
- <span className="truncate font-medium" style={{ color: "var(--dsw-label-primary)" }}>{t.promptAssembledKey}</span>
278
- </button>
279
- </section>
280
- )}
281
-
282
- {data?.compactedSummary && (
283
- <section className="mb-3">
284
- <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{t.promptKindCompacted}</div>
285
- <button
286
- type="button"
287
- className="w-full rounded-xl px-2.5 py-2 text-left transition-all"
288
- style={{
289
- border: "1px solid var(--dsw-border-l2)",
290
- background: "var(--dsw-bg-elevated)",
291
- transition: "all 0.2s var(--isx-ease)",
292
- }}
293
- title={t.promptCompactedKey}
294
- onMouseEnter={(e) => {
295
- e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
296
- e.currentTarget.style.background = "var(--dsw-hover)";
297
- e.currentTarget.style.transform = "translateY(-1px)";
298
- }}
299
- onMouseLeave={(e) => {
300
- e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
301
- e.currentTarget.style.background = "var(--dsw-bg-elevated)";
302
- e.currentTarget.style.transform = "none";
303
- }}
304
- onClick={() => onOpenContent?.("compacted-summary.md", data.compactedSummary ?? "")}
305
- >
306
- <span className="truncate font-medium" style={{ color: "var(--dsw-label-primary)" }}>{t.promptCompactedKey}</span>
307
- </button>
308
- </section>
309
- )}
310
- </div>
311
- </div>
312
- );
313
- }
1
+ "use client";
2
+ /**
3
+ * 提示词面板:把"发给模型的提示词从哪来"集中列出来,点某一项查看原文。
4
+ *
5
+ * 只读:文件类来源的路径来自 Pi 资源加载器(项目记忆 / 系统提示词覆盖 / 追加提示词 /
6
+ * 技能 / 提示模板,含扩展与 npm 包提供的那些);热会话额外给出"组装后的系统提示词"
7
+ * 与每个工具的定义,它们不是文件、没有路径,直接在本面板内展开查看。
8
+ */
9
+ import { useCallback, useEffect, useRef, useState } from "react";
10
+ import { useI18n } from "@/i18n";
11
+ import { fmtBytes } from "@/lib/format";
12
+ import { IconRefreshOutline14, IconCloseOutline14 } from "@/components/icons";
13
+
14
+ export type PromptSourceKind = "system" | "append" | "agents" | "skill" | "template" | "tool" | "assembled";
15
+
16
+ export interface PromptSourceOrigin {
17
+ scope: "project" | "agent" | "package" | "extension";
18
+ name?: string;
19
+ }
20
+
21
+ export interface PromptSource {
22
+ kind: PromptSourceKind;
23
+ name: string;
24
+ path?: string;
25
+ origin: PromptSourceOrigin;
26
+ bytes?: number;
27
+ }
28
+
29
+ export interface PromptToolView {
30
+ name: string;
31
+ description?: string;
32
+ parameters?: unknown;
33
+ promptGuidelines?: string[];
34
+ source: "builtin" | "extension";
35
+ }
36
+
37
+ export interface PromptSourcesData {
38
+ sources: PromptSource[];
39
+ assembledSystemPrompt?: string;
40
+ /** 压缩摘要(同样进入上下文) */
41
+ compactedSummary?: string;
42
+ tools?: PromptToolView[];
43
+ sessionReady: boolean;
44
+ }
45
+
46
+ const GROUP_KINDS: PromptSourceKind[] = ["system", "append", "agents", "skill", "template", "tool", "assembled"];
47
+
48
+ function formatBytes(bytes: number | undefined): string {
49
+ return bytes ? fmtBytes(bytes) : "";
50
+ }
51
+
52
+ export function PromptPanel({
53
+ cwd,
54
+ sessionId,
55
+ refreshKey,
56
+ onOpenContent,
57
+ onClose,
58
+ }: {
59
+ cwd: string;
60
+ sessionId: string | null;
61
+ /** 变化即重新拉取(例如切换会话) */
62
+ refreshKey?: string | number | null;
63
+ /** 打开查看器显示内容(复用应用现有的文件查看器) */
64
+ onOpenContent?: (path: string, content: string) => void;
65
+ onClose: () => void;
66
+ }) {
67
+ const { t } = useI18n();
68
+ const [data, setData] = useState<PromptSourcesData | null>(null);
69
+ const [error, setError] = useState<string | null>(null);
70
+ const [busy, setBusy] = useState(false);
71
+ const [opening, setOpening] = useState<string | null>(null);
72
+ /** 只认最后一次请求:快速切会话时,先发的请求后回来会把上一个会话的提示词盖到当前会话上 */
73
+ const latestRequest = useRef(0);
74
+
75
+ const load = useCallback(async () => {
76
+ const request = ++latestRequest.current;
77
+ setBusy(true);
78
+ setError(null);
79
+ try {
80
+ const query = new URLSearchParams({ cwd });
81
+ if (sessionId) query.set("session", sessionId);
82
+ const response = await fetch(`/api/prompts?${query.toString()}`);
83
+ const body = await response.json();
84
+ if (request !== latestRequest.current) return;
85
+ if (!response.ok || !body.success) throw new Error(body.error || `request failed (${response.status})`);
86
+ setData(body.data as PromptSourcesData);
87
+ } catch (err) {
88
+ if (request === latestRequest.current) setError(err instanceof Error ? err.message : String(err));
89
+ } finally {
90
+ if (request === latestRequest.current) setBusy(false);
91
+ }
92
+ }, [cwd, sessionId]);
93
+
94
+ // 换了工作区/会话:先清掉上一个的内容,别在加载期间把旧会话的提示词当成当前的
95
+ useEffect(() => {
96
+ setData(null);
97
+ }, [cwd, sessionId]);
98
+
99
+ useEffect(() => {
100
+ void load();
101
+ }, [load, refreshKey]);
102
+
103
+ const originLabel = (origin: PromptSourceOrigin): string => {
104
+ if (origin.scope === "project") return t.promptOriginProject;
105
+ if (origin.scope === "agent") return t.promptOriginAgent;
106
+ if (origin.scope === "package") return `${t.promptOriginPackage} ${origin.name ?? ""}`.trim();
107
+ return `${t.promptOriginExtension} ${origin.name ?? ""}`.trim();
108
+ };
109
+
110
+ const kindLabel = (kind: PromptSourceKind): string => {
111
+ switch (kind) {
112
+ case "system": return t.promptKindSystem;
113
+ case "append": return t.promptKindAppend;
114
+ case "agents": return t.promptKindAgents;
115
+ case "skill": return t.promptKindSkill;
116
+ case "template": return t.promptKindTemplate;
117
+ case "tool": return t.promptKindTool;
118
+ case "assembled": return t.promptKindAssembled;
119
+ }
120
+ };
121
+
122
+ /** 文件类:按需读内容,交给外部查看器 */
123
+ const openFile = async (source: PromptSource) => {
124
+ if (!source.path || !onOpenContent) return;
125
+ setOpening(source.path);
126
+ setError(null);
127
+ try {
128
+ const response = await fetch("/api/prompts", {
129
+ method: "POST",
130
+ headers: { "Content-Type": "application/json" },
131
+ body: JSON.stringify({ action: "read", filePath: source.path, cwd }),
132
+ });
133
+ const body = await response.json();
134
+ if (!response.ok || !body.success) throw new Error(body.error || "read failed");
135
+ onOpenContent(source.path, body.data.content as string);
136
+ } catch (err) {
137
+ setError(err instanceof Error ? err.message : String(err));
138
+ } finally {
139
+ setOpening(null);
140
+ }
141
+ };
142
+
143
+ const groups = GROUP_KINDS.map((kind) => ({ kind, items: (data?.sources ?? []).filter((source) => source.kind === kind) })).filter(
144
+ (group) => group.items.length > 0,
145
+ );
146
+ const hasTools = (data?.tools?.length ?? 0) > 0;
147
+
148
+ return (
149
+ <div className="flex min-h-0 flex-1 flex-col">
150
+ <div className="hairline-b flex items-center gap-2 px-4 py-2.5">
151
+ <span className="min-w-0 flex-1 truncate" style={{ fontSize: 13.5, fontWeight: 600 }}>{t.promptPanel}</span>
152
+ <button type="button" className="icon-btn" style={{ width: 26, height: 26 }} title={t.promptRefresh} aria-label={t.promptRefresh} onClick={() => void load()}>
153
+ <span className={busy ? "piweb-spin" : undefined} style={{ display: "inline-flex" }}>
154
+ <IconRefreshOutline14 size={14} />
155
+ </span>
156
+ </button>
157
+ <button type="button" className="icon-btn" style={{ width: 26, height: 26 }} title={t.close} aria-label={t.close} onClick={onClose}>
158
+ <IconCloseOutline14 size={14} />
159
+ </button>
160
+ </div>
161
+ <div className="min-h-0 flex-1 overflow-auto px-3 py-3" style={{ fontSize: 12.5 }}>
162
+ {error && (
163
+ <div className="mb-2 rounded-lg px-2 py-1.5" style={{ background: "var(--dsw-hover)", color: "var(--dsw-danger)" }} role="alert">
164
+ {error}
165
+ </div>
166
+ )}
167
+ {!data && busy && <div style={{ color: "var(--dsw-label-tertiary)" }}>{t.promptLoading}</div>}
168
+ {data && !data.sessionReady && (
169
+ <div className="mb-2 rounded-lg px-2 py-1.5" style={{ background: "var(--dsw-hover)", color: "var(--dsw-label-caption)" }} role="status">
170
+ {t.promptColdHint}
171
+ </div>
172
+ )}
173
+
174
+ {groups.map((group) => (
175
+ <section key={group.kind} className="mb-3">
176
+ <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{kindLabel(group.kind)}</div>
177
+ <div className="flex flex-col gap-1.5">
178
+ {group.items.map((source) => (
179
+ <button
180
+ key={`${source.kind}:${source.path ?? source.name}`}
181
+ type="button"
182
+ className="flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left transition-all"
183
+ style={{
184
+ background: opening === source.path ? "var(--dsw-active)" : "var(--dsw-bg-elevated)",
185
+ border: "1px solid var(--dsw-border-l2)",
186
+ transition: "all 0.2s var(--isx-ease)",
187
+ }}
188
+ title={source.path ?? source.name}
189
+ onMouseEnter={(e) => {
190
+ e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
191
+ e.currentTarget.style.background = "var(--dsw-hover)";
192
+ e.currentTarget.style.transform = "translateY(-1px)";
193
+ }}
194
+ onMouseLeave={(e) => {
195
+ e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
196
+ e.currentTarget.style.background = opening === source.path ? "var(--dsw-active)" : "var(--dsw-bg-elevated)";
197
+ e.currentTarget.style.transform = "none";
198
+ }}
199
+ onClick={() => void openFile(source)}
200
+ >
201
+ <span className="min-w-0 flex-1 truncate font-medium" style={{ color: "var(--dsw-label-primary)" }}>{source.name}</span>
202
+ <span className="flex-none font-mono" style={{ fontSize: 10.5, color: "var(--dsw-label-tertiary)" }}>{formatBytes(source.bytes)}</span>
203
+ <span className="flex-none rounded-full px-2 py-0.5" style={{ fontSize: 10.5, border: "1px solid var(--dsw-border-l2)", color: "var(--dsw-label-tertiary)", background: "var(--dsw-bg-base)" }}>
204
+ {originLabel(source.origin)}
205
+ </span>
206
+ </button>
207
+ ))}
208
+ </div>
209
+ </section>
210
+ ))}
211
+
212
+ {hasTools && (
213
+ <section className="mb-3">
214
+ <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{t.promptKindTool}</div>
215
+ <div className="flex flex-col gap-1.5">
216
+ {data!.tools!.map((tool) => (
217
+ <button
218
+ key={`tool:${tool.name}`}
219
+ type="button"
220
+ className="flex w-full items-center gap-2 rounded-xl px-2.5 py-2 text-left transition-all"
221
+ style={{
222
+ border: "1px solid var(--dsw-border-l2)",
223
+ background: "var(--dsw-bg-elevated)",
224
+ transition: "all 0.2s var(--isx-ease)",
225
+ }}
226
+ title={tool.name}
227
+ onMouseEnter={(e) => {
228
+ e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
229
+ e.currentTarget.style.background = "var(--dsw-hover)";
230
+ e.currentTarget.style.transform = "translateY(-1px)";
231
+ }}
232
+ onMouseLeave={(e) => {
233
+ e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
234
+ e.currentTarget.style.background = "var(--dsw-bg-elevated)";
235
+ e.currentTarget.style.transform = "none";
236
+ }}
237
+ onClick={() =>
238
+ onOpenContent?.(
239
+ `tool-${tool.name}.md`,
240
+ [
241
+ `# ${tool.name}`,
242
+ tool.source === "builtin" ? t.promptToolBuiltin : t.promptToolExtension,
243
+ tool.description ?? "",
244
+ ...(tool.promptGuidelines?.length ? [t.promptGuidelines, ...tool.promptGuidelines.map((line) => `- ${line}`)] : []),
245
+ ...(tool.parameters ? [t.promptParameters, "```json", JSON.stringify(tool.parameters, null, 2), "```"] : []),
246
+ ]
247
+ .filter(Boolean)
248
+ .join("\n\n"),
249
+ )
250
+ }
251
+ >
252
+ <span className="min-w-0 flex-1 truncate font-mono text-[12px] font-semibold" style={{ color: "var(--dsw-label-primary)" }}>{tool.name}</span>
253
+ <span className="flex-none rounded-full px-2 py-0.5" style={{ fontSize: 10.5, border: "1px solid var(--dsw-border-l2)", color: "var(--dsw-label-tertiary)", background: "var(--dsw-bg-base)" }}>
254
+ {tool.source === "builtin" ? t.promptToolBuiltin : t.promptToolExtension}
255
+ </span>
256
+ </button>
257
+ ))}
258
+ </div>
259
+ </section>
260
+ )}
261
+
262
+ {data?.assembledSystemPrompt && (
263
+ <section className="mb-3">
264
+ <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{t.promptKindAssembled}</div>
265
+ <button
266
+ type="button"
267
+ className="w-full rounded-xl px-2.5 py-2 text-left transition-all"
268
+ style={{
269
+ border: "1px solid var(--dsw-border-l2)",
270
+ background: "var(--dsw-bg-elevated)",
271
+ transition: "all 0.2s var(--isx-ease)",
272
+ }}
273
+ title={t.promptAssembledKey}
274
+ onMouseEnter={(e) => {
275
+ e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
276
+ e.currentTarget.style.background = "var(--dsw-hover)";
277
+ e.currentTarget.style.transform = "translateY(-1px)";
278
+ }}
279
+ onMouseLeave={(e) => {
280
+ e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
281
+ e.currentTarget.style.background = "var(--dsw-bg-elevated)";
282
+ e.currentTarget.style.transform = "none";
283
+ }}
284
+ onClick={() => onOpenContent?.("system-prompt.md", data.assembledSystemPrompt ?? "")}
285
+ >
286
+ <span className="truncate font-medium" style={{ color: "var(--dsw-label-primary)" }}>{t.promptAssembledKey}</span>
287
+ </button>
288
+ </section>
289
+ )}
290
+
291
+ {data?.compactedSummary && (
292
+ <section className="mb-3">
293
+ <div className="mb-1 px-1" style={{ fontSize: 11.5, color: "var(--dsw-label-caption)" }}>{t.promptKindCompacted}</div>
294
+ <button
295
+ type="button"
296
+ className="w-full rounded-xl px-2.5 py-2 text-left transition-all"
297
+ style={{
298
+ border: "1px solid var(--dsw-border-l2)",
299
+ background: "var(--dsw-bg-elevated)",
300
+ transition: "all 0.2s var(--isx-ease)",
301
+ }}
302
+ title={t.promptCompactedKey}
303
+ onMouseEnter={(e) => {
304
+ e.currentTarget.style.borderColor = "var(--dsw-border-l3)";
305
+ e.currentTarget.style.background = "var(--dsw-hover)";
306
+ e.currentTarget.style.transform = "translateY(-1px)";
307
+ }}
308
+ onMouseLeave={(e) => {
309
+ e.currentTarget.style.borderColor = "var(--dsw-border-l2)";
310
+ e.currentTarget.style.background = "var(--dsw-bg-elevated)";
311
+ e.currentTarget.style.transform = "none";
312
+ }}
313
+ onClick={() => onOpenContent?.("compacted-summary.md", data.compactedSummary ?? "")}
314
+ >
315
+ <span className="truncate font-medium" style={{ color: "var(--dsw-label-primary)" }}>{t.promptCompactedKey}</span>
316
+ </button>
317
+ </section>
318
+ )}
319
+ </div>
320
+ </div>
321
+ );
322
+ }