btr 0.2.3

CLI to standardize build, test, and run commands across projects
Documentation
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project

`btr` (Build Test Run) is a Rust CLI that standardizes `build`, `test`, `run`, and named-command execution across heterogeneous projects by reading a per-project `.btr.toml` file. The repo dogfoods itself: a `.btr.toml` at the root defines how to build/test/lint the crate.

## Commands

```bash
cargo test                                       # full integration + unit suite
cargo test --test cli <pattern>                  # run a single integration test by name (substring match)
cargo build                                      # debug build
cargo build --release
cargo fmt --check                                # CI runs this — must pass
cargo clippy --all-targets --all-features -- -D warnings   # CI runs this — must pass

btr build / btr test / btr lint                  # via the dogfooded .btr.toml once installed
btr ci                                           # pipeline: fmt -> lint -> test
```

The single integration test binary lives at `tests/cli.rs` and uses `assert_cmd` + `tempfile` to drive the compiled `btr` binary against scratch directories. Tests are isolated by `TempDir`, so they can run in parallel.

Install locally: `./install.sh` (wraps `cargo install --path .`). Useful flags: `--debug`, `--force`, `--no-lock`, `--check`, `--install-completions <dir>`, `--install-manpage <dir>`.

## Architecture

The crate is split into a thin `main.rs` and a library where all real logic lives. The library entry point is `btr::run_from_args()` in `src/lib.rs`, which parses CLI args and dispatches each `Action` variant to a top-level `*_action` function.

**Module map:**
- `src/cli.rs``clap`-derived `Cli`, `Action` enum (one variant per subcommand), and per-subcommand `*Args` structs. Adding a subcommand starts here.
- `src/config.rs``.btr.toml` schema (`ProjectFile`, `ProjectConfig`, `CommandSpec`, profiles, requirements, trust). Handles parsing, inheritance via `extends`, `args_mode`/`env_mode` merge semantics, platform overrides (`windows`/`unix`), profile overlays, and `.env`/`env_file` loading.
- `src/discovery.rs` — walks up from `cwd` collecting every `.btr.toml` (parent → child) for the merge chain, and walks down to find workspace projects.
- `src/runner.rs` — process spawning. Handles shell vs `program+args` commands, pipeline `steps`, `retries`, `timeout`, `cwd`, output capture/prefixing for workspace/parallel runs, and `--log-dir` log files.
- `src/error.rs``thiserror`-based `Error` enum used throughout.
- `src/constants.rs``CONFIG_FILE_NAME = ".btr.toml"`, `BINARY_NAME`, `PROFILE_ENV_VAR = "BTR_PROFILE"`.
- `src/lib.rs` (~3400 lines) — every `Action`'s implementation: `run_action`, `workspace_action`, `watch_action`, `init_action` (with detect/import/interactive/template-file paths), `validate_action`, `doctor_action`, `show_action`, `explain_action`, `which_action`, `list_action`, `templates_action`, `package_action`, `release_action`, `parallel_action`, `completions_action`, `schema_action`, `manpage_action`, plus the JSON envelope/event helpers.

**Config resolution flow** (important for any change touching command behavior):
1. `discovery::discover_config_chain` finds every `.btr.toml` from cwd to filesystem root.
2. `config::load_project` parses each file, merges them parent-into-child, applies the selected profile overlay (`--profile` > `BTR_PROFILE`), then applies the active `windows`/`unix` platform override per command.
3. Per-command `extends` is resolved within the merged set, with `args_mode = "append" | "replace"` and `env_mode = "merge" | "replace"`.
4. `.env` and `env_file` are loaded into `config.env` before the child process is spawned.

The `btr show`, `btr explain`, and `btr which` commands surface this provenance — when debugging config behavior, run them against the failing project rather than re-reading the code.

**Shell completions** are generated by `clap_complete` in `completions_action` from the `clap` `Cli` definition. The `CompletionShell` enum in `src/cli.rs` is the supported-shell list. To extend completion behavior (e.g. dynamic completion of command names from `.btr.toml`), note that `clap_complete::generate` only produces static scripts from the clap grammar — dynamic completion requires either `clap_complete::dynamic` or a hand-written wrapper.

## Conventions

- The crate name is `btr` (renamed from the old `mbr` — a few internal helper names like `mbr_schema` still reflect the old name; not a bug, just historical).
- JSON output uses a stable envelope: `{"status": "...", "command": "...", ...}`. The `json_envelope` helper in `lib.rs` builds it; preserve this shape when adding fields.
- CI matrix runs on ubuntu/macos/windows — keep platform-specific code behind `cfg!(windows)` or the `windows`/`unix` command override mechanism, and mirror the pattern when adding integration tests (see `print_command_spec` and friends at the top of `tests/cli.rs`).
- There are many root-level `*.md` files (`SPEC.md`, `EXAMPLES.md`, `ROADMAP.md`, `*_FEATURES.md`, etc.). `SPEC.md` is the authoritative behavior spec; the others are working notes and may be stale.