Commands System
Overview
The commands system provides ~85 slash commands for user interaction. Commands are invoked with /command syntax in the terminal interface.
Command Structure
src/commands/
├── commitCommand.ts - Git commit automation
├── mcpCommand.ts - MCP server management
├── memoryCommand.ts - Memory management
├── reviewCommand.ts - Code review automation
├── [85+ command files]
└── index.ts - Command registry
Command Registration Pattern
All commands follow a consistent registration pattern:
// Example: commitCommand.ts
import { buildCommand } from '../commands.js';
export const commitCommand = buildCommand({
name: 'commit',
description: 'Create a git commit with AI assistance',
parameters: z.object({
message: z.string().optional(),
amend: z.boolean().optional(),
}),
async handler(args, context) {
// Command execution logic
await performCommit(args, context);
},
});
Command Categories
Version Control Commands
/commit- Create git commits/diff- Show file differences/status- Git status overview
MCP Commands
/mcp add- Add MCP server/mcp list- List MCP servers/mcp remove- Remove MCP server
Memory Commands
/memory add- Add to memory/memory list- List memory entries/memory clear- Clear memory
Debugging Commands
/debug- Enable debug mode/profile- Performance profiling
System Commands
/help- Display help/tips- Show usage tips/version- Show version info
Command Execution Flow
1. User types /command [args]
2. Command system parses input
3. Parameters validated against schema
4. handler() executes command logic
5. Result displayed to user
6. State updated (if applicable)
Command Discovery
Commands are discovered and registered via:
// src/commands.ts
export function getCommands(): Command[] {
const commands: Command[] = [];
commands.push(commitCommand);
commands.push(mcpCommand);
commands.push(memoryCommand);
// ... all other commands
return commands;
}
Command Best Practices
- Schema Validation: Zod schemas for strict parameter validation
- Consistent Interface: All commands use buildCommand()
- Error Handling: Graceful degradation on failures
- State Management: Commands can update app state
- UI Integration: Commands can trigger UI components
Command Examples
Git Commit Command
export const commitCommand = buildCommand({
name: 'commit',
description: 'Create a git commit with AI assistance',
parameters: z.object({
message: z.string().optional().describe('Commit message'),
amend: z.boolean().optional().describe('Amend last commit'),
}),
async handler(args, context) {
// Stage changes
await execGitCommand('git add .');
// Create commit
const msg = args.message || 'Auto-commit';
const flag = args.amend ? '--amend' : '';
await execGitCommand(`git commit -m "${msg}" ${flag}`);
// Update state
context.setAppState(prev => ({
...prev,
lastCommitMessage: msg,
}));
},
});
MCP Add Command
export const mcpAddCommand = buildCommand({
name: 'mcp add',
description: 'Add an MCP server configuration',
parameters: z.object({
name: z.string().describe('Server name'),
command: z.string().describe('Server command'),
}),
async handler(args, context) {
const serverConfig = {
name: args.name,
command: args.command,
};
// Add to MCP configuration
await addMcpServer(serverConfig);
// Refresh MCP clients
await refreshMcpClients();
},
});
Command Filtering
Commands can be filtered for specific contexts:
// Filter commands for remote mode
export function filterCommandsForRemoteMode(commands: Command[]): Command[] {
return commands.filter(cmd =>
!cmd.name.startsWith('local-')
);
}
Command Best Practices
- Modular Design: Each command is self-contained
- Parameter Validation: Strict schema enforcement
- State Updates: Commands can modify app state
- Error Recovery: Graceful handling of failures
- UI Feedback: Commands provide visual feedback
Security Considerations
- Permission Checks: Commands respect permission modes
- Working Directory: Commands respect cwd restrictions
- Feature Flags: Conditional command availability
- Lazy Loading: Heavy commands loaded on demand
- Error Boundaries: Isolated failure handling
Command Discovery Mechanism
Commands are auto-discovered from the commands directory:
// Automatic command loading
const commandFiles = glob('src/commands/*.ts');
for (const file of commandFiles) {
const command = require(file).default;
commands.push(command);
}
Command Integration with Tools
Commands can invoke tools:
async handler(args, context) {
// Invoke a tool from within a command
const result = await context.tools.find(t => t.name === 'BashTool')
.call({ command: 'git status' }, context);
// Display result
context.setAppState(prev => ({
...prev,
commandOutput: result,
}));
}