# AGENTS.md
This file provides guidance to agents (both AI and human) working with VT Code.
## Design Philosophy: Desire Paths
When agents intuitively guess wrong about a command, flag, or workflow, we treat it as a signal to **improve the interface** rather than just documenting correct behavior. We "pave the desire paths" by adding aliases, flags, and shortcuts that match intuitive expectations. Over time, this compounds—agents stop making mistakes naturally, and the tool becomes easier to use.
## Build & Test Commands
```bash
# Preferred development workflow
cargo check # Fast compile check
cargo test # Run tests
cargo test --package vtcode-core # Test specific package
cargo clippy # Lint with strict rules
cargo fmt # Format code
# Additional commands
cargo test -- --nocapture # Tests with output
cargo bench # Run performance benchmarks
cargo build # Build the project
cargo run -- ask "Hello world" # Run VT Code CLI
# Run a single test
cargo test test_name -- --nocapture
# Aliases & Quick Commands
cargo t # Run tests (alias)
cargo c # Check compilation (alias)
```
### Release Commands
```bash
# Dry-run release (test first!)
./scripts/release.sh --patch --dry-run
# Actual patch release
./scripts/release.sh --patch
# Minor/major releases
./scripts/release.sh --minor
./scripts/release.sh --major
# Custom version
./scripts/release.sh 1.2.3
# With options
./scripts/release.sh --patch --skip-binaries --skip-crates
```
**Release Process**:
1. Triggers version bump and crate publishing
2. Creates git tags (`v0.58.3`)
3. GitHub Actions automatically:
- Builds binaries for all platforms
- Uploads to GitHub Releases
- Updates Homebrew formula with checksums
- Commits and pushes formula changes
See: `docs/HOMEBREW_RELEASE_GUIDE.md` for troubleshooting.
### Desire Path Commands (Paved for Agents)
These shortcuts match intuitive agent expectations:
- `cargo t` → `cargo test`
- `cargo c` → `cargo check`
- `cargo r` → `cargo run`
- When running a specific test, agents intuitively try:
- `cargo test function_name` ✓ (this works)
- `cargo test --lib` ✓ (unit tests only)
- `cargo test --integration` ✓ (integration tests only)
## Workspace Structure
VT Code uses a **11-member workspace** architecture:
```
vtcode/ # Binary entrypoint (src/main.rs)
├── vtcode-core/ # Core library (LLM, tools, config, MCP)
├── vtcode-config/ # Configuration loader & schema
├── vtcode-commons/ # Shared utilities
├── vtcode-llm/ # LLM provider abstractions
├── vtcode-tools/ # Tool implementations
├── vtcode-bash-runner/ # Shell execution engine
├── vtcode-markdown-store/ # Document storage
├── vtcode-indexer/ # Code indexing
├── vtcode-exec-events/ # Event definitions
├── vtcode-acp-client/ # Agent Client Protocol bridge
└── vtcode-process-hardening/ # Process hardening & security measures
```
**Key separation**:
- **vtcode-core/**: Reusable library with 77% complexity reduction through mode-based execution
- **src/**: CLI executable (Ratatui TUI, PTY, slash commands)
## Architecture Highlights
Understanding these patterns requires reading multiple files across the codebase:
### Multi-Provider LLM System
- **Location**: `vtcode-llm/`, `vtcode-core/src/llm/`
- **Pattern**: Factory pattern with provider-specific request shaping
- **Providers**: OpenAI, Anthropic, Gemini, xAI, DeepSeek, OpenRouter, Ollama, Z.AI, Moonshot AI, MiniMax
- **Features**: Automatic failover, prompt caching, token budget tracking
### Trait-Based Tool System
- **Location**: `vtcode-tools/`, `vtcode-core/src/tools/`
- **Pattern**: Trait-driven composition (`Tool`, `ModeTool`, `CacheableTool`)
- **Key**: Single source of truth for content search (grep_file) and file operations
- **Tools**: 54+ specialized handlers with workspace-scoped isolation
### Code Intelligence Tool
- **Location**: `vtcode-core/src/tools/code_intelligence.rs`
- **Purpose**: LSP-like code navigation using tree-sitter
- **Operations**:
- `goto_definition`: Find where a symbol is defined
- `find_references`: Find all references to a symbol
- `hover`: Get documentation and type info for a symbol
- `document_symbol`: Get all symbols in a file
- `workspace_symbol`: Search for symbols across the workspace
- **Languages**: Rust, Python, JavaScript, TypeScript, Go, Java, Bash, Swift
- **Usage**: Call `code_intelligence` tool with operation, file_path, line, and character parameters
### Configuration Precedence
**Critical**: Configuration flows in this order:
1. Environment variables (API keys, overrides)
2. `vtcode.toml` (runtime configuration)
3. `vtcode-core/src/config/constants.rs` (code constants)
### PTY Session Management
- **Location**: `vtcode-core/src/exec/`, `vtcode-bash-runner/`
- **Pattern**: Interactive shell sessions with streaming output
- **Use**: Long-running commands, interactive workflows, real-time feedback
### Tree-Sitter Integration
- **Location**: `vtcode-core/src/tree_sitter/`, `vtcode-indexer/`
- **Languages**: Rust, Python, JavaScript/TypeScript, Go, Java, Bash (+ optional Swift)
- **Pattern**: Incremental AST building with caching for semantic code analysis
### Protocol Integrations
- **ACP** (Agent Client Protocol): `vtcode-acp-client/` - Zed IDE integration
- **MCP** (Model Context Protocol): `vtcode-core/src/mcp/` - Extensible tooling via `rmcp`
- **Location**: `vtcode-core/src/mcp/` (9 modules)
- **Key Components**:
- `McpClient`: Main high-level client managing multiple providers
- `McpProvider`: Individual provider connection and lifecycle
- `McpToolExecutor`: Trait interface for tool registry integration
- `rmcp_transport.rs`: Supports stdio, HTTP, and child-process transports
- **Configuration**:
- Project: `.mcp.json` (checked into source control)
- User: `~/.claude.json` (cross-project personal utilities)
- Runtime: `vtcode.toml` with `[mcp]` section
- **Features**:
- Tool discovery and execution with allowlist enforcement
- Resource and prompt management from MCP providers
- Security validation (argument size, path traversal, schema)
- OAuth 2.0 authentication support
- Event notifications (logging, progress, resource updates)
- Elicitation handling for user interaction
- Per-provider concurrency control with semaphores
- Timeout management (startup and per-tool)
- **Transports**:
- **Stdio**: Local tool execution (development, CLI tools)
- **HTTP**: Remote server integration (requires `experimental_use_rmcp_client = true`)
- **Child Process**: Managed stdio with lifecycle control
- **Documentation**:
- Integration guide: `docs/MCP_INTEGRATION_GUIDE.md` (current implementation)
- Improvement designs: `docs/MCP_IMPROVEMENTS.md` (planned enhancements)
- Implementation roadmap: `docs/MCP_ROADMAP.md` (detailed next steps)
### Subagent System
- **Location**: `vtcode-core/src/subagents/`, `vtcode-config/src/subagent.rs`
- **Purpose**: Delegate tasks to specialized agents with isolated context
- **Built-in Subagents**: `explore` (haiku, read-only), `plan` (sonnet, research), `general` (sonnet, full), `code-reviewer`, `debugger`
- **Tool**: `spawn_subagent` with params: `prompt`, `subagent_type`, `resume`, `thoroughness`, `parent_context`
- **Custom Agents**: Define in `.vtcode/agents/` (project) or `~/.vtcode/agents/` (user) as Markdown with YAML frontmatter
- **Documentation**: `docs/subagents/SUBAGENTS.md`
### Execution Policy System (Codex Patterns)
- **Location**: `vtcode-core/src/exec_policy/`, `vtcode-core/src/sandboxing/`
- **Purpose**: Command authorization and sandboxed execution inspired by OpenAI Codex
- **Key Components**:
- `ExecPolicyManager`: Central coordinator for policy evaluation
- `SandboxPolicy`: Isolation levels (ReadOnly, WorkspaceWrite, DangerFullAccess)
- `SandboxManager`: Platform-specific transforms (macOS Seatbelt, Linux Landlock)
- `ExecApprovalRequirement`: Skip, NeedsApproval, Forbidden outcomes
- **Policy Features**:
- Prefix-based rule matching for command authorization
- Heuristics for unknown commands (safe: ls, cat; dangerous: rm, sudo)
- Session-scoped approval caching
- Policy amendments for trusted patterns
- **Turn Diff Tracking**: `TurnDiffTracker` aggregates file changes across patches
- **Tool Trait Extensions**: `is_mutating()`, `is_parallel_safe()`, `kind()`, `matches_kind()`
### Process Hardening
- **Location**: `vtcode-process-hardening/` (dedicated crate)
- **Purpose**: Apply security hardening measures before the main binary executes
- **Pattern**: Pre-main execution using `#[ctor::ctor]` constructor decorator
- **Features**:
- **Linux/Android**: `PR_SET_DUMPABLE` (ptrace disable), `RLIMIT_CORE` (disable core dumps), `LD_*` env var removal
- **macOS**: `PT_DENY_ATTACH` (debugger prevention), `RLIMIT_CORE`, `DYLD_*` env var removal
- **BSD**: `RLIMIT_CORE`, `LD_*` env var removal
- **Windows**: Placeholder for future mitigation policies
- **Key Detail**: Uses `std::env::vars_os()` to handle non-UTF-8 environment variables correctly
- **Exit Codes**: 5 (prctl), 6 (ptrace), 7 (setrlimit) indicate hardening failures
- **Documentation**: `docs/PROCESS_HARDENING.md`
- **Integration**: Called via `#[ctor::ctor]` in `src/main.rs:init()`
## Communication Style
### Response Guidelines
- **No emoji**: Never use emojis in responses. Keep output professional and text-based.
- **Minimize exclamation points**: Use them sparingly; let the content speak for itself.
- **Be concise**: Answer directly without unnecessary preamble, elaboration, or summaries.
- **Avoid flattery**: Don't call ideas "good," "great," "interesting," or other positive adjectives. Respond directly to the request.
- **Focus on the task**: Only address the user's specific query. Skip tangential information unless critical.
- **One-to-three sentences**: Aim for brevity whenever possible. One-word answers are preferred for simple questions.
- **No long introductions**: Get to the point immediately.
- **Clean markdown**: Format responses with GitHub-flavored Markdown where appropriate.
## Code Style & Conventions
### Critical Standards from .github/copilot-instructions.md
**Error Handling**:
```rust
// ALWAYS use anyhow::Result<T> with context
use anyhow::{Context, Result};
pub async fn read_config(path: &str) -> Result<Config> {
tokio::fs::read_to_string(path)
.await
.with_context(|| format!("Failed to read config at {}", path))?;
// Process...
}
// NEVER use unwrap()
// ❌ let data = result.unwrap();
// ✅ let data = result.with_context(|| "Description")?;
```
**Constants & Configuration**:
```rust
// NEVER hardcode values (especially model IDs)
// ❌ let model = "gpt-4";
// ❌ let timeout = 30;
// ✅ Use constants from vtcode-core/src/config/constants.rs
use vtcode_core::config::constants::DEFAULT_TIMEOUT;
// ✅ Read from vtcode.toml at runtime
let config = Config::load("vtcode.toml")?;
// ✅ Model metadata in docs/models.json
```
**Naming Conventions**:
- `snake_case` for functions and variables
- `PascalCase` for types and structs
- Descriptive names, early returns
- 4-space indentation
**Documentation**:
- All `.md` files go in `./docs/` directory (NOT in root)
- `README.md` is the only exception (stays in root)
- Use `docs/models.json` for latest LLM model metadata
## Testing Infrastructure
### Test Organization
- **Unit tests**: Inline with source in `#[cfg(test)]` modules
- **Integration tests**: `tests/` directory (20+ test files)
- **Benchmarks**: `benches/` directory
- **Mock data**: `tests/mock_data.rs` for realistic scenarios
### Running Specific Tests
```bash
# All tests
cargo test
# Integration tests
cargo test --test integration_tests
# Benchmarks
cargo bench
cargo bench -- search_benchmark
# With output
cargo test -- --nocapture
```
## Agent UX & Desire Paths
This section tracks UX friction points that agents intuitively expect vs. how the system actually works.
### Philosophy: Pave the Desire Paths
When agents guess wrong about commands, flags, or workflows, we treat that as a signal to **improve the interface** rather than just documenting the correct behavior. Over time, small UX improvements compound—agents stop making "mistakes" naturally.
### Active Patterns
**Cargo alias expectations**:
- Agents try `cargo t` expecting `cargo test` → ✓ Paved with cargo aliases
- Agents try `cargo c` expecting `cargo check` → ✓ Paved with cargo aliases
- Agents try `cargo r` expecting `cargo run` → ✓ Paved with cargo aliases
**Tool operation patterns**:
- Agents expect `code_intelligence goto_definition` → Unified under `unified_search` with `action="intelligence"`
- Agents expect `spawn_subagent --name explore` → Currently requires positional `subagent_type` param
- Agents expect `exec_command` and `write_stdin` (Unified Exec) → ✓ Paved with `unified_exec` (compatible with OpenAI Codex pattern)
- Agents expect `read_file`, `write_file`, `edit_file` → ✓ Unified under `unified_file` with `action` param
- Agents expect `grep_file`, `list_files`, `search_tools`, `get_errors`, `agent_info` → ✓ Unified under `unified_search` with `action` param (`grep`, `list`, `intelligence`, `tools`, `errors`, `agent`)
### Reporting Friction
If you (agent or human) notice a repeated "wrong" guess that makes intuitive sense, document it here before implementing the improvement.
## Important Development Notes
### Git Operations
**Agent Must Not Perform Git Operations Automatically**
- Do NOT run `git commit`, `git push`, `git merge`, or any destructive git operations on behalf of the user
- Inform the user when changes need to be committed and let them handle git operations
- Use `git status`, `git diff`, and `git log` only for diagnostic/informational purposes
- Always inform the user before making changes that would affect git history
### Security & Safety
- Validate all file paths (workspace boundary enforcement)
- Command allowlist with per-argument validation
- Tool policies (allow/deny/prompt) in `vtcode.toml`
- Human-in-the-loop approval system
### Autonomy & Verification
- **Verification Autonomy**: The agent MUST run verification commands (`cargo check`, `cargo test`, etc.) itself using `run_pty_cmd` after making changes. Do NOT ask the user to run these commands.
- **Planning**: Use `update_plan` for any task requiring 4+ steps to maintain state and provide visibility to the user.
### Memory & Performance
- LTO enabled even in dev profile (optimized for M4 Apple Silicon)
- Single codegen unit for better optimization
- Strict Clippy linting rules (see `Cargo.toml` workspace.lints)
- No `expect_used`, `unwrap_used`, or manual implementations when stdlib has them
### Key Files Never to Hardcode
- **Model IDs**: Use `docs/models.json`
- **Constants**: Use `vtcode-core/src/config/constants.rs`
- **Config values**: Read from `vtcode.toml`
### Common Pitfalls
1. **Don't hardcode model names** - they change frequently, use constants
2. **Don't use `unwrap()`** - use `.with_context()` for error context
3. **Don't create .md files in root** - they belong in `./docs/`
4. **Don't modify constants directly** - consider if it should be in `vtcode.toml` instead
## Development Workflow
### Before Committing
```bash
# Run all quality checks
cargo clippy && cargo fmt --check && cargo check && cargo test
```
### Adding New Features
1. Read existing code patterns first
2. Use configuration from `vtcode.toml` when possible
3. Add constants to `vtcode-core/src/config/constants.rs` if needed
4. Write tests (unit + integration)
5. Update documentation in `./docs/` if needed
### Environment Setup
```bash
# Set API key for your preferred provider
export OPENAI_API_KEY="sk-..." # OpenAI
export ANTHROPIC_API_KEY="sk-..." # Anthropic
export GEMINI_API_KEY="..." # Google Gemini
# See docs/installation/ for all provider options
# Run VT Code
cargo run
```
## Additional Resources
- **Architecture**: See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
- **Security**: See [docs/SECURITY_MODEL.md](docs/SECURITY_MODEL.md)
- **Contributing**: See [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md)
- **Configuration**: See [docs/config/CONFIGURATION_PRECEDENCE.md](docs/config/CONFIGURATION_PRECEDENCE.md)
- **Provider Setup**: See [docs/PROVIDER_GUIDES.md](docs/PROVIDER_GUIDES.md)
- **Testing Guide**: See [docs/development/testing.md](docs/development/testing.md)
## Agent Workflows
This CLAUDE.md focuses on the **VT Code codebase itself**.
## IMPORTANT:
- When working on VT Code features, ALWAYS follow the guidelines in this document to ensure code quality, maintainability, and security.
- Make sure the name is "VT Code" not "VTCODE" or "vtcode" in user-facing text.