CLI Reference
Platform binaries
Section titled “Platform binaries”The @boboddy/cli npm package ships pre-compiled binaries for:
| Platform | Binary |
|---|---|
| macOS (Apple Silicon) | boboddy-darwin-arm64 |
| macOS (Intel) | boboddy-darwin-x64 |
| Linux x64 | boboddy-linux-x64 |
| Linux ARM64 | boboddy-linux-arm64 |
| Windows x64 | boboddy-windows-x64.exe |
The wrapper at bin/boboddy detects your platform and delegates to the correct binary automatically — you should never need to reference these directly except when debugging a broken install.
Global flags
Section titled “Global flags”These flags apply to every command:
| Flag | Description |
|---|---|
--env-file <path> |
Load environment variables from an alternate .env file |
--base-url <url> |
Override the API server URL (default: https://app.boboddy.dev, also set via BOBODDY_BASE_URL) |
--help |
Show help for the current command |
--version |
Print the CLI version |
boboddy auth
Section titled “boboddy auth”Manage authentication credentials.
boboddy auth login
Section titled “boboddy auth login”Start a device-flow browser login. Opens your browser; credentials are saved to ~/.boboddy.json on completion.
boboddy auth loginboboddy auth logout
Section titled “boboddy auth logout”Remove stored credentials.
boboddy auth logoutboboddy auth status
Section titled “boboddy auth status”Show whether you are currently authenticated.
boboddy auth statusboboddy auth whoami
Section titled “boboddy auth whoami”Print the email address of the authenticated user.
boboddy auth whoamiboboddy init
Section titled “boboddy init”Interactive project setup. Runs in sequence:
- Resolves the git repository by walking up from the current directory to
find the real repo root — the same way
git rev-parse --show-toplevelwould — soinitworks from any subdirectory of a repo, including from inside a git submodule. Prints the resolved repo path and the resolvedoriginremote URL before doing anything else. - Authenticates (device flow if not logged in)
- Checks for OpenCode auth — an
auth.jsonentry or a recognized provider env var (ANTHROPIC_API_KEY,OPENAI_API_KEY,GEMINI_API_KEY,GOOGLE_GENERATIVE_AI_API_KEY,OPENROUTER_API_KEY,GROQ_API_KEY,XAI_API_KEY,DEEPSEEK_API_KEY), the same detectionpipelines design’s preflight uses. If neither is found, it runsopencode auth logininline and waits for you to finish before continuing, instead of stopping with an instructional error - Selects a project matched by the resolved remote URL from step 1. If none
matches,
initopens your browser to/projects/new— pre-filled with the detected repository — instead of creating one for you. Finish the GitHub-linking choice there, then come back and press Enter to letinitcontinue. - Writes
.boboddy/boboddy.jsoncwith theprojectId(you can also add an optionalbranchPrefix— see Work branches) - Checks for a
.devcontainer/devcontainer.jsonand reports what it finds. A missing one is a notice, not an error —initdoes not write one, but it does not stop either: the design session authors it (seepipelines design) - Offers to launch
boboddy pipelines designstraight away — carrying--work-item-idthrough when you passed one, instead of always leaving it to the designer’s own picker
boboddy initboboddy init --work-item-id <id>| Flag | Description |
|---|---|
--base-url <url> |
Override the API server URL |
--work-item-id <id> |
Carry this work item ID into the designer handoff in step 7, instead of letting it pick from the project’s recent items |
init does not create any pipeline. All authoring happens in boboddy pipelines design. Re-running init on an already-configured project is safe: it re-checks the dev container and offers the handoff again.
init does not analyze the repo. The design agent does that itself, by reading the repository at the start of a session.
boboddy pipelines
Section titled “boboddy pipelines”Manage pipeline and step definitions. All step and pipeline authoring lives inside .boboddy/pipeline-builder/.
boboddy pipelines design [projectId]
Section titled “boboddy pipelines design [projectId]”Design pipelines interactively with an AI agent, then push them. This is the recommended way to author pipelines: it scaffolds whatever is missing, interviews you about your project, writes the definitions, typechecks them, and pushes.
boboddy pipelines designboboddy pipelines design <projectId>| Flag | Description |
|---|---|
--base-url <url> |
Override the API server URL |
--work-item-id <id> |
Design around this specific work item ID instead of picking from the project’s recent items. Wins outright and skips the picker entirely — use it for an item older than the picker’s recent window, or any time you already have the id. An id that does not resolve (wrong id, or belongs to a different project) falls through to the picker, the same as if you had not passed the flag |
Preflight. Every precondition is self-healing except the last one:
| Check | If missing |
|---|---|
| Boboddy session | Runs the device-flow login inline |
| Project ID | Uses the positional argument, else .boboddy/boboddy.jsonc, else matches this repo’s origin remote to a project on the server (creating it when absent) and writes .boboddy/boboddy.jsonc. Only prompts when the repo has no origin remote |
| A work item to design around | With --work-item-id, loads that item directly and skips the picker (falling through to the picker if it doesn’t resolve). Otherwise shows a picker of the project’s most recent ingested items, plus two rungs: search for a different item, which re-queries the project by keyword and shows the matches instead of only the recent window, and paste a link/id, or describe a new one. The latter resolves a pasted work item id or ticket URL against what’s already ingested when it can, and only creates a new item (platform boboddy) when it doesn’t — so pasting a link to an existing ticket finds it instead of duplicating it. Every session designs around a real work item |
.boboddy/pipeline-builder/ |
Scaffolds it (requires a .git or .boboddy directory in the current directory) |
| Dependencies | Installs them with the package manager matching the directory’s lockfile, else bun or npm from your PATH |
| AI runtime | Downloads the pinned OpenCode runtime once (~100 MB, with progress) |
| AI provider credentials | Hard stop. Prints the auth login command for the provisioned runtime and exits |
You do not need OpenCode installed — Boboddy downloads and pins its own runtime. You do need your own provider credentials (an OpenCode auth login, or an env var such as ANTHROPIC_API_KEY). The injected config deep-merges over your global ~/.config/opencode/opencode.json[c] and deliberately omits model, so your configured model and provider are used.
The session. The command launches the OpenCode TUI in .boboddy/pipeline-builder/ with an injected pipeline-designer agent, seeded with the work item you chose. The agent reads what’s already there and orients itself in the repository, then opens on the goal: what should come out the other end when a ticket like this one arrives? Every question after that is asked through that item — what it would take to work it, what the execution environment can reach, what must never be touched — before it proposes 2–3 ranked pipeline archetypes filtered by what’s actually reachable. It builds the one you pick plus default-pipeline-assignment.ts, typechecks, and runs boboddy pipelines push.
Early advisory dry-run. Right after orienting itself in the repository, the agent backgrounds work --dry-run --global-only (container + OpenCode health only — nothing step-specific exists this early, since no pipeline has been pushed yet) and keeps interviewing without waiting on it. It reports what that check found near the end of the session. This is purely advisory: an unresolved failure never stops the session from reaching push.
Post-push blocking dry-run. Before the run offer (below) asks whether to run the pushed pipeline, it resolves the pipeline id to its ordered step list — via work --dry-run --pipeline-id <id>, unambiguous by construction, unlike a step id — and runs the full dry run (container + OpenCode + MCP servers + declared health checks) against the pipeline’s first step only. It never validates every step in one launch; first-step validation is enough to catch an obviously-broken run. A failure here blocks: nothing is queued, and the offer falls back to the same “run it later” messaging as its other gates. There is no live agent left in this session to fix it — the TUI has already exited — so the failure is recorded and surfaces automatically at the start of your next boboddy pipelines design session for that project, before the interview begins.
Edit sessions. When definitions already exist, the agent must state a change-size verdict and get your confirmation before it edits a file: tweak an existing pipeline, add a route in default-pipeline-assignment.ts, or create a new pipeline. It prefers them in that order and escalates only when the cheaper change can’t express the difference, so a second pipeline that duplicates most of an existing one’s steps comes back as a tweak or a route instead. One confirmed change per session is the norm, not a limit.
The devcontainer. If the repository has no .devcontainer/devcontainer.json, the agent writes one mid-session, before it authors any pipeline file, using the orientation it already performed — runtime and version pins, the package manager that owns the lockfile, the services in docker-compose.yml, the install lines in CI. It is write-only: no image is built during the session, and your first pipeline run is what verifies it. The agent says as much when it hands the config over.
Permissions. A design session is supervised — you are watching the TUI — so shell commands run unattended. The agent needs your project’s own toolchain (its test runner, its typecheck script, its linter), and no allowlist can enumerate that in advance. One command is the exception: boboddy pipelines push always prompts, however it is invoked, because that confirmation is the moment anything reaches the server.
Writing is scoped, and that is what contains the session. Reading and searching are unattended repo-wide so the agent can orient itself, but it may only write to .boboddy/pipeline-builder/ and .devcontainer/. Every other path — package.json, your source, CI config — asks first. Network access and subagents ask too.
The run offer. When the session exits cleanly, design closes its own loop: it asks Run your new pipeline on “<work item title>” now?, and on yes it queues a run of the assigned pipeline against that work item and runs the worker in the same terminal. There is no flag to learn.
| Situation | What happens |
|---|---|
| Devcontainer present, pipeline assigned, first step healthy | The confirm appears; accepting queues the run and runs the worker here |
| You decline | Prints boboddy work <projectId> --work-item-id <id> for later, and notes that nothing is queued yet — start a run from the work item in the dashboard and that command picks it up |
No .devcontainer/devcontainer.json |
No offer — steps execute inside your devcontainer, so it prints the devcontainer guidance plus that same command |
| No pipeline assigned to the project | No offer — the session never got as far as pushing one |
| The pipeline’s first step fails its dry run | No offer. Blocking, not advisory: prints why plus the same “run it later” command, and the failure surfaces automatically at the start of your next design session |
| The session did not exit cleanly | No offer. A non-zero designer exit code still passes through |
Before the worker starts, the offer states where a failure goes: back to boboddy pipelines design, to tell the agent what happened. That covers the failures the worker absorbs into its polling loop — a failing step, or a devcontainer that won’t build — which do not stop the worker and so cannot be reported after the fact. The edit loop is the repair loop.
The worker keeps polling until you stop it, because later steps are only queued as earlier ones advance.
Re-run design any time. It reads your existing definitions and iterates instead of starting over, so the same command covers first-time setup and ongoing changes — a new session, a different work item.
An interactive terminal is required — the command errors out under a pipe, redirect, or CI runner.
boboddy pipelines init
Section titled “boboddy pipelines init”Scaffold .boboddy/pipeline-builder/ with a starter package.json, tsconfig.json, and example step and pipeline files, then edit them by hand. Must be run from the root of a git repository. Use boboddy pipelines design unless you specifically want to author everything yourself.
boboddy pipelines initcd .boboddy/pipeline-builder && npm install # or bun/pnpm/yarn installThe scaffolded package.json includes a typecheck script (tsc -p tsconfig.json), so npm run typecheck in that directory validates your definitions before you push.
The scaffolded .gitignore ignores only node_modules/, lockfiles, and push.ts. Your pipeline and step definitions are source code — commit and review them. Lockfiles are deliberately not committed: boboddy pipelines push picks its runtime from whichever lockfile it finds in that directory, so committing one would force every teammate onto the same package manager.
boboddy pipelines pull [projectId]
Section titled “boboddy pipelines pull [projectId]”Fetch pipeline and step definitions from the server and write them into .boboddy/pipeline-builder/ as editable TypeScript files. If the directory already contains files you will be prompted before they are overwritten.
boboddy pipelines pullboboddy pipelines pull <projectId>| Flag | Description |
|---|---|
--base-url <url> |
Override the API server URL |
What gets written:
| File | Description |
|---|---|
package.json |
Declares @boboddy/sdk and zod dependencies (only on first pull) |
tsconfig.json |
TypeScript config scoped to the pipeline-builder package (only on first pull) |
.gitignore |
Ignores node_modules/, lockfiles, and push.ts (only on first pull) |
steps.ts |
One defineStep() export per step definition (latest version of each key) |
<pipeline-key>.ts |
One pipeline export per pipeline (uses the fluent pipeline() builder) |
default-pipeline-assignment.ts |
Project routing policy (written if configured on the server; removed if not) |
After pulling, run npm install or bun install inside .boboddy/pipeline-builder/ to install dependencies.
boboddy pipelines push [projectId]
Section titled “boboddy pipelines push [projectId]”Push step and pipeline definitions from .boboddy/pipeline-builder/ to the server. Steps are pushed first, then pipelines. If default-pipeline-assignment.ts is present it is synced to the server last. Absent files are ignored; they do not clear server configuration.
boboddy pipelines pushboboddy pipelines push <projectId>| Flag | Description |
|---|---|
--base-url <url> |
Override the API server URL |
boboddy work [projectId]
Section titled “boboddy work [projectId]”Run a worker that polls for and executes step jobs.
boboddy workboboddy work <projectId>| Flag | Alias | Default | Description |
|---|---|---|---|
--once |
— | false |
Poll once and wait for any claimed jobs to finish |
--concurrency <n> |
-c |
1 |
Max concurrently active jobs (env: BOBODDY_WORK_CONCURRENCY) |
--batch-size <n> |
-b |
value of --concurrency |
Max step executions claimed per poll |
--lease-duration-seconds <n> |
-l |
30 |
Seconds the claim lease lasts (env: BOBODDY_WORK_LEASE_DURATION_SECONDS) |
--poll-interval-ms <n> |
-p |
5000 |
Milliseconds between poll cycles (env: BOBODDY_WORK_POLL_INTERVAL_MS) |
--worker-id <id> |
-w |
auto | Worker identifier used while claiming steps |
--work-item-id <id> |
— | — | Only process step executions for this work item ID |
--source-branch <branch> |
— | your current local branch | Override the branch checked out for the first step of this run. Defaults to your current local branch, which must exist and be in exact sync with origin (push it first if it isn’t) |
--preserve-runtime-on-complete |
-k |
false |
Keep runtime containers and workspace after step completion |
--dry-run |
— | false |
Rehearse the environment a real step would launch (devcontainer + OpenCode + MCP servers) and report its health instead of running work |
--step-id <id> |
— | — | Dry run only: fetch this step definition’s real MCP servers to test |
--global-only |
— | false |
Dry run only: skip step-specific MCP injection and test whatever is already configured |
--pipeline-id <id> |
— | — | Dry run only: resolve this pipeline definition ID to its first step (by position) and test that — unambiguous by construction, unlike --step-id. Wins over --step-id/--global-only |
boboddy runtime
Section titled “boboddy runtime”Utilities for managing the local execution environment.
boboddy runtime cleanup-networks
Section titled “boboddy runtime cleanup-networks”Remove unused Docker networks created by prior worker runs.
boboddy runtime cleanup-networksboboddy runtime cleanup-networks --verbose| Flag | Description |
|---|---|
--verbose |
Print names of networks as they are removed |
boboddy hello [name]
Section titled “boboddy hello [name]”Print a greeting. Primarily used to verify the CLI is installed correctly.
boboddy hello # Hello, world!boboddy hello Alice # Hello, Alice!boboddy report-bug
Section titled “boboddy report-bug”File a bug report against the CLI. By default it opens a prefilled GitHub issue in your browser.
boboddy report-bugboboddy report-bug --title "..." --description "..." --no-browser| Flag | Default | Description |
|---|---|---|
--title <text> |
— | Short summary of the bug |
--description <text> |
— | Detailed description |
--browser / --no-browser |
true |
Open the prefilled issue in a browser; --no-browser prints the URL only |
boboddy telemetry
Section titled “boboddy telemetry”Manage the CLI’s onboarding-funnel observability reporting. See
Observability for what’s collected and why, the
status/disable/enable subcommands, and the opt-out environment
variables.
Exit codes
Section titled “Exit codes”| Code | Meaning |
|---|---|
0 |
Success |
1 |
General error (check stderr / log output) |