diff --git a/rust/crates/rusty-claude-cli/src/main.rs b/rust/crates/rusty-claude-cli/src/main.rs index 4f9790d..04eeda3 100644 --- a/rust/crates/rusty-claude-cli/src/main.rs +++ b/rust/crates/rusty-claude-cli/src/main.rs @@ -12,9 +12,7 @@ use api::{ ToolResultContentBlock, }; -use commands::{ - handle_slash_command, render_slash_command_help, resume_supported_slash_commands, SlashCommand, -}; +use commands::{render_slash_command_help, resume_supported_slash_commands, SlashCommand}; use compat_harness::{extract_manifest, UpstreamPaths}; use render::{Spinner, TerminalRenderer}; use runtime::{ @@ -358,6 +356,24 @@ fn format_init_report(path: &Path, created: bool) -> String { } } +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 parse_git_status_metadata(status: Option<&str>) -> (Option, Option) { let Some(status) = status else { return (None, None); @@ -402,23 +418,20 @@ fn run_resume_command( message: Some(render_repl_help()), }), SlashCommand::Compact => { - let Some(result) = handle_slash_command( - "/compact", + let result = runtime::compact_session( session, CompactionConfig { max_estimated_tokens: 0, ..CompactionConfig::default() }, - ) else { - return Ok(ResumeCommandOutcome { - session: session.clone(), - message: None, - }); - }; - result.session.save_to_path(session_path)?; + ); + let removed = result.removed_message_count; + let kept = result.compacted_session.messages.len(); + let skipped = removed == 0; + result.compacted_session.save_to_path(session_path)?; Ok(ResumeCommandOutcome { - session: result.session, - message: Some(result.message), + session: result.compacted_session, + message: Some(format_compact_report(removed, kept, skipped)), }) } SlashCommand::Clear { confirm } => { @@ -746,6 +759,8 @@ impl LiveCli { fn compact(&mut self) -> Result<(), Box> { let result = self.runtime.compact(CompactionConfig::default()); let removed = result.removed_message_count; + let kept = result.compacted_session.messages.len(); + let skipped = removed == 0; self.runtime = build_runtime_with_permission_mode( result.compacted_session, self.model.clone(), @@ -753,7 +768,7 @@ impl LiveCli { true, permission_mode_label(), )?; - println!("Compacted {removed} messages."); + println!("{}", format_compact_report(removed, kept, skipped)); Ok(()) } } @@ -1384,12 +1399,12 @@ fn print_help() { #[cfg(test)] mod tests { use super::{ - format_cost_report, format_init_report, format_model_report, format_model_switch_report, - format_permissions_report, format_permissions_switch_report, format_resume_report, - format_status_report, normalize_permission_mode, parse_args, parse_git_status_metadata, - render_config_report, render_init_claude_md, render_memory_report, render_repl_help, - resume_supported_slash_commands, status_context, CliAction, SlashCommand, StatusUsage, - DEFAULT_MODEL, + format_compact_report, format_cost_report, format_init_report, format_model_report, + format_model_switch_report, format_permissions_report, format_permissions_switch_report, + format_resume_report, format_status_report, normalize_permission_mode, parse_args, + parse_git_status_metadata, render_config_report, render_init_claude_md, + render_memory_report, render_repl_help, resume_supported_slash_commands, status_context, + CliAction, SlashCommand, StatusUsage, DEFAULT_MODEL, }; use runtime::{ContentBlock, ConversationMessage, MessageRole}; use std::path::{Path, PathBuf}; @@ -1521,6 +1536,16 @@ mod tests { assert!(report.contains("Turns 6")); } + #[test] + fn compact_report_uses_structured_output() { + let compacted = format_compact_report(8, 5, false); + assert!(compacted.contains("Compact")); + assert!(compacted.contains("Result compacted")); + assert!(compacted.contains("Messages removed 8")); + let skipped = format_compact_report(0, 3, true); + assert!(skipped.contains("Result skipped")); + } + #[test] fn cost_report_uses_sectioned_layout() { let report = format_cost_report(runtime::TokenUsage {