youtube-legend-cli 0.4.0

Non-interactive Rust CLI that downloads YouTube subtitles through third-party providers, using a native Unix stdin/stdout interface.
# Contributing to youtube-legend-cli
[English]CONTRIBUTING.md | [Português Brasileiro]CONTRIBUTING.pt-BR.md

This document explains how to set up a development environment, how to
run the gates that judge a change, and how to submit one.


## Code of Conduct
- Follow [CODE_OF_CONDUCT.md]CODE_OF_CONDUCT.md in every interaction with this project


## Reporting bugs
- Open a GitHub issue with a minimal reproduction
- Include the output of `youtube-legend-cli --version`
- Include the exact command line that triggered the bug, with the URL redacted when you need to


## Reporting security vulnerabilities
- Read [SECURITY.md]SECURITY.md before you write anything in public
- NEVER file a public issue for a security-sensitive problem


## Development environment
- Rust 1.88.0 or newer, which is the MSRV `Cargo.toml` declares in `rust-version`
- `rust-toolchain.toml` pins channel `1.96.0` for local development
- This project ships no CI, so nothing runs the checks below on your behalf
- Run them yourself, on the toolchain you intend to support
- `cargo fmt`, `cargo clippy`, `cargo test`, `cargo bench` and `cargo doc` are the required tools
- `mimalloc`, `criterion`, `wiremock`, `assert_cmd`, `predicates`, `serial_test` and `libc` resolve through ordinary dependency resolution
- The only optional Cargo features are the locale groups `i18n-cjk`, `i18n-rtl`, `i18n-europe` and `i18n-full`
- `default` is empty, so `--all-features` compiles every locale group into the binary
- There is no `headless` feature and no browser dependency, because 0.4.0 removed the browser subsystem


## Quality gates
- These commands are the whole verification surface of this project
- Run every one of them before you open a pull request
- A gate that fails is the answer, and your own report is never the answer

```bash
cargo fmt --all -- --check
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo build --release --locked --all-features
cargo test --all-features --locked
cargo test --doc --all-features --locked
cargo bench --no-run
cargo doc --no-deps --all-features -- -D warnings
cargo deny check    # when cargo-deny is on PATH
cargo audit         # when cargo-audit is on PATH
```


## Workflow
- Fork the repository and create a topic branch
- Make your change, and add or update the tests that prove it
- Run every quality gate above
- Open a pull request against `main`


## Release process
- Every step is LOCAL, and no hosted runner takes part in any of them
- Bump `version` in the `[package]` table of `Cargo.toml`
- Add the release section to `CHANGELOG.md` and to `CHANGELOG.pt-BR.md`, with the same version and an ISO date
- Keep the newest release section first, because `changelog_headings_descend_by_release_order` refuses ascending order
- Add the new `[version]` section to `docs/public-surface.txt`, listing every `pub mod` path the tree has
- Grow the MINOR component whenever that section drops a path the previous one had, because dropping a public module is a break
- Run the four commands below, in this order, and read the exit code of each one

```bash
cargo fmt --all -- --check
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --all-features --locked
cargo publish --dry-run --locked
```

- Publish with `cargo publish --locked` only after all four exited `0`


## Agent Teams workflow
- The v0.2.6 release was delivered through the Agent Teams feature of Claude Code
- The playbook lives at [`docs/agent-teams-workflow.md`]docs/agent-teams-workflow.md
- One and only one task owns a file, and two tasks editing the same file are merged before the spawn
- `Cargo.toml` is a serialised file under Agent Teams, and [`docs/decisions/0009-cargo-toml-ownership-in-parallel-tasks.md`]docs/decisions/0009-cargo-toml-ownership-in-parallel-tasks.md carries the rationale
- Every file mutation goes through `atomwrite`, so a BLAKE3 checksum is captured per write and a state drift aborts the operation with exit `82`
- The validation phase runs the quality gates above, and a teammate's own report is informational only


## Style
- Rust edition 2021, and MSRV 1.88.0, both declared in `Cargo.toml`
- Every public item carries a `///` doc comment, enforced by `missing_docs` in the `[lints.rust]` table
- Every `unsafe` block carries a `// SAFETY:` line naming the invariant it upholds
- Error messages and `Display` impls are written in English, because this is a technical CLI consumed by scripts
- User-facing stderr messages are localised through `--ui-lang`, and never through a hand-rolled string
- `cargo fmt` formatting is canonical, so never hand-format
- `[lints.rustdoc]` in `Cargo.toml` denies `bare_urls`, `broken_intra_doc_links`, `private_intra_doc_links`, `invalid_html_tags`, `invalid_rust_codeblocks` and `private_doc_tests`
- Prefer the `[text](url)` form in doc comments, because a raw URL fails the `bare_urls` deny


## Commit messages
- Imperative mood, one-line subject under 72 characters, optional body wrapped at 72
- Reference the relevant issue or pull request number when there is one
- NEVER include a `Co-authored-by` trailer


## License
- Contributing means you agree that your contribution is dual-licensed under [LICENSE]LICENSE
- The manifest declares `MIT OR Apache-2.0`, at the maintainer's option