confirm() at src/lib/events.ts:26-35 reads from stdin via readline. It is used by three mutating commands:
src/commands/rsvp.ts:153
src/commands/blasts.ts:84 (send blast)
src/commands/events.ts:580 (cancel event)
Each is correctly gated by if (!globalOpts['yes'] && !globalOpts['force']), but there is no process.stdin.isTTY check. In a non-interactive context the readline promise never resolves, so the process hangs indefinitely rather than failing.
AGENTS.md already documents this as a known trap: "events cancel and blasts send prompt for confirmation before executing. Pass -y or --yes to skip in automated/agent flows." An agent that misses that line doesn't get an error it can recover from — it gets a hang, which is much harder to diagnose and can silently consume a whole session.
src/commands/auth.ts:167 (SMS code prompt) has the same shape.
Fix
Fail closed. When process.stdin.isTTY is falsy and neither --yes nor --force was passed:
- exit with
EXIT.VALIDATION_ERROR (3)
- emit the standard error envelope with an actionable hint, e.g.
"pass -y/--yes to confirm in non-interactive contexts"
Never auto-approve on a non-TTY — these are destructive operations (cancel event, send blast to all guests).
This is probably the single highest-value agent-reliability fix in the repo: it converts a silent hang into a typed, self-explaining error.
confirm()atsrc/lib/events.ts:26-35reads from stdin via readline. It is used by three mutating commands:src/commands/rsvp.ts:153src/commands/blasts.ts:84(send blast)src/commands/events.ts:580(cancel event)Each is correctly gated by
if (!globalOpts['yes'] && !globalOpts['force']), but there is noprocess.stdin.isTTYcheck. In a non-interactive context the readline promise never resolves, so the process hangs indefinitely rather than failing.AGENTS.mdalready documents this as a known trap: "events cancelandblasts sendprompt for confirmation before executing. Pass-yor--yesto skip in automated/agent flows." An agent that misses that line doesn't get an error it can recover from — it gets a hang, which is much harder to diagnose and can silently consume a whole session.src/commands/auth.ts:167(SMS code prompt) has the same shape.Fix
Fail closed. When
process.stdin.isTTYis falsy and neither--yesnor--forcewas passed:EXIT.VALIDATION_ERROR(3)"pass -y/--yes to confirm in non-interactive contexts"Never auto-approve on a non-TTY — these are destructive operations (cancel event, send blast to all guests).
This is probably the single highest-value agent-reliability fix in the repo: it converts a silent hang into a typed, self-explaining error.