agent_core/tui/commands/registry.rs
1//! Command registry for managing slash commands.
2
3use super::standard::default_commands;
4use super::traits::SlashCommand;
5
6/// Registry of slash commands for an agent.
7///
8/// Provides a builder-style API for configuring which commands are available.
9///
10/// # Example
11///
12/// ```ignore
13/// use agent_core::tui::commands::{
14/// CommandRegistry, CustomCommand, CommandResult,
15/// HelpCommand, ClearCommand, ThemesCommand,
16/// };
17///
18/// // Start with defaults and customize
19/// let commands = CommandRegistry::with_defaults()
20/// .add(CustomCommand::new("deploy", "Deploy the app", |args, ctx| {
21/// CommandResult::Message(format!("Deploying to {}...", args))
22/// }))
23/// .remove("quit") // Disable quit command
24/// .build();
25///
26/// // Or build from scratch
27/// let commands = CommandRegistry::new()
28/// .add(HelpCommand)
29/// .add(ClearCommand)
30/// .add(ThemesCommand)
31/// .build();
32/// ```
33pub struct CommandRegistry {
34 commands: Vec<Box<dyn SlashCommand>>,
35}
36
37impl CommandRegistry {
38 /// Create an empty registry with no commands.
39 pub fn new() -> Self {
40 Self {
41 commands: Vec::new(),
42 }
43 }
44
45 /// Create a registry with the default commands.
46 ///
47 /// Default commands include: help, clear, compact, themes, sessions,
48 /// status, version, new-session, and quit.
49 pub fn with_defaults() -> Self {
50 Self {
51 commands: default_commands(),
52 }
53 }
54
55 /// Add a command to the registry.
56 ///
57 /// # Example
58 ///
59 /// ```ignore
60 /// registry.add(ClearCommand).add(HelpCommand);
61 /// ```
62 pub fn add<C: SlashCommand + 'static>(mut self, command: C) -> Self {
63 self.commands.push(Box::new(command));
64 self
65 }
66
67 /// Add a boxed command to the registry.
68 ///
69 /// Use this when you already have a `Box<dyn SlashCommand>`.
70 pub fn add_boxed(mut self, command: Box<dyn SlashCommand>) -> Self {
71 self.commands.push(command);
72 self
73 }
74
75 /// Remove a command by name.
76 ///
77 /// # Example
78 ///
79 /// ```ignore
80 /// // Disable the quit command
81 /// registry.remove("quit");
82 /// ```
83 pub fn remove(mut self, name: &str) -> Self {
84 self.commands.retain(|c| c.name() != name);
85 self
86 }
87
88 /// Build into the final command list.
89 ///
90 /// Consumes the registry and returns the commands.
91 pub fn build(self) -> Vec<Box<dyn SlashCommand>> {
92 self.commands
93 }
94
95 /// Get commands as a slice (for inspection without consuming).
96 pub fn commands(&self) -> &[Box<dyn SlashCommand>] {
97 &self.commands
98 }
99}
100
101impl Default for CommandRegistry {
102 fn default() -> Self {
103 Self::with_defaults()
104 }
105}