Terminal session manager for AI coding agents. Use when user mentions 'agent-deck', 'session', 'sub-agent', 'MCP attach', 'git worktree', or needs to (1) create/start/stop/restart/fork sessions, (2) attach/detach MCPs, (3) manage groups/profiles, (4) get session output, (5) configure agent-deck, (6) troubleshoot issues, (7) launch sub-agents, or (8) create/manage worktree sessions. Covers CLI commands, TUI shortcuts, config.toml options, and automation.
Terminal session manager for AI coding agents. Built with Go + Bubble Tea.
Repo: github.com/asheshgoplani/agent-deck | Discord: discord.gg/e4xSs6NBN8
Run
agent-deck --versionfor your installed version. This skill targets v1.9+ but most patterns work back to v1.7.
This skill includes helper scripts in its scripts/ subdirectory. When Claude Code loads this skill, it shows a line like:
Base directory for this skill: /path/to/.../skills/agent-deck
You MUST use that base directory path to resolve all script references. Store it as SKILL_DIR:
# Set SKILL_DIR to the base directory shown when this skill was loaded
SKILL_DIR="/path/shown/in/base-directory-line"
# Then run scripts as:
$SKILL_DIR/scripts/launch-subagent.sh "Title" "Prompt" --wait
Common mistake: Do NOT use <project-root>/scripts/launch-subagent.sh. The scripts live inside the skill's own directory (plugin cache or project skills folder), NOT in the user's project root.
For plugin users, the path looks like: ~/.claude/plugins/cache/agent-deck/agent-deck/<hash>/skills/agent-deck/scripts/
For local development, the path looks like: <repo>/skills/agent-deck/scripts/
# Launch TUI
agent-deck
# Create and start a session
agent-deck add -t "Project" -c claude /path/to/project
agent-deck session start "Project"
# Send message and get output
agent-deck session send "Project" "Analyze this codebase"
agent-deck session output "Project"
What agent-deck does, at the noun level (independent of which surface — CLI / TUI / Web UI — you reach it through). Each row maps to one or more commands, keystrokes, or screens. For full surface coverage and per-row known issues, see your conductor's CAPABILITIES.md (generated by the Self-Improvement workflow below).
| Capability | What it does | Surfaces |
|---|---|---|
| Manage sessions | Create, start, stop, restart, fork, send, output, remove a session | CLI ✅ · TUI ✅ · Web UI 🟡 |
| Sub-agent / worker spawning | agent-deck launch a child Claude session with parent linkage and inherited --add-dir | CLI ✅ · TUI ⚪ |
| Manage conductors | Set up long-lived orchestrators with their own profile + channel + heartbeat | CLI ✅ · TUI 🟡 |
| Manage groups | Move / delete groups; organize sessions hierarchically | CLI ✅ · TUI ✅ |
| Manage watchers | Install / configure event-driven adapters (Gmail, GitHub, ntfy) — doorbell-not-messenger | CLI ✅ · TUI ✅ |
| Heartbeat orchestration | Cron / ScheduleWakeup feeding the conductor periodic system-state nudges | CLI ✅ |
| Worktree workflows | --worktree to create isolated git-worktree-backed sessions for parallel branch work | CLI ✅ |
| Channel routing | Telegram / Slack inbound delivery to the right conductor, with --channels per-session binding | CLI ✅ |
| Attach MCPs | Per-session or global MCP plugin attach / detach / status, with optional pooling | CLI ✅ · TUI ✅ · Web UI ⚪ |
| Attach skills | Pool-based on-demand skill loading per Claude session | CLI ✅ · TUI ✅ |
| Session-metadata mutation | session set for claude-session-id, path, wrapper, channels, parent; session unset-parent | CLI ✅ |
| State persistence | state.json + task-log.md + LEARNINGS.md + HANDOFF.md survive Claude Code compaction/restart | CLI ✅ |
| GitHub pipeline oversight | Conductor-driven release flow: PR merge → tag → goreleaser → release | CLI ✅ |
| Remote sessions | SSH-based remote register / list / attach across hosts | CLI ✅ |
| Session sharing | Export / import a Claude conversation for handoff between developers | CLI ✅ |
| Consult another agent | Launch a Codex / Gemini sub-agent for a second opinion | CLI ✅ |
| Profile-scoped operation | -p <profile> separation between personal and work auth | CLI ✅ · TUI ✅ |
| Self-improvement | Analyze your conductor's own transcripts → surface bugs / patterns / capabilities, file GH issues with privacy guards | CLI ✅ |
Status legend: ✅ verified, 🟡 partial, 🔴 known broken, ⚪ unknown. To update for your own machine, see Self-Improvement below.
The table above is what agent-deck does. This one is what the CLI inside a session can do — agent-deck launches one per session (-c claude|codex|gemini). A conductor uses this to pick the right tool for a child; a launched child uses it to know its own powers without being told. This is a capability map, not a manual — run <cli> --help for exact flags. Verified 2026-06 against claude 2.1.x, codex-cli 0.137, gemini 0.45.
| In-session capability | claude (Claude Code) | codex | gemini |
|---|---|---|---|
| Multi-agent fan-out inside one session | ✅ Agent tool (parallel subagents, each its own context window; run_in_background) and Workflow tool (deterministic JS: agent()/pipeline()/parallel() over item lists, structured-output schemas, phases) | ❌ single-agent — fan out by launching codex peers via agent-deck | ❌ not exposed — fan out via agent-deck peers |
| Skills | ✅ Skill tool + agent-deck pool skills (~/.agent-deck/skills/pool/; new installs $XDG_DATA_HOME/agent-deck/skills/pool/, default ~/.local/share/agent-deck/skills/pool/) | ❌ | ✅ gemini skills |
| MCP servers | ✅ claude mcp / --mcp-config; agent-deck mcp attach | ✅ codex mcp; also runs as a server (codex mcp-server) | ✅ gemini mcp, --allowed-mcp-server-names |
| Built-in code review | ✅ ultrareview (cloud multi-agent) + /code-review skill | ✅ codex review / codex exec review --uncommitted | via prompt only |
| Plan / read-only mode | --permission-mode plan | -s read-only | --approval-mode plan |
| Autonomy / sandbox | --permission-mode acceptEdits\|bypassPermissions; config dangerous_mode | -s read-only\|workspace-write\|danger-full-access; --dangerously-bypass-approvals-and-sandbox | --approval-mode auto_edit\|yolo, -s/--sandbox |
| Structured output | --json-schema, --output-format json | codex exec json event stream | -o json\|stream-json |
| Image input (multimodal) | paste / Read an image | -i/--image (attach to prompt; not image generation) | multimodal prompt |
| Apply a diff to working tree | Edit/Write tools | codex apply (git-apply the last agent diff) | Edit tools |
| Git worktree | -w/--worktree | via agent-deck --worktree | -w/--worktree |
| Plugins / extensions / hooks / channels | plugin, --plugin-dir/-url, hooks, --channels | codex plugin | extensions, hooks |
| Resume / fork conversation | -r/--resume, --fork-session | codex resume / codex fork | --resume, --session-file |
| Local / OSS models | 3P providers (Bedrock/Vertex) | --oss, --local-provider lmstudio\|ollama | gemini gemma routing |
Choosing the -c tool for a child: default to claude — only it has in-session multi-agent fan-out (Agent + Workflow tools) and pool skills, so it can own a whole task end-to-end and orchestrate its own sub-work. Reach for codex for a fast non-interactive second opinion or code review (codex review) and sandboxed exec; gemini for a third opinion or large-context reads. For codex/gemini, parallelism comes from launching multiple agent-deck peers, not from inside the session.
agent-deck powers every child also has (independent of CLI): agent-deck mcp attach/detach then session restart; launch further child or peer sessions (-no-parent for peers); load pool skills on demand; session send to talk to sibling sessions. See Sub-Agent Launch, Peer (Root) Sessions vs Sub-Agents, MCP Management.
When to go inline vs Agent tool vs Workflow (for claude children) is owned by the shared conductor template's Delegation section (~/.agent-deck/conductor/conductor-claude.md) and is not duplicated here: 1 task = inline; a few independent subtasks = Agent tool; a sweep / audit / matrix = Workflow — and always adversarially verify findings with a second agent told to refute.
| Command | Purpose |
|---------|---------|
| agent-deck | Launch interactive TUI |
| agent-deck add -t "Name" -c claude /path | Create session |
| agent-deck launch . -c claude --account <name> | Create and start a session under a named account slot |
| agent-deck accounts [--json] | List configured named account slots |
| agent-deck session start/stop/restart <name> | Control session |
| agent-deck session send <name> "message" | Send message |
| agent-deck session send <name> --message-file <file> | Send message from file (- = stdin); no shell quoting. Also on launch/session start |
| agent-deck session output <name> | Get last response |
| agent-deck session children --json | Child sessions' live status + asserted completions (non-blocking, read-only) |
| agent-deck session current [-q\|--json] | Auto-detect current session |
| agent-deck session fork <name> | Fork Claude/Pi conversation |
| agent-deck session switch-account <name> <account> | Switch Claude account, conversation follows |
| agent-deck mcp list | List available MCPs |
| agent-deck mcp attach <name> <mcp> | Attach MCP (then restart) |
| agent-deck status | Quick status summary |
| agent-deck add --worktree <branch> | Create session in git worktree |
| agent-deck try <name> | Scratch session in a dated experiment folder |
| agent-deck worktree list | List worktrees with sessions |
| agent-deck worktree cleanup | Find orphaned worktrees/sessions |
| agent-deck feedback | Submit feedback (opens rating prompt + optional comment) |
Status: ● running | ◐ waiting | ○ idle | ✕ error
Use when: User says "launch sub-agent", "create sub-agent", "spawn agent"
$SKILL_DIR/scripts/launch-subagent.sh "Title" "Prompt" [--mcp name] [--wait]
The script auto-detects current session/profile and creates a child session.
| Mode | Command | Use When |
|------|---------|----------|
| Fire & forget | (no --wait) | Default. Tell user: "Ask me to check when ready" |
| On-demand | agent-deck session output "Title" | User asks to check |
| Blocking | --wait flag | Need immediate result |
This section covers one child (launch + one of the three retrieval modes). For a fleet — several children in parallel, supervised non-blockingly from the parent — load the sibling fleet skill instead. It covers parented fan-out, polling live status and asserted completions via agent-deck session children --json (plus the push variant --follow --until-done), answering children stuck in waiting, and the grouping/--parent pitfalls.
| Task Type | MCPs |
|-----------|------|
| Web research | exa, firecrawl |
| Code documentation | context7 |
| Complex reasoning | sequential-thinking |
When the prompt asks the worker to Edit or Write any existing file, include an explicit prelude-read as the first step. Claude Code's tool guard rejects Edit/Write before Read of the same path, and conductor-spawned workers hit this mid-task (#968) when their prompt jumps straight into the change. The interruption forces the worker to backfill reads inside its main loop, breaking flow and burning cycles.
Template skeleton — bake this into every worker prompt that mutates code:
## Step 0 — Prelude reads
Read every file you intend to Edit/Write below. Read calls are cheap
and do NOT count against scope discipline; they prevent tool-guard
interruptions mid-task. Skip only for paths that will be created fresh.
Files to read first:
- <path/to/file/you/will/edit>
- <path/to/other/file/you/will/edit>
## Step 1 — Investigation
…
## Step 2 — Implementation
…
Rules:
Read it first, even if the worker "knows" the contents.Write to a path that does not yet exist): no prelude needed — the guard only applies to modifications.A worker's Stop hook fires at the end of every turn, so "waiting" never means "done" — the conductor would otherwise have to poll RESULTS files / gh pr / session output to know a task actually finished. Instead, instruct every worker to assert completion by ending its final turn with a single machine-greppable line:
===AGENTDECK_DONE=== status=<ok|fail> summary=<one line to end of line>
agent-deck detects this on the Stop edge (scanning the transcript tail) and emits a distinct event to the parent:
[DONE] Child '<name>' (<id>) finished: status=ok summary=<...>
instead of the generic [EVENT] … is waiting. This is by-construction: completion is asserted by the only party that knows (the worker), not inferred from terminal cosmetics.
Bake this line into every worker prompt's final instruction:
## Final step — assert completion
When the task is fully done, print exactly this as the last line of your final message:
===AGENTDECK_DONE=== status=ok summary=<what you accomplished, one line>
Use status=fail if you could not complete it; put the blocker in the summary.
Notes:
Stop — does not re-emit. A genuinely new completion (different summary) emits again.Stop edges, so existing waiting behavior is unchanged.status) are ignored, not guessed at.Use when: User says "consult with codex", "ask gemini", "get codex's opinion", "what does codex think", "consult another agent", "brainstorm with codex/gemini", "get a second opinion"
IMPORTANT: You MUST use the --tool flag to specify which agent. Without it, the script defaults to Claude.
# Consult Codex (MUST include --tool codex)
$SKILL_DIR/scripts/launch-subagent.sh "Consult Codex" "Your question here" --tool codex --wait --timeout 120
# Consult Gemini (MUST include --tool gemini)
$SKILL_DIR/scripts/launch-subagent.sh "Consult Gemini" "Your question here" --tool gemini --wait --timeout 120
DO NOT try to create Codex/Gemini sessions manually with agent-deck add. Always use the script above. It handles tool-specific initialization, readiness detection, and output retrieval automatically.
$SKILL_DIR/scripts/launch-subagent.sh "Title" "Prompt" \
--tool codex|gemini \ # REQUIRED for non-Claude agents
--path /project/dir \ # Working directory (auto-inherits parent path if omitted)
--wait \ # Block until response is ready
--timeout 180 \ # Seconds to wait (default: 300)
--mcp exa # Attach MCP servers (can repeat)
| Tool | Flag | Notes |
|------|------|-------|
| Claude | --tool claude | Default, no flag needed |
| Codex | --tool codex | Requires codex CLI installed |
| Gemini | --tool gemini | Requires gemini CLI installed |
--wait: polls until the agent responds, then returns the full output--wait: returns immediately, check output later with agent-deck session output "Title"# Code review from Codex
$SKILL_DIR/scripts/launch-subagent.sh "Codex Review" "Read cmd/main.go and suggest improvements" --tool codex --wait --timeout 180
# Architecture feedback from Gemini
$SKILL_DIR/scripts/launch-subagent.sh "Gemini Arch" "Review the project structure and suggest better patterns" --tool gemini --wait --timeout 180
# Both in parallel (consult both, compare answers)
$SKILL_DIR/scripts/launch-subagent.sh "Ask Codex" "Best way to handle errors in Go?" --tool codex --wait --timeout 120 &
$SKILL_DIR/scripts/launch-subagent.sh "Ask Gemini" "Best way to handle errors in Go?" --tool gemini --wait --timeout 120 &
wait
After getting the response, remove the consultation session:
agent-deck remove "Consult Codex"
# Or remove multiple at once:
agent-deck remove "Codex Review" && agent-deck remove "Gemini Arch"
The default — sub-agent linkage: agent-deck launch and agent-deck add, when invoked from inside an existing agent-deck session, automatically link the new session as a child of the calling session (sets parent_session_id, inherits the parent's group when -g is omitted, and grants --add-dir to the parent's project path). This is usually what you want for short-lived work sessions (plan / verify / release / consult).
When the default is wrong — root-level peer sessions: if you are creating a session that should stand independently at the root — a peer conductor, a standalone project session, a session that should outlive the current one, or anything that semantically is NOT a child of the calling session — pass the -no-parent flag.
| Use case | Parent linkage | Flag |
|---|---|---|
| Plan / impl / verify worker for the current task | ✅ child | (default) |
| Consultation (codex / gemini / research) | ✅ child | (default) |
| Another conductor (root-level peer) | ❌ child | -no-parent |
| Project session unrelated to current work | ❌ child | -no-parent |
| Session intended to outlive the caller | ❌ child | -no-parent |
# Root-level peer conductor, no parent linkage:
agent-deck launch ~/projects/foo -t "conductor-foo" -g "conductor" -c claude -no-parent -m "..."
# Verify after spawn:
agent-deck list --json | jq '.[] | select(.title=="conductor-foo") | .parent_session_id'
# Must print: null
Symptoms you created a sub-agent when you wanted a peer:
parent_session_id is non-null in list --json outputpane_start_command contains --add-dir <caller's path> even though you gave it a different project pathFix for an already-created sub-agent: stop + remove the session, re-launch with -no-parent. There is no in-place un-parent flag.
Note on the launch-subagent.sh script: that script is specifically designed to create sub-agents (the name says so). It does NOT support -no-parent. For peer sessions, skip the script and invoke agent-deck launch -no-parent directly.
A conductor is a persistent agent-deck session that orchestrates other sessions. It watches the rest of your sessions, auto-responds when confident, escalates to you when ambiguous, and optionally pairs with a remote channel (Telegram or Slack) so you can talk to it from your phone.
Use this section when the user says "conductor", "set up a conductor", "monitor sessions", "telegram bot for agent-deck", "slack bot for agent-deck", or "remote control my sessions".
# Create a conductor in the default profile
agent-deck conductor setup ops --description "Ops monitor"
# Create on a specific profile (work/personal/etc.)
agent-deck -p work conductor setup infra --description "Infra watcher"
# Use a non-Claude agent for the conductor itself
agent-deck conductor setup review --agent codex --description "Codex reviewer"
# Provide custom env (e.g., third-party Anthropic-compatible endpoint)
agent-deck conductor setup glm-bot \
-env ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic \
-env ANTHROPIC_AUTH_TOKEN=<token>
# Status across all conductors
agent-deck conductor status
# List configured conductors
agent-deck conductor list
Each conductor lives at ~/.agent-deck/conductor/<name>/ (new installs: $XDG_DATA_HOME/agent-deck/conductor/<name>/, default ~/.local/share/agent-deck/conductor/<name>/) with its own CLAUDE.md (or AGENTS.md for Codex), meta.json, state.json, and task-log.md. Multiple conductors per profile are supported and each can pair with its own bot.
Channels are how a conductor talks to you remotely. Each conductor pairs one-to-one with its own bot — bots are not shared. agent-deck conductor setup interactively walks you through Telegram or Slack pairing during creation.
Key constraints:
settings.json. Per-session activation happens via the channels field on the conductor's session record.<channel-state-dir>/.env (chmod 600). Never committed to git.TELEGRAM_STATE_DIR and can leak duplicate pollers on the same bot token, causing 409 conflicts.See: docs/conductor/ for the full quickstart, channel setup, multi-conductor setups, and lifecycle commands.
| Key | Action |
|-----|--------|
| j/k or ↑/↓ | Move up/down |
| h/l or ←/→ | Collapse/expand groups |
| Enter | Attach to session |
| Key | Action |
|-----|--------|
| n | New session |
| r/R | Restart (reloads MCPs) |
| m | MCP Manager |
| s | Skills Manager |
| f/F | Fork Claude/OpenCode/Pi/Codex session |
| d | Delete |
| A | Archive (stops tmux, hides from default list) |
| Shift+U | Unarchive (does not auto-start tmux) |
| M | Move to group |
| Key | Action |
|-----|--------|
| / | Local search |
| G | Global search (all Claude conversations) |
| !@#& | Filter by status (running/waiting/idle/error) |
| ^ | View archived sessions |
| Key | Action |
|-----|--------|
| ? | Help overlay |
| Ctrl+Q | Detach (keep tmux running) |
| Ctrl+E | Open feedback dialog |
| q | Quit |
Default: Do NOT attach MCPs unless user explicitly requests.
# List available
agent-deck mcp list
# Attach and restart
agent-deck mcp attach <session> <mcp-name>
agent-deck session restart <session>
# Or attach on create
agent-deck add -t "Task" -c claude --mcp exa /path
Scopes:
.mcp.json in project, affects only that session--global) - Claude config, affects all projectsSearch for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer