CODEX TEBOUHow to Be a Beast
Codex TebouThe Workshopf. 47r

Table IV · The Workshop

CLIs

Why command-line tools are the cheapest way to give an agent a capability, the third-party CLIs Cole's agents use all day, the ones Cole wrote, and the design habits that make a CLI safe and pleasant for agents to drive.

f. 47r127 stichoiemended Oct 28, 2026cited by 10

Capitula · contents
  1. Why agents like CLIs
  2. The everyday toolbox
  3. Cole’s own CLIs
  4. How Cole designs a CLI for agents
  5. Gotchas

A command-line tool is the cheapest way to give an agent a new capability. It documents itself (--help), it can print JSON for the next tool in the pipe, it reports success or failure with an exit code, and it costs nothing at all until it runs, unlike an MCP server whose tools are listed in every session. Models have read an enormous amount of shell, so they are good at it. Most of Cole’s setup is CLIs, and the agents drive them all day, the same way a person would.

Why agents like CLIs

  • Self-documenting. An agent that meets an unfamiliar tool runs tool --help and carries on.
  • Composable. gh api … | jq … answers questions no single tool was built for.
  • Testable. A CLI has inputs, outputs and an exit code, so it gets real tests (see Tests).
  • Shared with the human. The command an agent ran is one Cole can run, read in a transcript, or put in a script.
  • Cheap in context. Nothing loads until a command is used, and output can be filtered before it reaches the model.

The tradeoff is structure and authority. A long-lived connection, credentials the agent should not hold, or results gathered across machines fit better behind an MCP server. Cole’s Drover offers both: every capability is one op, available as drover op <op>, as an MCP tool and as a button.

The everyday toolbox

Tool What the agents use it for
git Everything; see Git Habits and Git Worktrees
gh Pull requests, issues, CI runs and raw API calls to GitHub
jq Reading and reshaping JSON: hook payloads, API answers, transcripts
rg, fd Fast text search and file finding (see grep, ripgrep and ugrep)
tmux Windows for every session; capture, send keys (see tmux)
cf Cloudflare’s own CLI, for DNS, tunnels and the rest (see The Cloudflare API and cf)
aws The AWS servers and storage (see Servers and S3 and Glacier)
docker Compose stacks per worktree
dotenvx Encrypted env files (see Env Files and dotenvx)
gitleaks Secret scanning on every commit and push
claude, codex Starting more agents, headless (claude -p, codex exec) or in tmux

Inside Claude Code there is one twist: Cole’s rules tell agents to prefer Claude Code’s built-in Read, Grep and Glob tools over cat, rg and find within a session. The shell versions are for pipelines, scripts and machines without the agent.

Tools arrive on each machine through the The Bootstrap Script, Homebrew’s Brewfile on macOS and pinned Node tool versions everywhere, so every machine has the same versions. Plugins can ship their own CLIs too: Claude Code puts a plugin’s bin/ directory on the Bash tool’s PATH while the plugin is enabled (see Skills and Plugins).

Cole’s own CLIs

CLI What it does Page
wt Create or attach a git worktree and cd into it Git Worktrees
pw Launch, watch, broadcast to and tear down parallel worktree sessions Parallel Worktrees
cc-park Park idle Claude Code sessions and bring them back cc-park
cc-handoff Hand a session to a fresh successor through a brief Handoff Chains
reflections Add, search and close items in the reflection store The Reflection Store
drover The control plane: drover op, drover search, drover grep, drover stacks Drover
dotsync Commit, pull, push and apply the dotfiles on every machine Dotfiles
autoreview-pair Two independent reviews of one frozen scope, in parallel, one exit code Git Habits
badland-brain Mint keys, import memory, reindex the shared brain The Shared Brain

Several are public on their own: porchlight, a fleet-aware login dashboard for the terminal; ai-keys, one CLI to create, list, revoke and distribute API keys across AI providers; and Cole’s forks of imsg (Messages from the command line, for agents), acpx (a headless client for Agent Client Protocol sessions) and clawpatch (review code, patch bugs, land pull requests).

How Cole designs a CLI for agents

Patterns that recur across Cole’s tools:

  • Results on stdout, conversation elsewhere. wt-helper writes its prompts and status lines to the terminal and prints only the final path on standard output, so a shell function can capture it.
  • Exit codes that mean something. cc-handoff launch documents eight: 0 started and replied, 2 bad arguments or an unready brief (nothing started), 3 a required tool is missing, 4 a successor already exists (never relaunch), 5 tmux failed (a window that opened is left running), 7 started but not replied yet, 8 no launcher reproduces the session’s route, 9 the remote preflight failed. An agent can branch on the number instead of parsing prose.
  • A dry run for anything that changes things. The installer’s --dry-run, cc-park list, pw validate, and --print on the handoff launcher all show the plan and touch nothing.
  • Refuse rather than guess. A brief with a placeholder left, an unknown launch flag, a volume that is not mounted: the tool stops and says why.
  • Never print a secret, never take one in argv. Values come from standard input or a hidden prompt, because other users can read a process’s arguments, and status commands print names, never values.
  • Gates fail closed, helpers fail open. A secret scan that cannot run blocks the push; a helper hook that breaks just steps aside.
  • Idempotent. Running it twice changes nothing the second time; the installer moves anything it replaces into a dated backup with a log.
  • Portable. Most of Cole’s scripts run on macOS’s stock bash 3.2 as well as on Linux, so they avoid tools that differ between BSD and GNU (sed -i, readlink -f, date -d, stat). See POSIX, macOS and Linux.

Gotchas

  • Interactive prompts hang agents. Anything that waits for a password, a passphrase or a browser callback stalls a headless session. Give automation --batch, BatchMode=yes for SSH, and tokens instead of logins.
  • Pipes hide exit codes. Without set -o pipefail, gate | tail exits with tail’s status. Wrap a gate so the wrapper exits with the gate’s own code.
  • Huge output is expensive. Filter before printing: rg with a glob, jq with a selection, tail -n 50.
  • pgrep -f matches more than you think. It also matches every other session’s polling loop that mentions the same pattern; match by exact process name with pgrep -x.

f. 47v The back of the leaf

Cited by

Cites

Fontes · sources

Colophon of this leaf

↑ ↓ to chooseEnter to openEsc to close