---
name: Agent Deck
slug: agent-deck
category: AI Engineering
description: Agent Deck manages terminal sessions for AI coding agents. Use it to create, start, stop, restart, fork, and inspect sessions, attach MCPs, launch sub-agents, and manage worktree-based workflows.
github: "https://github.com/asheshgoplani/agent-deck/tree/main/skills/agent-deck"
language: Go
stars: 775
forks: 135
install: "npx degit https://github.com/asheshgoplani/agent-deck/tree/main/skills/agent-deck ~/.claude/skills/agent-deck"
installs_to: ~/.claude/skills/agent-deck
source_path: skills/agent-deck/SKILL.md
collection_size: 5
category_size: 2451
collection_url: "https://dirskills.com/collections/asheshgoplani/agent-deck"
added: 2026-08-23T05:19:06.807Z
last_synced: 2026-08-23T05:19:06.807Z
canonical_url: "https://dirskills.com/skills/agent-deck"
---

# Agent Deck

Agent Deck manages terminal sessions for AI coding agents. Use it to create, start, stop, restart, fork, and inspect sessions, attach MCPs, launch sub-agents, and manage worktree-based workflows.

**Install:**

```bash
npx degit https://github.com/asheshgoplani/agent-deck/tree/main/skills/agent-deck ~/.claude/skills/agent-deck
```

## README

# Agent Deck

Terminal session manager for AI coding agents. Built with Go + Bubble Tea.

**Repo:** [github.com/asheshgoplani/agent-deck](https://github.com/asheshgoplani/agent-deck) | **Discord:** [discord.gg/e4xSs6NBN8](https://discord.gg/e4xSs6NBN8)

> Run `agent-deck --version` for your installed version. This skill targets v1.9+ but most patterns work back to v1.7.

## Script Path Resolution (IMPORTANT)

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`:

```bash
# 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/`

## Quick Start

```bash
# 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"
```

## Capabilities

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](#self-improvement) below.

## Per-CLI Capabilities (what a launched session can do)

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](#sub-agent-launch), [Peer (Root) Sessions vs Sub-Agents](#peer-root-sessions-vs-sub-agents), [MCP Management](#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.

## Essential Commands

| Command | Purpose |
|---------|---------|
| `agent-deck` | Launch interactive TUI |
| `agent-deck add -t "Name" -c claude /path` | Create session |
| `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

## Sub-Agent Launch

**Use when:** User says "launch sub-agent", "create sub-agent", "spawn agent"

```bash
$SKILL_DIR/scripts/launch-subagent.sh "Title" "Prompt" [--mcp name] [--wait]
```

The script auto-detects current session/profile and creates a child session.

### Retrieval Modes

| 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 |

### Fanning out several children?

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](../fleet/SKILL.md) 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.

### Recommended MCPs

| Task Type | MCPs |
|-----------|------|
| Web research | `exa`, `firecrawl` |
| Code documentation | `context7` |
| Complex reasoning | `sequential-thinking` |

### Worker Prompt Conventions

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:**
- Any file the worker will modify: prelude `Read` it first, even if the worker "knows" the contents.
- Brand-new files (`Write` to a path that does not yet exist): no prelude needed — the guard only applies to modifications.
- For conductor nudges that re-fire the same prompt across cycles, keep Step 0 in the prompt. The second-cycle process may not have prior reads in context.

### Completion sentinel (trustworthy "worker finished" signal, #1186)

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:
- Fires once per distinct completion (idempotent per task): re-reading the same sentinel across polls — or repeating an identical sentinel on a later `Stop` — does not re-emit. A genuinely new completion (different summary) emits again.
- Absent on ordinary mid-task `Stop` edges, so existing `waiting` behavior is unchanged.
- Malformed sentinel lines (missing/invalid `status`) are ignored, not guessed at.

## Consult Another Agent (Codex, Gemini)

**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.

### Quick Reference

```bash
# 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.

### Full Options

```bash
$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)
```

### Supported Tools

| Tool | Flag | Notes |
|------|------|-------|
| Claude | `--tool claude` | Default, no flag needed |
| Codex | `--tool codex` | Requires `codex` CLI installed |
| Gemini | `--tool gemini` | Requires `gemini` CLI installed |

### How It Works

1. Script auto-detects current session and profile
2. Creates a child session with the specified tool in the parent's project directory
3. Waits for the tool to initialize (handles Codex approval prompts automatically)
4. Sends the question/prompt
5. With `--wait`: polls until the agent responds, then returns the full output
6. Without `--wait`: returns immediately, check output later with `agent-deck session output "Title"`

### Examples

```bash
# 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
```

### Cleanup

After getting the response, remove the consultation session:

```bash
agent-deck remove "Consult Codex"
# Or remove multiple at once:
agent-deck remove "Codex Review" && agent-deck remove "Gemini Arch"
```

## Peer (Root) Sessions vs Sub-Agents

**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` |

```bash
# 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` output
- The new session's baked `pane_start_command` contains `--add-dir <caller's path>` even though you gave it a different project path
- Transition events for the new session's children flow to the caller instead of the new peer
- Event routing and heartbeat parent-linkage puts it under the caller's tree in the TUI

**Fix 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.

## Conductors

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"**.

```bash
# 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 watc
