duck CLI is your terminal interface to Rubber Duck. It attaches workspaces, streams conversation events, sends text messages, and manages sessions.
Overview
Rubber Duck uses a client-daemon architecture:- The daemon (
duck-daemon) runs in the background, manages Pi subprocesses, and coordinates sessions - The CLI (
duck) is a lightweight client that communicates with the daemon over a Unix socket
The daemon starts automatically when you run any
duck command. It listens on a Unix socket at ~/Library/Application Support/RubberDuck/daemon.sock.Core Commands
duck [path]
Attach a workspace and stream events.
This is the default command — just run duck in any directory:
- Attaches the current directory (or
[path]if provided) as a workspace - Creates or resumes the default session for that workspace
- Sets the session as the active voice session (so Option+D talks to this session)
- Starts streaming all conversation events to your terminal
- User utterances (voice transcripts and text messages)
- Assistant responses (text and audio transcripts)
- Tool calls with streaming output
- Session state changes
The terminal stays open and streams events in real time. Press Ctrl+C to stop following, but the session continues running in the background.
duck say <message...>
Send a text message to the active session.
This is equivalent to speaking via the voice interface, but using text input:
- Sends the message to the active session’s Pi subprocess
- Waits for the agent to respond (tool calls, streaming output, etc.)
- Prints all events to the terminal
- Exits when the agent finishes (or after 10 minutes)
--json: Output raw NDJSON events instead of pretty-printed text--session <id>: Send to a specific session (by name or ID prefix)--show-thinking: Display model thinking blocks (hidden by default)
duck sessions
List all sessions for the current workspace (or all workspaces with --all).
Output includes:
- Session name and ID
- Workspace path
- Status (running or stopped)
- Last active timestamp
- Active session indicator (✔)
--all: Show sessions across all workspaces--json: Output as JSON array
The active session (marked with ✔) is the one that receives new voice utterances when you press Option+D.
duck doctor
Check system health and dependencies.
Runs diagnostics for:
- Daemon: Is the daemon running and reachable?
- Pi binary: Is Pi installed and executable?
- API keys: Are required environment variables set (e.g.,
OPENAI_API_KEY,ANTHROPIC_API_KEY)? - Microphone: Does Rubber Duck have microphone permissions?
- Workspace: Is the current directory a valid workspace?
Removed Commands
Previous versions of Rubber Duck CLI had separate commands forattach, follow, new, use, abort, and export. These have been streamlined:
duck attach+duck follow→duck [path](attach and stream in one command)duck new→ Sessions are created automatically when neededduck use→ The active session is set automatically byduck [path]duck abort→ Barge-in via voice (Option+D toggles off) or Ctrl+C in the terminalduck export→ Coming soon (use Pi RPCexport_htmlmethod directly for now)
Output Formats
Text (Default)
Pretty-printed, color-coded output with prefixes:- Cyan: User messages
- Green: Assistant responses
- Yellow: Tool calls and arguments
- Dim: Tool output and metadata
NO_COLOR is set or stdout is not a TTY.
JSON (NDJSON)
Raw event stream as newline-delimited JSON. Useful for scripting or integrating with other tools:types.ts for the full event schema.
Extension UI Requests
When Pi needs interactive input (e.g., from an extension or skill), the CLI automatically handles it using @clack/prompts:extension_ui_response, and the agent continues.
Extension UI prompts only appear in interactive mode (when
stdin and stdout are both TTYs). In non-interactive mode (e.g., CI), prompts are skipped.Environment Variables
RUBBER_DUCK_PI_BINARY
Override the Pi binary path. By default, the CLI looks for:
RUBBER_DUCK_PI_BINARY(if set)node_modules/.bin/pi(local install)pionPATH
RUBBER_DUCK_PI_MODEL
Set the default model for Pi sessions. Defaults to gpt-4o-mini when OPENAI_API_KEY is set.
RUBBER_DUCK_PI_THINKING
Set the thinking level for Pi. Defaults to off for speed. Options: off, minimal, low, medium, high, xhigh.
NO_COLOR
Disable all color output (follows the NO_COLOR standard).
Daemon Management
The daemon starts automatically when you run anyduck command. It runs in the background and persists across terminal sessions.
Daemon Files
All daemon runtime files are stored in~/Library/Application Support/RubberDuck/:
daemon.sock- Unix socket for IPC (or$TMPDIR/rubber-duck-<hash>.sockif path is too long)duck-daemon.pid- Process ID of the running daemonduck-daemon.log- Lifecycle logs (start, stop, crashes)metadata.json- Workspace and session metadata (atomically updated)config.json- Runtime configuration (model, thinking level, etc.)pi-sessions/- Per-session JSONL history files
Manual Daemon Control
You can manually start, stop, or restart the daemon:Socket Path Fallback
Unix sockets have a maximum path length (104 bytes on macOS). If the default path~/Library/Application Support/RubberDuck/daemon.sock exceeds this limit, the daemon and CLI automatically fall back to:
This fallback is transparent — you don’t need to do anything. Both the daemon and CLI will use the same logic to determine the socket path.
Related
- Sessions - Multi-session workflows and workspace management
- Voice Interface - Using the voice interface alongside the CLI
- Interruptions - Aborting or steering agent runs