use data_fmt::{ RowBuilder, TableFormatter, TableConfig, TableCaption, Format };
static TOOLS : &[ ( &str, &str, &str ) ] = &[
( "Read", "File Operations", "Read files (text, image, PDF, notebook) with line numbers" ),
( "Write", "File Operations", "Create or overwrite files" ),
( "Edit", "File Operations", "Patch files via exact string replacement" ),
( "Bash", "Shell", "Execute shell commands with timeout control" ),
( "Glob", "Search", "Find files by glob patterns" ),
( "Grep", "Search", "Search file contents with regex (ripgrep)" ),
( "Agent", "Agents", "Launch specialized subagent processes" ),
( "AskUserQuestion", "Interaction", "Prompt user for input or clarification" ),
( "WebFetch", "Web", "Fetch content from a URL" ),
( "WebSearch", "Web", "Search the web" ),
( "NotebookEdit", "File Operations", "Edit Jupyter notebook cells" ),
( "LSP", "Code Intelligence", "Language server protocol queries" ),
( "Skill", "Extensibility", "Invoke user-defined slash command skills" ),
( "TaskCreate", "Background Tasks", "Create and start background tasks" ),
( "TaskGet", "Background Tasks", "Get information about a background task" ),
( "TaskList", "Background Tasks", "List all background tasks" ),
( "TaskOutput", "Background Tasks", "Read output from a background task" ),
( "TaskStop", "Background Tasks", "Stop a running background task" ),
( "TaskUpdate", "Background Tasks", "Update status of a background task" ),
( "CronCreate", "Scheduling", "Create recurring scheduled tasks" ),
( "CronDelete", "Scheduling", "Delete scheduled tasks" ),
( "CronList", "Scheduling", "List scheduled tasks" ),
( "EnterPlanMode", "Mode", "Enter plan mode (read-only analysis)" ),
( "ExitPlanMode", "Mode", "Exit plan mode" ),
( "EnterWorktree", "Mode", "Enter git worktree isolation" ),
( "ExitWorktree", "Mode", "Exit git worktree isolation" ),
];
pub( crate ) fn dispatch_tools( tokens : &[ String ] ) -> !
{
if tokens.iter().skip( 1 ).any( | t | t == "--help" || t == "-h" )
{
println!( "clr tools — List all Claude Code built-in tools" );
println!();
println!( "USAGE:" );
println!( " clr tools" );
println!();
println!( "Prints a table of all 26 Claude Code built-in tools with name, category," );
println!( "and description. No flags or arguments are accepted." );
std::process::exit( 0 );
}
let unexpected : Vec< &str > = tokens.iter().skip( 1 ).map( String::as_str ).collect();
if !unexpected.is_empty()
{
eprintln!(
"Error: 'clr tools' does not accept arguments: {}",
unexpected.join( ", " )
);
std::process::exit( 1 );
}
let headers = vec![
"#".to_string(),
"Tool".to_string(),
"Category".to_string(),
"Description".to_string(),
];
let mut builder = RowBuilder::new( headers );
for ( idx, ( name, cat, desc ) ) in TOOLS.iter().enumerate()
{
let row : Vec< String > = vec![
( idx + 1 ).to_string(),
( *name ).to_string(),
( *cat ).to_string(),
( *desc ).to_string(),
];
builder = builder.add_row( row.into_iter().map( Into::into ).collect() );
}
let caption = TableCaption::new( "Claude Code Tools" )
.field( format!( "{} built-in", TOOLS.len() ) );
let view = builder.build_view();
let probe = Format::format(
&TableFormatter::with_config( TableConfig::plain().auto_wrap( false ) ),
&view,
).unwrap_or_default();
let body_width = probe
.lines()
.find( | l | !l.trim().is_empty() )
.map_or( 120, | l | l.chars().count() );
let table = Format::format(
&TableFormatter::with_config(
TableConfig::plain()
.auto_wrap( false )
.terminal_width( Some( body_width ) )
.caption( caption ),
),
&view,
).unwrap_or_default();
println!( "{table}" );
std::process::exit( 0 );
}