# 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.

## 1. Architecture Overview & Navigation

### Project Structure

The brush project is organized into several key crates:

- **`brush-core/`**: Core shell functionality, builtins, and runtime
- **`brush-parser/`**: Shell script parsing (AST generation)
- **`brush-builtins/`**: Implementation of shell builtins (e.g., echo, cd)
- **`brush-interactive/`**: Interactive shell interfaces (readline, etc.)
- **`brush-shell/`**: Main CLI application and entry point

### 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
- We try to keep platform-specific code in `brush-core` under the `sys` module
- Follows Rust 2024 edition standards

### Module Dependencies

```text
brush-shell → brush-interactive → brush-core → brush-parser
            ↘ brush-builtins ↗
```

## 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 full pre-commit checks (~45s warm): quick + deps, schemas, integration tests
cargo xtask ci pre-commit

# Run with --continue-on-error to see all failures at once
cargo xtask ci pre-commit -k

# Add -v for verbose output showing exact commands being run
cargo xtask -v ci pre-commit
```

#### 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 <changed-package>` - Fast syntax/type checking
2. **Correctness validation**: `cargo test --package <changed-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 pre-commit workflow:

```bash
cargo xtask ci pre-commit
```

**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`
- **Security/License audit**: `cargo deny check all`
- **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 -- '<name of test case>'
```

**Fast iteration strategies:**

- Target specific crates: `cargo test --package <changed-package>`
- Target specific test cases: `cargo test <test-name>` or `cargo test --test <test-file>`
- 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 <name>`
- 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 pre-commit checks (comprehensive)
cargo xtask ci pre-commit

# Individual checks
cargo xtask check fmt      # Format check
cargo xtask check lint     # Clippy
cargo xtask check deps     # cargo-deny
cargo xtask check build    # Compilation check
cargo xtask check schemas  # Schema drift check

# 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 <pkg>`
- **Regular (before commits)**: `cargo xtask ci pre-commit` or `cargo fmt` + `cargo clippy`
- **Occasional (outer loop)**: `cargo xtask test integration` or `cargo test --workspace`
- **Rare (pre-finish only)**: `cargo xtask check deps` or `cargo deny check`

**Pre-commit validation:**

- Recommended: `cargo xtask ci pre-commit`
- Quick check: `cargo xtask ci quick` for fast feedback
- Manual: Run `cargo fmt` and `cargo clippy` before committing

**Outer loop validation:**

- `cargo deny check all` should pass (security/license auditing) - not for frequent use during development

## 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

---

## 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

### 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
