CLI overview
How the bowline CLI is organized, how it talks to the daemon, and how JSON output, discovery, dry-run, and retry handling work.
For both humans and coding agents, the bowline CLI is the primary surface for
inspecting, repairing, and deciding. It's a thin client over the local
bowline-daemon, which owns sync, materialization, and merging. This page
covers how the CLI is organized and the conventions that apply across every
command. For every command and flag, see the
command reference.
How the CLI talks to the daemon
The CLI sends requests to the local daemon over a Unix domain socket. The
default socket path is /tmp/bowline-daemon.sock. You rarely need to think
about this, but two things are worth knowing:
--socket <path>points the CLI at a non-default socket. Keep using the same socket when you want subsequent commands to reach the same daemon.- If commands report the daemon is unreachable, check it with
bowline daemon statusand start or install it withbowline daemon startorbowline daemon install.
Command groups
The command surface is grouped by intent. The reference page is organized the same way.
| Group | Purpose |
|---|---|
| Discovery | help, version, contract. |
| Workspace | update, login, logout, status, setup, events, tui, forget-local, archive, purge. |
| Trust | device list, device approve, device deny, device revoke, recover. |
| Remote | connect. |
| Work | work create, work list, work diff, work review, work accept, work discard, work restore, work cleanup. |
| Daemon | daemon start, daemon stop, daemon status, daemon install, daemon restart, daemon uninstall. |
| Support | diagnostics collect, doctor. |
For commands that select a workspace, Bowline infers the root from the current
directory or, when exactly one accepted root is known, from local metadata. Use
--root <path> to override that inference. Commands report an error and ask for
--root when no root can be inferred or multiple roots are ambiguous.
Command-scoped options
Options follow the complete command path and exist only on commands whose descriptor declares them.
| Option | Applies to | Description |
|---|---|---|
--json | JSON-capable commands | Emit machine-readable JSON on stdout. |
--socket <path> | Daemon-connected commands | Use a non-default daemon socket. |
--dry-run | Declared mutating commands | Preview a change without applying it. |
JSON output
Every command except the interactive TUI emits JSON by default when stdout isn't
a terminal. This makes pipes, command substitution, agents, and scripts use the
stable, contract-backed output automatically. When stdout is a terminal, Bowline
keeps the human-readable default. Use --json to force JSON or --human to
force human-readable output in a pipe.
work list, events, and device list also accept --quiet. Quiet mode
prints one primary identifier per line with no heading or decoration. It is
useful when another command needs only work-view IDs, event IDs, device IDs, or
pending-request IDs.
When a command fails in JSON mode, it prints a CommandErrorOutput envelope to
stdout and exits non-zero. The envelope includes contractVersion, command,
generatedAt, status, and an optional top-level nextActions field, plus an
error object. The error object holds code, message, and
recoverability, with optional remediation, details, retryAfterSeconds,
and correlationId. Human-mode failures print to stderr instead.
Exit codes are stable and mirror the error taxonomy. bowline contract exposes
the same mapping in its exitCodes section.
| Exit code | Meaning |
|---|---|
0 | Success. |
2 | Usage error. |
3 | Retryable runtime error. |
4 | User action is required before retrying. |
5 | Blocked or degraded by a safety constraint. |
Discovery
The CLI is self-describing, so agents and scripts don't have to scrape prose. Start with the compact command index, then fetch the full descriptor only for the command you intend to use:
bowline contract --summary --json
bowline contract status --json
bowline status --root ~/Code --jsonbowline contract --summary --json returns contract metadata and a compact
entry for every command: its canonical name, group, one-line summary,
side-effect level, and support for --json and --dry-run. Pass the canonical
command name to load its full descriptor, including usage, options, examples,
JSON output type, bounded-output controls, and related commands. For example,
bowline contract work diff --json returns the descriptor for work diff.
The unscoped bowline contract --json remains the canonical full export for
tools that need every descriptor and fixture path at once. Topic help also works
in JSON:
bowline help work create --json
bowline help daemon install --jsonDry-run and retries
Supported mutating commands accept --dry-run, and failed commands expose
stable retry guidance through their exit code and error envelope.
--dry-runreturns a preview and changes no filesystem, metadata, daemon, trust, or recovery state. Its result includes the exact command to apply the change.- Exit code
3means a retryable runtime error. In JSON mode, confirm thaterror.recoverabilityis retryable and honorerror.retryAfterSecondswhen present before retrying. - Exit codes
2,4, and5require corrected input, user action, or safety remediation. Don't automatically replay those commands unchanged.
Next steps
- Command reference: every command, flag, and example.
- Agent-native contract: drive Bowline from a coding agent.
- Status and health: read status output and next actions.