From 93d547c65e654cc134accb627af44cd2c0cda461 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Tue, 12 May 2026 17:28:09 +0200 Subject: [PATCH] =?UTF-8?q?fix(headless):=20skip=20Ask=E2=86=92Build=20mod?= =?UTF-8?q?e=20gate=20in=20SF=5FHEADLESS=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In headless mode the showConfirm dialog blocks forever since there is no TUI to answer it. The user already consented by calling /next or /autonomous explicitly — the gate adds no value and hangs the run. Add process.env.SF_HEADLESS !== '1' to the gate condition so headless runs bypass it and proceed directly to autonomous execution. Verified: `sf headless --command next` now completes slice S03 (719 526 tokens, 10 tool calls, $0.027) without hanging. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/resources/extensions/sf/auto.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/resources/extensions/sf/auto.js b/src/resources/extensions/sf/auto.js index d23393337..dad4bdc99 100644 --- a/src/resources/extensions/sf/auto.js +++ b/src/resources/extensions/sf/auto.js @@ -1470,10 +1470,13 @@ export async function startAuto(ctx, pi, base, verboseMode, options) { // Skip if workMode is already "build" — runControl is reset to "manual" on // autonomous stop but workMode persists, so this avoids a spurious prompt // for users who stay in Build mode between autonomous runs. + // Skip in headless mode — the user already consented by calling /next or + // /autonomous explicitly; showing a TUI confirm dialog would block forever. if ( s.runControl === "manual" && s.workMode !== "build" && - !options?.skipModeGate + !options?.skipModeGate && + process.env.SF_HEADLESS !== "1" ) { const confirmed = await showConfirm(ctx, { title: "Switch to Build mode?",