use anyhow::Result;
use clap::{Parser, Subcommand};
use piw::{server, ui};
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "piw", version, about)]
struct Cli {
run_id: Option<String>,
#[arg(long, value_name = "URL", conflicts_with = "run_id")]
connect: Option<String>,
#[arg(long, value_name = "NAME")]
theme: Option<String>,
#[arg(long)]
list_themes: bool,
#[command(subcommand)]
command: Option<Command>,
}
#[derive(Subcommand)]
enum Command {
Serve {
#[arg(long, default_value = "127.0.0.1:9377")]
bind: String,
},
}
fn default_database() -> PathBuf {
std::env::home_dir()
.unwrap_or_else(|| PathBuf::from("."))
.join(".pi")
.join("agent")
.join("workflows")
.join("state.sqlite")
}
fn main() -> Result<()> {
let cli = Cli::parse();
if cli.list_themes {
for name in piw::theme::THEME_NAMES {
println!("{name}");
}
return Ok(());
}
let cli_theme = cli.theme.clone();
if cli.command.is_none() {
if let Some(url) = cli.connect.as_deref() {
return ui::run_remote(url, cli_theme.as_deref());
}
}
let database = default_database();
anyhow::ensure!(
database.is_file(),
"Pi Workflows database {} does not exist",
database.display()
);
match cli.command {
Some(Command::Serve { bind }) => {
let runtime = tokio::runtime::Runtime::new()?;
runtime.block_on(server::serve(server::ServeOptions {
database_path: database,
bind,
}))
}
None => match cli.run_id {
Some(run_id) => ui::run_single(&database, &run_id, cli_theme.as_deref()),
None => ui::run_local(&database, cli_theme.as_deref()),
},
}
}