Quick contributor map for con.
Read these first:
README.md— public project overviewAGENTS.md— development conventionsDESIGN.md— architecture and product directiondocs/README.md— documentation index
Terminal crates do not depend on the UI. The agent crate does not depend on a specific terminal backend.
| Crate | Role |
|---|---|
con |
GPUI shell: windows, tabs, panes, agent UI, settings, command surfaces |
con-core |
Config, sessions, shared app logic, harness wiring |
con-terminal |
Theme + palette helpers shared across backends |
con-ghostty |
Per-platform terminal backends: macOS embedded libghostty + Metal, Windows libghostty-vt + ConPTY + D3D11/DirectWrite, Linux Unix PTY + libghostty-vt + GPUI-owned StyledText paint |
con-agent |
Rig integration, tools, hooks, conversation, skills |
con-cli |
CLI + socket client for the live local control plane |
Each platform exposes the same GhosttyApp / GhosttyTerminal /
TerminalColors type names from con-ghostty, so the rest of the
workspace consumes the backend without per-call-site cfg gates.
See docs/impl/{linux,windows}-port.md for the per-platform plans
and the path to the long-term GPU-accelerated grid renderer.
- Shared Tokio runtime per window
- Per-tab agent sessions
- Tool and model events flow to the UI over channels
- Rig
PromptHookdrives streaming, approvals, and lifecycle events
For the full breakdown, see docs/impl/agent-harness.md.
- Rust (stable, edition 2024)
cmake- Zig: use Zig 0.17.0 exactly for full terminal builds. The pinned Ghostty revision requires this version; older Zig releases cannot build it, and newer releases may change the build APIs again.
If you use mise, the repo root mise.toml
pins the exact Zig version. Run:
mise install # installs the pinned toolchain
mise exec -- just build # runs with Zig 0.17.0 on PATHRun the just commands below through mise exec -- so the pinned tools are
available even when mise shell activation is not configured. For example,
mise exec -- just test runs the platform-appropriate test set. If your shell
already activates mise, you can use just directly.
If you do not use mise, install the prerequisites yourself:
- Zig: download the official 0.17.0 archive from
https://ziglang.org/download/0.17.0/and put the directory onPATH, or setCON_ZIG_BIN=/path/to/zig. - macOS:
cmakeplus Zig 0.17.0. The macOS release workflow installs Zig 0.17.0 explicitly before building embedded libghostty. - Windows: Zig 0.17.0, Visual Studio 2022 Build Tools with the Windows 10/11 SDK. Run full builds from a Developer Command Prompt for VS 2022 so
rc.exeis onPATH. If Windows Defender is on, either add an exclusion for the repo dir or disable real-time scanning — Zig's sub-build exes get briefly locked by MpEngine and spawn withFileNotFound. - Linux: Zig 0.17.0, plus the GPUI runtime apt deps the CI job already installs:
The
sudo apt-get install -y --no-install-recommends \ libxcb-composite0-dev libxcb-dri2-0-dev libxcb-glx0-dev \ libxcb-present-dev libxcb-xfixes0-dev libxkbcommon-x11-dev \ libwayland-dev libvulkan-dev libfreetype-dev libfontconfig1-dev \ mesa-vulkan-drivers
mesa-vulkan-driversline gives you a software ICD (llvmpipe) as a fallback for headless / VM environments; on a real desktop with a hardware GPU you can skip it.
CI mirrors this deliberately:
release-macos.yml,release-linux.yml, andrelease-windows.ymlinstall Zig 0.17.0 before release builds.- macOS app packaging sets
CON_GHOSTTY_PREFETCH_DEPS=1to populate Zig's package cache through curl/git and localzig fetchbefore building. This avoids a reproducible Zig direct Git-fetch failure in release CI. Ordinary development builds do not prefetch; they retain the on-failure retry. SetCON_GHOSTTY_PREFETCH_DEPS=0to opt out while diagnosing a local package issue. ci-macos-ghostty.ymlbuilds the native Ghostty binding on an Intel runner when the build path changes. Its manual dispatch also builds the full release binaries without signing.- The Linux PR smoke check in
ci-portable.ymlalso installs Zig 0.17.0 because it type-checkscon-ghosttywithlibghostty-vt. - The Windows and Linux PR jobs build and link the real libghostty-vt backend, then run
con-ghosttytests. Do not replace these withCON_SKIP_GHOSTTY_VTor check-only coverage: removed symbols and calling-convention drift otherwise remain invisible until release.
# macOS / Linux
cargo build
# Windows — must use the `w*` aliases. The default `con` binary cannot
# exist on Windows because `CON` is a reserved DOS device name, so the
# Windows build ships as `con-app.exe` via a feature-gated alias bin
# target. `cargo wbuild` is `cargo build --no-default-features
# --features con/bin-con-app`; `wrun`, `wcheck`, `wtest` mirror it.
cargo wbuild -p con --release # → target\release\con-app.exeIf you have just installed, the root justfile wraps the common local
flows:
just build # debug build for the current platform
just run # run from source
just test # platform-appropriate test set
just check # fast type check
just install # build and install to the local platform install pathOn Windows, those default recipes dispatch through the cargo w* aliases
above, so they produce and run con-app.exe instead of trying to build a
reserved con.exe name. Platform-specific release helpers are also available,
for example just channel=beta macos-release,
just channel=beta linux-release, just arch=x86_64 macos-bundle, and
just windows-build-release.
# macOS / Linux
cargo run -p con
# Windows
cargo wrun -p conWith optional arguments:
RUST_LOG=con_agent::flow=info,con_agent=warn,con_core=warn,con::suggestions=debug,con_core::suggestions=debug cargo run -p conOrdinary debug builds read RustEmbed assets from the source checkout. Before copying a native debug app to another Mac of the same architecture, embed them:
cargo build -p con --bin con --features rust-embed/debug-embedThis builds the executable, not a complete signed app bundle. Keep con-cli
beside it, prepare the bundle separately, and isolate configuration and session
paths on the test host. Check startup logs for missing assets after transfer.
Copying a same-architecture binary avoids a heavy build on a shared CI runner.
cargo test --workspace # macOS / Linux
cargo wtest -p con-core -p con-cli -p con-agent -p con-terminal # Windows (portable crates only)cargo build --release -p con # macOS / Linux
cargo build --release -p con-cli # control-plane CLI
cargo wbuild -p con --release # Windows → target\release\con-app.exe
cargo build --release -p con-cli # Windows → target\release\con-cli.exeFor signed macOS release artifacts, use:
./scripts/macos/release.shThe macOS app bundle contains both Contents/MacOS/con and
Contents/MacOS/con-cli; the release verifier fails if the CLI is
missing. The Homebrew cask and Unix installer expose that bundled
con-cli on PATH so orchestrators such as pi-interactive-subagents
do not need a separate source checkout.
Release CI also has a final promotion gate. Platform jobs verify the
artifact shape before upload, and release-finalize.yml keeps the
GitHub Release drafted unless all expected assets, appcasts, and
gh-pages installer scripts are present for the same tag. A broken
artifact should fail private, not become /releases/latest. Internal
v*-dev.* smoke tags are prereleases, never update public
stable/beta appcasts or Homebrew casks, do not embed a Sparkle feed URL,
and are only gated on artifact and installer-script shape.
For a Linux release tarball (un-signed; mirrors the Windows preview's distribution shape), use:
CON_RELEASE_VERSION=0.1.0-beta.X CON_RELEASE_CHANNEL=beta \
./scripts/linux/release.shOutput lands in dist/con-<version>-linux-<arch>.tar.gz with a
SHA256 sum next to it. The CI workflow at
.github/workflows/release-linux.yml runs the same script on every
v* tag, attaches the tarball to the shared GitHub release, and
updates the Sparkle-shaped appcast at
https://con-releases.nowledge.co/appcast/<channel>-linux-x86_64.xml
that the in-app notify-only updater polls.
crates/con-app/src— app shell and GPUI surfaces (the crate directory iscon-appbecauseconis a reserved DOS device name on Windows; the Cargo package and binary are still namedconon macOS, socargo run -p conworks as before — seedocs/impl/windows-port.md)crates/con-core/src— shared app logiccrates/con-agent/src— agent provider, hooks, tools, skillsdocs/design— design handoff setdocs/impl— implementation notespostmortem— issue writeups and lessons learned