refactor(#838): consolidate harness state files into hyperhive-harness.json

This commit is contained in:
damocles 2026-05-31 20:19:56 +02:00
commit fce1f49f6a
7 changed files with 166 additions and 78 deletions

View file

@ -211,24 +211,31 @@ fn read_dashboard_links(name: &str) -> Vec<DashboardLink> {
serde_json::from_str::<Vec<DashboardLink>>(&text).unwrap_or_default()
}
/// Returns true if the agent's harness is currently parked after an API
/// rate-limit response. Detected via the sentinel file written by
/// `hive_ag3nt::events::Bus::emit_status("rate_limited")`.
/// Read `rate_limited` + `needs_login` from the consolidated
/// `hyperhive-harness.json`. Falls back to the legacy individual
/// sentinel files written by older harness builds so in-place upgrades
/// don't lose state during the transition window.
fn read_harness_flags(name: &str) -> (bool, bool) {
let dir = Coordinator::agent_notes_dir(name);
if let Ok(raw) = std::fs::read_to_string(dir.join("hyperhive-harness.json")) {
if let Ok(v) = serde_json::from_str::<serde_json::Value>(&raw) {
let rl = v.get("rate_limited").and_then(|x| x.as_bool()).unwrap_or(false);
let nl = v.get("needs_login").and_then(|x| x.as_bool()).unwrap_or(false);
return (rl, nl);
}
}
// Legacy fallback: presence of individual sentinel files.
let rate_limited = dir.join("hyperhive-rate-limited").exists();
let needs_login = dir.join("hyperhive-needs-login").exists();
(rate_limited, needs_login)
}
fn is_rate_limited(name: &str) -> bool {
Coordinator::agent_notes_dir(name)
.join("hyperhive-rate-limited")
.exists()
read_harness_flags(name).0
}
/// True when the harness wrote `{state_dir}/hyperhive-needs-login`
/// after a 401 mid-turn. Lets the dashboard surface `needs_login` for
/// agents whose `/root/.claude/` dir still exists (so
/// `claude_has_session` returns true) but whose OAuth credentials
/// inside it have actually expired.
fn auth_failed_sentinel(name: &str) -> bool {
Coordinator::agent_notes_dir(name)
.join("hyperhive-needs-login")
.exists()
read_harness_flags(name).1
}
/// Read the agent's free-text status and the Unix timestamp when it was last set