| name | codans |
| description | Drive the codans Mac app from a terminal with the `codans` CLI — inspect the Project / Worktree / Tab / Pane hierarchy, create and switch worktrees, spawn tabs and panes, send keystrokes or text to a pane, read back its rendered output, broadcast input across panes, and check app health. Use this skill whenever the user is operating inside a codans Pane, references the `codans` command, asks how to script codans, or wants to coordinate panes / worktrees / agents from the shell. Prefer `codans tree` to discover state before issuing any other command. |
codans CLI (codans)
What is codans?
codans is a macOS desktop app built for the next generation of
agent-based parallel development. At its core it is a parallel-development
tool on top of git worktree + terminals, organised as
Project → Worktree → Tab → Pane. Terminals are rendered natively via
libghostty.
codans is the command-line client that drives the app over a local Unix
domain socket — the same things the GUI does, scriptable from any shell.
The binary is installed as codans.
Before you run anything: check it's installed
Before suggesting any codans command, verify the app is installed and
reachable:
codans doctor
Three outcomes:
-
Prints socketReachable true — app is installed and running.
Proceed.
-
Prints socketReachable false — app is installed but not running.
Run codans launch (or open Codans from /Applications) and retry.
-
codans: command not found — Codans is not installed. Stop and tell
the user to install it from the releases page:
Codans is not installed. Download the latest .dmg from
https://github.com/wanggang316/codans/releases/, drag
Codans.app into /Applications, launch it once so codans lands
on PATH, then retry.
Do not invent fallback commands or try to install it via Homebrew / npm
/ pip — there is no such package today; the GitHub releases page is the
only distribution channel.
When to use
- The user is inside a codans Pane and wants to script some action.
- The user mentions "codans ..." or asks how to do something in codans from
the terminal.
- An agent (Claude Code, Codex, custom) wants to read a sibling pane's
output, send input to it, or spawn new panes / tabs / worktrees.
- The user wants to inspect the codans app's state without opening the
GUI.
Hierarchy in 60 seconds
Project a tracked git repo (one Project per repo)
└── Worktree a git worktree of that repo (own dir + branch + tab layout)
└── Tab one named grouping of panes in a worktree (one Tab visible)
└── Pane a single libghostty terminal session
codans is on PATH automatically inside every codans Pane, and the app
auto-detects which Project / Worktree / Tab / Pane that Pane belongs to —
so most commands default to the surrounding context and you rarely need
to pass IDs.
Targeting model
Most subcommands accept identifiers in any of these forms:
current or . — the ambient Project / Worktree / Tab / Pane of
the shell you're running codans from. This is the default for nearly every
--project, --worktree, --tab, and --pane flag, so you usually
don't have to type anything.
- Literal UUID — passed through unchanged; fast path for scripts.
@label (panes only) — server-side lookup against pane labels
applied with codans pane label.
- Anything else — sent to the server's alias resolver (e.g. a project
name or a worktree alias the app knows about).
If you run codans from a shell that is not inside a codans Pane,
current has no meaning and you'll get a noContext error — pass an
explicit UUID, or use codans tree to discover one.
Global flags
These work on every subcommand (mounted via @OptionGroup):
--json — machine-readable output instead of text.
--socket <path> — talk to a non-default socket (rarely needed; the
default points at the running app automatically).
--timeout <seconds> — RPC client timeout (default 10s).
Use codans <subcommand> --help for the exact flag list of any command.
Quick start
codans doctor
codans tree
codans pane send 'pwd'
codans pane read
Command reference
App & diagnostics
codans status
codans launch [--wait 10]
codans doctor
codans launch is idempotent — if the app is already up it just prints the
existing socket path.
codans tree — discover state
codans tree
codans tree --json
codans tree --project current
Always run codans tree first when you don't know what's around. The text
form marks the selected worktree/tab with * and prints pane labels as
@label.
codans project — manage projects
codans project list
codans project add ~/code/api
codans project add --name "API" ~/code/api
codans project rm <project>
Adding a project just registers it with codans; it does not move
files. Removing only de-registers — no files are deleted.
codans worktree — manage git worktrees
codans worktree list
codans worktree list --project <project>
codans worktree new <branch>
codans worktree new --path /abs/path --name "Hotfix" <branch>
codans worktree switch <worktree>
codans worktree rm <worktree>
<branch> is required for new. --path accepts a relative path
(resolved against $PWD) or an absolute one. --name overrides the
display label (defaults to the branch).
codans tab — manage tabs inside a worktree
codans tab list
codans tab new
codans tab new "dev server"
codans tab switch <tab>
codans tab close <tab>
codans tab new creates the tab but does not spawn a pane inside it — use
codans pane new for that, or rely on the GUI's auto-pane behavior.
codans pane — manage and drive panes
Creation / lifecycle:
codans pane list
codans pane new
codans pane new --label agent --label claude -- claude
codans pane new --cwd /tmp -- htop
codans pane focus <pane>
codans pane close <pane>
codans pane reset <pane>
codans pane label <pane> agent debug
codans pane label <pane> agent --replace
Terminal I/O (also accessible as codans pane send, codans pane send-key,
codans pane read, codans pane capture):
codans pane send 'echo hi'
codans pane send <pane> 'echo hi'
codans pane send -p @agent 'status'
codans pane send --stdin <<<'long blob'
codans pane send --no-enter 'partial '
codans pane send --focus <pane> 'cmd'
codans pane send-key escape
codans pane send-key <pane> ctrl_c
codans pane send --raw 1b5b41
codans pane read
codans pane read --screen
codans pane read --selection
codans pane capture --lines 50
codans pane capture --scope screen
Notes:
codans pane send appends \n by default. Use --no-enter to leave the
shell prompt waiting for more input.
--raw ships hex bytes directly (e.g. 1b = ESC); control bytes ride a
key-event path, printable bytes ride the text channel.
- Pane I/O is rendered-text only — codans does not expose the raw PTY
byte stream, so OSC / CSI / APC sequences are not visible via
read or
capture. Track app-level state via codans tree instead.
codans broadcast — fan out input
codans broadcast --tab current 'pwd'
codans broadcast --worktree <wt> 'git status'
codans broadcast --label agent 'reload'
codans broadcast --tab current --no-enter '#!comment'
codans broadcast --label deploy --stdin <<<'rolling restart'
Exactly one of --tab, --worktree, or --label must be given. The
returned delivered count tells you how many panes received the input.
Common patterns
Read a sibling pane (agent A inspecting agent B)
codans pane list --json | jq -r '.panes[].id'
codans pane read <uuid>
codans pane capture <uuid> --lines 200 > /tmp/log.txt
If both panes share a tab, label the target once (codans pane label <uuid> agent)
and refer to it as @agent thereafter.
Drive a REPL from a script
codans pane new --label repl -- python3
codans pane send -p @repl 'import math'
codans pane send -p @repl 'print(math.pi)'
codans pane capture -p @repl --lines 3
Spin up a worktree and a tab for it
codans worktree new exp/feature-x
codans worktree switch "$(codans tree --json | jq -r '.projects[0].worktrees[-1].id')"
codans tab new "dev"
codans pane new -- npm run dev
JSON-driven scripting
Every command supports --json. Pipe through jq to extract IDs without
parsing the human format:
PANE=$(codans pane list --json | jq -r '.panes[0].id')
codans pane send "$PANE" 'echo hello from script'
Verify before you act
codans pane send is fire-and-forget — the RPC reports bytes shipped, not the
receiving program's reaction. When coordinating agents across panes, read
back after sending:
codans pane send -p @worker 'run-task'
sleep 1
codans pane read -p @worker | tail -20
(This mirrors the project memory note "prowl send 后 read-back 验证" — the
same idea applies to codans.)
Troubleshooting
| Symptom | Likely cause / fix |
|---|
socket /tmp/codans-*.sock did not become reachable | App isn't running. Run codans launch or open codans from the GUI. |
noContext(kind: .pane) (or project/worktree/tab) | You used current / . outside a codans Pane. Pass an explicit ID. |
pane <uuid> not found | The pane was closed, or the UUID came from a different app instance. |
unknown key "..." | codans pane send-key only knows the keys listed above. Use --raw for the rest. |
--raw is exclusive of ... | codans pane send --raw cannot combine with positional text, --stdin, or --no-enter. |
| Help shows fewer commands than expected | Some legacy docs reference unimplemented commands (e.g. codans open, codans skill, codans agent). Trust codans --help over external docs. |
What this CLI does not do (yet)
To prevent suggesting commands that don't exist:
- No
codans send / codans read / codans send-key / codans capture at top level —
they live under codans pane.
- No
codans open (external editor handoff).
- No
codans skill ... (skill installation lives outside the CLI).
- No
codans agent ... (agent hook installation lives outside the CLI).
- No
codans space ... — codans does not expose a Space concept via codans
today; the hierarchy is rooted at Project.
If a user asks for any of these, surface the gap rather than fabricating a
command.