# Technical Orientation

> What Warp is, how the Cargo workspace and the app binary fit together, the per-channel entry points under app/src/bin, and how the rest of this developer reference is organized.

- Repository: warpdotdev/warp
- GitHub: https://github.com/warpdotdev/warp
- Human wiki: https://grok-wiki.com/public/wiki/warpdotdev-warp-a55b6d0c09b5
- Complete Markdown: https://grok-wiki.com/public/wiki/warpdotdev-warp-a55b6d0c09b5/llms-full.txt

## Source Files

- `README.md`
- `WARP.md`
- `Cargo.toml`
- `app/Cargo.toml`
- `app/src/bin/stable.rs`
- `app/src/bin/oss.rs`
- `app/src/app_state.rs`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [README.md](README.md)
- [WARP.md](WARP.md)
- [Cargo.toml](Cargo.toml)
- [app/Cargo.toml](app/Cargo.toml)
- [app/src/bin/stable.rs](app/src/bin/stable.rs)
- [app/src/bin/oss.rs](app/src/bin/oss.rs)
- [app/src/bin/local.rs](app/src/bin/local.rs)
- [app/src/bin/dev.rs](app/src/bin/dev.rs)
- [app/src/bin/preview.rs](app/src/bin/preview.rs)
- [app/src/bin/integration.rs](app/src/bin/integration.rs)
- [app/src/bin/channel_config.rs](app/src/bin/channel_config.rs)
- [app/src/lib.rs](app/src/lib.rs)
- [app/src/app_state.rs](app/src/app_state.rs)
- [crates/warp_core/src/channel/mod.rs](crates/warp_core/src/channel/mod.rs)
- [crates/warp_core/src/channel/config.rs](crates/warp_core/src/channel/config.rs)
- [crates/warp_core/src/channel/state.rs](crates/warp_core/src/channel/state.rs)
- [crates/warp_features/src/lib.rs](crates/warp_features/src/lib.rs)
</details>

# Technical Orientation

This page orients a developer to the **warpdotdev/warp** repository: what Warp is, how its Cargo workspace is laid out, how the `app` crate produces several near-identical channel binaries from one shared library, and how the per-channel entry points under `app/src/bin` differ only in the configuration and feature flags they install before calling the common `warp::run()`. It is the entry door to the rest of this developer reference; later pages drill into the subsystems this page names (terminal, AI/agents, UI framework, persistence, cloud sync).

Warp is **an agentic development environment, born out of the terminal** — a Rust terminal emulator with a custom UI framework, a built-in coding agent, and support for bringing your own CLI agent (Claude Code, Codex, Gemini CLI, and others). The client codebase is open source in this repository; the UI framework crates (`warpui_core`, `warpui`) are MIT-licensed and the rest is AGPL v3.

Sources: [README.md:32-58](), [WARP.md:55-91]()

## The Cargo Workspace

The repository is a single Cargo workspace whose members are every directory under `crates/*` plus the `app` crate. WARP.md describes this as a workspace with **60+ member crates**, with the main binary in `app/` and the UI framework in `crates/warpui/`.

```toml
# Cargo.toml
[workspace]
members = [
  "crates/*",
  "app",
]
resolver = "2"
```

A separate `default-members` list narrows what `cargo build`/`cargo test` touch by default. It deliberately excludes `serve-wasm` (a helper for serving wasm binaries) and `integration` (used only for testing), while keeping `app` and a focused set of fast-iterating crates such as `editor`, `warpui`, `warp_terminal`, and `warp_completer`.

The workspace also centralizes dependency versions. Internal crates are declared once under `[workspace.dependencies]` with `path = "crates/..."`, so member crates reference them as `foo.workspace = true` rather than repeating paths or versions — for example `warp = { path = "app" }`, `warp_core = { path = "crates/warp_core" }`, and `warpui = { path = "crates/warpui" }`. Shared third-party versions (tokio, reqwest, wgpu, diesel, etc.) live in the same table. Workspace-wide package metadata sets the AGPL-3.0-only license and marks all crates `publish = false`.

```text
warp workspace (Cargo.toml)
├── app/                      → the application crate (lib + 7 bins)
└── crates/*                  → 60+ supporting crates
     ├── warp_core            channel/state, feature flags, platform abstractions
     ├── warpui, warpui_core  custom UI framework (MIT)
     ├── warp_terminal        terminal emulation core
     ├── editor               text editing
     ├── persistence          Diesel + SQLite storage
     ├── graphql              GraphQL client/schema
     └── ai, mcp, ipc, lsp …  agents, tooling, IPC, language servers
```

Sources: [Cargo.toml:1-28](), [Cargo.toml:30-96](), [WARP.md:78-99]()

## The `app` Crate: One Library, Many Binaries

The `app` crate (package `warp`, library name `warp`) is the heart of the client. Almost all application logic lives in its library (`src/lib.rs`); the binaries are thin wrappers. `autobins = false` disables Cargo's automatic binary discovery so that every binary target is declared explicitly, and `default-run = "warp-oss"` makes the open-source binary the one `cargo run` launches without arguments.

```toml
# app/Cargo.toml
[package]
default-run = "warp-oss"
autobins = false
name = "warp"

[lib]
name = "warp"
path = "src/lib.rs"
```

The crate declares **seven binary targets**. Six are channel/role front-ends, and one (`generate_settings_schema`) is a build-time tool. The comment in the manifest states the intent directly: each channel binary exists "so that we can bundle with its own icon, app name, and channel-specific configuration (such as flag overrides). Otherwise these binaries are exactly identical to our main binary."

| Binary target | Path | Purpose | Notes |
|---|---|---|---|
| `warp-oss` | `src/bin/oss.rs` | Open-source build (default `cargo run`) | Production server config, no telemetry/crash reporting |
| `warp` | `src/bin/local.rs` | Internal HEAD build | Bundle id `dev.warp.Warp-Local` |
| `stable` | `src/bin/stable.rs` | First-party stable release | Loads `"stable"` channel config |
| `preview` | `src/bin/preview.rs` | First-party feature-preview release | Requires `preview_channel` feature |
| `dev` | `src/bin/dev.rs` | Internal nightly build | |
| `integration` | `src/bin/integration.rs` | Integration-test build | Parses `WorkerCommand` subcommands |
| `generate_settings_schema` | `src/bin/generate_settings_schema.rs` | Settings-schema generator tool | |

The `[package.metadata.bundle.bin.*]` tables give each channel binary its own bundle identity — e.g. `stable` bundles as `name = "Warp"`, `preview` as `WarpPreview` (`dev.warp.Warp-Preview`), and `warp-oss` as `WarpOss` (`dev.warp.WarpOss`) — confirming that the binaries differ in packaging, not in core code.

Sources: [app/Cargo.toml:1-54](), [app/Cargo.toml:972-1021]()

## Per-Channel Entry Points

Every channel binary follows the same three-line shape: build a `ChannelState`, install it as global state via `ChannelState::set(...)`, then hand off to the shared `warp::run()`. The differences are entirely in *which* configuration and *which* feature-flag sets each one layers in.

```mermaid
flowchart TB
    subgraph bins["app/src/bin (per-channel front-ends)"]
        oss["oss.rs<br/>Channel::Oss"]
        local["local.rs<br/>Channel::Local"]
        stable["stable.rs<br/>Channel::Stable"]
        preview["preview.rs<br/>Channel::Preview"]
        dev["dev.rs<br/>Channel::Dev"]
        integ["integration.rs<br/>Channel::Integration"]
    end

    cfg["channel_config::load_config!<br/>(generator binary or embedded JSON)"]
    state["warp_core::channel::ChannelState<br/>ChannelState::set(...) → global"]
    flags["warp_features flag sets<br/>DEBUG / DOGFOOD / PREVIEW / RELEASE"]
    run["warp::run()<br/>app/src/lib.rs (shared entry)"]

    oss --> state
    local --> cfg
    stable --> cfg
    preview --> cfg
    dev --> cfg
    integ --> state
    cfg --> state
    flags --> state
    state --> run
```

**Configuration source.** Internal channels (`stable`, `dev`, `preview`, `local`) obtain their `ChannelConfig` through the `load_config!` macro in `channel_config.rs`. That macro switches on the `release_bundle` feature: bundled builds embed the JSON config at compile time via `include_str!` of `<channel>_config.json` in `OUT_DIR`, while non-bundled builds shell out at runtime to a `warp-channel-config` generator binary that must be on `PATH`. By contrast, `oss.rs` and `integration.rs` construct `ChannelConfig` inline in Rust — the OSS build uses `WarpServerConfig::production()` / `OzConfig::production()` with telemetry, crash reporting, autoupdate, and MCP static config all set to `None`; the integration build points server URLs at the black-hole IANA test address `192.0.2.0:9`.

```rust
// app/src/bin/stable.rs
fn main() -> Result<()> {
    ChannelState::set(ChannelState::new(
        Channel::Stable,
        channel_config::load_config!("stable"),
    ));
    warp::run()
}
```

**Feature-flag layering.** Each channel applies `with_additional_features(...)` for its audience. Internal channels stack the broadest sets — `local.rs` and `dev.rs` add `DEBUG_FLAGS`, `DOGFOOD_FLAGS`, *and* `PREVIEW_FLAGS`; `preview.rs` adds `PREVIEW_FLAGS` plus a forced-login flag; `oss.rs` adds `DEBUG_FLAGS` only in debug builds. These flag arrays are defined in the `warp_features` crate (re-exported as `warp_core::features`). `local.rs` even reads an env var to conditionally enable a sandbox-telemetry flag.

```rust
// app/src/bin/local.rs
let mut state = ChannelState::new(Channel::Local, config)
    .with_additional_features(features::DEBUG_FLAGS)
    .with_additional_features(features::DOGFOOD_FLAGS)
    .with_additional_features(features::PREVIEW_FLAGS);
```

The `integration` binary is the one structurally distinct front-end: it uses `clap` to parse optional `WorkerCommand` subcommands (e.g. running as a terminal server, remote-server proxy, or daemon) before falling back to `warp::run()`.

Sources: [app/src/bin/stable.rs:12-19](), [app/src/bin/oss.rs:10-30](), [app/src/bin/local.rs:8-24](), [app/src/bin/dev.rs:13-22](), [app/src/bin/preview.rs:13-21](), [app/src/bin/integration.rs:15-73](), [app/src/bin/channel_config.rs:25-101](), [crates/warp_features/src/lib.rs:896-956]()

## `Channel`, `ChannelState`, and `ChannelConfig`

The model the entry points install lives in `crates/warp_core/src/channel`. The `Channel` enum enumerates the six channels and encodes behavior policy on them: `is_dogfood()` is true only for `Dev`/`Local`, and `allows_server_url_overrides()` is true only for the internal channels (`Dev`, `Local`, `Integration`) — release channels (`Stable`, `Preview`, `Oss`) ignore `--server-root-url` and friends so shipped builds can't be redirected from their baked-in URLs. Each channel also maps to a CLI command name (e.g. `Stable → "oz"`, `Oss → "warp-oss"`).

`ChannelConfig` is the per-channel data record: an `app_id`, a logfile name, a `WarpServerConfig` (server, RTC, session-sharing URLs, Firebase key), an `OzConfig` for ambient-agent dashboards, and optional telemetry/autoupdate/crash-reporting/MCP configs. `WarpServerConfig::production()` and `OzConfig::production()` bake in the real `app.warp.dev` / `oz.warp.dev` endpoints.

`ChannelState` is held in a process-global `lazy_static` `Mutex`. `ChannelState::set(...)` is what the entry points call; thereafter, code anywhere reads the active channel and resolved URLs through associated functions like `ChannelState::channel()`, `ChannelState::server_root_url()`, and `ChannelState::ws_server_url()`. This is why the `main()` functions can be three lines: they seed one global, and the rest of the app reads from it.

```rust
// crates/warp_core/src/channel/state.rs
lazy_static! {
    static ref CHANNEL_STATE: Mutex<ChannelState> = Mutex::new(ChannelState::init());
}
```

Sources: [crates/warp_core/src/channel/mod.rs:9-74](), [crates/warp_core/src/channel/config.rs:7-72](), [crates/warp_core/src/channel/state.rs:15-99]()

## The Shared Entry Point: `warp::run()`

After channel state is installed, all binaries converge on `warp::run()` in `app/src/lib.rs`. This is where the application actually starts: it performs platform-specific init, initializes feature flags, and parses CLI arguments. It then honors server-URL overrides only when `ChannelState::channel().allows_server_url_overrides()` is true — closing the loop on the release-channel safety property described above. Finally it dispatches: if a `warp_cli` subcommand was given (terminal server, plugin host, minidump server, remote-server proxy/daemon, ripgrep search, …) it runs that worker and returns; otherwise it proceeds into the normal GUI launch.

```rust
// app/src/lib.rs
pub fn run() -> Result<()> {
    platform::init();
    features::init_feature_flags();
    let args = warp_cli::Args::from_env();
    if ChannelState::channel().allows_server_url_overrides() {
        // apply --server-root-url / --ws-server-url overrides
    }
    // dispatch worker subcommands, else launch the app
}
```

A complementary piece of the `app` crate is `app_state.rs`, which defines the serializable `AppState` / `WindowSnapshot` / `TabSnapshot` types used to persist and restore window, tab, and pane layout across launches — distinct from channel state, but part of the same crate's startup responsibilities.

Sources: [app/src/lib.rs:579-662](), [app/src/app_state.rs:26-69]()

## How the Rest of This Reference Is Organized

This page is the orientation layer. The subsystems it names map onto the deeper pages of this developer reference, grounded in the structure WARP.md and the workspace already expose:

| Area | Where it lives | Deeper-reference topic |
|---|---|---|
| UI framework (Entity-Component-Handle, `App`/`ViewHandle`) | `crates/warpui`, `crates/warpui_core` | WarpUI architecture |
| Terminal emulation & shell | `app/src/terminal/`, `crates/warp_terminal` | Terminal model (note the `model.lock()` deadlock caution) |
| AI / Agent Mode | `app/src/ai/`, `crates/ai`, `crates/mcp` | Agents, MCP, BYO-CLI agents |
| Channels & feature flags | `crates/warp_core/src/channel`, `crates/warp_features` | Build channels, flag rollout |
| Persistence | `crates/persistence` (Diesel + SQLite) | Storage & migrations |
| GraphQL & cloud sync | `crates/graphql`, `app/src/drive/` | Warp Drive, server protocol |
| Build & dev workflow | `script/bootstrap`, `script/run`, `script/presubmit` | Building locally, presubmit checks |

The recommended starting point for actually building is the three-command flow in the README (`./script/bootstrap`, `./script/run`, `./script/presubmit`), with WARP.md as the full engineering guide for coding style, testing conventions (`cargo nextest`, `${filename}_tests.rs`), and the feature-flag lifecycle.

In short: a single Cargo workspace builds one shared `warp` library, which several thin per-channel binaries in `app/src/bin` wrap by installing a channel-specific `ChannelState` (config + feature flags) before delegating to `warp::run()`. Understanding that fan-in is the key to navigating everything else in the codebase.

Sources: [WARP.md:55-99](), [README.md:73-83](), [Cargo.toml:1-23]()
