Files
chrome-use/cli/src/doctor/daemon.rs
T
Chris Tate 14ece9b3ad feat: add doctor command for diagnosing installs and cleaning stale daemon state (#1254)
* feat: add `doctor` command for install diagnostics and cleanup

Adds `agent-browser doctor`, a one-shot diagnostic that checks
environment, Chrome install, daemon state, config, encryption key,
providers, network reachability, and a live headless launch test.
Auto-cleans stale `.sock` / `.pid` / `.version` / `.stream` sidecar
files on every run. Destructive repairs (reinstall Chrome, purge old
state, close version-mismatched daemons, generate missing encryption
key) are gated behind `--fix`. Supports `--offline`, `--quick`, and
`--json`.

* fixes
2026-04-16 18:20:41 -05:00

71 lines
2.3 KiB
Rust

//! Check running daemons: inventory of sessions, version match with the
//! CLI, and stale sidecar files cleaned up as a side effect of the walk.
use super::{Check, Status};
use crate::connection::{walk_daemons, CleanReason};
pub(super) fn check(checks: &mut Vec<Check>) {
let category = "Daemons";
let cli_version = env!("CARGO_PKG_VERSION");
let inventory = walk_daemons();
for cleaned in &inventory.cleaned {
let reason = match cleaned.reason {
CleanReason::ProcessGone | CleanReason::DashboardGone => "process gone",
CleanReason::UnreadablePidFile => "unreadable pid file",
CleanReason::OrphanedSocket => "orphaned socket",
};
checks.push(Check::new(
format!("daemon.cleaned.{}", cleaned.name),
category,
Status::Warn,
format!("Cleaned stale files: {} ({})", cleaned.name, reason),
));
}
if inventory.sessions.is_empty() {
checks.push(Check::new(
"daemon.active",
category,
Status::Pass,
"No active daemons",
));
} else {
for session in &inventory.sessions {
let version_match = session.version.as_deref() == Some(cli_version);
let status = if version_match {
Status::Pass
} else {
Status::Warn
};
let suffix = if version_match {
String::new()
} else {
format!(" (version mismatch with CLI {})", cli_version)
};
let mut check = Check::new(
format!("daemon.session.{}", session.name),
category,
status,
format!("Session {} (pid {}){}", session.name, session.pid, suffix),
);
if !version_match {
check = check.with_fix(format!("agent-browser --session {} close", session.name));
}
checks.push(check);
}
}
if let Some(dashboard) = inventory.dashboard {
if dashboard.alive {
checks.push(Check::new(
"daemon.dashboard",
category,
Status::Pass,
format!("Dashboard server running (pid {})", dashboard.pid),
));
}
}
}