1use crate::runner::gateway::GatewayRunner;
4use anyhow::{Context, Result};
5use clap::{Parser, Subcommand};
6use compact_str::CompactString;
7use std::path::PathBuf;
8
9pub mod agent;
10pub mod chat;
11pub mod config;
12pub mod download;
13pub mod memory;
14pub mod send;
15
16#[derive(Parser, Debug)]
18#[command(name = "walrus", about = "Walrus CLI client")]
19pub struct Cli {
20 #[command(subcommand)]
22 pub command: Command,
23
24 #[arg(long, global = true)]
26 pub agent: Option<CompactString>,
27
28 #[arg(long, global = true)]
30 pub socket: Option<PathBuf>,
31}
32
33impl Cli {
34 pub fn resolve_agent(&self) -> CompactString {
36 self.agent.clone().unwrap_or_else(|| "assistant".into())
37 }
38
39 fn resolve_socket(&self) -> PathBuf {
41 self.socket.clone().unwrap_or_else(|| {
42 dirs::home_dir()
43 .expect("no home directory")
44 .join(".walrus")
45 .join("walrus.sock")
46 })
47 }
48
49 pub async fn run(self) -> Result<()> {
51 let agent = self.resolve_agent();
52 let socket_path = self.resolve_socket();
53 match self.command {
54 Command::Config(cmd) => cmd.run(),
55 Command::Chat(cmd) => {
56 let runner = connect(&socket_path).await?;
57 cmd.run(runner, agent).await
58 }
59 Command::Send(cmd) => {
60 let mut runner = connect(&socket_path).await?;
61 cmd.run(&mut runner, &agent).await
62 }
63 Command::Agent(cmd) => {
64 let mut runner = connect(&socket_path).await?;
65 cmd.run(&mut runner).await
66 }
67 Command::Memory(cmd) => {
68 let mut runner = connect(&socket_path).await?;
69 cmd.run(&mut runner).await
70 }
71 Command::Download(cmd) => {
72 let mut runner = connect(&socket_path).await?;
73 cmd.run(&mut runner).await
74 }
75 }
76 }
77}
78
79#[derive(Subcommand, Debug)]
81pub enum Command {
82 Chat(chat::Chat),
84 Send(send::Send),
86 #[command(subcommand)]
88 Agent(agent::AgentCommand),
89 #[command(subcommand)]
91 Memory(memory::MemoryCommand),
92 Download(download::Download),
94 #[command(subcommand)]
96 Config(config::ConfigCommand),
97}
98
99async fn connect(socket_path: &std::path::Path) -> Result<GatewayRunner> {
101 GatewayRunner::connect(socket_path).await.with_context(|| {
102 format!(
103 "failed to connect to walrusd at {}. Is walrusd running?",
104 socket_path.display()
105 )
106 })
107}