fix(desktop): recover the Files tab from listings that fail during a host outage
Problem
Customer report (the "right sidebar is a complete mess" feedback): the Files tab doesn't refresh when switching projects until a manual refresh, folders won't open, files won't open.
The v2 failure mode, reproduced deterministically over CDP: a directory listing that fails during a workspace switch (host-service restarting, relay flap) is never retried, leaving the Files tab permanently empty. The Refresh button can't recover it — doRefresh only re-lists already-loaded directories, and after a failed initial load there are none, so it issues zero requests (confirmed via console logs). A Refresh clicked mid-outage even commits the empty result and wipes a previously loaded tree.
Fix (all in useFilesTabBridge.ts)
- Failed listings retry with bounded exponential backoff (1s→15s, 5 attempts); the root always qualifies, other dirs only while still known and expanded.
doRefreshalways re-lists from the root, so it can bootstrap an empty tree.doRefreshaborts without committing on transport-level failures (isHostServiceConnectionError); typed errors (NOT_FOUND) still drop a genuinely deleted directory.- When the host connection (re)opens, re-fetch the unloaded root and any expanded dirs still awaiting children — covers outages that outlast the backoff window.
Verification
A/B over CDP against the dev app, identical journey (Files tab loaded → hold host-service down 30s via SIGKILL loop → switch workspace mid-outage → let the host respawn):
| tree rows | during outage | host back +25s | Refresh ×2 |
|---|---|---|---|
| before | 0 | 0 — stuck | 0 — no requests sent |
| after | 0 | 45 — self-healed, no clicks | 45 kept during a fresh outage |
Also verified unaffected happy paths still work: workspace switch A→B→A, lazy subfolder expansion, file open, external folder rename while expanded, create-then-rename bursts.
bun test (2706 desktop tests), typecheck, and biome all pass.
Summary by cubic
Recovers the Files tab after host outages by retrying failed directory listings and letting Refresh bootstrap from the root. Previously, a listing failure during a workspace switch left the tab empty; Refresh sent no requests and could commit an empty tree.
Key changes
- Retries failed listings with bounded exponential backoff (1s–15s, max 5). Root always eligible; nested dirs only if still known and expanded.
- Refresh always re-lists from the root and aborts committing on transport-level failures; typed errors (e.g., NOT_FOUND) still remove genuinely deleted dirs.
- On host connection open, re-fetches the unloaded root and any expanded dirs awaiting children.
- Clears per-dir failure counts on success and on workspace switch. All changes are contained in
useFilesTabBridge.ts.
Summary by CodeRabbit
- Bug Fixes
- Improved file and folder loading reliability after temporary connection failures.
- Added automatic retries for failed directory listings, including expanded folders and the workspace root.
- Prevented incomplete file results from appearing when the host connection is unavailable.
- Cleared outdated loading errors after successful refreshes and workspace changes.