Skip to content

Repository files navigation

canopy

canopy is a terminal UI for developers running multiple AI coding agents in parallel. One view. All your agents.

Go version Go Report Card License: MIT Platform

Table of Contents

Canopy dashboard

Each worktree gets a dedicated tmux session so your agent runs in a real terminal with full PTY support. Canopy sits above all of them: monitor every agent at a glance and drop in when you need to.

Why canopy?

Managing 3–5 parallel AI agents across separate terminals is chaotic. You have no overview of what's running, you're constantly switching windows, and there's no signal for when an agent needs your input. Canopy gives you one persistent view: see every agent's state, catch anything waiting for you, and drop in when needed.

Demo

Creating a worktree

New worktree

Requirements

Install

Quick install (Linux & macOS):

curl -fsSL https://raw.githubusercontent.com/isacssw/canopy/main/install.sh | sh

Homebrew:

brew install isacssw/tap/canopy

With Go:

go install github.com/isacssw/canopy/cmd/canopy@latest

Usage

Run from anywhere inside your git repo:

canopy

First run will open a short setup wizard to configure your agent command and give it a name.

canopy --help      # show keybinds and usage
canopy --version   # print version

Config is saved to ~/.config/canopy/config.json.

Keybinds

Key Action
↑/↓ or j/k Navigate worktrees
n Create new worktree (prompts for branch + base)
r Run agent in selected worktree (shows picker if multiple agents are configured)
a Attach to the live tmux session (full interactive agent)
x Kill running agent
d View git diff for selected worktree
D Delete worktree (confirm with y, then 5-second undo window)
u / esc Cancel a pending delete during the countdown
i Send input to agent when it's waiting
R Refresh worktree list
e Open selected diff file in your editor at the changed line
? Toggle keybindings help overlay
q Quit

Mouse support

Click any worktree in the left panel to select it. Use the scroll wheel to scroll the output panel.

Attaching to an agent

Press a to drop into the agent's tmux session and interact with it directly. Canopy suspends while you're attached. Press Ctrl+b d to detach and return to canopy.

Nested tmux sessions: If you're already running inside a tmux session, canopy opens a nested session. To detach from the inner (canopy) session, press Ctrl+b twice then d. The first Ctrl+b is consumed by your outer session, so you need a second one to reach the inner session. To avoid the double-prefix, set "tmux_prefix": "C-Space" (or any other key) in your config — canopy's sessions will use that prefix instead.

Agent states

Icon State Meaning
idle No agent running
running Agent active
waiting Agent needs your input, press i or a
done Agent finished cleanly
error Agent exited with error

When an agent transitions to waiting, canopy marks it with a yellow badge in the list and emits a terminal bell, so you notice even when working in another window. The badge clears when you navigate to that worktree.

The status bar shows a live summary of agent counts (e.g. 1 running · 2 waiting) on the right side.

Idle timeout

With idle_timeout_secs set, any agent that has produced no new output for that many seconds is automatically promoted from running to waiting. This is a useful fallback for agents that don't emit standard input-prompt patterns. Set to 0 (the default) to disable.

How it works

When you press r, canopy creates a detached tmux session named canopy_<repo-hash>_<branch> and launches your agent command inside it. The output panel shows a live snapshot of the tmux pane, refreshed every 500ms.

Session names include a short hash of the repo root, so branches with the same name across different repos never collide.

Agents keep running after you quit canopy. They're just tmux sessions. You can reattach at any time with tmux attach -t <session-name> or by reopening canopy and pressing a.

Config

~/.config/canopy/config.json:

{
  "agents": [
    { "name": "claude", "command": "claude" },
    { "name": "claude-yolo", "command": "claude --dangerously-skip-permissions" },
    { "name": "codex", "command": "codex" }
  ],
  "left_panel_width": 38,
  "theme": "github-dark",
  "output_colors": "adaptive",
  "idle_timeout_secs": 0,
  "tmux_prefix": "C-Space"
}

With a single agent configured, pressing r starts it immediately. With two or more, a picker appears so you can choose which profile to run.

Field Default Description
agents List of agent profiles. Each entry has a name (label shown in the picker) and a command (executable + flags).
agent_command Legacy. Single agent command, used when agents is not set. Existing configs continue to work without any changes.
left_panel_width 38 Width of the worktree list panel in columns. Minimum 20. Omit to use the default.
theme "github-dark" UI colour theme. Options: "github-dark", "nord", "catppuccin", "light". Omit or leave empty for the default.
output_colors theme-dependent Agent output colour handling. Options: "preserve" to keep raw ANSI colours from tmux, "plain" to strip ANSI and render output with the current theme text colour, or "adaptive" to remap ANSI colours into the active theme palette. Defaults to "adaptive" for the light theme and "preserve" otherwise.
idle_timeout_secs 0 Seconds of no new agent output before status is promoted from running to waiting. 0 disables the timeout. Useful for non-Claude agents that don't emit standard input-prompt patterns.
tmux_prefix Custom prefix key for canopy's tmux sessions (e.g. "C-Space", "C-a"). Avoids double-prefix when running inside an existing tmux. Omit to use tmux's default (C-b).

Themes

Name Description
github-dark Default, GitHub dark palette
nord Nord palette, cool blues and greens
catppuccin Catppuccin Mocha, pastel dark theme
light Light terminal palette

Soft delete

Pressing D on a worktree asks for confirmation. After pressing y, canopy starts a 5-second countdown displayed in the status bar (Deleting "branch" in 5s… [u]ndo). Press u, esc, or n at any point during the countdown to cancel. The delete only executes when the timer reaches zero.

Editor Integration

Neovim

For Neovim users, see canopy.nvim for setup instructions and integration.

VS Code and Cursor

Set EDITOR=code or EDITOR=cursor and press e from diff view. Canopy opens the selected file at the first changed hunk line in your GUI editor.

Contributing

See CONTRIBUTING.md. Contributions, bug reports, and feature requests are welcome.

License

MIT, see LICENSE

About

canopy is a terminal UI for developers running multiple AI coding agents in parallel. One view. All your agents.

Resources

Contributing

Stars

25 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages