From ae70e77f14e00610d3bc546360cc80993141309f Mon Sep 17 00:00:00 2001 From: zhaoyanchao Date: Tue, 26 May 2026 19:39:41 +0800 Subject: [PATCH] refactor: extract formatting.rs (report formatters) from main.rs --- .../crates/rusty-claude-cli/src/formatting.rs | 157 ++++++++++++++++++ rust/crates/rusty-claude-cli/src/main.rs | 152 +---------------- 2 files changed, 160 insertions(+), 149 deletions(-) create mode 100644 rust/crates/rusty-claude-cli/src/formatting.rs diff --git a/rust/crates/rusty-claude-cli/src/formatting.rs b/rust/crates/rusty-claude-cli/src/formatting.rs new file mode 100644 index 00000000..527083af --- /dev/null +++ b/rust/crates/rusty-claude-cli/src/formatting.rs @@ -0,0 +1,157 @@ +use std::path::PathBuf; +use runtime::TokenUsage; +use serde_json::Value; + +use crate::constants::*; +use crate::models::*; +use crate::omc_compatibility_note_for_unknown_slash_command; +use crate::suggest_slash_commands; + +pub(crate) fn format_unknown_slash_command_message(name: &str) -> String { + let suggestions = suggest_slash_commands(name); + let mut message = format!("unknown slash command: /{name}."); + if !suggestions.is_empty() { + message.push_str(" Did you mean "); + message.push_str(&suggestions.join(", ")); + message.push('?'); + } + if let Some(note) = omc_compatibility_note_for_unknown_slash_command(name) { + message.push(' '); + message.push_str(note); + } + message.push_str(" Use /help to list available commands."); + message +} + +pub(crate) fn format_model_report(model: &str, message_count: usize, turns: u32) -> String { + format!( + "Model + Current model {model} + Session messages {message_count} + Session turns {turns} + +Usage + Inspect current model with /model + Switch models with /model " + ) +} + +pub(crate) fn format_model_switch_report(previous: &str, next: &str, message_count: usize) -> String { + format!( + "Model updated + Previous {previous} + Current {next} + Preserved msgs {message_count}" + ) +} + +pub(crate) fn format_permissions_report(mode: &str) -> String { + let modes = [ + ("read-only", "Read/search tools only", mode == "read-only"), + ( + "workspace-write", + "Edit files inside the workspace", + mode == "workspace-write", + ), + ( + "danger-full-access", + "Unrestricted tool access", + mode == "danger-full-access", + ), + ] + .into_iter() + .map(|(name, description, is_current)| { + let marker = if is_current { + "● current" + } else { + "○ available" + }; + format!(" {name:<18} {marker:<11} {description}") + }) + .collect::>() + .join( + " +", + ); + + format!( + "Permissions + Active mode {mode} + Mode status live session default + +Modes +{modes} + +Usage + Inspect current mode with /permissions + Switch modes with /permissions " + ) +} + +pub(crate) fn format_permissions_switch_report(previous: &str, next: &str) -> String { + format!( + "Permissions updated + Result mode switched + Previous mode {previous} + Active mode {next} + Applies to subsequent tool calls + Usage /permissions to inspect current mode" + ) +} + +pub(crate) fn format_cost_report(usage: TokenUsage) -> String { + format!( + "Cost + Input tokens {} + Output tokens {} + Cache create {} + Cache read {} + Total tokens {}", + usage.input_tokens, + usage.output_tokens, + usage.cache_creation_input_tokens, + usage.cache_read_input_tokens, + usage.total_tokens(), + ) +} + +pub(crate) fn format_resume_report(session_path: &str, message_count: usize, turns: u32) -> String { + format!( + "Session resumed + Session file {session_path} + Messages {message_count} + Turns {turns}" + ) +} + +pub(crate) fn render_resume_usage() -> String { + format!( + "Resume + Usage /resume + Auto-save .claw/sessions/.{PRIMARY_SESSION_EXTENSION} + Tip use /session list to inspect saved sessions" + ) +} + +pub(crate) fn format_compact_report(removed: usize, resulting_messages: usize, skipped: bool) -> String { + if skipped { + format!( + "Compact + Result skipped + Reason session below compaction threshold + Messages kept {resulting_messages}" + ) + } else { + format!( + "Compact + Result compacted + Messages removed {removed} + Messages kept {resulting_messages}" + ) + } +} + +pub(crate) fn format_auto_compaction_notice(removed: usize) -> String { + format!("[auto-compacted: removed {removed} messages]") +} + diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 3f9a4473..d32815eb 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -13,6 +13,7 @@ mod args; mod constants; mod doctor; mod error; +mod formatting; mod session; mod init; mod input; @@ -27,6 +28,7 @@ pub(crate) use args::*; pub(crate) use constants::*; pub(crate) use doctor::*; pub(crate) use error::*; +pub(crate) use formatting::*; pub(crate) use session::*; pub(crate) use model::*; pub(crate) use models::*; @@ -858,156 +860,8 @@ impl GitWorkspaceSummary { } } -#[cfg(test)] -fn format_unknown_slash_command_message(name: &str) -> String { - let suggestions = suggest_slash_commands(name); - let mut message = format!("unknown slash command: /{name}."); - if !suggestions.is_empty() { - message.push_str(" Did you mean "); - message.push_str(&suggestions.join(", ")); - message.push('?'); - } - if let Some(note) = omc_compatibility_note_for_unknown_slash_command(name) { - message.push(' '); - message.push_str(note); - } - message.push_str(" Use /help to list available commands."); - message -} -fn format_model_report(model: &str, message_count: usize, turns: u32) -> String { - format!( - "Model - Current model {model} - Session messages {message_count} - Session turns {turns} - -Usage - Inspect current model with /model - Switch models with /model " - ) -} - -fn format_model_switch_report(previous: &str, next: &str, message_count: usize) -> String { - format!( - "Model updated - Previous {previous} - Current {next} - Preserved msgs {message_count}" - ) -} - -fn format_permissions_report(mode: &str) -> String { - let modes = [ - ("read-only", "Read/search tools only", mode == "read-only"), - ( - "workspace-write", - "Edit files inside the workspace", - mode == "workspace-write", - ), - ( - "danger-full-access", - "Unrestricted tool access", - mode == "danger-full-access", - ), - ] - .into_iter() - .map(|(name, description, is_current)| { - let marker = if is_current { - "● current" - } else { - "○ available" - }; - format!(" {name:<18} {marker:<11} {description}") - }) - .collect::>() - .join( - " -", - ); - - format!( - "Permissions - Active mode {mode} - Mode status live session default - -Modes -{modes} - -Usage - Inspect current mode with /permissions - Switch modes with /permissions " - ) -} - -fn format_permissions_switch_report(previous: &str, next: &str) -> String { - format!( - "Permissions updated - Result mode switched - Previous mode {previous} - Active mode {next} - Applies to subsequent tool calls - Usage /permissions to inspect current mode" - ) -} - -fn format_cost_report(usage: TokenUsage) -> String { - format!( - "Cost - Input tokens {} - Output tokens {} - Cache create {} - Cache read {} - Total tokens {}", - usage.input_tokens, - usage.output_tokens, - usage.cache_creation_input_tokens, - usage.cache_read_input_tokens, - usage.total_tokens(), - ) -} - -fn format_resume_report(session_path: &str, message_count: usize, turns: u32) -> String { - format!( - "Session resumed - Session file {session_path} - Messages {message_count} - Turns {turns}" - ) -} - -fn render_resume_usage() -> String { - format!( - "Resume - Usage /resume - Auto-save .claw/sessions/.{PRIMARY_SESSION_EXTENSION} - Tip use /session list to inspect saved sessions" - ) -} - -fn format_compact_report(removed: usize, resulting_messages: usize, skipped: bool) -> String { - if skipped { - format!( - "Compact - Result skipped - Reason session below compaction threshold - Messages kept {resulting_messages}" - ) - } else { - format!( - "Compact - Result compacted - Messages removed {removed} - Messages kept {resulting_messages}" - ) - } -} - -fn format_auto_compaction_notice(removed: usize) -> String { - format!("[auto-compacted: removed {removed} messages]") -} - -fn parse_git_status_metadata(status: Option<&str>) -> (Option, Option) { +pub(crate) fn parse_git_status_metadata(status: Option<&str>) -> (Option, Option) { parse_git_status_metadata_for( &env::current_dir().unwrap_or_else(|_| PathBuf::from(".")), status,