feat(#1298): add hivectl choom verb — interactive claude session in agent container
This commit is contained in:
parent
70832fcbf1
commit
ab65245619
1 changed files with 51 additions and 0 deletions
|
|
@ -15,6 +15,8 @@
|
|||
//! `hive-c0re` lib — single source of truth, no duplication.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::CommandExt as _;
|
||||
|
||||
use anyhow::{Context as _, Result, bail};
|
||||
use clap::{Parser, Subcommand};
|
||||
|
|
@ -69,6 +71,25 @@ enum Cmd {
|
|||
#[command(subcommand)]
|
||||
cmd: AgentsCmd,
|
||||
},
|
||||
/// Open an interactive Claude session inside an agent container.
|
||||
///
|
||||
/// Replaces the current process with `machinectl shell h-<name>`
|
||||
/// running `claude --continue` — drops the operator straight into
|
||||
/// the agent's live Claude session with its full loaded context and
|
||||
/// persona. Requires root (same as all machinectl shell operations)
|
||||
/// and the container must be running.
|
||||
///
|
||||
/// Pass `--fresh` to start a new Claude session instead of continuing
|
||||
/// the most recent one.
|
||||
Choom {
|
||||
/// Agent name (e.g. `damocles`, `iris`).
|
||||
name: String,
|
||||
/// Start a fresh Claude session instead of continuing the most
|
||||
/// recent one. Without this flag `--continue` is passed to Claude
|
||||
/// so the operator joins the agent's ongoing session context.
|
||||
#[arg(long)]
|
||||
fresh: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
|
@ -292,6 +313,7 @@ async fn main() -> Result<()> {
|
|||
AgentsCmd::Restart { name, socket } => agents_restart(&socket, &name).await,
|
||||
AgentsCmd::RestartAll { socket } => agents_restart_all(&socket).await,
|
||||
},
|
||||
Cmd::Choom { name, fresh } => choom(&name, fresh),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -304,6 +326,35 @@ fn is_agent(name: &str) -> bool {
|
|||
Coordinator::agent_state_root(name).exists()
|
||||
}
|
||||
|
||||
/// Drop into an interactive Claude session in the agent container.
|
||||
///
|
||||
/// Replaces the current process (exec) with `machinectl shell h-<name>
|
||||
/// /run/current-system/sw/bin/claude [--continue]`. The `--continue`
|
||||
/// flag is passed by default so the operator joins the agent's active
|
||||
/// session; omit it via `--fresh` to start a blank session instead.
|
||||
///
|
||||
/// `machinectl shell` inherits the caller's PTY, so the session is
|
||||
/// fully interactive. Requires root and a running container.
|
||||
fn choom(name: &str, fresh: bool) -> Result<()> {
|
||||
if !is_agent(name) {
|
||||
bail!(
|
||||
"no such agent: '{name}' (no state dir under /var/lib/hyperhive/agents/)"
|
||||
);
|
||||
}
|
||||
let container = hive_c0re::lifecycle::container_name(name);
|
||||
let claude = "/run/current-system/sw/bin/claude";
|
||||
let mut cmd = std::process::Command::new("machinectl");
|
||||
cmd.arg("shell").arg(&container).arg(claude);
|
||||
if !fresh {
|
||||
cmd.arg("--continue");
|
||||
}
|
||||
// exec() replaces the current process — we inherit stdin/stdout/stderr
|
||||
// (the caller's PTY) so the Claude session is fully interactive.
|
||||
// This call only returns on error.
|
||||
let err = cmd.exec();
|
||||
Err(anyhow::anyhow!("exec machinectl: {err}"))
|
||||
}
|
||||
|
||||
async fn forge_create_user(name: &str, password: Option<&str>, password_stdin: bool) -> Result<()> {
|
||||
if !hive_c0re::forge::is_present().await {
|
||||
bail!(
|
||||
|
|
|
|||
Loading…
Reference in a new issue