diff --git a/src/resources/extensions/gsd/guided-flow.ts b/src/resources/extensions/gsd/guided-flow.ts index 62fcd0d5e..750906401 100644 --- a/src/resources/extensions/gsd/guided-flow.ts +++ b/src/resources/extensions/gsd/guided-flow.ts @@ -792,17 +792,28 @@ export async function showSmartEntry( const crashLock = readCrashLock(basePath); if (crashLock) { clearLock(basePath); - const resume = await showNextAction(ctx, { - title: "GSD — Interrupted Session Detected", - summary: [formatCrashInfo(crashLock)], - actions: [ - { id: "resume", label: "Resume with /gsd auto", description: "Pick up where it left off", recommended: true }, - { id: "continue", label: "Continue manually", description: "Open the wizard as normal" }, - ], - }); - if (resume === "resume") { - await startAuto(ctx, pi, basePath, false); - return; + + // Bootstrap crash with zero completed units = no work was lost. + // Auto-discard instead of prompting the user — this commonly happens + // when the user exits during init wizard or discuss phase before any + // real auto-mode work begins. + const isBootstrapCrash = crashLock.unitType === "starting" + && crashLock.unitId === "bootstrap" + && crashLock.completedUnits === 0; + + if (!isBootstrapCrash) { + const resume = await showNextAction(ctx, { + title: "GSD — Interrupted Session Detected", + summary: [formatCrashInfo(crashLock)], + actions: [ + { id: "resume", label: "Resume with /gsd auto", description: "Pick up where it left off", recommended: true }, + { id: "continue", label: "Continue manually", description: "Open the wizard as normal" }, + ], + }); + if (resume === "resume") { + await startAuto(ctx, pi, basePath, false); + return; + } } } diff --git a/src/resources/extensions/gsd/session-lock.ts b/src/resources/extensions/gsd/session-lock.ts index 1541d9172..0f0ca227b 100644 --- a/src/resources/extensions/gsd/session-lock.ts +++ b/src/resources/extensions/gsd/session-lock.ts @@ -122,6 +122,12 @@ function ensureExitHandler(gsdDir: string): void { try { if (_releaseFunction) { _releaseFunction(); _releaseFunction = null; } } catch { /* best-effort */ } + // Remove the auto.lock metadata file so crash-recovery doesn't + // falsely detect an interrupted session on the next startup. + try { + const lockFile = join(gsdDir, LOCK_FILE); + if (existsSync(lockFile)) unlinkSync(lockFile); + } catch { /* best-effort */ } try { const lockDir = join(gsdDir + ".lock"); if (existsSync(lockDir)) rmSync(lockDir, { recursive: true, force: true });