| 1 | # Contributing to codewhale |
| 2 | |
| 3 | Thank you for your interest in contributing to codewhale! This document provides guidelines and instructions for contributing. |
| 4 | |
| 5 | ## Getting Started |
| 6 | |
| 7 | ### Prerequisites |
| 8 | |
| 9 | - Rust 1.88 or later (edition 2024) |
| 10 | - Cargo package manager |
| 11 | - Git |
| 12 | |
| 13 | ### Setting Up Development Environment |
| 14 | |
| 15 | 1. Fork and clone the repository: |
| 16 | ```bash |
| 17 | git clone https://github.com/YOUR_USERNAME/CodeWhale.git |
| 18 | cd CodeWhale |
| 19 | ``` |
| 20 | |
| 21 | 2. Build the project: |
| 22 | ```bash |
| 23 | cargo build |
| 24 | ``` |
| 25 | |
| 26 | 3. Run tests: |
| 27 | ```bash |
| 28 | cargo test --workspace --all-features |
| 29 | ``` |
| 30 | |
| 31 | 4. Run with development settings: |
| 32 | ```bash |
| 33 | cargo run --bin codewhale |
| 34 | ``` |
| 35 | |
| 36 | ## Development Workflow |
| 37 | |
| 38 | ### Code Style |
| 39 | |
| 40 | - Run `cargo fmt` before committing to ensure consistent formatting |
| 41 | - Run `cargo clippy` and address all warnings |
| 42 | - Follow Rust naming conventions (snake_case for functions/variables, CamelCase for types) |
| 43 | - Add documentation comments for public APIs |
| 44 | |
| 45 | ### Testing |
| 46 | |
| 47 | - Write tests for new functionality |
| 48 | - Ensure all existing tests pass: `cargo test --workspace --all-features` |
| 49 | - Colocate unit tests beside the code they cover (standard Rust `#[cfg(test)]` |
| 50 | modules), and add integration tests under the owning crate's `tests/` |
| 51 | directory (for example `crates/tui/tests/` or `crates/state/tests/`). The |
| 52 | repository root `tests/` directory is not used |
| 53 | |
| 54 | ### Pre-push verification |
| 55 | |
| 56 | Run these before every push. They match what CI enforces on pull |
| 57 | requests, so passing locally means the PR lanes should pass too: |
| 58 | |
| 59 | ```bash |
| 60 | cargo fmt --all -- --check |
| 61 | cargo clippy --workspace --all-features --locked -- \ |
| 62 | -D warnings \ |
| 63 | -A clippy::uninlined_format_args \ |
| 64 | -A clippy::too_many_arguments \ |
| 65 | -A clippy::unnecessary_map_or \ |
| 66 | -A clippy::collapsible_if \ |
| 67 | -A clippy::assertions_on_constants |
| 68 | cargo test --workspace --all-features --locked |
| 69 | ``` |
| 70 | |
| 71 | The release lane runs a stricter clippy that also lints test, bench, and |
| 72 | example targets. The PR template checklist asks for this form, and it is |
| 73 | the right command before requesting review or doing release-bound work, |
| 74 | because `--all-features` alone skips lints that will fail the release |
| 75 | lane later: |
| 76 | |
| 77 | ```bash |
| 78 | cargo clippy --workspace --all-targets --all-features --locked -- \ |
| 79 | -D warnings \ |
| 80 | -A clippy::uninlined_format_args \ |
| 81 | -A clippy::too_many_arguments \ |
| 82 | -A clippy::unnecessary_map_or \ |
| 83 | -A clippy::collapsible_if \ |
| 84 | -A clippy::assertions_on_constants |
| 85 | ``` |
| 86 | |
| 87 | #### Fast local loop |
| 88 | |
| 89 | The full gate above is what CI enforces, but you do not need it for every |
| 90 | edit. `crates/tui` is a ~750k-line crate, so the loop that stays fast is |
| 91 | the one that avoids rebuilding it more than necessary (numbers and the |
| 92 | reasoning are in [`docs/BUILD_PERFORMANCE.md`](docs/BUILD_PERFORMANCE.md)): |
| 93 | |
| 94 | ```bash |
| 95 | # 1. Type-check first (seconds after the first build; no codegen, no link). |
| 96 | scripts/dev-cargo.sh check -p codewhale-tui |
| 97 | |
| 98 | # 2. Run only the tests near your change (one crate, one filter). |
| 99 | scripts/dev-test.sh tui fleet_setup |
| 100 | # or: scripts/dev-test.sh crates/tui/src/elapsed.rs |
| 101 | |
| 102 | # 3. Run a whole crate's unit suite. scripts/dev-test.sh uses nextest when |
| 103 | # it is installed (one process per test, all cores busy, slow tests |
| 104 | # named; ~100 s here vs ~270 s with libtest). |
| 105 | cargo install cargo-nextest --locked # once |
| 106 | scripts/dev-test.sh tui |
| 107 | scripts/dev-cargo.sh nextest run --workspace --all-features --locked |
| 108 | |
| 109 | # 4. Before pushing, run the authoritative gate exactly as CI does: |
| 110 | cargo test --workspace --all-features --locked |
| 111 | ``` |
| 112 | |
| 113 | `.config/nextest.toml` already serializes the PTY suite and bounds the |
| 114 | integration tests that spawn the real binary, so `cargo nextest run` is |
| 115 | safe to use on the whole workspace (nextest does not run doctests; the |
| 116 | authoritative `cargo test` gate does). Tests must not depend on running in |
| 117 | the same process as another test (nextest gives every test its own |
| 118 | process); if a test needs the rustls crypto provider, install it in that |
| 119 | test as production does at startup. |
| 120 | |
| 121 | On a machine with less than 16 GB of RAM (or when cross-compiling, e.g. |
| 122 | for OHOS), build one rustc at a time: `CARGO_BUILD_JOBS=1` (or `-j1`), one |
| 123 | crate at a time, `--lib` for tests, never `--workspace`/`--all-targets`. |
| 124 | The tui library needs ~6 GB for its own rustc and its unit-test build ~8 GB; |
| 125 | `cargo test --workspace` runs both at once. Numbers and the full recipe: |
| 126 | [`docs/BUILD_PERFORMANCE.md`](docs/BUILD_PERFORMANCE.md#low-memory-build-recipe-machines-with--16-gb-cross-builds). |
| 127 | |
| 128 | If you work in several worktrees, do **not** share one `CARGO_TARGET_DIR` |
| 129 | by default: two cargos on the same target flock and serialize. Use |
| 130 | `scripts/dev-cargo.sh` / `scripts/dev-test.sh`, which give each workspace |
| 131 | its own Cargo `build-dir` (`{workspace-path-hash}` under |
| 132 | `${CODEWHALE_CACHE_ROOT:-${XDG_CACHE_HOME:-$HOME/.cache}/codewhale}`). |
| 133 | `CODEWHALE_DEV_CACHE=local` keeps `./target` if you want that. |
| 134 | `sccache` wraps rustc only when incremental compilation is already off |
| 135 | (`CARGO_INCREMENTAL=0` or `CODEWHALE_SCCACHE=1`) and `sccache` is on |
| 136 | `PATH`; a missing binary is a printed fallback, not an error. Override |
| 137 | the cache root with `CODEWHALE_CACHE_ROOT` — there is no machine-specific |
| 138 | default. A single shared `CARGO_TARGET_DIR` remains valid only for |
| 139 | serialized trunk work. See |
| 140 | [`docs/BUILD_PERFORMANCE.md`](docs/BUILD_PERFORMANCE.md). |
| 141 | |
| 142 | Some checks are platform-bound or intentionally excluded from an ordinary |
| 143 | change. Choose them for the risk they answer rather than treating every |
| 144 | available suite as ritual. Visible TUI behavior is accepted in the actual |
| 145 | terminal at the sizes and interaction path affected by the change; the former |
| 146 | full-screen PTY assertion suite was removed because it froze layout and copy |
| 147 | while missing product quality. |
| 148 | |
| 149 | - **Long-running process acceptance** should use a sealed local home, local |
| 150 | fixtures, and the real binary. Record the terminal size, inputs, visible |
| 151 | result, and any filesystem side effect instead of adding a full-screen |
| 152 | golden. |
| 153 | - **OCR** (`image_ocr`) uses the macOS Vision framework or a locally |
| 154 | installed `tesseract`; its platform-specific paths are |
| 155 | `cfg(target_os = "macos")`-gated and depend on host tooling. |
| 156 | - **Seatbelt sandbox** tests are macOS-only (`cfg(target_os = |
| 157 | "macos")` at the module level) and do not run elsewhere. |
| 158 | |
| 159 | #### Local git hooks are optional |
| 160 | |
| 161 | This repository does not install git hooks, and no hook installer |
| 162 | exists; CI is the enforced gate. If you want a local `pre-push` hook |
| 163 | that runs the commands above, add it yourself (`.git/hooks/pre-push` or |
| 164 | `git config core.hooksPath`). Constraints for any local hook: |
| 165 | |
| 166 | - A hook must never push, tag, publish, deploy, mutate credentials, or |
| 167 | rewrite the working tree (no auto-fix commits or silent file |
| 168 | modification). It may only verify and report. |
| 169 | - To bypass your own hook for a knowingly documented reason (for |
| 170 | example, pushing work-in-progress to your own fork branch), use |
| 171 | `git push --no-verify` and say so in the PR description. Bypassing a |
| 172 | local hook does not make the gates pass — CI still runs them, and a |
| 173 | bypassed gate must never be reported as a passing one. |
| 174 | - Release publication (tags, GitHub Releases, crates/npm artifacts) is a |
| 175 | separate, owner-approved gate. Neither local hooks nor a green local |
| 176 | run authorize any publication step. |
| 177 | |
| 178 | ### Commit Messages |
| 179 | |
| 180 | Use clear, descriptive commit messages following conventional commits: |
| 181 | |
| 182 | - `feat:` New feature |
| 183 | - `fix:` Bug fix |
| 184 | - `docs:` Documentation changes |
| 185 | - `refactor:` Code refactoring |
| 186 | - `test:` Adding or updating tests |
| 187 | - `chore:` Maintenance tasks |
| 188 | |
| 189 | Example: `feat: add doctor subcommand for system diagnostics` |
| 190 | |
| 191 | **Changelog entries are written on `main` at merge time, not in PRs.** Do not |
| 192 | edit `CHANGELOG.md` or `crates/tui/CHANGELOG.md` on a branch: every PR |
| 193 | touching them re-conflicts with every other PR touching them. The release |
| 194 | manager writes one batched "receipts" commit per merge session, and |
| 195 | `./scripts/sync-changelog.sh` keeps the packaged slice in sync. A PR that |
| 196 | carries changelog hunks will be asked to strip them |
| 197 | (`git checkout origin/main -- CHANGELOG.md crates/tui/CHANGELOG.md`). |
| 198 | |
| 199 | **AI-assistant co-author trailers are fine.** Using an assistant is welcome and |
| 200 | needs no disclosure, and CI no longer rejects an auto-appended |
| 201 | `Co-authored-by: <some tool>` line. What we do care about is that the humans who |
| 202 | did the work are named — `Co-authored-by` feeds the GitHub contribution graph. |
| 203 | Remove an auto-appended line only if you want to: |
| 204 | |
| 205 | ```bash |
| 206 | git rebase -i origin/main # reword each commit, delete the Co-authored-by line |
| 207 | ``` |
| 208 | |
| 209 | Co-author a *person* freely; the address must be their GitHub-linked one |
| 210 | (`id+login@users.noreply.github.com`) or the credit does not register. |
| 211 | |
| 212 | When a commit harvests code from a community PR (see "How Your Contribution |
| 213 | Lands" below), include a `Harvested from PR #N by @author` line in the commit |
| 214 | body. An auto-close workflow watches for this pattern and closes the |
| 215 | referenced PR with credit so the contributor gets a clear signal that |
| 216 | their work shipped. |
| 217 | |
| 218 | ## How Your Contribution Lands |
| 219 | |
| 220 | We follow a deliberate "land what's useful, credit the contributor" model |
| 221 | that occasionally surprises new contributors. Two paths: |
| 222 | |
| 223 | ### Path 1 — Direct merge |
| 224 | |
| 225 | If your PR is well-scoped, passes CI, doesn't touch the trust-boundary |
| 226 | surface (auth / sandbox / publishing / branding), and doesn't conflict |
| 227 | with main, a maintainer merges it directly. This is the most common |
| 228 | outcome for small bug fixes and well-tested feature additions. |
| 229 | |
| 230 | ### Path 2 — Harvest |
| 231 | |
| 232 | If your PR is large, mixes scope, conflicts with main, or needs polish |
| 233 | that's faster for the maintainer to apply than to round-trip with the |
| 234 | contributor, the maintainer may **harvest** the useful commits or hunks |
| 235 | into a new commit on `main` rather than merging the PR directly. This is |
| 236 | **not a rejection** — it means your code landed. |
| 237 | |
| 238 | When this happens: |
| 239 | |
| 240 | - The harvested commit's message includes `Harvested from PR #N by |
| 241 | @your-handle`. This is the contract: that line is your credit and the |
| 242 | signal that your contribution shipped. |
| 243 | - If the maintainer copies or adapts your code, the harvested commit also |
| 244 | keeps attribution with the original author identity when possible: either by |
| 245 | preserving the commit author on a cherry-pick or by adding a |
| 246 | `Co-authored-by: Name <id+login@users.noreply.github.com>` trailer. This is |
| 247 | what lets GitHub's contribution surfaces recognize more than prose credit. |
| 248 | Maintainers should use `.github/AUTHOR_MAP`, or run |
| 249 | `gh api users/<login> --jq '"\(.id)+\(.login)@users.noreply.github.com"'`, |
| 250 | rather than copying raw, `.local`, or old-style noreply emails from a |
| 251 | contributor's machine. |
| 252 | - The `CHANGELOG.md` entry for the next release credits you by handle. |
| 253 | - The auto-close workflow closes your PR with a templated thank-you and |
| 254 | a link to the commit on `main`. |
| 255 | |
| 256 | When a maintainer closes a harvested PR by hand, the closing comment |
| 257 | follows this template (the pattern set on PR #2634): |
| 258 | |
| 259 | ```text |
| 260 | Closing with harvest credit, @handle — <what landed> landed via |
| 261 | <commit sha(s) or PR #N>. <If work remains:> The remainder is tracked |
| 262 | in #NNN — follow-ups welcome there. |
| 263 | Thank you for <one specific thing the contribution got right>. |
| 264 | ``` |
| 265 | |
| 266 | Three required elements: the contributor's handle, the exact commits or |
| 267 | PRs where their work landed, and — when the PR contained more than what |
| 268 | landed — a tracking issue for the remainder. A harvested PR is never |
| 269 | closed with a bare "superseded". |
| 270 | |
| 271 | To make a future contribution land via the faster Direct-Merge path |
| 272 | instead of the Harvest path, the highest-leverage things you can do are: |
| 273 | |
| 274 | 1. **Keep PRs single-purpose.** One bug fix per PR; one feature per PR. |
| 275 | Don't mix a refactor with a feature. |
| 276 | 2. **Rebase onto current `main` before opening the PR**, and after CI |
| 277 | feedback. Conflicts force the harvest path even when the change is |
| 278 | small. |
| 279 | 3. **Include tests** with new behavior. The maintainer often harvests |
| 280 | PRs without tests because adding the test is faster than asking the |
| 281 | contributor for one. |
| 282 | 4. **Avoid the trust-boundary surface** without prior maintainer |
| 283 | sign-off. That includes auth/credential flows, sandbox policy, |
| 284 | publishing/release plumbing, and `prompts/` content. PRs that touch |
| 285 | these without prior discussion are unlikely to merge directly even |
| 286 | when the change is well-implemented. |
| 287 | |
| 288 | ## Layered and EPIC-Sized Work |
| 289 | |
| 290 | Some architecture work is too large for one PR but still needs to be built in |
| 291 | dependent layers. For those changes, use this workflow: |
| 292 | |
| 293 | 1. Start with a tracking issue or EPIC when the work spans multiple PRs. Name |
| 294 | the intended slices and state what each slice is not trying to close yet. |
| 295 | 2. Keep each implementation PR focused on one behavior boundary. |
| 296 | 3. Later layers may stay in your fork or open as draft PRs while the lower |
| 297 | layer is still moving. Draft stacked PR titles or descriptions should say |
| 298 | `Draft / depends on #NNNN`. |
| 299 | 4. A dependent PR is not ready for merge review until the lower layer has |
| 300 | landed, the branch has been rebased onto current `main`, and the PR targets |
| 301 | `main`. |
| 302 | 5. The PR body should identify which earlier PR it builds on, what is in scope, |
| 303 | what is explicitly out of scope, which issues it references, and which local |
| 304 | commands were run. |
| 305 | 6. Use `Closes #...` only when the slice fully satisfies an issue. Use |
| 306 | `Refs #...` with a short `(partial)` note when the PR advances a broad issue |
| 307 | but leaves follow-up work. |
| 308 | 7. Structured commits are fine during review. Maintainers may squash or harvest |
| 309 | at merge time, with contributor credit preserved through authorship, |
| 310 | co-author trailers, changelog entries, or PR/issue comments. When the merge |
| 311 | commit itself carries a `Harvested from PR #N by @author` line, that PR is |
| 312 | merged with rebase or a merge commit rather than squashed, so the line |
| 313 | reaches `main` intact and the auto-close credit fires. |
| 314 | |
| 315 | Before asking for merge review on a layered PR, check that it is: |
| 316 | |
| 317 | - rebased onto current `main` |
| 318 | - marked ready for review, not draft |
| 319 | - focused to one behavior boundary |
| 320 | - backed by local command evidence in the PR body |
| 321 | - green in CI, or has any remaining red lane clearly explained |
| 322 | - covered by round-trip or migration-preservation tests when it changes config |
| 323 | or schema behavior |
| 324 | - referencing broad issues as partial unless it really closes them |
| 325 | |
| 326 | For layered work, a useful PR description shape is: |
| 327 | |
| 328 | ```text |
| 329 | Summary: |
| 330 | Scope: |
| 331 | Not in this slice: |
| 332 | Builds on: |
| 333 | Issues: |
| 334 | Validation: |
| 335 | ``` |
| 336 | |
| 337 | ## Which branch to target |
| 338 | |
| 339 | **`main`, for everything.** There is no separate staging branch. An earlier |
| 340 | version of this guide pointed layered refactors at `codex/v0.9.0-stewardship`; |
| 341 | that branch no longer exists, so please ignore any instruction you find |
| 342 | elsewhere to base work on it. |
| 343 | |
| 344 | For a multi-PR series or anything that will collide with other in-flight work, |
| 345 | maintainers may land your branch on an `integration/<topic>-<pr>-<date>` branch |
| 346 | first and merge from there. That is our bookkeeping, not extra work for you — |
| 347 | you still open the PR against `main`, and your commits reach `main` with their |
| 348 | history and authorship intact. |
| 349 | |
| 350 | **We do not expect you to rebase around our churn.** If your PR conflicts only |
| 351 | because `main` moved while it was in review, say so and a maintainer resolves |
| 352 | it. If your branch is in a fork we cannot push to, we land the resolved merge |
| 353 | on an integration branch rather than asking you to redo the work. |
| 354 | |
| 355 | ## Contribution Gate |
| 356 | |
| 357 | Codewhale uses a maintainer-managed contribution gate for the community front |
| 358 | door. Maintainers and collaborators bypass this gate automatically. The gate |
| 359 | workflows default to dry-run / comment-only mode so maintainers can observe the |
| 360 | signal before changing contributor flow. |
| 361 | |
| 362 | The maintainer posture is documented in |
| 363 | [docs/AGENT_ETHOS.md](docs/AGENT_ETHOS.md): automation should reduce load while |
| 364 | keeping good-faith contributors seen, credited, and able to keep helping. |
| 365 | |
| 366 | Issues are never auto-closed by the contribution gate. Unapproved external |
| 367 | issues receive a short welcome note that asks for reproduction details and then |
| 368 | remain open for maintainer triage. Codewhale depends on real edge cases from |
| 369 | real users, so issue intake should stay warm and open. |
| 370 | |
| 371 | Pull requests are different because they can touch code, CI, release plumbing, |
| 372 | auth, sandboxing, provider policy, and other trust-boundary surfaces. The PR |
| 373 | gate can be switched from dry-run to enforcement when maintainers decide they |
| 374 | need that safety control, but it should be treated as a review-load control, |
| 375 | not a judgment on contributor quality. Before enabling PR enforcement, seed the |
| 376 | allowlist broadly enough for active external contributors who should not be |
| 377 | interrupted by the rollout. |
| 378 | |
| 379 | The allowlist is scoped: |
| 380 | |
| 381 | - `pr:username` allows pull requests. |
| 382 | - `issue:username` allows issues. |
| 383 | - `all:username` allows both. |
| 384 | |
| 385 | A maintainer can approve someone by commenting `/lgtm` on a pull request for PR |
| 386 | access, or `/lgtmi` on an issue for issue access. The exact bare commands |
| 387 | `lgtm` and `lgtmi` are also accepted for compatibility, but the prefixed forms |
| 388 | are preferred because they are harder to trigger accidentally in ordinary review |
| 389 | discussion. |
| 390 | |
| 391 | Approvals do not edit `main` directly. The approval workflow opens a small |
| 392 | allowlist update PR so the new entry is reviewable before it takes effect. |
| 393 | |
| 394 | If the PR gate fires on a good contributor incorrectly, use the same approval |
| 395 | flow to restore them: comment `/lgtm`, merge the generated allowlist PR, then |
| 396 | reopen the affected pull request. If GitHub will not allow the closed PR to be |
| 397 | reopened, ask the contributor to resubmit after the allowlist PR is merged. |
| 398 | |
| 399 | ## Agent-Assisted Improvements |
| 400 | |
| 401 | Codewhale is allowed to help improve Codewhale, but the contribution still has |
| 402 | to be shaped for human review. The recommended workflow is the recursive self-improvement prompt |
| 403 | in the private `codewhale-ops` repo: run it |
| 404 | from a fresh fork or branch, let the agent find exactly one small friction point, |
| 405 | and stop after one patch. DeepSeek V4 Pro is the reference path for this loop |
| 406 | today, but any configured provider works — the review shape matters more than |
| 407 | the provider. |
| 408 | |
| 409 | Agents and maintainers should follow the stewardship posture in |
| 410 | [docs/AGENT_ETHOS.md](docs/AGENT_ETHOS.md): use automation for evidence, |
| 411 | verification, and narrow patches while keeping the final community decision |
| 412 | human-reviewed. |
| 413 | |
| 414 | The useful output is not "ideas for improvement." The useful output is a |
| 415 | specific reproduction, a minimal diff, focused checks, and a PR description that |
| 416 | explains the trade-off. Do not use an agent to touch auth, credentials, sandbox |
| 417 | policy, publishing/release plumbing, provider policy, telemetry, sponsorship, |
| 418 | branding, or global prompts without prior maintainer sign-off. |
| 419 | |
| 420 | ## Project Structure |
| 421 | |
| 422 | Codewhale is a Cargo workspace with one Engine implementation in |
| 423 | `crates/tui/src/core/engine/`. The public `codewhale` executable links the |
| 424 | TUI/runtime library; interactive sessions, noninteractive runs and the Runtime |
| 425 | API share that Engine. |
| 426 | |
| 427 | | Path | Purpose | |
| 428 | | --- | --- | |
| 429 | | `crates/cli/` | Public command entrypoint, configuration commands and runtime dispatch | |
| 430 | | `crates/tui/` | Interactive terminal, Engine, tools, Runtime API and embedded local web client | |
| 431 | | `crates/core/`, `crates/protocol/`, `crates/state/` | Request construction, session/turn types, protocol framing and persistence | |
| 432 | | Other `crates/` | Shared configuration, credentials, telemetry, hooks, workflow and packaging support; see each Cargo manifest | |
| 433 | | `web/` | Public Next.js website and documentation; separate from the embedded Runtime web client | |
| 434 | | `telemetry-ingest/` | Telemetry service, schemas and service tests | |
| 435 | | `extensions/`, `integrations/` | Editor integration and external-service bridges | |
| 436 | | `npm/`, `packaging/`, `nix/` | npm wrappers/SDK and platform installation definitions | |
| 437 | | `computer/snapshots/` | Cloud Computer image definitions, pinned independently of the source checkout | |
| 438 | | `deploy/` | Deployment templates consumed by setup scripts, including Tencent Lighthouse services | |
| 439 | | `fleets/`, `workflows/` | Distributed Fleet definitions and workflow examples | |
| 440 | | `brand/` | Source artwork and generated brand variants used by the README, website and terminal | |
| 441 | | `docs/` | User/developer documentation, schemas, fixtures and referenced release material | |
| 442 | | `scripts/`, `.github/`, `.cnb.yml` | Development, validation, CI and release tooling | |
| 443 | | `patches/` | Vendored dependency fixes, including their licensing files | |
| 444 | |
| 445 | Generated files that the product embeds or validates, such as model catalogs, |
| 446 | website facts and schemas, remain tracked with their generators. Platform |
| 447 | mirrors such as `.winget/` are retained when their packaging tools require them. |
| 448 | Keep local critique output, temporary verification reports and personal |
| 449 | operator instructions outside the tracked product tree; describe the change |
| 450 | and its validation in the pull request. Do not copy workspace-level operator |
| 451 | `AGENTS.md` or `CLAUDE.md` files into this repository. |
| 452 | |
| 453 | See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for the runtime data flow and |
| 454 | [the build guide](docs/BUILD_PERFORMANCE.md) for crate dependencies and local |
| 455 | verification. |
| 456 | |
| 457 | ## Submitting Changes |
| 458 | |
| 459 | 1. Create a feature branch from `main`: |
| 460 | ```bash |
| 461 | git checkout -b feat/your-feature |
| 462 | ``` |
| 463 | |
| 464 | 2. Make your changes and commit them |
| 465 | |
| 466 | 3. Run the pre-push verification commands (see |
| 467 | [Pre-push verification](#pre-push-verification) above for the exact |
| 468 | gate and the stricter release clippy form) |
| 469 | |
| 470 | 4. Push your branch and create a Pull Request |
| 471 | |
| 472 | 5. Describe your changes clearly in the PR description |
| 473 | |
| 474 | ## Pull Request Guidelines |
| 475 | |
| 476 | - Use the [pull request template](.github/PULL_REQUEST_TEMPLATE.md) when opening |
| 477 | a PR — it includes the Summary, Testing, and Checklist sections reviewers |
| 478 | expect |
| 479 | - Keep PRs focused on a single change |
| 480 | - Update documentation if needed |
| 481 | - Add tests for new functionality |
| 482 | - Ensure CI passes before requesting review |
| 483 | |
| 484 | ## Shape of a Typical PR |
| 485 | |
| 486 | A well-structured PR follows a consistent pattern. Recent exemplars include: |
| 487 | |
| 488 | - **#386** — `/init` command: new `crates/tui/src/commands/groups/project/init.rs` module, project-type detection, |
| 489 | AGENTS.md generation, command registration in `commands/mod.rs`, localization strings. |
| 490 | - **#389** — Inline LSP diagnostics: LSP subsystem in `crates/tui/src/lsp/`, engine hooks in |
| 491 | `crates/tui/src/core/engine/lsp_hooks.rs`, config toggle, test coverage. |
| 492 | - **#387** — Self-update: new `crates/cli/src/update.rs` module, CLI subcommand registration, |
| 493 | HTTP download + SHA256 verification + atomic binary replacement. |
| 494 | - **#393** — `/share` session URL: new `crates/tui/src/commands/groups/project/share.rs`, HTML rendering, |
| 495 | `gh gist create` integration, command registration. |
| 496 | - **#343/#346** — (v0.8.5) Runtime thread/turn timeline and durable task manager refactors. |
| 497 | |
| 498 | Typically each PR touches 1–3 new files, modifies 2–5 existing files for wiring |
| 499 | (registries, dispatch matches, localization), and adds or updates tests. Changes |
| 500 | are scoped to a single feature or fix — if you discover related work that needs |
| 501 | doing, open a separate issue rather than expanding the PR scope. |
| 502 | |
| 503 | Before submitting, run the commands in |
| 504 | [Pre-push verification](#pre-push-verification). |
| 505 | |
| 506 | ## Reporting Issues |
| 507 | |
| 508 | When reporting issues, please use one of the issue templates: |
| 509 | |
| 510 | - [Bug report](.github/ISSUE_TEMPLATE/bug_report.md) — for reproducible problems |
| 511 | or regressions |
| 512 | - [Feature request](.github/ISSUE_TEMPLATE/feature_request.md) — for ideas and |
| 513 | improvements |
| 514 | |
| 515 | Issue reports should include: |
| 516 | |
| 517 | - Operating system and version |
| 518 | - Rust version (`rustc --version`) |
| 519 | - codewhale version (`codewhale --version`) |
| 520 | - Steps to reproduce the issue |
| 521 | - Expected vs actual behavior |
| 522 | - Relevant error messages or logs |
| 523 | |
| 524 | ## Security |
| 525 | |
| 526 | If you discover a security vulnerability, please do **not** open a public issue. |
| 527 | See [SECURITY.md](.github/SECURITY.md) for the responsible disclosure process and |
| 528 | contact information. |
| 529 | |
| 530 | ## Code of Conduct |
| 531 | |
| 532 | Be respectful and inclusive. We welcome contributors of all backgrounds and |
| 533 | experience levels. See [CODE_OF_CONDUCT.md](.github/CODE_OF_CONDUCT.md) for the full |
| 534 | code of conduct. |
| 535 | |
| 536 | ## License |
| 537 | |
| 538 | By contributing to codewhale, you agree that your contributions will be licensed under the MIT License. |
| 539 | |
| 540 | ## Questions? |
| 541 | |
| 542 | Feel free to open an issue for any questions about contributing. |
| 543 |