use clap::{Parser, Subcommand};
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(name = "cship", about = "Claude Code statusline renderer")]
struct Cli {
#[arg(short = 'v', long = "version")]
version: bool,
#[arg(long, global = true, value_name = "PATH")]
config: Option<PathBuf>,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand, Debug)]
enum Commands {
Explain,
Uninstall,
}
fn main() {
tracing_subscriber::fmt()
.with_writer(std::io::stderr)
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();
let cli = Cli::parse();
if cli.version {
println!("cship {}", env!("CARGO_PKG_VERSION"));
return;
}
match cli.command {
Some(Commands::Explain) => {
let output = cship::explain::run(cli.config.as_deref());
if !output.is_empty() {
println!("{output}");
}
}
Some(Commands::Uninstall) => {
cship::uninstall::run();
}
None => {
let ctx = match cship::context::from_stdin() {
Ok(ctx) => ctx,
Err(e) => {
tracing::error!("cship: failed to parse Claude Code session JSON: {e}");
std::process::exit(1);
}
};
let workspace_dir = ctx
.workspace
.as_ref()
.and_then(|w| w.current_dir.as_deref());
let cfg = match cship::config::discover_and_load(
workspace_dir,
cli.config.as_deref().and_then(|p| p.to_str()),
) {
Ok(cfg) => cfg,
Err(e) => {
tracing::error!("cship: failed to load config: {e}");
std::process::exit(1);
}
};
let lines = cfg.lines.as_deref().unwrap_or(&[]);
if cfg.format.is_some() || !lines.is_empty() {
let output = cship::renderer::render(lines, &ctx, &cfg);
if !output.is_empty() {
println!("{output}");
}
}
}
}
}