Warp Rust warpdotdev/warp

Getting Started with Your First Contribution to Warp

Walk the README, the bootstrap script, the run script, the presubmit gate, a contributor SKILL.md, and the CONTRIBUTING.md flow before opening your first PR.

7 stops ~18 min Verified 2026-05-04
What you will learn
  • How the README's three-script inner loop maps to the rest of the contribution workflow
  • What the macOS bootstrap actually installs and why each missing-tool branch exits early
  • How script/run dispatches between the macOS .app bundle build and a plain cargo run on Linux and Windows
  • What script/presubmit checks (fmt, two clippy passes, tests) and why running it locally avoids a wasted Oz review cycle
  • How a contributor-facing SKILL.md frontmatter signals when an agent or human should load that skill
  • The five-step Code PR flow in CONTRIBUTING.md and why you do not request reviewers manually
  • Where to go next: the Architecture and Agent Skills tours from WARP.md's overview
Prerequisites
  • A macOS, Linux, or Windows machine where you can run cargo
  • Comfort reading bash and YAML frontmatter
  • No prior Rust knowledge required to follow the workflow stops
1 / 7

README: The Three-Script Inner Loop

README.md:61

The README documents three scripts that abstract every platform and channel difference behind one inner-loop interface.

The README answers the first question every new contributor has: what do I run to get this thing building. Three scripts cover the whole inner loop, and the README pins them by name. ./script/bootstrap sets up the platform, ./script/run builds and launches Warp, and ./script/presubmit runs the checks CI will run on your PR. Reading these in order before opening any file gives you a working build and a confidence check that your machine is configured.

The pointer at the bottom matters too. WARP.md is the engineering guide that any agent or contributor lands on next. It documents commands, the WarpUI patterns, the testing bar, and the platform-specific notes the bootstrap script is light on. Read the README, run the three scripts, then open WARP.md.

Key takeaway

Three scripts make up the inner loop: ./script/bootstrap, ./script/run, ./script/presubmit. Run them in that order before reading any code.

### Building the Repo Locally

To build and run Warp from source:

```bash
./script/bootstrap   # platform-specific setup
./script/run         # build and run Warp
./script/presubmit   # fmt, clippy, and tests
```

See [WARP.md](WARP.md) for the full engineering guide, including coding style, testing, and platform-specific notes.
2 / 7

Bootstrap: Probe-and-Install for Rust

script/macos/bootstrap:20

The macOS bootstrap probes for each tool with command -v and only installs what is missing.

Setting up a Rust toolchain by hand is a small ritual every contributor knows. Warp's macOS bootstrap reduces it to a probe-and-install pattern: check whether brew is on PATH, install it if missing; check whether cargo is on PATH, run the rustup one-liner if missing. Each missing-tool branch exits and asks you to start a new shell, because the freshly installed binaries only land on PATH after a fresh login or a manual source.

Once both tools are present, the script invokes install_cargo_test_deps and install_cargo_release_deps to install the cargo-managed binaries the build and test pipeline expect. The pinned cargo-bundle install at the end is the macOS-specific bit: a forked revision is required because the --profile flag landed on a fork before reaching crates.io. After this script finishes, ./script/run can build the app.

Key takeaway

The bootstrap probes for brew, cargo, and the cargo-bundle fork, installing each only when missing. Idempotent re-runs are safe.

if ! command -v brew; then
    echo "Installing brew..."
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    echo "Please make sure brew is set correctly in your PATH"
    exit 1
fi

if ! command -v cargo; then
    echo "Installing rust..."
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    echo "Please start a new terminal session so that cargo is in your PATH"
    exit 1
fi

# Install various binaries through cargo.
"$PWD"/script/install_cargo_test_deps
"$PWD"/script/install_cargo_release_deps

# Install a version of cargo-bundle that supports the --profile flag
cargo install cargo-bundle --git=https://github.com/burtonageo/cargo-bundle --rev ae4c76e92c08774bf54ff077b1c52e3d1cd6c16d
3 / 7

script/run: Platform Switch at the Bottom

script/run:111

The platform switch dispatches to a macOS bundle build or a plain cargo run for Linux and Windows.

The platform switch at the end of script/run handles three operating systems with one rule each. The script routes Darwin to ./script/macos/run for the full .app bundle build, and Linux or Windows to a plain cargo run with the bin name set in WARP_BIN_NAME. That bin name was set earlier based on whether the internal channel config tool is on PATH, so outside contributors get warp-oss automatically.

The forked invocation pattern repeats for each branch. If the user passed extra arguments after a literal double-dash separator, those get forwarded to the resulting Warp process; otherwise the simpler invocation runs. The echo before the Linux cargo run prints the exact command being executed, which is the kind of small affordance that pays off when a contributor needs to copy a build invocation into a debugger or a shell history search.

Key takeaway

The trailing platform switch in script/run routes macOS to a full .app bundle build and other platforms to a plain cargo run.

if [[ "$OS_TYPE" = "Darwin" ]]; then
  if [[ ${#WARP_ARGS[@]} -gt 0 ]]; then
    exec ./script/macos/run "${MAC_ARGS[@]}" -- "${WARP_ARGS[@]}"
  else
    exec ./script/macos/run "${MAC_ARGS[@]}"
  fi
elif [[ "$OS_TYPE" = "Linux" ]] || [[ "$OS_TYPE" =~ ^(MINGW64_NT|MSYS_NT) ]]; then
  echo "Running cargo run --bin $WARP_BIN_NAME --features \"$FEATURES\" ${CARGO_PARAMS[*]}"
  if [[ ${#WARP_ARGS[@]} -gt 0 ]]; then
    cargo run --bin "$WARP_BIN_NAME" --features "$FEATURES" "${CARGO_PARAMS[@]}" -- "${WARP_ARGS[@]}"
  else
    cargo run --bin "$WARP_BIN_NAME" --features "$FEATURES" "${CARGO_PARAMS[@]}"
  fi
else
  echo "No run script defined for the current platform ($OS_TYPE)!" >&2
  exit 1
fi
4 / 7

presubmit: Format, Lint, Test

script/presubmit:9

script/presubmit runs cargo fmt, two clippy invocations, then tests. Failing it locally predicts CI failure.

Running CI's checks locally before pushing saves a round trip with Oz. script/presubmit is the canonical pre-PR gate, and the first two stages it runs are formatting and linting. cargo fmt with the --check flag fails the script if any file is unformatted, and the error message tells you the exact command to run to fix it. You do not have to scan a diff manually. The clippy stage is split into two invocations because warp_completer has feature-gated WIP code that does not yet pass --all-features. The main workspace runs with -D warnings so any new warning fails the gate, and warp_completer runs separately with default features. Catching this before opening a PR matters because Oz's first review will run the same checks; failing them means a wasted review cycle. Run presubmit, fix what it flags, then push.

Key takeaway

Run ./script/presubmit before pushing. It runs cargo fmt, two clippy passes, plus tests, matching what Oz checks on review.

FMT_COMMAND="cargo fmt"
echo "Running $FMT_COMMAND..."
set -e
EXIT_CODE=0
$FMT_COMMAND -- --check || EXIT_CODE=$?
if [[ $EXIT_CODE -ne 0 ]]; then
    echo 'Run `'"$FMT_COMMAND"'` to fix.'
    exit $EXIT_CODE
fi

echo "Cargo fmt succeeded..."

echo "Running clippy..."
# Exclude warp_completer because we run clippy on it with default features (rather than all features) below.
#
# TODO(vorporeal): Re-enable the `all-features` flag once we've fixed things.
cargo clippy --workspace --exclude warp_completer --all-targets --tests -- -D warnings
# Run clippy on warp_completer with default, rather than all features enabled, because there is
# feature-gated logic for the WIP completions-on-js implementation.
cargo clippy -p warp_completer --all-targets --tests -- -D warnings
echo "clippy succeeded..."
5 / 7

create-pr SKILL.md: The Contributor Checklist

.agents/skills/create-pr/SKILL.md:1

SKILL.md frontmatter tells the harness when to load the skill; the body documents the contributor checklist.

The create-pr skill exists because opening a PR in this repo has steps a fresh contributor will not guess. The frontmatter tells the harness when to load this skill: any user intent mentioning opening a PR, submitting changes, or preparing code for merge. The body then walks through the checklist.

The Related Skills section is the part to read first. Each entry is a hand-off: fix-errors runs after presubmit fails, rust-unit-tests runs while you are writing the change, warp-integration-test covers the user-visible flow bar, and add-feature-flag gates risky changes. A coding agent loaded in this repo discovers the skill by description, then chains to the related skills as the contribution unfolds. A human contributor reads the same file and gets the same map.

Key takeaway

The create-pr skill is the contributor checklist for opening a PR. Read it before your first push; it links to the four sibling skills.

---
name: create-pr
description: Create a pull request in the warp repository for the current branch. Use when the user mentions opening a PR, creating a pull request, submitting changes for review, or preparing code for merge.
---

# create-pr

## Overview

This guide covers best practices for creating pull requests in the warp repository, including merging master, running presubmit checks, linking Linear tasks, ensuring appropriate test coverage, and structuring your PR for effective review.

## Related Skills

- `fix-errors` - Fix presubmit failures (formatting, linting, tests) before opening PR
- `rust-unit-tests` - Write unit tests for your changes, if applicable (see "Testing Requirements" below)
- `warp-integration-test` - Add or update integration coverage for user-visible flows, regressions, and P0 use cases
- `add-feature-flag` - Gate changes behind feature flags
6 / 7

CONTRIBUTING.md: Opening a Code PR

CONTRIBUTING.md:100

The code-PR section lists five contributor steps and explains why you do not request reviewers yourself.

Once your change is ready, the code-PR section is the rule book. Five steps in order: branch from master, implement with tests, run ./script/presubmit, open the PR with the template plus a changelog entry, and keep the diff focused on one logical change. The changelog entry is a single file under CHANGELOG-NEW-FEATURE, CHANGELOG-IMPROVEMENT, or CHANGELOG-BUG-FIX; a missing entry will be flagged unless your PR is docs-only.

The reviewer flow is the surprise. You do not request reviewers manually. Oz auto-assigns itself when the PR opens against a ready issue, produces the first review, and then auto-requests a Warp subject-matter expert once it approves. After you push fixes, comment /oz-review to trigger a re-review, capped at three per PR. Past that, mention @oss-maintainers to escalate. The whole flow is automated until escalation is needed.

Key takeaway

The code-PR section gives a five-step checklist plus an automated reviewer flow. Oz reviews first, then a Warp engineer; /oz-review requests up to three re-reviews.

## Opening a Code PR

For issues labeled `ready-to-implement` (this includes any triaged bug):

1. Branch from `master`.
2. Implement the change and add tests (see [Testing](#testing)).
3. Run `./script/presubmit` and fix any failures before pushing.
4. Open a PR using the [pull request template](.github/pull_request_template.md) and add a changelog entry (`CHANGELOG-NEW-FEATURE`, `CHANGELOG-IMPROVEMENT`, or `CHANGELOG-BUG-FIX`); omit only for docs-only or refactoring-only changes.
5. Keep the PR focused on a single logical change and merge `master` in before the PR enters review.

You **do not need to manually request reviewers**. Oz is auto-assigned to PRs that target a ready issue and produces an initial review. After Oz approves, it automatically requests a follow-up review from the appropriate Warp team subject-matter expert.

After you push changes that address Oz's feedback, comment `/oz-review` on the PR to request a re-review — you can do this up to **three times** per PR. If something looks stuck or you need more reviews than that, mention **@oss-maintainers** on the PR to escalate to the team.
7 / 7

WARP.md: Where to Dive Deeper

WARP.md:44

WARP.md's Architecture Overview names the WarpUI Entity-Component-Handle pattern and points to the major subsystems.

After your first PR lands, the question becomes: where do I look next. WARP.md is the engineering guide and its Architecture Overview section is the map. WarpUI is called out first because every UI change in this repo touches it: an Entity-Component-Handle pattern with a global App object, ViewHandle references between views, and an AppContext that hands out temporary access during render and event dispatch. The Flutter-inspired Element layout and Actions event system follow.

The MouseStateHandle warning is the kind of repo-specific detail you only learn the hard way otherwise: create it once at construction, clone it where you need it, and never inline a default() while rendering. From here, the Architecture tour walks the workspace, the Tokio runtime, the wgpu glyph shader, and the IPC; the Agent Skills tour walks the contributor surface in depth.

Key takeaway

WARP.md is the engineering guide. After your first PR, the Architecture and Agent Skills tours walk the rest of the codebase.

## Architecture Overview

This is a Rust-based terminal emulator with a custom UI framework called **WarpUI**.

### Key Components

**WarpUI Framework** (`ui/`):
- Custom UI framework with Entity-Component-Handle pattern
- Global `App` object owns all views/models (entities)
- Views hold `ViewHandle<T>` references to other views
- `AppContext` provides temporary access to handles during render/events
- Elements describe visual layout (Flutter-inspired)
- Actions system for event handling
- MouseStateHandle must be created once during construction, and then referenced/cloned anywhere we're using mouse input to track mouse changes. Inline `MouseStateHandle::default()` while rendering will cause no mouse interactions to work.
Your codebase next

Create code tours for your project

Intraview lets AI create interactive walkthroughs of any codebase. Install the free VS Code extension and generate your first tour in minutes.

Install Intraview Free