1006faa6f8
Adds a bounded, read-only health probe per CONFIGURED tool backend, run only when the user explicitly passes `--live` (real network calls): - Firecrawl: credit-usage metadata GET (auth check, no scrape spend) - FAL: models metadata GET (never a generation) - Browser: headless launch + about:blank + close (full cleanup) - MCP: initialize + tools/list per configured server (reuses the `hermes mcp test` machinery in mcp_config._probe_single_server) - TTS/STT: provider models/voices list GET (openai/groq/elevenlabs); local providers (edge/piper/faster-whisper/...) skipped Invariants: - Opt-in only: zero probes without --live (default False) - Bounded: sequential, per-probe timeout (doctor.live_probe_timeout, default 10s, config.yaml knob) - Never mutates state; unconfigured backends skip with a note - Failure isolation: every probe wrapped in a catch-all; a probe crash can never break the doctor run; failures append to the issues summary New: hermes_cli/doctor_live.py, tests/hermes_cli/test_doctor_live.py (23 tests, probes mocked at the HTTP/client seam). Wired: --live flag in subcommands/doctor.py; run_doctor calls maybe_run_live_checks after all static checks. Coordination: PR #70124 (--probe-routes) probes LLM routes; this flag probes TOOL backends — different surface, no code-region collision (the run_doctor hook here sits at the end-of-run summary, not the API Connectivity section #70124 extends). Inspired by: paradigmxyz/centaur tool-health-smoke (MIT/Apache-2.0); sibling: #70124 (LLM route probes — different surface)