← All tools

bigmoostache/context-pilot

Popularity 75 Updated Development & Build

AI-native terminal IDE. You control what your AI sees.

githubauto-collected

Installation

A directly usable install command is not verified yet. Check the project documentation or releases.

Context Pilot

An AI coding agent that lives in your terminal — and a fleet orchestrator and web cockpit to run many of them at once.

Context Pilot is a ~47,000-line Rust project (18 module crates + a main binary + an orchestration backend) plus a React web client. It started as a single self-hosting TUI in which an AI agent develops the very tool it runs inside, and grew an orchestration layer so that a fleet of such agents can be discovered, observed, commanded, and supervised — from the terminal or from a browser.

This document describes how the whole thing fits together: the agent's main loop, the module system, the three-tier durability model, the orchestrator, the bridge that joins an agent to a fleet, the web frontend, and the sidecar services (console server, Meilisearch, SQLite entities).

---

1. System overview

Context Pilot is not one process. It is a small constellation of cooperating surfaces:

                         ┌───────────────────────────────────────────┐
                         │              Web frontend (web/)           │
                         │  React 19 · TanStack Query · Vite · SSE    │
                         └───────────────┬───────────────────────────┘
                                         │  REST + Server-Sent Events
                                         │  (HTTP :7878)
                         ┌───────────────▼───────────────────────────┐
                         │        Orchestrator  (cp-orchestrator)     │
                         │  registry · materialized view ·             │
                         │  stream hub · supervisor · REST/SSE        │
                         └───┬───────────────┬───────────────┬────────┘
            oplog tail       │   commands     │   stream tap  │   spawn / signals

┌───▼───────────────▼───────────────▼────────┐ │ Agent (the TUI, src/) │ │ event loop · modules · LLM streaming · │ │ bridge (CPBRIDGE=1) · tier-② state │ └───┬───────────────┬───────────────┬────────┘ │ │ │ ┌───────▼──────┐ ┌──────▼──────┐ ┌──────▼───────┐ │ Console server│ │ Meilisearch │ │ SQLite │ │ (long-running │ │ (full-text │ │ entities │ │ processes) │ │ search) │ │ (structured) │ └───────────────┘ └─────────────┘ └───────────────┘


**One agent = one folder.** Every agent owns a *realm* (a working directory) and stores all its state under `<folder>/.context-pilot/`. Switching agents is switching folders. The orchestrator manages many such realms; the web cockpit renders them.

| Surface | Crate / dir | Role |
|---|---|---|
| **Agent (TUI)** | `src/` (`tui` binary) | The interactive coding agent: event loop, tools, LLM streaming, panels, persistence. |
| **Orchestrator** | `crates/cp-orchestrator` | Fleet control plane: discover, observe, command, supervise; serves REST + SSE on `:7878` (loopback — on the appliance Caddy fronts it on `:80`/`:443`). |
| **Web frontend** | `web/` | Browser cockpit: fleet dashboard, per-agent threads / panels / file manager. |
| **Console server** | `crates/cp-console-server` | Per-realm daemon running child processes that survive TUI restarts. |
| **Meilisearch** | external process | Full-text index of project files + logs. |

---

2. The agent (TUI)

The agent is a blocking, single-threaded Elm/Redux-style application built on Ratatui + Crossterm. No async runtime — everything is driven by one event loop.

Main loop

src/app/run/lifecycle.rs is the heart. Each iteration is input-first (a non-blocking poll), then it advances background work: stream events, the tool pipeline, cache updates, file/GitHub watchers, the spine (notifications), and reverie (the context optimizer). The loop runs on an adaptive cadence — ~8 ms while streaming or when panels are dirty, ~2 ms when an orchestrator is connected (so a web command applies within a tick), ~50 ms when idle — and renders at ~28 fps.

State changes flow through a central action dispatcher (src/app/actions/), Redux-style: an action mutates State, the next render reflects it. Key pipelines:

  • Streaming (src/app/run/streaming.rs) — LLM chunks drive a typewriter buffer; ToolUse blocks queue pending tool calls; Done finalizes the message and reconciles token/cost accounting. API errors retry with backoff.
  • Tool pipeline (src/app/run/tools/pipeline.rs) — pre-flight validation → queue interception → execution → file-edit callbacks → tempo break → sentinel deferral. Each tool is its own flame-graph span.
  • Prompt assembly (src/app/promptbuilder.rs) — rebuilds the LLM prompt in three phases: context panels injected as synthetic tooluse/toolresult pairs, then the conversation history, then strict role alternation.

Main-loop watchdog

Because the loop is single-threaded, every step runs inline on the one thread — so any synchronous block (a tool hitting a hung dependency, a slow panel rehash, a lock wait, a stalled socket read) freezes the entire UI for its full duration, historically with no trace of which step wedged. The watchdog (src/app/run/tools/watchdog.rs) ends that blind spot. It is the interactive sibling of the headless deadman, but purely observational: it never terminates, re-execs, or signals the process (a human is at the keyboard) — it only writes a diagnostic so a freeze that "had no apparent reason" becomes "the log says it wedged in <step for <Ns."