use crate::runner::gateway::GatewayRunner;
use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
use compact_str::CompactString;
use std::path::PathBuf;
pub mod agent;
pub mod chat;
pub mod config;
pub mod download;
pub mod memory;
pub mod send;
#[derive(Parser, Debug)]
#[command(name = "walrus", about = "Walrus CLI client")]
pub struct Cli {
#[command(subcommand)]
pub command: Command,
#[arg(long, global = true)]
pub agent: Option<CompactString>,
#[arg(long, global = true)]
pub socket: Option<PathBuf>,
}
impl Cli {
pub fn resolve_agent(&self) -> CompactString {
self.agent.clone().unwrap_or_else(|| "assistant".into())
}
fn resolve_socket(&self) -> PathBuf {
self.socket.clone().unwrap_or_else(|| {
dirs::home_dir()
.expect("no home directory")
.join(".walrus")
.join("walrus.sock")
})
}
pub async fn run(self) -> Result<()> {
let agent = self.resolve_agent();
let socket_path = self.resolve_socket();
match self.command {
Command::Config(cmd) => cmd.run(),
Command::Chat(cmd) => {
let runner = connect(&socket_path).await?;
cmd.run(runner, agent).await
}
Command::Send(cmd) => {
let mut runner = connect(&socket_path).await?;
cmd.run(&mut runner, &agent).await
}
Command::Agent(cmd) => {
let mut runner = connect(&socket_path).await?;
cmd.run(&mut runner).await
}
Command::Memory(cmd) => {
let mut runner = connect(&socket_path).await?;
cmd.run(&mut runner).await
}
Command::Download(cmd) => {
let mut runner = connect(&socket_path).await?;
cmd.run(&mut runner).await
}
}
}
}
#[derive(Subcommand, Debug)]
pub enum Command {
Chat(chat::Chat),
Send(send::Send),
#[command(subcommand)]
Agent(agent::AgentCommand),
#[command(subcommand)]
Memory(memory::MemoryCommand),
Download(download::Download),
#[command(subcommand)]
Config(config::ConfigCommand),
}
async fn connect(socket_path: &std::path::Path) -> Result<GatewayRunner> {
GatewayRunner::connect(socket_path).await.with_context(|| {
format!(
"failed to connect to walrusd at {}. Is walrusd running?",
socket_path.display()
)
})
}