feat(wave1): Full clap Cli struct + dispatch skeleton in main.rs [claudbg-pkyj]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
Elijah Voigt 2 months ago
parent ae33d93d8e
commit 4129e65594

@ -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.

@ -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));
}
}

@ -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(())
}

Loading…
Cancel
Save