fix(#1390): gateway uninstall headless — --yes/--remove-data flags; non-TTY without consent fails loud
ci/woodpecker/pr/ci Pipeline was successful

Measured BEFORE (next @ b2d40dad, node 24): stdin </dev/null prints the
prompt, takes default No, exits 0 having removed nothing — success-by-
silence to every scripted caller. (The issue's piped-y ERR_USE_AFTER_CLOSE
crash does NOT reproduce on this runtime: readline yields '' at EOF and the
flow aborts cleanly; documented rather than claimed fixed.)

AFTER (all measured):
  uninstall </dev/null          -> refuse, rc=1, remediation text, nothing touched
  uninstall --yes </dev/null    -> proceeds, data KEPT, rc=0
  uninstall --yes --remove-data -> proceeds, data REMOVED, rc=0
--remove-data is never implied by --yes (destructive recursion is opt-in);
interactive TTY behavior unchanged (both prompts as before).
This commit is contained in:
2026-08-25 10:07:52 -05:00
parent b2d40dada0
commit d0a17362ec
3 changed files with 148 additions and 15 deletions
+7 -2
View File
@@ -202,9 +202,14 @@ export function registerGatewayCommand(program: Command): void {
gw.command('uninstall')
.description('Uninstall the gateway daemon and optionally remove data')
.action(async () => {
.option(
'-y, --yes',
'Headless: skip the confirmation prompt (required when stdin is not a TTY)',
)
.option('--remove-data', 'Also remove all gateway data (never implied by --yes)')
.action(async (cmdOpts: { yes?: boolean; removeData?: boolean }) => {
const { runUninstall } = await import('./gateway/uninstall.js');
await runUninstall();
await runUninstall(cmdOpts);
});
// ─── doctor ─────────────────────────────────────────────────────────────────