AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
A GPU terminal where everything renders as tiles, no overlays. Auto-tiling panes, a docked input bar, a live sidebar. Built in Rust.
Translation pending
Developer toolsRust · HTMLGitHub @ashishtyagi10OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Loading the full README. The saved excerpt is shown below.
A from-scratch, native GPU terminal written in Rust — an AI-oriented terminal
where everything renders as tiles (no overlays). Panes auto-tile into a
near-square grid, drawn cell-by-cell on the GPU with winit + wgpu +
glyphon. See docs/CREW.md for the full guide.Read the full README ↗A from-scratch, native GPU terminal written in Rust — an AI-oriented terminal
where everything renders as tiles (no overlays). Panes auto-tile into a
near-square grid, drawn cell-by-cell on the GPU with winit + wgpu +
glyphon. See docs/CREW.md for the full guide.
It also ships a built-in swarm orchestration engine (crew-hive): give it a
goal and it decomposes the work into a task graph and runs a pool of agents
toward it — single-goal decomposition or parallel-job batches, bring-your-own-LLM
per agent, with a live task-list view that folds into a per-task record — token
totals, dollar costs (per task + run total), durations, and a Gantt-style run
timeline. See
Swarm orchestration and
docs/ARCHITECTURE.md.
It reads the terminal it is: the whole underline family, dim and conceal, OSC 8
hyperlinks, DECSCUSR cursor shapes, program-requested notifications and progress
(OSC 9 / 9;4), and OSC 133 semantic prompt marks where a shell offers them —
and it derives command blocks without shell integration, so /out can open
the last command's output on its own, /out list can show what you ran and how
long each took, and every card can mark where its commands began, where its
errors are, and which command you are currently scrolled back into.
Built on macOS, Linux, and Windows.
Rendering is built for legibility: a whole-pixel cell grid whose box never
changes with the font you pick (every glyph advance — bold and wide CJK/emoji
included — snaps to whole cells, so panes, borders, and columns never move),
pixel-exact themes (colours convert to linear once at the GPU boundary —
the near-black page really is near-black), width-aware text everywhere
(emoji/CJK occupy two cells without overlapping), Hindi and every script
that joins its letters drawn whole (Bengali, Tamil, Gujarati, Thai and the
rest: vowel signs, conjuncts and marks shaped together, on the grid), a
verified font picker
(families are listed by measuring that they render fixed-pitch Latin, so
variable fonts like JetBrains Mono appear and mis-flagged symbol fonts don't —
check with crew --list-fonts), and frame-to-frame shaped-text reuse so
unchanged panes cost nothing to redraw.
curl -sSfL https://raw.githubusercontent.com/ashishtyagi10/crew/main/install.sh | sh
Installs the prebuilt crew binary to ~/.local/bin. Set INSTALL_DIR to
choose another location.
irm https://raw.githubusercontent.com/ashishtyagi10/crew/main/install.ps1 | iex
Installs crew.exe to %LOCALAPPDATA%\Programs\crew and adds it to your
user PATH. Nothing is written outside your profile — no Program Files,
no HKLM, no MSI, no UAC prompt — so it works on a locked-down or managed
machine, and /update stays admin-free too. Open a new terminal afterwards so
the PATH change reaches it.
Options: -InstallDir <path> (or $env:CREW_INSTALL_DIR) to install
elsewhere, -Version v0.17.8 to pin a release, -NoPath to leave PATH
alone. To pass them, download the script first:
irm https://raw.githubusercontent.com/ashishtyagi10/crew/main/install.ps1 -OutFile install.ps1
.\install.ps1 -InstallDir D:\tools\crew
cargo install --git https://github.com/ashishtyagi10/crew crew-app
Download the latest archive for your platform from the Releases page, extract it, and move the crew binary to a directory on your PATH.
| Platform | Asset |
|---|---|
| macOS (Apple Silicon) | crew-v*-aarch64-apple-darwin.tar.gz |
| macOS (Intel) | crew-v*-x86_64-apple-darwin.tar.gz |
| Linux (x86_64) | crew-v*-x86_64-unknown-linux-gnu.tar.gz |
| Linux (ARM64) | crew-v*-aarch64-unknown-linux-gnu.tar.gz |
| Windows (x86_64) | crew-v*-x86_64-pc-windows-msvc.zip |
| Windows (ARM64) | crew-v*-aarch64-pc-windows-msvc.zip |
The Windows archives hold a single crew.exe with no installer and no
registry footprint — unzip it anywhere you can write and run it.
git clone https://github.com/ashishtyagi10/crew.git
cd crew
cargo build --release -p crew-app
# Binary is at target/release/crew
How you update depends on how you installed:
~/.local/bin
(idempotent, no sudo):
curl -sSfL https://raw.githubusercontent.com/ashishtyagi10/crew/main/install.sh | sh
On Windows the equivalent is re-running install.ps1; it moves a running
crew.exe aside rather than failing on the lock.cargo install --git https://github.com/ashishtyagi10/crew crew-app --forcegit pull && cargo build --release -p crew-app./update command downloads the latest release binary for
your platform over the running one and restarts crew into it. Progress
streams into a dedicated UPDATE card in the left nav (checking →
downloading → installed → restarting) — no separate shell or checkout. The
old /restart command was merged into /update; an update the background
check installed quietly is applied by the next /update too. A standalone
crew --self-update CLI path remains as a headless fallback.The prebuilt path only sees a version once its release assets are published.
Crew registers itself in your OS app menu on first GUI launch (Spotlight and
Launchpad on macOS, the Start menu on Windows, the applications menu on
Linux). The entry launches the installed binary (~/.local/bin/crew) when
present, so /update keeps it current.
crew install-app — create or refresh the entry explicitlycrew install-app --remove — remove itCREW_NO_APP_INSTALL=1 — disable automatic registrationcargo run --release -p crew-app
crew starts detached by default: it re-launches itself in a new session
(no controlling terminal) and returns your prompt immediately, so closing the
launching terminal doesn't SIGHUP the window. --detach / -d are still
accepted as no-ops.
To keep crew attached to the terminal instead (e.g. to see logs while debugging):
crew --no-detach # or: crew --foreground
Panes auto-tile into a near-square grid. Each pane has a title bar showing its
index, the program-set title (often the cwd), and right-aligned status glyphs
(⇡N scrollback, ● new output, ! bell, » broadcast input). The focused
pane has a near-white border and a bright block cursor. In broadcast mode
every terminal pane's whole frame takes the broadcast colour and the input
bar's legend reads » every terminal — a mode that changes where your
keystrokes go should be visible for as long as it is on, not only when you
switch it on.
Crew displays up to 6 panes as full tiles. Additional panes are demoted to a minimized thumbnail strip along the bottom of the content area, ordered least-recently-active first. Each thumbnail carries the line its pane is currently showing — a failing test, an agent's question, a shell back at its prompt — beside the activity marker and the count of what arrived. Click a thumbnail, use the nav, or press Cmd+1 … 9 to focus a pane and restore it to the full grid.
While a pane is scrolled back, its right border is a live scroll gutter — press or drag it to move through the buffer. Cmd+wheel resizes the font, and a wheel over the nav's LOG scrolls back through its buffered lines.
The left nav starts collapsed: a seven-column rail with one row per pane —
focus caret, number, and the mark that says what the pane is doing — and, along
the bottom, the readings that survive five columns: the clock, the sky, the
three system meters, the net rates, and what git has to say about the tree. The
chevron on its top border opens the full dashboard (clock, dials, load,
host, net, git, the LOG or the glance cards) and puts it away again: › on the
rail, ‹ in front of the legend when it is open. Cmd+G is the other
question — whether there is a column at all.
The pointer changes shape to say what it can do: an I-beam over text, a hand over a button or a nav row, an open hand over a card's legend row, a resize arrow on an open nav's edge — drag that edge to widen or narrow the nav.
Inside a pane, double-click selects a word and triple-click the line —
the gesture every terminal has, and each selection copies. On a card's top
border the mouse does structural things instead: double-click zooms, and
dragging the card onto another swaps the two. A scrolled-back pane shows a
proportional thumb down its right border beside the ⇡N count.
Cmd+Arrow moves focus the way the eye does: the card to the left, the one below, the one across. Pane cycling (Cmd+[ / Cmd+]) walks the panes in index order, which in a tiled grid is not the order they appear in — in a 2×2 grid, pane 2 sits below pane 1, not beside it. Hold Shift and the focused pane comes with you, swapping places with whichever card is that way. Neither wraps at the edge of the grid.
The chrome answers the pointer: the – / × button under the cursor
lights up (× in the bell colour — it ends a running program), and the
nav PANES row under it brightens, because the whole row is a click target.
Any full tile can also be minimized into the left nav: click the –
button on its top border and the pane keeps running but leaves the grid; its
row in the nav gains a + (the collapsed rail marks it too) — click the row (or jump to it with
Cmd+1 … 9) to restore it. Focusing a hidden pane always restores it.
Background panes can still flag you down: when a pane you're not looking at
rings the bell (Claude Code prompting for input), matches a watched
output pattern, or finishes a long command, its nav row raises an
attention marker — ! / ⚑ / ✓ in the bell colour — that blinks for a
few seconds, then holds steady until you focus the pane. Thumbnails in the
minimized strip carry the same marker, so an agent waiting on you is visible
no matter where its pane went.
Press /keys in the input bar for the full list in-app — it scrolls with
the arrow and page keys, and any other key closes it. It opens on the
section for the pane you are in (in a /far file panel · this pane), with
the global chords one scroll up; a pane whose keys are the global ones opens
at the top, as before. On macOS it and the command palette write chords the
way the menu bar does (⇧⌘T, ⌃⇧L); the table below keeps the portable
spelling, and typing cmd or shift still filters the list.
On Windows and Linux the Cmd key is the Windows/Super key, which the OS
keeps for itself (Win+I opens Settings), so every Cmd chord below is pressed
with Ctrl, as a browser or an editor has it: Ctrl+T opens a shell, Ctrl+W
closes a pane, Ctrl+N opens a window, Ctrl+1 … 9 jump to a pane, in every
pane, terminals included. A terminal (or a line you are typing) keeps the
plain Ctrl keys it lives by — C, D, Z, R, L, A, E, K, U, and M, J, I, H and
[, which are Enter, newline, Tab, Backspace and Escape to it — and there
Ctrl+Shift and the key reaches crew instead (Ctrl+Shift+C, Ctrl+Shift+I);
Ctrl+Shift works for every chord anywhere. A chord a Mac shifts is
Ctrl+Shift too: Ctrl+Shift+T reopens the pane you just closed, as a browser
reopens a tab, and Ctrl+Shift+[ / ] move a pane. The grid's arrows take
Alt (Alt+arrow focuses that way, Alt+Shift+arrow swaps), since Windows
keeps Win+arrow for snapping windows. Cmd+Click and Cmd+wheel are Ctrl+Click
and Ctrl+wheel, and a document window takes plain Ctrl (Ctrl+B, Ctrl+S).
Ctrl+Shift+F, G, L and M keep their meanings (focus mode, the gradient,
themes, markdown source) on every platform. /keys writes each chord the
way that machine presses it.
| Action | Keys |
|---|---|
| Next / previous pane | Ctrl+Tab / Ctrl+Shift+Tab (also Cmd+] / Cmd+[) |
| Jump to pane N | Cmd+1 … 9 |
| Jump to next active / waiting pane | Cmd+A / Cmd+. |
| Move pane left / right | Cmd+{ / Cmd+} |
| Focus the pane that way on the grid | Cmd+←↑→↓ |
| Swap the focused pane with that neighbour | Cmd+Shift+←↑→↓ |
| Next / previous screen: the grid, then each zoomed pane (inbox, far, …) | Cmd+Opt+←→ |
| Focus the input bar | Cmd+I |
| Recall a line you typed before | ↑ / ↓ — filtered by what is already in the bar; the top border says hist 2/5 · git |
| New shell pane | Cmd+T |
| Reopen last session's panes (shells, Far, agent smith) | /restore |
| Settings | Cmd+, |
| Open agent smith | Cmd+O (same as /smith) |
| Toggle the nav | Cmd+G |
| These keys, on screen | Cmd+/ (or /keys) — type to filter, ↑↓ to scroll, Esc to close |
| Zoom the focused pane, or put a zoomed one on the grid | Cmd+Z (or double-click its top border) |
| Broadcast input to all panes | /broadcast (by name only — Cmd+S saves a focused settings form) |
| Font bigger / smaller / reset | Cmd+= / Cmd+- / Cmd+0 |
| Copy the selection (or the visible screen) / paste | Cmd+C / Cmd+V (Cmd+V pastes a clipboard image as a temp PNG path) |
| Open URL / file / dir under cursor | Cmd+Click |
The docked command bar routes bare text smartly: if the focused pane is an
idle shell, what you type is typed into it; otherwise a first word that
resolves on your login shell's $PATH spawns the command in its own pane, and
anything else — a builtin (export, cd -), an alias, a for loop — opens
your interactive shell with the line typed into it, so the shell is the judge
of what it means. The palette shows a preview
row telling you where the line will go before you press Enter. Three
prefixes make the bar explicit: !<cmd> always runs the command in a new
pane, *<text> broadcasts one line to every terminal pane, and
?<plain english> asks the AI for a command (à la Warp AI / Copilot CLI)
— the suggestion lands back in the input bar, ready to edit or Enter, powered
by the same provider stack as agent smith (DashScope / OpenRouter / Anthropic, or
a direct OpenAI / Gemini / DeepSeek / NVIDIA key — a free
build.nvidia.com key is the no-cost first run — see
docs/CREW.md).
??<question> goes the other way: the AI reads the focused terminal's
recent output and opens its explanation in the zoomed file viewer, rendered
as markdown — ??why did this fail after a broken build gets you a
formatted post-mortem.
Slash commands complete the bar (type / for a fuzzy palette): /smith
(alias /crew), /goal <text>, /batch <file>, /view <file>, /doc <file>,
/diff, /settings, /find [all] <text>, /errors,
/out, /marks, /name <text>, /pin, /clear, /close,
/copy, /dump, /reopen,
/restore, /blame, /lsp, /pwd, /about, /log, /nav,
/model, /update, /broadcast, /zoom, /sidebar, /keys, /far,
/todo, /dash, /usage, /disk, /inbox, /focus, /notify — then
/exit.
Your Gmail in a pane: /inbox. A quiet list: two lines a thread when
the pane is tall enough, with a blank row between threads instead of rules
(who wrote, as Gmail writes it — Ann, Bo, me — and the message count, the
time at the right with a star or a paperclip beside it; then the subject and
the snippet in a quieter ink; unread mail comes first, under an unread
band, with a dot and its names, subject and time bold in your accent colour
(a thread you read there keeps its place until R lists again); L for
one line a thread, kept for the session; the rest grouped under today,
yesterday, the weekday, last week and on back; every key the pane
answers to is listed at its foot; a click selects a thread and a second
reads it, a click on a star takes it off, and the thread under the pointer
wears a lighter wash; every key at the foot is a keycap you can click, in
groups; an open thread says where it is in the list (‹ 3 of 25 ›, the
arrows step through it); the selection glides, an archived thread folds away
and new mail glows once, all still at Motion off),
/ to search in Gmail's own syntax
(from:ann is:unread), Enter to read a thread (which marks it read, as
Gmail does) — HTML mail drawn as formatted text: headings, bold, lists,
tables and links, headings and bold set in CSS read as headings and bold,
buttons drawn as buttons, hidden text dropped, the earlier replies a mail
quotes folded to one row (q unfolds them), v for the plain-text version,
pictures drawn in place — the mail's own and, as in Gmail, those from the web
(i hides those: fetching one tells the sender you opened the mail; tracking
pixels are never fetched), and a link opened by Cmd+click or
Cmd+E at its real address (one whose words name another site shows where
it really goes), each attachment a row you Cmd+click to save it to
~/Downloads and open it, n and p (or J and K, or ↓ and ↑; j and k scroll) for the next and the previous thread (a long thread reads as Gmail's
does, its older mails folded to a line each until a click or x opens them, and
lines never run wider than a reading measure)
without going back to the list, and w for the thread in a window of its
own; on a pane 140 columns or wider the thread reads beside the list —
e to archive, d to delete (to Gmail's Trash, as Gmail's
own delete does — nothing is deleted for good; either one, in an open
mail, opens the next mail instead of going back to the list), m to mark read or unread,
s to star, to undo the last of those, in an open mail to
unsubscribe from its sender (one click where the mail offers it, else a
mail to the list's address; a second confirms, and only mail Gmail
found DKIM-signed is acted on), to (its and
lines are yours to change; ↓ reaches its row of files, where Enter on
opens your system's file chooser, or drop files on the pane;
Cmd+Enter, Ctrl+Enter off a Mac, sends it in the thread; Tab has agent smith
write a draft into the box for you to change first; Esc closes it, twice when
it holds words), to forward the newest mail with its pictures and files, to hand the thread to smith ("what does it want
from me?"), to open a card under the mail with the row
it asks for, guessed from the thread on your computer (the ask as its title,
a project you already have, the person asked by name, and the deadline the
mail states, "by Friday" read as of the day it was sent; Tab asks smith to
fill it, every line checked), to change before Enter adds it, to refresh, to open it in
Gmail, to open on a search, to withdraw
the grant. Gmail's read scope is restricted, so it signs in with an OAuth
client of your own: the pane's setup page opens the five Google Cloud
console pages in order (about five minutes, once), finds the
you download in , and Enter signs in
through the browser. Publish the app on the console's Audience page, or
Google ends the sign-in after seven days. Nothing is stored but the grant
(, 0600, beside ), and the pane asks Gmail
whether anything changed once a minute (1 of the 6,000 quota units a minute
a project gets) rather than listing on a timer. The nav's card
shows the unread count and the newest unread thread, refreshed every five
minutes while the pane is closed; a click opens .
How crew looks is one command. /look owns the whole appearance family
as SUBJECTS — theme, font, weight, leading, density, motion,
contrast, shapes, crt, gradient, smooth,
gamma, invisibles — and the palette walks them in two steps: /look
lists the subjects, /look gamma lists that subject's ladder with the value
you are on marked. Fifteen rows became one, which is fourteen fewer names to
know and fourteen fewer rows between you and /find. The old spellings
(/theme dark, /gamma medium, …) still run exactly as before — muscle
memory is a feature — they are simply no longer things you have to learn.
The left column is one verb too: /nav glance, /nav log, /nav weather <place>; the command block list is /out list; and /doc <file> owns the
document window (/md still opens one).
The all variants are arguments, not names. /clear clears this pane,
/clear all every pane, /clear log the activity log; /find <text> searches
here and /find all <text> everywhere; /errors walks this pane's failures
and /errors all counts every pane's; /close all and /close others replace
/closeall and /only. Six rows fewer, and the variants are visible the
moment you type the verb instead of being names you had to know. Every folded
spelling still runs.
Commands with a fixed value set (like /look theme) expand into an
arrow-selectable value picker. Fish-style autosuggest from history, cd
completion with $VAR expansion, and Up/Down history recall persisted to
$XDG_CONFIG/crew/history round it out. /diff opens the working tree's
colored git diff (status, stat, full diff) in its own pane — Codex-style
change review beside your shells; /view <file> opens a zoomed file
viewer pane — code, markdown (rendered), CSV, diffs and more, one pane, read
only; /todo opens a todo list pane — type
pay rent tomorrow 5pm @home and the due date and @project tag are
recognised as you type (tinted live, stripped from the title on Enter),
overdue items surface to the top, a toast fires when an item comes due, and
r on a row hands it to a coding agent (claude, codex, opencode or agent
smith) in a new pane in the @project's directory — or end the line with &
and it runs the moment it is added. On macOS, /todo reminders keeps the list
and a crew list in Apple Reminders in step both ways: add or tick a todo on
your phone and it is added or done here, and the other way round.
A docked left panel (toggle with Cmd+G) with a live clock, CPU/MEM/DISK dials (drawn capsules on a narrow nav), a moving CPU curve under them, load average, host info, network rates over a twin chart that draws the two directions apart, a git section for the working directory, a LOG tail, and a list of open panes (click a row to focus it) headed by the crew mix — one chip per pane on a row per state, working / waiting / idle, with the crew total on the section rule. The charts scroll on the nav's once-a-second refresh, so they animate at no extra redraw cost.
Every part of it answers to the width you give it (drag the inner edge):
─ SYSTEM peak 55% ──,
─ NET peak 822 KB/s ──). Below the axis's floor (25%, 64 KB/s) the rule
says nothing: the floor is a minimum, not a reading.─ LOG 8/64 ──). A wheel
over it scrolls back. On a narrow rail it drops the 23:12 stamps and
gives those six columns to the message — a clock beside eight columns of
crew v0… is a column of timestamps next to a column of nothing.Crew's cards carry what it knows about a pane on their borders, never in the program's own columns — a terminal's grid belongs to whatever is running in it.
main ●3 ↑2 ↓1, shed detail
first as the card narrows, queried off-thread so a slow repo never stalls the
UI.9s, 2m14, 1h05),
past five seconds./marks off for a
plain frame.╶ cargo build beside the ⇡N, since the prompt that started the output is off the
top of the window by then. Other terminals pin a sticky prompt line inside
the viewport; that costs a row of the program's grid.╶ cargo build ✗101), and raises a failed card
rather than a quiet done when it happens. A shell that says nothing keeps
exactly the blocks it had; "no answer" is never drawn as success./out [n] opens a command's output on its own in the file viewer — the
last one, or the one n commands back. /copy out puts the same slice on
the clipboard./errors walks back to the most recent failure in a pane; /errors all
says which panes have failures and how many, then lands on the first./diff reviews the working tree in the viewer, pairing each removed line
with the added line that replaced it and drawing only the run that actually
differs at full strength — word edges respected, trailing whitespace on added
lines marked. ] and [ walk files and hunks, v lays it out side by
side (each half carrying its own file's line numbers), and the same
treatment applies to a fenced diff in an agent's reply./out list lists what you ran in the pane, newest first: how long each
took, which of them failed, and the number /out counts back with — so
/out list says what you ran and /out 2 opens the output of the third one
back./tools lists what the agents ran through the tool gate — tier, outcome,
who asked and how it ended — newest first. Every tool call already appended a
line to the action ledger; this is the thing that opens it. /tools <term>
narrows it — one term against the tool, tier, requester, decision, outcome
or note./integrations lists what crew can reach — every manifest, its credential and
whether it is set, every tool's tier./lsp lists the language servers crew knows (rust-analyzer, typescript-language-server,
pyright, gopls, plus ~/.config/crew/lsp.json), which are installed and which are running.
Agents get lsp:hover / lsp:definition / lsp:references / lsp:diagnostics, and the
viewer marks a code file's diagnostics in the margin. An edit an agent makes with sys:edit or
sys:write_file says in its own result when it introduced an error (diagnostics now: …), so
the agent fixes it in the next round; CREW_LSP=0 turns the servers off./watching lists what crew is waiting to do on its own clock — every
standing intent, soonest first — and /watching cancel <id> calls one off.The cursor takes the shape the program asks for — block, bar or underline (DECSCUSR), so an editor's insert mode reads as one. Unfocused panes draw an outline instead, so exactly one cursor on the canvas is filled in.
The full underline family — single, double, curly (the spell-check squiggle), dotted, dashed — plus strikethrough and SGR 58's separate underline colour, drawn as GPU rules that stay continuous across cells. Dim (SGR 2) and conceal (SGR 8) are honoured too: half of what an agent CLI prints is dim, and a password prompt that hides its field means it.
Links are marked as links. URLs are tinted and underlined; OSC 8 hyperlinks
are drawn as links whatever their text says, and Cmd+click opens the program's
target (only http/https/mailto/file, named on the status line). File
references — src/main.rs:42, ./deploy.sh, Cargo.toml — wear a dotted
rule instead, because they open here rather than in a browser, and a clicked
path:line lands on that line.
What a program paints with coloured spaces — a TUI's status line, a
progress bar, fzf's selected row — renders as it should, and so does a
selection dragged across empty space.
Crew renders markdown natively (a pulldown-cmark-based engine drawn straight
to GPU cells — headings, lists, tables aligned by display width, fenced code
cards, links):
- [ ] / - [x]) render
as checklists — ☐ open, green ✓ with dimmed text when done — and
```diff/```patch fences colour added/removed/hunk lines
(an untagged fence that reads as a diff is auto-detected and coloured the
same).crew › Themes › CRT). in markdown renders
as the picture, resolved against the document and read off the frame thread./doc <file> opens a document in a window of its own — no nav, no input
bar, no tiles: one file, framed, filling its own window, sized to a reading
measure. w inside the viewer pops the document you are already reading out
of the grid and into one. The grid goes on being a grid.Cmd+N opens another crew window — a whole second canvas: its own grid
of panes, its own focus and zoom, its own input bar. Closing a window closes
that window; the last one quits. A session remembers which window each pane
was in.# or
** ever appears on screen.Cmd+E labels everything on the pane worth reaching — every URL, file
reference and hash wears a letter; pressing it copies, pressing its capital
opens (a URL in the browser, a file in the viewer). Labels come off the home
row and go to the newest output first, so the thing a program just printed is
the cheapest key. Esc — or any letter that starts no label — ends the mode.APC G form — kitten icat, timg, matplotlib's kitty
backend), so a plot or a screenshot arrives inside the output: anchored to
the line it came in on, scrolling with it, clipped to the pane, decoded off
the frame thread and drawn on the sub-cell paint layer./smith)/smith (alias /crew) opens a pane that lets independent CLI coding agents — claude,
codex, and opencode — message each other to work a task. On open, the
pane probes which agent CLIs are installed and lists the ones it found (missing
ones are skipped). Type a task and press Enter; prefix @<agent> to choose who
starts (otherwise the first detected agent does).
Each agent gets a clean message plus the task and a transcript so far, and ends
its reply with a control line: @next <agent> to hand off to a peer, or
@done to end the thread (the parser tolerates markdown wrappers and
re-asks once if the line is missing). The broker logs every hop as from → to
with the reply, so the whole conversation is visible in the pane. A hop counter
caps each thread (default 6), an optional token budget caps spend, and every
agent call has a timeout — a hung agent is killed and logged, never blocking the
UI. The provider connection opens while you type: the first key of a message
has the broker shake hands with the provider's host, so the turn's first model
call skips the ~0.5 s TCP and TLS open (CREW_PREWARM=0 turns it off).
The pane speaks a small construct language (/help lists every command),
and plain language does the rest: "have every agent take a crack at this"
sends one task to every agent in parallel (replies stream back
fastest-first), "keep refining it" iterates on the crew's own answer, "keep
working until …" loops until a judge agent rules the goal met — the broker's
intent router picks the execution shape (CREW_INTENT=0 turns it off).
@a+b <task> fans out to a subset, bare /model shows a grouped provider
picker — your subscriptions (a signed-in claude or codex seat serves
agent smith with no API key; signed-out ones show the exact sign-in
command, and a device-flow provider like Qwen signs in right in the pane:
pick its number, approve the code card in your browser, done — tokens live
in the OS keychain and refresh themselves), your keys, and installed CLIs,
with /model <n> switching provider
persistently and /logout removing a stored sign-in (from its own picker, or
/logout <name>) — /model <agent> <model> pins agents to different models
side by side, and
the footer reports live totals — with Tab completion for @agent names and
slash constructs in the composer, one-letter aliases (/m → /model), and
did-you-mean on typos. Long constructs run as concurrent background tasks
(default cap 4): each reply is tagged with a dim #N task chip, the footer
lists what's running, and /stop [#n] cancels one task or all of them.
Shift+Tab steps the pane's approval mode — auto-approve, accept edits, ask
first, plan only, yolo — and /approvals <mode> says it in words
(/approvals default <mode> also makes it the mode new panes start in);
/init writes an AGENTS.md for the project, and /clear starts a fresh
conversation.
@file mentions in the composer fuzzy-complete against the project tree and
splice the file's contents into the outgoing message — a path with spaces
rides a quoted @"my notes.md" mention, and a file dragged onto the pane
becomes one too (terminals get the shell-quoted path instead). Ctrl+R
reverse-searches what you've sent, shell-style; Cmd+F searches the
transcript and jumps to each match.
Agents can also touch the workspace through built-in sys tools — bounded
sys:run (non-interactive shell, 120s deadline; a long output reaches the
agent as its start and its end, and a non-zero exit is a failed call),
sys:read_file (~5 KB
pages of whole lines, every row numbered with its line in the file (41│ )
and each page naming its lines and the next offset; line starts one at a
sys:grep hit's line, and lines stops it after that many),
sys:write_file (makes the directories a new file needs, inside the
project only, and replaces an existing file only once the task has read it
with sys:read_file), sys:edit (replace an exact, unique fragment
— part of a file without rewriting the whole of it — or, with "all": true,
every occurrence of it, for a rename, or with "line": N the one of several
copies that line falls in), sys:list_dir,
sys:grep and sys:glob (a regex over the project's files, with context
lines around each hit on request, and files by name or path — both over what
git lists, so nothing .gitignore names crowds out the project's own code),
sys:outline (one file's functions, types, impls, classes and methods, or
its Markdown headings, each on a row with its line number for sys:read_file's
line to open, the way Aider's repo map shows a file: its shape in one call
rather than five pages),
sys:todo (a checklist of up to 12 steps the agent keeps for a task with
three or more of them, sent whole each time, shown back to it above every
round's tool results so shortening never drops it, and the steps left undone
named at the end of its answer, the way Claude Code's TodoWrite does; the
pane draws it, and Claude Code's own list, as the plan over the code line),
sys:git (status, diff, log, show and blame, run without a shell and with
any argument that writes a file or runs a program refused, so it needs no
approval and works in read-only mode),
sys:fetch (an http(s)
page as readable text — markup and scripts stripped, private and
link-local addresses refused), and sys:search (a keyless web search: ranked
titles, real URLs and snippets to fetch and cite) — callable mid-relay the
same way as MCP tools. A long result from sys:run, sys:git, sys:grep,
sys:glob or sys:fetch is fitted to what the agent is shown and saved
whole to .crew/out/ (git-ignored, newest 30 kept), its last line naming the
file for sys:read_file and sys:grep to reach what was left out;
turns that off. blocks the mutating ones,
turns the surface off, and shows the working
directory and sandbox mode. An optional token budget
() hard-stops a runaway thread.
Tool use shows in the transcript as its own voice: the call announces itself
subject-first, the result card leads with sys:run ✓ 1.2s — outcome and
duration, ✗ for a command that exited non-zero — and its output is folded
to that one line until you click it open.
Both take the quiet dotted gutter, so a task that calls four tools doesn't read
as nine agent replies. A turn that fans the same task out to the whole roster
folds the same way: each subagent's answer is its own section, one line
under that agent's badge with … +N for the rest, open on a click — eleven
full answers is eleven transcripts, not one, live or landed — a fanned
agent's card is folded from its first streamed fragment, not after it has
already filled the pane.
It also borrows the flagship moves of the big coding agents: plan mode
(ask for "a plan for …" and nothing runs until you approve it — enter or
"approve" runs it, esc or "reject" discards — à la Claude Code; say "plan
first" and it becomes the session's MODE, so every task is drafted and waits
until you say "stop planning"),
workspace checkpoints
(a checkpoint is taken automatically before every task that can change files,
as a hidden commit under
refs/crew/ without touching HEAD or your index; say "undo that" and crew
names what would come back and waits for your "yes" — à la Cline's
checkpoints and Claude Code's rewind, with no command to remember),
a check on its own work (put one command in .crew/check — or let crew
read the one your AGENTS.md already tells contributors to run — and it runs
after every task that changes files, reporting passed or the first lines of
the failure, naming its source when you did not type it here — à la Codex's
test step, declared rather than guessed; CREW_CHECK=0 turns it off; a failure
it has met before adds seen before: … the 3rd time, last in <file>, and the
repair pass is told the same),
transcript export (/export writes the conversation to
crew-transcript-<stamp>.md — à la OpenCode), AI commit messages
(say "commit this" and the crew drafts a Conventional Commits message for
your diff; nothing is committed until you say "apply" — à la Aider),
AI code review (ask "look over my changes" for findings on the working
diff worst-first — à la Codex), session resume (the conversation
auto-saves to ./.crew/, and asking to "pick up where we left off" in a
fresh pane folds the last session into the next task — à la Claude
Code's --continue), /doctor (a ✓/✗ health check of the whole AI
stack: provider key, agent CLIs, MCP servers with their tools, skills,
memory — each failure names its fix), AI standups (ask "what did I ship
this week?" for an update from recent commits: done by theme, in progress,
risks). The old slash forms of all of these — fan, loop, goal, plan,
commit, review, standup, resume, skill, memory, mcp — are retired; plain
language replaced them. The transcript folds itself, which
folds older messages away when a long session gets heavy; /diff (in the
pane or the input bar) completes the loop with Codex-style change review.
The pane is extensible the way other coding tools are — three drop-in
surfaces, no rebuild, edits picked up live (/reload forces it; no restart
needed) — see docs/CREW.md:
# shortcut: #always use pnpm in the pane
appends to ./.crew/memory.md, and every task from then on carries the
merged memory (user + project files, 2 KB cap) as a standing block the
agents follow; ask "what do you remember?" (or "what do you know about the
router?") and crew reads it back itself — the notes, the recall graph's
turns and files for that subject, and the project's instruction files — with
no model call, so it answers with no provider signed in.AGENTS.md / CLAUDE.md — the conventions your repo already wrote
down are followed without being retold. Crew finds them from the working
directory up to the repo root and carries them in front of every task,
under your own standing memory; both names are read, the nearer file wins,
and the whole block is capped at 4 KB../.crew/recall.jsonl as a node joined to the topics and files it was
about (an embedded append-only graph store — no server, no new dependency),
and the next request walks those joins to carry back the earlier turns that
bear on it: From earlier work in this project: - 3d ago — you asked ….
Relevance, not recency, so a month-old answer comes back when it is the one
that fits; CREW_RECALL=0 turns it off.~/.config/crew/skills/ or
./.crew/skills/ (optional name:/description: frontmatter; project
overrides user). A skill can also be a directory with a SKILL.md plus
supporting files, and oversized playbooks disclose progressively: past
8 KB the relay gets the description + heading outline + path, and agents
read sections on demand with chunked sys:read_file calls. There is no
command: the model chooses which loaded playbooks a task follows (a task
that names one picks it up by itself when the model cannot be asked), and
when skills are loaded but none chosen the crew sees a one-line roster of
them.~/.config/crew/agents/ or
./.crew/agents/ ({"name", "command", "args": […, "{}"], "role"}) turns
any headless CLI into a roster agent; installed manifests appear in
the roster and make agent smith usable with no API key at all.~/.config/crew/mcp.json or ./.crew/mcp.json
(the standard mcpServers schema) connect lazily over stdio;
lists each server with its tools, relay prompts advertise them, and agents
call one by ending a
reply with — the result is fed back
(bounded rounds, visible in the transcript) before routing resumes. A
model's own trained shape (, or
Qwen3-Coder's XML) is read as the same call.The pane itself reads like a multi-agent console: a header with a live status
(| coder · 12s while an agent thinks, | 3 working · 8s during a parallel
fan, a completed-turns counter, a running ~N tok meter, connection dot),
statusline-style agent rows — one per agent with its model badge, reply
count, running token total, and live bars for context-window fill (sized
to the pinned model's window) and its share of the turn's time, the active
agent highlighted —
a live activity row while agents work (⠹ user ⇢ planner 4s, one animated
chip per working agent naming who handed it the task, so parallel fans and
hand-offs are visible as they happen), and message cards (▍sender · 2m ago · 4.2s)
that colour each agent consistently and show hand-offs as from → to. Every
turn ends with a timeline log line: turn done — planner 4s → coder 8s · 2 exchanges · ~950 tok (approx), and each settled reply that reported real
usage closes with its own muted trailer — 900 in / 50 out · $0.012. Long
system/telemetry cards (turn summaries, /doctor output) auto-fold to a
header + first line + … +N — click to expand, click the header to fold
back. New cards fade in from the page colour;
fenced code in replies renders as a
solid tinted field — one rectangle, the language on its top row, the same width
on every line — whose colour is walked per theme so it reads on paper and on a
phosphor tube alike; the transcript sits against the composer rather than
floating at the top of the pane; a composer with
@agent chips and key hints frames the input (a valid @mention lights up in
the agent's colour); a proportional scrollbar plus a ↓ N new pill keep long
transcripts navigable; and a fresh pane opens with onboarding — the detected
crew, roles, and an example prompt.
Agents run headlessly off the render thread (in a broker subprocess), so the
window stays responsive. Adding a fourth agent takes one adapter: add a
constructor in crates/crew-plugin/src/broker/agents.rs and register it in
known_adapters — the routing engine is untouched. See
docs/CREW.md for the protocol and architecture.
crew-hive)Beyond the agent smith relay (a few CLI agents talking turn-by-turn), Crew includes a
full orchestration engine, the crew-hive crate — the substrate for running
many agents toward one goal:
StubPlanner and an LlmPlanner that asks an LLM for the graph.tokio DAG executor with a bounded worker pool (concurrency
cap), dependency fan-in/fan-out, failure cascade-cancel, panic-as-failure
resilience, and cooperative cancellation.Agent trait with three workers: StubAgent (tests),
ApiAgent (a native LLM call — just a future, no PTY, so thousands can run),
and RemoteAgent (dispatched over a wire to an out-of-process worker or an
external engine such as LangGraph).Provider abstraction (mock + an Anthropic client),
with per-agent ModelTier cost tiering (haiku / sonnet / opus).batch_graph); a budget_governor enforces a hard cost ceiling.The engine is wired into the app through two commands, each opening a live swarm pane that renders the task list + a fleet HUD (live / done / failed / cost) and updates every frame:
/goal <text> — plans the goal into a task-graph off the UI thread, then
runs it. With ANTHROPIC_API_KEY set it uses the real LlmPlanner + native
ApiAgent workers (each task billed at the planner's per-task ModelTier);
without a key it falls back to the deterministic stub backend so the full
flow still works offline./batch <file> — runs a file of jobs (one per line) as a flat, all-parallel
swarm — the "many parallel jobs" mode.Real-LLM /goal and /batch runs are capped by the budget_governor (default
$1.00); the pane shows a "budget exceeded — swarm cancelled" notice if the cap
trips. See docs/ARCHITECTURE.md and
docs/superpowers/specs/2026-06-27-crew-agent-swarm-design.md.
/settings opens a bento form of fieldset cards — APPEARANCE, CANVAS,
NOTIFICATIONS, WINDOW and USAGE — dealt into one, two or three balanced
columns, whichever makes the form shortest at the pane's width. On a whole
window that is three columns and no scrolling at all. It covers every
configurable property: font family/size, font smoothing (the /smooth
ladder), text gamma
(the /gamma ladder), line spacing
(/leading), density, nav width + visibility, theme, accent, card border
marks, revealed invisibles, launch-maximized, and the whole
notification block (master + per-event toggles, min-secs threshold, watched
output patterns as a one-per-line text area). Every key in the config file has
a field here, and a test that parses config.rs says so. Cmd+S / Alt+S
saves, and /keys lists how to reach and change each field without the
mouse — as it now does for every pane kind that answers to keys of its own. Settings persist to
$XDG_CONFIG/crew/config.toml and apply live on Save. The config file also
accepts accent = "#rrggbb" to override Crew's accent; omit it (or give an
invalid value) to use the active theme's default accent. It applies at launch —
quit and reopen Crew to pick up edits made outside the /settings pane.
Themes. light and dark are Ink Reader: an e-reader's white and
black pages, the way the Kindle app draws them. light is a white page
with near-black words and black lines. dark is the same page inverted:
a black page, white-grey words, grey lines and a white frame round the pane
you are in. (The old names paper-light and paper-dark still load, as
light and dark.) On both, the pane you are in is framed in a heavy line, twice
the weight of the others. Both are opaque print, with no glass, glow, gradient or text
shadow. Grey is the only second ink. Colour stays where it means something
(a terminal's ANSI output, a diff, the status marks) in deep printed inks
that read on the page. Code reads the way Apple's own editor shows it, Xcode's
Default themes: on dark, magenta keywords, salmon strings, yellow numbers,
cyan types; on light, magenta keywords, red strings, blue numbers, teal
types; slate comments on both.
Every other theme is see-through glass: the window shows your desktop, each
pane is a slab of smoked glass over it, and the words on it are bright, with
a soft shadow behind them. glass is the iPhone's liquid glass in its Clear
look, rotating four palettes: glass-clear (neutral smoke, rose accents,
code in the iPhone's own colours: pink keywords, purple types, blue calls),
glass-night (navy smoke, mint, an aurora focus ring, code in aurora
colours: mint keywords, violet types, pink calls), nebula (violet smoke,
orchid→rose accents, code in rose keywords, teal types, orchid calls and
lavender names) and blossom (a wine-rose smoke, pink accents, a blush
frame, code in spring colours and Comic Mono). crt is a
phosphor tube in glass, in crt-green and crt-amber, each one hue at six
brightnesses; code is highlighted by brightness alone, as on a phosphor
terminal (keywords brightest, then types and calls, numbers, strings,
comments). A rotation changes palette every 10 minutes; light and dark
are one page each and stay put. And auto walks every look in turn —
dark → light → crt → glass → neon → classic → purple → dark — a new one
every 10 minutes, whatever the clock or the OS appearance. In classic it shows all five,
one after another, so every lap (110 minutes) shows every classic.
neon is a holographic control room in electric blue, violet and cyan, and
it is always dark, whatever the OS appearance or the clock. A fine grid glows
in electric blue behind the
panes, brighter every fourth line with a crosshair where those cross, and
sparks drift up it — and packets of light run up its bright lines — while a
pane works (they hold still when nothing does, and at Motion off). Each pane
is a slab of blue-smoked glass over the grid, which shows through it: a
cyan-white rim, its frame's light bleeding a little way in and turning cyan
to violet across the card like a hologram's foil, and a halo of blue round
it; the pane you are in burns cyan. Words are bright white and the face is
IBM Plex Mono. Code and shell output take neon's own colours: violet keywords,
electric-blue calls, cyan types and hot-pink numbers. Its palette's own name, neon-dark, loads as neon, and so does
the retired neon-light.
classic is five editor palettes people already know by name, as smoked
glass with bright words: tokyo-night (deep navy, cyan accent, a blue→magenta
ring), solarized (deep teal, yellow accent, blue→cyan), everforest
(forest green-grey, parchment words, green→aqua), gruvbox (charcoal, cream
words, orange accent, yellow→orange) and monokai (olive-black, lime accent,
pink→purple). /theme classic rotates them; /theme gruvbox pins one. Each
keeps its page's hue and its signature colours; the text ladder is crew's
own. Shell output and syntax colours use each scheme's own hues (gruvbox's
teal "blue", monokai's pink red) at crew's contrast, so they stay as legible
as on any other palette, and code is coloured the way each scheme colours it:
monokai's keywords pink and strings yellow, solarized's keywords green,
gruvbox's and everforest's red, Tokyo Night's purple with cyan types. Each
selects in its scheme's own tint (solarized's deep teal, gruvbox's warm grey)
and its comments carry the scheme's comment colour (Tokyo Night's storm blue,
monokai's olive). Each wears its own face, so stepping through them changes
the font too: JetBrains Mono, IBM Plex Mono, Comic Shanns Mono,
MonoLisa and SF Mono.
purple is one page, amethyst: the smoked glass on a royal-purple page,
white words with a lilac cast, a lavender accent, a vivid violet frame and a
violet→magenta ring, with progress marks in a pale mint. Its code is in
jewel tones: orchid keywords, amber types, periwinkle calls, rose numbers and
mint strings. nebula is violet too, but on a near-black page; here the page
itself is purple. /theme purple or /theme amethyst turns it on.
That makes fifteen palettes in all.
Almost every colour in a palette is derived, not chosen: the ramp produces the whole text ladder and all sixteen ANSI slots from the page and the ink, a wash produces the search highlight, and an alarm derivation produces the bell — each with a contract test that fails when a shipped value drifts from what the system would produce. What a palette actually picks is its page, its ink, its accent and its gradient poles.
/theme offers the modes and then every palette by name, and shows
you the colours rather than the names: a mode draws one chip per palette it
would serve, and a named palette draws its whole hand — the ink it writes in,
its accent, and the four ANSI slots every program in a pane paints with, each
over that palette's own page. Better still, arrowing onto a palette puts it
on, and arrowing off (or dismissing the picker) puts back the one you had —
because a swatch tells you what a palette is and only wearing it tells you
what the screen you are looking at will look like. /gradient previews its
named pairs the same way. Ctrl+Shift+L cycles the rotations; the palettes retired
in an earlier roster cut still parse, so an old config keeps working. /crt on|off|auto overrides the tube post-process independently of the theme.
On the glass themes crew paints no wallpaper of its own: your desktop is the
background, seen through the glass. Config key: theme = "glass" (or any rotation or palette
name). See docs/CREW.md.
Crew is a Cargo workspace with six crates:
| Crate | Purpose |
|---|---|
crew-app | Window, panes, input, in-pane UI |
crew-render | GPU rendering (wgpu + glyphon) |
crew-term | PTY + terminal grid (alacritty_terminal + portable-pty) |
crew-plugin | Chat / agent plugins (the agent smith relay broker) |
crew-theme | Theme presets + palette contracts (13 themes, rotation modes, contrast thresholds) |
crew-hive | Swarm orchestration engine (planner, scheduler, agents, blackboard, telemetry) |
See docs/ARCHITECTURE.md for the full diagram (app + engine internals).
Hard rules: every .rs file stays ≤200 lines; cargo clippy --workspace --all-targets is warning-free.
MIT or Apache-2.0, at your option.
crew embeds Lilex 2.700 (SIL Open
Font License 1.1 — see assets/fonts/OFL.txt) as its built-in typeface, so the
grid never depends on what happens to be installed on the machine. Any
installed coding face you prefer still wins: pick one with /font, or let the
theme choose (crew --list-fonts shows what it can see).
| Label every URL, file and hash on the pane (a letter copies, its capital opens) | Cmd+E |
| Open another crew window | Cmd+N |
| Cycle the theme rotations (dark → light → crt → glass → neon → classic → purple → auto) | Ctrl+Shift+L |
| Step the canvas gradient (… → the theme's own) | Ctrl+Shift+G |
| Focus mode: hold notifications, never steal focus | Ctrl+Shift+F (or /focus) |
| Agent pane: markdown preview ↔ raw source | Ctrl+Shift+M |
| Agent pane: compact transcript (one line per message) | Ctrl+O |
| Reverse-search the chat composer's send history | Ctrl+R |
Find: the chat transcript, or /find in the bar | Cmd+F (or Ctrl+F) |
| Insert a newline in a terminal | Shift+Enter (sends a line feed, not submit) |
| Close pane / maximize window | Cmd+W / Cmd+M |
| Reopen the pane you just closed | Cmd+Shift+T (or /reopen) |
| Clear focused pane scrollback | Cmd+K (or /clear) |
| Scroll any pane | Shift+PageUp / Shift+PageDown (Shift+Home/End for top/bottom), or mouse wheel — in a full-screen app (vim/less/agent TUI) the wheel is forwarded to the program |
| Quit | Cmd+Q (press twice to confirm when panes are open) |
zuurtocc+ attachfat/todoRo/inbox <search>/inbox signoutclient_secret_….json~/Downloadsgmail.jsoncredentials.json/inbox/blame/reopen (Cmd+Shift+T) undoes the last pane close: a shell in the
directory that one was standing in, the viewer back on its file. The last
eight, so a /close others walks back a pane at a time./pin keeps a pane on the grid when the LRU would demote it./view <file> opens a zoomed file viewer pane — a
single, read-only pane over the file, rendered by format: markdown
(headings/lists/links/code fences), a numbered-gutter code view, aligned
CSV columns, colored diffs, or a metadata card for anything else. Arrows/
PageUp/PageDown/Home/End scroll, r reloads from disk, s toggles raw
text (markdown and CSV files), / searches with n/N for next/previous
hit, e opens $EDITOR, o hands the file to the OS default app,
Cmd+Click opens a rendered markdown link, Esc closes. A picture
opens as the picture — PNG, JPEG, GIF, BMP and WebP are drawn on the
sub-cell paint layer, fitted to the pane and centred, decoded off the winit
thread; transparent pixels let the page through.CREW_SPILL=0CREW_SYS_MODE=readonlyCREW_SYS_TOOLS=0/doctorCREW_BROKER_TOKEN_BUDGET/doctor`@tool server:tool {"arg": …}`<tool_call>{"name": …, "arguments": …}<function=…>~/.config/crew/hooks.json and never in a project, so a cloned repo cannot
make crew run anything: {"pre_tool": [{"match": "sys:run", "cmd": "…", "on_failure": "block"}], "post_tool": [{"match": "sys:edit", "cmd": "…"}]}.
match is a server:tool label, server:* or *; each hook reads the call
as one JSON line on stdin and has five seconds. A pre hook that exits 2, or
prints {"decision": "block", "reason": "…"}, stops the call and the agent
reads why as its result; a post hook's output lands under the result, so a
formatter or linter answers back. CREW_HOOKS=0 turns hooks off.