From 65ba0fc30bba4e30e875d71b9371c185c784c60b Mon Sep 17 00:00:00 2001 From: mastertyko <11311479+mastertyko@users.noreply.github.com> Date: Mon, 13 Apr 2026 14:05:59 +0200 Subject: [PATCH] fix(gsd): preserve paused auto badge after provider pause (#4062) --- src/resources/extensions/gsd/auto.ts | 10 ++++--- .../gsd/tests/auto-paused-ui-cleanup.test.ts | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts diff --git a/src/resources/extensions/gsd/auto.ts b/src/resources/extensions/gsd/auto.ts index 18cad0d22..59b84f362 100644 --- a/src/resources/extensions/gsd/auto.ts +++ b/src/resources/extensions/gsd/auto.ts @@ -677,9 +677,13 @@ function cleanupAfterLoopExit(ctx: ExtensionContext): void { logWarning("session", `lock cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" }); } - ctx.ui.setStatus("gsd-auto", undefined); - ctx.ui.setWidget("gsd-progress", undefined); - ctx.ui.setFooter(undefined); + // A transient provider-error pause intentionally leaves the paused badge + // visible so the user still has a resumable auto-mode signal on screen. + if (!s.paused) { + ctx.ui.setStatus("gsd-auto", undefined); + ctx.ui.setWidget("gsd-progress", undefined); + ctx.ui.setFooter(undefined); + } // Restore CWD out of worktree back to original project root if (s.originalBasePath) { diff --git a/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts b/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts new file mode 100644 index 000000000..9ce54a61e --- /dev/null +++ b/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts @@ -0,0 +1,27 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const autoSource = readFileSync(join(__dirname, "..", "auto.ts"), "utf-8"); + +test("#3370: cleanupAfterLoopExit preserves paused auto badge after provider pause", () => { + const cleanupIdx = autoSource.indexOf("function cleanupAfterLoopExit"); + assert.ok(cleanupIdx > -1, "auto.ts should define cleanupAfterLoopExit"); + + const dispatchIdx = autoSource.indexOf("export async function dispatchHookUnit", cleanupIdx); + assert.ok(dispatchIdx > cleanupIdx, "cleanupAfterLoopExit body should be bounded by the next export"); + + const cleanupBody = autoSource.slice(cleanupIdx, dispatchIdx); + const pausedGuardIdx = cleanupBody.indexOf("if (!s.paused) {"); + const clearStatusIdx = cleanupBody.indexOf('ctx.ui.setStatus("gsd-auto", undefined);'); + + assert.ok(pausedGuardIdx > -1, "loop-exit cleanup must guard UI clearing when auto is paused"); + assert.ok(clearStatusIdx > pausedGuardIdx, "status clearing must live behind the paused guard"); + assert.ok( + autoSource.includes('ctx?.ui.setStatus("gsd-auto", "paused");'), + "pauseAuto must still set the paused badge for transient provider pauses", + ); +});