refactor(#1292): remove agent-owned fields from ContainerView

Now that the dashboard fetches agent-owned state directly from
GET /api/dashboard-state (via gateway), hive-c0re no longer needs
to read those fields from disk on the agent's behalf.

Removed from ContainerView:
  ctx_tokens, context_window_tokens, rate_limited,
  extra_links, status_text, status_set_at

Removed from container_view.rs:
  DashboardLink struct, build_nav_links, read_dashboard_links,
  read_status, is_rate_limited, read_last_turn, resolve_ctx_window
  (and the resolve_ctx_window unit tests)

Removed from dashboard.rs:
  GET /api/agent/{name}/links route + get_agent_links handler

dashboard JS (tabs.js):
  Merged rate_limited, ctx-window badge, and status-text rendering
  into the async dashboard-state fetch block. c0re still provides
  needs_login (auth sentinel on host), needs_update, pending_reminders,
  running, deployed_sha, parent — all genuinely host-side fields.
This commit is contained in:
iris 2026-06-04 19:39:06 +02:00
commit e0ea22f3ee
3 changed files with 76 additions and 361 deletions

View file

@ -72,7 +72,6 @@ pub async fn serve(port: u16, coord: Arc<Coordinator>) -> Result<()> {
.route("/api/build-logs/id/{id}", get(get_build_log_full))
.route("/api/build-logs/id/{id}/stream", get(get_build_log_stream))
.route("/api/build-logs/id/{id}/raw", get(get_build_log_raw))
.route("/api/agent/{name}/links", get(get_agent_links))
.route("/api/agent/{name}/mark-all-read", post(post_mark_all_read))
.route("/cancel-reminder/{id}", post(post_cancel_reminder))
.route("/retry-reminder/{id}", post(post_retry_reminder))
@ -2123,28 +2122,6 @@ async fn post_schedule_cancel(
}
}
/// Same-origin proxy that fetches the named agent's
/// `GET /api/state` and forwards only the `links` field to the
/// dashboard JS. Lets the agent backend stay the
/// single source of truth for its own nav links: the dashboard
/// card's icon-only strip and the per-agent page's labelled row
/// render the same list, no shared Rust wire type required, no
/// CORS surface on the agent side.
///
/// Failure modes (agent down, slow response, malformed JSON) all
/// degrade to an empty list so the dashboard still renders.
async fn get_agent_links(AxumPath(name): AxumPath<String>) -> Response {
// Format-only guard. Unknown/malformed names get an empty list.
if validate_agent_name(&name).is_some() {
return axum::Json(serde_json::json!([])).into_response();
}
// Links are built from disk — no TCP call to the agent web UI.
// The old TCP proxy broke when all agents switched to unix-socket
// binding (HIVE_WEB_SOCKET). See container_view::build_nav_links
// for the full rationale.
axum::Json(container_view::build_nav_links(&name)).into_response()
}
async fn post_cancel_reminder(
State(state): State<AppState>,
AxumPath(id): AxumPath<i64>,