refactor(#2352): extract standalone hivectl crate, hive-c0re daemon-only
This commit is contained in:
parent
cce35c20e6
commit
cc67a05974
13 changed files with 236 additions and 147 deletions
|
|
@ -1,9 +1,8 @@
|
|||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
use anyhow::{Context as _, Result};
|
||||
use clap::{Parser, Subcommand};
|
||||
use hive_host_sock::{HostRequest, HostResponse};
|
||||
|
||||
// Every module hangs off the `hive_c0re` library (see `src/lib.rs`).
|
||||
// The daemon and the `hivectl` sibling binary share the same module
|
||||
|
|
@ -12,7 +11,7 @@ use hive_host_sock::{HostRequest, HostResponse};
|
|||
// explicit (any new daemon entry point reads off the next add).
|
||||
use hive_c0re::coordinator::{Coordinator, HiveEnv, ServeConfig};
|
||||
use hive_c0re::{
|
||||
agent_sockets, auto_update, broker, client, crash_watch, dashboard, dashboard_events, forge,
|
||||
agent_sockets, auto_update, broker, crash_watch, dashboard, dashboard_events, forge,
|
||||
host_stats, job_queue, knowledge, matrix, mcp_sockets, migrate, reminder_scheduler,
|
||||
scheduled_prompts_worker, server, socket_server, sweep_health, warnings,
|
||||
};
|
||||
|
|
@ -91,52 +90,6 @@ enum Cmd {
|
|||
#[arg(long)]
|
||||
build_slots: Option<usize>,
|
||||
},
|
||||
/// Spawn a new agent container directly (`hive-agent-<name>`). Bypasses
|
||||
/// the approval queue — use only as an operator on the host. For
|
||||
/// approval-gated spawns, use `request-spawn` instead.
|
||||
Spawn { name: String },
|
||||
/// Queue a spawn request as an approval. The container is created on
|
||||
/// `approve <id>` (CLI) or the dashboard's APPR0VE button.
|
||||
RequestSpawn { name: String },
|
||||
/// Stop a managed container (graceful).
|
||||
Kill { name: String },
|
||||
/// Tear down a sub-agent container. Container is removed; persistent
|
||||
/// state (config repos + Claude credentials) is kept by default. Pass
|
||||
/// `--purge` to also wipe the agent's state dirs (config + creds +
|
||||
/// notes). No undo.
|
||||
Destroy {
|
||||
name: String,
|
||||
#[arg(long)]
|
||||
purge: bool,
|
||||
},
|
||||
/// Apply pending config to a managed container.
|
||||
Rebuild { name: String },
|
||||
/// List managed containers.
|
||||
List,
|
||||
/// List pending approval requests submitted by the manager.
|
||||
Pending,
|
||||
/// Approve a pending request by id; the action runs immediately.
|
||||
Approve { id: i64 },
|
||||
/// Deny a pending request by id.
|
||||
Deny { id: i64 },
|
||||
/// Move an agent in the topology tree. Set `--parent` to a new
|
||||
/// parent agent name; pass `--root` to promote the agent to root
|
||||
/// (no parent). Refuses cycles and unknown agents. The manager
|
||||
/// is reparentable like any other agent — its privileges come
|
||||
/// from the privileged MCP socket, not its tree position.
|
||||
SetParent {
|
||||
child: String,
|
||||
/// New parent agent name. Mutually exclusive with `--root`.
|
||||
/// Exactly one of `--parent` / `--root` is required — clap
|
||||
/// rejects both-absent calls so a fat-fingered
|
||||
/// `hive-c0re set-parent alice` doesn't silently promote
|
||||
/// alice to root.
|
||||
#[arg(long, conflicts_with = "root", required_unless_present = "root")]
|
||||
parent: Option<String>,
|
||||
/// Promote `child` to root (no parent).
|
||||
#[arg(long)]
|
||||
root: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
@ -206,37 +159,6 @@ async fn main() -> Result<()> {
|
|||
}
|
||||
cmd_serve(sc.env, sc.model_prices, sc.build_slots, db, &cli.socket).await
|
||||
}
|
||||
Cmd::Spawn { name } => {
|
||||
render(client::request(&cli.socket, HostRequest::Spawn { name }).await?)
|
||||
}
|
||||
Cmd::RequestSpawn { name } => {
|
||||
render(client::request(&cli.socket, HostRequest::RequestSpawn { name }).await?)
|
||||
}
|
||||
Cmd::Kill { name } => {
|
||||
render(client::request(&cli.socket, HostRequest::Kill { name }).await?)
|
||||
}
|
||||
Cmd::Destroy { name, purge } => {
|
||||
render(client::request(&cli.socket, HostRequest::Destroy { name, purge }).await?)
|
||||
}
|
||||
Cmd::Rebuild { name } => {
|
||||
render(client::request(&cli.socket, HostRequest::Rebuild { name }).await?)
|
||||
}
|
||||
Cmd::List => render(client::request(&cli.socket, HostRequest::List).await?),
|
||||
Cmd::Pending => render(client::request(&cli.socket, HostRequest::Pending).await?),
|
||||
Cmd::Approve { id } => {
|
||||
render(client::request(&cli.socket, HostRequest::Approve { id }).await?)
|
||||
}
|
||||
Cmd::Deny { id } => render(client::request(&cli.socket, HostRequest::Deny { id }).await?),
|
||||
Cmd::SetParent {
|
||||
child,
|
||||
parent,
|
||||
root,
|
||||
} => {
|
||||
let new_parent = if root { None } else { parent };
|
||||
render(
|
||||
client::request(&cli.socket, HostRequest::SetParent { child, new_parent }).await?,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -648,11 +570,3 @@ fn spawn_broker_to_dashboard_forwarder(coord: Arc<Coordinator>) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn render(resp: HostResponse) -> Result<()> {
|
||||
println!("{}", serde_json::to_string_pretty(&resp)?);
|
||||
if !resp.ok {
|
||||
bail!(resp.error.unwrap_or_else(|| "request failed".to_owned()));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue