fix: delete command must fail loudly, not silently no-op, without -y in non-TTY mode#7
Conversation
|
CI status update: all jobs ( This is pre-existing and unrelated to this change. Verified by:
This PR's actual change was fully verified locally instead: Leaving this PR open pending a decision on the lockfile/ESLint-config issue (likely worth its own fix) rather than merging with red CI. |
…n-TTY mode Previously, running `firex delete` without --yes in a non-interactive context (e.g. execSync, piped input) exited 0 with no output and no deletion, because the confirmation prompt could not be displayed. This caused a downstream test harness to silently skip cleanup on every run, accumulating stale data and producing hard-to-diagnose false failures. Add a guard at the top of DeleteCommand#run: when stdout is not a TTY and --yes was not passed, print a clear error and exit non-zero instead of proceeding into the no-op confirmation path. The MCP firestore_delete tool already auto-confirms unconditionally and is unaffected by this bug, so it was left unchanged. Fixes #4 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
369005a to
3db1a07
Compare
Summary
execSync, piped stdin — no TTY), runningfirex delete <path> [--recursive]without-y/--yespreviously exited 0 with no output and no deletion, because the confirmation prompt couldn't be displayed and the command silently no-op'd.-y, silently did nothing on every run, and stale data accumulated, producing hard-to-diagnose false failures across multiple debugging sessions.DeleteCommand#runnow checks!skipConfirm && !process.stdout.isTTYup front and fails fast with[ERROR] 非対話実行では -y が必要です(確認プロンプトを表示できません)(exit code 1,validationcategory) instead of proceeding into the no-op confirmation path.src/mcp/tools/delete.ts(MCP tool wrapper): it always auto-confirms (async () => true) regardless of TTY, so it was never affected by this bug and was left unchanged.Test plan
src/commands/delete.test.tscovering: non-TTY + no-y→ exits withoclif.exit === 1and the error message, and never reachesinitialize()(i.e. no deletion path is entered); non-TTY +-y→ proceeds past the guard; TTY + no-y→ proceeds past the guard (existing interactive behavior unaffected).npm run typecheck— passesnpm test— 1042/1042 tests pass (59 files)npm run build— passesnode bin/run.js delete "users/doc1" < /dev/null) — exits 1 with the expected error message and no Firestore call attempted; with-yit proceeds past the guard to the (separate, expected) auth error.npm run lint— could not run: this repo currently has no ESLint config file at all (eslint src --ext .tsfails with "ESLint couldn't find a configuration file"). Verified this is pre-existing and unrelated to this change by stashing my diff and runningnpm run linton a clean checkout ofmaster(d23a3a5) — same failure. This matches the CI history: the last 5 runs of.github/workflows/ci.ymlonmaster(including the0.9.0and0.9.1release commits) all fail at thenpm cistep in every job (lint/typecheck/test/build) withnpm error Invalid: lock file's picomatch@2.3.2 does not satisfy picomatch@4.0.4— a pre-existing lockfile/CI infra issue unrelated to this fix.Fixes #4