@rexvane/piweb 0.3.16 → 0.3.17

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/850c2fd130ffa2fc.css +1 -0
  127. package/.next/static/zsynuO_9Kx6nrXgkTUJ04/_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 +90 -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 → zsynuO_9Kx6nrXgkTUJ04}/_ssgManifest.js +0 -0
@@ -6,14 +6,13 @@
6
6
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
7
  import { createEventBatcher, type EventBatcher } from "@/lib/event-batcher";
8
8
  import type {
9
- GrowthStep,
9
+ GrowthRound,
10
10
  SessionSummary,
11
11
  TrajEntry,
12
12
  WebEvent,
13
13
  WebMessage,
14
14
  WebSnapshot,
15
15
  ToolPreset,
16
- WorkflowMode,
17
16
  } from "@/lib/types";
18
17
 
19
18
  export interface ToolCardState {
@@ -61,24 +60,8 @@ export interface PiWebState {
61
60
  extensionStatuses: Record<string, string>;
62
61
  /** 扩展覆盖的「工作中」文案(setWorkingMessage) */
63
62
  workingMessage: string | null;
64
- /** 项目生长:本次连接期间收到的步(完整账本由 useGrowth 拉取后合并),以及运行中工具正在生成的路径 */
65
- growth: { steps: GrowthStep[]; pending: string[]; error: string | null };
66
- }
67
-
68
- export function previewEditedBranch(messages: WebMessage[], entryId: string, text: string): WebMessage[] | null {
69
- const index = messages.findIndex((message) => message.role === "user" && message.id === entryId);
70
- if (index < 0) return null;
71
- const original = messages[index];
72
- return [
73
- ...messages.slice(0, index),
74
- {
75
- ...original,
76
- content: [
77
- { type: "text" as const, text },
78
- ...original.content.filter((part) => part.type === "image"),
79
- ],
80
- },
81
- ];
63
+ /** 项目生长:本次连接期间收到的 commit(完整时间轴由 useGrowth 拉取后按 commit 去重合并) */
64
+ growth: { rounds: GrowthRound[]; error: string | null };
82
65
  }
83
66
 
84
67
  export interface SessionListItem extends SessionSummary {
@@ -208,9 +191,6 @@ export const foldPiWebEvent = (state: PiWebState, evt: WebEvent): PiWebState =>
208
191
  tools: { active: evt.active, all: evt.all.map((n) => ({ name: n })) },
209
192
  };
210
193
  return s;
211
- case "workflow":
212
- if (s.snapshot) s.snapshot = { ...s.snapshot, workflow: evt.workflow };
213
- return s;
214
194
  case "resources":
215
195
  if (s.snapshot) {
216
196
  s.snapshot = {
@@ -253,15 +233,12 @@ export const foldPiWebEvent = (state: PiWebState, evt: WebEvent): PiWebState =>
253
233
  }
254
234
  return s;
255
235
  case "growth": {
256
- const steps = s.growth.steps.some((x) => x.seq === evt.step.seq) ? s.growth.steps.map((x) => (x.seq === evt.step.seq ? evt.step : x)) : [...s.growth.steps, evt.step];
257
- s.growth = { steps, pending: [], error: null };
236
+ const rounds = s.growth.rounds.some((x) => x.commit === evt.round.commit) ? s.growth.rounds : [...s.growth.rounds, evt.round];
237
+ s.growth = { rounds, error: null };
258
238
  return s;
259
239
  }
260
- case "growth_pending":
261
- s.growth = { ...s.growth, pending: evt.paths };
262
- return s;
263
240
  case "growth_error":
264
- s.growth = { ...s.growth, pending: [], error: evt.message };
241
+ s.growth = { ...s.growth, error: evt.message };
265
242
  return s;
266
243
  case "retry":
267
244
  // 只保留最后一次尝试:重试过程在界面上是「重试 3/5」这一条,而不是五行报错
@@ -338,7 +315,7 @@ const emptyState = (toolPreset: ToolPreset = "standard"): PiWebState => ({
338
315
  extensionNotices: [],
339
316
  extensionStatuses: {},
340
317
  workingMessage: null,
341
- growth: { steps: [], pending: [], error: null },
318
+ growth: { rounds: [], error: null },
342
319
  });
343
320
 
344
321
  function pathKey(value: string): string {
@@ -355,20 +332,14 @@ export function usePiWeb() {
355
332
  const [currentId, setCurrentId] = useState<string | null>(null);
356
333
  const [currentPath, setCurrentPath] = useState<string | null>(null);
357
334
  const [state, setState] = useState<PiWebState>(emptyState);
358
- const stateRef = useRef(state);
359
- stateRef.current = state;
360
335
  /** 当前 SSE 连接的增量批量器:按帧合并事件,避免每个 token 一次整树渲染 */
361
336
  const batcherRef = useRef<EventBatcher<WebEvent> | null>(null);
362
337
  const [models, setModels] = useState<{ providers: any[]; models: any[] } | null>(null);
363
- const [modelLoading, setModelLoading] = useState(true);
364
- const [modelLoadError, setModelLoadError] = useState<string | null>(null);
365
- const modelRequestRef = useRef(0);
366
338
  const [addedWorkspaces, setAddedWorkspaces] = useState<string[]>([]);
367
339
  const [removedWorkspaces, setRemovedWorkspaces] = useState<string[]>([]);
368
340
  const [groupBy, setGroupByState] = useState<"workspace" | "flat">("workspace");
369
341
  const [orderBy, setOrderByState] = useState<"updated" | "manual">("updated");
370
342
  const [resyncNonce, setResyncNonce] = useState(0);
371
- const resync = useCallback(() => setResyncNonce((nonce) => nonce + 1), []);
372
343
  const [snapshotEpoch, setSnapshotEpoch] = useState(0);
373
344
  const esRef = useRef<EventSource | null>(null);
374
345
  const promptRequestsRef = useRef(new Set<string>());
@@ -376,7 +347,6 @@ export function usePiWeb() {
376
347
  const presetRestorePromiseRef = useRef<Promise<void> | null>(null);
377
348
  const activeSessionRef = useRef(currentId);
378
349
  activeSessionRef.current = currentId;
379
- const editSyncRef = useRef<{ sessionId: string; phase: "submitting" | "resyncing"; error?: string } | null>(null);
380
350
  const subscribedSessionRef = useRef<string | null>(null);
381
351
  const retrySessionList = useCallback(() => setSessionListRetryNonce((value) => value + 1), []);
382
352
  const clearCompaction = useCallback(() => setState((current) => ({ ...current, compaction: null })), []);
@@ -532,28 +502,6 @@ export function usePiWeb() {
532
502
  }
533
503
  }, [refreshWorkspaces]);
534
504
 
535
- /** 直接添加指定路径到工作区列表;成功返回规范化路径 */
536
- const addWorkspaceByPath = useCallback(async (dir: string): Promise<string | null> => {
537
- try {
538
- const r = await fetch("/api/workspaces", {
539
- method: "POST",
540
- headers: { "Content-Type": "application/json" },
541
- body: JSON.stringify({ action: "add", path: dir }),
542
- });
543
- const j = await r.json();
544
- if (!r.ok || !j.success) throw new Error(j.error || `request failed (${r.status})`);
545
- if (j.data?.workspaces) {
546
- setAddedWorkspaces(j.data.workspaces);
547
- }
548
- await refreshWorkspaces();
549
- return dir;
550
- } catch (error) {
551
- const message = error instanceof Error ? error.message : "failed to add workspace";
552
- setState((current) => ({ ...current, error: message }));
553
- throw error;
554
- }
555
- }, [refreshWorkspaces]);
556
-
557
505
 
558
506
  const removeWorkspace = useCallback(
559
507
  async (dir: string) => {
@@ -642,20 +590,12 @@ export function usePiWeb() {
642
590
 
643
591
  // 模型目录
644
592
  const refreshModels = useCallback(async () => {
645
- const request = ++modelRequestRef.current;
646
- setModelLoading(true);
647
- setModelLoadError(null);
648
593
  try {
649
594
  const r = await fetch("/api/models");
650
595
  const j = await r.json();
651
- if (!r.ok || !j.success || !Array.isArray(j.data?.providers) || !Array.isArray(j.data?.models)) {
652
- throw new Error(j.error || `request failed (${r.status})`);
653
- }
654
- if (request === modelRequestRef.current) setModels({ providers: j.data.providers, models: j.data.models });
655
- } catch (error) {
656
- if (request === modelRequestRef.current) setModelLoadError(error instanceof Error ? error.message : "model catalog unavailable");
657
- } finally {
658
- if (request === modelRequestRef.current) setModelLoading(false);
596
+ if (j.success) setModels({ providers: j.data.providers, models: j.data.models });
597
+ } catch {
598
+ /* ignore */
659
599
  }
660
600
  }, []);
661
601
  useEffect(() => {
@@ -667,17 +607,14 @@ export function usePiWeb() {
667
607
  esRef.current?.close();
668
608
  esRef.current = null;
669
609
  if (!currentId) {
670
- editSyncRef.current = null;
671
610
  subscribedSessionRef.current = null;
672
611
  setState(emptyState(savedToolPreset()));
673
612
  return;
674
613
  }
675
614
  const reconnectingCurrentSession = subscribedSessionRef.current === currentId;
676
- if (!reconnectingCurrentSession) editSyncRef.current = null;
677
615
  subscribedSessionRef.current = currentId;
678
- const editResync = editSyncRef.current?.sessionId === currentId && editSyncRef.current.phase === "resyncing";
679
616
  setState((current) => reconnectingCurrentSession
680
- ? { ...current, connected: editResync ? current.connected : false }
617
+ ? { ...current, connected: false }
681
618
  : { ...emptyState(savedToolPreset()), connected: false });
682
619
  let retryDelayMs = 2000;
683
620
  const connect = () => {
@@ -702,10 +639,7 @@ export function usePiWeb() {
702
639
  };
703
640
  // 流式事件按帧合并:token 速率再高也只每 16ms 渲染一次(见 event-batcher)
704
641
  const batcher = createEventBatcher<WebEvent>({
705
- flush: (events) => {
706
- if (editSyncRef.current?.sessionId === currentId) return;
707
- setState((s) => events.reduce((acc, evt) => foldPiWebEvent(acc, evt), s));
708
- },
642
+ flush: (events) => setState((s) => events.reduce((acc, evt) => foldPiWebEvent(acc, evt), s)),
709
643
  });
710
644
  batcherRef.current = batcher;
711
645
  es.onmessage = (e) => {
@@ -717,9 +651,6 @@ export function usePiWeb() {
717
651
  return;
718
652
  }
719
653
  if (parsed.type === "snapshot" && parsed.snapshot) {
720
- const editSync = editSyncRef.current;
721
- if (editSync?.sessionId === currentId && editSync.phase === "submitting") return;
722
- if (editSync?.sessionId === currentId) editSyncRef.current = null;
723
654
  // 快照是权威状态:之前缓冲的增量已经过时,直接丢弃
724
655
  batcher.cancel();
725
656
  retryDelayMs = 2000;
@@ -731,7 +662,7 @@ export function usePiWeb() {
731
662
  tools: toolsFromMessages(snap.messages, snap.isStreaming),
732
663
  toolPreset: snap.toolPreset,
733
664
  connected: true,
734
- error: editSync?.sessionId === currentId ? editSync.error ?? null : null,
665
+ error: null,
735
666
  compaction: null,
736
667
  retryNotice: null,
737
668
  // 服务器当前 pending 集合是权威来源,刷新可恢复、已答请求不能复活。
@@ -743,7 +674,6 @@ export function usePiWeb() {
743
674
  growth: { ...prev.growth, error: snap.growthError ?? null },
744
675
  }));
745
676
  } else {
746
- if (editSyncRef.current?.sessionId === currentId) return;
747
677
  batcher.push(parsed as WebEvent);
748
678
  }
749
679
  };
@@ -786,42 +716,9 @@ export function usePiWeb() {
786
716
  }
787
717
  }, [currentId]);
788
718
 
789
- const editAndResend = useCallback(async (entryId: string, text: string) => {
790
- if (editSyncRef.current?.sessionId === currentId) return { success: false, error: "edit already in progress" };
791
- if (!currentId || !previewEditedBranch(stateRef.current.messages, entryId, text)) return { success: false, error: "message is not editable" };
792
- editSyncRef.current = { sessionId: currentId, phase: "submitting" };
793
- batcherRef.current?.cancel();
794
- setState((previous) => {
795
- const messages = previewEditedBranch(previous.messages, entryId, text);
796
- if (!messages) return previous;
797
- return {
798
- ...previous,
799
- messages,
800
- tools: toolsFromMessages(messages),
801
- snapshot: previous.snapshot ? { ...previous.snapshot, messages, isStreaming: true } : null,
802
- error: null,
803
- retryNotice: null,
804
- workingMessage: null,
805
- };
806
- });
807
- const result = await sendCommand({ cmd: "editAndResend", entryId, text });
808
- if (editSyncRef.current?.sessionId === currentId) {
809
- editSyncRef.current = {
810
- sessionId: currentId,
811
- phase: "resyncing",
812
- error: result?.success ? undefined : result?.error ?? "Failed to edit message",
813
- };
814
- batcherRef.current?.cancel();
815
- esRef.current?.close();
816
- esRef.current = null;
817
- resync();
818
- }
819
- return result;
820
- }, [currentId, resync, sendCommand]);
821
-
822
719
  const newSession = useCallback(async (
823
720
  cwd: string,
824
- overrides: { provider?: string; modelId?: string; thinking?: string; mode?: WorkflowMode } = {},
721
+ overrides: { provider?: string; modelId?: string; thinking?: string } = {},
825
722
  ): Promise<string | null> => {
826
723
  try {
827
724
  const r = await fetch("/api/agent/new", {
@@ -835,7 +732,6 @@ export function usePiWeb() {
835
732
  const id = idOf(p);
836
733
  // 工具预设取通用设置的持久化选择;模型/思考级别由 Hero 页显式下发
837
734
  const setup: Record<string, unknown>[] = [{ cmd: "setToolPreset", preset: savedToolPreset() }];
838
- if (overrides.mode && overrides.mode !== "agent") setup.push({ cmd: "setWorkflowMode", mode: overrides.mode });
839
735
  if (overrides.provider && overrides.modelId) setup.push({ cmd: "setModel", provider: overrides.provider, modelId: overrides.modelId });
840
736
  if (overrides.thinking) setup.push({ cmd: "setThinkingLevel", level: overrides.thinking });
841
737
  for (const command of setup) {
@@ -929,6 +825,7 @@ export function usePiWeb() {
929
825
  // ---------- 会话预设已移除:工具档位见通用设置/工具启用情况,模型与思考级别由 Hero 页显式下发 ----------
930
826
 
931
827
  /** 强制重连 SSE 拿新快照(navigate 等场景) */
828
+ const resync = useCallback(() => setResyncNonce((n) => n + 1), []);
932
829
  /** 应答扩展对话框(select/confirm/input);cancelled=true 表示用户关掉了 */
933
830
  const answerExtensionDialog = useCallback(
934
831
  async (id: string, response: { value?: string; confirmed?: boolean; cancelled?: boolean }) => {
@@ -987,8 +884,6 @@ export function usePiWeb() {
987
884
  currentPath,
988
885
  state,
989
886
  models,
990
- modelLoading,
991
- modelLoadError,
992
887
  addedWorkspaces,
993
888
  removedWorkspaces,
994
889
  workspaceAliases,
@@ -1003,11 +898,9 @@ export function usePiWeb() {
1003
898
  setGroupBy,
1004
899
  setOrderBy,
1005
900
  addWorkspaceByPicker,
1006
- addWorkspaceByPath,
1007
901
  removeWorkspace,
1008
902
  refreshModels,
1009
903
  sendCommand,
1010
- editAndResend,
1011
904
  newSession,
1012
905
  openSession,
1013
906
  closeSession,
package/src/i18n.tsx CHANGED
@@ -13,14 +13,13 @@ const zh = {
13
13
  rename: "重命名",
14
14
  renameSession: "重命名会话",
15
15
  renameWorkspace: "重命名工作区",
16
- sessionActions: "会话操作",
17
- workspaceActions: "工作区操作",
18
16
  search: "搜索",
19
17
  save: "保存",
20
18
  close: "关闭",
21
19
  error: "出错",
22
20
  copy: "复制",
23
21
  copyFailed: "复制失败",
22
+ chatWidthHandle: "拖动调整对话宽度",
24
23
  editMessage: "编辑这条消息",
25
24
  sendEdit: "重新发送",
26
25
  editMessageFailed: "编辑重发失败",
@@ -73,23 +72,6 @@ const zh = {
73
72
  backToBottom: "回到底部",
74
73
  modeSteer: "插话",
75
74
  modeQueue: "排队",
76
- workflowAgent: "Agent",
77
- workflowPlan: "Plan",
78
- workflowGoal: "Goal",
79
- workflowMenu: "选择工作模式",
80
- workflowClear: "退出工作模式",
81
- workflowPlanPlaceholder: "规划改动…",
82
- workflowGoalPlaceholder: "描述要达成的目标…",
83
- workflowAgentHint: "直接执行任务",
84
- workflowPlanHint: "先只读规划,确认后执行",
85
- workflowGoalHint: "围绕目标持续推进并验证",
86
- planReady: "方案已就绪,等待你确认",
87
- planReadyHint: "确认后开始修改代码并验证结果",
88
- planRefine: "调整方案",
89
- planApproving: "正在启动…",
90
- planApprovalFailed: "启动失败,请重试",
91
- planApprove: "执行方案",
92
- goalActive: "当前目标",
93
75
  sendSteer: "插话:当前工具跑完就送达",
94
76
  sendQueue: "排队:本轮结束后发送",
95
77
  queueEdit: "↑ 取回编辑",
@@ -216,7 +198,6 @@ const zh = {
216
198
  webAuthOn: "已启用(PI_WEB_PASSWORD)",
217
199
  webAuthOff: "未启用(仅本机可访问)",
218
200
  logout: "退出登录",
219
- logoutFailed: "退出登录失败,请检查网络后重试。",
220
201
  authMethodApiKey: "API 密钥",
221
202
  oauthDevicePrompt: "请在浏览器中完成授权",
222
203
  oauthOpenAuth: "打开授权页面",
@@ -255,8 +236,6 @@ const zh = {
255
236
  noSessions: "暂无会话",
256
237
  // Hero
257
238
  startWith: "新建工作区",
258
- heroTitle: "让想法落到代码。",
259
- heroDescription: "规划、执行、验证。一个专注于交付的轻量工作台。",
260
239
  // 输入卡
261
240
  inputPlaceholder: "给 pi 发消息…",
262
241
  thinking: "思考",
@@ -266,8 +245,6 @@ const zh = {
266
245
  triggerLoading: "正在加载模型…",
267
246
  blockedComposer: "当前模型不可用,请先选择模型",
268
247
  emptyModels: "没有可用的模型。",
269
- modelsLoading: "正在加载模型…",
270
- modelsLoadFailed: "模型列表加载失败。",
271
248
  emptyEfforts: "当前模型未提供推理等级。",
272
249
  thinkingUnsupported: "此模型不支持",
273
250
  thinkingUnsupportedHint: "模型没有声明推理能力。自定义模型请在 ~/.pi/agent/models.json 里给该模型加 \"reasoning\": true(可选 thinkingLevelMap 指定档位)",
@@ -341,9 +318,8 @@ const zh = {
341
318
  contextAgentToolCall: "Agent Tool Call",
342
319
  contextToolOutput: "Tool Output",
343
320
  contextCompacted: "Compacted Data",
344
- contextAutoCompactBuffer: "自动压缩预留(非占用)",
345
- contextFreeSpace: "剩余空间",
346
- contextEstimateNote: "总量由 Pi 估算;下方分类按字符估算,不可相加。",
321
+ contextAutoCompactBuffer: "Auto-Compact Buffer",
322
+ contextFreeSpace: "Free Space",
347
323
  // 统计条
348
324
  turns: "轮次",
349
325
  toolCalls: "工具调用",
@@ -439,7 +415,6 @@ const zh = {
439
415
  themeNordPaper: "北欧纸墨",
440
416
  themePebrel: "Pebrel",
441
417
  themeDsh: "海与墨",
442
- themePiWeb: "PiWeb · 工作台",
443
418
  fontSize: "正文字号",
444
419
  fontUiSize: "界面字体",
445
420
  fontUiSizeDesc: "侧栏、按钮、标签等界面文字",
@@ -532,8 +507,6 @@ const zh = {
532
507
  updateFailed: "更新失败",
533
508
  updateManualHint: "先停止 piweb,再执行上面的命令(Windows 无法替换运行中的安装目录)",
534
509
  skillsDesc: "关闭后技能不会出现在系统提示中,仅可通过 /skill:名称 手动调用",
535
- skillsLoading: "正在加载技能…",
536
- skillsEmpty: "当前工作区没有可用技能",
537
510
  confirmDeleteSkill: "确定删除技能“{name}”吗?将删除其所在技能目录,不可恢复。",
538
511
  deleteSkillHint: "删除技能目录",
539
512
  skillDeletePackageHint: "包技能请用禁用管理",
@@ -581,37 +554,36 @@ const zh = {
581
554
  running: "运行中",
582
555
  // 项目生长(项目栏 / 文件查看器)
583
556
  projectPanel: "项目",
584
- growthScopeStep: "本步",
585
- growthScopeSession: "本会话",
586
- growthOnlyChanges: "只看变更",
557
+ growthScopeRound: "本轮",
558
+ growthScopeSession: "本会话累计",
559
+ growthOnlyChanges: "只看改动",
587
560
  growthFollow: "跟随",
588
561
  growthFollowing: "跟随中",
589
562
  growthPrev: "上一轮",
590
563
  growthNext: "下一轮",
591
564
  growthRoundPosition: "第 {current}/{total} 轮",
592
- growthSnapshotNow: "立即快照",
593
- growthSnapshotNone: "没有变化",
594
- growthNoSteps: "还没有快照。发一条消息让 pi 开始工作,项目的变化会在这里逐步出现。",
595
- growthLoading: "正在加载快照…",
596
- growthUnrecorded: "此轮发生在生长快照启用前,改动未记录",
565
+ growthRecordNow: "立即记录:把当前改动记为「你的修改」",
566
+ growthRecordNone: "没有新的改动",
567
+ growthNoRounds: "还没有记录。发一条消息让 pi 开始工作,每一轮的改动会出现在这里。",
568
+ growthLoading: "正在读取记录…",
597
569
  growthNoChangesRound: "本轮无文件改动",
598
570
  growthNoSession: "打开或新建一个会话后,这里会显示项目的生长过程。",
599
571
  growthUnavailable: "机器上找不到 git,项目生长功能不可用",
600
- growthUnavailableFallback: "生长快照不可用(找不到可用的 git),已显示当前目录结构",
601
- growthStepLabel: "第 {n} 步",
572
+ growthUnavailableFallback: "生长记录不可用(找不到可用的 git),已显示当前目录结构",
602
573
  growthRoundLabel: "第 {n} 轮",
603
- growthStepsCount: "{n} 步",
604
- growthKindBaseline: "会话基线",
605
- growthKindTurn: "回合结束",
606
- growthKindExternal: "外部修改",
607
- growthKindManual: "手动快照",
608
- growthStatA: "新增",
609
- growthStatM: "修改",
574
+ growthKindUser: "你的修改",
575
+ growthRoundFiles: "{n} 个文件",
576
+ growthJumpToChat: "在对话里看",
577
+ growthRunning: "本轮进行中…",
578
+ growthStatusAborted: "已中止",
579
+ growthStatusError: "出错",
610
580
  growthStatD: "删除",
611
- growthStatR: "重命名",
612
581
  growthPending: "生成中",
613
- growthLazyDir: "当前磁盘条目,不在所选快照中",
614
- growthTruncated: "这一步变更过多,只显示前 2000 条",
582
+ growthLazyDir: "当前磁盘条目,不在所选这一轮的记录中",
583
+ growthTruncated: "这一轮变更过多,只显示前 2000 条",
584
+ chatRoundChanged: "本轮改了 {n} 个文件",
585
+ chatRoundNoChanges: "本轮没有改动文件",
586
+ chatRoundShow: "在项目栏里查看这一轮",
615
587
  growthExpandAll: "展开全部",
616
588
  growthCollapseAll: "收起全部",
617
589
  growthFilter: "筛选…",
@@ -647,14 +619,13 @@ const en: Dict = {
647
619
  rename: "Rename",
648
620
  renameSession: "Rename session",
649
621
  renameWorkspace: "Rename workspace",
650
- sessionActions: "Session actions",
651
- workspaceActions: "Workspace actions",
652
622
  search: "Search",
653
623
  save: "Save",
654
624
  close: "Close",
655
625
  error: "Error",
656
626
  copy: "Copy",
657
627
  copyFailed: "Copy failed",
628
+ chatWidthHandle: "Drag to resize the conversation",
658
629
  editMessage: "Edit this message",
659
630
  sendEdit: "Send again",
660
631
  editMessageFailed: "Edit and resend failed",
@@ -706,23 +677,6 @@ const en: Dict = {
706
677
  backToBottom: "Back to bottom",
707
678
  modeSteer: "steer",
708
679
  modeQueue: "queue",
709
- workflowAgent: "Agent",
710
- workflowPlan: "Plan",
711
- workflowGoal: "Goal",
712
- workflowMenu: "Choose workflow mode",
713
- workflowClear: "Leave workflow mode",
714
- workflowPlanPlaceholder: "Plan changes…",
715
- workflowGoalPlaceholder: "Describe the goal…",
716
- workflowAgentHint: "Execute the task directly",
717
- workflowPlanHint: "Plan read-only, then request approval",
718
- workflowGoalHint: "Pursue and verify an objective",
719
- planReady: "Plan ready for your approval",
720
- planReadyHint: "Confirm to make changes and verify the result",
721
- planRefine: "Refine plan",
722
- planApproving: "Starting…",
723
- planApprovalFailed: "Could not start. Try again.",
724
- planApprove: "Execute plan",
725
- goalActive: "Current goal",
726
680
  sendSteer: "Steer: delivered after the current tool call",
727
681
  sendQueue: "Queue: sent after this turn ends",
728
682
  queueEdit: "↑ Edit queued",
@@ -849,7 +803,6 @@ const en: Dict = {
849
803
  webAuthOn: "Enabled (PI_WEB_PASSWORD)",
850
804
  webAuthOff: "Disabled (local access only)",
851
805
  logout: "Sign out",
852
- logoutFailed: "Could not sign out. Check your connection and retry.",
853
806
  authMethodApiKey: "API key",
854
807
  oauthDevicePrompt: "Finish authorization in your browser",
855
808
  oauthOpenAuth: "Open authorization page",
@@ -887,8 +840,6 @@ const en: Dict = {
887
840
  oauthCancel: "Cancel login",
888
841
  noSessions: "No sessions yet",
889
842
  startWith: "New workspace",
890
- heroTitle: "Move ideas into working code.",
891
- heroDescription: "Plan, execute, verify. A focused workbench for shipping.",
892
843
  inputPlaceholder: "Message pi…",
893
844
  thinking: "Thinking",
894
845
  thinkingOff: "Off",
@@ -897,8 +848,6 @@ const en: Dict = {
897
848
  triggerLoading: "Loading models…",
898
849
  blockedComposer: "This model is unavailable — select one to continue",
899
850
  emptyModels: "No models available.",
900
- modelsLoading: "Loading models…",
901
- modelsLoadFailed: "Could not load models.",
902
851
  emptyEfforts: "This model provides no reasoning effort levels.",
903
852
  thinkingUnsupported: "Not supported by this model",
904
853
  thinkingUnsupportedHint: "The model does not declare reasoning support. For custom models, add \"reasoning\": true (optionally a thinkingLevelMap) to the model in ~/.pi/agent/models.json",
@@ -972,9 +921,8 @@ const en: Dict = {
972
921
  contextAgentToolCall: "Agent Tool Call",
973
922
  contextToolOutput: "Tool Output",
974
923
  contextCompacted: "Compacted Data",
975
- contextAutoCompactBuffer: "Auto-compact reserve (not used)",
924
+ contextAutoCompactBuffer: "Auto-Compact Buffer",
976
925
  contextFreeSpace: "Free Space",
977
- contextEstimateNote: "Pi estimates total usage; content categories are rough estimates and do not add up.",
978
926
  turns: "turns",
979
927
  toolCalls: "tool calls",
980
928
  cost: "cost",
@@ -1066,7 +1014,6 @@ const en: Dict = {
1066
1014
  themeNordPaper: "Nord & Paper",
1067
1015
  themePebrel: "Pebrel",
1068
1016
  themeDsh: "Sea & Ink",
1069
- themePiWeb: "PiWeb · Workbench",
1070
1017
  fontSize: "Font size",
1071
1018
  fontUiSize: "UI font size",
1072
1019
  fontUiSizeDesc: "Sidebar, buttons, labels and other UI text",
@@ -1159,8 +1106,6 @@ const en: Dict = {
1159
1106
  updateFailed: "Update failed",
1160
1107
  updateManualHint: "Stop piweb, then run the command above (Windows cannot replace a running installation)",
1161
1108
  skillsDesc: "Disabled skills are hidden from the system prompt and only callable via /skill:name",
1162
- skillsLoading: "Loading skills…",
1163
- skillsEmpty: "No skills available in this workspace",
1164
1109
  confirmDeleteSkill: "Delete skill \"{name}\"? Its skill directory will be removed and cannot be recovered.",
1165
1110
  deleteSkillHint: "Delete the skill directory",
1166
1111
  skillDeletePackageHint: "package skill: use disable",
@@ -1207,37 +1152,36 @@ const en: Dict = {
1207
1152
  toastError: "Operation failed",
1208
1153
  running: "Running",
1209
1154
  projectPanel: "Project",
1210
- growthScopeStep: "This step",
1211
- growthScopeSession: "This session",
1155
+ growthScopeRound: "This round",
1156
+ growthScopeSession: "Session total",
1212
1157
  growthOnlyChanges: "Changes only",
1213
1158
  growthFollow: "Follow",
1214
1159
  growthFollowing: "Following",
1215
1160
  growthPrev: "Previous round",
1216
1161
  growthNext: "Next round",
1217
1162
  growthRoundPosition: "Round {current}/{total}",
1218
- growthSnapshotNow: "Snapshot now",
1219
- growthSnapshotNone: "No changes",
1220
- growthNoSteps: "No snapshots yet. Send pi a message and the project's changes will show up here step by step.",
1221
- growthLoading: "Loading snapshots…",
1222
- growthUnrecorded: "This round predates growth snapshots; its changes were not recorded",
1163
+ growthRecordNow: "Record now: save the current changes as \"Your changes\"",
1164
+ growthRecordNone: "No new changes",
1165
+ growthNoRounds: "Nothing recorded yet. Send pi a message and each round's changes will show up here.",
1166
+ growthLoading: "Loading history…",
1223
1167
  growthNoChangesRound: "No file changes in this round",
1224
1168
  growthNoSession: "Open or start a session to watch the project grow here.",
1225
1169
  growthUnavailable: "git was not found on this machine; project growth is unavailable",
1226
- growthUnavailableFallback: "Growth snapshots are unavailable (no usable git); showing the current directory structure",
1227
- growthStepLabel: "Step {n}",
1170
+ growthUnavailableFallback: "Growth history is unavailable (no usable git); showing the current directory structure",
1228
1171
  growthRoundLabel: "Round {n}",
1229
- growthStepsCount: "{n} steps",
1230
- growthKindBaseline: "Session baseline",
1231
- growthKindTurn: "Turn ended",
1232
- growthKindExternal: "External change",
1233
- growthKindManual: "Manual snapshot",
1234
- growthStatA: "Added",
1235
- growthStatM: "Modified",
1172
+ growthKindUser: "Your changes",
1173
+ growthRoundFiles: "{n} files",
1174
+ growthJumpToChat: "Show in chat",
1175
+ growthRunning: "Round in progress…",
1176
+ growthStatusAborted: "Aborted",
1177
+ growthStatusError: "Error",
1236
1178
  growthStatD: "Deleted",
1237
- growthStatR: "Renamed",
1238
1179
  growthPending: "Writing…",
1239
- growthLazyDir: "Current disk entry, not in the selected snapshot",
1240
- growthTruncated: "Too many changes in this step; showing the first 2000",
1180
+ growthLazyDir: "Current disk entry, not recorded in the selected round",
1181
+ growthTruncated: "Too many changes in this round; showing the first 2000",
1182
+ chatRoundChanged: "This round changed {n} files",
1183
+ chatRoundNoChanges: "No file changes this round",
1184
+ chatRoundShow: "Show this round in the project panel",
1241
1185
  growthExpandAll: "Expand all",
1242
1186
  growthCollapseAll: "Collapse all",
1243
1187
  growthFilter: "Filter…",