From b11bff2b002f4080b68bc3f2ce46c97542570507 Mon Sep 17 00:00:00 2001 From: Sam & Claude Date: Sat, 13 Jun 2026 11:07:58 +0200 Subject: [PATCH] refactor: rename the daemon socket API Herdr* -> Colibri* (Sam & Claude) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The colibri-daemon's own control-plane socket was named after Herdr (the AGPL Linux supervision tool whose protocol shape it borrowed), which made logs/types ("Herdr socket API listening", HerdrCommand/HerdrResponse) look like a Herdr dependency. There is none — no herdr crate, process, or network call. zot is the agent; this is Colibri's control-plane socket. Renamed Colibri's OWN API only: - HerdrCommand -> ColibriCommand, HerdrResponse -> ColibriResponse (daemon defs + socket.rs + colibri-client usages). - log/doc/Cargo strings: "Herdr socket API"/"operator dashboard"/"Herdr Unix socket" -> "Colibri control-plane socket" (daemon, clawdie). Wire-compatible: the JSON `cmd` values come from #[serde(rename=...)] and are unchanged. Kept legitimate references to Herdr *the tool* (glasspane lineage "reimplements Herdr's glasspane capability", "Herdr's 5-state model"; client "display clients (Herdr on Linux…)"; tui "herdr-like"). build + test + clippy -D warnings + fmt --check clean; runtime confirms the daemon now logs "Colibri control-plane socket listening". Co-Authored-By: Claude Opus 4.8 --- crates/clawdie/Cargo.toml | 4 +- crates/clawdie/src/main.rs | 6 +- crates/colibri-client/src/lib.rs | 30 +++--- crates/colibri-daemon/Cargo.toml | 2 +- crates/colibri-daemon/src/config.rs | 2 +- crates/colibri-daemon/src/lib.rs | 12 +-- crates/colibri-daemon/src/main.rs | 4 +- crates/colibri-daemon/src/socket.rs | 160 ++++++++++++++-------------- 8 files changed, 111 insertions(+), 109 deletions(-) diff --git a/crates/clawdie/Cargo.toml b/crates/clawdie/Cargo.toml index fc00a1a..4218225 100644 --- a/crates/clawdie/Cargo.toml +++ b/crates/clawdie/Cargo.toml @@ -3,7 +3,7 @@ name = "clawdie" version = "0.0.1" edition = "2021" license = "AGPL-3.0-only" -description = "Clawdie — the simplified, operator-friendly Colibri agent (glasspane + herdr + DeepSeek/Telegram) as one small binary" +description = "Clawdie — the simplified, operator-friendly Colibri agent (glasspane + supervision + DeepSeek/Telegram) as one small binary" [[bin]] name = "clawdie" @@ -11,7 +11,7 @@ path = "src/main.rs" [dependencies] # Reuse the proven control-plane core: glasspane (supervision radar), -# the Herdr Unix-socket API, the coordination loop, and session lifecycle. +# the Colibri control-plane socket, the coordination loop, and session lifecycle. colibri-daemon = { path = "../colibri-daemon" } colibri-glasspane = { path = "../colibri-glasspane" } tokio = { version = "1", features = ["full"] } diff --git a/crates/clawdie/src/main.rs b/crates/clawdie/src/main.rs index 2d764a1..1ae268f 100644 --- a/crates/clawdie/src/main.rs +++ b/crates/clawdie/src/main.rs @@ -1,7 +1,7 @@ //! clawdie — the simplified, operator-friendly Colibri agent. //! //! One small binary, two credentials, zero ceremony. It bundles the proven -//! control-plane core (glasspane supervision radar + the Herdr Unix-socket API + +//! control-plane core (glasspane supervision radar + the Colibri control-plane socket + //! the coordination loop — the "split brain") and puts a DeepSeek-backed //! Telegram bot in front of it. That is the entire out-of-the-box surface. //! @@ -70,7 +70,7 @@ async fn main() -> Result<(), Box> { "credentials resolved (build flags + runtime env)" ); - // ── Bring up the control-plane core (glasspane + Herdr socket + loop) ──── + // ── Bring up the control-plane core (glasspane + control-plane socket + loop) ──── let config = DaemonConfig::from_env(); info!( host = %config.host, @@ -103,7 +103,7 @@ async fn main() -> Result<(), Box> { } } - // Herdr Unix-socket API. + // Colibri control-plane socket. let socket_state = state.clone(); let socket_shutdown = state.shutdown_rx.resubscribe(); let socket_handle = tokio::spawn(async move { diff --git a/crates/colibri-client/src/lib.rs b/crates/colibri-client/src/lib.rs index ac51869..9bd5da5 100644 --- a/crates/colibri-client/src/lib.rs +++ b/crates/colibri-client/src/lib.rs @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf}; -use colibri_daemon::{HerdrCommand, HerdrResponse}; +use colibri_daemon::{ColibriCommand, ColibriResponse}; use colibri_glasspane::GlasspaneSnapshot; use serde::de::DeserializeOwned; use thiserror::Error; @@ -48,7 +48,7 @@ impl DaemonClient { } /// Send one command and parse the daemon's generic response envelope. - pub async fn send(&self, command: &HerdrCommand) -> Result { + pub async fn send(&self, command: &ColibriCommand) -> Result { let stream = UnixStream::connect(&self.socket_path).await?; let (reader, mut writer) = stream.into_split(); let mut reader = BufReader::new(reader); @@ -70,7 +70,7 @@ impl DaemonClient { /// Send one command and deserialize its `data` payload to a typed value. pub async fn request( &self, - command: &HerdrCommand, + command: &ColibriCommand, ) -> Result { let response = self.send(command).await?; if !response.ok { @@ -85,15 +85,15 @@ impl DaemonClient { } pub async fn status(&self) -> Result { - self.request(&HerdrCommand::Status).await + self.request(&ColibriCommand::Status).await } pub async fn glasspane_snapshot(&self) -> Result { - self.request(&HerdrCommand::GlasspaneSnapshot).await + self.request(&ColibriCommand::GlasspaneSnapshot).await } pub async fn list_sessions(&self) -> Result { - self.request(&HerdrCommand::ListSessions).await + self.request(&ColibriCommand::ListSessions).await } pub async fn spawn_agent( @@ -103,7 +103,7 @@ impl DaemonClient { session_id: Option, system_prompt: Option, ) -> Result { - self.request(&HerdrCommand::SpawnAgent { + self.request(&ColibriCommand::SpawnAgent { provider: provider.into(), model: model.into(), session_id, @@ -117,7 +117,7 @@ impl DaemonClient { &self, agent_id: impl Into, ) -> Result { - self.request(&HerdrCommand::KillAgent { + self.request(&ColibriCommand::KillAgent { agent_id: agent_id.into(), }) .await @@ -127,7 +127,7 @@ impl DaemonClient { &self, session_id: impl Into, ) -> Result { - self.request(&HerdrCommand::GetSession { + self.request(&ColibriCommand::GetSession { session_id: session_id.into(), }) .await @@ -137,7 +137,7 @@ impl DaemonClient { &self, session_id: impl Into, ) -> Result { - self.request(&HerdrCommand::CompactSession { + self.request(&ColibriCommand::CompactSession { session_id: session_id.into(), }) .await @@ -147,7 +147,7 @@ impl DaemonClient { &self, status: Option, ) -> Result { - self.request(&HerdrCommand::ListTasks { status }).await + self.request(&ColibriCommand::ListTasks { status }).await } pub async fn create_task( @@ -155,7 +155,7 @@ impl DaemonClient { title: impl Into, description: Option, ) -> Result { - self.request(&HerdrCommand::CreateTask { + self.request(&ColibriCommand::CreateTask { title: title.into(), description, }) @@ -168,7 +168,7 @@ impl DaemonClient { description: Option, capabilities: Vec, ) -> Result { - self.request(&HerdrCommand::IntakeTask { + self.request(&ColibriCommand::IntakeTask { title: title.into(), description, capabilities: Some(capabilities), @@ -177,7 +177,7 @@ impl DaemonClient { } pub async fn list_skills(&self) -> Result { - self.request(&HerdrCommand::ListSkills).await + self.request(&ColibriCommand::ListSkills).await } pub async fn register_skill( @@ -186,7 +186,7 @@ impl DaemonClient { description: Option, category: Option, ) -> Result { - self.request(&HerdrCommand::RegisterSkill { + self.request(&ColibriCommand::RegisterSkill { name: name.into(), description, category, diff --git a/crates/colibri-daemon/Cargo.toml b/crates/colibri-daemon/Cargo.toml index e0984d7..8106fdd 100644 --- a/crates/colibri-daemon/Cargo.toml +++ b/crates/colibri-daemon/Cargo.toml @@ -3,7 +3,7 @@ name = "colibri-daemon" version = "0.0.1" edition = "2021" license = "AGPL-3.0-only" -description = "Always-on Rust service: agent session lifecycle, subprocess spawner, Herdr Unix socket API" +description = "Always-on Rust service: agent session lifecycle, subprocess spawner, Colibri control-plane socket API" [dependencies] colibri-contracts = { path = "../colibri-contracts" } diff --git a/crates/colibri-daemon/src/config.rs b/crates/colibri-daemon/src/config.rs index 4c12515..68ac75c 100644 --- a/crates/colibri-daemon/src/config.rs +++ b/crates/colibri-daemon/src/config.rs @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize}; pub struct DaemonConfig { /// Directory for session JSONL files and state. pub data_dir: PathBuf, - /// Path for the Herdr Unix socket. + /// Path for the Colibri control-plane socket. pub socket_path: PathBuf, /// Maximum bytes per session before automatic rollover. pub session_max_bytes: u64, diff --git a/crates/colibri-daemon/src/lib.rs b/crates/colibri-daemon/src/lib.rs index f185b80..ba90870 100644 --- a/crates/colibri-daemon/src/lib.rs +++ b/crates/colibri-daemon/src/lib.rs @@ -4,7 +4,7 @@ //! Core responsibilities: //! - Session lifecycle (JSONL write/read/prune + context-window management) //! - Agent subprocess spawner (provider/model config, retry/backoff) -//! - Unix socket API for Herdr operator dashboard +//! - Unix socket API for the Colibri control plane //! - Provider routing: DeepSeek primary, OpenRouter/Anthropic fallback //! - DeepSeek cache discipline: immutable system prefix + appendable log + //! volatile scratch (the 3-region prompt model) @@ -27,10 +27,10 @@ use serde::{Deserialize, Serialize}; // Wire types for the socket API // --------------------------------------------------------------------------- -/// Inbound command from Herdr over the Unix socket. +/// Inbound command over the Colibri control-plane socket. #[derive(Debug, Serialize, Deserialize)] #[serde(tag = "cmd")] -pub enum HerdrCommand { +pub enum ColibriCommand { #[serde(rename = "status")] Status, #[serde(rename = "glasspane-snapshot")] @@ -91,9 +91,9 @@ pub enum HerdrCommand { SetCostMode { mode: String }, } -/// Outbound response to Herdr. +/// Outbound control-plane response. #[derive(Debug, Serialize, Deserialize)] -pub struct HerdrResponse { +pub struct ColibriResponse { pub ok: bool, #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, @@ -101,7 +101,7 @@ pub struct HerdrResponse { pub data: Option, } -impl HerdrResponse { +impl ColibriResponse { pub fn ok(data: serde_json::Value) -> Self { Self { ok: true, diff --git a/crates/colibri-daemon/src/main.rs b/crates/colibri-daemon/src/main.rs index 7b7fbb0..cf04c66 100644 --- a/crates/colibri-daemon/src/main.rs +++ b/crates/colibri-daemon/src/main.rs @@ -3,7 +3,7 @@ //! Starts: //! - Session manager (JSONL persistence + context window management) //! - Agent spawner (subprocess lifecycle + provider routing) -//! - Herdr Unix socket API +//! - Colibri control-plane socket API //! //! Graceful shutdown on SIGTERM/SIGINT (or Ctrl+C). @@ -68,7 +68,7 @@ async fn main() -> Result<(), Box> { } } - // Start the Herdr socket server + // Start the Colibri control-plane socket server let socket_state = state.clone(); let socket_shutdown = state.shutdown_rx.resubscribe(); let socket_handle = tokio::spawn(async move { diff --git a/crates/colibri-daemon/src/socket.rs b/crates/colibri-daemon/src/socket.rs index e760461..aad18c3 100644 --- a/crates/colibri-daemon/src/socket.rs +++ b/crates/colibri-daemon/src/socket.rs @@ -1,4 +1,4 @@ -//! Unix socket API for Herdr operator dashboard. +//! Unix socket API for the Colibri control plane (operator CLI/TUI). //! //! Listens on a Unix domain socket, accepts newline-delimited JSON commands, //! and dispatches to the session manager and agent spawner. @@ -20,13 +20,13 @@ use tokio::sync::broadcast; use tracing::{debug, error, info, trace, warn}; use crate::spawner::{AgentSpawnConfig, Provider, Spawner}; -use crate::{HerdrCommand, HerdrResponse, SharedState}; +use crate::{ColibriCommand, ColibriResponse, SharedState}; // --------------------------------------------------------------------------- // Socket server // --------------------------------------------------------------------------- -/// Run the Herdr socket API server. Binds to the configured Unix socket path +/// Run the Colibri control-plane socket server. Binds to the configured Unix socket path /// and processes inbound commands until a shutdown signal is received. pub async fn serve(state: SharedState, mut shutdown_rx: broadcast::Receiver<()>) { let socket_path = state.config.socket_path.clone(); @@ -86,7 +86,7 @@ pub async fn serve(state: SharedState, mut shutdown_rx: broadcast::Receiver<()>) } } - info!(path = %socket_path.display(), "Herdr socket API listening"); + info!(path = %socket_path.display(), "Colibri control-plane socket listening"); loop { select! { @@ -110,7 +110,7 @@ pub async fn serve(state: SharedState, mut shutdown_rx: broadcast::Receiver<()>) // Clean up socket file on graceful exit let _ = tokio::fs::remove_file(&socket_path).await; - info!("Herdr socket API shut down"); + info!("Colibri control-plane socket shut down"); } // --------------------------------------------------------------------------- @@ -136,9 +136,9 @@ async fn handle_connection(stream: UnixStream, state: SharedState) { continue; } - let response = match serde_json::from_str::(trimmed) { + let response = match serde_json::from_str::(trimmed) { Ok(cmd) => dispatch(cmd, &state).await, - Err(e) => HerdrResponse::err(format!("invalid command: {e}")), + Err(e) => ColibriResponse::err(format!("invalid command: {e}")), }; let mut response_json = serde_json::to_string(&response).unwrap_or_default(); @@ -161,12 +161,12 @@ async fn handle_connection(stream: UnixStream, state: SharedState) { // Command dispatch // --------------------------------------------------------------------------- -async fn dispatch(cmd: HerdrCommand, state: &SharedState) -> HerdrResponse { +async fn dispatch(cmd: ColibriCommand, state: &SharedState) -> ColibriResponse { match cmd { - HerdrCommand::Status => cmd_status(state).await, - HerdrCommand::GlasspaneSnapshot => cmd_glasspane_snapshot(state).await, - HerdrCommand::ListSessions => cmd_list_sessions(state).await, - HerdrCommand::SpawnAgent { + ColibriCommand::Status => cmd_status(state).await, + ColibriCommand::GlasspaneSnapshot => cmd_glasspane_snapshot(state).await, + ColibriCommand::ListSessions => cmd_list_sessions(state).await, + ColibriCommand::SpawnAgent { provider, model, session_id, @@ -183,40 +183,42 @@ async fn dispatch(cmd: HerdrCommand, state: &SharedState) -> HerdrResponse { ) .await } - HerdrCommand::KillAgent { agent_id } => cmd_kill_agent(state, agent_id).await, - HerdrCommand::GetSession { session_id } => cmd_get_session(state, session_id).await, - HerdrCommand::CompactSession { session_id } => cmd_compact_session(state, session_id).await, + ColibriCommand::KillAgent { agent_id } => cmd_kill_agent(state, agent_id).await, + ColibriCommand::GetSession { session_id } => cmd_get_session(state, session_id).await, + ColibriCommand::CompactSession { session_id } => { + cmd_compact_session(state, session_id).await + } // ── Coordination board ──────────────────────────────── - HerdrCommand::ListTasks { status } => cmd_list_tasks(state, status).await, - HerdrCommand::CreateTask { title, description } => { + ColibriCommand::ListTasks { status } => cmd_list_tasks(state, status).await, + ColibriCommand::CreateTask { title, description } => { cmd_create_task(state, title, description).await } - HerdrCommand::TransitionTask { task_id, status } => { + ColibriCommand::TransitionTask { task_id, status } => { cmd_transition_task(state, task_id, status).await } - HerdrCommand::ClaimTask { task_id, agent_id } => { + ColibriCommand::ClaimTask { task_id, agent_id } => { cmd_claim_task(state, task_id, agent_id).await } - HerdrCommand::ListAgents => cmd_list_agents(state).await, - HerdrCommand::RegisterAgent { name, capabilities } => { + ColibriCommand::ListAgents => cmd_list_agents(state).await, + ColibriCommand::RegisterAgent { name, capabilities } => { cmd_register_agent(state, name, capabilities).await } - HerdrCommand::ListSkills => cmd_list_skills(state).await, - HerdrCommand::RegisterSkill { + ColibriCommand::ListSkills => cmd_list_skills(state).await, + ColibriCommand::RegisterSkill { name, description, category, } => cmd_register_skill(state, name, description, category).await, - HerdrCommand::IntakeTask { + ColibriCommand::IntakeTask { title, description, capabilities, } => cmd_intake_task(state, title, description, capabilities).await, - HerdrCommand::SetCostMode { mode } => cmd_set_cost_mode(state, mode).await, + ColibriCommand::SetCostMode { mode } => cmd_set_cost_mode(state, mode).await, } } -async fn cmd_status(state: &SharedState) -> HerdrResponse { +async fn cmd_status(state: &SharedState) -> ColibriResponse { let session_count = state.sessions.len(); let agent_count = state.agents.len(); let pane_count = state @@ -261,7 +263,7 @@ async fn cmd_status(state: &SharedState) -> HerdrResponse { let last_warm_hit = *state.last_warm_cache_hit.read().await; let last_warm_tokens = *state.last_warm_hit_tokens.read().await; - HerdrResponse::ok(serde_json::json!({ + ColibriResponse::ok(serde_json::json!({ "daemon": "colibri-daemon", "version": env!("CARGO_PKG_VERSION"), "host": state.config.host, @@ -293,19 +295,19 @@ async fn cmd_status(state: &SharedState) -> HerdrResponse { })) } -async fn cmd_glasspane_snapshot(state: &SharedState) -> HerdrResponse { +async fn cmd_glasspane_snapshot(state: &SharedState) -> ColibriResponse { let snapshot = state.glasspane.read().await.snapshot_at( state.config.host.clone(), SystemTime::now(), DEFAULT_STALL_AFTER, ); match serde_json::to_value(snapshot) { - Ok(value) => HerdrResponse::ok(value), - Err(e) => HerdrResponse::err(format!("snapshot serialization failed: {e}")), + Ok(value) => ColibriResponse::ok(value), + Err(e) => ColibriResponse::err(format!("snapshot serialization failed: {e}")), } } -async fn cmd_list_sessions(state: &SharedState) -> HerdrResponse { +async fn cmd_list_sessions(state: &SharedState) -> ColibriResponse { let mut sessions = Vec::new(); for entry in state.sessions.iter() { let session = entry.value(); @@ -317,7 +319,7 @@ async fn cmd_list_sessions(state: &SharedState) -> HerdrResponse { })); } - HerdrResponse::ok(serde_json::json!({ + ColibriResponse::ok(serde_json::json!({ "sessions": sessions, })) } @@ -329,13 +331,13 @@ async fn cmd_spawn_agent( session_id: Option, system_prompt: Option, local_args: Option>, -) -> HerdrResponse { +) -> ColibriResponse { let provider = match provider_str.to_lowercase().as_str() { "deepseek" => Provider::DeepSeek, "openrouter" => Provider::OpenRouter, "anthropic" => Provider::Anthropic, "local" => Provider::Local, - other => return HerdrResponse::err(format!("unknown provider: {other}")), + other => return ColibriResponse::err(format!("unknown provider: {other}")), }; let (binary, args) = if provider == Provider::Local { @@ -424,16 +426,16 @@ async fn cmd_spawn_agent( }); } - HerdrResponse::ok(serde_json::json!({ + ColibriResponse::ok(serde_json::json!({ "agent_id": id, "status": "running", })) } - Err(e) => HerdrResponse::err(format!("spawn failed: {e}")), + Err(e) => ColibriResponse::err(format!("spawn failed: {e}")), } } -async fn cmd_kill_agent(state: &SharedState, agent_id: String) -> HerdrResponse { +async fn cmd_kill_agent(state: &SharedState, agent_id: String) -> ColibriResponse { match state.agents.remove(&agent_id) { Some((_id, handle)) => match handle.kill().await { Ok(()) => { @@ -442,24 +444,24 @@ async fn cmd_kill_agent(state: &SharedState, agent_id: String) -> HerdrResponse r#"{"type":"error"}"#, SystemTime::now(), ); - HerdrResponse::ok(serde_json::json!({ + ColibriResponse::ok(serde_json::json!({ "agent_id": agent_id, "status": "stopped", })) } - Err(e) => HerdrResponse::err(format!("kill failed: {e}")), + Err(e) => ColibriResponse::err(format!("kill failed: {e}")), }, - None => HerdrResponse::err(format!("agent not found: {agent_id}")), + None => ColibriResponse::err(format!("agent not found: {agent_id}")), } } -async fn cmd_get_session(state: &SharedState, session_id: String) -> HerdrResponse { +async fn cmd_get_session(state: &SharedState, session_id: String) -> ColibriResponse { match state.sessions.get(&session_id) { Some(session) => { let turns = session.value().turns().await; let messages = session.value().build_prompt_messages().await; - HerdrResponse::ok(serde_json::json!({ + ColibriResponse::ok(serde_json::json!({ "session_id": session_id, "turn_count": turns.len(), "byte_count": session.value().byte_count().await, @@ -468,7 +470,7 @@ async fn cmd_get_session(state: &SharedState, session_id: String) -> HerdrRespon "prompt_messages": messages, })) } - None => HerdrResponse::err(format!("session not found: {session_id}")), + None => ColibriResponse::err(format!("session not found: {session_id}")), } } @@ -512,27 +514,27 @@ async fn stream_agent_stdout_to_glasspane( } } -async fn cmd_compact_session(state: &SharedState, session_id: String) -> HerdrResponse { +async fn cmd_compact_session(state: &SharedState, session_id: String) -> ColibriResponse { match state.sessions.get(&session_id) { Some(session) => match session.value().compact_oldest_turns().await { - Ok(()) => HerdrResponse::ok(serde_json::json!({ + Ok(()) => ColibriResponse::ok(serde_json::json!({ "session_id": session_id, "turn_count": session.value().turn_count().await, "status": "compacted", })), - Err(e) => HerdrResponse::err(format!("compaction failed: {e}")), + Err(e) => ColibriResponse::err(format!("compaction failed: {e}")), }, - None => HerdrResponse::err(format!("session not found: {session_id}")), + None => ColibriResponse::err(format!("session not found: {session_id}")), } } // ── Coordination board handlers ────────────────────────────────── -async fn cmd_list_tasks(state: &SharedState, status: Option) -> HerdrResponse { +async fn cmd_list_tasks(state: &SharedState, status: Option) -> ColibriResponse { let filter = status.and_then(|s| colibri_store::TaskStatus::parse_status(&s)); match state.store.lock().unwrap().list_tasks(filter) { - Ok(tasks) => HerdrResponse::ok(serde_json::to_value(tasks).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("list tasks failed: {e}")), + Ok(tasks) => ColibriResponse::ok(serde_json::to_value(tasks).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("list tasks failed: {e}")), } } @@ -540,15 +542,15 @@ async fn cmd_create_task( state: &SharedState, title: String, description: Option, -) -> HerdrResponse { +) -> ColibriResponse { match state .store .lock() .unwrap() .create_task(&title, description.as_deref()) { - Ok(task) => HerdrResponse::ok(serde_json::to_value(task).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("create task failed: {e}")), + Ok(task) => ColibriResponse::ok(serde_json::to_value(task).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("create task failed: {e}")), } } @@ -556,10 +558,10 @@ async fn cmd_transition_task( state: &SharedState, task_id: String, status: String, -) -> HerdrResponse { +) -> ColibriResponse { let new_status = match colibri_store::TaskStatus::parse_status(&status) { Some(s) => s, - None => return HerdrResponse::err(format!("invalid status: {status}")), + None => return ColibriResponse::err(format!("invalid status: {status}")), }; match state .store @@ -567,22 +569,22 @@ async fn cmd_transition_task( .unwrap() .transition_task(&task_id, new_status) { - Ok(task) => HerdrResponse::ok(serde_json::to_value(task).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("transition task failed: {e}")), + Ok(task) => ColibriResponse::ok(serde_json::to_value(task).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("transition task failed: {e}")), } } -async fn cmd_claim_task(state: &SharedState, task_id: String, agent_id: String) -> HerdrResponse { +async fn cmd_claim_task(state: &SharedState, task_id: String, agent_id: String) -> ColibriResponse { match state.store.lock().unwrap().claim_task(&task_id, &agent_id) { - Ok(task) => HerdrResponse::ok(serde_json::to_value(task).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("claim task failed: {e}")), + Ok(task) => ColibriResponse::ok(serde_json::to_value(task).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("claim task failed: {e}")), } } -async fn cmd_list_agents(state: &SharedState) -> HerdrResponse { +async fn cmd_list_agents(state: &SharedState) -> ColibriResponse { match state.store.lock().unwrap().list_agents() { - Ok(agents) => HerdrResponse::ok(serde_json::to_value(agents).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("list agents failed: {e}")), + Ok(agents) => ColibriResponse::ok(serde_json::to_value(agents).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("list agents failed: {e}")), } } @@ -590,18 +592,18 @@ async fn cmd_register_agent( state: &SharedState, name: String, capabilities: Option, -) -> HerdrResponse { +) -> ColibriResponse { let caps = capabilities.unwrap_or(serde_json::json!([])); match state.store.lock().unwrap().register_agent(&name, caps) { - Ok(agent) => HerdrResponse::ok(serde_json::to_value(agent).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("register agent failed: {e}")), + Ok(agent) => ColibriResponse::ok(serde_json::to_value(agent).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("register agent failed: {e}")), } } -async fn cmd_list_skills(state: &SharedState) -> HerdrResponse { +async fn cmd_list_skills(state: &SharedState) -> ColibriResponse { match state.store.lock().unwrap().list_skills() { - Ok(skills) => HerdrResponse::ok(serde_json::to_value(skills).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("list skills failed: {e}")), + Ok(skills) => ColibriResponse::ok(serde_json::to_value(skills).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("list skills failed: {e}")), } } @@ -610,14 +612,14 @@ async fn cmd_register_skill( name: String, description: Option, category: Option, -) -> HerdrResponse { +) -> ColibriResponse { match state.store.lock().unwrap().register_skill( &name, description.as_deref(), category.as_deref(), ) { - Ok(skill) => HerdrResponse::ok(serde_json::to_value(skill).unwrap_or_default()), - Err(e) => HerdrResponse::err(format!("register skill failed: {e}")), + Ok(skill) => ColibriResponse::ok(serde_json::to_value(skill).unwrap_or_default()), + Err(e) => ColibriResponse::err(format!("register skill failed: {e}")), } } @@ -626,7 +628,7 @@ async fn cmd_intake_task( title: String, description: Option, capabilities: Option>, -) -> HerdrResponse { +) -> ColibriResponse { let caps = capabilities.unwrap_or_default(); let mut scheduler = state.scheduler.lock().await; scheduler.submit(crate::scheduler::TaskRequest { @@ -634,10 +636,10 @@ async fn cmd_intake_task( description, required_capabilities: caps, }); - HerdrResponse::ok(serde_json::json!({"status": "queued"})) + ColibriResponse::ok(serde_json::json!({"status": "queued"})) } -async fn cmd_set_cost_mode(state: &SharedState, mode: String) -> HerdrResponse { +async fn cmd_set_cost_mode(state: &SharedState, mode: String) -> ColibriResponse { match crate::cost::CostMode::parse(&mode) { Some(cost_mode) => { info!( @@ -650,13 +652,13 @@ async fn cmd_set_cost_mode(state: &SharedState, mode: String) -> HerdrResponse { // For now, we acknowledge and log the request. // T1.4 scope: runtime-only. Persistence (COLIBRI_COST_MODE in // config/socket-update) is post-Phase-5. - HerdrResponse::ok(serde_json::json!({ + ColibriResponse::ok(serde_json::json!({ "previous": state.config.cost_mode, "requested": cost_mode.as_str(), "status": "acknowledged", })) } - None => HerdrResponse::err(format!( + None => ColibriResponse::err(format!( "invalid cost mode: {mode}. Use fast, smart, or max." )), } @@ -700,8 +702,8 @@ mod tests { #[test] fn glasspane_snapshot_command_deserializes() { - let cmd: HerdrCommand = serde_json::from_str(r#"{"cmd":"glasspane-snapshot"}"#).unwrap(); - assert!(matches!(cmd, HerdrCommand::GlasspaneSnapshot)); + let cmd: ColibriCommand = serde_json::from_str(r#"{"cmd":"glasspane-snapshot"}"#).unwrap(); + assert!(matches!(cmd, ColibriCommand::GlasspaneSnapshot)); } #[tokio::test]