q is a typed Python CLI (built with Typer) that wraps the config/Makefile targets. It replaces raw make invocations with an ergonomic, documented interface.
Package location: app/cli/
Entry point: q (installed via uv)
cd app/cli
uv sync # installs typer, rich, and the q entry point
uv run q --help # verify installationBuilds the claude-agent:wolfi image (no cache).
q build
q build --image my-image:tag --dockerfile Dockerfile.custom| Option | Default | Description |
|---|---|---|
--image |
claude-agent:wolfi |
Image tag |
--dockerfile |
Dockerfile.wolfi |
Dockerfile to use |
Creates the isolated bridge network (claude-agent-net). Idempotent — skips if already exists.
q network
q network --subnet 10.0.0.0/24 --network-name my-netRuns an interactive coordinator shell. Hands off the TTY completely via os.execvp.
q run
q run --cpus 4 --memory 8G --name my-coordinator
q shell # alias for runRequires CLAUDE_CONTAINER_OAUTH_TOKEN to be set.
Spawns a detached headless agent in an isolated git worktree.
q spawn --branch feat/oauth2 --task "Implement OAuth2 with JWT tokens"
q spawn --branch test/payments --task "Write unit tests for payments module" --cpus 4| Option | Required | Description |
|---|---|---|
--branch |
yes | Git branch for the agent worktree |
--task |
yes | Task description (prompt for Claude) |
--cpus |
no | CPU count override |
--memory |
no | Memory limit override (e.g. 8G) |
--image |
no | Image tag override |
Requires CLAUDE_CONTAINER_OAUTH_TOKEN to be set.
Branch naming: avoid
/in branch names — they create nested subdirectories in$AGENTS_HOMEwhich the entrypoint cannot handle. Use flat names likefeat-oauth2instead offeat/oauth2.
Lists active agent containers and worktrees on disk.
q agents listShows snapshot logs for a branch agent.
q agents logs --branch feat-oauth2Follows live streaming logs (hands off TTY via os.execvp).
q agents follow --branch feat-oauth2Shows agent status from the persisted status.json file. Works even after the
container has exited — reads directly from the worktree filesystem.
q agents status --branch feat-oauth2Output includes: phase, branch, task, timestamps, duration, exit code, commit count.
Shows structured lifecycle events ([agent:status] markers) for a branch agent.
q agents summary --branch feat-oauth2Stops a branch agent container.
q agents stop --branch feat-oauth2When the container no longer exists (agent finished, --rm removed it), logs and
follow automatically fall back to the persisted .agent/agent.log in the worktree
directory with a contextual message. This avoids confusing error output.
q clean # Remove container + image
q clean-network # Remove bridge network
q clean-all # Remove image + networkAll commands resolve the config/Makefile path dynamically:
git rev-parse --show-toplevel → GIT_ROOT / "config" → make -C <path> <target> [VARS]
Commands that contact the container daemon (run, spawn) call check_token() which validates CLAUDE_CONTAINER_OAUTH_TOKEN is set before invoking make.
TTY-intensive commands (run, shell, agents follow) use os.execvp to replace the process entirely, so the terminal is fully handed off with no intermediary.
app/cli/
├── pyproject.toml ← uv project, entry point: q
└── src/
└── container_cli/
├── main.py ← registers all commands + agents sub-app
├── utils.py ← find_git_root, makefile_dir, check_token, run_make
└── commands/
├── build.py ← build, clean, clean-network, clean-all
├── network.py ← network
├── run.py ← run, shell
└── agents.py ← spawn, list, logs, follow, stop
| CLI command | Makefile target | Notes |
|---|---|---|
q build |
build |
optional --image, --dockerfile |
q network |
network |
optional --subnet, --network-name |
q run |
run |
TTY hand-off via os.execvp |
q shell |
shell |
alias for run |
q spawn |
spawn |
requires --branch, --task |
q agents list |
list-agents |
|
q agents logs |
logs-agent |
requires --branch |
q agents follow |
follow-agent |
TTY hand-off |
q agents stop |
stop-agent |
requires --branch |
q clean |
clean |
|
q clean-network |
clean-network |
|
q clean-all |
clean-all |