Custom Commands
Custom commands allow you to define reusable operations using TOML configuration files. Commands support template substitution, shell execution, file injection, and integration with the sandbox and hook systems.
Overviewβ
Custom commands provide:
- TOML-based definitions: Easy to create and maintain
- Template substitution: Dynamic content generation
- Shell command execution: Run shell commands safely
- File content injection: Include file contents in output
- Sandbox integration: Safe command execution
- Hook integration: Approval/denial workflows
Command Definitionβ
Commands are defined in TOML files located in:
- Project commands:
.radium/commands/*.toml - User commands:
~/.radium/commands/*.toml - Extension commands: Extension-specific directories
Basic Command Structureβ
[command]
name = "command-name"
description = "Command description"
template = "Command template with {{args}} and !{shell} and @{file}"
Example: Simple Commandβ
[command]
name = "hello"
description = "Say hello"
template = "Hello, {{arg1}}!"
Template Substitutionβ
Commands support three types of template substitution:
Argument Substitutionβ
Arguments are substituted using {{args}} or {{arg1}}, {{arg2}}, etc.
[command]
name = "greet"
description = "Greet someone"
template = "Hello {{arg1}}, you said: {{args}}"
args = ["name", "message"]
Usage:
rad custom greet "Alice" "Welcome!"
# Output: Hello Alice, you said: Alice Welcome!
Shell Command Executionβ
Shell commands are executed using !{command} syntax:
[command]
name = "git-status"
description = "Show git status"
template = "Git Status:\n!{git status}"
The shell command output replaces the !{command} placeholder.
File Content Injectionβ
File contents are injected using @{file} syntax:
[command]
name = "show-readme"
description = "Display README"
template = "# README\n\n@{README.md}"
Files are resolved relative to the command's base directory.
Combined Templateβ
You can combine all substitution types:
[command]
name = "build-report"
description = "Generate build report"
template = "Building {{arg1}}...\n!{cargo build --release}\n\nNotes:\n@{notes.md}"
Command Discoveryβ
Commands are discovered from multiple locations with precedence:
- Project commands (
.radium/commands/) - Highest precedence - User commands (
~/.radium/commands/) - Medium precedence - Extension commands - Lowest precedence
Namespaced Commandsβ
Commands can be organized in namespaces using subdirectories:
.radium/commands/
git/
status.toml
commit.toml
build/
test.toml
release.toml
Namespaced commands are referenced as namespace:command-name:
rad custom git:status
rad custom build:test
Command Executionβ
Via CLIβ
# List all commands
rad custom list
# Execute a command
rad custom command-name arg1 arg2
# Execute namespaced command
rad custom namespace:command-name arg1
Programmaticallyβ
use radium_core::commands::custom::CustomCommand;
// Load command
let command = CustomCommand::load("command-name")?;
// Execute with arguments
let output = command.execute(&["arg1", "arg2"], &workspace_root)?;
Sandbox Integrationβ
Commands can execute within a sandbox for security:
use radium_core::sandbox::{Sandbox, SandboxConfig};
let mut sandbox = Sandbox::new(&SandboxConfig::default())?;
let output = command.execute_with_sandbox(
&args,
&workspace_root,
Some(&mut sandbox)
)?;
Sandbox Configurationβ
Configure sandbox behavior in .radium/config.toml:
[sandbox]
enabled = true
network_enabled = false
allow_write = true
Hook Integrationβ
Commands integrate with the hook system for approval workflows:
use radium_core::hooks::registry::HookRegistry;
let registry = Arc::new(HookRegistry::new());
let output = command.execute_with_hooks(
&args,
&workspace_root,
Some(registry)
).await?;
Hook Approval Flowβ
- Tool Selection Hook: Approve or deny command execution
- Before Tool Hook: Modify arguments before execution
- After Tool Hook: Modify output after execution
If a hook denies execution, the command fails with a ToolDenied error.
Examplesβ
Example: Git Status Commandβ
[command]
name = "git-status"
description = "Show git status with context"
template = "# Git Status\n\n!{git status}\n\n# Recent Commits\n\n!{git log --oneline -5}"
Usage:
rad custom git-status
Example: Test Command with Argumentsβ
[command]
name = "test"
description = "Run tests with filter"
template = "Running tests for {{arg1}}...\n\n!{cargo test --lib {{arg1}}}"
args = ["filter"]
Usage:
rad custom test "my_module"
Example: Documentation Commandβ
[command]
name = "docs"
description = "Show project documentation"
template = "# Project Documentation\n\n@{README.md}\n\n## API Reference\n\n@{docs/API.md}"
Usage:
rad custom docs
Best Practicesβ
Command Organizationβ
- Use namespaces for related commands
- Keep command templates simple and readable
- Document commands with clear descriptions
Securityβ
- Use sandbox for untrusted commands
- Configure hooks to approve/deny dangerous operations
- Validate arguments before execution
Performanceβ
- Avoid long-running commands in templates
- Cache expensive operations
- Use file injection for large static content
Troubleshootingβ
Command Not Foundβ
- Verify command file exists in
.radium/commands/ - Check command name matches file name (without .toml)
- Verify workspace is initialized
Template Substitution Failsβ
- Check argument count matches template placeholders
- Verify file paths are correct (relative to workspace root)
- Ensure shell commands are available in PATH
Sandbox Issuesβ
- Verify sandbox is enabled in config
- Check sandbox permissions allow required operations
- Review sandbox logs for blocked operations
Hook Denialβ
- Check hook configuration
- Review hook logs for denial reasons
- Verify command matches hook approval criteria