From 2b4e78d9ab92020aa2ccfb5ec7adcef652a3996a Mon Sep 17 00:00:00 2001 From: Derek Pearson Date: Sat, 21 Mar 2026 13:41:22 -0400 Subject: [PATCH] fix: preserve explicit interrupted-session resume mode Pass paused step-mode metadata through guided resume actions and tighten source coverage around stale paused-session handling so the interrupted-session flow matches the selected resume mode. --- src/resources/extensions/gsd/guided-flow.ts | 5 ++++- .../gsd/tests/interrupted-session-auto.test.ts | 11 +++++++++++ .../gsd/tests/interrupted-session-ui.test.ts | 5 +++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/resources/extensions/gsd/guided-flow.ts b/src/resources/extensions/gsd/guided-flow.ts index 4e1ccb4ec..f8019ec30 100644 --- a/src/resources/extensions/gsd/guided-flow.ts +++ b/src/resources/extensions/gsd/guided-flow.ts @@ -894,7 +894,10 @@ export async function showSmartEntry( ], }); if (resume === "resume") { - await startAuto(ctx, pi, basePath, false, { interrupted }); + await startAuto(ctx, pi, basePath, false, { + interrupted, + step: interrupted.pausedSession?.stepMode ?? false, + }); return; } } diff --git a/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts b/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts index dd0c54f69..f81cb6266 100644 --- a/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +++ b/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts @@ -128,6 +128,17 @@ test("direct /gsd auto stale paused-session metadata is treated as stale when no } }); +test("direct /gsd auto source only resumes paused-session metadata for recoverable state with real recovery signals", async () => { + const source = await import(`node:fs/promises`).then((fs) => + fs.readFile(new URL("../auto.ts", import.meta.url), "utf-8") + ); + assert.ok(source.includes('freshStartAssessment.classification === "recoverable"')); + assert.ok(source.includes('freshStartAssessment.hasResumableDiskState')); + assert.ok(source.includes('|| !!freshStartAssessment.recoveryPrompt')); + assert.ok(source.includes('|| !!freshStartAssessment.lock')); + assert.ok(!source.includes('freshStartAssessment.classification === "recoverable"\n || freshStartAssessment.hasResumableDiskState')); +}); + test("auto module imports successfully after interrupted-session changes", async () => { const mod = await import(`../auto.ts?ts=${Date.now()}-${Math.random()}`); assert.equal(typeof mod.startAuto, "function"); diff --git a/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts b/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts index df0f820e4..9ff1e8c1d 100644 --- a/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +++ b/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts @@ -137,12 +137,13 @@ test("guided-flow stale paused-session scenario is suppressed when no resumable } }); -test("guided-flow source uses step-aware resume label and shared assessment", () => { +test("guided-flow source uses step-aware resume label and passes step mode into startAuto", () => { const source = readFileSync(join(import.meta.dirname, "..", "guided-flow.ts"), "utf-8"); assert.ok(source.includes('const interrupted = await assessInterruptedSession(basePath);')); assert.ok(source.includes('if (interrupted.classification === "running")')); assert.ok(source.includes('if (interrupted.classification === "stale")')); assert.ok(source.includes('resumeLabel = interrupted.pausedSession?.stepMode')); assert.ok(source.includes('"Resume with /gsd next"')); - assert.ok(source.includes('await startAuto(ctx, pi, basePath, false, { interrupted });')); + assert.ok(source.includes('step: interrupted.pausedSession?.stepMode ?? false')); + assert.ok(!source.includes('await startAuto(ctx, pi, basePath, false, { interrupted });')); });