feat(cli): Add blue agent command for Goose integration
- Add `blue agent` command that launches Goose with Blue MCP extension - Detects Goose installation and provides install instructions if missing - Supports --model flag and additional Goose arguments - Uses exec() on Unix to replace process for clean signal handling Completes RFC 0005: Local LLM Integration (15/15 tasks) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5d3a7c0d1b
commit
1f9eb88137
1 changed files with 82 additions and 0 deletions
|
|
@ -75,6 +75,17 @@ enum Commands {
|
|||
#[command(subcommand)]
|
||||
command: SessionCommands,
|
||||
},
|
||||
|
||||
/// Launch Goose AI agent with Blue extension
|
||||
Agent {
|
||||
/// Model to use (default: claude-sonnet-4-20250514)
|
||||
#[arg(long, short)]
|
||||
model: Option<String>,
|
||||
|
||||
/// Additional Goose arguments
|
||||
#[arg(trailing_var_arg = true)]
|
||||
args: Vec<String>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
|
|
@ -391,6 +402,9 @@ async fn main() -> Result<()> {
|
|||
Some(Commands::Migrate { from }) => {
|
||||
println!("Coming home from {}.", from);
|
||||
}
|
||||
Some(Commands::Agent { model, args }) => {
|
||||
handle_agent_command(model, args).await?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -1117,3 +1131,71 @@ async fn handle_session_command(command: SessionCommands) -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_agent_command(model: Option<String>, extra_args: Vec<String>) -> Result<()> {
|
||||
use std::process::Command;
|
||||
|
||||
// Check if Goose is installed
|
||||
let goose_check = Command::new("goose")
|
||||
.arg("--version")
|
||||
.output();
|
||||
|
||||
match goose_check {
|
||||
Err(_) => {
|
||||
println!("Goose not found. Install it first:");
|
||||
println!(" pipx install goose-ai");
|
||||
println!(" # or");
|
||||
println!(" brew install goose");
|
||||
println!("\nSee https://github.com/block/goose for more options.");
|
||||
return Ok(());
|
||||
}
|
||||
Ok(output) if !output.status.success() => {
|
||||
println!("Goose check failed. Ensure it's properly installed.");
|
||||
return Ok(());
|
||||
}
|
||||
Ok(_) => {}
|
||||
}
|
||||
|
||||
// Get the path to the blue binary
|
||||
let blue_binary = std::env::current_exe()?;
|
||||
|
||||
// Build the extension command
|
||||
let extension_cmd = format!("{} mcp", blue_binary.display());
|
||||
|
||||
println!("Starting Goose with Blue extension...");
|
||||
println!(" Extension: {}", extension_cmd);
|
||||
|
||||
// Build goose command
|
||||
let mut cmd = Command::new("goose");
|
||||
cmd.arg("session");
|
||||
cmd.arg("--with-extension").arg(&extension_cmd);
|
||||
|
||||
// Add model if specified
|
||||
if let Some(m) = model {
|
||||
cmd.arg("--model").arg(m);
|
||||
}
|
||||
|
||||
// Add any extra arguments
|
||||
for arg in extra_args {
|
||||
cmd.arg(arg);
|
||||
}
|
||||
|
||||
// Execute goose, replacing current process
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::process::CommandExt;
|
||||
let err = cmd.exec();
|
||||
// exec() only returns if there was an error
|
||||
anyhow::bail!("Failed to exec goose: {}", err);
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
// On non-Unix, spawn and wait
|
||||
let status = cmd.status()?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("Goose exited with status: {}", status);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue