fix(cli): keep first-run commands from hanging or faking success without a terminal

ER
12h ago
+170-158

Three first-run fixes for people and agents running the CLI without a terminal. This builds on #338, which makes the login prompt fail when stdin ends; until #338 merges, this diff also shows its two files.

Bare firecrawl without a terminal

With no API key, firecrawl with no arguments opened the onboarding auth picker even when stdin was not a terminal. The picker could not read input, printed Error: User force closed the prompt with 0 null, and the process exited 0. Agents that probe firecrawl saw a false success and no usage. Without a terminal, it now prints the banner and help, as it already does for an authenticated user. Interactive terminals keep the picker.

One shared prompt

setup.ts and launch.ts each had their own copy of the readline prompt that the login flow used, with the same problem: when the input closed (Ctrl+D) the promise never settled and the process exited 0 mid-question. The prompt from #338 moves to src/utils/prompt.ts and all three callers use it. A closed input now rejects with a caller-specific message (setup defaults points at --agent/--yes, launch at passing the app name), and Ctrl+C exits 130.

Skills before login in init -y/--all

The documented agent setup line, npx -y firecrawl-cli@latest init --all --browser, ran authentication first. Browser login waits up to five minutes for the user, so an agent whose shell command times out sooner never reached the skills step. Non-interactive init now installs the CLI and the skills first and authenticates last, and the step numbers follow that order. The interactive wizard is unchanged.

Before and after, with an empty HOME and no FIRECRAWL_API_KEY:

$ firecrawl </dev/null; echo $?
# before: auth picker, "User force closed the prompt", 0
# after:  banner and help, 0

$ firecrawl init --all --skip-install </dev/null
# before: [1/2] Authenticating... (blocks or fails first)
# after:  [1/2] Installing firecrawl skills... then [2/2] Authenticating with Firecrawl...

Bumps the version to 1.26.16, on top of the 1.26.15 that https://github.com/firecrawl/cli/pull/336 shipped.

Testing

  • New test in src/__tests__/commands/init.test.ts: in non-interactive init, the skills install runs before login, and a failed login still exits 1. It fails without the reorder.
  • src/__tests__/utils/auth.test.ts covers the shared prompt through the login flow.
  • pnpm test, pnpm type-check, pnpm format:check, pnpm build. I also ran the two commands above by hand on the built CLI.

Open in Capy


Summary by cubic

Fixes first-run CLI commands hanging or falsely succeeding when run without a terminal.

  • Bare firecrawl with no API key skips the interactive auth picker when stdin isn't a TTY and prints the banner and help instead.
  • Login prompts now share one prompt utility that rejects when stdin ends, so commands exit non-zero with messages pointing at the flags that skip the prompt (Ctrl+C exits 130). One shared piped-stdin reader lets a single pipe answer successive prompts.
  • Non-interactive init now installs the CLI and skills before authenticating, so an auth timeout can't prevent the skills step.

Found by Wildfire, Firecrawl's integration testing: these first-run hangs surfaced while reproducing the failing cli-setup-mcp check.