use std::io::Write;
use anyhow::{Result, anyhow};
use clap::Subcommand;
use crate::mcp::BasemindServer;
use crate::mcp::params::*;
use super::render::emit;
use super::run_tool;
#[derive(Subcommand, Debug)]
pub enum ShellsCmd {
Spawn {
command: String,
#[arg(long)]
cwd: Option<String>,
#[arg(long = "env", value_name = "KEY=VALUE")]
env: Vec<String>,
#[arg(long)]
title: Option<String>,
},
Send {
session_id: String,
text: String,
#[arg(long)]
no_enter: bool,
},
Capture {
session_id: String,
#[arg(long)]
lines: Option<usize>,
},
Kill {
session_id: String,
},
Broadcast {
text: String,
#[arg(long = "session", value_name = "SESSION_ID", required = true)]
session_ids: Vec<String>,
#[arg(long)]
no_enter: bool,
},
List,
}
fn parse_env(raw: &str) -> Result<ShellEnv> {
let (key, value) = raw
.split_once('=')
.ok_or_else(|| anyhow!("invalid --env {raw:?}: expected KEY=VALUE"))?;
Ok(ShellEnv {
key: key.to_string(),
value: value.to_string(),
})
}
pub async fn run(
server: &BasemindServer,
cmd: ShellsCmd,
json: bool,
out: &mut impl Write,
) -> Result<()> {
match cmd {
ShellsCmd::Spawn {
command,
cwd,
env,
title,
} => {
let env = if env.is_empty() {
None
} else {
Some(env.iter().map(|e| parse_env(e)).collect::<Result<_>>()?)
};
let p = ShellSpawnParams {
command,
cwd: cwd.map(|c| c.as_str().into()),
env,
title,
};
let r = run_tool("shell_spawn", server.shell_spawn(Parameters(p)).await)?;
emit("shell_spawn", &r, json, out)
}
ShellsCmd::Send {
session_id,
text,
no_enter,
} => {
let p = ShellSendParams {
session_id,
text,
enter: !no_enter,
};
let r = run_tool("shell_send", server.shell_send(Parameters(p)).await)?;
emit("shell_send", &r, json, out)
}
ShellsCmd::Capture { session_id, lines } => {
let p = ShellCaptureParams { session_id, lines };
let r = run_tool("shell_capture", server.shell_capture(Parameters(p)).await)?;
emit("shell_capture", &r, json, out)
}
ShellsCmd::Kill { session_id } => {
let p = ShellKillParams { session_id };
let r = run_tool("shell_kill", server.shell_kill(Parameters(p)).await)?;
emit("shell_kill", &r, json, out)
}
ShellsCmd::Broadcast {
text,
session_ids,
no_enter,
} => {
let p = ShellBroadcastParams {
session_ids,
text,
enter: !no_enter,
};
let r = run_tool(
"shell_broadcast",
server.shell_broadcast(Parameters(p)).await,
)?;
emit("shell_broadcast", &r, json, out)
}
ShellsCmd::List => {
let p = ShellListParams {};
let r = run_tool("shell_list", server.shell_list(Parameters(p)).await)?;
emit("shell_list", &r, json, out)
}
}
}