Running the CLI locally
The cihub CLI ships with Companion Hub. This page covers running it from a source checkout while you work on it β for everyday use of the packaged binary, see the CLI Reference.
Set up your checkout first β Running locally covers cloning, dependencies, and environment.
How cihub runs from source
The cihub binary is declared in the repository root package.json as bin: { "cihub": "./bin/cihub.cjs" }. That entry point launches scripts/start.ts through tsx, so it always runs your working-tree TypeScript β there is no build step between an edit and the next invocation.
That means a checkout gives you a working cihub as soon as dependencies are installed. The install needs no GitHub token:
pnpm install./bin/cihub.cjs --helpSee Running locally for the rest of the setup.
The Companion Hub repository uses pnpm (packageManager: pnpm@11.5.1,
Node 22+). It is not the same toolchain as this docs site.
The iteration loop
Use this loop when changing CLI or wizard behaviour. Because ./bin/cihub.cjs runs the working tree through tsx, every edit is live on the next invocation:
flowchart LR
e["Edit working-tree<br/>TypeScript"] --> r["./bin/cihub.cjs <command><br/>tsx β scripts/start.ts"]
r --> w{"Changing the<br/>wizard?"}
w -->|"Yes"| s["cihub reset local --yes<br/>move .env.local aside"]
s --> z["cihub wizard"]
w -->|"No"| t
z --> t["pnpm run test:cli"]
t -->|"iterate"| e
t -->|"ship"| b["pnpm run build:cli<br/>standalone binary"]
click b "#building-the-standalone-binary"Run the command you changed
./bin/cihub.cjs --helpMost CLI changes β help text, argument parsing, status output β show up without starting a stack. Run the command directly after each edit.
Clear local runtime state
cihub reset local --yesRemoves installed apps, containers, volumes, and the local data folder. It leaves .env.local in place, and the wizard treats a missing .env.local as a first run. To see the first-run flow, move .env.local aside before you run cihub wizard.
Exercise the interactive flow
cihub wizardThe wizard needs an interactive terminal. With no .env.local, it runs the first-time setup experience, which is where most CLI and TUI changes show up. In the local environment it ends by starting the backend and frontend from source in that terminal β PostgreSQL and RabbitMQ in Docker, the dashboard at http://localhost:5005, and the API at http://localhost:5004 β with no Docker image rebuild between edits. The backend needs the required values from .env.local β see Create your env file β so without it, use first-run mode only to exercise the wizardβs screens. With .env.local in place, the wizard shows the returning-user action menu instead.
To start the same stack without the wizard, run cihub up local. It also stays in the foreground, so use a second terminal for other commands.
Run the CLI test suite
pnpm run test:cliVitest suite covering the banner, step renderer, first-run detection, argument validation, wizard selectors, and help output.
Building the standalone binary
To produce the packaged executable that ships inside the desktop app, install BunΒ first β the build compiles the CLI with bun build. Then run:
pnpm run build:cliThe executable is written to dist/cli/ as cihub-<platform>-<arch>, for example cihub-linux-x64. Pass --target <target> to node scripts/build-standalone-cli.cjs to build for a different platform.
Hubβs own
docs/CLI.md
is the authoritative reference for CLI internals and is kept alongside the
code. Hubβs default branch is dev.