diff --git a/.beans/claudbg-pkyj--implement-main-cli-entry-point-and-subcommand-stru.md b/.beans/claudbg-pkyj--implement-main-cli-entry-point-and-subcommand-stru.md index 115ed76..9d86795 100644 --- a/.beans/claudbg-pkyj--implement-main-cli-entry-point-and-subcommand-stru.md +++ b/.beans/claudbg-pkyj--implement-main-cli-entry-point-and-subcommand-stru.md @@ -1,11 +1,12 @@ --- # claudbg-pkyj title: Implement main CLI entry point and subcommand structure -status: todo +status: completed type: task +priority: normal created_at: 2026-03-27T19:38:56Z -updated_at: 2026-03-27T19:38:56Z +updated_at: 2026-03-28T05:00:28Z parent: claudbg-h7xu --- -Wire up clap App with top-level subcommands: sessions, agents, index, tui, query. Each subcommand is a separate clap subcommand group. Binary entry point dispatches to the correct handler. +Expanded src/cli.rs with Cli, GlobalOpts, Commands, SessionsCmd, and AgentsCmd clap structs. Updated src/main.rs with tokio main, clap::Parser, and full match dispatch skeleton printing coming-soon stubs. Verified cargo run -- --help shows all subcommands and cargo run -- sessions list prints the stub message. diff --git a/src/cli.rs b/src/cli.rs index a8d549c..0de1838 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -//! CLI types: output format, include list, and global options. +//! CLI types: output format, include list, global options, and command structure. /// Output format for all commands. #[derive(Debug, Clone, Default, clap::ValueEnum)] @@ -51,6 +51,112 @@ impl std::str::FromStr for IncludeList { } } +/// Top-level CLI entry point for claudbg. +#[derive(Debug, clap::Parser)] +#[command(name = "claudbg", about = "Claude Code session inspector")] +pub struct Cli { + /// Global options shared across all subcommands. + #[command(flatten)] + pub global: GlobalOpts, + /// The subcommand to execute. + #[command(subcommand)] + pub command: Commands, +} + +/// Global options available on every subcommand. +#[derive(Debug, Clone, clap::Args)] +pub struct GlobalOpts { + /// Output format: table (default), json, xml. + #[arg(long, global = true, default_value = "table")] + pub output: OutputFormat, + /// Show full UUIDs and extra detail. + #[arg(long, global = true)] + pub verbose: bool, + /// Comma-separated content to include: thinking, output. + #[arg(long, global = true, default_value = "")] + pub include: IncludeList, +} + +/// Top-level subcommands. +#[derive(Debug, clap::Subcommand)] +pub enum Commands { + /// List, dump, and transcribe sessions. + Sessions { + /// Sessions subcommand. + #[command(subcommand)] + cmd: SessionsCmd, + }, + /// List, dump, and transcribe sub-agent runs. + Agents { + /// Agents subcommand. + #[command(subcommand)] + cmd: AgentsCmd, + }, + /// Sync all session files into the local cache DB. + Index { + /// Force full rebuild even if files appear up to date. + #[arg(long)] + force: bool, + }, + /// Launch terminal UI (coming soon). + Tui, + /// Run ad-hoc queries against the cache DB (coming soon). + Query, +} + +/// Subcommands for `sessions`. +#[derive(Debug, clap::Subcommand)] +pub enum SessionsCmd { + /// List all sessions, most recent first. + List, + /// Dump raw messages from a session. + Dump { + /// Session ID or 8-char prefix. + id: String, + /// Stream new entries as the session file is written. + #[arg(long)] + follow: bool, + }, + /// Show a human-readable transcript of a session. + Transcribe { + /// Session ID or 8-char prefix. + id: String, + /// Stream new entries as the session file is written. + #[arg(long)] + follow: bool, + }, +} + +/// Subcommands for `agents`. +#[derive(Debug, clap::Subcommand)] +pub enum AgentsCmd { + /// List all agent runs within a session. + List { + /// Parent session ID or 8-char prefix. + session_id: String, + }, + /// Dump raw messages from an agent run. + Dump { + /// Parent session ID or 8-char prefix. + session_id: String, + /// Agent ID or 8-char prefix. + agent_id: String, + /// Stream new entries as the agent file is written. + #[arg(long)] + follow: bool, + }, + /// Show a human-readable transcript of an agent run. + Transcribe { + /// Parent session ID or 8-char prefix. + session_id: String, + /// Agent ID or 8-char prefix. + agent_id: String, + /// Stream new entries as the agent file is written. + #[arg(long)] + follow: bool, + }, +} + #[cfg(test)] mod tests { use super::*; @@ -104,4 +210,11 @@ mod tests { assert!(list.thinking); assert!(list.output); } + + /// `OutputFormat` defaults to `Table`. + #[test] + fn output_format_default() { + let fmt = OutputFormat::default(); + assert!(matches!(fmt, OutputFormat::Table)); + } } diff --git a/src/main.rs b/src/main.rs index ea2d861..f743990 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,36 @@ //! claudbg binary entry point. +use clap::Parser; +use claudbg::cli::{AgentsCmd, Cli, Commands, SessionsCmd}; use claudbg::error::Result; -fn main() { - let _: Result<()> = Ok(()); - println!("Hello, world!"); +#[tokio::main] +async fn main() -> Result<()> { + let cli = Cli::parse(); + match cli.command { + Commands::Sessions { cmd } => match cmd { + SessionsCmd::List => println!("sessions list: coming soon"), + SessionsCmd::Dump { id, .. } => println!("sessions dump {id}: coming soon"), + SessionsCmd::Transcribe { id, .. } => { + println!("sessions transcribe {id}: coming soon") + } + }, + Commands::Agents { cmd } => match cmd { + AgentsCmd::List { session_id } => println!("agents list {session_id}: coming soon"), + AgentsCmd::Dump { + session_id, + agent_id, + .. + } => println!("agents dump {session_id} {agent_id}: coming soon"), + AgentsCmd::Transcribe { + session_id, + agent_id, + .. + } => println!("agents transcribe {session_id} {agent_id}: coming soon"), + }, + Commands::Index { force } => println!("index (force={force}): coming soon"), + Commands::Tui => println!("tui: coming soon!"), + Commands::Query => println!("query: coming soon!"), + } + Ok(()) }