use clap::{Parser, Subcommand};
use std::fmt;
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum DebugLevel {
Debug,
Info,
Warn,
Error,
}
impl FromStr for DebugLevel {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"debug" => Ok(DebugLevel::Debug),
"info" => Ok(DebugLevel::Info),
"warn" | "warning" => Ok(DebugLevel::Warn),
"error" => Ok(DebugLevel::Error),
_ => Err(format!(
"invalid log level '{}', expected: debug, info, warn, error",
s
)),
}
}
}
impl fmt::Display for DebugLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
DebugLevel::Debug => write!(f, "debug"),
DebugLevel::Info => write!(f, "info"),
DebugLevel::Warn => write!(f, "warn"),
DebugLevel::Error => write!(f, "error"),
}
}
}
#[derive(Debug, Subcommand)]
pub enum Commands {
Update,
}
#[derive(Parser, Debug)]
#[command(name = "claude-history")]
#[command(version)]
#[command(about = "View Claude conversation history")]
#[command(args_conflicts_with_subcommands = true)]
pub struct Args {
#[command(subcommand)]
pub command: Option<Commands>,
#[arg(long, short = 't', group = "tools_display")]
pub show_tools: bool,
#[arg(long, group = "tools_display")]
pub no_tools: bool,
#[arg(
long,
short = 'd',
help = "Print the conversation directory path and exit"
)]
pub show_dir: bool,
#[arg(long, short = 'l', group = "preview_content")]
pub last: bool,
#[arg(long, group = "preview_content")]
pub first: bool,
#[arg(long, group = "thinking_display")]
pub show_thinking: bool,
#[arg(long, group = "thinking_display")]
pub hide_thinking: bool,
#[arg(
long,
short = 'c',
help = "Resume the selected conversation in Claude Code"
)]
pub resume: bool,
#[arg(long, help = "Fork the session when resuming", requires = "resume")]
pub fork_session: bool,
#[arg(long, short = 'p', help = "Print the selected conversation file path")]
pub show_path: bool,
#[arg(long, short = 'i', help = "Print the selected conversation session ID")]
pub show_id: bool,
#[arg(long, help = "Output plain text without ledger formatting")]
pub plain: bool,
#[arg(
long,
value_name = "LEVEL",
default_missing_value = "debug",
num_args = 0..=1,
help = "Print debug information (optionally filter by level: debug, info, warn, error)"
)]
pub debug: Option<DebugLevel>,
#[arg(long, short = 'g', hide = true)]
pub global: bool,
#[arg(
long,
short = 'L',
help = "Show only conversations from the current workspace directory"
)]
pub local: bool,
#[arg(long, group = "pager_display")]
pub pager: bool,
#[arg(long, group = "pager_display")]
pub no_pager: bool,
#[arg(
long,
value_name = "FILE",
help = "Render a JSONL file in ledger format and exit"
)]
pub render: Option<PathBuf>,
#[arg(long, help = "Disable colored output")]
pub no_color: bool,
#[arg(
long,
value_name = "SESSION_ID",
help = "Delete a session by its UUID and exit",
conflicts_with_all = ["global", "show_dir", "resume", "show_path", "show_id", "plain", "render", "input_file"]
)]
pub delete: Option<String>,
#[arg(
long = "debug-search",
value_name = "QUERY",
help = "Debug search result scoring for a query",
conflicts_with_all = ["show_dir", "resume", "show_path", "show_id", "plain", "render", "delete", "input_file"]
)]
pub debug_search: Option<String>,
#[arg(
value_name = "FILE",
help = "JSONL conversation file to view directly",
conflicts_with_all = ["global", "local", "show_dir", "resume", "show_path", "show_id", "plain", "render", "delete"]
)]
pub input_file: Option<PathBuf>,
}