Skip to content

Command-Line Client

The workbench CLI talks to the running desktop app over a local socket. Most operations flow through the GUI’s own command core — so tray icons, notifications, and the workspace list update live as the CLI works.

Most subcommands require the desktop app to be running. If it isn’t, they exit with a clear “open the desktop app first” message rather than silently degrading. Two exceptions:

  • workbench completion <shell> is purely local — it generates a clap-driven completion script and writes it to stdout, no IPC at all.
  • workbench version always prints the CLI’s own version, then attempts to query the GUI for its version on top — if the GUI isn’t reachable it prints a “GUI not reachable” note instead of erroring out.

The workbench binary ships inside the desktop app bundle. Use the in-app installer in Settings > CLI, which symlinks the bundled binary onto your PATH. On Linux, .deb installs place the CLI at /usr/bin/workbench automatically. Standalone workbench-cli-<platform> release assets are also published per release for headless / CI consumers.

To install shell completion:

Terminal window
# zsh
workbench completion zsh > ~/.zsh/completions/_workbench
# bash
workbench completion bash > ~/.bash_completions/workbench
# fish
workbench completion fish > ~/.config/fish/completions/workbench.fish

Build from source:

Terminal window
cargo install --path src-cli

Driving Workbench from a Claude Code agent

Section titled “Driving Workbench from a Claude Code agent”

The Workbench repository ships a Claude Code skill at .claude/skills/SKILL.md that wraps every CLI command described on this page. With the skill installed, an agent running anywhere on your machine can list workspaces, send prompts, resolve pending plan approvals, and fan out batch manifests — without you copy-pasting commands into a terminal.

This is the loop that powers most agent-orchestrating-agents workflows: a “main” Claude Code session uses the skill to drive Workbench, which spawns its own Claude Code subprocesses inside isolated worktrees.

Two paths, depending on where you want it available:

Project-local (recommended if you only use the skill while working inside the Workbench checkout):

Terminal window
git clone https://github.com/utensils/Workbench.git
# Skill is now at <repo>/.claude/skills/SKILL.md and auto-loads
# whenever a Claude Code session opens this directory.

User-global (recommended if you want the skill available from any project):

Terminal window
# Symlink the skill into your user skills dir
mkdir -p ~/.claude/skills
ln -s "$(pwd)/.claude/skills/workbench" ~/.claude/skills/workbench
# Or copy it (no auto-update; you control when to refresh):
cp -R .claude/skills/workbench ~/.claude/skills/

Claude Code looks in <repo>/.claude/skills/ and ~/.claude/skills/ automatically — no registration step.

The skill’s frontmatter declares allowed-tools: Bash(workbench:*), which pre-grants the agent permission to invoke any workbench ... command without per-call prompts. The skill body itself is a curated playbook of common workflows: workspace lifecycle, sending prompts with the right flags, inspecting pending_controls, resolving AskUserQuestion / plan-mode requests, batch fan-out, and so on.

In a Claude Code session, ask “list my Workbench workspaces” — if the skill is wired up correctly, the agent runs workbench workspace list directly rather than asking permission. If you see a permission prompt for Bash(workbench ...), the skill isn’t being discovered; double-check the directory name (workbench, exactly) and that SKILL.md lives inside it.

Terminal window
workbench --help # Top-level usage
workbench capabilities # JSON manifest of supported IPC methods
workbench version # GUI app + protocol version

Output formats vary by subcommand:

  • Table by default, JSON with --json: workspace list, repo list, pr list, plugin list — these have a human-readable table renderer; pass --json to get the raw JSON for scripting.
  • Always JSON: every other IPC-backed command (capabilities, chat *, workspace create, workspace archive, pr show, plugin invoke, rpc, etc.) returns JSON straight from the GUI, regardless of --json.
  • Plain text: version prints two human-readable lines (CLI version + GUI version when reachable). completion <shell> writes the generated shell-completion script to stdout.
Terminal window
workbench workspace list # Active workspaces
workbench workspace list --json # Scriptable output
workbench workspace create <repo-id> <name> # New workspace on a fresh worktree
workbench workspace archive <id> # Archive (worktree removed; chat preserved)
workbench workspace archive <id> --delete-branch # Force-delete the branch on archive
workbench workspace purge --repo <repo-id> # Permanently delete archived workspaces in a repo
workbench workspace purge --repo <repo-id> --older-than-days 90 --dry-run

workspace purge only ever removes archived workspaces — the server rejects Active IDs. Add --older-than-days N to restrict by age, and --dry-run to preview the IDs without deleting.

workspace create returns the new workspace’s ID and a default_session_id that you can immediately target with chat send.

Terminal window
# Inspect
workbench chat list <workspace-id>
workbench chat list <workspace-id> --include-archived
workbench chat show <session-id> # Snapshot: metadata, recent messages, pending controls
workbench chat show <session-id> --limit 50 --before <message-id>
workbench chat turns <session-id> # Persisted completed turns + tool activity
workbench chat attachments <session-id> # Attachment metadata
workbench chat attachment-data <attachment-id> # Full body as base64
# Lifecycle
workbench chat create <workspace-id>
workbench chat rename <session-id> <new-name>
workbench chat archive <session-id>
workbench chat stop <session-id> # Stop a running agent turn
workbench chat reset <session-id> # Reset Claude resume state
workbench chat clear-attention <session-id>
Terminal window
# Send a fresh prompt (kicks off an agent turn)
workbench chat send <session-id> "Refactor the auth middleware"
workbench chat send <session-id> @./prompts/task.md # @file reads from disk
workbench chat send <session-id> - # `-` reads from stdin
# Mid-turn steering: queue a follow-up while the agent is running
workbench chat steer <session-id> "Also update the tests"

chat send mirrors every lever the GUI’s chat input bar exposes:

Terminal window
workbench chat send <session-id> @./prompt.md \
--model opus \
--plan \
--thinking \
--effort high \
--chrome \
--permission acceptEdits

Boolean flags are tri-state — pass --plan to force on, --no-plan to force off, or omit both to inherit the GUI default. This lets a script override a workspace-level toggle in either direction without rewriting settings.

FlagValuesEffect
--modelopus, sonnet, haiku, claude-opus-4-8, claude-fable-5, …Override model for this turn
--plan / --no-planPlan mode (read-only until approved)
--thinking / --no-thinkingExtended thinking
--fast / --no-fastFast mode (built-in support: Opus 4.6)
--effortlow, medium, high, xhigh, maxReasoning effort (xhigh requires Opus 4.7+, Fable 5, or Sonnet 5)
--chrome / --no-chromeChrome browser tool
--disable-1m-contextSuppress Max-plan auto-upgrade to a 1M context window
--permissiondefault, acceptEdits, bypassPermissionsPermission level

Plan mode and AskUserQuestion produce pending controls — the agent pauses and waits for a human (or another script) to respond. Resolve them from the terminal:

Terminal window
# Answer an AskUserQuestion request
workbench chat answer <session-id> <tool-use-id> \
--answers-json '{"Which library should we use?":"date-fns"}'
# Approve a plan
workbench chat approve-plan <session-id> <tool-use-id>
# Deny a plan with feedback
workbench chat deny-plan <session-id> <tool-use-id> \
"Use middleware composition instead of inheritance"

tool_use_id is in the pending_controls field of chat show output. See Plan Mode for the workflow context.

Terminal window
workbench repo list # Registered repositories
workbench repo list --json

The GUI is the canonical registration surface today. Use repo list to map between repository IDs (used by workspace create) and human-readable names.

pr is a friendly shortcut over the active SCM provider plugin (typically scm-github or scm-gitlab). It resolves the workspace’s branch and SCM provider automatically.

Terminal window
workbench pr list --workspace <workspace-id> # PRs for this branch
workbench pr list --workspace <workspace-id> --all # Every open PR in the repo
workbench pr show <number> --workspace <workspace-id>

Set WORKBENCH_WORKSPACE_ID to skip the --workspace flag.

If no SCM provider matches the repository’s remote, the command exits with a helpful message — usually because the corresponding CLI (gh, glab) is missing or the plugin is disabled.

The generic plugin surface lets scripts list discovered plugins and invoke any declared operation directly. Friendly per-kind shortcuts (pr list) are layered on top.

Terminal window
workbench plugin list # Loaded plugins, kind, CLI status
workbench plugin invoke github list_pull_requests \
--workspace <workspace-id> \
'{"branch":"feature/x"}'

The third positional argument is JSON passed verbatim as the operation’s args. Defaults to {}.

The flagship use case for the CLI: a phase-of-work plan that creates N workspaces and dispatches a prompt to each.

Terminal window
workbench batch validate plan.yaml # Lint without creating
workbench batch run plan.yaml # Create workspaces + dispatch prompts

Manifest schema (YAML or JSON):

repository: my-repo # Name or id
defaults: # Applied to each workspace before per-workspace overrides
model: sonnet
plan: false
workspaces:
- name: builtins-tsx
prompt_file: ./prompts/43-builtins.md
- name: shell-rs
prompt: |
Implement issue #42 ...
model: opus # Per-workspace override
- name: validator
prompt: "Add input validation tests"
plan: true
permission: acceptEdits

prompt_file paths are resolved relative to the manifest’s directory. validate catches duplicate names, missing prompts, prompt-file paths that don’t exist, and invalid workspace names.

routine manages native cron-style scheduled prompts that fire through a chat session:

Terminal window
workbench routine list # Wakeups + routines
workbench routine create <session-id> "0 9 * * 1-5" "Check open PRs" --name weekday-prs
workbench routine create <session-id> "30 14 28 2 *" "Review the checklist" --once
workbench routine run weekday-prs # Fire immediately by id or name
workbench routine delete weekday-prs # Delete by id or name

routine create accepts literal prompts, @file prompts, and - for stdin, matching chat send. See Agent Scheduling for the cron semantics.

For methods that don’t have a typed subcommand yet:

Terminal window
workbench rpc list_workspaces
workbench rpc create_workspace '{"repo_id":"…","name":"my-task","preserve_name":true}'

Use workbench capabilities to see the full method list.

VariablePurpose
WORKBENCH_WORKSPACE_IDDefault --workspace for pr and plugin invoke

Original source: utensils.io/claudette