gsd-pi 2.80.0-dev.2848d9009 → 2.80.0-dev.42bd34838

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 (241) hide show
  1. package/README.md +4 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/auto/loop.js +32 -1
  4. package/dist/resources/extensions/gsd/auto/phases.js +29 -15
  5. package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
  6. package/dist/resources/extensions/gsd/auto/run-unit.js +13 -1
  7. package/dist/resources/extensions/gsd/auto-prompts.js +13 -1
  8. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  9. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  10. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  11. package/dist/resources/extensions/gsd/auto.js +68 -4
  12. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +21 -2
  13. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +27 -20
  14. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +21 -0
  15. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  16. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  17. package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
  18. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  19. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  20. package/dist/resources/extensions/gsd/git-service.js +36 -4
  21. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  22. package/dist/resources/extensions/gsd/guided-flow.js +52 -10
  23. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  24. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  25. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  26. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  27. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  28. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +14 -13
  29. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  30. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  31. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  32. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  33. package/dist/resources/extensions/gsd/quick.js +34 -2
  34. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  35. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  36. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  37. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  38. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  39. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  40. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  41. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  42. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  43. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  44. package/dist/resources/extensions/gsd/worktree-resolver.js +33 -17
  45. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  46. package/dist/web/standalone/.next/BUILD_ID +1 -1
  47. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  48. package/dist/web/standalone/.next/build-manifest.json +2 -2
  49. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  50. package/dist/web/standalone/.next/required-server-files.json +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/index.html +1 -1
  68. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  75. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  76. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  77. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  78. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  79. package/dist/web/standalone/server.js +1 -1
  80. package/package.json +3 -3
  81. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  82. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  83. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  84. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  85. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  86. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  87. package/packages/native/tsconfig.tsbuildinfo +1 -1
  88. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  89. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  90. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  91. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -0
  92. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  93. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
  94. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  95. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  96. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  97. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  98. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  99. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  100. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  101. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  102. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  103. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  104. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  105. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  106. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  107. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  108. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  109. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  110. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  111. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
  112. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  113. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -0
  114. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  115. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +2 -0
  116. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  117. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +7 -0
  118. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  119. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  120. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  121. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  122. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  123. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  125. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  126. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +3 -0
  127. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  128. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  129. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +13 -5
  130. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  131. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +53 -0
  132. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  133. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  134. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
  135. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  136. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  137. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  138. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  139. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  140. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  141. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  142. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  143. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  144. package/packages/pi-coding-agent/src/core/agent-session.ts +8 -0
  145. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
  146. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  147. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  148. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  149. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  150. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +2 -0
  151. package/packages/pi-coding-agent/src/core/extensions/runner.ts +3 -0
  152. package/packages/pi-coding-agent/src/core/extensions/types.ts +7 -0
  153. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  154. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +4 -0
  155. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +56 -0
  156. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +22 -7
  157. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
  158. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  159. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  160. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  161. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  162. package/packages/pi-tui/dist/tui.js +18 -8
  163. package/packages/pi-tui/dist/tui.js.map +1 -1
  164. package/packages/pi-tui/src/tui.ts +20 -8
  165. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  166. package/src/resources/extensions/gsd/auto/loop.ts +50 -8
  167. package/src/resources/extensions/gsd/auto/phases.ts +35 -20
  168. package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
  169. package/src/resources/extensions/gsd/auto/run-unit.ts +18 -1
  170. package/src/resources/extensions/gsd/auto-prompts.ts +17 -1
  171. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  172. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  173. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  174. package/src/resources/extensions/gsd/auto.ts +80 -3
  175. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -1
  176. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +27 -19
  177. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  178. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  179. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  180. package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
  181. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  182. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  183. package/src/resources/extensions/gsd/git-service.ts +46 -8
  184. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  185. package/src/resources/extensions/gsd/guided-flow.ts +71 -10
  186. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  187. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  188. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  189. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  190. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  191. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  192. package/src/resources/extensions/gsd/prompts/complete-milestone.md +14 -13
  193. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  194. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  195. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  196. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  197. package/src/resources/extensions/gsd/quick.ts +37 -2
  198. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +71 -0
  199. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  200. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  201. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  202. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  203. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  204. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  205. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  206. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  207. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  208. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  209. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +234 -0
  210. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  211. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  212. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  213. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  214. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  215. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  216. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  217. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  218. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  219. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  220. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +20 -0
  221. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  222. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
  223. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  224. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  225. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
  226. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  227. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  228. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +63 -1
  229. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  230. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  231. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  232. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  233. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  234. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  235. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  236. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  237. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  238. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  239. package/src/resources/extensions/gsd/worktree-resolver.ts +36 -15
  240. /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → tht0ltP8EIjsohPOA_WZf}/_buildManifest.js +0 -0
  241. /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → tht0ltP8EIjsohPOA_WZf}/_ssgManifest.js +0 -0
@@ -1287,6 +1287,10 @@ export class ToolPhaseSummaryComponent extends Container {
1287
1287
  super();
1288
1288
  }
1289
1289
 
1290
+ getPhases(): ToolExecutionPhase[] {
1291
+ return this.phases.map((phase) => ({ ...phase }));
1292
+ }
1293
+
1290
1294
  override render(width: number): string[] {
1291
1295
  const frameWidth = Math.max(20, width);
1292
1296
  const rows = this.phases.map((phase) => {
@@ -1,5 +1,7 @@
1
1
  import assert from "node:assert/strict";
2
2
  import test from "node:test";
3
+ import { Container } from "@gsd/pi-tui";
4
+ import stripAnsi from "strip-ansi";
3
5
 
4
6
  import { findLatestPinnableText, handleAgentEvent } from "./chat-controller.js";
5
7
  import { initTheme } from "../theme/theme.js";
@@ -111,3 +113,57 @@ test("handleAgentEvent: agent_start clears stale adaptive blocking error", async
111
113
  assert.equal(cleared, true);
112
114
  assert.equal(requestedRender, true);
113
115
  });
116
+
117
+ test("handleAgentEvent: standalone completed tool events roll up incrementally", async () => {
118
+ initTheme("dark", false);
119
+ const chatContainer = new Container();
120
+ let renderCount = 0;
121
+ const host = {
122
+ isInitialized: true,
123
+ footer: { invalidate() {} },
124
+ settingsManager: {
125
+ getTimestampFormat() {
126
+ return "date-time-iso";
127
+ },
128
+ getShowImages() {
129
+ return false;
130
+ },
131
+ },
132
+ getRegisteredToolDefinition() {
133
+ return undefined;
134
+ },
135
+ chatContainer,
136
+ pendingTools: new Map(),
137
+ ui: {
138
+ requestRender() {
139
+ renderCount++;
140
+ },
141
+ },
142
+ } as any;
143
+
144
+ for (const [toolCallId, toolName] of [
145
+ ["read-1", "read"],
146
+ ["read-2", "read"],
147
+ ["edit-1", "edit"],
148
+ ] as const) {
149
+ await handleAgentEvent(host, {
150
+ type: "tool_execution_start",
151
+ toolCallId,
152
+ toolName,
153
+ args: { path: `/tmp/${toolCallId}.txt` },
154
+ } as any);
155
+ await handleAgentEvent(host, {
156
+ type: "tool_execution_end",
157
+ toolCallId,
158
+ toolName,
159
+ result: { content: [], isError: false },
160
+ isError: false,
161
+ } as any);
162
+ }
163
+
164
+ const rendered = stripAnsi(chatContainer.render(100).join("\n"));
165
+ assert.match(rendered, /Context reads 2 actions\s+success · \d+(ms|s)/);
166
+ assert.match(rendered, /File changes 1 action\s+success · \d+(ms|s)/);
167
+ assert.doesNotMatch(rendered, /\bread\s+success ·/);
168
+ assert.ok(renderCount > 0);
169
+ });
@@ -28,7 +28,8 @@ type RenderedSegment =
28
28
  contentType: "text" | "thinking";
29
29
  component: AssistantMessageComponent;
30
30
  }
31
- | { kind: "tool"; contentIndex: number; component: ToolExecutionComponent };
31
+ | { kind: "tool"; contentIndex: number; component: ToolExecutionComponent }
32
+ | { kind: "tool-summary"; component: ToolPhaseSummaryComponent; phases: ToolExecutionPhase[] };
32
33
 
33
34
  let renderedSegments: RenderedSegment[] = [];
34
35
  // When providers reuse one assistant lifecycle across internal sub-turns,
@@ -124,17 +125,25 @@ function replaceCompactToolRowsWithPhaseSummary(
124
125
  ): void {
125
126
  let changed = false;
126
127
  const nextRenderedSegments: RenderedSegment[] = [];
127
- let rollupRun: Array<{ seg: Extract<RenderedSegment, { kind: "tool" }>; phase: ToolExecutionPhase }> = [];
128
+ let rollupRun: Array<{
129
+ seg: Extract<RenderedSegment, { kind: "tool" | "tool-summary" }>;
130
+ phases: ToolExecutionPhase[];
131
+ }> = [];
128
132
 
129
133
  const flushRollupRun = () => {
130
- if (rollupRun.length < 2) {
134
+ const actionCount = rollupRun.reduce(
135
+ (total, item) => total + item.phases.reduce((sum, phase) => sum + phase.count, 0),
136
+ 0,
137
+ );
138
+ if (actionCount < 2) {
131
139
  nextRenderedSegments.push(...rollupRun.map((item) => item.seg));
132
140
  rollupRun = [];
133
141
  return;
134
142
  }
135
143
 
136
144
  const firstIndex = Math.max(0, host.chatContainer.children.indexOf(rollupRun[0].seg.component));
137
- const summary = new ToolPhaseSummaryComponent(mergeToolPhases(rollupRun.map((item) => item.phase)));
145
+ const phases = mergeToolPhases(rollupRun.flatMap((item) => item.phases));
146
+ const summary = new ToolPhaseSummaryComponent(phases);
138
147
 
139
148
  for (const { seg } of rollupRun) {
140
149
  host.chatContainer.removeChild(seg.component);
@@ -149,13 +158,18 @@ function replaceCompactToolRowsWithPhaseSummary(
149
158
  }
150
159
 
151
160
  changed = true;
161
+ nextRenderedSegments.push({ kind: "tool-summary", component: summary, phases });
152
162
  rollupRun = [];
153
163
  };
154
164
 
155
165
  for (const seg of renderedSegments) {
156
166
  const phase = seg.kind === "tool" ? seg.component.getRollupPhase() : null;
157
167
  if (seg.kind === "tool" && phase) {
158
- rollupRun.push({ seg, phase });
168
+ rollupRun.push({ seg, phases: [phase] });
169
+ continue;
170
+ }
171
+ if (seg.kind === "tool-summary") {
172
+ rollupRun.push({ seg, phases: seg.component.getPhases() });
159
173
  continue;
160
174
  }
161
175
 
@@ -409,6 +423,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
409
423
  details: externalToolResult.details,
410
424
  isError: externalToolResult.isError,
411
425
  });
426
+ replaceCompactToolRowsWithPhaseSummary(host);
412
427
  }
413
428
  }
414
429
 
@@ -843,7 +858,6 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
843
858
  host.streamingComponent.setShowMetadata(true);
844
859
  host.streamingComponent.updateContent(host.streamingMessage);
845
860
  }
846
- replaceCompactToolRowsWithPhaseSummary(host);
847
861
 
848
862
  if (host.streamingMessage.stopReason === "aborted" || host.streamingMessage.stopReason === "error") {
849
863
  if (!errorMessage) {
@@ -862,6 +876,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
862
876
  for (const [, component] of host.pendingTools.entries()) {
863
877
  component.setArgsComplete();
864
878
  }
879
+ replaceCompactToolRowsWithPhaseSummary(host);
865
880
  }
866
881
  host.streamingComponent = undefined;
867
882
  host.streamingMessage = undefined;
@@ -912,7 +927,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
912
927
  const component = host.pendingTools.get(event.toolCallId);
913
928
  if (component) {
914
929
  component.updateResult({ ...event.result, isError: event.isError });
915
- host.pendingTools.delete(event.toolCallId);
930
+ replaceCompactToolRowsWithPhaseSummary(host);
916
931
  host.ui.requestRender();
917
932
  }
918
933
  break;
@@ -1378,6 +1378,9 @@ export class InteractiveMode {
1378
1378
  })();
1379
1379
  },
1380
1380
  getSystemPrompt: () => this.session.systemPrompt,
1381
+ setCompactionThresholdOverride: (percent) => {
1382
+ this.session.settingsManager.setCompactionThresholdOverride(percent);
1383
+ },
1381
1384
  });
1382
1385
 
1383
1386
  // Set up the extension shortcut handler on the default editor
@@ -0,0 +1,14 @@
1
+ import assert from "node:assert/strict";
2
+ import { readFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import test from "node:test";
5
+
6
+ test("MemoryStorage persists sql.js snapshots through the atomic DB snapshot writer", () => {
7
+ const src = readFileSync(
8
+ join(process.cwd(), "packages", "pi-coding-agent", "src", "resources", "extensions", "memory", "storage.ts"),
9
+ "utf-8",
10
+ );
11
+
12
+ assert.match(src, /atomicWriteDbSnapshotSync\(/, "storage must use atomic DB snapshot writes");
13
+ assert.doesNotMatch(src, /writeFileSync\(this\.dbPath/, "direct live DB overwrite is forbidden");
14
+ });
@@ -9,8 +9,9 @@
9
9
 
10
10
  import initSqlJs, { type Database as SqlJsDatabase } from "sql.js";
11
11
  import { randomUUID } from "crypto";
12
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
12
+ import { existsSync, mkdirSync, readFileSync } from "fs";
13
13
  import { dirname } from "path";
14
+ import { atomicWriteDbSnapshotSync } from "../../../core/db-snapshot.js";
14
15
 
15
16
  export interface ThreadRow {
16
17
  thread_id: string;
@@ -74,7 +75,7 @@ export class MemoryStorage {
74
75
 
75
76
  private persist(): void {
76
77
  const data = this.db.export();
77
- writeFileSync(this.dbPath, Buffer.from(data));
78
+ atomicWriteDbSnapshotSync(this.dbPath, data);
78
79
  }
79
80
 
80
81
  private schedulePersist(): void {