korbo-cli
v0.1.1
Published
Korbo CLI — run a self-hosted (bring-your-own-machine) opencode session and register it with Korbo.
Maintainers
Readme
korbo CLI
Run a self-hosted ("bring-your-own-machine") opencode session and register it with Korbo.
korbo turns your own machine into the compute for a Korbo session. It:
- signs you in to Korbo with GitHub (OAuth device flow, so it works over SSH / headless);
- starts a local
opencode serveprotected by an auto-generated secret; - opens a
cloudflaredtunnel to give it a public HTTPS URL; and - registers the session with the Korbo backend so it shows up in the Korbo app.
Because the compute is your own machine, these sessions are free — no Korbo credits are used.
Prerequisites
The CLI orchestrates two external programs. Install both before running korbo up:
| Tool | Why | Install |
| --- | --- | --- |
| opencode (>= 1.14) | the agent server that runs on your machine | curl -fsSL https://opencode.ai/install \| bash — see the opencode docs |
| cloudflared | exposes the local server over a public HTTPS tunnel | macOS: brew install cloudflared · Linux: see the cloudflared downloads |
korbo up checks for both up front and prints install hints if either is missing.
For development you also need Bun (>= 1.3).
Install
From npm
npm install -g korbo # or: bun add -g korbo
korbo --helpThe published package is a Bun-targeted bundle (its entry point is
#!/usr/bin/env bun), so Bun must be installed to runkorbo. This keeps the npm package tiny (~28 kB) and cross-platform, rather than shipping a per-OS compiled binary.
Prebuilt binary (no Bun required)
Each release attaches standalone executables for Linux, macOS, and Windows (x64/arm64) to its GitHub Release. The Bun runtime is embedded, so these run with no Bun install:
# macOS/Linux — pick the asset matching your OS/arch
curl -L -o korbo https://github.com/darylcecile/korbo-cli/releases/latest/download/korbo-darwin-arm64
chmod +x korbo && mv korbo /usr/local/bin/korboOn Windows, download korbo-windows-x64.exe, rename it to korbo.exe, and put it on your
PATH. Verify any download against the release's SHA256SUMS.txt.
From source (build a single-file binary)
This produces a standalone executable that does not require Bun at runtime:
bun install
bun run compile # produces ./dist/korbo
# put it on your PATH, e.g.
mv dist/korbo /usr/local/bin/korboRun without compiling
bun install
bun run dev -- <command> # e.g. bun run dev -- statusUsage
korbo login Sign in to Korbo with GitHub (device flow)
korbo logout Remove the stored Korbo credentials
korbo up | start Start opencode + a cloudflared tunnel and register the session
korbo down | stop Stop the session started by this CLI
korbo status Show the local session and registered sessions
korbo --help | --versionkorbo login
Starts the GitHub device flow. The CLI prints a short user code and a verification URL
(the Korbo dashboard /cli page) and, unless you pass --no-browser, opens it for you. Approve
the code in the browser and the CLI stores your token.
korbo login # opens the browser automatically
korbo login --no-browser # print the URL/code only (good for SSH)The token is stored in your OS keychain when available (macOS security, Linux secret-tool),
otherwise in ~/.config/korbo/config.json with 0600 permissions.
korbo up (alias start)
Runs the full flow in the foreground with live status output. Press Ctrl+C once to shut
down cleanly (it deregisters the session and stops both child processes); press it twice to
force-kill immediately.
korbo up
korbo up --repo owner/name --name "my laptop"
korbo up --port 4096| Flag | Description |
| --- | --- |
| --repo <owner/name> | associate the session with a repository |
| --name <label> | a human-friendly label shown in the Korbo app |
| --port <port> | local port for opencode (default: a free port is chosen) |
| --named-tunnel <name> | use a pre-configured cloudflared named tunnel instead of a quick tunnel |
| --tunnel-url <url> | the public HTTPS URL of your named tunnel (required with --named-tunnel) |
By default a Cloudflare quick tunnel (*.trycloudflare.com) is created automatically. To use a
named tunnel,
configure it in cloudflared yourself and pass both --named-tunnel and --tunnel-url.
korbo down (alias stop)
Stops the session started by this CLI on this machine (deregisters it and tears down the opencode + cloudflared processes). Safe to run from another terminal.
korbo status
Shows the locally running session (if any) and the list of sessions registered to your account from the backend.
Configuration
| Env var | Default | Description |
| --- | --- | --- |
| KORBO_API | https://my.korbo.app/api | Korbo API base URL. Accepts a bare host (e.g. staging.korbo.app), an origin, or a full base path. |
| XDG_CONFIG_HOME | ~/.config | Base directory for korbo/ config + runtime state. |
State files (under $XDG_CONFIG_HOME/korbo/):
config.json— stored user + fallback token (0600).runtime.json— describes the running session fordown/status(0600).
How the session is secured
opencode's server is protected with HTTP Basic Auth. On korbo up the CLI generates a strong
random secret (32 bytes) and starts opencode with OPENCODE_SERVER_PASSWORD=<secret> (username
opencode). Every request to the public tunnel — REST and the SSE event stream — must present
that credential, which is registered with the Korbo backend so its proxy can authenticate on your
behalf. The secret never leaves your machine except in the registration call to Korbo.
Development
bun install
bun run typecheck # tsc --noEmit
bun run lint # biome check
bun run lint:fix # biome check --write
bun test # unit tests
bun run compile # build ./dist/korboTroubleshooting
- "opencode is not installed" / "cloudflared is not installed" — install the missing tool (see Prerequisites) and re-run.
- "You are not signed in" — run
korbo login. - "Your session has expired" — run
korbo loginagain to refresh the token. - Tunnel host rejected — the backend only accepts
*.trycloudflare.comand*.cfargotunnel.comhosts. With--named-tunnel, make sure--tunnel-urlpoints at a Cloudflare tunnel hostname. - A session is already running —
korbo upallows one local session per machine; runkorbo downfirst.
Releasing (maintainers)
Releases publish to npm automatically via GitHub Actions using
npm OIDC Trusted Publishing — there is no
NPM_TOKEN secret. The .github/workflows/publish.yml
workflow runs on every push to main that touches package.json; it typechecks, lints, tests,
builds, and then publishes only if the version in package.json is not already on npm.
To cut a release, just bump the version on main:
npm version patch # or minor / major — commits the bump
git push origin mainThe workflow detects the new version and publishes it (with build provenance attached automatically).
The same version bump also triggers .github/workflows/release.yml,
which cross-compiles standalone executables for Linux, macOS, and Windows (x64/arm64) and
attaches them, plus a SHA256SUMS.txt, to a v<version> GitHub Release. These binaries embed
the Bun runtime, so end users can run them without installing Bun. The release job is gated on
the tag not already existing, so re-runs are safe. No secrets are required (it uses the built-in
GITHUB_TOKEN). You can also build the current version's release on demand from the Actions tab
via Run workflow.
One-time setup on npmjs.com
Trusted publishing must be authorized once before the first automated publish:
- Requires npm CLI >= 11.5.1 and Node >= 22.14.0 (the workflow provisions both).
- The package's
repository.urlinpackage.jsonmust exactly match the GitHub repo (already set). - On npmjs.com, open the package's Settings → Trusted Publisher,
choose GitHub Actions, and enter:
- Organization or user:
darylcecile - Repository:
korbo-cli - Workflow filename:
publish.yml - Allowed actions: select
npm publish(required, or OIDC will match the workflow but still be unauthorized to publish).
- Organization or user:
- Bootstrapping a brand-new package name: npm configures trusted publishing on an existing
package's settings page. For the very first publish of a name that doesn't exist on npm yet,
either run a one-time manual
npm publishfrom a maintainer machine, or publish once with a short-lived granular token, then add the trusted publisher so all subsequent releases are token-free.
After setup, optionally harden the package under Settings → Publishing access by selecting "Require two-factor authentication and disallow tokens" — trusted publishing keeps working because it uses OIDC, not tokens.
License
MIT
