The agent reports a rich capability payload (sudo mode, runtime
managers, detected runtimes, allowed paths, systemd JSON support)
that the panel was discarding once the WebSocket disconnected. The
Overview tab also gave no visibility into what the agent had
discovered, which left users guessing why a feature tab was missing
or a Docker call returned empty.
Backend:
- Server model gains seven nullable columns: cached_capabilities,
cached_runtimes, cached_runtime_managers, cached_allowed_paths,
cached_sudo, cached_systemd_json, capabilities_at. Migration 005
is idempotent (checks existing columns before adding) so it's safe
on already-bootstrapped databases.
- agent_registry.update_capabilities() now persists a snapshot to the
Server row whenever the agent reports state. Wrapped in try/except
so a DB hiccup doesn't drop the in-memory update.
- /servers/<id> falls back to the cached snapshot when the agent is
offline and exposes capabilities_stale + capabilities_at so the UI
can badge stale data.
Frontend:
- New SystemStatusCard renders sudo mode, package manager, runtime
managers, detected runtime versions, capability map (as colored
chips), and file-access roots. "Stale" badge + relative timestamp
+ Refresh button (calls agent:recapabilities).
- DockerTab now distinguishes "agent online but no docker daemon"
from "no containers found", with concrete remediation hints. Load
errors surface as a banner instead of being swallowed to console.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>