# Agent Development Guide for `brush` This guide helps AI agents work efficiently on the `brush` codebase by providing essential context about architecture, patterns, and development workflows. ## Required: Independent Implementation Before investigating or implementing a change, read and follow the [independent-implementation and provenance policy](CONTRIBUTING.md#independent-implementation-and-provenance). It is the canonical policy for contributors and all agents, including delegated agents and their tools. Use Bash as a black-box behavioral oracle, not as implementation source material. If you encounter Bash implementation material, stop implementation and disclose the exposure; do not translate, summarize, or rewrite it into brush. Disclose this to the human contributor to clarify how to proceed. ## 1. Architecture Overview & Navigation ### Architecture [docs/explanation/architecture.md](docs/explanation/architecture.md) is the definition of brush's architecture: its crates, how they depend on each other, how `brush-core` is structured, and the layering principles that decide which crate code belongs in (e.g. what `brush-core` owns vs. the interactive front end). Read it before adding a crate, moving code between crates, or changing a public API's shape, and keep it up to date when the architecture changes. ### Key Files & Entry Points **Critical files to understand first:** - `brush-core/src/shell.rs` - Main `Shell` struct and creation logic - `brush-core/src/lib.rs` - Public API exports - `brush-shell/src/main.rs` - CLI application entry point **Architecture patterns:** - Shell instances are created via `Shell::builder()` - The project uses builder patterns for type-safe configuration - Platform-specific code in `brush-core` MUST live under the `sys` module - Follows Rust 2024 edition standards ### Module Dependencies ```text brush-shell → brush-interactive ─────────────────────────→ brush-core → brush-parser ↘ brush-builtins → brush-winnow-args-adapter ↗ ``` ## 2. Testing Strategy ### Test Execution Priority **Recommended development workflow:** #### Using xtask (Recommended) The project provides a `cargo xtask` command that centralizes common development tasks: ```bash # Run quick inner-loop checks (~7s warm): fmt, build, lint, unit tests cargo xtask ci quick # Run the full workflow (~60s warm): quick + pre-commit hooks, schemas, integration tests cargo xtask ci full # Run with --continue-on-error to see all failures at once cargo xtask ci full -k # Add -v for verbose output showing exact commands being run cargo xtask -v ci full ``` `cargo xtask ci quick` needs only the Rust toolchain. `cargo xtask ci full` also needs `prek` on `PATH` (see CONTRIBUTING.md for install commands). If `prek` is unavailable in your environment, run `cargo xtask ci full --no-hooks`; CI still runs the hooks. #### Individual Test Commands ```bash # Run unit tests (fast tests excluding integration binaries) cargo xtask test unit # Run integration tests (all workspace tests including compat tests) cargo xtask test integration # Run tests with coverage cargo xtask test integration --coverage --coverage-output codecov.xml ``` #### Manual Approach (Alternate) For finer-grained control: ##### Inner Loop (Fast Iteration) 1. **Quick validation**: `cargo check --package ` - Fast syntax/type checking 2. **Correctness validation**: `cargo test --package ` - Target specific crates for faster feedback ##### Outer Loop (Comprehensive Testing) 1. **Compatibility tests**: `cargo test --test brush-compat-tests` - Bash compatibility validation 2. **Full workspace tests**: `cargo test --workspace` - Complete test suite #### Pre-Finish Quality Validation **Recommended:** Run the xtask full workflow: ```bash cargo xtask ci full ``` **Manual approach:** Before considering work complete, run these validation steps: - **Compatibility tests**: `cargo test --test brush-compat-tests` - **Linting**: `cargo clippy` - **Formatting**: `cargo fmt --check` - **Pre-commit hooks** (spelling, links, workflows, dependency audit, structural lints): `cargo xtask check hooks` (needs `prek`) - **Full test suite**: `cargo test --workspace` **When tests fail:** - Focus on failures in the area you changed first - Compatibility test failures often indicate shell behavior changes - Check if new functionality needs corresponding test cases - Format/clippy failures should be fixed before proceeding **Common pitfalls:** - **Test scope mistakes**: Running full test suite too early instead of targeting specific areas first - **Skipping test-driven development**: Add tests that specify desired behavior before implementing **Test-driven development approach:** - When possible, write tests first that specify the desired behavior - Use unit tests for logic changes, compatibility tests for shell behavior changes - Use these tests as validation that your implementation is working correctly **Pro tip**: For specific compatibility test cases, use: ```bash cargo test --test brush-compat-tests -- '' ``` **Fast iteration strategies:** - Target specific crates: `cargo test --package ` - Target specific test cases: `cargo test ` or `cargo test --test ` - Requires knowledge of which tests best exercise the code being changed **Testing approach:** - Follow good software engineering practice: start by validating the specific area being changed, then iteratively move to incrementally broader sets of tests ### Test Organization **Testing expectations for new public APIs:** - Unit tests are expected if feasible - Examples are nice to have and worthwhile for sufficiently critical APIs **Test patterns and conventions:** - **Compatibility tests**: For any compatibility-related fixes, it's critical to add new test cases to the compat tests (see docs/how-to/run-tests.md and section 3 for when breaking changes apply) **Test categories:** - Unit tests: In `src/` files with `#[cfg(test)]` - Integration tests: In `tests/` directories - Examples: In `examples/` directories (must be runnable) - Shell script tests: YAML-based test cases in `brush-shell/tests/cases/` ### Performance Testing **Performance regression testing:** - Not a chief concern for most changes - For performance-specific work, benchmarks are available (see docs/how-to/run-benchmarks.md) - Performance sensitivity will be identified in the initial brief if relevant ## 3. Breaking Changes & Compatibility ### API Stability Guidelines **Breaking change policy:** - Non-backwards compatible changes to public APIs are considered breaking - Breaking changes are still in consideration, but need to be highlighted and carefully reviewed - Any APIs exported from crates are considered public because all of the crates are published to crates.io **Adding new fields to public structs:** - New optional fields are fine to add as long as the struct implements the Default trait and as long as the defaulted value is a sensible one ### Dependency Impact When changing public APIs in `brush-core` (see section 3 for breaking change policy): 1. Check `brush-shell/src/main.rs` for struct initialization sites 2. Check `brush-interactive/` for any usage ## 4. Documentation & Examples Standards ### Documentation Requirements **Rustdoc documentation standards:** - At minimum we must have good rustdoc documentation for exported types, functions, traits, etc. as well as on all exported modules and crates - Documentation for internal components should be a best-effort, nice to have thing **Examples for new features:** - Unless explicitly requested, only major feature additions warrant an example. **Documentation style:** - Follow general best practices for Rust ### Example Standards Examples should: - Be self-contained and runnable with `cargo run --package brush-core --example ` - Include comprehensive error handling - Demonstrate both basic and advanced usage patterns - Include output examples in comments when helpful ## 5. Build & Release Process ### Development Tools The project uses several tools for code quality: **Using xtask (Recommended):** The project provides a `cargo xtask` command that centralizes common development tasks: ```bash # Run all checks (comprehensive) cargo xtask ci full # Individual checks cargo xtask check fmt # Format check cargo xtask check lint # Clippy cargo xtask check build # Compilation check cargo xtask check crates # Crate structure (e.g. LICENSE symlinks) cargo xtask check schemas # Schema drift check cargo xtask check hooks # prek hooks: file hygiene, typos, zizmor, lychee, cargo-deny, ast-grep cargo xtask check hooks deps # One hook, by id or alias # Tests cargo xtask test unit # Fast unit tests (excludes integration binaries) cargo xtask test integration # All workspace tests (unit + compat) # Analysis cargo xtask analyze bench # Run benchmarks ``` **Manual approach (Alternate):** - Standard cargo commands (e.g., check, test, build, run, clippy) - You may need to reverse engineer some of the args looking at CI checks in .github/*.yml **Command frequency guidelines:** - **Frequent (inner loop)**: `cargo xtask ci quick`, `cargo check`, `cargo test --package ` - **Regular (before commits)**: `cargo xtask ci quick` or `cargo fmt` + `cargo clippy` - **Occasional (outer loop)**: `cargo xtask test integration` or `cargo test --workspace` - **Rare (before opening a PR)**: `cargo xtask ci full`, which adds the pre-commit hooks, schemas, and integration tests **Pre-commit validation:** - Recommended: `cargo xtask ci quick` - Before opening a PR: `cargo xtask ci full` - Manual: Run `cargo fmt` and `cargo clippy` before committing **Outer loop validation:** - `cargo xtask check hooks` should pass (file hygiene, typos, zizmor, lychee, cargo-deny, ast-grep) - not for frequent use during development; `cargo xtask ci full --no-hooks` skips it when `prek` is unavailable ## 6. Performance & Error Handling Patterns ### Error Handling **Error handling patterns:** - `thiserror` is used for implementing crate-specific errors - Use `anyhow` only in tests **Logging and tracing patterns:** - Use `tracing` for debug logging with predefined categories - Categories are defined in `trace_categories.rs` modules (e.g., `COMMANDS`, `COMPLETION`, `EXPANSION`, `FUNCTIONS`, `INPUT`, `JOBS`, `PARSE`, `PATTERN`, `UNIMPLEMENTED`) - Usage pattern: `tracing::debug!(target: trace_categories::CATEGORY_NAME, "message")` - Example: `tracing::debug!(target: trace_categories::JOBS, "Polling job {} for completion...", job_id)` ### Performance Considerations **Clone vs references:** - Avoid cloning by default, no reason to make extra copies - Only use cloning when you really must capture a separate copy for async safety or similarly important reasons --- ## 7. Commit Message Conventions Following the Linux kernel convention, when AI assistants or advanced coding tools have been used in the development of a change, include an `Assisted-by:` tag in the commit message. This provides transparency about the use of such tools in the development process. The format for the Assisted-by tag is: ``` Assisted-by: AGENT_NAME:MODEL_VERSION [TOOL1] [TOOL2] ``` Example: ``` Assisted-by: Mistral Vibe:mistral-medium-3.5 ``` ## Quick Reference Checklist When making changes to brush: ### Before Starting - [ ] Understand which crate(s) are affected - [ ] Check if changes might break dependent crates - [ ] Identify relevant test files and examples ### During Development - [ ] Run `cargo check` frequently during development - [ ] Test changes with package-specific tests first (see section 2 for testing workflow) - [ ] Update dependent crate usage if needed (see section 3 for compatibility considerations) - [ ] Add/update examples for major feature additions only (see section 4) ### Before Committing - [ ] Run full test suite: `cargo test` (see section 2 for complete testing workflow) - [ ] Format code: `cargo fmt` (see section 5 for tool details) - [ ] Check linting: `cargo clippy` - [ ] Use conventional commit format - [ ] If using AI assistants or advanced coding tools, include an `Assisted-by:` tag in the format `AGENT_NAME:MODEL_VERSION` (following Linux kernel convention) ### Documentation - [ ] Add rustdoc to exported APIs (see section 4 for documentation standards) - [ ] Include working examples for major features only - [ ] Update this guide if new patterns emerge