use clap::{Parser, Subcommand};
mod client;
mod menu;
mod notify;
mod rebuild;
mod serve;
mod state;
mod tmux;
#[derive(Parser)]
#[command(
name = "cekanje",
about = "tmux notifier daemon for Claude sessions",
version
)]
struct Cli {
#[command(subcommand)]
command: Cmd,
}
#[derive(Subcommand)]
enum Cmd {
Serve {
#[arg(long, default_value_t = 8731)]
port: u16,
#[arg(long)]
ensure: bool,
#[arg(long, default_value_t = 1800)]
idle_secs: u64,
#[arg(long, default_value_t = 300)]
rebuild_window_secs: u64,
},
Status {
#[arg(long, default_value_t = 8731)]
port: u16,
},
List {
#[arg(long, default_value_t = 8731)]
port: u16,
},
Visit {
pane: String,
#[arg(long, default_value_t = 8731)]
port: u16,
},
Menu {
#[arg(long, default_value_t = 8731)]
port: u16,
},
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "cekanje=info".into()),
)
.init();
match Cli::parse().command {
Cmd::Serve {
port,
ensure,
idle_secs,
rebuild_window_secs,
} => {
if ensure {
if client::http_get(port, "/status").await.is_ok() {
return Ok(());
}
spawn_detached(port, idle_secs, rebuild_window_secs)?;
return Ok(());
}
serve::run(port, idle_secs, rebuild_window_secs).await
}
Cmd::Status { port } => {
let body = client::http_get(port, "/status").await.unwrap_or_default();
print!("{body}");
Ok(())
}
Cmd::List { port } => {
let body = client::http_get(port, "/list").await?;
println!("{body}");
Ok(())
}
Cmd::Visit { pane, port } => {
let body = serde_json::json!({ "pane": pane }).to_string();
client::http_post_json(port, "/visit", &body).await?;
Ok(())
}
Cmd::Menu { port } => menu::run(port).await,
}
}
fn spawn_detached(port: u16, idle_secs: u64, rebuild_window_secs: u64) -> anyhow::Result<()> {
use std::process::{Command, Stdio};
let exe = std::env::current_exe()?;
Command::new(exe)
.arg("serve")
.arg("--port")
.arg(port.to_string())
.arg("--idle-secs")
.arg(idle_secs.to_string())
.arg("--rebuild-window-secs")
.arg(rebuild_window_secs.to_string())
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()?;
Ok(())
}