# Claude Code Source: https://docs.clideck.dev/agents/claude-code Using Claude Code with CliDeck [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview) is Anthropic's CLI coding agent. ## Setup The first time you launch a Claude Code session, CliDeck shows a setup toast. Click **Patch Claude** and CliDeck adds lifecycle hooks to `~/.claude/settings.json`. Claude will ask for one-time approval on next launch. These hooks give CliDeck deterministic start/stop/idle signals — no polling, no heuristics. ## What Works * **Status detection** — Hook-driven. CliDeck receives direct signals when Claude starts working, stops, goes idle, or shows a choice menu * **Message preview** — The sidebar shows the latest output line (identified by the `⏺` marker) * **Session resume** — Session IDs are captured from telemetry for seamless resume * **Notifications** — Get notified when Claude Code finishes a task ## Session Resume When you close CliDeck (or it shuts down), your Claude Code sessions are saved automatically. Next time you open CliDeck, you'll see them in the **Previous Sessions** section of the sidebar. Click the resume button to pick up where you left off. Behind the scenes, CliDeck captures the session ID from Claude Code's telemetry and uses `claude --resume ` to reconnect. ## Telemetry Details CliDeck sets these environment variables when launching Claude Code: | Variable | Value | | ------------------------------ | ----------------------- | | `CLAUDE_CODE_ENABLE_TELEMETRY` | `1` | | `OTEL_LOGS_EXPORTER` | `otlp` | | `OTEL_EXPORTER_OTLP_PROTOCOL` | `http/json` | | `OTEL_EXPORTER_OTLP_ENDPOINT` | `http://localhost:4000` | | `OTEL_LOGS_EXPORT_INTERVAL` | `2000` | These tell Claude Code to send OpenTelemetry logs to CliDeck's local receiver every 2 seconds. The data never leaves your machine. If Claude Code releases a major update that changes its telemetry format, you may need to update CliDeck. Check for the latest version with `npm update -g clideck`. # Codex Source: https://docs.clideck.dev/agents/codex Using OpenAI's Codex CLI with CliDeck [Codex](https://github.com/openai/codex) is OpenAI's CLI coding agent. CliDeck supports it with one-click telemetry setup. ## Setup Click **Codex** in the session launcher. The session starts normally. On first launch, CliDeck shows a setup toast: **"Codex — Status Tracking"**. Click **Configure automatically**. CliDeck adds an `[otel]` section to `~/.codex/config.toml` with the correct endpoint settings. After configuration, click **Restart Session** on the toast. The new session will have telemetry active. This is a one-time setup. All future Codex sessions will have telemetry enabled automatically. ## What the Config Looks Like CliDeck adds this to your `~/.codex/config.toml`: ```toml theme={null} [otel] exporter = { otlp-http = { endpoint = "http://localhost:4000/v1/logs", protocol = "json" } } ``` You can also add this manually if you prefer. ## Session Resume Codex supports session resume. CliDeck captures the session ID from telemetry and uses `codex resume ` to reconnect to previous sessions. ## Disabling Telemetry If you want to stop sending telemetry from Codex to CliDeck: 1. Open **Settings** > **CLI Agents** > **Codex** 2. Toggle off **CliDeck integration** CliDeck will remove the `[otel]` section from your Codex config file. If Codex releases a major update that changes its configuration format, you may need to update CliDeck. Check for the latest version with `npm update -g clideck`. # Custom Agents Source: https://docs.clideck.dev/agents/custom-agents Add any CLI tool as a CliDeck session type Beyond the four built-in agents, you can add any CLI command as a session type in CliDeck. ## Adding a Custom Agent Click the gear icon in the left navigation rail to open Settings. Select the **CLI Agents** category. At the bottom of the agent list, click **Add Agent**. You can pick from unused presets or choose **Custom** to start from scratch. Fill in the details: * **Name** — Display name in the session launcher * **Command** — The CLI command to run (e.g., `aider`, `continue`, `my-custom-script`) * **AI Agent** — Check this if the tool is an AI agent (enables resume options) ## Resume Support If your custom agent supports session resume, you can configure it: 1. Check **AI Agent** to enable the resume section 2. Check **Supports session resume** 3. Enter the **Resume command** with `{{sessionId}}` as a placeholder For example, if your agent resumes with `my-agent --continue SESSION_ID`: ``` my-agent --continue {{sessionId}} ``` CliDeck will substitute the captured session ID when resuming. ## Session ID Capture For resume to work, CliDeck needs to know the session ID. There are two ways this can happen: 1. **Telemetry** — If your agent supports OpenTelemetry, enable telemetry in the agent settings. CliDeck will capture the session ID from OTLP log attributes. 2. **Output matching** — CliDeck can match a regex pattern against the agent's terminal output to find the session ID. The built-in presets use patterns like UUID format (`[0-9a-f]{8}-...-[0-9a-f]{12}`). You can set a custom pattern in the agent configuration. ## Plain Shell Sessions The built-in **Shell** option launches a plain terminal (`/bin/zsh`) with no agent features. This is useful for running quick commands, checking git status, or anything else you'd normally do in a terminal. Shell sessions don't have telemetry, resume, or status detection — they're just regular terminals inside CliDeck. # Gemini CLI Source: https://docs.clideck.dev/agents/gemini-cli Using Google's Gemini CLI with CliDeck [Gemini CLI](https://github.com/google-gemini/gemini-cli) is Google's CLI coding agent. CliDeck supports it with one-click telemetry setup. ## Setup Click **Gemini CLI** in the session launcher. The session starts normally. On first launch, CliDeck shows a setup toast: **"Gemini CLI — Status Tracking"**. Click **Configure automatically**. CliDeck adds a `telemetry` section to `~/.gemini/settings.json` with the correct endpoint settings. After configuration, click **Restart Session** on the toast. The new session will have telemetry active. This is a one-time setup. All future Gemini CLI sessions will have telemetry enabled automatically. ## What the Config Looks Like CliDeck adds this to your `~/.gemini/settings.json`: ```json theme={null} { "telemetry": { "enabled": true, "target": "local", "otlpEndpoint": "http://localhost:4000", "otlpProtocol": "http", "logPrompts": true } } ``` You can also add this manually if you prefer. ## Session Resume Gemini CLI supports session resume. CliDeck captures the session ID from telemetry and uses `gemini --resume ` to reconnect to previous sessions. ## Disabling Telemetry If you want to stop sending telemetry from Gemini CLI to CliDeck: 1. Open **Settings** > **CLI Agents** > **Gemini CLI** 2. Toggle off **CliDeck integration** CliDeck will remove the `telemetry` section from your Gemini settings file. If Gemini CLI releases a major update that changes its configuration or telemetry format, you may need to update CliDeck. Check for the latest version with `npm update -g clideck`. # OpenCode Source: https://docs.clideck.dev/agents/opencode Using OpenCode with CliDeck — run any local or cloud model [OpenCode](https://github.com/opencode-ai/opencode) is a terminal-based AI coding agent that supports a wide range of models — both local (Ollama, LM Studio) and cloud (OpenAI, Anthropic, Google, etc). This makes it a great choice if you want to use models that aren't available through the other agents. OpenCode uses a **plugin bridge** instead of OTLP telemetry. A small JavaScript plugin runs inside OpenCode and sends real-time events to CliDeck over HTTP. ## Setup Click **OpenCode** in the session launcher. The session starts normally. On first launch, CliDeck shows a setup toast: **"OpenCode — Bridge Plugin"**. Click **Install plugin**. CliDeck automatically copies the bridge plugin to `~/.config/opencode/plugins/clideck-bridge.js`. After installation, click **Restart Session** on the toast. The new session will have the bridge active. This is a one-time setup. The plugin stays in place across OpenCode and CliDeck updates. CliDeck also detects the plugin on startup — if it's already installed, the integration is enabled automatically. You can also install the plugin manually if you prefer: ```bash theme={null} mkdir -p ~/.config/opencode/plugins cp "$(npm root -g)/clideck/opencode-plugin/clideck-bridge.js" ~/.config/opencode/plugins/ ``` ## What the Plugin Does The CliDeck bridge plugin sends events to `http://localhost:4000/opencode-events` when: | Event | What CliDeck Gets | | ---------------------------- | ------------------------------- | | `session.status` (busy/idle) | Working/idle status indicator | | `message.part.updated` | Live message preview in sidebar | | `session.updated` | Session title and ID for resume | | `session.created` | Initial session connection | The plugin doesn't modify OpenCode's behavior or read your prompts. It only observes status changes and output text. ## Session Resume OpenCode supports session resume. CliDeck captures the session ID from plugin events and uses `opencode --session ` to reconnect to previous sessions. Session IDs in OpenCode look like `ses_` followed by alphanumeric characters (e.g., `ses_abc123xyz`). ## How It Differs from OTLP Agents | Aspect | OTLP (Claude/Codex/Gemini) | Plugin (OpenCode) | | ------------------ | ------------------------------ | ------------------------------------- | | Status detection | I/O heuristics (byte rates) | Explicit busy/idle events from plugin | | Message preview | Terminal output buffer parsing | Direct text from plugin events | | Session ID capture | OTLP log attributes | Plugin event payload | | Setup | Env vars or config file | Copy plugin file | The plugin approach gives more accurate status information since OpenCode explicitly reports when it's busy or idle, rather than CliDeck having to guess from output patterns. If OpenCode releases a major update that changes its plugin API, the bridge plugin may need updating. Check for the latest CliDeck version with `npm update -g clideck`. # Agent Overview Source: https://docs.clideck.dev/agents/overview How CliDeck integrates with CLI coding agents CliDeck supports four CLI coding agents out of the box, plus any custom CLI tool you want to add. ## How It Works Each agent runs in its own real terminal (PTY). CliDeck doesn't modify the agent, inject middleware, or intercept your commands. The agent thinks it's running in a normal terminal. The intelligence comes from **telemetry** — lightweight signals the agent already emits (or can be configured to emit). CliDeck receives these signals locally and uses them to show you: | What CliDeck Shows | How It Knows | | --------------------- | --------------------------------------------------------------------------------- | | Working / idle status | Telemetry events (Claude, Codex, Gemini) or I/O heuristics (Shell, custom agents) | | Last message preview | Reads terminal output buffer (output markers per agent) | | Session ID for resume | Captured from telemetry logs or plugin events | | Notifications | Detects working-to-idle transitions | CliDeck never reads what you type or what the agent writes back through telemetry. It sees event timing — not content. ## Supported Agents | Agent | Telemetry Method | Auto-Setup | Resume | | ---------------------------------- | ------------------ | ---------- | -------------------- | | [Claude Code](/agents/claude-code) | Hooks + OTLP | One-click | `claude --resume` | | [Codex](/agents/codex) | OTLP (config file) | One-click | `codex resume` | | [Gemini CLI](/agents/gemini-cli) | OTLP (config file) | One-click | `gemini --resume` | | [OpenCode](/agents/opencode) | Plugin bridge | One-click | `opencode --session` | ## Telemetry Methods **OTLP (OpenTelemetry)** — Claude Code, Codex, and Gemini CLI emit OpenTelemetry logs over HTTP. CliDeck runs a local OTLP receiver at `POST /v1/logs` on port 4000. When you launch an agent from CliDeck, it sets the right environment variables so the agent sends its logs to CliDeck. **Plugin bridge** — OpenCode uses a JavaScript plugin that sends events to CliDeck over HTTP. This provides the same status and preview information as OTLP, just through a different mechanism. ## Working / Idle Detection For **Claude Code, Codex, and Gemini CLI**, status is fully **telemetry-driven**. CliDeck reads the timing of telemetry events to know exactly when the agent starts processing and when it finishes — no guessing from terminal output. | Agent | How status works | | --------------------- | ---------------------------------------------------------------------------------------------------------------- | | Claude Code | `api_request` event → idle (confirmed after 1 second of output silence). Other events → working. | | Codex | `codex.sse_event` → idle. Other events → working. | | Gemini CLI | `api_response` (main role) → idle. `api_request` / `model_routing` → working. | | OpenCode | Explicit `busy`/`idle` status events through its plugin bridge. | | Shell / custom agents | I/O heuristics — byte rates and burst timing. Working means output is flowing; idle means 2+ seconds of silence. | Telemetry-driven status is faster and more reliable than I/O heuristics. It reflects what the agent is actually doing, not just whether text is appearing on screen. ## Adding More Agents You can add any CLI tool as a session type. See [Custom Agents](/agents/custom-agents) for how to configure your own. # Ask Source: https://docs.clideck.dev/features/ask Send a message from one agent session to another and get the response back `clideck ask` lets one agent session send a question to another active session and wait for the answer. The response prints to stdout so the caller can use it immediately. This is designed for agent-to-agent communication — one LLM agent asks another for help without you in the loop. ## Discovery Before asking, discover who's available: ```bash theme={null} clideck agents ``` This lists active sessions in the same project as the caller. Output looks like: ``` Programmer (self, claude-code, idle) id=abc123 Reviewer (peer, claude-code, idle) id=def456 ``` To see sessions across all projects (with their cross-project addresses): ```bash theme={null} clideck agents --all ``` Add `--json` for machine-readable output. ## Same-Project Ask When the caller and target are in the same project, use the session name directly: ```bash theme={null} clideck ask --session "Reviewer" --message "Review my changes and return only findings." ``` Or with positional arguments: ```bash theme={null} clideck ask Reviewer "Review my changes and return only findings." ``` The target is resolved within the caller's project only. If no match is found in the same project, the request fails — it does not search other projects. ## Cross-Project Ask To reach a session in a different project, use the `@project/session` format: ```bash theme={null} clideck ask "@website/Docs Writer" "Check if the docs mention the new CLI flags." --timeout 15m ``` The project name and session name are both resolved case-insensitively. If multiple projects or sessions share a name, use the ID instead. ## Quoting Targets with Spaces If the session name or project name contains spaces, quote the entire target: ```bash theme={null} clideck ask "research manager" "Check this plan." clideck ask "@My Project/Docs Writer" "Update the changelog." ``` When using `--session`, the quotes go around the value: ```bash theme={null} clideck ask --session "research manager" --message "Check this plan." ``` ## Piping Input You can pipe a file or command output as the message via stdin: ```bash theme={null} cat notes.md | clideck ask --session "Docs Writer" --timeout 10m ``` When stdin is piped, the `--message` flag is not needed. ## Busy Target Behavior `clideck ask` only sends to **idle** sessions. If the target is currently working, the request fails immediately with: ``` Target session "Reviewer" is busy. CliDeck ask only sends to idle sessions. Try again later, choose another idle session, or ask the user how to proceed. ``` This is intentional — injecting a message into a working agent would interrupt its current task. Wait for the target to finish, or pick a different session. ## Timeout The target is another LLM agent. It may need minutes to read files, think, use tools, and compose an answer. ```bash theme={null} clideck ask --session "Programmer" --message "Refactor the auth module" --timeout 15m ``` | Flag | Default | Max | | ------------------ | ---------- | ------ | | `--timeout` / `-t` | 10 minutes | 1 hour | Accepts durations like `30s`, `10m`, `1h`. **Set both timeouts.** `clideck ask --timeout` controls how long the ask command waits. But if your caller agent's shell or tool-call timeout is shorter, the shell kills the process first — the target agent may keep working but the caller loses the response. Make sure both timeouts are high enough. While waiting, `clideck ask` prints progress updates to stderr every 15 seconds showing the target's status and elapsed time. Use `--no-progress` to suppress these. ## How It Works 1. The caller agent runs `clideck ask` from its terminal 2. CliDeck resolves the target session (same-project or cross-project) 3. If the target is busy, the request fails immediately 4. CliDeck injects the message into the target's terminal as a bracketed paste, prefixed with `[CliDeck ask from ]` 5. CliDeck waits for the target agent to go from working back to idle 6. The target's response is captured from the transcript and printed to the caller's stdout ## Full CLI Reference ``` clideck ask --session --message [--timeout 10m] clideck ask [--timeout 10m] clideck ask "@project/session" [--timeout 10m] cat file.txt | clideck ask --session [--timeout 10m] ``` | Option | Description | | ----------------- | ----------------------------------------------------------------------- | | `-s`, `--session` | Target session name or ID | | `-m`, `--message` | Message to send (or use stdin) | | `-t`, `--timeout` | Wait time (e.g. `30s`, `10m`, `1h`). Default: `10m` | | `--url` | CliDeck server URL. Default: `CLIDECK_URL` or `http://127.0.0.1:` | | `--no-progress` | Suppress progress updates on stderr | `clideck ask` requires `CLIDECK_SESSION_ID` to be set, which CliDeck sets automatically for sessions launched from the UI. It cannot be used from a terminal outside CliDeck. # Autopilot Source: https://docs.clideck.dev/features/autopilot Automatic multi-agent workflow routing between role-based sessions Autopilot is a project-level workflow router. It watches your agents, waits for them to finish, then forwards one agent's output to the next agent that should see it. It does not do the work itself, and it does not rewrite or summarize the routed content. Think of it as a dispatcher: it reads the state of your project, understands each agent's role, and decides who should act next. ## Why This Architecture Autopilot is a dispatcher, not a critic. It doesn't evaluate quality, rewrite agent output, or inject its own instructions. It makes one small decision per round — who should see this output next — and gets out of the way. This design is intentional: * **Cheap to run** — The router's only job is to pick the next handoff. Its average output is 30–50 tokens per round — a steering decision, not a conversation. Even expensive models cost very little when they only emit a tool call. * **Non-destructive** — You can enable or disable Autopilot at any time. It doesn't own the sessions. Stop it mid-workflow and your agents keep their full context. Start it again and it picks up from the current state. * **You stay in control** — You can type directly into any agent session while Autopilot is running. Your input takes priority. Autopilot waits for all agents to go idle before acting, so it never races you. The agents do the work. Autopilot picks the next handoff. ## Requirements Autopilot works on sessions within a **project** that have **assigned roles**. Both are required: * Sessions must be grouped in the same project * Each session must have a role assigned when created * No two sessions in the same project can share the same role * At least one session with a role must exist in the project ## How It Works The core loop: 1. **Wait for idle** — Autopilot monitors all role-assigned sessions in the project. It acts only when all agents are idle. 2. **Inspect state** — It reads the structured workflow state: which outputs are new, which were already routed, what the last handoff was, and whether progress has stalled. 3. **Consult the router** — An LLM evaluates the current state and each agent's role responsibilities, then calls one of two tools: * `route(from, to)` — Forward one agent's output to another * `notify_user(reason)` — Stop Autopilot and alert the user 4. **Forward output** — The selected agent's output is sent verbatim to the target agent's terminal, wrapped with a small header showing routing context. This cycle repeats until the task is complete, the workflow is blocked, or you stop it manually. ### Routed Output Format When Autopilot routes output from one agent to another, the receiving agent sees: ``` [Autopilot route | output #a1b2c3] [Team: Programmer, Reviewer, Product Manager] [You are: Reviewer] [From: Programmer] [Do not spawn internal agents.] ``` The header tells the receiving agent its role, who sent the output, and the team composition. The original output is never edited or summarized. ### Routing Intelligence Autopilot tracks routing state to avoid useless loops: * **Output identity** — Each output gets a hash ID. Autopilot knows if the same output was already routed to a given agent. * **Handoff history** — A log of all routes is maintained per project. The router sees the last 30 entries. * **Waiting state** — After routing, Autopilot records which role it's waiting on for new output. * **Staleness detection** — If all agents are idle and no new output has appeared since the last route, the state is flagged as stale. The router can use this to decide if the workflow is stuck. The router prefers new output over previously routed output, and uses role responsibilities and restrictions to choose the most appropriate next specialist. ### Role-Aware Routing Autopilot reads each agent's role instructions before every routing decision. It uses the instructions to understand what each agent is responsible for, what kind of output they should receive, and when they should be involved. This means routing adapts to whatever roles you define. For example, say you have a team with a Programmer, a Reviewer, and an Innovation Officer whose role prompt says: "Check every code change for whether it pushes boundaries. If the approach is too conventional, send it back with suggestions for more creative solutions." Autopilot reads that prompt and understands: after the Programmer writes the code and the Reviewer approves it, route it to the Innovation Officer for a creativity check. If the Innovation Officer pushes back, route it back to the Programmer with the feedback. You don't configure this routing order anywhere. Autopilot infers it from the role instructions. The more specific your role prompts are about responsibilities and when an agent should be involved, the better Autopilot routes. ### When It Notifies You Autopilot calls `notify_user` only in specific situations: * **Work is naturally complete** — All agents agree the task is done * **Truly blocked** — Something prevents progress (missing dependency, conflicting requirements, etc.) * **Human input needed** — A decision only a human can make It does not ask for permission to continue, and it does not pause to check in. The expectation is that you can walk away and come back when notified. ## Starting and Stopping Each project header in the sidebar has an **Autopilot** button (visible when the project has role-assigned sessions). * **Click to start** — Autopilot discovers all role-assigned sessions in the project and begins the routing loop * **Click to stop** — Autopilot stops immediately. Active agent sessions are not affected. When Autopilot starts, it seeds its state from the current screen output of any idle agents, so it can make an informed first routing decision without waiting for new work. ## The Project Pill While running, Autopilot appears as a **pill** in the sidebar under its project. The pill shows: * **Status** — Working (spinner) when consulting the router, idle when waiting for agents * **Status text** — Current action, e.g., "Consulting router...", "Waiting on Reviewer", "Programmer -> Reviewer" Click the pill to view the **Autopilot log** — a timestamped feed of everything it did: * Worker discovery ("Started with 3 workers: Programmer, Reviewer, Product Manager") * Routing decisions ("Routed Programmer -> Reviewer") * Status transitions ("Reviewer -> idle") * Notifications ("Notify: All tasks complete, tests passing") When Autopilot finishes via `notify_user`, the pill stays visible with a "Finished" status so you can review the log. It's removed when you start a new Autopilot session or manually stop it. ## Settings Autopilot settings are in the **Plugins** panel under **Autopilot**. | Setting | Description | Default | | ------------- | ------------------------------------------------------- | ---------------- | | **Enabled** | Master switch — disables the Autopilot button when off | On | | **Provider** | LLM provider for the routing decisions | Anthropic | | **Model** | Which model to use (populated dynamically per provider) | claude-haiku-4-5 | | **API Key** | API key for the selected provider | — | | **Debugging** | Save router prompts and responses to disk | Off | ### Supported Providers | Provider | Env Var Fallback | | ---------- | ------------------------------------ | | Anthropic | `ANTHROPIC_API_KEY` | | OpenAI | `OPENAI_API_KEY` | | Google | `GOOGLE_API_KEY` or `GEMINI_API_KEY` | | Groq | `GROQ_API_KEY` | | OpenRouter | `OPENROUTER_API_KEY` | | xAI | `XAI_API_KEY` | | Mistral | `MISTRAL_API_KEY` | | Cerebras | `CEREBRAS_API_KEY` | If the API Key field in settings is empty, Autopilot falls back to the provider's standard environment variable. You only need to set the key in one place. If Autopilot can't find a valid API key, it pauses with a configuration prompt. Fix the key in settings and it resumes automatically. ### Debugging When debugging is enabled, each router consultation is saved to `~/.clideck/autopilot/logs/`. Each file contains: * The system prompt sent to the router * The user message with workflow state and agent outputs * The router's response and tool call Files are named with a sequence number, label, and timestamp for easy sorting. Useful when you want to understand why Autopilot made a specific routing decision. ### Token Usage Autopilot tracks input and output token counts per project. The total is shown in the Autopilot button tooltip ("Autopilot ON — 45,230 tokens") and stored in `~/.clideck/autopilot/usage.json`. ## Data Storage | Path | Purpose | | ---------------------------------------- | -------------------------------------------- | | `~/.clideck/autopilot/` | Autopilot data directory | | `~/.clideck/autopilot/.jsonl` | Routing history (knowledge base) per project | | `~/.clideck/autopilot/usage.json` | Cumulative token usage | | `~/.clideck/autopilot/logs/` | Debug logs (when debugging enabled) | # Notifications Source: https://docs.clideck.dev/features/notifications Get alerted when your agents finish working CliDeck sends browser notifications when an agent transitions from working to idle. This lets you step away from your computer and come back only when something needs your attention. ## How It Works 1. CliDeck tracks each agent's working/idle status (via telemetry events for Claude Code, Codex, and Gemini CLI; via I/O heuristics for Shell and custom agents) 2. When an agent transitions from working to idle, CliDeck confirms the transition 3. If the CliDeck tab is **not in focus**, a browser notification fires 4. If sound is enabled, a notification sound plays (also only when the tab is not in focus) The notification includes: * Session name * Project name (if assigned) * The latest message preview from the agent ## Setting Up Open **Settings** > **Notifications** and check **Notify when agent finishes working**. Click **Enable browser notifications**. Your browser will ask for permission — click **Allow**. Check **Play sound** and pick from 7 built-in notification sounds. Use the preview button to hear each one before choosing. ## Notification Sounds CliDeck includes 7 notification sounds: | Sound | Style | | ------------ | ------------------------------- | | Default Beep | Short, neutral beep | | Soft Beep | Quieter, gentler tone | | Bold Beep | Louder, more attention-grabbing | | Echo Beep | Beep with reverb | | Musical Beep | Melodic tone | | Small Bleep | Quick, subtle bleep | | Space | Sci-fi inspired tone | ## Minimum Working Time To reduce noise, you can set a minimum working time before notifications fire. If an agent works for less than this threshold, no notification is sent. Open **Settings** > **Notifications** and adjust the **Minimum working time** dropdown (5 seconds to 60 seconds). This prevents notifications from firing when an agent does a quick check and immediately goes idle. ## Muting Individual Sessions If a particular session is too noisy, you can mute it without disabling notifications globally: * Right-click the session > **Mute** * Or click the session menu button > **Mute** Muted sessions show a mute icon in the sidebar. They still show status changes visually, just no notifications or sounds. ## When Notifications Don't Fire Notifications only fire when: * The CliDeck browser tab is **not in focus** (if you're already looking at it, you don't need a notification) * The active session is **not the one that just finished** (if you're already watching that session, no notification) * The session is **not muted** * The agent worked for longer than the minimum working time threshold * Browser notification permission is **granted** # Plugins Source: https://docs.clideck.dev/features/plugins Extend CliDeck with custom plugins Plugins extend CliDeck without modifying the core. A plugin can observe terminal output, transform input, react to status changes, create and control sessions, add toolbar buttons, and communicate between backend and frontend. The plugin API is the same one the bundled plugins use — Autopilot, for example, is built entirely on it. ## Bundled Plugins CliDeck ships with three plugins out of the box. They're automatically installed into `~/.clideck/plugins/` on first run. ### Trim Clip A clipboard utility that cleans up copied text. Click the scissors icon in the terminal toolbar to trim trailing whitespace from every line in your clipboard. Useful when copying code from terminal output that has extra spaces. | Setting | Description | Default | | --------------------------- | ------------------------------------------------------ | ------- | | **Enabled** | Show the toolbar button | On | | **Trim leading whitespace** | Also remove leading spaces (off preserves indentation) | Off | ### Autopilot A project-level workflow router that automatically forwards output between role-assigned agent sessions. See the dedicated [Autopilot](/features/autopilot) page for full documentation. | Setting | Description | Default | | ------------- | ---------------------------------------------- | ---------------- | | **Enabled** | Enable the Autopilot button on project headers | On | | **Provider** | LLM provider for routing decisions | Anthropic | | **Model** | Model for routing decisions | claude-haiku-4-5 | | **API Key** | Provider API key (falls back to env var) | — | | **Debugging** | Save router prompts/responses to disk | Off | ### Voice Input Speak to your agents instead of typing. Press a hotkey (default: **F4**) to start recording, press again to stop. Your speech is transcribed and typed into the active terminal session. Two transcription backends are available: | Backend | Description | Requirements | | -------------------- | ------------------------------------ | ---------------------------------- | | **OpenAI** (default) | Uses OpenAI's Whisper API (remote) | OpenAI API key | | **Local** | Runs Whisper via MLX on your machine | macOS with Apple Silicon, Python 3 | | Setting | Description | Default | | --------------------- | ---------------------------------------------------- | ------- | | **Enabled** | Enable voice input | Off | | **ASR Backend** | OpenAI (remote) or Local (MLX) | OpenAI | | **OpenAI API Key** | Required for OpenAI backend | — | | **Language** | Transcription language (or auto-detect) | Auto | | **Record Key** | Hotkey to start/stop recording | F4 | | **Replacements File** | Path to a text replacements file for post-processing | — | The replacements file uses a simple format — one rule per line: ``` wrong phrase => correct phrase another mistake => fix | all ``` The `| all` flag makes the replacement case-insensitive. Voice Input requires microphone access. Your browser will ask for permission the first time you record. ## Installing Custom Plugins Each plugin is a folder inside `~/.clideck/plugins/`. There are two kinds: **Plugin without dependencies** — loaded immediately on startup: ``` ~/.clideck/plugins/my-plugin/ clideck-plugin.json # manifest (optional, recommended) index.js # backend code (required) client.js # frontend code (optional) public/ # static assets (optional) ``` **Plugin with npm dependencies** — requires a one-time install: ``` ~/.clideck/plugins/my-plugin/ clideck-plugin.json # manifest with "install": "npm" package.json # npm dependencies index.js # backend code (required) client.js # frontend code (optional) ``` Plugins without dependencies are loaded on restart. Plugins with dependencies appear in the Plugins panel with an **Install** button — click it to run `npm install` in the plugin directory, then the plugin loads. The `install` field currently only supports `"npm"`. If your plugin needs non-Node dependencies (Python, Rust, etc.), use `scripts.postinstall` in your `package.json` — npm runs it automatically during install. Plugins run with full Node.js access — same trust model as npm packages. Only install plugins you trust or have reviewed. ## Managing Plugins Plugins appear in the **Plugins panel** (circuit icon in the sidebar rail). Each plugin shows its icon, name, and settings. If a plugin has settings, they show up as controls (toggles, dropdowns, text fields, number inputs) that you can change on the fly. Install state is tracked in CliDeck's config. If a plugin's `node_modules` is deleted manually, CliDeck detects this on next startup and resets the install state — you'll see the Install button again. When a bundled plugin is updated to a new version, its install state is also cleared so new dependencies get picked up. To remove a custom plugin, click **Delete** in the plugin's settings panel, or delete its folder from `~/.clideck/plugins/` and restart CliDeck. ## Creating a Plugin ### The Manifest A `clideck-plugin.json` manifest lets you define your plugin's identity and settings. If omitted, the folder name is used as the ID and name. ```json theme={null} { "id": "my-plugin", "name": "My Plugin", "version": "1.0.0", "icon": "...", "install": "npm", "settings": [ { "key": "enabled", "label": "Enable feature", "type": "toggle", "default": true }, { "key": "mode", "label": "Mode", "type": "select", "options": ["fast", "slow"], "default": "fast" }, { "key": "limit", "label": "Max items", "type": "number", "min": 1, "max": 100, "default": 10 }, { "key": "apiKey", "label": "API Key", "type": "text", "default": "" } ] } ``` | Field | Required | Description | | ---------- | -------- | ---------------------------------------------------------------------------- | | `id` | No | Unique plugin identifier (defaults to folder name) | | `name` | No | Display name in the UI (defaults to folder name) | | `version` | No | Version string (defaults to `0.0.0`) | | `icon` | No | Inline SVG string for the Plugins panel. If omitted, a default icon is shown | | `install` | No | Set to `"npm"` if the plugin has a `package.json` with dependencies | | `settings` | No | Array of user-configurable settings | ### Setting Types | Type | Control | Extra Options | | ---------------- | ----------------------------- | --------------------------------------------------------- | | `toggle` | On/off switch | — | | `select` | Dropdown | `options`: array of strings or `{ value, label }` objects | | `dynamic-select` | Dropdown with runtime options | Options set via `api.setSettingOptions(key, options)` | | `number` | Number input | `min`, `max` (optional) | | `text` | Text field | — | All setting types support an optional `description` field for hint text below the control. Settings are validated against the manifest — type, allowed options, and min/max are enforced automatically. ### Backend API (index.js) The backend entry point exports an `init` function that receives the plugin API: ```javascript theme={null} module.exports = { init(api) { // Your plugin code here } }; ``` #### Session Hooks ```javascript theme={null} // Transform input before it reaches the terminal // Return a string to replace the input, or nothing to leave it unchanged api.onSessionInput((sessionId, data) => { return data; }); // Observe terminal output (read-only) api.onSessionOutput((sessionId, data) => { // data is the raw terminal output }); // React to working/idle transitions api.onStatusChange((sessionId, working, source) => { // working: true = agent started working, false = agent went idle // source: 'telemetry', 'client', 'esc', 'menu', etc. }); // React to interactive menu detection (choice menus in agent output) api.onMenuDetected((sessionId, choices) => { // choices: [{ value, label, selected }] }); // Receive clean, complete transcript entries (user inputs and agent outputs) api.onTranscriptEntry((sessionId, role, text) => { // role: 'user' (complete input line) or 'agent' (processed output block) // text: clean text with ANSI codes stripped, ready to use }); ``` Input hooks run as a chain — each hook's return value becomes the input for the next hook. This lets multiple plugins transform input in sequence. `onSessionInput` and `onSessionOutput` receive raw terminal data (keystrokes, escape sequences, ANSI codes). If you need clean, human-readable text, use `onTranscriptEntry` instead — it delivers complete lines with all terminal noise stripped out. #### Session Info ```javascript theme={null} api.getSessions(); // [{ id, name, cwd, commandId, presetId, themeId, projectId, roleName, working }] api.getSession(id); // single session object, or null ``` #### Frontend Messaging Backend and frontend communicate through namespaced messages: ```javascript theme={null} // Send a message to the frontend api.sendToFrontend('my-event', { key: 'value' }); // Receive a message from the frontend api.onFrontendMessage('my-action', (msg) => { // handle message }); ``` Messages are automatically namespaced as `plugin..` — no collision between plugins. #### Session Control ```javascript theme={null} // Write data to a session's terminal (as if the user typed it) api.inputToSession(id, data); // Create a new session programmatically const sessionId = api.createSession({ presetId: 'claude-code', // or commandId name: 'My Session', cwd: '/path/to/project', projectId: 'uuid', // optional roleName: 'Reviewer', // optional ephemeral: true, // optional — won't persist for resume }); // Close a session api.closeSession(id); // Enable/disable auto-approval of interactive menus for a session api.setAutoApproveMenu(id, true); ``` #### Config Access ```javascript theme={null} api.getRoles(); // all defined roles (deep copy) api.getProjects(); // all defined projects (deep copy) ``` #### Transcript and Screen ```javascript theme={null} // Get the last N transcript turns (user/agent alternating entries) api.getTranscript(id, 20); // Get structured screen turns parsed from the terminal buffer api.getScreenTurns(id, 'claude-code', { raw: false }); // Get the raw clean screen content api.getScreen(id); // Detect interactive menus from raw screen lines api.detectMenu(lines, 'claude-code'); ``` #### Toolbar and Project Actions ```javascript theme={null} api.addToolbarAction({ id: 'do-thing', title: 'Do Thing', icon: '...', // inline SVG, 16x16 }); // Add a button to project headers in the sidebar api.addProjectAction({ id: 'run-workflow', title: 'Run Workflow', icon: '...', }); ``` #### Session Pills Session pills are sidebar entries that represent background tasks (like Autopilot). They appear under their project, similar to sessions. ```javascript theme={null} // Create a pill api.addSessionPill({ id: 'my-task', title: 'My Task', projectId: 'uuid', icon: '' }); // Update pill state api.updateSessionPill('my-task', { working: true, statusText: 'Processing...', title: 'Updated Title', // optional projectId: 'new-uuid', // optional }); // Append a timestamped log entry (viewable by clicking the pill) api.appendPillLog('my-task', 'Step 1 complete'); // Remove the pill from the sidebar api.removeSessionPill('my-task'); ``` #### Settings ```javascript theme={null} api.getSetting('mode'); // current value for a single key api.getSettings(); // all settings as { key: value } // Update a setting programmatically (validated against manifest) api.setSetting('mode', 'fast'); // Set dropdown options at runtime for dynamic-select settings api.setSettingOptions('model', [ { value: 'gpt-4', label: 'GPT-4 ($30/M input)' }, { value: 'gpt-3.5', label: 'GPT-3.5 ($0.50/M input)' }, ]); api.onSettingsChange((key, value) => { // called when the user changes a setting in the UI }); ``` #### Utilities ```javascript theme={null} api.log('message'); // log with [plugin:my-plugin] prefix api.pluginId; // this plugin's ID api.pluginDir; // absolute path to this plugin's folder api.version; // API version (currently 1) api.onShutdown(() => { // cleanup when CliDeck shuts down }); // Resolve a package — checks plugin-local node_modules first, then app-level const piAi = api.resolve('@mariozechner/pi-ai'); ``` ### Frontend API (client.js) The optional frontend entry point is an ES module: ```javascript theme={null} export function init(api) { // Send a message to the backend api.send('my-action', { key: 'value' }); // Receive a message from the backend api.onMessage('my-event', (msg) => { // msg is the full message object including type }); // Add a button to the terminal toolbar api.addToolbarButton({ title: 'Do Thing', icon: '...', onClick: () => { /* handle click */ } }); // Session helpers api.getActiveSessionId(); // current active session ID api.writeToSession(id, text); // write text to a session's terminal // Toast notifications api.toast('Something happened', { type: 'success' }); } ``` #### Toast Notifications Show toast notifications from your plugin. Returns an object with a `dismiss()` method. ```javascript theme={null} api.toast(message, opts) ``` | Option | Type | Default | Description | | ---------- | ------- | -------- | ------------------------------------------------------------------ | | `type` | string | `'info'` | `'info'`, `'success'`, `'warn'`, or `'error'` | | `duration` | number | `3000` | Auto-dismiss in ms. `0` = persistent (manual dismiss only) | | `id` | string | — | Dedupe key. A new toast with the same id replaces the previous one | | `html` | boolean | `false` | If true, message is rendered as HTML | ```javascript theme={null} // Transient success api.toast('Model loaded', { type: 'success' }); // Persistent progress (dismiss when done) const t = api.toast('Installing dependencies...', { type: 'info', duration: 0, id: 'setup' }); // later... t.dismiss(); // Replace previous toast with same id api.toast('Dependencies installed', { type: 'success', id: 'setup' }); ``` Multiple toasts from different plugins stack automatically without overlapping. ### Static Assets Files in the `public/` subdirectory are served at `/plugins//`. Use this for images, CSS, or additional scripts your plugin needs. ## Example: Simple Logger Plugin A minimal plugin that logs when agents start and stop working: ``` ~/.clideck/plugins/work-logger/ clideck-plugin.json index.js ``` **clideck-plugin.json:** ```json theme={null} { "id": "work-logger", "name": "Work Logger", "version": "1.0.0" } ``` **index.js:** ```javascript theme={null} module.exports = { init(api) { api.onStatusChange((sessionId, working) => { const session = api.getSession(sessionId); const name = session?.name || sessionId; api.log(`${name} is now ${working ? 'working' : 'idle'}`); }); api.onShutdown(() => { api.log('shutting down'); }); } }; ``` ## Error Handling Plugin errors are caught and logged — one plugin can't crash CliDeck or affect other plugins. If your plugin throws during `init`, it's unloaded and its hooks are removed. # Projects Source: https://docs.clideck.dev/features/projects Group your sessions by project with drag-and-drop organization Projects are a lightweight way to organize sessions. If you're working on multiple codebases at once, projects keep things tidy. ## Creating a Project 1. Click the **New Project** button in the sidebar 2. Enter a project name 3. Choose a folder path (the default working directory for sessions in this project) 4. Pick an accent color (8 colors available) Sessions created within a project automatically use the project's folder path. ## Organizing Sessions ### Drag and Drop Drag any session in the sidebar to a project header to move it into that project. Drag it to the area above all projects to remove it from a project. ### Context Menu Right-click a session and use **Move to project** to assign it to any project, or remove it from its current project. ### Session Launcher When creating a new session, you can pick a project from the dropdown in the launcher. The working directory auto-fills from the project path. ## Project Groups Sessions are visually grouped under their project header in the sidebar. Each project header shows: * Project name (with accent color) * Session count * Collapse/expand toggle * Menu button Click a project header to collapse or expand it. Collapsed projects still show their session count. ## Managing Projects Right-click a project header (or click its menu button) to: * **Change color** — Pick from 8 accent colors * **Rename** — Double-click the project name to edit * **Delete** — Removes the project grouping. You'll be asked to confirm if the project has active sessions (sessions are closed, not just ungrouped) ## Resumable Sessions When CliDeck restarts, previously saved sessions appear grouped under their original project in the **Previous Sessions** section. # Prompt Library Source: https://docs.clideck.dev/features/prompts Save reusable prompts and paste them into any terminal session The Prompt Library stores prompts you use often. Type `//` in any terminal to pick from your list and paste it in. ## Creating a Prompt Open the **Prompts** panel from the sidebar rail. Click the **+** button at the top. Each prompt has two fields: * **Name** — A short label for the prompt (up to 60 characters). This is what you'll search for. * **Text** — The full prompt text that gets pasted into the terminal. Click **Add** to save, or press **Ctrl+Enter** / **Cmd+Enter** from the text field. ## Using a Prompt There are two ways to paste a prompt into a terminal session. ### Click to paste Click any prompt in the Prompts panel. The text is sent directly to the active terminal session, and the terminal regains focus. ### Autocomplete with // Type `//` in any terminal to open the autocomplete dropdown. 1. Type `//` — the first `/` goes to the terminal, the second activates autocomplete and erases the first 2. Start typing to filter by name or prompt text 3. Use **Arrow keys** to navigate the list 4. Press **Enter** or **Tab** to paste the selected prompt 5. Press **Escape** to cancel The autocomplete searches both prompt names and prompt text, and highlights matching characters in the results. The `//` trigger only activates when you have at least one prompt saved. If your library is empty, `/` characters pass through to the terminal normally. ## Editing and Deleting Hover over any prompt in the list to reveal the **edit** and **delete** buttons. * **Edit** — Opens the editor with the existing name and text pre-filled. Click **Save** to update. * **Delete** — Removes the prompt immediately. There is no confirmation dialog. ## Starter Prompts New CliDeck installations include three demo prompts: **Update documentation**, **Investigate codebase**, and **Reviewer findings**. These are fully editable — modify them, delete them, or add your own. Starter prompts are only seeded on first run when no config exists. Existing users keep their current prompt library untouched. ## Storage Prompts are stored in your CliDeck configuration file (`~/.clideck/config.json`) under the `prompts` array. They sync across all connected browser tabs automatically. # Search & Filter Source: https://docs.clideck.dev/features/search Find sessions quickly with search and tab filtering Two ways to find sessions in the sidebar: text search and tab filtering. ## Search The search bar at the top of the sidebar filters sessions as you type. It matches against: * **Session name** — The name you gave the session (or the auto-generated one) * **Transcript content** — Everything the agent has output during the session This means you can search for a function name, error message, or file path and find the session where you worked on it — even if you didn't name the session after it. Search updates instantly as you type. Clear the search to see all sessions again. ## Tab Filtering Below the search bar, two tabs filter the session list: * **All** — Shows every session * **Unread** — Shows only sessions with new output you haven't looked at yet. A count badge shows how many unread sessions there are. ## How Unread Works A session is marked as **unread** (blue dot in the sidebar) when it produces new output while you're looking at a different session. Clicking on the session marks it as read. This helps when you're running multiple agents — you can quickly see which ones have produced new output since you last checked. ## Transcript Store Behind the scenes, CliDeck records a searchable transcript for every session: * **User input** is captured keystroke-by-keystroke and recorded when you press Enter * **Agent output** is batched (300ms debounce), stripped of ANSI formatting codes, and stored as plain text * Transcripts are saved as JSONL files in `~/.clideck/transcripts/` The transcript powers sidebar search. It's plain text only — no terminal formatting, colors, or control sequences. This makes search fast and results relevant. Transcripts are stored locally on your machine. They're used only for search functionality within CliDeck. # Sessions Source: https://docs.clideck.dev/features/sessions Create, manage, resume, and organize your terminal sessions Sessions are the core of CliDeck. Each session is a real terminal running a CLI agent or shell command. ## Creating a Session Click the **+** button in the sidebar to open the session launcher. You'll see: * **Agent buttons** — One for each enabled agent (Claude Code, Codex, Gemini CLI, OpenCode), ordered by most recently used * **Shell** — A plain terminal, always listed last * **Session name** — Optional. CliDeck generates a random name if you leave it blank * **Working directory** — Defaults to your configured default path. Click **Browse** to pick a different folder * **Project** — Optionally assign the session to a project right away * **Role** — Optionally assign a role to the session. When selected, the session name auto-fills with the role name. The role's instructions are injected into the agent after it starts. Click an agent button to launch the session immediately. ## The Session Sidebar Each session appears in the sidebar with: | Element | What It Shows | | ---------------- | ----------------------------------------------- | | Agent icon | Which agent is running | | Session name | Editable — double-click to rename | | Status indicator | Green bounce = working, "zzZ" = idle | | Preview text | Latest meaningful output line from the agent | | Time | How long since last activity | | Unread dot | Blue dot if there's new output you haven't seen | Click a session to switch to it. The terminal appears in the main area with full keyboard focus. ## Renaming Sessions Double-click the session name in the sidebar to edit it. Press **Enter** to save or **Escape** to cancel. ## Session Resume When CliDeck shuts down (or you close the app), sessions from agents that support resume are automatically saved to `sessions.json`. Next time you start CliDeck, these appear in a **Previous Sessions** section at the bottom of the sidebar. Click the resume button on any saved session to pick up where you left off. CliDeck uses the agent's resume command (e.g., `claude --resume `) to reconnect. Resume requires: * The agent supports resume (Claude Code, Codex, Gemini CLI, OpenCode all do) * A session ID was captured during the original session (via telemetry or plugin) If CliDeck is killed forcefully (e.g., `kill -9`), sessions may not be saved. Normal shutdown (Ctrl+C or closing the terminal) saves sessions correctly. ## Restarting Sessions Sometimes you need to restart a session — for example, after changing the terminal theme polarity (switching from a dark theme to a light theme). CliDeck shows a restart banner when this is needed. A restart kills the current terminal process and launches a new one. If the agent supports resume and has a session ID, the restart uses the resume command so you don't lose context. ## Muting Sessions Right-click a session (or click the menu button) and select **Mute** to disable notifications for that session. A muted session still shows status changes in the sidebar, but won't trigger browser notifications or sounds. ## Clearing the Terminal To clear a terminal's scrollback buffer (visual clear, like macOS Terminal's Cmd+K): | Platform | Shortcut | | --------------- | ---------------- | | macOS | **Cmd+K** | | Windows / Linux | **Ctrl+Shift+K** | This works from anywhere in the app — you don't need to focus the terminal first. It clears the active session's scrollback. On macOS, Cmd and Ctrl are separate modifiers. CliDeck only captures Cmd+K — it does not interfere with Ctrl+K (kill-line) or other Ctrl keybindings that CLI agents use. ## Closing Sessions Right-click a session and select **Delete**, or use the session context menu. If close confirmation is enabled in settings, you'll see a confirmation dialog before the session is closed. Closing a session kills the terminal process. If the agent supports resume, the session is saved for later resume. # Telemetry & Privacy Source: https://docs.clideck.dev/features/telemetry How CliDeck uses telemetry, what data is collected, and where it goes Telemetry is how CliDeck detects agent status. This page explains what data is involved and where it goes. ## What Telemetry Means in CliDeck When we say "telemetry," we mean the **signals that CLI agents emit about their own activity**. These are OpenTelemetry (OTLP) log messages that agents like Claude Code, Codex, and Gemini CLI already support. CliDeck runs a local OTLP receiver on port 4000 and configures the agents to send their logs there. ## Where Does the Data Go? **Nowhere. It stays on your machine.** The telemetry flow is: ``` CLI Agent → localhost:4000 → CliDeck → your browser ``` There is no cloud component. CliDeck doesn't have a backend service, doesn't phone home, and doesn't collect analytics. Everything runs locally. ## What Data Does CliDeck Receive? From OTLP logs, CliDeck extracts: | Data | Used For | | --------------------- | ------------------------------------------------------------------ | | Session ID | Enabling session resume | | Event type and timing | Working/idle status detection (for Claude Code, Codex, Gemini CLI) | CliDeck does **not** read: * Your prompts or what you type to the agent * The agent's full responses or generated code * File contents or repository data * API keys or credentials ## What About Working/Idle Detection? For **Claude Code, Codex, and Gemini CLI**, working/idle status is driven by **telemetry event timing**. CliDeck sees *when* events happen (e.g., an API request started, a response finished) — not *what* was requested or returned. This gives accurate, real-time status without reading any content. For **Shell sessions and custom agents** (which don't emit telemetry), CliDeck falls back to I/O heuristics — byte rates and burst timing. If output is flowing, the session is working. After 2 seconds of silence, it's idle. ## What About the Message Preview? The sidebar preview (last message from the agent) comes from reading the terminal's output buffer — the same text you see in the terminal. This is local to your browser and is not sent anywhere. ## Can I Disable Telemetry? Yes. Per agent: 1. Open **Settings** > **CLI Agents** 2. Select the agent 3. Toggle off **CliDeck integration** Without telemetry, CliDeck still works as a terminal multiplexer. You lose: * Accurate working/idle status for Claude Code, Codex, and Gemini CLI * Session resume (no session ID capture) * Telemetry setup detection CliDeck falls back to I/O heuristics for status detection, which is less precise than telemetry. ## Auto-Setup: What Changes on My System? When you click "Configure automatically" for an agent, CliDeck writes to the agent's config file: | Agent | File Modified | What's Added | | ----------- | ----------------------------- | ------------------------------------------------ | | Codex | `~/.codex/config.toml` | `[otel]` section with OTLP endpoint | | Gemini CLI | `~/.gemini/settings.json` | `telemetry` object with local endpoint | | Claude Code | `~/.claude/settings.json` | Lifecycle hooks for start/stop/idle/menu signals | | OpenCode | `~/.config/opencode/plugins/` | Bridge plugin auto-installed (one-click) | Disabling the integration in CliDeck settings removes these additions. CliDeck also detects existing configurations on startup — if you've already configured an agent, the integration is enabled automatically without repeating setup. # Themes Source: https://docs.clideck.dev/features/themes Customize terminal colors with 15 built-in themes and custom theme support CliDeck ships with 15 terminal color themes and supports custom themes. ## Built-in Themes ### Dark Themes | Theme | Style | | ---------------- | -------------------- | | Midnight | Slate blue (default) | | Dracula | Classic purple | | Nord | Cool blue-gray | | Catppuccin Mocha | Warm lavender | | Solarized Dark | Solarized blue | | One Dark | Atom-inspired | | Monokai | Sublime-inspired | | Tokyo Night | Muted blue | | GitHub Dark | GitHub's dark theme | | Gruvbox Dark | Warm retro | ### Light Themes | Theme | Style | | ---------------- | ---------------- | | GitHub Light | Clean and bright | | Solarized Light | Easy on the eyes | | Catppuccin Latte | Warm pastels | | One Light | Atom light | | Rose Pine Dawn | Soft and warm | ## Changing the Default Theme 1. Open **Settings** > **Appearance** 2. Select a theme from the dropdown — each shows a mini color preview 3. A larger preview panel below shows sample code in the selected theme The default theme applies to all new sessions. ## Per-Session Themes Each session can have its own theme. Right-click a session > **Change Theme** to pick a different one. ## Light / Dark Mode The sun/moon toggle in the left navigation rail switches between light and dark mode. When you switch: * The CliDeck UI switches color scheme * Sessions using a "default" theme (the mode's default) automatically switch to the new mode's default theme * Sessions with a specific theme keep their theme If switching modes would change a session's theme polarity (e.g., dark session in light mode), CliDeck shows a restart banner — the terminal needs to restart so the agent sees the correct color environment. ## Custom Themes Create a `custom-themes.json` file in `~/.clideck/` to add your own themes: ```json theme={null} [ { "id": "my-theme", "name": "My Custom Theme", "accent": "#ff6b6b", "theme": { "background": "#1a1b26", "foreground": "#c0caf5", "cursor": "#c0caf5", "selectionBackground": "#33467c", "black": "#15161e", "red": "#f7768e", "green": "#9ece6a", "yellow": "#e0af68", "blue": "#7aa2f7", "magenta": "#bb9af7", "cyan": "#7dcfff", "white": "#a9b1d6", "brightBlack": "#414868", "brightRed": "#f7768e", "brightGreen": "#9ece6a", "brightYellow": "#e0af68", "brightBlue": "#7aa2f7", "brightMagenta": "#bb9af7", "brightCyan": "#7dcfff", "brightWhite": "#c0caf5" } } ] ``` The theme object follows the [xterm.js ITheme](https://xtermjs.org/docs/api/terminal/interfaces/itheme/) format. Custom themes appear alongside built-in themes in all theme pickers. # CliDeck Source: https://docs.clideck.dev/index One screen for all your AI coding agents CliDeck is a local terminal dashboard for running multiple CLI coding agents from one browser tab. It's a coordination layer over your existing tools, not a replacement. You keep using Claude Code, Codex, Gemini CLI, and OpenCode exactly as you do today. CliDeck wraps each agent in its own terminal panel and adds: live status, message previews, notifications, session resume, agent-to-agent communication, project grouping, and multi-agent workflow routing. ## Why CliDeck You run multiple AI agents in separate terminals. You lose track of which one is working, which one finished, and what it said. CliDeck puts them all in one place and shows you what's happening. * **Status at a glance** — Green dot means working, "zzZ" means idle. * **Live previews** — Latest message from each agent in the sidebar. * **Notifications** — Browser notification (with optional sound) when an agent finishes. Walk away and come back when something needs your attention. * **Session resume** — Shut down CliDeck, come back later, and resume your agent sessions right where you left off. * **Mobile remote** — Check on your agents from your phone. QR scan to pair, see who's working, send messages, answer menus. E2E encrypted. * **Agent-to-agent ask** — One agent can ask another agent a question and get the answer back, without you in the loop. Same-project or cross-project. The agents discover each other, communicate directly, and keep working while you're away. * **Autopilot** — Project-level workflow routing. Watches your role-assigned agents, waits for idle, forwards output to the next specialist. 30–50 tokens per routing decision. * **Zero interference** — CliDeck doesn't sit between you and the agent. The terminal is a real terminal. Your keystrokes go directly to the agent, and the agent's output comes directly to you. * **Plugins** — Server + client API with hooks for input, output, status, transcript, and menus. Ships with Trim Clip, Voice Input, and Autopilot. Same API the bundled plugins use. ## Supported Agents CliDeck works out of the box with four CLI agents: Anthropic's CLI agent. Telemetry works automatically — no setup needed. OpenAI's CLI agent. One-click telemetry setup from the CliDeck UI. Google's CLI agent. One-click telemetry setup from the CliDeck UI. Run any model (local or cloud) through OpenCode's TUI. Uses a plugin bridge for real-time status. You can also add any CLI tool as a custom agent or a plain shell session. ## How It Works CliDeck runs a local Node.js server. Each agent session gets a real PTY (pseudo-terminal), rendered in the browser via xterm.js. The agent doesn't know CliDeck exists — it thinks it's in a normal terminal. Status detection works through **telemetry**. Each supported agent emits OpenTelemetry logs that CliDeck receives on localhost. This is how it knows when an agent is working, idle, or waiting for input — without parsing terminal output or intercepting commands. Autopilot routes existing agent output between agents verbatim — it chooses the next handoff, but never rewrites or summarizes the content. All data stays on your machine. Telemetry flows from the agent to CliDeck over localhost. Autopilot's LLM calls go directly to whichever provider you configure. CliDeck has no servers. ## Quick Start Install and run: ```bash theme={null} npm install -g clideck clideck ``` Then open [http://localhost:4000](http://localhost:4000) in your browser. Detailed installation instructions and first session walkthrough. # Mobile Remote Source: https://docs.clideck.dev/mobile Check on your agents from your phone — pair with a QR scan, no account needed Start a task on your computer, walk away, and check on your agents from your phone. See who's working, who's idle, who needs input. Send messages, answer questions, resume sessions — all from a chat-style interface on your phone. No account, no app install. Scan a QR code and you're connected. End-to-end encrypted — the relay server never sees your code, prompts, or output. ## How It Works Your phone connects to your desktop CliDeck through a lightweight relay: ``` Phone ←→ Relay (Cloudflare) ←→ Desktop CliDeck (encrypted, can't read anything) ``` 1. **Your desktop** runs CliDeck as usual with your agent sessions 2. **The relay** forwards encrypted messages between your phone and desktop — it never decrypts them 3. **Your phone** opens a web app that shows your sessions in a chat-like interface The relay is a Cloudflare Worker that passes encrypted blobs between two WebSocket connections. It doesn't store anything. When you disconnect, the room is gone. ## Security Mobile Remote uses **end-to-end encryption (E2E)**. Here's what that means in practice: | What | Who can see it | | ------------------------ | ------------------------------------------------------ | | Your prompts and code | Only your phone and your desktop | | Agent responses | Only your phone and your desktop | | Session names and status | Only your phone and your desktop | | Anything at all | **Not the relay. Not CliDeck's servers. Nobody else.** | **How the encryption works:** * When you pair, your desktop and phone each generate a cryptographic key pair (ECDH P-256) * They exchange public keys through the relay to derive a shared secret * All messages after that are encrypted with **AES-256-GCM** — the same standard used by Signal and WhatsApp * The relay only sees encrypted blobs. It cannot decrypt them. Even if someone intercepted the traffic, they couldn't read it The pairing URL (in the QR code) contains your desktop's public key in the URL fragment — the part after `#` that browsers never send to the server. The relay never sees it. CliDeck is a local tool. Mobile Remote doesn't change that. Your code, prompts, and agent output stay between your devices. The relay is just a dumb pipe. ## Getting Started Mobile Remote is built into CliDeck. No separate app to install. Mobile Remote shows your existing sessions — it doesn't create new ones. Launch one or more agent sessions in CliDeck first. In the CliDeck sidebar, click the **phone icon** in the navigation rail. A modal opens. The first time you use Mobile Remote, CliDeck installs the `clideck-remote` package automatically. Click **Add to CliDeck** and wait a few seconds. A QR code appears. Scan it with your phone's camera. A web app opens in your phone's browser — no app store download needed. Your phone shows all your active sessions. Tap one to see the conversation and start interacting. You can also copy the pairing link and open it manually on any device with a browser. ## What You Can Do From Your Phone Once paired, your phone shows a session list grouped by project — similar to a chat app. ### View sessions and status Each session shows its name, agent icon, last message preview, and a live working/idle indicator. You can see at a glance which agents are done and which are still thinking. ### Send messages Tap a session to open it. Type a message and hit send — it goes straight to the agent's terminal, as if you typed it on your keyboard. ### Answer agent questions When an agent presents a choice menu (like "Yes / No / Yes to all"), the menu appears as tappable buttons on your phone. No need to type — just tap your choice. ### Resume previous sessions Saved sessions from previous CliDeck runs appear in a separate section. Tap to resume them. ### Close sessions Swipe or use the session menu to close a session from your phone. ## What You Can't Do (Yet) * **Create new sessions** — You can only interact with sessions that already exist on your desktop. Start sessions from CliDeck on your computer first. * **Multiple phones** — One phone connection at a time per CliDeck instance. ## Desktop Lock Screen While your phone is connected, CliDeck shows a lock screen overlay on your desktop. This blurs the terminal content and blocks keyboard input — so if you're away from your desk, nobody can see your sessions or type into them. The lock screen shows: * Connection time * Number of active sessions * A **Disconnect** button to end the session When your phone disconnects (close the browser tab or navigate away), the lock screen lifts automatically and your desktop returns to normal. ## Free Tier Mobile Remote is free with one limit: **one active session at a time**. If you tap a different session while one is open, your current session closes first. A confirmation prompt lets you know before switching. You can check "Don't show again" to switch silently. ## Disconnecting To end a mobile session: * **From your phone** — Close the browser tab * **From your desktop** — Click **Disconnect** on the lock screen, or click the mobile icon in the sidebar and disconnect from the modal Once disconnected, the relay room is destroyed. Your pairing QR code is single-use — pair again next time with a fresh QR code. ## Troubleshooting ### QR code not appearing * Make sure `clideck-remote` installed successfully. Check the mobile icon modal for error messages. * Try clicking the mobile icon again to retry pairing. ### Phone can't connect * Make sure your phone has internet access. * The QR code is single-use. If you've already scanned it once and disconnected, click the mobile icon to generate a fresh one. ### No sessions showing on phone * Mobile Remote only shows sessions that are already running on your desktop. Create at least one session in CliDeck first. * If you just started CliDeck, wait for the agent to initialize before pairing. ### Status not updating on phone * Make sure telemetry is configured for your agents. Without telemetry, CliDeck can't detect working/idle status — and that means your phone can't show it either. # Quick Start Source: https://docs.clideck.dev/quickstart Install CliDeck and launch your first agent session in under a minute ## Install CliDeck works on **macOS** and **Windows**. You need [Node.js](https://nodejs.org/) installed. ```bash theme={null} npm install -g clideck ``` Then run it with: ```bash theme={null} clideck ``` Or run directly without installing: ```bash theme={null} npx clideck ``` Open [http://localhost:4000](http://localhost:4000) in your browser. That's it — you're in. ### Access from other devices on your network By default, CliDeck binds to `127.0.0.1` (localhost only). To access it from another device on your LAN or over a VPN like Wireguard: ```bash theme={null} clideck --host 0.0.0.0 ``` You can also bind to a specific interface: ```bash theme={null} clideck --host 192.168.1.50 ``` Binding to `0.0.0.0` exposes CliDeck to your entire network. Only use this on trusted networks. ## Your First Session In the sidebar, click the **+** button to open the session launcher. You'll see buttons for each installed agent (Claude Code, Codex, Gemini CLI, OpenCode) plus a Shell option. You can also select a **project** and a **role** before launching. Click an agent button to start. A new terminal session opens. Use the agent exactly as you normally would — type prompts, run commands, everything works the same. The sidebar now shows your session with a live status indicator and message preview. Launch a few more sessions — you'll see all of them updating at once. New installs ship with three example roles (Programmer, Reviewer, Product Manager) and three example prompts. These are just starting points — edit or delete them as you see fit. ## Set Up Telemetry Telemetry is how CliDeck knows when agents are working, idle, or finished. Without it, you get a terminal multiplexer but no status detection. The first time you launch a Claude Code session, CliDeck shows a setup toast. Click **Patch Claude** and CliDeck adds lifecycle hooks to `~/.claude/settings.json`. Claude will ask for one-time approval on next launch. After that, status detection works automatically. The first time you launch a Codex session, CliDeck shows a setup toast at the top of the terminal. Click **Configure automatically** and CliDeck writes the necessary config to `~/.codex/config.toml`. Restart the session when prompted. Same as Codex — click **Configure automatically** on the setup toast. CliDeck writes the config to `~/.gemini/settings.json`. Restart the session when prompted. OpenCode uses a plugin bridge instead of OTLP telemetry. The first time you launch an OpenCode session, CliDeck shows a setup toast. Click **Install plugin** and CliDeck copies the bridge plugin to `~/.config/opencode/plugins/` automatically. Restart the session when prompted. ## What You'll See Once telemetry is connected, the sidebar shows: * **Green bouncing dot** — The agent is actively working (generating code, running tools) * **"zzZ" indicator** — The agent is idle, waiting for your input * **Preview text** — The last meaningful line the agent output, right in the sidebar * **Unread dot** — New output you haven't looked at yet ## Next Steps Check on your agents from your phone with a QR scan. Detailed setup for each supported agent. Resume, restart, rename, and organize your sessions. Get notified when agents finish working. Let agents ask each other questions and get answers back. Automatic multi-agent workflow routing. # Architecture Source: https://docs.clideck.dev/reference/architecture How CliDeck works under the hood CliDeck is a local Node.js application with a browser-based frontend. This page explains the key architectural decisions for anyone who wants to understand what's happening behind the scenes. ## System Overview ``` ┌─────────────────────────────────────────────────┐ │ Browser │ │ ┌─────────────┐ ┌──────────┐ ┌────────────┐ │ │ │ Sidebar │ │ Terminal │ │ Settings │ │ │ │ (sessions, │ │ (xterm.js)│ │ Panel │ │ │ │ search) │ │ │ │ │ │ │ └──────┬───────┘ └─────┬────┘ └──────┬──────┘ │ │ └────────────┬───┘──────────────┘ │ │ │ WebSocket │ └──────────────────────┼─────────────────────────────┘ │ ┌──────────────────────┼─────────────────────────────┐ │ Node.js Server (:4000) │ │ │ │ │ ┌───────────────────┴────────────────────────┐ │ │ │ WebSocket Handler │ │ │ │ (message routing, config, telemetry setup) │ │ │ └──────┬─────────┬──────────┬────────────────┘ │ │ │ │ │ │ │ ┌──────┴───┐ ┌───┴────┐ ┌──┴──────────┐ │ │ │ Sessions │ │ Config │ │ Transcript │ │ │ │ (PTY mgmt)│ │ (CRUD) │ │ (JSONL store)│ │ │ └──────┬───┘ └────────┘ └─────────────┘ │ │ │ │ │ ┌──────┴──────────────────────────────────┐ │ │ │ PTY Processes (node-pty) │ │ │ │ ┌─────────┐ ┌─────────┐ ┌──────────┐ │ │ │ │ │ claude │ │ codex │ │ gemini │ │ │ │ │ └─────────┘ └─────────┘ └──────────┘ │ │ │ └─────────────────────────────────────────┘ │ │ │ │ ┌──────────────┐ ┌────────────────┐ │ │ │ OTLP Receiver│ │ OpenCode Bridge│ │ │ │ POST /v1/logs│ │ POST /opencode │ │ │ └──────────────┘ └────────────────┘ │ │ │ │ ┌──────────────────────────────────────────┐ │ │ │ Plugin System │ │ │ │ ~/.clideck/plugins/ (Trim Clip, │ │ │ │ Voice Input, Autopilot, custom plugins) │ │ │ └──────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────┘ ``` ## Key Components ### PTY Sessions (node-pty) Each terminal session spawns a real pseudo-terminal using `node-pty`. The agent process runs inside this PTY and behaves exactly as if it were in a normal terminal. CliDeck doesn't inject any middleware between you and the agent. Terminal output is buffered (up to 200KB per session) and sent to the browser over WebSocket. The browser renders it using xterm.js. ### WebSocket Communication A single WebSocket connection carries all messages between the browser and server. Messages are JSON-encoded with a `type` field for routing. The server broadcasts to all connected clients — you can have multiple browser tabs open. ### OTLP Telemetry Receiver The server runs an HTTP endpoint at `POST /v1/logs` that accepts OpenTelemetry log data in JSON format. When an agent is launched, CliDeck sets environment variables that point the agent's OTLP exporter to this local endpoint. The receiver: 1. Parses the OTLP resource logs 2. Matches the log to the correct session (via `clideck.session_id` resource attribute) 3. Extracts the agent's session ID from log record attributes 4. Determines working/idle status from event types (per-agent logic) 5. Detects if telemetry is properly configured (triggers setup toast if not) ### OpenCode Plugin Bridge OpenCode uses a different integration path. A JavaScript plugin inside OpenCode sends HTTP events to `POST /opencode-events`. The bridge maps these events to the correct CliDeck session by matching the working directory. ### Activity Monitor A 1-second polling loop measures I/O rates for each session: * **Bytes in/out** since last poll * **Burst duration** — how long the current output burst has been going * Resets after 2 seconds of silence For **Shell sessions and custom agents**, these stats are the source of truth for working/idle status. For **Claude Code, Codex, and Gemini CLI**, status is driven by telemetry events instead — the activity monitor serves only as a timing reference (e.g., confirming output silence after an API response). ### Plugin System Plugins live in `~/.clideck/plugins/`. Each plugin is a folder with an `index.js` (backend) and optional `client.js` (frontend), `clideck-plugin.json` (manifest), and `public/` (static assets). On startup, CliDeck seeds bundled plugins (Trim Clip, Voice Input, Autopilot) into the plugins directory if they don't already exist. Then it loads all plugin folders, calls their `init()` with a sandboxed API, and wires up their hooks (input/output/status). Plugins communicate with the browser through namespaced WebSocket messages. The plugin API provides: * **Session hooks** — observe output, transform input, react to status changes * **Frontend messaging** — bidirectional communication between backend and browser * **Toolbar actions** — add buttons to the terminal toolbar * **Settings** — user-configurable settings with type validation, persisted in `config.json` * **Lifecycle** — shutdown handlers for cleanup Plugin errors are isolated — one plugin can't crash CliDeck or affect other plugins. ### Transcript Store Every session's I/O is recorded as plain-text JSONL in `~/.clideck/transcripts/`. ANSI codes are stripped, short lines filtered out. The transcript is used for sidebar search — a cache is built on startup and updated incrementally. ## Data Flow: Agent Status **Telemetry-driven agents (Claude Code, Codex, Gemini CLI):** ``` Agent emits telemetry → POST /v1/logs → OTLP receiver ├→ Matches event to session ├→ Determines working or idle from event type └→ Broadcasts session.status → browser updates indicator ``` **Shell and custom agents (I/O fallback):** ``` Agent outputs text → PTY → node-pty onData ├→ WebSocket 'output' → browser renders in xterm.js ├→ Activity tracker counts bytes └→ Transcript records stripped text Activity poll (1s) → broadcasts stats → browser computes working/idle ├→ Updates status indicator └→ Triggers notification (if idle transition) ``` ## Data Flow: Session Resume ``` Agent starts → telemetry logs flow to /v1/logs → OTLP receiver extracts session ID → stored as session.sessionToken CliDeck shuts down → SIGTERM/SIGINT handler → saves sessions to sessions.json → kills PTY processes CliDeck starts → loads sessions.json → shows in "Previous Sessions" sidebar → user clicks resume → spawns new PTY with resume command + saved session ID ``` ## Startup Detection When CliDeck starts, it scans for existing agent configurations on disk: * **Codex**: checks `~/.codex/config.toml` for an `[otel]` section pointing to localhost:4000 * **Gemini CLI**: checks `~/.gemini/settings.json` for a `telemetry` object with the local endpoint * **OpenCode**: checks if `~/.config/opencode/plugins/clideck-bridge.js` exists * **Claude Code**: checks `~/.claude/settings.json` for CliDeck lifecycle hooks If a configuration is found, the integration is marked as enabled in the UI automatically — no manual setup needed. This means if you've already configured an agent in a previous session, CliDeck picks it up on restart. ## Local Only CliDeck runs entirely on your machine. There's no cloud service, no account, no external API calls. By default, the Node.js server binds to `127.0.0.1:4000` — not accessible from other machines. Use `--host 0.0.0.0` to bind to all interfaces if you need LAN or VPN access. If the Node.js server stops, all PTY processes stop too. This is intentional — CliDeck manages terminal sessions locally. # Configuration Source: https://docs.clideck.dev/reference/configuration All CliDeck settings and how to configure them CliDeck is configured through the **Settings** panel in the UI. Settings are stored in `~/.clideck/config.json`. You rarely need to edit `config.json` directly — the Settings UI covers everything. This page documents all available options for reference. ## Command-Line Flags | Flag | Description | Default | | ------------------ | ---------------------------- | ---------------------------- | | `--host
` | Network interface to bind to | `127.0.0.1` (localhost only) | Use `--host 0.0.0.0` to make CliDeck accessible from other devices on your network (LAN, Wireguard, etc.), or `--host ` to bind to a specific interface. Running `--host` without a value defaults to `0.0.0.0`. ## General Settings | Setting | Description | Default | | ------------------------- | ------------------------------------------------ | ------------- | | Default working directory | Starting directory for new sessions | `~/Documents` | | Confirm before closing | Show a confirmation dialog when closing sessions | Enabled | ## CLI Agent Settings Each agent in the command list has these properties: | Property | Description | | ----------------------- | ------------------------------------------------------ | | **Label** | Display name in the session launcher | | **Command** | CLI command to run (e.g., `claude`, `codex`, `gemini`) | | **Enabled** | Whether the agent appears in the session launcher | | **Icon** | Agent icon (from presets or custom) | | **AI Agent** | Whether this is an AI agent (enables resume features) | | **Supports resume** | Whether session resume is available | | **Resume command** | Command template with `{{sessionId}}` placeholder | | **CliDeck integration** | Enable/disable live status and resume for this agent | ## Notification Settings | Setting | Description | Default | | -------------------------- | -------------------------------------------- | ------------ | | Notify when agent finishes | Enable idle transition notifications | Enabled | | Play sound | Play a sound on notification | Enabled | | Notification sound | Which sound to play | Default Beep | | Minimum working time | How long an agent must work before notifying | 10 seconds | ## Appearance Settings | Setting | Description | Default | | ------------- | ------------------------------------- | ---------------- | | Default theme | Terminal color theme for new sessions | Catppuccin Mocha | | Color mode | Light or dark UI mode | Dark | ## Projects Projects are stored in the config as an array: | Property | Description | | --------- | ----------------------------------------- | | **id** | Unique identifier (UUID) | | **name** | Project display name | | **path** | Default working directory for the project | | **color** | Accent color (one of 8 preset colors) | ## Data Directory All CliDeck data lives in `~/.clideck/`: | File | Purpose | | -------------------- | ------------------------------------------------------ | | `config.json` | Your settings and agent configuration | | `sessions.json` | Saved sessions for resume (written on shutdown) | | `transcripts/` | Per-session transcript files for search | | `plugins/` | Plugin folders (bundled + custom) | | `autopilot/` | Autopilot routing history, token usage, and debug logs | | `custom-themes.json` | User-defined terminal themes (optional) | This directory is created automatically on first run. It's separate from the CliDeck installation, so your data is preserved when you update CliDeck. ### Migrations CliDeck automatically migrates your config when the format changes between versions. Old settings are preserved — you won't lose your configuration when updating. ## Agent Presets Built-in agent definitions are stored in `agent-presets.json`. These provide defaults for each supported agent (command, icon, resume command, telemetry settings, etc.). When CliDeck loads, it syncs your configured agents with the latest preset data — ensuring you always get updated icons, resume commands, and telemetry configurations. You don't need to edit `agent-presets.json`. It's managed by CliDeck and updated when you install new versions. # Troubleshooting Source: https://docs.clideck.dev/reference/troubleshooting Common issues and how to fix them ## Keep CliDeck Updated CLI agents (Claude Code, Codex, Gemini CLI, OpenCode) are actively developed and may change their telemetry format, config file structure, or command-line flags. When this happens, CliDeck needs to be updated to match. **Always check for the latest version when something stops working:** ```bash theme={null} npm update -g clideck ``` Or if you use `npx`: ```bash theme={null} npx clideck@latest ``` ## Telemetry Not Working ### Setup toast keeps appearing This means the agent's integration isn't configured. The toast title tells you what's needed — **"Status Tracking"** for OTLP agents, **"Bridge Plugin"** for OpenCode. **For Codex or Gemini CLI:** 1. Click **Configure automatically** on the toast 2. Restart the session when prompted 3. If it still doesn't work, check if the config file was written correctly: * Codex: `~/.codex/config.toml` should have an `[otel]` section * Gemini: `~/.gemini/settings.json` should have a `telemetry` object **For Claude Code:** Telemetry should work automatically. If it doesn't: * Make sure you're launching Claude Code from CliDeck (not from a separate terminal) * Check that `claude` is in your PATH ### Status indicator stuck on idle If the status dot shows "zzZ" even when the agent is clearly working: * **Claude Code, Codex, Gemini CLI:** Make sure telemetry is configured. Without it, CliDeck can't detect status for these agents. Check for the setup toast when you launch a session. * **OpenCode:** Make sure the bridge plugin is installed in `~/.config/opencode/plugins/` * **Shell / custom agents:** The agent may not be producing enough output to trigger burst detection (needs output within a 2-second window) * Try restarting the session ### Status indicator stuck on working * The agent may still be processing in the background * **Claude Code, Codex, Gemini CLI:** Status clears when the agent emits its completion event. If it stays working, the agent may be stuck — try sending input or restarting the session. * **Shell / custom agents:** Wait 2+ seconds of silence for the burst timeout to reset * **OpenCode:** The plugin may have disconnected. Restart the session. ## Session Resume Issues ### "Resume" button doesn't appear Resume requires: 1. The agent preset has `canResume` enabled 2. A session ID was captured during the original session 3. CliDeck was shut down gracefully (Ctrl+C, not `kill -9`) If the session ID wasn't captured (telemetry wasn't configured), resume won't be available. ### Resume starts a new session instead of continuing The agent may not recognize the session ID. This can happen if: * The agent was updated and its session format changed * The session expired on the agent's side * The session ID was captured incorrectly Try starting a fresh session instead. ## Agent Not Appearing in Launcher * Open **Settings** > **CLI Agents** and make sure the agent is **enabled** * Check that the agent's command is installed and in your PATH. Try running the command directly in a terminal: ```bash theme={null} which claude # or codex, gemini, opencode ``` * If the command isn't found, install the agent following its official documentation ## Terminal Display Issues ### Colors look wrong * Check if your theme's polarity (light/dark) matches the UI mode. A dark theme in light mode (or vice versa) can cause contrast issues. * If you see a restart banner, click it — the terminal needs to restart for theme changes to take effect. * Try switching to a different theme in **Settings** > **Appearance** ### Terminal not resizing properly * CliDeck uses a ResizeObserver to track terminal dimensions. If the terminal appears cut off, try: * Refreshing the browser page * Clicking on the session to re-focus it * Resizing your browser window slightly ### Text appears garbled * Some agents use complex ANSI sequences that xterm.js may not render perfectly * Try a different terminal theme — some handle edge cases better * If persistent, check if the agent has a "plain output" mode ## Connection Issues ### "WebSocket disconnected" The browser lost its connection to the CliDeck server. This usually means: * The CliDeck server crashed or was stopped * Your computer went to sleep and the connection timed out Refresh the page to reconnect. Your sessions are still running on the server (if it's still up). ### Port 4000 already in use Another process is using port 4000. This could be a previous CliDeck instance or another application. ```bash theme={null} lsof -i :4000 ``` ```cmd theme={null} netstat -ano | findstr :4000 ``` Find and stop the process using the port, then start CliDeck again. ## OpenCode Plugin Issues ### Plugin not connecting 1. Make sure the bridge plugin is installed. Launch an OpenCode session from CliDeck — if the plugin isn't installed, a toast will appear with an **Install plugin** button that does it automatically. 2. Verify the plugin file exists: ```bash theme={null} ls ~/.config/opencode/plugins/clideck-bridge.js ``` 3. Make sure CliDeck is running before launching OpenCode 4. Check that OpenCode loads plugins from `~/.config/opencode/plugins/` ### Wrong session matched The OpenCode bridge matches sessions by working directory. If you have multiple OpenCode sessions in the same directory, they may get mixed up. Use different working directories for different sessions. ## Getting Help If none of the above resolves your issue: 1. Check the [GitHub Issues](https://github.com/rustykuntz/clideck/issues) for known problems 2. Open a new issue with: * Your CliDeck version * The agent and version you're using * Steps to reproduce the problem * Any error messages from the browser console or terminal