Files
claude-code/rust/crates/commands/src/lib.rs
Yeachan-Heo 334d1854d6 feat: merge 2nd round from all rcc/* sessions
- api: tool_use parsing, message_delta, request_id tracking, retry logic
- tools: extended tool suite (WebSearch, WebFetch, Agent, etc.)
- cli: live streamed conversations, session restore, compact commands
- runtime: config loading, system prompt builder, token usage, compaction
2026-03-31 17:43:25 +00:00

111 lines
3.0 KiB
Rust

use runtime::{compact_session, CompactionConfig, Session};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CommandManifestEntry {
pub name: String,
pub source: CommandSource,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CommandSource {
Builtin,
InternalOnly,
FeatureGated,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct CommandRegistry {
entries: Vec<CommandManifestEntry>,
}
impl CommandRegistry {
#[must_use]
pub fn new(entries: Vec<CommandManifestEntry>) -> Self {
Self { entries }
}
#[must_use]
pub fn entries(&self) -> &[CommandManifestEntry] {
&self.entries
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SlashCommandResult {
pub message: String,
pub session: Session,
}
#[must_use]
pub fn handle_slash_command(
input: &str,
session: &Session,
compaction: CompactionConfig,
) -> Option<SlashCommandResult> {
let trimmed = input.trim();
if !trimmed.starts_with('/') {
return None;
}
match trimmed.split_whitespace().next() {
Some("/compact") => {
let result = compact_session(session, compaction);
let message = if result.removed_message_count == 0 {
"Compaction skipped: session is below the compaction threshold.".to_string()
} else {
format!(
"Compacted {} messages into a resumable system summary.",
result.removed_message_count
)
};
Some(SlashCommandResult {
message,
session: result.compacted_session,
})
}
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::handle_slash_command;
use runtime::{CompactionConfig, ContentBlock, ConversationMessage, MessageRole, Session};
#[test]
fn compacts_sessions_via_slash_command() {
let session = Session {
version: 1,
messages: vec![
ConversationMessage::user_text("a ".repeat(200)),
ConversationMessage::assistant(vec![ContentBlock::Text {
text: "b ".repeat(200),
}]),
ConversationMessage::tool_result("1", "bash", "ok ".repeat(200), false),
ConversationMessage::assistant(vec![ContentBlock::Text {
text: "recent".to_string(),
}]),
],
};
let result = handle_slash_command(
"/compact",
&session,
CompactionConfig {
preserve_recent_messages: 2,
max_estimated_tokens: 1,
},
)
.expect("slash command should be handled");
assert!(result.message.contains("Compacted 2 messages"));
assert_eq!(result.session.messages[0].role, MessageRole::System);
}
#[test]
fn ignores_unknown_slash_commands() {
let session = Session::new();
assert!(handle_slash_command("/unknown", &session, CompactionConfig::default()).is_none());
}
}