feat: automatically update global CLI installations
Merged
MA
2d ago+4067+4067+0123456789012345678901234567890123456789-33-33-01234567890123456789
Why
Keep global CLI installations current without interrupting commands or rewriting package files that a running process still needs.
Summary
- Add background updates for global npm, pnpm, bun, and yarn installs using a stable launcher and verified, versioned packages under
~/.firecrawl/versions/. Package updates require npm on PATH. Switch the active pointer atomically; retain each global installation's current and previous releases plus versions used by live processes. Reclaim inactive releases and abandoned staging directories without interrupting running commands. - Update standalone macOS and Linux binaries through checksum verification and atomic replacement, retaining the previous verified binary.
- Wait at least 24 hours after first observing a release and recheck the registry before unattended installation. Automatic updates stay within the installed major version and exclude prereleases. Bound npm dependency resolution to the release's registry publish time with
--before, and fail safely if publish-time metadata is missing. Preserve network and HTTP error details. - Add
firecrawl update, persistent enable/disable controls, environment and CI opt-outs, a shared user opt-out from any installation, and offlinefirecrawl update --rollback. The stable package launcher runs rollback without loading the active release, including when root options precedeupdate, so a broken release cannot block recovery. Rollback disables automatic updates to prevent immediately reinstalling the release. - Reuse one background worker, locking, retry backoff, local logs, and a one-time terminal notice. Keep command stdout unchanged. Homebrew, system packages, project-local installs, package runners, and standalone Windows binaries retain their existing update mechanism.
- Honor explicit npm reinstalls, including downgrades; reuse saved releases across compatible Node patch upgrades; provide package-manager-specific manual update commands when npm is unavailable.
- Correct the CI action version comment and run package update coverage on Windows alongside binary and package coverage on Linux and macOS.
Test Plan
- Build, type-check, and formatting checks locally.
- Run all 885 regular tests locally.
- Run 51 updater end-to-end checks locally with compiled binaries, real packed npm packages, isolated global installations, and local registry/release servers. Cover background updates, unchanged global files, running old releases, concurrent invocations, verification failures, observation delays, withdrawn releases, opt-outs, major versions, prereleases, rollback, pinned local/npx installs, missing npm, state-write failures, rollback failures, process-safe version cleanup, abandoned staging cleanup, ordinary npm reinstalls, hardlink metadata changes, independent global installations, busy-lock no-op updates, and Node patch compatibility. Additional cases cover time-bounded caret dependencies, registry failure diagnostics, and launcher recovery from an unstartable release with root options and command-like option values. The Windows fixture uses one real global npm install copied into isolated prefixes.
- Install this PR's package as an older version in an isolated global prefix, update against the public npm registry, and verify the original npm launcher selects the downloaded release while the original package remains unchanged. Inject a saved-selection scan permission failure into the real background worker and verify it logs the failure, preserves existing versions, and still completes the update.
- Independently verify a compiled binary updates from the public release server and runs the downloaded version on its next invocation.
- All eight CI checks pass on
ea416d9. Cubic reports 5/5 with zero findings and no open review threads. CI covers 51 updater cases on Linux and macOS and 26 package updater cases on Windows. Required human review remains pending.