Files
codewhale/CONTRIBUTING.md
T
Hunter Bown 1763261503 v0.8.46: release archives, sandbox depth, quick fixes, web install, docs
* docs: v0.8.46 CHANGELOG — platform archives, palette, sub-agents, sandbox, web install, search fixes

Closes #2188

* feat(v0.8.46): quick fixes — palette, model picker Esc, sub-agent sidebar, shell chip, model name casing, CVE bump (#2212)

* fix: bump qs to >=6.15.2 for CVE-2026-8723

Add qs override in feishu-bridge package.json to force transitive
dependency resolution to >=6.15.2, addressing CVE-2026-8723.

Refs: #2198

* fix: Esc in model picker applies last-highlighted choice

Previously Esc reverted to the initial model when the user hadn't
moved the selection. Now Esc always applies the currently highlighted
model and thinking-effort tier, making Esc consistent with Enter.

Also updates the picker footer hint from 'Esc cancel' to 'Esc apply'.

Refs: #2196

* feat: show ' shell running' chip in TUI footer

Adds a footer_shell_chip function that displays a ' shell running'
status chip in the footer's right cluster whenever a foreground shell
command is active via exec_shell. The chip is always visible regardless
of user-configured status items.

Refs: #2194

* feat: auto-collapse finished sub-agents in sidebar

When a sub-agent completes (status = 'done'), its detail lines
(id, steps, duration, progress) are now hidden in the sidebar agents
panel. Only the summary label line is shown, keeping the sidebar
compact. Running agents still show full detail.

Refs: #2195

* feat: refresh Whale dark palette for better contrast

Improve contrast and layer separation in the Whale dark theme:
- Deepen base background for more depth (10,17,32)
- Lighten panel (22,34,56) for clearer distinction from bg
- Lighten elevated surface (36,52,78) for better elevation
- Lighten selection (48,68,100) for clearer selected state
- Boost text hint (138,150,174) and dim (118,130,156) readability
- Brighter border (52,88,145) for better edge definition
- Update tool surface colors for consistency

Refs: #2197

* fix: preserve model name casing in normalize_model_name_for_provider

When the user enters a model name like 'DeepSeek-V4-Flash', the
normalizer was lowercasing it to 'deepseek-v4-flash' via the
canonical_official_deepseek_model_id function. Now the normalizer
preserves the caller's casing when the input already matches a known
model id case-insensitively. Compact aliases like 'deepseek-v4pro'
are still rewritten to 'deepseek-v4-pro'.

Refs: #2109

* feat(web): install download tile with arch detection, SHA256, China mirrors + companion binary fix (#2213)

* fix(web): download both codewhale and codewhale-tui binaries in install snippets

The SNIPPETS map only fetched one binary per platform, causing the
dispatcher to fail with MISSING_COMPANION_BINARY. Every arch now
downloads both codewhale AND codewhale-tui side-by-side.

- macOS/Linux: added second curl + combined chmod/xattr/mv for tui
- Windows: added second Invoke-WebRequest for codewhale-tui.exe
- VERIFY: PowerShell now hashes both binaries; Unix --ignore-missing
  covers all present binaries in a single sha256sum pass

* feat(web): add install download tile with arch detection, SHA256, and China mirrors (#2192)

* feat(sandbox/linux): process hardening — PR_SET_DUMPABLE, NO_NEW_PRIVS, RLIMIT_CORE (#2214)

* feat(sandbox/linux): add process hardening module — PR_SET_DUMPABLE, NO_NEW_PRIVS, RLIMIT_CORE (#2183)

* feat(sandbox/linux): seccomp filter + bwrap passthrough

- seccomp: BPF filter whitelisting safe syscalls, denying ptrace/mount/kexec
  and other dangerous syscalls. Uses raw BPF instructions via libc prctl to
  avoid external dependencies (#2182).
- bwrap: optional bubblewrap passthrough when /usr/bin/bwrap is present
  and [sandbox] prefer_bwrap=true in config. Creates read-only rootfs with
  write access limited to the working directory (#2184).
- landlock detect_denial extended to recognize seccomp SIGSYS/"Bad system
  call" patterns alongside existing Landlock EACCES/EPERM detection.
- SandboxManager gains prefer_bwrap field; set_prefer_bwrap on ShellManager.
- EngineConfig gains prefer_bwrap field, wired through main/ui/runtime_threads.
- Diagnostics now reports bwrap_available and cgroup_version.
- config.example.toml documents the prefer_bwrap key.

Pre-existing clippy fixes picked up in the same build:
- collapsible_if in ui.rs version-check
- cmp_owned in goal.rs test
- consecutive str::replace in normalize_auth_mode

Closes #2182, closes #2184

* docs: add cross-links to issue and PR templates in CONTRIBUTING.md (#2215)

- Link .github/ISSUE_TEMPLATE/bug_report.md and feature_request.md from
  the Reporting Issues section
- Link .github/PULL_REQUEST_TEMPLATE.md from the Pull Request Guidelines
  section

* feat(release): bundle platform archives with install scripts (#2216)

- Add bundle job to release workflow that creates per-platform archives
  (tar.gz for Linux/macOS, .zip for Windows) containing both codewhale
  and codewhale-tui binaries plus install scripts
- Create install.bat (Windows) — copies binaries to %USERPROFILE%\bin
- Create install.sh (Unix) — copies binaries to ~/.local/bin
- Windows gets a portable .zip variant without install script
- Release notes updated to promote archives as primary download method
- Individual binaries retained for npm wrapper and scripting

Closes #2193

* fix(web_search): fall back to DuckDuckGo when Bing returns zero results (#2130)

When the configured search provider is Bing and the query returns zero
results (common for technical/compound queries), fall through to the
DuckDuckGo path instead of reporting empty. A provenance message is
surfaced: "Bing returned no results; used DuckDuckGo fallback".

Also adds Security and Code of Conduct cross-links to CONTRIBUTING.md
per the sub-agent renovation (#2203).

* docs: SANDBOX.md threat model + RFCs for persistence and MCP + SandboxExecutor trait

- docs/SANDBOX.md: complete threat model describing each platform's sandbox
  (Seatbelt, Landlock, seccomp, process hardening, bwrap, Windows v1).
  Covers defense-in-depth layering, config keys, denial detection, limitations.
- docs/rfcs/2189-persistence-sqlite.md: RFC for SQLite migration (drafted by sub-agent)
- docs/rfcs/2190-mcp-modularization.md: RFC for MCP crate split into
  protocol/client/server with OAuth support
- crates/tui/src/sandbox/policy.rs: SandboxExecutor trait definition and
  SafetyLevel→SandboxPolicyBehavior mapping function with tests

Closes #2180, closes #2186, closes #2189, closes #2190

* feat: sandbox parity tests + remove sub-agent 100-turn cap

- Add sandbox parity tests covering platform detection, denial patterns,
  bwrap preference, and policy consistency across modes (#2187)
- Remove arbitrary 100-turn sub-agent cap: DEFAULT_MAX_STEPS changed
  from 100 to u32::MAX. Sub-agents now run until they produce a final
  text response, are cancelled by the parent, or hit a configured
  explicit budget (#2034)

Closes #2187, closes #2034
2026-05-26 09:52:22 -05:00

9.4 KiB
Raw Blame History

Contributing to codewhale

Thank you for your interest in contributing to codewhale! This document provides guidelines and instructions for contributing.

Getting Started

Prerequisites

  • Rust 1.88 or later (edition 2024)
  • Cargo package manager
  • Git

Setting Up Development Environment

  1. Fork and clone the repository:

    git clone https://github.com/YOUR_USERNAME/CodeWhale.git
    cd CodeWhale
    
  2. Build the project:

    cargo build
    
  3. Run tests:

    cargo test --workspace --all-features
    
  4. Run with development settings:

    cargo run --bin codewhale
    

Development Workflow

Code Style

  • Run cargo fmt before committing to ensure consistent formatting
  • Run cargo clippy and address all warnings
  • Follow Rust naming conventions (snake_case for functions/variables, CamelCase for types)
  • Add documentation comments for public APIs

Testing

  • Write tests for new functionality
  • Ensure all existing tests pass: cargo test --workspace --all-features
  • Colocate unit tests beside the code they cover (standard Rust #[cfg(test)] modules), and add integration tests under the owning crate's tests/ directory (for example crates/tui/tests/ or crates/state/tests/). The repository root tests/ directory is not used

Commit Messages

Use clear, descriptive commit messages following conventional commits:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • refactor: Code refactoring
  • test: Adding or updating tests
  • chore: Maintenance tasks

Example: feat: add doctor subcommand for system diagnostics

When a commit harvests code from a community PR (see "How Your Contribution Lands" below), include a Harvested from PR #N by @author line in the commit body. An auto-close workflow watches for this pattern and closes the referenced PR with credit so the contributor gets a clear signal that their work shipped.

How Your Contribution Lands

We follow a deliberate "land what's useful, credit the contributor" model that occasionally surprises new contributors. Two paths:

Path 1 — Direct merge

If your PR is well-scoped, passes CI, doesn't touch the trust-boundary surface (auth / sandbox / publishing / branding), and doesn't conflict with main, a maintainer merges it directly. This is the most common outcome for small bug fixes and well-tested feature additions.

Path 2 — Harvest

If your PR is large, mixes scope, conflicts with main, or needs polish that's faster for the maintainer to apply than to round-trip with the contributor, the maintainer may harvest the useful commits or hunks into a new commit on main rather than merging the PR directly. This is not a rejection — it means your code landed.

When this happens:

  • The harvested commit's message includes Harvested from PR #N by @your-handle. This is the contract: that line is your credit and the signal that your contribution shipped.
  • If the maintainer copies or adapts your code, the harvested commit also keeps attribution with the original author identity when possible: either by preserving the commit author on a cherry-pick or by adding a Co-authored-by: Name <email> trailer from the original PR commit. This is what lets GitHub's contribution surfaces recognize more than prose credit.
  • The CHANGELOG.md entry for the next release credits you by handle.
  • The auto-close workflow closes your PR with a templated thank-you and a link to the commit on main.

To make a future contribution land via the faster Direct-Merge path instead of the Harvest path, the highest-leverage things you can do are:

  1. Keep PRs single-purpose. One bug fix per PR; one feature per PR. Don't mix a refactor with a feature.
  2. Rebase onto current main before opening the PR, and after CI feedback. Conflicts force the harvest path even when the change is small.
  3. Include tests with new behavior. The maintainer often harvests PRs without tests because adding the test is faster than asking the contributor for one.
  4. Avoid the trust-boundary surface without prior maintainer sign-off. That includes auth/credential flows, sandbox policy, publishing/release plumbing, and prompts/ content. PRs that touch these without prior discussion are unlikely to merge directly even when the change is well-implemented.

Agent-Assisted Improvements

CodeWhale is allowed to help improve CodeWhale, but the contribution still has to be shaped for human review. The recommended workflow is the recursive self-improvement prompt: run it from a fresh fork or branch, let the agent find exactly one small friction point, and stop after one patch. DeepSeek V4 Pro is the first-class path for this loop today, but the review shape matters more than the provider.

The useful output is not "ideas for improvement." The useful output is a specific reproduction, a minimal diff, focused checks, and a PR description that explains the trade-off. Do not use an agent to touch auth, credentials, sandbox policy, publishing/release plumbing, provider policy, telemetry, sponsorship, branding, or global prompts without prior maintainer sign-off.

Project Structure

codewhale is a Cargo workspace. The live runtime and the majority of TUI, engine, and tool code currently live in crates/tui/src/. Smaller workspace crates provide shared abstractions that are being extracted incrementally.

crates/
├── tui/           codewhale-tui binary (interactive TUI + runtime API)
├── cli/           codewhale binary (dispatcher facade)
├── app-server/    HTTP/SSE + JSON-RPC transport
├── core/          Agent loop / session / turn management
├── protocol/      Request/response framing
├── config/        Config loading, profiles, env precedence
├── state/         SQLite thread/session persistence
├── tools/         Typed tool specs and lifecycle
├── mcp/           MCP client + stdio server
├── hooks/         Lifecycle hooks (stdout/jsonl/webhook)
├── execpolicy/    Approval/sandbox policy engine
├── agent/         Model/provider registry
└── tui-core/      Event-driven TUI state machine scaffold

See docs/ARCHITECTURE.md for the live data flow across these crates, including the bottom-up build order.

Submitting Changes

  1. Create a feature branch from main:

    git checkout -b feat/your-feature
    
  2. Make your changes and commit them

  3. Ensure CI passes:

    cargo fmt --all -- --check
    cargo clippy --workspace --all-targets --all-features
    cargo test --workspace --all-features
    
  4. Push your branch and create a Pull Request

  5. Describe your changes clearly in the PR description

Pull Request Guidelines

  • Use the pull request template when opening a PR — it includes the Summary, Testing, and Checklist sections reviewers expect
  • Keep PRs focused on a single change
  • Update documentation if needed
  • Add tests for new functionality
  • Ensure CI passes before requesting review

Shape of a Typical PR

A well-structured PR follows a consistent pattern. Recent exemplars include:

  • #386/init command: new crates/tui/src/commands/init.rs module, project-type detection, AGENTS.md generation, command registration in commands/mod.rs, localization strings.
  • #389 — Inline LSP diagnostics: LSP subsystem in crates/tui/src/lsp/, engine hooks in core/engine/lsp_hooks.rs, config toggle, test coverage.
  • #387 — Self-update: new crates/cli/src/update.rs module, CLI subcommand registration, HTTP download + SHA256 verification + atomic binary replacement.
  • #393/share session URL: new crates/tui/src/commands/share.rs, HTML rendering, gh gist create integration, command registration.
  • #343/#346 — (v0.8.5) Runtime thread/turn timeline and durable task manager refactors.

Typically each PR touches 13 new files, modifies 25 existing files for wiring (registries, dispatch matches, localization), and adds or updates tests. Changes are scoped to a single feature or fix — if you discover related work that needs doing, open a separate issue rather than expanding the PR scope.

Before submitting, run:

cargo fmt --check
cargo clippy --workspace --all-targets --all-features 2>&1 | head -50
cargo check

Reporting Issues

When reporting issues, please use one of the issue templates:

Issue reports should include:

  • Operating system and version
  • Rust version (rustc --version)
  • codewhale version (codewhale --version)
  • Steps to reproduce the issue
  • Expected vs actual behavior
  • Relevant error messages or logs

Security

If you discover a security vulnerability, please do not open a public issue. See SECURITY.md for the responsible disclosure process and contact information.

Code of Conduct

Be respectful and inclusive. We welcome contributors of all backgrounds and experience levels. See CODE_OF_CONDUCT.md for the full code of conduct.

License

By contributing to codewhale, you agree that your contributions will be licensed under the MIT License.

Questions?

Feel free to open an issue for any questions about contributing.