CLI Commands
OpenFlows ships as a single openflows binary. Previous separate binaries such as openflows-setup,
openflows-dashboard, and openflows-doctor have been consolidated into subcommands. The binary is
the only entry point an operator needs to bootstrap the deployment, manage tenants, and run the autonomous orchestrator.
In development, commands are run through Cargo with cargo run -p openflows --bin openflows -- <command>.
In production, the same commands are invoked directly against the compiled binary, typically inside a Docker container or
systemd unit. The behavior is identical.
Each worker workspace receives a small openflows-harness binary. It is the only Redis client in the workspace
and is never invoked by the operator directly. The openflows binary is the operator-facing CLI; the harness is
an implementation detail of the workspace.
Command Overview
| Command | Purpose |
|---|---|
bootstrap | Initialize the deployment, create the admin user, push Coder templates, and verify connectivity. |
tenant add <owner/repo> | Bind a GitHub repository to a new OpenFlows tenant. Creates the tenant namespace and nexus workspace. |
tenant remove <tenant-id> | Remove a tenant and stop all of its workers. |
tenant list | List all configured tenants, repositories, and namespaces. |
run | Start the autonomous orchestrator in daemon mode. This is the default command. |
doctor | Run diagnostics on the environment, registry, and Coder/GitHub connectivity. |
version | Print the OpenFlows version and dependency versions. |
help | Print command or subcommand help. |
Global Flags
These flags are accepted by most openflows subcommands. They control configuration paths, logging, tenant
targeting, and the control-plane API.
| Flag | Purpose |
|---|---|
--config <path> | Path to the orchestrator configuration file. Default orchestration/config.yaml. |
--registry-path <path> | Path to registry.json. Default orchestration/agent/registry.json. |
--tenant <tenant-id> | Run against a specific tenant. Default is the first configured tenant. |
--once | Run a single poll cycle and exit. Useful for cron jobs and testing. |
--dry-run | Do not create PRs, merge, or destroy workspaces. Plan and log actions only. |
--repair | Run NEXUS reconcile and repair broken states. Does not pick up new work. |
--verbose or -v | Enable verbose logging. Equivalent to RUST_LOG=openflows=debug. |
--log-level <level> | Set the log level (trace, debug, info, warn, error). |
--port <port> | Port for the OpenFlows control-plane API. Default 8080. |
--env-file <path> | Load environment variables from an alternate .env file. |
--no-api | Start the orchestrator without exposing the control-plane HTTP API. |
--help | Show help for a command or subcommand. |
bootstrap
openflows bootstrap is the first command you run after starting the infrastructure stack. It creates the
OpenFlows admin user in Coder, pushes the openflows-{role} workspace templates, validates the
.env configuration, and verifies connectivity to Redis, Coder, and the AI Gateway. It is safe to run multiple
times; subsequent runs are idempotent and only update changed templates.
# Development cargo run -p openflows --bin openflows -- bootstrap # Production inside the container openflows bootstrap
Typical output:
[INFO] OpenFlows bootstrap v1.2.0 [INFO] Checking Coder connectivity at https://coder.example.com ... OK [INFO] Checking Redis connectivity at redis://localhost:6379 ... OK [INFO] Creating admin user openflows-admin ... already exists [INFO] Pushing template openflows-forge ... updated [INFO] Pushing template openflows-nexus ... updated [INFO] Pushing template openflows-sentinel ... updated [INFO] Pushing template openflows-vessel ... updated [INFO] Pushing template openflows-lore ... updated [INFO] AI Gateway reachable ... OK [INFO] Bootstrap complete. Run: openflows tenant add owner/repo --name my-team
Re-run after template changes
openflows bootstrap again to push the updated definitions. Existing
running workspaces are not affected; new workspaces will use the updated template.
tenant add
A tenant represents a team working on a specific repository. The tenant add command creates the tenant
record, binds it to a GitHub repository, and provisions a dedicated NEXUS workspace. Each tenant is isolated by Coder RBAC
and a Redis namespace prefix.
# Add a tenant openflows tenant add owner/repo --name my-team # Development cargo run -p openflows --bin openflows -- tenant add owner/repo --name my-team
Available flags for tenant add:
| Flag | Purpose |
|---|---|
--name <tenant-name> | Tenant display name. Used as the Redis namespace and in logs. |
--repository <owner/repo> | GitHub repository. Can be specified as a positional argument instead. |
--coder-user <user> | Coder user that owns the tenant. Default is openflows-nexus. |
--namespace <namespace> | Override the Redis namespace. Default is derived from the tenant name. |
--skip-workspace | Create the tenant record without provisioning the nexus workspace. |
Typical output:
[INFO] Creating tenant my-team for repository owner/repo [INFO] Redis namespace: my-team [INFO] Provisioning nexus workspace for tenant my-team ... workspace-uuid [INFO] Tenant my-team is active
Repository identity is per tenant
--repository argument accepts the owner/repo form. The GitHub identity for that repository
comes from the Coder external auth provider configured for the tenant's Coder user. OpenFlows does not read or store a
GitHub PAT.
tenant remove
tenant remove deletes the tenant record, removes its Redis namespace, and stops any running workers.
Workspaces are destroyed. This action is irreversible, but the underlying GitHub repository and issues are not affected.
# Remove a tenant by ID or name openflows tenant remove my-team # Development cargo run -p openflows --bin openflows -- tenant remove my-team
Destructive operation
tenant remove destroys all active workspaces and pending PRs for the tenant. Any in-flight work will be
interrupted. Use this command only when you are sure the tenant is no longer needed.
tenant list
tenant list prints all configured tenants, their repositories, namespaces, and the number of active
workers. It is a read-only command and can be run safely at any time.
openflows tenant list
ID Repository Namespace Active Workers State -------- ----------------- ---------- --------------- ------- my-team owner/repo my-team 3 active team-b another-org/repo team-b 0 paused
run
openflows run starts the autonomous orchestrator. In daemon mode, it runs the NEXUS poll loop continuously:
discovering issues, assigning workers, provisioning Coder workspaces, running reviews, merging PRs, and tearing down
workspaces. It also starts the control-plane HTTP API on the configured port.
# Start in daemon mode openflows run # Start with verbose logging and a specific tenant openflows run --tenant my-team --verbose # Single-shot mode for cron or GitHub Actions openflows run --once # Dry run to test the flow without modifying GitHub openflows run --dry-run # Repair mode to reconcile broken state openflows run --repair
Run Modes
| Mode | Command | Purpose |
|---|---|---|
| Daemon | openflows run | Continuously polls for issues, assigns workers, and manages the full lifecycle. Default mode. |
| Single-shot | openflows run --once | Runs one poll cycle, processes any ready work, and exits. Good for cron or GitHub Actions. |
| Dry run | openflows run --dry-run | Plans actions but does not modify GitHub, merge code, or destroy workspaces. |
| Repair | openflows run --repair | Runs NEXUS reconcile to fix orphaned tickets, stale workers, and unmerged PRs. |
| No API | openflows run --no-api | Runs the orchestrator loop without starting the HTTP control-plane server. |
--once and --repair are mutually exclusive
--once processes new work for a single cycle. --repair only reconciles existing state. Use them
separately; combining them produces an error.
doctor
openflows doctor runs a suite of diagnostics. It checks the .env file, parses the registry,
verifies Coder and GitHub connectivity, and reports any misconfigurations. It does not modify state.
# Full diagnostic suite openflows doctor # Check only the registry openflows doctor registry # Check only Coder connectivity openflows doctor coder
Doctor is read-only
openflows doctor never provisions workspaces, opens PRs, or deletes data. It is safe to run in production to
verify the environment.
version
openflows version prints the binary version, the Coder SDK version, the Rust toolchain version used at build
time, and the enabled feature flags. It is useful for debugging compatibility issues.
openflows version
OpenFlows v1.2.0 Coder SDK: v2.x Rust toolchain: 1.82 Features: litellm_fallback, redis_sharedstore, coder_gateway Registry schema: v2
update-binaries.sh
./update-binaries.sh is the development helper for keeping the compiled binaries in sync with the Coder
templates and workspace images. It builds the openflows and openflows-harness binaries in release
mode, then copies them into the template directories so that newly provisioned workspaces receive the latest code.
The script is typically run after pulling new code, after modifying workspace logic, or before testing a change against a real workspace.
# Rebuild and update all binaries and templates ./update-binaries.sh # The script performs roughly: # 1. cargo build --release -p openflows -p openflows-harness # 2. cp target/release/openflows orchestration/templates/bin/ # 3. cp target/release/openflows-harness orchestration/templates/bin/ # 4. docker compose build (if running in Docker)
Restart after updating binaries
./update-binaries.sh, restart the orchestrator container or process so that the new
openflows binary is used. Existing running workspaces continue with their old harness binary until they are
torn down; new workspaces will pick up the updated one.
Development Commands
Most development workflows use cargo run to invoke the openflows binary directly from the Rust
workspace. The following commands are the ones you will use most often.
| Command | Purpose |
|---|---|
./update-binaries.sh | Rebuild the orchestrator and openflows-harness binaries, then copy them into the Coder templates and workspace images. |
cargo run -p openflows --bin openflows -- bootstrap | Run the bootstrap command from the workspace in development. |
cargo run -p openflows --bin openflows -- tenant add owner/repo --name my-team | Add a tenant from the development workspace. |
cargo run -p openflows --bin openflows -- run --verbose | Start the orchestrator in development with verbose logging. |
cargo test | Run the full Rust test suite. |
cargo build --release | Build the release binary for production deployment. |
cargo clippy | Run the Clippy linter. |
cargo fmt | Format the Rust codebase. |
# Common development workflow cargo run -p openflows --bin openflows -- bootstrap cargo run -p openflows --bin openflows -- tenant add my-org/my-repo --name my-team cargo run -p openflows --bin openflows -- run --verbose # After making changes to the harness or orchestrator ./update-binaries.sh cargo run -p openflows --bin openflows -- doctor
Cargo vs. binary
cargo run -p openflows --bin openflows -- <command> is identical to
openflows <command> after the binary is installed. The only difference is that Cargo rebuilds the
binary when source files have changed.
Complete Example
The following command sequence brings up a full OpenFlows deployment from a fresh clone. It assumes Docker Compose is
running and the .env file is configured.
# 1. Start the infrastructure stack -docker compose up -d # 2. Bootstrap OpenFlows cargo run -p openflows --bin openflows -- bootstrap # 3. Add a tenant cargo run -p openflows --bin openflows -- tenant add owner/repo --name my-team # 4. Start the orchestrator cargo run -p openflows --bin openflows -- run --verbose # 5. After code changes, rebuild and update binaries ./update-binaries.sh
Once the orchestrator is running, create a GitHub issue in the configured repository. NEXUS will detect it on the next poll cycle and the autonomous team will take over.