@rexvane/piweb 0.3.16 → 0.3.18

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 (288) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +8 -11
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/prerender-manifest.json +6 -6
  5. package/.next/react-loadable-manifest.json +4 -16
  6. package/.next/required-server-files.js +1 -3
  7. package/.next/required-server-files.json +1 -3
  8. package/.next/routes-manifest.json +0 -20
  9. package/.next/server/app/_global-error/page.js +2 -2
  10. package/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/server/app/_global-error.html +1 -1
  12. package/.next/server/app/_global-error.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  15. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/server/app/_not-found/page.js +1 -1
  17. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/server/app/_not-found.html +1 -1
  19. package/.next/server/app/_not-found.rsc +4 -7
  20. package/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -5
  22. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  23. package/.next/server/app/api/agent/[id]/events/route.js +2 -2
  24. package/.next/server/app/api/agent/[id]/events/route.js.nft.json +1 -1
  25. package/.next/server/app/api/agent/[id]/route.js +1 -1
  26. package/.next/server/app/api/agent/[id]/route.js.nft.json +1 -1
  27. package/.next/server/app/api/agent/[id]/tree/route.js +1 -1
  28. package/.next/server/app/api/agent/[id]/tree/route.js.nft.json +1 -1
  29. package/.next/server/app/api/agent/new/route.js +1 -1
  30. package/.next/server/app/api/agent/new/route.js.nft.json +1 -1
  31. package/.next/server/app/api/config/route.js +1 -1
  32. package/.next/server/app/api/config/route.js.nft.json +1 -1
  33. package/.next/server/app/api/files/route.js +1 -1
  34. package/.next/server/app/api/files/route.js.nft.json +1 -1
  35. package/.next/server/app/api/git/route.js +2 -2
  36. package/.next/server/app/api/git/route.js.nft.json +1 -1
  37. package/.next/server/app/api/growth/route.js +1 -1
  38. package/.next/server/app/api/growth/route.js.nft.json +1 -1
  39. package/.next/server/app/api/health/route.js +1 -1
  40. package/.next/server/app/api/models/route.js +1 -1
  41. package/.next/server/app/api/models/route.js.nft.json +1 -1
  42. package/.next/server/app/api/pi-settings/route.js +1 -1
  43. package/.next/server/app/api/pi-settings/route.js.nft.json +1 -1
  44. package/.next/server/app/api/plugins/route.js +1 -1
  45. package/.next/server/app/api/plugins/route.js.nft.json +1 -1
  46. package/.next/server/app/api/prompts/route.js +1 -1
  47. package/.next/server/app/api/prompts/route.js.nft.json +1 -1
  48. package/.next/server/app/api/security/route.js +1 -1
  49. package/.next/server/app/api/security/route.js.nft.json +1 -1
  50. package/.next/server/app/api/sessions/[id]/export/route.js +1 -1
  51. package/.next/server/app/api/sessions/[id]/export/route.js.nft.json +1 -1
  52. package/.next/server/app/api/sessions/[id]/route.js +1 -1
  53. package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  54. package/.next/server/app/api/sessions/import/route.js +3 -3
  55. package/.next/server/app/api/sessions/import/route.js.nft.json +1 -1
  56. package/.next/server/app/api/sessions/route.js +1 -1
  57. package/.next/server/app/api/sessions/route.js.nft.json +1 -1
  58. package/.next/server/app/api/skills/route.js +2 -2
  59. package/.next/server/app/api/skills/route.js.nft.json +1 -1
  60. package/.next/server/app/api/update/route.js +2 -2
  61. package/.next/server/app/api/update/route.js.nft.json +1 -1
  62. package/.next/server/app/api/version/route.js +1 -1
  63. package/.next/server/app/api/version/route.js.nft.json +1 -1
  64. package/.next/server/app/api/web-auth/route.js +1 -1
  65. package/.next/server/app/api/workspaces/route.js +1 -1
  66. package/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  67. package/.next/server/app/icon.svg/route.js +1 -1
  68. package/.next/server/app/index.html +1 -1
  69. package/.next/server/app/index.rsc +6 -9
  70. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -7
  71. package/.next/server/app/index.segments/_full.segment.rsc +6 -9
  72. package/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  73. package/.next/server/app/login/page.js +1 -1
  74. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app/login.html +1 -1
  76. package/.next/server/app/login.rsc +5 -8
  77. package/.next/server/app/login.segments/_full.segment.rsc +5 -8
  78. package/.next/server/app/login.segments/_tree.segment.rsc +2 -5
  79. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +3 -6
  80. package/.next/server/app/page.js +1 -1
  81. package/.next/server/app/page_client-reference-manifest.js +1 -1
  82. package/.next/server/app-paths-manifest.json +8 -11
  83. package/.next/server/chunks/496.js +1 -1
  84. package/.next/server/chunks/532.js +1 -1
  85. package/.next/server/chunks/686.js +4 -8
  86. package/.next/server/middleware-build-manifest.js +1 -1
  87. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  88. package/.next/server/pages/404.html +1 -1
  89. package/.next/server/pages/500.html +1 -1
  90. package/.next/server/server-reference-manifest.json +1 -1
  91. package/.next/static/chunks/2608.ec8ff1f5767c9056.js +1 -0
  92. package/.next/static/chunks/2716.93be8ad5c970c516.js +1 -0
  93. package/.next/static/chunks/4632.112d2e893d48d188.js +1 -0
  94. package/.next/static/chunks/4673.c1fb1580efc6ace7.js +1 -0
  95. package/.next/static/chunks/4686-f4a037d609cea3f2.js +1 -0
  96. package/.next/static/chunks/app/_global-error/page-f77e9ede9808b18e.js +1 -0
  97. package/.next/static/chunks/app/api/agent/[id]/events/route-f77e9ede9808b18e.js +1 -0
  98. package/.next/static/chunks/app/api/agent/[id]/route-f77e9ede9808b18e.js +1 -0
  99. package/.next/static/chunks/app/api/agent/[id]/tree/route-f77e9ede9808b18e.js +1 -0
  100. package/.next/static/chunks/app/api/agent/new/route-f77e9ede9808b18e.js +1 -0
  101. package/.next/static/chunks/app/api/config/route-f77e9ede9808b18e.js +1 -0
  102. package/.next/static/chunks/app/api/files/route-f77e9ede9808b18e.js +1 -0
  103. package/.next/static/chunks/app/api/git/route-f77e9ede9808b18e.js +1 -0
  104. package/.next/static/chunks/app/api/growth/route-f77e9ede9808b18e.js +1 -0
  105. package/.next/static/chunks/app/api/health/route-f77e9ede9808b18e.js +1 -0
  106. package/.next/static/chunks/app/api/models/route-f77e9ede9808b18e.js +1 -0
  107. package/.next/static/chunks/app/api/pi-settings/route-f77e9ede9808b18e.js +1 -0
  108. package/.next/static/chunks/app/api/plugins/route-f77e9ede9808b18e.js +1 -0
  109. package/.next/static/chunks/app/api/prompts/route-f77e9ede9808b18e.js +1 -0
  110. package/.next/static/chunks/app/api/security/route-f77e9ede9808b18e.js +1 -0
  111. package/.next/static/chunks/app/api/sessions/[id]/export/route-f77e9ede9808b18e.js +1 -0
  112. package/.next/static/chunks/app/api/sessions/[id]/route-f77e9ede9808b18e.js +1 -0
  113. package/.next/static/chunks/app/api/sessions/import/route-f77e9ede9808b18e.js +1 -0
  114. package/.next/static/chunks/app/api/sessions/route-f77e9ede9808b18e.js +1 -0
  115. package/.next/static/chunks/app/api/skills/route-f77e9ede9808b18e.js +1 -0
  116. package/.next/static/chunks/app/api/update/route-f77e9ede9808b18e.js +1 -0
  117. package/.next/static/chunks/app/api/version/route-f77e9ede9808b18e.js +1 -0
  118. package/.next/static/chunks/app/api/web-auth/route-f77e9ede9808b18e.js +1 -0
  119. package/.next/static/chunks/app/api/workspaces/route-f77e9ede9808b18e.js +1 -0
  120. package/.next/static/chunks/app/page-b51087831582ee37.js +1 -0
  121. package/.next/static/chunks/next/dist/client/components/builtin/app-error-f77e9ede9808b18e.js +1 -0
  122. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-f77e9ede9808b18e.js +1 -0
  123. package/.next/static/chunks/next/dist/client/components/builtin/not-found-f77e9ede9808b18e.js +1 -0
  124. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-f77e9ede9808b18e.js +1 -0
  125. package/.next/static/chunks/webpack-c31263fd83d75ce6.js +1 -0
  126. package/.next/static/css/0cd968b9b62035b5.css +1 -0
  127. package/.next/static/en03hnPiuro0rnf8QkFEe/_buildManifest.js +1 -0
  128. package/.next/types/routes.d.ts +1 -4
  129. package/.next/types/validator.ts +0 -27
  130. package/README.md +17 -29
  131. package/assets/archive.jpg +0 -0
  132. package/assets/growth-1.jpg +0 -0
  133. package/assets/growth-2.jpg +0 -0
  134. package/assets/import.jpg +0 -0
  135. package/assets/main.jpg +0 -0
  136. package/assets/outline.jpg +0 -0
  137. package/assets/prompts-1.jpg +0 -0
  138. package/assets/prompts-2.jpg +0 -0
  139. package/assets/providers-1.jpg +0 -0
  140. package/assets/providers-2.jpg +0 -0
  141. package/assets/providers-3.jpg +0 -0
  142. package/assets/trace-1.jpg +0 -0
  143. package/assets/trace-2.png +0 -0
  144. package/assets/trace-3.png +0 -0
  145. package/assets/trace-4.png +0 -0
  146. package/assets/viewer-1.jpg +0 -0
  147. package/assets/viewer-2.jpg +0 -0
  148. package/bin/pi.js +50 -0
  149. package/next.config.ts +32 -7
  150. package/package.json +4 -9
  151. package/scripts/launcher.mjs +1 -1
  152. package/scripts/pick-folder.ps1 +2 -11
  153. package/scripts/release.mjs +31 -11
  154. package/scripts/verify-package.mjs +0 -53
  155. package/src/app/api/config/route.ts +1 -4
  156. package/src/app/api/growth/route.ts +14 -14
  157. package/src/app/api/models/route.ts +2 -1
  158. package/src/app/api/security/route.ts +3 -8
  159. package/src/app/api/update/route.ts +2 -8
  160. package/src/app/globals.css +92 -777
  161. package/src/app/layout.tsx +6 -13
  162. package/src/components/AppShell.tsx +229 -521
  163. package/src/components/ChatInput.tsx +26 -153
  164. package/src/components/ChatWindow.tsx +231 -51
  165. package/src/components/ContextMeter.tsx +17 -11
  166. package/src/components/FileViewer.tsx +11 -10
  167. package/src/components/GitPanel.tsx +11 -13
  168. package/src/components/ModelSelector.tsx +6 -19
  169. package/src/components/PiMark.tsx +38 -5
  170. package/src/components/ProjectPanel.tsx +111 -95
  171. package/src/components/PromptPanel.tsx +51 -132
  172. package/src/components/SessionImportSection.tsx +37 -53
  173. package/src/components/SessionSidebar.tsx +57 -159
  174. package/src/components/SettingsPanel.tsx +193 -330
  175. package/src/components/icons.tsx +0 -23
  176. package/src/hooks/useGrowth.ts +123 -156
  177. package/src/hooks/usePiWeb.ts +15 -122
  178. package/src/i18n.tsx +42 -98
  179. package/src/lib/agent-manager.ts +21 -187
  180. package/src/lib/command-validation.ts +1 -9
  181. package/src/lib/growth-service.ts +390 -166
  182. package/src/lib/growth-tracker.ts +64 -264
  183. package/src/lib/growth-turns.ts +31 -1
  184. package/src/lib/models/model-scope.ts +15 -0
  185. package/src/lib/models-service.ts +16 -0
  186. package/src/lib/pi-settings.ts +7 -0
  187. package/src/lib/pi.ts +2 -3
  188. package/src/lib/session-import/claude.ts +2 -13
  189. package/src/lib/session-import/codex.ts +8 -44
  190. package/src/lib/session-import/files.ts +0 -14
  191. package/src/lib/session-import/grok.ts +24 -54
  192. package/src/lib/session-import/index.ts +0 -5
  193. package/src/lib/session-import/types.ts +0 -12
  194. package/src/lib/session-import/writer.ts +3 -8
  195. package/src/lib/skills-service.ts +9 -16
  196. package/src/lib/theme.ts +1 -68
  197. package/src/lib/trajectory.ts +0 -1
  198. package/src/lib/types.ts +27 -36
  199. package/tsconfig.json +2 -1
  200. package/.next/server/app/api/swarm/[id]/route.js +0 -1
  201. package/.next/server/app/api/swarm/[id]/route.js.nft.json +0 -1
  202. package/.next/server/app/api/swarm/[id]/route_client-reference-manifest.js +0 -1
  203. package/.next/server/app/api/swarm/route.js +0 -1
  204. package/.next/server/app/api/swarm/route.js.nft.json +0 -1
  205. package/.next/server/app/api/swarm/route_client-reference-manifest.js +0 -1
  206. package/.next/server/app/api/tests/route.js +0 -2
  207. package/.next/server/app/api/tests/route.js.nft.json +0 -1
  208. package/.next/server/app/api/tests/route_client-reference-manifest.js +0 -1
  209. package/.next/server/chunks/757.js +0 -1
  210. package/.next/server/chunks/775.js +0 -3
  211. package/.next/static/0t1jBUAuVaTFTXxRyIo3q/_buildManifest.js +0 -1
  212. package/.next/static/chunks/2608.43c58236c9cce8e6.js +0 -1
  213. package/.next/static/chunks/2716.4ec42df1d51354c9.js +0 -1
  214. package/.next/static/chunks/4632.62139b565b657aac.js +0 -1
  215. package/.next/static/chunks/4673.7796104395deb8d7.js +0 -1
  216. package/.next/static/chunks/4686-17f21a006739a596.js +0 -1
  217. package/.next/static/chunks/7577.10af9bb661652da8.js +0 -1
  218. package/.next/static/chunks/8866.38ec4ac4ee5a1b74.js +0 -1
  219. package/.next/static/chunks/app/_global-error/page-5148173b3f55e415.js +0 -1
  220. package/.next/static/chunks/app/api/agent/[id]/events/route-5148173b3f55e415.js +0 -1
  221. package/.next/static/chunks/app/api/agent/[id]/route-5148173b3f55e415.js +0 -1
  222. package/.next/static/chunks/app/api/agent/[id]/tree/route-5148173b3f55e415.js +0 -1
  223. package/.next/static/chunks/app/api/agent/new/route-5148173b3f55e415.js +0 -1
  224. package/.next/static/chunks/app/api/config/route-5148173b3f55e415.js +0 -1
  225. package/.next/static/chunks/app/api/files/route-5148173b3f55e415.js +0 -1
  226. package/.next/static/chunks/app/api/git/route-5148173b3f55e415.js +0 -1
  227. package/.next/static/chunks/app/api/growth/route-5148173b3f55e415.js +0 -1
  228. package/.next/static/chunks/app/api/health/route-5148173b3f55e415.js +0 -1
  229. package/.next/static/chunks/app/api/models/route-5148173b3f55e415.js +0 -1
  230. package/.next/static/chunks/app/api/pi-settings/route-5148173b3f55e415.js +0 -1
  231. package/.next/static/chunks/app/api/plugins/route-5148173b3f55e415.js +0 -1
  232. package/.next/static/chunks/app/api/prompts/route-5148173b3f55e415.js +0 -1
  233. package/.next/static/chunks/app/api/security/route-5148173b3f55e415.js +0 -1
  234. package/.next/static/chunks/app/api/sessions/[id]/export/route-5148173b3f55e415.js +0 -1
  235. package/.next/static/chunks/app/api/sessions/[id]/route-5148173b3f55e415.js +0 -1
  236. package/.next/static/chunks/app/api/sessions/import/route-5148173b3f55e415.js +0 -1
  237. package/.next/static/chunks/app/api/sessions/route-5148173b3f55e415.js +0 -1
  238. package/.next/static/chunks/app/api/skills/route-5148173b3f55e415.js +0 -1
  239. package/.next/static/chunks/app/api/swarm/[id]/route-5148173b3f55e415.js +0 -1
  240. package/.next/static/chunks/app/api/swarm/route-5148173b3f55e415.js +0 -1
  241. package/.next/static/chunks/app/api/tests/route-5148173b3f55e415.js +0 -1
  242. package/.next/static/chunks/app/api/update/route-5148173b3f55e415.js +0 -1
  243. package/.next/static/chunks/app/api/version/route-5148173b3f55e415.js +0 -1
  244. package/.next/static/chunks/app/api/web-auth/route-5148173b3f55e415.js +0 -1
  245. package/.next/static/chunks/app/api/workspaces/route-5148173b3f55e415.js +0 -1
  246. package/.next/static/chunks/app/page-14379b8060d5cf07.js +0 -1
  247. package/.next/static/chunks/next/dist/client/components/builtin/app-error-5148173b3f55e415.js +0 -1
  248. package/.next/static/chunks/next/dist/client/components/builtin/forbidden-5148173b3f55e415.js +0 -1
  249. package/.next/static/chunks/next/dist/client/components/builtin/not-found-5148173b3f55e415.js +0 -1
  250. package/.next/static/chunks/next/dist/client/components/builtin/unauthorized-5148173b3f55e415.js +0 -1
  251. package/.next/static/chunks/webpack-d1a69ad9edb38b11.js +0 -1
  252. package/.next/static/css/d0a0162cb481abe8.css +0 -1
  253. package/.next/types/app/api/swarm/[id]/route.ts +0 -353
  254. package/.next/types/app/api/swarm/route.ts +0 -353
  255. package/.next/types/app/api/tests/route.ts +0 -353
  256. package/assets/archive.png +0 -0
  257. package/assets/growth-1.png +0 -0
  258. package/assets/growth-2.png +0 -0
  259. package/assets/import.png +0 -0
  260. package/assets/main.png +0 -0
  261. package/assets/outline.png +0 -0
  262. package/assets/prompts-1.png +0 -0
  263. package/assets/prompts-2.png +0 -0
  264. package/assets/providers-1.png +0 -0
  265. package/assets/providers-2.png +0 -0
  266. package/assets/providers-3.png +0 -0
  267. package/assets/trace-1.png +0 -0
  268. package/assets/viewer-1.png +0 -0
  269. package/assets/viewer-2.png +0 -0
  270. package/scripts/managed-niubash-assets.mjs +0 -146
  271. package/scripts/prepare-niubash-packages.mjs +0 -182
  272. package/scripts/run-test-file.mjs +0 -34
  273. package/scripts/smoke-managed-niubash.mjs +0 -62
  274. package/scripts/verify-release-config.mjs +0 -24
  275. package/src/app/api/swarm/[id]/route.ts +0 -28
  276. package/src/app/api/swarm/route.ts +0 -24
  277. package/src/app/api/tests/route.ts +0 -27
  278. package/src/components/SwarmCoordinatorPod.tsx +0 -1021
  279. package/src/components/TestInspectorPod.tsx +0 -549
  280. package/src/lib/delegation.ts +0 -93
  281. package/src/lib/growth-rounds.ts +0 -84
  282. package/src/lib/managed-niubash.ts +0 -231
  283. package/src/lib/runtime-activity.ts +0 -27
  284. package/src/lib/session-import/lock.ts +0 -25
  285. package/src/lib/swarm-service.ts +0 -371
  286. package/src/lib/test-run-service.ts +0 -122
  287. package/src/lib/workflow.ts +0 -55
  288. /package/.next/static/{0t1jBUAuVaTFTXxRyIo3q → en03hnPiuro0rnf8QkFEe}/_ssgManifest.js +0 -0
@@ -30,8 +30,6 @@ import {
30
30
  IconSettingsOutline16,
31
31
  IconTrashOutline16,
32
32
  IconTriangleRightFill14,
33
- IconAgentPresetOutline16,
34
- IconWorkflowAgent16,
35
33
  } from "@/components/icons";
36
34
  import { useI18n } from "@/i18n";
37
35
  import type { SessionListItem } from "@/hooks/usePiWeb";
@@ -99,12 +97,6 @@ export function SessionSidebar({
99
97
  onOpenSettings,
100
98
  onAddWorkspace,
101
99
  draftCwd,
102
- gitBranch = "—",
103
- gitStatus = "未选择",
104
- canAskCommit = false,
105
- onAskCommit,
106
- activeTopView = "workbench",
107
- onSelectTopView,
108
100
  }: {
109
101
  sessions: SessionListItem[];
110
102
  sessionListError?: string | null;
@@ -137,12 +129,6 @@ export function SessionSidebar({
137
129
  onAddWorkspace: () => void;
138
130
  /** 新会话草稿所在的工作区:条目显示在该分组内,发送第一条消息才真正创建 */
139
131
  draftCwd?: string | null;
140
- gitBranch?: string;
141
- gitStatus?: string;
142
- canAskCommit?: boolean;
143
- onAskCommit?: () => void;
144
- activeTopView?: "workbench" | "diff" | "tests" | "swarm" | "archive";
145
- onSelectTopView?: (view: "workbench" | "diff" | "tests" | "swarm" | "archive") => void;
146
132
  }) {
147
133
  const { t, lang } = useI18n();
148
134
  const [q, setQ] = useState("");
@@ -406,6 +392,9 @@ export function SessionSidebar({
406
392
  <IconSearchOutline16 size={17} />
407
393
  </button>
408
394
  <div className="flex-1" />
395
+ <button className="rail-btn" title={t.settings} onClick={onOpenSettings}>
396
+ <IconSettingsOutline16 size={17} />
397
+ </button>
409
398
  </div>
410
399
  );
411
400
  }
@@ -417,11 +406,16 @@ export function SessionSidebar({
417
406
  return (
418
407
  <div
419
408
  key={s.path}
420
- className="pw-session-row group relative flex items-center transition-colors"
421
- data-selected={selected || undefined}
409
+ className="group relative flex items-center rounded-xl transition-colors"
422
410
  style={{
423
411
  background: selected ? "var(--dsw-active)" : "transparent",
424
- paddingLeft: indented ? 32 : s.streaming ? 16 : 8,
412
+ paddingLeft: indented ? 38 : 10,
413
+ paddingRight: 8,
414
+ paddingTop: 6,
415
+ paddingBottom: 6,
416
+ // 选中/悬停框之间留缝,不互相粘连
417
+ marginTop: 2,
418
+ marginBottom: 2,
425
419
  }}
426
420
  onMouseEnter={(e) => {
427
421
  if (!selected) e.currentTarget.style.background = "var(--dsw-hover)";
@@ -454,8 +448,8 @@ export function SessionSidebar({
454
448
  <button
455
449
  className="icon-btn"
456
450
  style={{ width: 22, height: 22 }}
457
- title={t.sessionActions}
458
- aria-label={t.sessionActions}
451
+ title="..."
452
+ aria-label="session-actions"
459
453
  onClick={(e) => {
460
454
  e.stopPropagation();
461
455
  setSessionMenu(sessionMenu === s.path ? null : s.path);
@@ -531,12 +525,16 @@ export function SessionSidebar({
531
525
  return (
532
526
  <div key={g.cwd}>
533
527
  <div
534
- className="pw-workspace-row group relative flex items-center transition-colors"
535
- data-current={isCurrent || undefined}
536
- data-open={open || undefined}
528
+ className="group relative flex items-center rounded-xl transition-colors"
537
529
  style={{
538
530
  background: open || isCurrent ? "var(--dsw-hover)" : "transparent",
539
- paddingLeft: 8,
531
+ paddingLeft: 10,
532
+ paddingRight: 6,
533
+ paddingTop: 7,
534
+ paddingBottom: 7,
535
+ // 悬停/展开框之间留缝,不互相粘连(与会话行一致)
536
+ marginTop: 2,
537
+ marginBottom: 2,
540
538
  }}
541
539
  onMouseEnter={(e) => {
542
540
  if (!(open || isCurrent)) e.currentTarget.style.background = "var(--dsw-hover)";
@@ -572,8 +570,8 @@ export function SessionSidebar({
572
570
  <button
573
571
  className="icon-btn"
574
572
  style={{ width: 22, height: 22 }}
575
- title={t.workspaceActions}
576
- aria-label={t.workspaceActions}
573
+ title="..."
574
+ aria-label="workspace-actions"
577
575
  onClick={() => {
578
576
  setRowMenu(rowMenu === g.cwd ? null : g.cwd);
579
577
  setSessionMenu(null);
@@ -653,9 +651,9 @@ export function SessionSidebar({
653
651
  };
654
652
 
655
653
  return (
656
- <div className="pw-sidebar flex h-full min-h-0 flex-col">
654
+ <div className="flex h-full min-h-0 flex-col">
657
655
  {/* 品牌行 */}
658
- <div className="pw-sidebar-head flex items-center gap-1 px-4 pb-2 pt-4">
656
+ <div className="flex items-center gap-1 px-4 pb-2 pt-4">
659
657
  <BrandPi />
660
658
  <div className="flex-1" />
661
659
  <button className="icon-btn" onClick={onToggleCollapse} title="«">
@@ -663,116 +661,14 @@ export function SessionSidebar({
663
661
  </button>
664
662
  </div>
665
663
 
666
- {/* 新会话(柔和粘土拟物风格) */}
667
- <div className="pw-sidebar-new px-3 pt-1">
668
- <button className="clay-btn clay-btn-mint w-full py-2.5 px-4 text-xs font-semibold tracking-wide flex items-center justify-center gap-2 text-white shadow-md rounded-2xl transition-all" onClick={onNew}>
664
+ {/* 新会话(dsh .newSession) */}
665
+ <div className="px-3 pt-1">
666
+ <button className="btn-new-session w-full" onClick={onNew}>
669
667
  <IconNewChatOutline16 size={14} />
670
668
  {t.newChat}
671
669
  </button>
672
670
  </div>
673
671
 
674
- {/* Git 状态卡片 (Screen 1 & 2) */}
675
- <div className="px-3 pt-2">
676
- <div className="clay-card p-2.5 rounded-2xl border border-slate-200/50 dark:border-slate-800/50 bg-white/70 dark:bg-slate-900/70">
677
- <div className="flex items-center justify-between text-xs font-medium text-slate-700 dark:text-slate-200">
678
- <div className="flex items-center gap-1.5">
679
- <IconBranchOutline16 size={13} className="text-emerald-500" />
680
- <span className="font-mono truncate max-w-[90px]" title={gitBranch}>{gitBranch}</span>
681
- </div>
682
- <span className={`text-[10px] font-mono font-semibold px-1.5 py-0.5 rounded ${gitStatus === "干净" ? "text-emerald-600 dark:text-emerald-400 bg-emerald-50 dark:bg-emerald-950/60" : "text-amber-700 dark:text-amber-300 bg-amber-50 dark:bg-amber-950/60"}`}>
683
- {gitStatus}
684
- </span>
685
- </div>
686
- <div className="flex items-center justify-between pt-2">
687
- <span className="text-[11px] text-slate-400">就绪待审查</span>
688
- <button
689
- type="button"
690
- className="px-2.5 py-1 text-[11px] font-medium text-emerald-700 dark:text-emerald-300 rounded-xl clay-btn clay-btn-soft transition-colors flex items-center gap-1 disabled:opacity-50 disabled:cursor-not-allowed"
691
- disabled={!canAskCommit}
692
- onClick={onAskCommit}
693
- >
694
- <span>让 pi 提交</span>
695
- </button>
696
- </div>
697
- </div>
698
- </div>
699
-
700
- {/* 快速视图切换导航 (Screen 1 & 3 & 4) */}
701
- <div className="px-3 pt-2">
702
- <nav className="flex flex-col gap-1">
703
- <button
704
- type="button"
705
- className={`flex items-center justify-between px-3 py-1.5 rounded-xl transition-all text-xs font-medium ${
706
- activeTopView === "workbench"
707
- ? "clay-card text-emerald-700 dark:text-emerald-300 font-bold bg-white dark:bg-slate-800 shadow-sm"
708
- : "text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800/60"
709
- }`}
710
- onClick={() => onSelectTopView?.("workbench")}
711
- >
712
- <span className="flex items-center gap-2">
713
- <IconFolderOpenOutline16 size={14} className={activeTopView === "workbench" ? "text-emerald-500" : "text-slate-400"} />
714
- <span>工作区文件</span>
715
- </span>
716
- </button>
717
- <button
718
- type="button"
719
- className={`flex items-center justify-between px-3 py-1.5 rounded-xl transition-all text-xs font-medium ${
720
- activeTopView === "diff"
721
- ? "clay-card text-emerald-700 dark:text-emerald-300 font-bold bg-white dark:bg-slate-800 shadow-sm"
722
- : "text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800/60"
723
- }`}
724
- onClick={() => onSelectTopView?.("diff")}
725
- >
726
- <span className="flex items-center gap-2">
727
- <IconEditOutline16 size={14} className={activeTopView === "diff" ? "text-emerald-500" : "text-slate-400"} />
728
- <span>改动检查器</span>
729
- </span>
730
- </button>
731
- <button
732
- type="button"
733
- className={`flex items-center justify-between px-3 py-1.5 rounded-xl transition-all text-xs font-medium ${
734
- activeTopView === "tests"
735
- ? "clay-card text-emerald-700 dark:text-emerald-300 font-bold bg-white dark:bg-slate-800 shadow-sm"
736
- : "text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800/60"
737
- }`}
738
- onClick={() => onSelectTopView?.("tests")}
739
- >
740
- <span className="flex items-center gap-2">
741
- <IconWorkflowAgent16 size={14} className={activeTopView === "tests" ? "text-emerald-500" : "text-slate-400"} />
742
- <span>测试套件</span>
743
- </span>
744
- </button>
745
- <button
746
- type="button"
747
- className={`flex items-center justify-between px-3 py-1.5 rounded-xl transition-all text-xs font-medium ${
748
- activeTopView === "swarm"
749
- ? "clay-card text-emerald-700 dark:text-emerald-300 font-bold bg-white dark:bg-slate-800 shadow-sm"
750
- : "text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800/60"
751
- }`}
752
- onClick={() => onSelectTopView?.("swarm")}
753
- >
754
- <span className="flex items-center gap-2">
755
- <IconAgentPresetOutline16 size={14} className={activeTopView === "swarm" ? "text-emerald-500" : "text-slate-400"} />
756
- <span>智能体群组</span>
757
- </span>
758
- </button>
759
- <button
760
- type="button"
761
- className={`flex items-center justify-between px-3 py-1.5 rounded-xl transition-all text-xs font-medium ${
762
- activeTopView === "archive"
763
- ? "clay-card text-emerald-700 dark:text-emerald-300 font-bold bg-white dark:bg-slate-800 shadow-sm"
764
- : "text-slate-600 dark:text-slate-300 hover:bg-slate-100 dark:hover:bg-slate-800/60"
765
- }`}
766
- onClick={() => onSelectTopView?.("archive")}
767
- >
768
- <span className="flex items-center gap-2">
769
- <IconArchiveOutline20 size={14} className={activeTopView === "archive" ? "text-emerald-500" : "text-slate-400"} />
770
- <span>归档</span>
771
- </span>
772
- </button>
773
- </nav>
774
- </div>
775
-
776
672
  {/* 工作区标题行 / 搜索框(互替,照 dsh) */}
777
673
  {searchOpen ? (
778
674
  <div className="px-3 pb-1 pt-3">
@@ -780,7 +676,6 @@ export function SessionSidebar({
780
676
  <IconSearchOutline16 size={14} style={{ color: "var(--dsw-label-caption)" }} />
781
677
  <input
782
678
  autoFocus
783
- aria-label={t.searchSessions}
784
679
  value={q}
785
680
  onChange={(e) => setQ(e.target.value)}
786
681
  placeholder={t.searchSessions}
@@ -790,7 +685,6 @@ export function SessionSidebar({
790
685
  <button
791
686
  className="icon-btn"
792
687
  style={{ width: 20, height: 20 }}
793
- aria-label={t.close}
794
688
  onClick={() => {
795
689
  setQ("");
796
690
  setSearchOpen(false);
@@ -801,7 +695,7 @@ export function SessionSidebar({
801
695
  </div>
802
696
  </div>
803
697
  ) : (
804
- <div className="pw-sidebar-section-head flex items-center gap-0.5 px-4 pb-1 pt-3">
698
+ <div className="flex items-center gap-0.5 px-4 pb-1 pt-3">
805
699
  <span style={{ fontSize: 13, color: "var(--dsw-label-primary)" }}>{t.workspaces}</span>
806
700
  <div className="flex-1" />
807
701
  <button className="icon-btn" style={{ width: 26, height: 26 }} title={t.search} onClick={() => setSearchOpen(true)}>
@@ -839,7 +733,7 @@ export function SessionSidebar({
839
733
  )}
840
734
 
841
735
  {/* 列表区 */}
842
- <div className="pw-sidebar-list min-h-0 flex-1 overflow-y-auto px-3 pb-3">
736
+ <div className="min-h-0 flex-1 overflow-y-auto px-3 pb-3">
843
737
  {sessionListError && (
844
738
  <div role="alert" className="mb-2 rounded-xl px-3 py-2" style={{ background: "var(--dsw-hover)", color: "var(--dsw-danger)", fontSize: 12 }}>
845
739
  <div>{t.sessionListLoadFailed}: {sessionListError}</div>
@@ -970,20 +864,28 @@ export function SessionSidebar({
970
864
  )}
971
865
  </div>
972
866
 
973
- {/* 底部版本号 */}
974
- <div className="pw-sidebar-footer px-3 py-2 border-t border-slate-200/60 dark:border-slate-800/60 flex items-center justify-center text-xs text-slate-400 font-mono text-[11px] shrink-0">
975
- <span>PiWeb v0.3.15</span>
867
+ {/* 设置固定左下角 */}
868
+ <div className="px-3 py-2.5">
869
+ <button
870
+ className="flex w-full items-center gap-2.5 rounded-xl px-4 py-2 text-left transition-colors"
871
+ style={{ color: "var(--dsw-label-secondary)" }}
872
+ onMouseEnter={(e) => (e.currentTarget.style.background = "var(--dsw-hover)")}
873
+ onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
874
+ onClick={onOpenSettings}
875
+ >
876
+ <IconSettingsOutline16 size={16} />
877
+ <span style={{ fontSize: "var(--dsh-content-font-size)" }}>{t.settings}</span>
878
+ </button>
976
879
  </div>
977
880
 
978
881
  {/* 重命名弹窗(照用户截图 media_1788745548711.png,通过 createPortal 挂载到 document.body 确保浏览器正居中) */}
979
882
  {mounted && renameTarget && createPortal(
980
883
  <div
981
- className="modal-mask fixed inset-0 z-[9999] flex items-center justify-center p-4 animate-in fade-in duration-150"
884
+ className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm p-4 animate-in fade-in duration-150"
982
885
  onClick={closeRename}
983
886
  >
984
887
  <div
985
- className="glass-modal relative w-full max-w-[420px] rounded-[24px] p-6 shadow-2xl"
986
- style={{ color: "var(--dsw-label-primary)", border: "0.5px solid var(--dsw-border-l2)" }}
888
+ className="relative w-full max-w-[420px] rounded-[24px] bg-[#212121] p-6 text-white shadow-2xl border border-white/10"
987
889
  onClick={(e) => e.stopPropagation()}
988
890
  role="dialog"
989
891
  aria-modal="true"
@@ -994,14 +896,14 @@ export function SessionSidebar({
994
896
  type="button"
995
897
  onClick={closeRename}
996
898
  disabled={renamePending}
997
- className="icon-btn absolute right-5 top-5 rounded-full p-1"
899
+ className="absolute right-5 top-5 rounded-full p-1 text-zinc-400 hover:text-white hover:bg-white/10 transition"
998
900
  aria-label={t.close}
999
901
  >
1000
902
  <IconCloseOutline14 size={16} />
1001
903
  </button>
1002
904
 
1003
905
  {/* 标题 */}
1004
- <h3 id="rename-dialog-title" className="pr-8 text-lg font-medium">
906
+ <h3 id="rename-dialog-title" className="text-lg font-medium text-white pr-8">
1005
907
  {renameTarget.type === "session"
1006
908
  ? (t.renameSession || "重命名会话")
1007
909
  : (t.renameWorkspace || "重命名工作区")}
@@ -1012,7 +914,6 @@ export function SessionSidebar({
1012
914
  <input
1013
915
  ref={renameInputRef}
1014
916
  type="text"
1015
- aria-label={renameTarget.type === "session" ? t.renameSession : t.renameWorkspace}
1016
917
  value={renameValue}
1017
918
  disabled={renamePending}
1018
919
  onChange={(e) => {
@@ -1023,8 +924,7 @@ export function SessionSidebar({
1023
924
  if (e.key === "Enter") void handleConfirmRename();
1024
925
  if (e.key === "Escape") closeRename();
1025
926
  }}
1026
- className="w-full rounded-full px-4 py-2.5 text-[14.5px] outline-none transition"
1027
- style={{ background: "var(--dsw-hover)", border: "1px solid var(--dsw-border-l2)", color: "var(--dsw-label-primary)" }}
927
+ className="w-full rounded-full bg-white/[0.05] border border-white/15 px-4 py-2.5 text-[14.5px] text-white outline-none focus:border-white/40 focus:ring-1 focus:ring-white/30 transition"
1028
928
  />
1029
929
  </div>
1030
930
  {renameError && (
@@ -1037,7 +937,7 @@ export function SessionSidebar({
1037
937
  type="button"
1038
938
  onClick={closeRename}
1039
939
  disabled={renamePending}
1040
- className="btn-outline"
940
+ className="rounded-full bg-[#2c2c2c] px-5 py-2 text-sm font-medium text-zinc-200 hover:bg-[#383838] transition"
1041
941
  >
1042
942
  {t.cancel}
1043
943
  </button>
@@ -1045,7 +945,7 @@ export function SessionSidebar({
1045
945
  type="button"
1046
946
  onClick={() => void handleConfirmRename()}
1047
947
  disabled={renamePending || !renameValue.trim() || (renameTarget.type === "workspace" && (renameValue.trim() === renameTarget.name || renameWorkspaceConflict))}
1048
- className="btn-primary-white"
948
+ className="rounded-full bg-white px-5 py-2 text-sm font-medium text-black hover:bg-zinc-200 transition"
1049
949
  >
1050
950
  {t.rename}
1051
951
  </button>
@@ -1058,12 +958,11 @@ export function SessionSidebar({
1058
958
  {/* 删除工作区确认弹窗(照用户截图 media_1788745235179.png 与 media_1788746156687.png,通过 createPortal 挂载到 document.body 确保浏览器正居中) */}
1059
959
  {mounted && deleteWorkspaceTarget && createPortal(
1060
960
  <div
1061
- className="modal-mask fixed inset-0 z-[9999] flex items-center justify-center p-4 animate-in fade-in duration-150"
961
+ className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm p-4 animate-in fade-in duration-150"
1062
962
  onClick={() => !deleteWorkspacePending && setDeleteWorkspaceTarget(null)}
1063
963
  >
1064
964
  <div
1065
- className="glass-modal relative w-full max-w-[420px] rounded-[24px] p-6 shadow-2xl"
1066
- style={{ color: "var(--dsw-label-primary)", border: "0.5px solid var(--dsw-border-l2)" }}
965
+ className="relative w-full max-w-[420px] rounded-[24px] bg-[#212121] p-6 text-white shadow-2xl border border-white/10"
1067
966
  onClick={(e) => e.stopPropagation()}
1068
967
  role="dialog"
1069
968
  aria-modal="true"
@@ -1074,26 +973,26 @@ export function SessionSidebar({
1074
973
  type="button"
1075
974
  onClick={() => setDeleteWorkspaceTarget(null)}
1076
975
  disabled={deleteWorkspacePending}
1077
- className="icon-btn absolute right-5 top-5 rounded-full p-1"
976
+ className="absolute right-5 top-5 rounded-full p-1 text-zinc-400 hover:text-white hover:bg-white/10 transition"
1078
977
  aria-label={t.close}
1079
978
  >
1080
979
  <IconCloseOutline14 size={16} />
1081
980
  </button>
1082
981
 
1083
982
  {/* 标题 */}
1084
- <h3 id="delete-workspace-dialog-title" className="pr-8 text-lg font-medium">
983
+ <h3 id="delete-workspace-dialog-title" className="text-lg font-medium text-white pr-8">
1085
984
  {t.deleteWorkspace}
1086
985
  </h3>
1087
986
 
1088
987
  {/* 描述文本 */}
1089
- <p className="mt-3 text-[14.5px] leading-relaxed" style={{ color: "var(--dsw-label-secondary)" }}>
988
+ <p className="mt-3 text-[14.5px] leading-relaxed text-zinc-300">
1090
989
  {(t.deleteWorkspaceConfirm || "将把“{name}”从工作区列表中移除。文件夹与会话记录会保留,其会话将显示在“未分组”下。").replace(
1091
990
  "{name}",
1092
991
  deleteWorkspaceTarget.name,
1093
992
  )}
1094
993
  </p>
1095
994
  {deleteWorkspacePending && (
1096
- <p className="mt-4 text-sm" style={{ color: "var(--dsw-label-caption)" }} role="status">{t.deleteWorkspacePending}</p>
995
+ <p className="mt-4 text-sm text-zinc-400" role="status">{t.deleteWorkspacePending}</p>
1097
996
  )}
1098
997
  {deleteWorkspaceError && (
1099
998
  <p className="mt-4 text-sm" style={{ color: "var(--dsw-danger)" }} role="alert">{deleteWorkspaceError}</p>
@@ -1105,7 +1004,7 @@ export function SessionSidebar({
1105
1004
  type="button"
1106
1005
  onClick={() => setDeleteWorkspaceTarget(null)}
1107
1006
  disabled={deleteWorkspacePending}
1108
- className="btn-outline"
1007
+ className="rounded-xl border border-transparent bg-[#2c2c2c] px-5 py-2 text-sm font-medium text-zinc-200 transition hover:border-white/25 hover:bg-[#383838]"
1109
1008
  >
1110
1009
  {t.cancel}
1111
1010
  </button>
@@ -1113,8 +1012,7 @@ export function SessionSidebar({
1113
1012
  type="button"
1114
1013
  onClick={() => void handleConfirmDeleteWorkspace()}
1115
1014
  disabled={deleteWorkspacePending}
1116
- className="btn-outline"
1117
- style={{ color: "var(--dsw-danger)" }}
1015
+ className="rounded-xl border border-transparent bg-[#2c2c2c] px-5 py-2 text-sm font-medium text-[#f87171] transition hover:border-[#f87171]/40 hover:bg-[#383838] hover:text-[#ef4444]"
1118
1016
  >
1119
1017
  {t.deleteWorkspace}
1120
1018
  </button>