use std::io::{self, Read};
use claude_code_status_line::app::{parse_claude_input, render_statusline_with_width};
use claude_code_status_line::commands::{self, InstallOutcome};
use claude_code_status_line::config::load_config;
use claude_code_status_line::setup;
use claude_code_status_line::utils::{get_claude_config_dir, get_terminal_width};
fn main() {
const VERSION: &str = env!("CARGO_PKG_VERSION");
const PKG_NAME: &str = env!("CARGO_PKG_NAME");
if std::env::args().any(|a| a == "--version" || a == "-V") {
println!("{} {}", PKG_NAME, VERSION);
return;
}
if std::env::args().any(|a| a == "--help" || a == "-h") {
println!(
"{} {} - Beautiful statusline for Claude Code",
PKG_NAME, VERSION
);
println!("\nUsage:");
println!(
" Receives JSON on stdin from Claude Code, outputs formatted statusline to stdout"
);
println!("\nCommands:");
println!(" setup [--yes] Install this binary to ~/.claude/statusline/bin/,");
println!(" install the slash commands and point Claude Code's");
println!(" statusLine at it (--yes: don't ask before editing");
println!(" Claude Code's settings.json)");
println!("\nOptions:");
println!(" --version, -V Show version");
println!(
" --install-commands Install/update slash commands in ~/.claude/commands/ (honours CLAUDE_CONFIG_DIR)"
);
println!(" --help, -h Show this help");
println!("\nConfiguration:");
println!(" ~/.claude/statusline/settings.json - Statusline settings");
println!(" ~/.claude/statusline/colors.json - Color customization");
println!("\nSlash Commands:");
println!(" /install-statusline - Interactive installation wizard");
println!(" /update-statusline - Update to latest version");
println!(" /customize-statusline - Interactive configuration wizard");
println!(" /uninstall-statusline - Remove the statusline");
println!("\nDocumentation:");
println!(" https://www.npmjs.com/package/@ndave92/claude-code-status-line");
println!(" https://crates.io/crates/claude-code-status-line");
println!(" https://ndave92.github.io/claude-code-status-line/");
return;
}
if std::env::args().nth(1).as_deref() == Some("setup") {
let yes = std::env::args().skip(2).any(|a| a == "--yes" || a == "-y");
std::process::exit(setup::run(yes));
}
if std::env::args().any(|a| a == "--install-commands") {
std::process::exit(install_commands());
}
let config = load_config();
let mut input_str = String::new();
if io::stdin().read_to_string(&mut input_str).is_err() {
eprintln!("statusline error: failed to read stdin");
println!();
return;
}
let input = match parse_claude_input(&input_str) {
Ok(input) => input,
Err(_) => {
eprintln!("statusline error: invalid JSON");
println!();
return;
}
};
let term_width = get_terminal_width(&config);
if std::env::var("STATUSLINE_DEBUG").is_ok() {
eprintln!("Debug: term_width detected as {}", term_width);
}
let lines = render_statusline_with_width(&input, &config, term_width);
for line in lines {
println!("{}", line);
}
}
fn install_commands() -> i32 {
let Some(config_dir) = get_claude_config_dir() else {
eprintln!("error: could not determine home directory");
return 1;
};
let dir = config_dir.join("commands");
match commands::install_commands(&dir) {
Ok(results) => {
for (name, outcome) in results {
match outcome {
InstallOutcome::Installed => println!("installed {}", name),
InstallOutcome::UpToDate => println!("up to date {}", name),
InstallOutcome::Updated { backup } => {
println!(
"updated {} (previous saved to {})",
name,
backup.display()
)
}
}
}
println!("Commands directory: {}", dir.display());
0
}
Err(err) => {
eprintln!(
"error: failed to install commands into {}: {}",
dir.display(),
err
);
1
}
}
}