fix(file): handle a failed background file scan instead of leaving it unhandled

RA
1d ago
+279-49

Issue for this PR

Closes #1467

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Instance startup starts a file scan in the background that nothing awaits. Without ripgrep on PATH, the scan downloads ripgrep first. If the download or extraction failed, the rejection was unhandled, and bun failed a run whose tests had passed (main at 5bfb23191).

  • The background scan's failure is caught and logged as a warning, with its details (download URL and status, or tar's stderr).
  • A failed ripgrep lookup is retried at most once every 30 seconds. It used to be cached, so every later search in the process failed. Inside the cooldown the last failure is re-reported, so an offline machine does not download on every search. An unsupported platform is not retried.
  • Ripgrep is unpacked in a staging directory, and the binary is renamed into place only once complete. A failed extraction used to leave a partial rg that the next lookup accepted. The staging directory is always removed, as in the core package's installer.
  • A failed scan no longer sticks in files(), so the next call scans again.

Two subprocess fixtures in test/altimate/file-scan/ run with ripgrep absent and its download replaced. One covers the unhandled rejection, the cooldown (counting downloads) and recovery. The other serves an archive cut off halfway, then checks that nothing is left behind and that the retry installs a working binary. Both are skipped on Windows.

How did you verify your code works?

  • Both fixtures pass. Removing any one change makes one of them fail: the catch, the cooldown, the lookup reset, the finally, the staging cleanup, or the staging itself.
  • Related suites pass: 205 tests across file, the grep/glob/lsp/read tools, skill and file-scan. tsgo passes.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

šŸ¤– Generated with Claude Code

https://claude.ai/code/session_0174HUYiaceApqHP7EKMNgnb


Summary by cubic

Fixes unhandled background file scan failures that made bun test runs fail after their tests passed; closes #1467.

  • Logs the background scan failure as a warning, including its NamedError data; files() still scans again and returns its own failure to its caller.
  • Failed lookups and scans are no longer kept: Ripgrep.filepath() resets its cached lookup on failure, and files() clears a finished scan whether it succeeded or failed, so later searches retry and recover once ripgrep is available.
  • Adds a regression test that runs a child bun test without ripgrep available, verifying the run exits 0 and a later search recovers once ripgrep becomes available.

Summary by CodeRabbit

  • Bug Fixes
    • File searches can recover after a temporary startup scan or search-tool download failure, rather than remaining stuck with a failed attempt.
    • Interrupted downloads are cleaned up before a retry, reducing the chance of leaving an incomplete search tool in place.
    • Startup scans continue when a background scan encounters an error, and awaited file searches still report scan failures when they occur.
    • Retry behavior gives transient failures time to clear while continuing to report unsupported-platform errors.