@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
@@ -33,18 +33,14 @@ import { TrajLedger, buildTrajectoryFromEntries, toTrajTokens } from "./trajecto
33
33
  import { startArchivedSessionRetention } from "./session-retention";
34
34
  import { sanitizeToolOutput } from "./text-sanitize";
35
35
  import { BoundaryError } from "./path-security";
36
- import { beginActivity } from "./runtime-activity";
37
36
  import { estimateTokensOf } from "./process-format";
38
37
  import { getPiSettings } from "./pi-settings";
39
- import { createManagedNiubashTools } from "./managed-niubash";
40
- import { createDelegationTool } from "./delegation";
41
- import { awaitingGoalMessage, isWorkflowMode, planCanRun, readWorkflow, saveWorkflow, workflowInstruction, type WorkflowState } from "./workflow";
42
38
  import { clampThinkingLevel, getSupportedThinkingLevels } from "@earendil-works/pi-ai";
43
39
  import type {
44
40
  AgentCommand,
45
41
  ContextBreakdown,
46
42
  ContextResource,
47
- GrowthStep,
43
+ GrowthRound,
48
44
  TrajEntry,
49
45
  ToolPreset,
50
46
  WebEvent,
@@ -69,7 +65,6 @@ interface Managed {
69
65
  ledger: TrajLedger;
70
66
  lastActive: number;
71
67
  toolPreset: ToolPreset;
72
- workflow: WorkflowState;
73
68
  /** 显式逐项选择优先于 preset;保留失效名称以便资源重新启用后恢复用户选择。 */
74
69
  customActiveTools?: string[];
75
70
  resourceVersion: number;
@@ -531,20 +526,6 @@ function translate(m: Managed, evt: AgentSessionEvent): void {
531
526
  break;
532
527
  case "agent_settled":
533
528
  m.runActive = false;
534
- if (m.workflow.mode === "plan") {
535
- if (m.workflow.planStatus === "planning") {
536
- const answer = [...(m.session?.messages ?? [])].reverse().find((message) => message.role === "assistant");
537
- const ready = answer?.role === "assistant" && answer.stopReason === "stop" && answer.content.some((part) => part.type === "text" && part.text.trim());
538
- const entry = ready ? m.sm.getBranch().slice().reverse().find((item) => item.type === "message" && item.message.role === "assistant" && item.message.stopReason === "stop") : undefined;
539
- setWorkflow(m, { ...m.workflow, planStatus: entry ? "ready" : "idle", planId: entry?.id });
540
- } else if (m.workflow.planStatus === "executing") {
541
- // 执行报错或被中止时方案仍待执行:以当前叶节点为新的批准锚点,可以直接再次执行。
542
- const answer = [...(m.session?.messages ?? [])].reverse().find((message) => message.role === "assistant");
543
- const failed = answer?.role === "assistant" && (answer.stopReason === "error" || answer.stopReason === "aborted");
544
- const anchor = failed ? m.sm.getLeafId() : null;
545
- setWorkflow(m, anchor ? { ...m.workflow, planStatus: "ready", planId: anchor } : { ...m.workflow, planStatus: "idle", planId: undefined });
546
- }
547
- }
548
529
  publish(m, { type: "status", isStreaming: false, state: "idle", ts: now });
549
530
  publishUsage(m);
550
531
  if (m.resourceReloadPending) queueMicrotask(() => void reloadManagedResources(m));
@@ -606,13 +587,18 @@ function growthOf(m: Managed): GrowthTracker {
606
587
  m.growth.dispose();
607
588
  m.growth = null;
608
589
  }
609
- return (m.growth ??= createGrowthTracker({ cwd: m.cwd, sessionPath: m.sessionPath, publish: (evt) => publish(m, evt) }));
590
+ return (m.growth ??= createGrowthTracker({
591
+ cwd: m.cwd,
592
+ sessionPath: m.sessionPath,
593
+ publish: (evt) => publish(m, evt),
594
+ entries: () => m.sm.getEntries() as never,
595
+ }));
610
596
  }
611
597
 
612
- /** 手动快照(项目栏「立即快照」):记下的步同时广播给本会话的订阅者 */
613
- export async function growthSnapshot(m: Managed, label = ""): Promise<GrowthStep | null> {
598
+ /** 立即记录(项目栏按钮):把当前改动提交为「你的修改」,同时广播给本会话的订阅者 */
599
+ export async function growthRecord(m: Managed): Promise<GrowthRound | null> {
614
600
  touch(m);
615
- return growthOf(m).snapshotNow(label);
601
+ return growthOf(m).recordNow();
616
602
  }
617
603
 
618
604
  // ---------- 会话生命周期 ----------
@@ -654,7 +640,6 @@ function registerManaged(sessionPath: string, cwd: string, sm: SessionManager):
654
640
  ledger: new TrajLedger(initialTrajectory),
655
641
  lastActive: Date.now(),
656
642
  toolPreset: "readonly",
657
- workflow: readWorkflow(sm),
658
643
  resourceVersion: 0,
659
644
  resourceReloadPending: false,
660
645
  resourceReloading: false,
@@ -803,33 +788,12 @@ function publishEnvironmentTrajectory(m: Managed, session: AgentSession): void {
803
788
  }
804
789
 
805
790
  export async function ensureSession(m: Managed): Promise<AgentSession> {
806
- const release = beginActivity("session");
807
- try { return await ensureSessionActive(m); }
808
- finally { release(); }
809
- }
810
-
811
- async function ensureSessionActive(m: Managed): Promise<AgentSession> {
812
791
  if (m.disposed) throw new Error("session is disposed");
813
792
  if (m.creating) return m.creating;
814
793
  if (m.session) return m.session;
815
794
  m.creating = (async () => {
816
795
  await resourceLoaderReady(m.cwd);
817
- const loader = await createSessionResourceLoader(m.cwd, [{
818
- name: "piweb-workflow",
819
- hidden: true,
820
- factory: (pi) => {
821
- pi.on("before_agent_start", (event) => {
822
- const instruction = workflowInstruction(m.workflow);
823
- if (instruction) {
824
- if (event.systemPromptOptions.forceSystemPrompt !== undefined) event.systemPromptOptions.forceSystemPrompt += `\n\n${instruction}`;
825
- else event.systemPromptOptions.sections.piweb_workflow = instruction;
826
- } else delete event.systemPromptOptions.sections.piweb_workflow;
827
- if (m.workflow.mode === "plan" && m.workflow.planStatus !== "executing") {
828
- event.systemPromptOptions.selectedTools = event.systemPromptOptions.selectedTools.filter((name) => [...TOOL_PRESETS.readonly, "piweb_delegate"].includes(name));
829
- }
830
- });
831
- },
832
- }]);
796
+ const loader = await createSessionResourceLoader(m.cwd);
833
797
  let created: AgentSession | undefined;
834
798
  try {
835
799
  if (m.disposed) throw new Error("session is disposed");
@@ -840,8 +804,6 @@ async function ensureSessionActive(m: Managed): Promise<AgentSession> {
840
804
  modelRuntime: await getModelRuntime(),
841
805
  resourceLoader: loader,
842
806
  settingsManager: getSettingsManager(m.cwd),
843
- // Windows: 同名 bash 覆盖 SDK 内置工具,指向托管 niubash;其它平台返回 [],走 Pi 默认。
844
- customTools: [...createManagedNiubashTools(m.cwd), createDelegationTool(m.cwd, () => m.session)],
845
807
  });
846
808
  created = session;
847
809
  if (m.disposed) throw new Error("session is disposed");
@@ -888,9 +850,7 @@ function isManagedBusy(m: Managed): boolean {
888
850
 
889
851
  function allowedToolNames(m: Managed, session: AgentSession): string[] {
890
852
  const allowed = m.customActiveTools ?? (m.toolPreset === "full" ? undefined : TOOL_PRESETS[m.toolPreset]);
891
- const effective = allowed ? [...allowed, ...(m.customActiveTools || m.toolPreset === "readonly" ? [] : ["piweb_delegate"])] : undefined;
892
- const planning = m.workflow.mode === "plan" && m.workflow.planStatus !== "executing";
893
- return listAllToolNames(session).filter((name) => (!effective || effective.includes(name)) && (!planning || [...TOOL_PRESETS.readonly, "piweb_delegate"].includes(name)));
853
+ return listAllToolNames(session).filter((name) => !allowed || allowed.includes(name));
894
854
  }
895
855
 
896
856
  function applyToolPolicy(m: Managed, session: AgentSession): void {
@@ -901,20 +861,6 @@ function publishTools(m: Managed, session: AgentSession): void {
901
861
  publish(m, { type: "tools", active: listActiveTools(session), all: listAllToolNames(session), toolPreset: m.toolPreset, customActiveTools: m.customActiveTools ?? null, ts: Date.now() });
902
862
  }
903
863
 
904
- function setWorkflow(m: Managed, next: WorkflowState): void {
905
- saveWorkflow(m.sm, next);
906
- m.workflow = next;
907
- publishWorkflow(m);
908
- }
909
-
910
- function publishWorkflow(m: Managed): void {
911
- if (m.session && !m.disposed) {
912
- applyToolPolicy(m, m.session);
913
- publishTools(m, m.session);
914
- }
915
- publish(m, { type: "workflow", workflow: m.workflow, ts: Date.now() });
916
- }
917
-
918
864
  /** SDK reload 自动启用扩展工具,注册新工具也会刷新全集;统一在激活边界收敛到服务端选择。 */
919
865
  function installSessionPolicy(m: Managed, session: AgentSession): void {
920
866
  const setActive = session.setActiveToolsByName.bind(session);
@@ -1230,12 +1176,12 @@ export async function buildSnapshot(m: Managed): Promise<WebSnapshot> {
1230
1176
  }
1231
1177
  for (let i = messages.length - 1; i >= 0 && !compactedSinceLastAssistant; i--) {
1232
1178
  const msg = messages[i];
1233
- if (msg.role === "assistant" && msg.usage && msg.stopReason !== "error" && msg.stopReason !== "aborted") {
1234
- lastTurnTokens = Number(msg.usage.totalTokens ?? 0) || (
1179
+ if (msg.role === "assistant" && msg.usage) {
1180
+ lastTurnTokens =
1235
1181
  Number(msg.usage.input ?? 0) +
1236
1182
  Number(msg.usage.cacheRead ?? 0) +
1237
1183
  Number(msg.usage.cacheWrite ?? 0) +
1238
- Number(msg.usage.output ?? 0));
1184
+ Number(msg.usage.output ?? 0);
1239
1185
  break;
1240
1186
  }
1241
1187
  }
@@ -1300,7 +1246,6 @@ export async function buildSnapshot(m: Managed): Promise<WebSnapshot> {
1300
1246
  thinkingLevel,
1301
1247
  thinkingLevels,
1302
1248
  toolPreset: m.toolPreset,
1303
- workflow: m.workflow,
1304
1249
  customActiveTools: m.customActiveTools ?? null,
1305
1250
  extensionUiRequests: m.ui?.getPendingRequests() ?? [],
1306
1251
  tools,
@@ -1354,52 +1299,12 @@ export interface CommandResult {
1354
1299
  }
1355
1300
 
1356
1301
  export async function execute(m: Managed, cmd: AgentCommand): Promise<CommandResult> {
1357
- let release: (() => void) | undefined;
1358
- try {
1359
- if (!["abort", "clearQueue", "extensionUiResponse"].includes(cmd.cmd)) release = beginActivity("session");
1360
- return await executeCommand(m, cmd);
1361
- } catch (error) {
1362
- return { ok: false, error: error instanceof Error ? error.message : String(error) };
1363
- } finally {
1364
- release?.();
1365
- }
1366
- }
1367
-
1368
- function trackedPrompt(session: AgentSession, ...args: Parameters<AgentSession["prompt"]>): ReturnType<AgentSession["prompt"]> {
1369
- const release = beginActivity("session");
1370
- try { return session.prompt(...args).finally(release); }
1371
- catch (error) { release(); throw error; }
1372
- }
1373
-
1374
- async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandResult> {
1375
1302
  touch(m);
1376
1303
  try {
1377
1304
  switch (cmd.cmd) {
1378
1305
  case "prepare":
1379
1306
  await ensureSession(m);
1380
1307
  return { ok: true };
1381
- case "setWorkflowMode": {
1382
- if (!isWorkflowMode(cmd.mode)) return { ok: false, error: "invalid workflow mode" };
1383
- if (isManagedBusy(m)) return { ok: false, error: "cannot change workflow while the agent is running" };
1384
- // 重选当前模式不重置:否则会清掉 Goal 目标或待执行的方案,并多写一条记录。
1385
- if (cmd.mode === m.workflow.mode) return { ok: true };
1386
- setWorkflow(m, { mode: cmd.mode, planStatus: "idle", goal: "" });
1387
- return { ok: true };
1388
- }
1389
- case "approvePlan": {
1390
- if (!planCanRun(m.workflow)) return { ok: false, error: "there is no plan awaiting approval" };
1391
- if (isManagedBusy(m)) return { ok: false, error: "session is busy" };
1392
- const branch = m.sm.getBranch();
1393
- const planIndex = branch.findIndex((entry) => entry.id === m.workflow.planId);
1394
- if (planIndex < 0 || branch.slice(planIndex + 1).some((entry) => entry.type === "message")) {
1395
- return { ok: false, error: "the plan is no longer the latest conversation; request a new plan" };
1396
- }
1397
- const ready = m.workflow;
1398
- setWorkflow(m, { ...ready, planStatus: "executing" });
1399
- const result = await execute(m, { cmd: "prompt", text: "Execute the plan you just proposed. Verify the changes and report any unfinished work." });
1400
- if (!result.ok) setWorkflow(m, ready);
1401
- return result;
1402
- }
1403
1308
  case "prompt": {
1404
1309
  const text = (cmd.text ?? "").trim();
1405
1310
  if (!text && !cmd.images?.length) return { ok: false, error: "empty prompt" };
@@ -1411,7 +1316,6 @@ async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandRes
1411
1316
  if (m.disposed) throw new Error("session is disposed");
1412
1317
  // 只有用户显式选择 steer/followUp 才排队;旧的普通提交不能悄悄成为 steering。
1413
1318
  if ((session.isStreaming || m.runActive) && !cmd.behavior) return { ok: false, error: "session is busy; choose steer or followUp" };
1414
- if (m.workflow.mode === "plan" && (session.isStreaming || m.runActive)) return { ok: false, error: "wait for the current plan or execution to finish" };
1415
1319
  if (!session.isStreaming) {
1416
1320
  // 基线快照不能无限阻塞首条 prompt(git 不可用时每次探测至多 30s 超时):
1417
1321
  // 5s 内没完成就放行 prompt,快照后台补拍(工具结束后照常记步,外部修改兜底)。
@@ -1421,18 +1325,11 @@ async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandRes
1421
1325
  ]);
1422
1326
  }
1423
1327
  if (m.disposed) throw new Error("session is disposed");
1424
- const previousWorkflow = m.workflow;
1425
- if (m.workflow.mode === "plan" && m.workflow.planStatus !== "executing") {
1426
- setWorkflow(m, { ...m.workflow, planStatus: "planning", planId: undefined });
1427
- } else if (m.workflow.mode === "goal" && !m.workflow.goal && text) {
1428
- setWorkflow(m, { ...m.workflow, goal: text.slice(0, 8_000) });
1429
- }
1430
- const result = await new Promise<CommandResult>((resolve) => {
1328
+ return await new Promise<CommandResult>((resolve) => {
1431
1329
  let accepted = false;
1432
- const run = trackedPrompt(session, text, {
1330
+ const run = session.prompt(text, {
1433
1331
  images: cmd.images,
1434
1332
  streamingBehavior: cmd.behavior,
1435
- expandPromptTemplates: m.workflow.mode !== "plan" || m.workflow.planStatus === "executing",
1436
1333
  source: "rpc",
1437
1334
  preflightResult: (success) => {
1438
1335
  if (success) {
@@ -1449,9 +1346,7 @@ async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandRes
1449
1346
  if (accepted) publish(m, { type: "error", message, ts: Date.now() });
1450
1347
  else resolve({ ok: false, error: message });
1451
1348
  });
1452
- });
1453
- if (!result.ok && m.workflow !== previousWorkflow) setWorkflow(m, previousWorkflow);
1454
- return result;
1349
+ });
1455
1350
  } finally {
1456
1351
  m.promptSubmitting = false;
1457
1352
  if (!m.disposed) publish(m, { type: "status", isStreaming: isManagedBusy(m), state: isManagedBusy(m) ? "running" : "idle", ts: Date.now() });
@@ -1460,7 +1355,6 @@ async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandRes
1460
1355
  }
1461
1356
  case "steer":
1462
1357
  case "followUp": {
1463
- if (m.workflow.mode === "plan") return { ok: false, error: "Plan mode does not queue prompts" };
1464
1358
  if (m.promptSubmitting || m.resourceReloading) return { ok: false, error: "session is busy accepting another command" };
1465
1359
  const session = await ensureSession(m);
1466
1360
  if (m.promptSubmitting || m.resourceReloading || !session.isStreaming) return { ok: false, error: "session is not accepting queued messages" };
@@ -1549,10 +1443,6 @@ async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandRes
1549
1443
  const entryId = String((cmd as any).entryId ?? "");
1550
1444
  if (!entryId) return { ok: false, error: "missing entryId" };
1551
1445
  const r = await session.navigateTree(entryId);
1552
- if (!r?.cancelled) {
1553
- m.workflow = readWorkflow(m.sm);
1554
- publishWorkflow(m);
1555
- }
1556
1446
  return { ok: !r?.cancelled, data: { cancelled: r?.cancelled === true, editorText: r?.editorText } };
1557
1447
  }
1558
1448
  case "editAndResend": {
@@ -1562,9 +1452,6 @@ async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandRes
1562
1452
  const text = (cmd.text ?? "").trim();
1563
1453
  if (!entryId) return { ok: false, error: "missing entryId" };
1564
1454
  if (!text) return { ok: false, error: "empty prompt" };
1565
- const target = m.sm.getEntry(entryId);
1566
- if (target?.type !== "message" || target.message.role !== "user") return { ok: false, error: "message is not editable" };
1567
- const images = Array.isArray(target.message.content) ? target.message.content.filter((part) => part.type === "image") : [];
1568
1455
  if (m.promptSubmitting || m.resourceReloading) return { ok: false, error: "session is busy accepting another command" };
1569
1456
  m.promptSubmitting = true;
1570
1457
  try {
@@ -1578,64 +1465,11 @@ async function executeCommand(m: Managed, cmd: AgentCommand): Promise<CommandRes
1578
1465
  }
1579
1466
  }
1580
1467
  if (m.disposed) throw new Error("session is disposed");
1581
- // SDK 对当前叶节点直接返回 no-op;先移开叶节点,才能把最后一条用户消息也原位重发。
1582
- const originalLeafId = m.sm.getLeafId();
1583
- const leafWasTarget = originalLeafId === entryId;
1584
- if (leafWasTarget) {
1585
- if (target.parentId) m.sm.branch(target.parentId);
1586
- else m.sm.resetLeaf();
1587
- }
1588
- let moved;
1589
- try {
1590
- moved = await session.navigateTree(entryId);
1591
- } catch (error) {
1592
- if (leafWasTarget) m.sm.branch(entryId);
1593
- throw error;
1594
- }
1595
- if (moved?.cancelled && leafWasTarget) m.sm.branch(entryId);
1468
+ const moved = await session.navigateTree(entryId);
1596
1469
  if (moved?.cancelled) return { ok: false, error: "edit cancelled" };
1597
- m.workflow = readWorkflow(m.sm);
1598
- publishWorkflow(m);
1599
1470
  await growthOf(m).prepare().catch(() => undefined);
1600
- const previousWorkflow = m.workflow;
1601
- if (m.workflow.mode === "plan") setWorkflow(m, { ...m.workflow, planStatus: "planning", planId: undefined });
1602
- // 编辑的正是定下目标的那条消息时,目标跟着改;旧目标记录是它的祖先,回退分支不会带走它。
1603
- else if (m.workflow.mode === "goal" && awaitingGoalMessage(m.sm) && m.workflow.goal !== text.slice(0, 8_000)) {
1604
- setWorkflow(m, { ...m.workflow, goal: text.slice(0, 8_000) });
1605
- }
1606
- const options = { images, expandPromptTemplates: m.workflow.mode !== "plan" };
1607
- return await new Promise<CommandResult>((resolve) => {
1608
- let accepted = false;
1609
- const run = trackedPrompt(session, text, {
1610
- ...options,
1611
- preflightResult: (success) => {
1612
- if (success) {
1613
- accepted = true;
1614
- resolve({ ok: true, data: { accepted: true } });
1615
- }
1616
- },
1617
- });
1618
- void run.then(() => {
1619
- if (!accepted) resolve({ ok: true });
1620
- }, (error) => {
1621
- const message = String(error?.message ?? error);
1622
- if (accepted) {
1623
- publish(m, { type: "error", message, ts: Date.now() });
1624
- return;
1625
- }
1626
- // Rejected preflight never wrote the edited turn; restore the old branch before the client resyncs.
1627
- try {
1628
- if (originalLeafId) m.sm.branch(originalLeafId);
1629
- else m.sm.resetLeaf();
1630
- session.refreshContext();
1631
- m.workflow = readWorkflow(m.sm);
1632
- publishWorkflow(m);
1633
- } catch {
1634
- if (m.workflow !== previousWorkflow) setWorkflow(m, previousWorkflow);
1635
- }
1636
- resolve({ ok: false, error: message });
1637
- });
1638
- });
1471
+ await session.prompt(text);
1472
+ return { ok: true };
1639
1473
  } finally {
1640
1474
  m.promptSubmitting = false;
1641
1475
  }
@@ -1,4 +1,4 @@
1
- import type { AgentCommand, ImageAttachment, ToolPreset, WorkflowMode } from "./types";
1
+ import type { AgentCommand, ImageAttachment, ToolPreset } from "./types";
2
2
 
3
3
  const COMMANDS = new Set<AgentCommand["cmd"]>([
4
4
  "prepare",
@@ -10,8 +10,6 @@ const COMMANDS = new Set<AgentCommand["cmd"]>([
10
10
  "setModel",
11
11
  "setThinkingLevel",
12
12
  "setToolPreset",
13
- "setWorkflowMode",
14
- "approvePlan",
15
13
  "setActiveTools",
16
14
  "rename",
17
15
  "fork",
@@ -23,7 +21,6 @@ const COMMANDS = new Set<AgentCommand["cmd"]>([
23
21
  "reload",
24
22
  ]);
25
23
  const TOOL_PRESETS = new Set<ToolPreset>(["readonly", "standard", "full"]);
26
- const WORKFLOW_MODES = new Set<WorkflowMode>(["agent", "plan", "goal"]);
27
24
  const STREAMING_BEHAVIORS = new Set(["steer", "followUp"]);
28
25
  const IMAGE_TYPES = new Set(["image/jpeg", "image/png", "image/webp", "image/gif"]);
29
26
  const MAX_TEXT = 1_000_000;
@@ -81,10 +78,6 @@ export function parseAgentCommand(value: unknown): CommandParseResult {
81
78
  if (typeof raw.preset !== "string" || !TOOL_PRESETS.has(raw.preset as ToolPreset)) throw new Error("invalid tool preset");
82
79
  command.preset = raw.preset as ToolPreset;
83
80
  }
84
- if (raw.mode !== undefined) {
85
- if (typeof raw.mode !== "string" || !WORKFLOW_MODES.has(raw.mode as WorkflowMode)) throw new Error("invalid workflow mode");
86
- command.mode = raw.mode as WorkflowMode;
87
- }
88
81
  if (raw.behavior !== undefined) {
89
82
  if (typeof raw.behavior !== "string" || !STREAMING_BEHAVIORS.has(raw.behavior)) throw new Error("invalid streaming behavior");
90
83
  command.behavior = raw.behavior as "steer" | "followUp";
@@ -115,7 +108,6 @@ export function parseAgentCommand(value: unknown): CommandParseResult {
115
108
  if (command.cmd === "setModel" && (!command.provider || !command.modelId)) throw new Error("provider and modelId are required");
116
109
  if (command.cmd === "setThinkingLevel" && !command.level) throw new Error("level is required");
117
110
  if (command.cmd === "setToolPreset" && !command.preset) throw new Error("preset is required");
118
- if (command.cmd === "setWorkflowMode" && !command.mode) throw new Error("mode is required");
119
111
  if (command.cmd === "setActiveTools" && !command.names) throw new Error("names are required");
120
112
  if (command.cmd === "navigate" && !command.entryId) throw new Error("entryId is required");
121
113
  return { ok: true, command };