Problem
Day-to-day interaction with Bugpunch happens through the web dashboard (issues / chat / agents / devices / builds / scripts). For workflows where a CLI fits the muscle memory better — scripted issue triage, CI status checks, chat-from-terminal, log tailing during a debug session — there's nothing today. The existing cli/ directory under server/sdk/cli/ is the test-runner CLI bridge, not a general-purpose Bugpunch CLI.
gh is the obvious analogue. Single binary, subcommand structure, auth via gh auth login (browser OAuth or token paste), JSON output mode, scripting-friendly exit codes. Mirror that shape so the learning curve for anyone already using gh is zero.
Proposal
Ship a new bpunch binary (separate repo OR tools/bpunch/) that wraps the existing dashboard API surface as gh-style subcommands.
Core commands (v1)
bpunch auth login # OAuth browser flow OR `--with-token`
bpunch auth status # show logged-in user + active org
bpunch project list # list projects in active org
bpunch project switch <id|name> # set active project (cached in ~/.bpunch/config.yml)
bpunch issue list # crashes / exceptions / ANRs / user reports
--status open|resolved|all
--type crash|exception|anr|bug
--since 7d
--json
bpunch issue view <id>
bpunch issue resolve <id> --version <changeset> --comment "<msg>"
bpunch issue comment <id> --body "..."
bpunch issue assign <id> --user <email>
bpunch issue link <id> --task <task-short-id>
bpunch chat list # devices with active chat threads
bpunch chat send <device> --body "..." # post a dev-side chat message
bpunch chat tail <device> # follow new messages (long-poll)
bpunch device list # SDK-connected devices
bpunch device debug <id> # trigger debug-session upgrade (the dashboard's "Connect" button)
bpunch device logs <id> --follow # tail live log session
bpunch build list
bpunch build upload <path/to/apk> --version <v> --notes "..."
bpunch build download <id>
bpunch script run <device> --file foo.cs # ScriptRunner via chat-script flow
bpunch script result <message-id> # poll for a previously-sent script's result
bpunch task list # tasks in active project
bpunch task view <short-id>
bpunch task create --title "..." --body "..."
Cross-cutting
--json flag everywhere outputs the raw API response so shell pipelines work (bpunch issue list --json | jq '.[].id').
--org <id> / --project <id> flag overrides the cached active context per-call.
bpunch help <command> prints subcommand help, mirrors gh help.
- Exit codes:
0 success, 1 error, 4 auth needed (so CI can branch on bpunch auth status; if [ $? -eq 4 ]; then ...).
Auth model
Two flows, same as gh:
- Browser OAuth (
bpunch auth login): opens https://bugpunch.com/auth/cli in a browser, runs a local callback server, captures the token, writes to ~/.bpunch/auth.json (mode 0600). Server side: dashboard adds a CLI-auth landing page that mints a long-lived token scoped to the user's accessible orgs.
- Token paste (
bpunch auth login --with-token < token.txt): for CI / headless. Token comes from the dashboard's API Keys page (existing surface).
Implementation notes
- Language: TypeScript / Node, distributed as a single-file binary via
pkg or bun build --compile. Matches the existing server/agent/node/ and server/agent/unity-editor/ toolchain. Avoids requiring devs to install Go / Rust / .NET locally.
- Repo location: prefer a new
oddgames/bpunch-cli repo so it can ship its own release cadence (brew install bpunch, GitHub Releases binaries, npm package) without dragging the SDK or server release schedule. Source could initially live under server/cli/ for fast iteration before extraction.
- API surface: hits the same
/api/... routes the dashboard uses (DASHBOARD_PATHS in server/server/src/routes/paths.ts). Versioning: pin to the v1 namespace where it exists (chat, sessions, issues ingest); fall back to unversioned dashboard routes for everything else with the understanding that those can rename until a bpunch release locks them.
- Output formatting:
gh's pattern of "human-readable table by default, JSON via --json, custom template via --template" is the right shape. Use a small table renderer (cli-table3 or roll own).
Out of scope for v1
- Plugin system (
gh extension install ...-style). Worth doing if the CLI takes off; not for the first cut.
bpunch as the install transport for the SDK itself (separate concern from runtime telemetry).
- Editor / IDE integrations (
bpunch repl, autocomplete generators) — phase 2.
Why now
- Issue triage during incident response is faster from a terminal than a browser (especially when you're already in a tmux session looking at logs).
- CI workflows want a stable surface for build upload + smoke-test result posting that isn't curl + raw JSON; right now
server/sdk/cli/ is too narrow (test-runner only).
- Fits the muscle memory ODD Games already has from
gh — minimal cognitive switching cost.
Risks / dependencies
- Dashboard needs the
auth/cli OAuth landing page (small, ~100 LOC of React + a server endpoint that mints a CLI token).
- Need to design the long-lived CLI token's scope (read-only vs full) + revocation UX (Settings → API Keys page already supports per-key revocation; the CLI flow can land on the same page).
- Long-poll endpoints for
chat tail / device logs --follow may need to be added (server today serves these via WebSocket; CLI can either subscribe to the WS or hit a long-poll variant — design call when picked up).
Problem
Day-to-day interaction with Bugpunch happens through the web dashboard (issues / chat / agents / devices / builds / scripts). For workflows where a CLI fits the muscle memory better — scripted issue triage, CI status checks, chat-from-terminal, log tailing during a debug session — there's nothing today. The existing
cli/directory underserver/sdk/cli/is the test-runner CLI bridge, not a general-purpose Bugpunch CLI.ghis the obvious analogue. Single binary, subcommand structure, auth viagh auth login(browser OAuth or token paste), JSON output mode, scripting-friendly exit codes. Mirror that shape so the learning curve for anyone already usingghis zero.Proposal
Ship a new
bpunchbinary (separate repo ORtools/bpunch/) that wraps the existing dashboard API surface asgh-style subcommands.Core commands (v1)
Cross-cutting
--jsonflag everywhere outputs the raw API response so shell pipelines work (bpunch issue list --json | jq '.[].id').--org <id>/--project <id>flag overrides the cached active context per-call.bpunch help <command>prints subcommand help, mirrorsgh help.0success,1error,4auth needed (so CI can branch onbpunch auth status; if [ $? -eq 4 ]; then ...).Auth model
Two flows, same as
gh:bpunch auth login): openshttps://bugpunch.com/auth/cliin a browser, runs a local callback server, captures the token, writes to~/.bpunch/auth.json(mode 0600). Server side: dashboard adds a CLI-auth landing page that mints a long-lived token scoped to the user's accessible orgs.bpunch auth login --with-token < token.txt): for CI / headless. Token comes from the dashboard's API Keys page (existing surface).Implementation notes
pkgorbun build --compile. Matches the existingserver/agent/node/andserver/agent/unity-editor/toolchain. Avoids requiring devs to install Go / Rust / .NET locally.oddgames/bpunch-clirepo so it can ship its own release cadence (brew install bpunch, GitHub Releases binaries, npm package) without dragging the SDK or server release schedule. Source could initially live underserver/cli/for fast iteration before extraction./api/...routes the dashboard uses (DASHBOARD_PATHSinserver/server/src/routes/paths.ts). Versioning: pin to thev1namespace where it exists (chat, sessions, issues ingest); fall back to unversioned dashboard routes for everything else with the understanding that those can rename until abpunchrelease locks them.gh's pattern of "human-readable table by default, JSON via--json, custom template via--template" is the right shape. Use a small table renderer (cli-table3or roll own).Out of scope for v1
gh extension install ...-style). Worth doing if the CLI takes off; not for the first cut.bpunchas the install transport for the SDK itself (separate concern from runtime telemetry).bpunch repl, autocomplete generators) — phase 2.Why now
server/sdk/cli/is too narrow (test-runner only).gh— minimal cognitive switching cost.Risks / dependencies
auth/cliOAuth landing page (small, ~100 LOC of React + a server endpoint that mints a CLI token).chat tail/device logs --followmay need to be added (server today serves these via WebSocket; CLI can either subscribe to the WS or hit a long-poll variant — design call when picked up).