fix(gsd): clear stale pendingAutoStart after /clear interrupts discussion

When the pending auto-start guard fires, check if the discussion is
actually still in progress by verifying the discussion manifest or
milestone context exists on disk. If neither exists, the entry is stale
from an interrupted session — clear it and allow re-entry.

Fixes #3274

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tibsfox 2026-04-06 18:27:45 -07:00
parent b4c6229360
commit af2bd4d45f

View file

@ -1143,8 +1143,21 @@ export async function showSmartEntry(
// Without this guard, every subsequent /gsd call overwrites the pending auto-start
// and fires another dispatchWorkflow, resetting the conversation mid-interview.
if (pendingAutoStartMap.has(basePath)) {
ctx.ui.notify("Discussion already in progress — answer the question above to continue.", "info");
return;
// #3274: If /clear interrupted the discussion, the pending entry is stale.
// Detect this by checking if the discussion manifest still exists — it's
// only present while a discuss flow is actively in progress.
const manifestExists = existsSync(join(gsdRoot(basePath), "DISCUSSION-MANIFEST.json"));
const entry = pendingAutoStartMap.get(basePath)!;
const milestoneHasContext = existsSync(
join(gsdRoot(basePath), "milestones", entry.milestoneId, `${entry.milestoneId}-CONTEXT.md`),
);
if (!manifestExists && !milestoneHasContext) {
// Stale entry from an interrupted discussion — clear and continue
pendingAutoStartMap.delete(basePath);
} else {
ctx.ui.notify("Discussion already in progress — answer the question above to continue.", "info");
return;
}
}
const milestoneIds = findMilestoneIds(basePath);