Comprehensive architecture guide for the coding-agent CLI
The CLI (coding-agent-cli) is a conversational REPL interface that makes AI-assisted coding natural and transparent. Built on design principles of transparency, minimal friction, clean aesthetics, progressive disclosure, workflow-native integration, and self-healing.
The CLI follows a layered architecture where each layer has clear responsibilities:
┌─────────────────────────────────────────────────────────────┐
│ User Interface Layer │
│ (Terminal I/O, Spinners, Context Bar, Status Bar) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ REPL Orchestration │
│ (Input Handling, Command Routing, Conversation Flow) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Agent Layer │
│ (AgentManager, FixAgent, Tool Execution, Self-Healing) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Integration Layer │
│ (SpecStory, Git, Obsidian, Claude API) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ Core State Machine │
│ (coding-agent-core: Pure state transitions) │
└─────────────────────────────────────────────────────────────┘
crates/
├── coding-agent-core/ # State machine (shared library)
└── coding-agent-cli/ # Terminal application
└── src/
├── main.rs # Entry point, panic handler
├── cli/ # REPL orchestration
│ ├── repl.rs # Main REPL loop
│ ├── startup.rs # Welcome screen
│ ├── input.rs # Multi-line input, double-enter
│ ├── terminal.rs # Raw mode management
│ ├── output.rs # Formatted output
│ └── commands/ # Slash command registry
│ ├── mod.rs # Command trait & registry
│ ├── help.rs # /help
│ ├── clear.rs # /clear (reset context)
│ ├── status.rs # /status (active agents)
│ ├── config.rs # /config
│ ├── cost.rs # /cost (token breakdown)
│ ├── context.rs # /context
│ ├── commit.rs # /commit (smart git)
│ ├── diff.rs # /diff
│ ├── undo.rs # /undo
│ ├── spec.rs # /spec (planning mode)
│ ├── document.rs # /document (Obsidian)
│ └── model.rs # /model (switch AI model)
├── ui/ # Visual components
│ ├── theme.rs # Color definitions
│ ├── spinner.rs # Animated spinners
│ ├── thinking.rs # Thinking messages
│ ├── fun_facts.rs # Long-wait entertainment
│ ├── context_bar.rs # Token usage visualization
│ ├── status_bar.rs # Multi-agent progress
│ ├── progress.rs # Progress bars
│ ├── syntax.rs # Code syntax highlighting
│ └── components.rs # Reusable UI pieces
├── agents/ # Multi-agent orchestration
│ ├── manager.rs # Spawn, track, cancel agents
│ ├── status.rs # Agent state machine
│ └── fix_agent.rs # Self-healing agent
├── tools/ # Tool execution pipeline
│ ├── executor.rs # Run tools with retries
│ ├── recovery.rs # Error recovery strategies
│ ├── diagnostics.rs # Parse error messages
│ └── definitions.rs # Tool schemas for Claude
├── permissions/ # Permission system
│ ├── trusted.rs # Trusted path logic
│ ├── checker.rs # Permission checking
│ └── prompt.rs # Interactive prompts
├── integrations/ # External services
│ ├── specstory.rs # Session persistence
│ ├── git.rs # Git operations
│ └── obsidian.rs # Obsidian vault
├── tokens/ # Token tracking
│ ├── counter.rs # tiktoken-rs wrapper
│ ├── pricing.rs # Cost calculation
│ └── context.rs # Context window mgmt
└── config/ # Configuration
└── settings.rs # ~/.config/coding-agent/
The CLI orchestrates an event-driven state machine from coding-agent-core:
- State machine is pure - No I/O, synchronous, deterministic
- CLI executes actions - API calls, tool execution, file operations
- Six states: WaitingForUserInput → CallingLlm → ProcessingLlmResponse → ExecutingTools → Error → ShuttingDown
- Bounded retries - Exponential backoff (1s, 2s, 3s) with max 3 retries
Slash commands follow a trait-based extensible pattern:
pub trait Command {
fn name(&self) -> &str;
fn description(&self) -> &str;
fn execute(&self, args: &str, ctx: &mut CommandContext) -> Result<()>;
}
pub struct CommandContext<'a> {
pub repl: &'a mut Repl,
pub agent_manager: Arc<AgentManager>,
pub session: &'a mut Session,
pub config: &'a Config,
}Commands register themselves in CommandRegistry on startup. Adding new commands requires implementing the trait and registering in mod.rs.
The AgentManager coordinates parallel agent execution:
- Spawn agents - Background tasks for self-healing, search, refactoring
- Track state - queued → running → complete/failed
- Display progress - Status bar updates in real-time
- Cancel agents - User can abort long-running operations
Tool execution includes automatic error recovery:
Tool Call → ToolExecutor → Error? → Categorize
│
├─ Code Error → FixAgent
├─ Network Error → Retry with backoff
├─ Permission Error → Prompt user
└─ Resource Error → Suggest alternatives
Three-tier permission model:
- Trusted paths - Auto-approved (from config)
- Interactive prompts - Y/n/Always/Never for untrusted writes
- Session cache - Decisions remembered during session
All long-running operations provide real-time feedback:
- Spinners - Tool execution progress
- Progress bars - Multi-step operations
- Thinking messages - Rotated during API calls
- Fun facts - Displayed after 10+ second waits
- Context bar - Token usage updated after each exchange
main.rs
│
├─► Install panic handler (ensure terminal cleanup)
├─► Load config from ~/.config/coding-agent/config.toml
├─► Load .env for ANTHROPIC_API_KEY
│
▼
cli::run()
│
├─► Terminal::enable_raw_mode()
│ └─► Drop guard ensures restoration on panic/exit
│
├─► StartupScreen::show()
│ ├─ Display ASCII logo
│ ├─ [n] New session
│ ├─ [r] Resume last ──► SessionManager::load_last()
│ │ └─► Parse .specstory/history/<session>.md
│ ├─ [h] Help
│ └─ [c] Config
│
├─► Repl::new(config)
│ ├─ Initialize SessionManager
│ ├─ Initialize TokenCounter (tiktoken-rs)
│ ├─ Initialize AgentManager (Arc for sharing)
│ ├─ Initialize ToolExecutor (with retry logic)
│ ├─ Initialize PermissionChecker (trusted paths)
│ ├─ Initialize ContextBar
│ ├─ Initialize CommandRegistry
│ └─ Load conversation history if resuming
│
└─► Repl::run() (main loop)
loop {
┌─────────────────────────────────────────────┐
│ 1. Display Context Bar │
│ - Show token usage at bottom of screen │
│ - Color-coded: green/yellow/red │
└─────────────────────────────────────────────┘
│
┌──────────────────▼──────────────────────────┐
│ 2. Display Status Bar (if agents active) │
│ - Show running agents with progress │
│ - Update in real-time │
└─────────────────────────────────────────────┘
│
┌──────────────────▼──────────────────────────┐
│ 3. Read User Input │
│ - InputHandler::read_input() │
│ - Multi-line with double-enter submit │
│ - Ctrl+C clears, Ctrl+D exits │
└─────────────────────────────────────────────┘
│
┌────────▼────────┐
│ Slash command? │
└────────┬────────┘
Yes │ │ No
┌───────────▼ ▼───────────────┐
│ │
┌───▼────────────────────┐ ┌──────────▼────────────┐
│ CommandRegistry:: │ │ Process as message │
│ execute() │ │ to Claude │
│ │ └──────────┬────────────┘
│ - Parse command & args │ │
│ - Look up in registry │ ┌──────────▼────────────┐
│ - Execute with context │ │ Add to conversation │
└────────────────────────┘ │ history │
│ │
│ Call Claude API │
│ (ureq HTTP client) │
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Process response │
│ │
│ Text? → Display │
│ Tool call? → Execute │
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Tool Execution │
│ (if tool calls) │
│ │
│ - ToolExecutor:: │
│ execute() │
│ - Show spinner │
│ - Check permissions │
│ - Run tool │
│ - Handle errors │
│ - Return result │
│ │
│ Send results back │
│ to Claude │
└──────────┬────────────┘
│
┌──────────▼────────────┐
│ Update State │
│ │
│ - Count tokens │
│ - Update context bar │
│ - Save session │
│ (.specstory/) │
└───────────────────────┘
│
│
} ←────────────────────────────────────┘
The InputHandler operates in terminal raw mode (via crossterm):
Key Bindings:
- Enter - Add newline to buffer
- Enter + Enter - Submit input
- Ctrl+C - Clear current input buffer
- Ctrl+D - Exit REPL
- Backspace - Remove last character
Raw Mode Details:
- All input processed character-by-character
\nonly moves cursor down, must use\r\nfor proper newline- Terminal restored on drop via RAII guard (handles panics)
- Panic handler installed to ensure cleanup
Multi-line Input:
- Buffer accumulates characters and newlines
- Double consecutive Enter triggers submission
- Cursor tracking for proper display in raw mode
Command Categories:
| Category | Commands | Purpose |
|---|---|---|
| Navigation | /help, /clear, /exit, /status |
REPL control |
| Code & Files | /undo, /diff, /context |
File operations |
| Git | /commit, /commit --pick |
Smart git integration |
| Workflow | /model, /cost, /spec, /document |
Productivity tools |
| Session | /history, /config |
Session management |
Key Commands:
/clear- Saves session first, then resets conversation context and clears display/commit- Agent analyzes changes, groups related files, generates purpose-focused message/status- Shows active agents, running tools, current operations/cost- Detailed token breakdown with pricing by model
Architecture:
// Claude API call via ureq (synchronous HTTP)
let response = ureq::post("https://api.anthropic.com/v1/messages")
.set("x-api-key", &api_key)
.set("anthropic-version", "2023-06-01")
.send_json(request)?;Request Flow:
- Build request with conversation history
- Include available tools (read, write, edit, list, bash, search)
- Send to Claude API via
ureq - Parse response (text or tool calls)
- Execute tools if requested
- Send tool results back to Claude
- Repeat until final text response
Environment:
- Requires
ANTHROPIC_API_KEYin environment or.env - Auto-loads via
dotenvycrate on startup - API key never logged or displayed
Available Tools:
| Tool | Purpose | Permission |
|---|---|---|
read_file |
Read file contents | Always allowed |
write_file |
Create/overwrite files | Requires permission |
edit_file |
Targeted file edits | Requires permission |
list_files |
Directory listing | Always allowed |
bash |
Execute shell commands | Requires permission |
code_search |
Search via ripgrep | Always allowed |
Execution Flow:
Tool Request from Claude
│
▼
ToolExecutionSpinner::start()
│
▼
PermissionChecker::check() ──► Untrusted? ──► Prompt user
│ │
│ Trusted/Approved │
│ ◄───────────────────────────────────────────┘
▼
ToolExecutor::execute()
│
├─► Success ──► finish_success()
│
└─► Error ──► Categorize ──► Auto-fixable? ──► FixAgent::spawn()
│
│ Fixed?
│
└─► Retry original tool
Error Categories:
| Category | Strategy |
|---|---|
| Code Error | Spawn FixAgent to diagnose and repair |
| Network Error | Retry with exponential backoff |
| Permission Error | Prompt user for permission |
| Resource Error | Suggest alternatives |
FixAgent Flow:
1. Detect code error (e.g., missing dependency, syntax error)
2. Spawn FixAgent with error context
3. FixAgent analyzes error message
4. Generate fix (e.g., add to Cargo.toml, fix import)
5. Apply fix to codebase
6. Generate regression test
7. Verify fix compiles/passes tests
8. Retry original operation
9. Report success/failure to user
Auto-Fixes:
- Missing dependency → Add to
Cargo.tomlorpackage.json - Missing import → Add import statement
- Type mismatch → Suggest type annotation
- Syntax error → Attempt correction
Format:
Conversations saved as markdown in .specstory/history/:
---
title: Adding auth flow
created: 2024-02-13T14:30:00Z
updated: 2024-02-13T15:45:00Z
model: claude-3-opus
version: 1
---
# Adding auth flow
## User
How do I add authentication?
## Agent
Here's how to implement auth...Operations:
- Auto-save - After each message exchange
- Load - Parse markdown back to conversation
- List - Show all sessions with metadata
- Resume - Restore full conversation context
Implementation:
- Uses
tiktoken-rswithcl100k_basetokenizer (Claude-compatible) - Counts tokens for all messages in conversation
- Adds overhead: +4 tokens per message, +3 tokens system overhead
- Cached globally via
OnceLockfor performance
Context Bar:
Context: ████████████░░░░░░░░░░░░░░░░░░ 38% │ 76k / 200k
- Position: Bottom of screen, always visible
- Color-coded: Green (0-60%), Yellow (60-85%), Red (85%+)
- Updates after each message exchange
Trusted Paths:
Configured in ~/.config/coding-agent/config.toml:
[permissions]
trusted_paths = [
"/Users/username/coding-agent",
"~/Documents/Personal/",
]Permission Prompt:
Write to untrusted path: /tmp/test.txt
Allow this operation?
[y] Yes, this time
[n] No
[a] Always for this path
[v] Never
Behavior:
- "Always" - Adds to
trusted_pathsin config - "Never" - Caches denial for session
- Read operations - Always allowed everywhere
Displayed above input when agents are active:
┌─────────────────────────────────────────────┐
│ AGENTS ─────────────────────────────────── │
│ ● search-agent Searching... ██░░ │
│ ● refactor-agent Analyzing... ███░ │
│ ○ test-agent Queued │
└─────────────────────────────────────────────┘
States:
- ○ Queued - Waiting to start
- ● Running - Active with progress bar
- ✓ Complete - Successfully finished
- ✗ Failed - Error state
Smart Commits:
/commit flow:
1. Read git status (staged/unstaged changes)
2. Group related files (same dir, test+impl, etc.)
3. Analyze changes to understand purpose
4. Generate 3-sentence commit message focused on "why"
5. Show preview, allow edit
6. Commit with message
File Grouping Logic:
- Files in same directory → group together
- Test files + implementation → group together
- Unrelated changes → suggest separate commits
Commit Message Style:
Add JWT token validation to login flow
Users can now stay logged in across sessions with
secure token refresh. This improves UX by eliminating
repeated login prompts.
Operations:
- Search vault - Find notes by content
- Create note - Suggest location, generate template
- Update note - Show diff, apply changes
- Link notes - Add backlinks and metadata
Vault Path:
Configured in ~/.config/coding-agent/config.toml:
[integrations.obsidian]
vault_path = "~/Documents/Personal/"Location: ~/.config/coding-agent/config.toml
Full Configuration:
[permissions]
trusted_paths = [
"/Users/username/coding-agent",
"~/Documents/Personal/",
]
auto_read = true
[model]
default = "claude-3-opus"
available = ["claude-3-opus", "claude-3-sonnet"]
context_window = 200000
[theme]
style = "minimal" # minimal | colorful | monochrome
[persistence]
enabled = true
format = "specstory"
path = ".specstory/history/"
[behavior]
streaming = true
tool_verbosity = "standard" # minimal | standard | verbose
show_context_bar = true
fun_facts = true
fun_fact_delay = 10 # seconds
[fun_facts_api]
enabled = true
sources = ["uselessfacts", "jokes", "quotes"]
cache_size = 100
refresh_interval = 3600
[error_recovery]
auto_fix = true
generate_tests = true
max_retry_attempts = 3
[integrations.obsidian]
vault_path = "~/Documents/Personal/"
[integrations.git]
auto_stage = false
commit_style = "purpose" # purpose | conventional | simpleColors centralized in ui/theme.rs:
| Element | Color | Purpose |
|---|---|---|
| User input | White | Neutral |
| Agent response | Cyan | Distinguish from user |
| Tool calls | Yellow | Action happening |
| Success | Green | Completion |
| Error | Red | Problems |
| Warning | Orange | Caution |
| Muted/secondary | Gray | Less important |
| Cost/tokens | Magenta | Resource usage |
| Context bar | Green→Yellow→Red | Usage level |
Accessibility:
- Respects
NO_COLORenvironment variable - Falls back to plain text if colors unsupported
Core:
| Crate | Purpose |
|---|---|
ureq |
HTTP client for Claude API |
dotenvy |
Load .env files |
serde + serde_json |
Serialization |
toml |
Config file parsing |
Terminal & UI:
| Crate | Purpose |
|---|---|
crossterm |
Cross-platform terminal control |
console |
Terminal styling |
indicatif |
Spinners, progress bars |
syntect |
Syntax highlighting |
Tools & Integrations:
| Crate | Purpose |
|---|---|
walkdir |
Directory traversal |
git2 |
Git operations |
tiktoken-rs |
Token counting |
Async:
| Crate | Purpose |
|---|---|
tokio |
Async runtime (for future streaming) |
reqwest |
Async HTTP (for fun facts API) |
- Simpler control flow in REPL
- Easier error handling
ureqis lightweight and sufficient- Can add async/streaming later without major refactor
- Full control over input handling
- Enables double-enter submission
- Enables multi-line input buffer
- Better UX than line-buffered input
- Human-readable markdown
- Version controllable
- No database required
- Easy to backup/sync
- Searchable with standard tools
- Easy to extend
- Type-safe
- Compile-time guarantees
- No runtime reflection needed
- Enables parallel execution
- Clear cancellation model
- Progress tracking
- Future: distributed agents
Unit Tests:
- Pure functions (token counting, parsing)
- Config loading/saving
- Command parsing
- Error categorization
Integration Tests:
- Git operations (commit, status, diff)
- SpecStory save/load
- Permission checking
- Tool execution
End-to-End Tests:
- Full REPL sessions (PTY-based with
expectrl) - Mock Claude API (with
wiremock) - Terminal output snapshots (with
insta)
The AgentManager orchestrates multiple background agents that can run in parallel to handle complex tasks.
Agent States:
Queued → Running → Complete
↓
Failed
Agent Lifecycle:
-
Creation - Agent spawned via
AgentManager::spawn_agent()- Receives unique ID and configuration
- Added to active agents map
- Initial state:
Queued
-
Execution - Moved to
Runningstate- Assigned to tokio task
- Progress updates sent to manager
- Can be cancelled by user
-
Completion - Final state transition
- Success →
Completewith result - Error →
Failedwith error details - Removed from active agents after display
- Success →
Coordination:
- Parallel Execution - Multiple agents run concurrently via tokio
- Status Tracking -
AgentManager::get_all_statuses()provides snapshot - Progress Updates - Agents report progress percentage (0-100)
- Cancellation -
AgentManager::cancel_agent(id)stops running agent - Result Aggregation - Results collected from completed agents
Integration Points:
/statuscommand queries manager for display- StatusBar polls manager for UI updates
- FixAgent uses manager for spawning sub-agents
- REPL waits for agent completion before proceeding
The system implements multi-layered error recovery to handle failures gracefully.
Error Categorization:
pub enum ErrorCategory {
Code, // Missing deps, syntax errors, type errors
Network, // API timeouts, connection failures
Permission, // Access denied, insufficient permissions
Resource, // Disk full, memory exhausted, file not found
}Recovery Pipeline:
Tool Execution → Error Detected → Categorize
│
┌─────────────────────────────┼─────────────────────────────┐
│ │ │
Code Error Network Error Permission Error
│ │ │
▼ ▼ ▼
FixAgent::spawn() Retry with backoff PermissionPrompt
│ │ │
Diagnose error Attempt 1 (1s delay) User decision
│ │ │
Generate fix Attempt 2 (2s delay) [y] Allow once
│ │ [n] Deny
Apply fix Attempt 3 (3s delay) [a] Always (→ config)
│ │ [v] Never (→ cache)
Generate test Give up if all fail │
│ │ │
Verify fix │ │
│ │ │
└─────────────────────────────┴─────────────────────────────┘
│
▼
Retry Original Operation
│
┌───────┴────────┐
│ │
Success Failed
│ │
Report OK Report Error
FixAgent Workflow:
-
Detection -
ToolError::is_auto_fixable()returns true -
Analysis - Parse error message with
DiagnosticsParser- Extract error type (missing dep, import, etc.)
- Identify file and location
- Determine fix strategy
-
Fix Generation - Create fix based on error type
- Missing dependency: Add to
Cargo.tomlorpackage.json - Missing import: Insert import statement
- Type mismatch: Suggest type annotation
- Syntax error: Apply correction
- Missing dependency: Add to
-
Application - Apply fix to codebase
- Write file changes
- Verify syntax correctness
- Preserve formatting
-
Test Generation - Create regression test
- Test that fix resolves issue
- Prevent future recurrence
- Written to
tests/auto_fix/
-
Verification - Ensure fix works
- Re-run compiler/tests
- Verify no new errors introduced
- Confirm original operation now succeeds
-
Retry - Re-execute original tool
- Use same parameters
- Report success or new error
Retry Logic:
- Exponential Backoff: 1s, 2s, 3s delays between attempts
- Max Attempts: 3 retries before giving up
- Transient Only: Only network/resource errors retry automatically
- User Feedback: Show attempt number and delay to user
Loop Prevention:
- Track fix attempts per error
- Max 2 fix attempts per unique error
- Detect if fix introduces same error
- Abort if no progress after fix
The tool execution system provides a robust framework for running Claude's tool calls with error handling, retries, and progress feedback.
Pipeline Stages:
1. Tool Request (from Claude)
│
▼
2. Parse & Validate
- Extract tool name
- Parse input JSON
- Validate schema
│
▼
3. Permission Check
- Read operations → Allow
- Write operations → Check trusted paths
- Untrusted → Prompt user
│
▼
4. Spinner Start
- Show tool name + target
- Begin elapsed time tracking
│
▼
5. Execute Tool Function
- Call tool implementation
- Handle tool-specific errors
- Capture output
│
▼
6. Error Handling
- Success → Format result
- Error → Categorize & recover
│
▼
7. Spinner Finish
- Show success/failure
- Display elapsed time
- Log result
│
▼
8. Return Result
- Send back to Claude
- Update conversation history
Tool Registration:
// In ToolExecutor initialization
executor.register_tool("read_file", read_file_tool);
executor.register_tool("write_file", write_file_tool);
executor.register_tool("edit_file", edit_file_tool);
executor.register_tool("list_files", list_files_tool);
executor.register_tool("bash", bash_tool);
executor.register_tool("code_search", code_search_tool);Execution with Context:
pub struct ToolExecutionResult {
pub tool_id: String,
pub tool_name: String,
pub result: Result<String, ToolError>,
pub duration: Duration,
pub retry_count: u32,
}
impl ToolExecutor {
pub fn execute(
&self,
id: String,
name: &str,
input: Value,
) -> ToolExecutionResult {
let start = Instant::now();
let mut retry_count = 0;
loop {
match self.run_tool(name, &input) {
Ok(output) => {
return ToolExecutionResult {
tool_id: id,
tool_name: name.to_string(),
result: Ok(output),
duration: start.elapsed(),
retry_count,
};
}
Err(error) if error.is_retryable() && retry_count < MAX_RETRIES => {
retry_count += 1;
thread::sleep(exponential_backoff(retry_count));
continue;
}
Err(error) => {
return ToolExecutionResult {
tool_id: id,
tool_name: name.to_string(),
result: Err(error),
duration: start.elapsed(),
retry_count,
};
}
}
}
}
}Integration with REPL:
The REPL integrates the tool pipeline in process_conversation():
- Receive tool call from Claude response
- Create
ToolExecutionSpinnerfor visual feedback - Call
ToolExecutor::execute()with tool details - Handle result (success or error)
- For errors, trigger error recovery if applicable
- Send result back to Claude for next turn
- Update context bar with token usage
Performance Considerations:
- Lazy Loading - Tools loaded on first use
- Result Caching - Identical reads cached per session
- Parallel Execution - Independent tools can run concurrently
- Timeout Protection - Long-running tools have configurable timeouts
Completed Integration (Phase 14.1-14.6):
All advanced features have been fully integrated into the main execution flow:
-
AgentManager - Fully integrated into REPL as
Arc<AgentManager>- Spawns and tracks background agents
- Accessible from all commands via
CommandContext - Powers
/statuscommand for live agent monitoring
-
Permission System - Activated with interactive prompts
PermissionPromptwired intoPermissionChecker- "Always" responses update config file automatically
- "Never" responses cached per session
- Seamless integration with all write operations
-
ToolExecutor - Centralized tool execution with retry logic
- Replaces ad-hoc tool execution
- Automatic retry for transient errors (network, etc.)
- Exponential backoff: 1s, 2s, 3s (max 3 attempts)
-
ToolExecutionSpinner - Enhanced visual feedback
- Shows tool name and target (e.g., "Reading src/main.rs...")
- Displays success/failure with elapsed time
- Replaces simple "● Running..." messages
-
FixAgent - Automatic error diagnosis and repair
- Spawned for auto-fixable code errors
- Analyzes compiler/runtime errors
- Applies fixes (missing deps, imports, etc.)
- Generates regression tests
- Retries original operation after fix
-
Error Categorization - Intelligent error routing
- Code errors → FixAgent
- Network errors → Retry with backoff
- Permission errors → Interactive prompt
- Resource errors → Alternative suggestions
-
StatusBar - Multi-agent progress visualization
- Displays above input when agents active
- Real-time progress bars for each agent
- States: Queued, Running, Complete, Failed
-
LongWaitDetector - Entertainment during delays
- Monitors operation duration
- Triggers fun facts after 10s threshold
- Configurable via
fun_fact_delaysetting
-
ToolResultFormatter - Enhanced result display
- Syntax highlighting for code in results
- Collapsible sections for long outputs
- Line numbers for file reads
-
FileGrouper - Intelligent commit grouping
- Groups related files (same dir, test+impl)
- Suggests logical commit splits
- Shows grouping rationale to user
-
Smart Commit Messages - Purpose-focused generation
- Analyzes all files in group
- Focuses on "why" not "what"
- 3-sentence format with context
- Preview with edit option
- Multi-commit workflow support
-
ObsidianVault - Full vault operations
- Search by content with relevance scoring
- Create notes in suggested locations
- Update with diff preview
- Template system with metadata
-
Note Templates - Structured note generation
- Different types: meeting, concept, reference
- Includes date, tags, backlinks
- Context-aware suggestions
Potential Future Features:
- Voice input (Whisper integration)
- Plugin system (custom commands via Lua/Rust)
- Split pane view (code preview alongside conversation)
- Vim keybindings
- Custom themes (user-definable color schemes)
- Session branching (fork conversations)
- Web UI mode (optional browser interface)
- Fuzzy file picker (fzf-style)
- Snippets (save/reuse prompts)
- Create new file in
src/cli/commands/ - Implement
Commandtrait - Register in
src/cli/commands/mod.rs - Add to
/helpoutput - Write unit tests
- Update documentation
- Define tool schema in
src/tools/definitions.rs - Implement tool function (takes
serde_json::Value) - Register in
ToolExecutor - Add permission check if needed
- Add to tool documentation
- Write integration tests
- Create in
src/ui/ - Use
Themefor colors - Handle terminal resize
- Handle
NO_COLOR - Write snapshot tests
- Document in architecture
Terminal Not Restoring:
- Check panic handler installed in
main.rs - Verify
Terminalstruct has proper Drop impl - Test with intentional panics
API Key Not Loading:
- Check
.envfile exists in project root - Verify
ANTHROPIC_API_KEYset in environment - Check
dotenvyloaded before API call
Context Bar Not Updating:
- Verify
TokenCounter::count()called after each message - Check
ContextBar::update()called - Verify terminal width for proper rendering
Permission Prompt Not Showing:
- Check path not in
trusted_paths - Verify
PermissionChecker::check()called - Check session cache not caching decision
Tools Not Executing:
- Verify tool registered in
ToolExecutor - Check Claude API includes tool in request
- Verify tool schema matches Claude's format
- Check logs for parse errors
- Spec:
specs/command-line-interface.md- Full CLI specification - State Machine:
docs/STATE_MACHINE.md- Core state machine docs - CLAUDE.md:
/Users/charliposner/coding-agent/CLAUDE.md- Project overview