fix(tui): stopped async tool spinner ticks
Excluded running async result snapshots from live partial spinner intervals so finalized background tool rows do not repaint scrollback. Added regression coverage for async bash snapshots staying static.
This commit is contained in:
@@ -551,14 +551,13 @@ export class ToolExecutionComponent extends Container implements NativeScrollbac
|
||||
*/
|
||||
#updateSpinnerAnimation(): void {
|
||||
// Live partial tool blocks stay repaintable until a terminal result seals
|
||||
// them. Todo snapshots and detached background task progress are deliberate
|
||||
// them. Todo snapshots and detached background tool progress are deliberate
|
||||
// static exceptions because their rows can be superseded or committed to
|
||||
// scrollback while later updates continue elsewhere.
|
||||
const isStreamingArgs = !this.#argsComplete && (isEditLikeToolName(this.#toolName) || this.#toolName === "write");
|
||||
const isBackgroundAsyncRunning =
|
||||
(this.#result?.details as { async?: { state?: string } } | undefined)?.async?.state === "running";
|
||||
const isBackgroundAsyncTask = this.#toolName === "task" && isBackgroundAsyncRunning;
|
||||
const isLivePartialTool = this.#isPartial && this.#toolName !== "todo" && !isBackgroundAsyncTask;
|
||||
const isLivePartialTool = this.#isPartial && this.#toolName !== "todo" && !isBackgroundAsyncRunning;
|
||||
const needsSpinner = isStreamingArgs || isLivePartialTool || this.#displaceableByToolName === "job";
|
||||
if (needsSpinner && !this.#spinnerInterval) {
|
||||
const frameCount = theme.spinnerFrames.length;
|
||||
|
||||
@@ -69,4 +69,35 @@ describe("ToolExecutionComponent live preview spinners", () => {
|
||||
component.stopAnimation();
|
||||
}
|
||||
});
|
||||
|
||||
it("does not tick detached async bash result snapshots", () => {
|
||||
vi.useFakeTimers();
|
||||
const requestRender = vi.fn();
|
||||
const component = new ToolExecutionComponent(
|
||||
"bash",
|
||||
{ command: "sleep 600", async: true },
|
||||
{},
|
||||
undefined,
|
||||
{ requestRender } as unknown as TUI,
|
||||
process.cwd(),
|
||||
);
|
||||
|
||||
try {
|
||||
component.updateResult(
|
||||
{
|
||||
content: [{ type: "text", text: "started background job" }],
|
||||
details: {
|
||||
command: "sleep 600",
|
||||
async: { state: "running", jobId: "job-1", type: "bash" },
|
||||
},
|
||||
},
|
||||
true,
|
||||
);
|
||||
requestRender.mockClear();
|
||||
vi.advanceTimersByTime(500);
|
||||
expect(requestRender).not.toHaveBeenCalled();
|
||||
} finally {
|
||||
component.stopAnimation();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user