SIGN IN SIGN UP

fix(mcp): read an empty agent config as empty, and gate writes on a complete scan

#632's file is a 0-byte `~/.gemini/config/mcp_config.json` — Antigravity
touches it into existence before it ever writes a server. serde reports
`EOF while parsing a value at line 1 column 0`, so isolating the source
leaves that agent permanently invisible AND unwritable: every writer starts
by reading the file it is about to change, so nothing can put content into
it again. Treat empty and whitespace-only as "nothing configured", the rule
the Hermes reader already applied to its own config.

Two sources could still fail without the scan noticing, which would make the
fail-closed half of the isolation a no-op:

- `read_hermes_servers` swallowed I/O errors and invalid YAML into an empty
  map, so Hermes went silently absent instead of reporting a failure.
- Every JSON reader plus the Codex and Grok TOML readers gated on
  `Path::exists()`, which is false for ANY failed stat — a permission wall
  or a symlink loop read as "not configured". `read_config_to_string` makes
  the read itself the test and carries the path into the error detail.

Replace the scan-mode flag with an explicit write guard. `scan_local_servers`
returns `LocalMcpScan { servers, warnings }` and no longer fails, while
`mcp_upsert_local_server` and `mcp_set_server_apps` call
`require_complete_scan` before their first write — the strict
`find_local_server` on the upsert path ran after the writes, reporting
failure on a save that had already landed in fourteen configs.

Surface the warnings instead of only logging them: the settings page names
the agent whose config could not be read and why, and disables Save and
Create while any source is degraded, so a draft seeded from a partial scan
cannot be submitted after an out-of-band repair.

Closes #632
X
xintaofei committed
bf71cddeeb1ec56551134cc0baa488b439225862
Parent: e55da24