diff --git a/frontend/packages/dashboard/src/common.css b/frontend/packages/dashboard/src/common.css index 8ae53ae8..1ddd0858 100644 --- a/frontend/packages/dashboard/src/common.css +++ b/frontend/packages/dashboard/src/common.css @@ -81,12 +81,6 @@ code { color: var(--purple); border-color: var(--purple); text-shadow: 0 0 6px color-mix(in srgb, var(--purple) 40%, transparent); } -/* Paused agent: turn loop parked, container still up. Clickable (btn-inline): - clicking sends POST /api/resume/{name} so the badge doubles as a resume button. */ -.badge-paused { - color: var(--yellow); border-color: var(--yellow); - background: color-mix(in srgb, var(--yellow) 10%, transparent); -} /* Active Claude model badge on dashboard container rows. */ .badge-model { color: var(--blue); border-color: var(--blue); diff --git a/frontend/packages/dashboard/src/swarm.js b/frontend/packages/dashboard/src/swarm.js index 11e72478..88a9875a 100644 --- a/frontend/packages/dashboard/src/swarm.js +++ b/frontend/packages/dashboard/src/swarm.js @@ -307,19 +307,7 @@ function buildAgentMenu(c, forgeBase) { menuItem('▶ ST4RT', { action: '/api/start/', confirm: `start ${c.name}?` }), ); } - // Pause/resume is orthogonal to running: a paused stopped agent boots - // paused; a paused running agent keeps its container but drives no turns. - if (c.paused) { - dropdown.append( - menuItem('▶ R3SUM3', { action: '/api/resume/', confirm: `resume ${c.name}? the turn loop restarts and drains queued messages.` }), - ); - } else { - dropdown.append( - menuItem('⏸ P4US3', { action: '/api/pause/', confirm: `pause ${c.name}? parks the turn loop — inbox messages queue unacked.` }), - ); - } dropdown.append( - menuSep(), menuItem('↻ R3BU1LD', { action: '/api/rebuild/', confirm: `rebuild ${c.name}? hot-reloads the container.` }), menuSep(), // Deep-link to the AGENT log tab pre-filtered to this container. @@ -469,7 +457,6 @@ function containerRowFingerprint(c, node, pending, opRunning, selected, askerCount, targetCount, gatewayLinks, hostname) { return JSON.stringify({ running: c.running, - paused: c.paused, needs_login: c.needs_login, needs_update: c.needs_update, active_model: c.active_model, @@ -670,15 +657,6 @@ function buildContainerLi(c, node, opts) { { class: 'badge badge-warn', href: url, target: '_blank', rel: 'noopener' }, 'needs login →')); } - if (c.paused) { - // Paused badge is also a resume button: clicking POSTs /api/resume/{name} - // which removes the marker and flips the badge off via the SSE rescan. - head.append(form( - '/api/resume/' + c.name, 'badge badge-paused btn-inline', '⏸ paused', - `resume ${c.name}? the turn loop restarts and drains queued messages.`, - {}, { noRefresh: true }, - )); - } if (c.needs_update) { head.append(form( '/api/rebuild/' + c.name, 'badge badge-warn btn-inline', 'needs update ↻', diff --git a/hive-c0re/src/dashboard/lifecycle_ops.rs b/hive-c0re/src/dashboard/lifecycle_ops.rs index 70d4acbf..4f2bdb9f 100644 --- a/hive-c0re/src/dashboard/lifecycle_ops.rs +++ b/hive-c0re/src/dashboard/lifecycle_ops.rs @@ -25,7 +25,7 @@ pub(super) struct GracefulParams { graceful: bool, } -use super::{AppState, Ident, error_response, guard_agent_name, strip_container_prefix}; +use super::{AppState, error_response, guard_agent_name, strip_container_prefix}; use crate::job_queue::{Source, submit}; use crate::{actions, lifecycle}; @@ -137,56 +137,6 @@ pub(super) async fn post_start( (StatusCode::OK, "ok").into_response() } -/// `POST /api/pause/{name}` — write the pause marker for `name`. -/// -/// Unlike the lifecycle ops above this is not a DAG: it writes a single -/// marker file, which the harness stats at the top of its serve loop. -/// Works on stopped containers too (the marker is sticky and takes effect -/// when the container next boots). Triggers an immediate rescan so the -/// `paused` badge flips on the dashboard without waiting for the next -/// periodic sweep. -pub(super) async fn post_pause( - State(state): State, - AxumPath(name): AxumPath, -) -> Response { - let logical = strip_container_prefix(&name); - if let Some(reject) = guard_agent_name(&state, &logical).await { - return reject; - } - let ident = match Ident::parse(&logical) { - Ok(i) => i, - Err(e) => return (StatusCode::BAD_REQUEST, format!("bad agent name: {e}")).into_response(), - }; - if let Err(e) = crate::coordinator::Coordinator::set_paused(&ident, true) { - return error_response(&format!("pause {logical}: {e}")); - } - state.coord.rescan_containers_and_emit().await; - (StatusCode::OK, "ok").into_response() -} - -/// `POST /api/resume/{name}` — remove the pause marker for `name`. -/// -/// The inverse of `post_pause`. Removing a non-existent marker is a no-op -/// (idempotent). Triggers an immediate rescan so the paused badge clears. -pub(super) async fn post_resume( - State(state): State, - AxumPath(name): AxumPath, -) -> Response { - let logical = strip_container_prefix(&name); - if let Some(reject) = guard_agent_name(&state, &logical).await { - return reject; - } - let ident = match Ident::parse(&logical) { - Ok(i) => i, - Err(e) => return (StatusCode::BAD_REQUEST, format!("bad agent name: {e}")).into_response(), - }; - if let Err(e) = crate::coordinator::Coordinator::set_paused(&ident, false) { - return error_response(&format!("resume {logical}: {e}")); - } - state.coord.rescan_containers_and_emit().await; - (StatusCode::OK, "ok").into_response() -} - pub(super) async fn post_update_all(State(state): State) -> Response { let containers = lifecycle::list().await.unwrap_or_default(); for container in containers { diff --git a/hive-c0re/src/dashboard/mod.rs b/hive-c0re/src/dashboard/mod.rs index cdb35f55..7334a7d5 100644 --- a/hive-c0re/src/dashboard/mod.rs +++ b/hive-c0re/src/dashboard/mod.rs @@ -193,8 +193,6 @@ pub async fn serve( .route("/api/restart/{name}", post(lifecycle_ops::post_restart)) .route("/api/start/{name}", post(lifecycle_ops::post_start)) .route("/api/rebuild/{name}", post(lifecycle_ops::post_rebuild)) - .route("/api/pause/{name}", post(lifecycle_ops::post_pause)) - .route("/api/resume/{name}", post(lifecycle_ops::post_resume)) .route("/api/update-all", post(lifecycle_ops::post_update_all)) .route( "/api/infra-container/{name}/{action}",