feat(wave1): Define global CLI flags (OutputFormat, IncludeList) [claudbg-nmuu]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main
Elijah Voigt 2 months ago
parent 1a2f999636
commit ded9cd3a5c

@ -1,11 +1,12 @@
---
# claudbg-nmuu
title: Define global CLI flags
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-28T04:25:33Z
parent: claudbg-h7xu
---
Add global flags available to all subcommands: --output [table|json|xml] (default: table), --verbose (bool), --include <list> (comma-separated: thinking,output,tools — default: tools). These must be accessible from every command handler.
Created src/cli.rs with OutputFormat enum (Table/Json/Xml, derives Default+ValueEnum), IncludeList struct (thinking, output bools, derives Default), and FromStr impl for IncludeList that parses comma-separated tokens and returns AppError::InvalidArg for unknowns. Six unit tests cover empty string, single tokens, both tokens, unknown token error, and whitespace trimming. Updated src/lib.rs to declare pub mod cli.

@ -0,0 +1,107 @@
//! CLI types: output format, include list, and global options.
/// Output format for all commands.
#[derive(Debug, Clone, Default, clap::ValueEnum)]
pub enum OutputFormat {
/// Human-readable table (default).
#[default]
Table,
/// JSON output.
Json,
/// XML output.
Xml,
}
/// Comma-separated list of optional content to include in transcripts.
///
/// Accepted tokens: `thinking`, `output`.
#[derive(Debug, Clone, Default)]
pub struct IncludeList {
/// Include `thinking` blocks in transcripts.
pub thinking: bool,
/// Include tool `output` blocks in transcripts.
pub output: bool,
}
impl std::str::FromStr for IncludeList {
type Err = crate::error::AppError;
/// Parse a comma-separated string of include tokens.
///
/// Accepted tokens: `thinking`, `output`.
/// Returns [`AppError::InvalidArg`] for any unknown token.
fn from_str(s: &str) -> crate::error::Result<Self> {
let mut list = IncludeList::default();
for token in s.split(',') {
let token = token.trim();
if token.is_empty() {
continue;
}
match token {
"thinking" => list.thinking = true,
"output" => list.output = true,
other => {
return Err(crate::error::AppError::InvalidArg(format!(
"unknown include token: {other}"
)));
}
}
}
Ok(list)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
/// Empty string produces a default `IncludeList` with both flags false.
#[test]
fn include_list_empty_string() {
let list = IncludeList::from_str("").unwrap();
assert!(!list.thinking);
assert!(!list.output);
}
/// Parsing `"thinking"` sets the thinking flag only.
#[test]
fn include_list_thinking_only() {
let list = IncludeList::from_str("thinking").unwrap();
assert!(list.thinking);
assert!(!list.output);
}
/// Parsing `"output"` sets the output flag only.
#[test]
fn include_list_output_only() {
let list = IncludeList::from_str("output").unwrap();
assert!(!list.thinking);
assert!(list.output);
}
/// Parsing `"thinking,output"` sets both flags.
#[test]
fn include_list_both() {
let list = IncludeList::from_str("thinking,output").unwrap();
assert!(list.thinking);
assert!(list.output);
}
/// An unknown token returns an `AppError::InvalidArg`.
#[test]
fn include_list_unknown_token() {
let result = IncludeList::from_str("images");
assert!(result.is_err());
let msg = result.unwrap_err().to_string();
assert!(msg.contains("unknown include token: images"), "got: {msg}");
}
/// Whitespace around tokens is trimmed.
#[test]
fn include_list_whitespace_trim() {
let list = IncludeList::from_str(" thinking , output ").unwrap();
assert!(list.thinking);
assert!(list.output);
}
}

@ -1,6 +1,6 @@
//! claudbg — Claude Code session inspector library.
// pub mod cli;
pub mod cli;
// pub mod commands;
// pub mod db;
pub mod error;

Loading…
Cancel
Save