Quil
The persistent workflow orchestrator for AI-native development.
A terminal multiplexer built for developers who orchestrate 5–10 sessions per project across AI assistants, build watchers, webhook tunnels, and SSH connections. Unlike tmux, Quil understands projects and typed panes: it persists your entire workspace across reboots, auto-resumes AI conversations by session id, and lets your AI assistant drive your terminal over MCP.
Type quil after a reboot — every tab, pane, working directory, layout split, and AI conversation is right where you left it.
If Quil saves you time, a ⭐ helps other developers find it.
See it
Install
Linux / macOS — one-line install (detects OS+arch, verifies SHA-256):
curl -sSfL https://raw.githubusercontent.com/artyomsv/quil/master/scripts/install.sh | sh
Windows — download quil-windows-amd64.zip from Releases, extract anywhere on PATH.
Go users:
go install github.com/artyomsv/quil/cmd/quil@latest
go install github.com/artyomsv/quil/cmd/quild@latest
Full install options + build-from-source — see docs/installation.md.
Quick start
quil # launches the TUI, auto-starts the daemon
Five keys to remember:
That's enough to start. See docs/quick-start.md for the first-launch walkthrough and docs/keybindings.md for the full keymap.
If anything ever hangs: quil restart recovers the daemon (escalating stop → fresh start → tabs restored from the last snapshot), and Alt+R restarts a single stuck pane in place with its AI session resumed.
One window, every project
A project groups tabs, owns a root directory, and belongs to one daemon.
Alt+Shift+S opens a sidebar listing all of them at once, and that is the point:
an agent that finished — or got stuck asking you something — in a project you are
not looking at is visible from the one you are.
Each project row rolls up its panes: ▲ blocked on you, ⠹ working (spinning), ✓ finished
while you were elsewhere. Blocked and finished are different states, because
they need different things from you. Alt+Shift+A jumps to whichever agent has
been waiting longest anywhere in the workspace — oldest first rather than sidebar
order, since that is the one costing you time.
Under the active project each pane also shows the checkout it sits in — branch,
wt for a linked worktree, ↑N/↓N against upstream. Cached per checkout, so
ten panes in one repository cost one git invocation, and a probe that does not
answer keeps its last value marked stale rather than guessing.
Too many projects? Right-click one → Move to group… and collapse the groups
you are not using; a collapsed group still shows its agents' badges. Right-click
a tab to rename it, recolour it, re-lay-out its panes or move it to another
project, and hold Alt to drag a pane beside another, swap them, or onto another tab.
Existing workspaces migrate on first load into a single project named Default,
tab order preserved — no prompt, nothing to opt into. Full detail in
docs/features.md.
Run the work somewhere else
quil --remote gpu01
The machine doing the work and the machine you sit at are increasingly not the same one — a GPU box, a cluster node, a beefy desktop reached from a laptop. An AI agent mid-task is exactly the workload you least want tied to a laptop lid.
flowchart LR
subgraph laptop["your laptop"]
TUI["quil<br/><i>a viewer — holds no state</i>"]
end
subgraph host["gpu01"]
D["quild"]
P1["claude"]
P2["shell"]
P3["lazygit"]
D --> P1
D --> P2
D --> P3
end
TUI -->|"ssh -T · one channel · no open port"| D
No port is opened on the remote. Quil runs ssh -T gpu01 "quil --stdio" and
speaks its normal protocol over that single channel, so anything SSH reaches
works — a bastion behind ProxyJump, a Tailscale address, a box on the public
internet. The destination goes to ssh verbatim, so your ~/.ssh/config keeps
working: Host aliases, jump hosts, per-host keys, hardware tokens, certificates.
The server needs nothing installed first. Point --remote at a bare machine
and it offers to install one, then attaches. Your laptop downloads the release
for the remote's platform and pushes it over the connection you already have,
so a node with no route to GitHub provisions as easily as one with.
Or add the host without leaving the TUI. Tick Remote (ssh) in the New Project dialog and press Enter on the Host row — Quil dials it, installs or upgrades Quil there if it needs to, then browses that machine's filesystem for the root directory:
A dropped link is a pause, not an ending. Close the lid, lose wifi, change
network — an amber bar names the host, counts the attempts, and shows what ssh
said, retrying with backoff until it lands. The panes never stopped, so there is
nothing to resume. Keystrokes are dropped rather than queued while the link is
down: a key typed at a dead connection would otherwise arrive minutes later in a
live agent session, answering a question that had already moved on.
Every dialog describes the server, not your laptop. The working-directory
picker, ~, relative paths, drive and root listings, git-repository discovery,
kube contexts, which tools are installed, and the recent-directories list all
ask the daemon. Before that, Alt+G could report no repository in a directory
where the agent in that very pane answered git status with the branch name.
Known limits: plugin definitions still come from your local
machine, the daemon detects installed tools only at startup and on plugin
reload, quil status and the update controls refuse rather than retargeting,
and remotes must be Linux or macOS. Details and the roadmap are in
docs/features.md.
Run an agent in a box
--dangerously-skip-permissions is how an agent gets useful, and it is also how
an agent reaches every file you can. Tick Run in a Docker container in the
pane setup dialog and the pane runs inside a per-pane container instead — for
Claude Code, Codex or OpenCode.
The checkout is bind-mounted in, so the agent's edits and its commits are real. Everything outside it simply is not there.
The mount set is the whole boundary. No --privileged, no --cap-add, no
--network flag. The repository's .git is mounted as a mountpoint — which
answers EBUSY to rename and remove — with objects, hooks, config,
config.worktree, modules and worktrees pinned read-only on top, because
those are values host git executes. New objects go to a store belonging to the
pane, with your repository's own mounted read-only, so no commit on any branch
can be deleted from inside.
Notifications, the working spinner, input history and session resume keep working. Closing the pane removes its container.
You supply the image. Quil publishes none and pulls none:
scripts/sandbox-image.sh # build and verify quil-sandbox:latest
scripts/sandbox-image.sh --with codex,opencode # add the other agents
Prerequisites, both Claude sign-in flows, the image recipe line by line, and the limits that are not bounded (egress, branch pointers, submodules): docs/sandbox-panes.md.
Or a microVM. With Docker's sbx
CLI installed, ←/→ on the same row picks the sbx backend instead: the
agent runs in a Docker Sandboxes microVM with its own kernel and a default-deny
network allowlist. Your project's sbx environment file declares that cage, and a
.quil-sandbox.toml you approve with quil sandbox trust points Quil at it.
A pane can also attach to an existing sandbox that another tool created.
The sbx backend.
Set the whole tab up at once
Some work needs four panes, not one — an agent that plans, an agent that writes code, a lazygit, a shell. Building that by hand every time is the boring part, and the opening prompt for each pane is the part you retype.
A template describes one tab: its panes, their layout, and an optional starting prompt for each. Open the command palette, choose New from template, pick a directory, and Quil builds it.
[[templates]]
name = "pair"
description = "Claude and Codex side by side"
layout = "columns"
[[templates.panes]]
type = "claude-code"
name = "claude"
[[templates.panes]]
type = "codex"
name = "codex"
A pane may set a model, plugin toggles by name, a subdirectory, a mute, and
a prompt. Prompts take {{task}} (the text you typed), {{dir}},
{{branch}} and {{panes}} — the last one lists every pane in the tab with
its id, so a prompt can tell one agent how to reach the others without you
copying ids by hand. Add a branch name and the tab opens in a fresh git
worktree.
Three templates ship: agent-team, pair and review. Edit them, or add your own, at F1 → Settings → Templates. An invalid file is refused with the reason and your previous one is left alone.
Every field, every layout, and the limits worth knowing before writing a team prompt: docs/workspace-templates.md.
Let your AI assistant drive Quil
Add this to your AI client's MCP config (Claude Desktop, Claude Code, Cursor, VS Code Copilot):
{
"mcpServers": {
"quil": {
"command": "quil",
"args": ["mcp"]
}
}
}
Restart the client. The AI can now list_panes, read_pane_output, send_to_pane, watch_notifications, screenshot_pane, and 30 more tools. Read the build pane and react to errors without copy-paste.
Full guide: docs/mcp.md.
Built-in integrations
Typed panes ship for the tools developers run all day. Each opens from Ctrl+N; the ones that wrap an external binary appear only when that binary is on PATH (greyed with an install link otherwise).
Define your own pane types in TOML — see the plugin reference.
Documentation
The full doc index lives at docs/README.md.
Contributing
See CONTRIBUTING.md for branch / commit conventions and the development workflow. Bug reports and PRs welcome.
License
Apache License 2.0 — Copyright 2026 Artjoms Stukans
"Quil" and the Quil mark are trademarks of Artjoms Stukans. The licence covers the code, not the name — see TRADEMARK.md if you are distributing a modified build.
The Windows build bundles Microsoft's MIT-licensed OpenConsole (OpenConsole.exe + conpty.dll) to host terminal panes correctly on Windows 10. See THIRD_PARTY_LICENSES.md for full third-party attribution.