@bugmojo/cli
Turn a captured BugMojo bug into a runnable Playwright repro, verify the fix against a real deploy, and brief an AI agent — from your terminal or CI.

Why
BugMojo captures bugs with full context — an rrweb session recording, console logs, and network requests. This CLI closes the verified loop: it compiles that capture into an executable @playwright/test spec (via BugMojo's server-side repro compiler), runs it against your patched build, and reports the result — a bug is only verified fixed when its own repro passes. There is no BugMojo-hosted browser runner: your machine or CI runs the test, exactly like the rest of your suite.
bugmojo repro <bug-key> # pull + write the Playwright spec, logs, localization
bugmojo verify <bug-key> --url URL # run the repro locally; exit 0 pass / 1 fail
bugmojo fix <bug-key> # print an agent-ready prompt to paste into an AI IDE
bugmojo run [playwright args] # run your Playwright suite, record results + evidence
bugmojo init # teach every coding agent in this repo about BugMojo
Install
Run it ad-hoc with npx (no install):
npx @bugmojo/cli --help
…or add it to a project:
pnpm add -D @bugmojo/cli
npm install --save-dev @bugmojo/cli
yarn add -D @bugmojo/cli
Only verify needs a browser. @playwright/test is an optional peer
dependency — install it in the project you run verify from:
pnpm add -D @playwright/test
npx playwright install chromium
Quickstart
export BUGMOJO_API_TOKEN="bm_key_xxxxxxxxxxxxxxxxxxxx"
npx @bugmojo/cli repro WEB-42
npx @bugmojo/cli fix WEB-42 | pbcopy
npx @bugmojo/cli verify WEB-42 --url https://preview.example.com --report
Features
- One-command repro — a self-contained, runnable
@playwright/test project written to disk from a bug key.
- Real verification — the repro runs on your build with your Playwright install; exit
0/1 so CI can gate merges on it.
- CI status reporting —
verify --report flips the bug DEV_TESTING → VERIFIED_FIXED (pass) or REOPENED (fail) via the CI verify webhook.
- Agent-ready prompts —
fix renders goal + localization + error signals + the failing spec, ready to paste into Claude Code or Cursor.
- Secrets stay secret — config is env-only, and the server-provided spec runs in a temp project with a minimal allow-listed environment;
BUGMOJO_API_TOKEN / BUGMOJO_CI_SECRET are never forwarded to the spec process.
- Embeddable —
import { run } from '@bugmojo/cli' exposes the dispatcher and pure helpers with no side effects at import time.
Configuration (environment)
BUGMOJO_API_TOKEN | repro/verify/fix/run | A bm_key_… API key (Dashboard → Settings → API Keys). Sent as a Bearer token. init never needs it. |
BUGMOJO_API_URL | no | BugMojo base URL. Default https://www.bugmojo.com (hosted). Set your self-hosted URL, or http://localhost:3000 for local development. |
BUGMOJO_CI_SECRET | only for --report | Shared secret for the CI verify webhook (must match the deployment's CI secret). |
No secret is ever written to disk or embedded in output — everything is read
from the environment at runtime. You can also pass --token / --api-url as flags.
Commands
bugmojo repro <bug-key>
Pulls the repro pack for a bug and writes a self-contained repro directory.
bugmojo repro WEB-42
bugmojo repro WEB-42 --out ./repros
bugmojo repro WEB-42 --json
bugmojo repro WEB-42 --force
-o, --out <dir> | Output directory (default ./bugmojo-repro/<bug-key>). |
--force | Overwrite existing files in the output dir. |
--json | Print the raw repro pack JSON to stdout instead of writing files. |
Writes:
<slug>.spec.ts | The executable @playwright/test spec. |
logs.md | Errors-first console + network signals. |
localization.md | React component + candidate source files for the fix. |
pack.json | The raw repro pack (machine-readable). |
README.md | How to run it. |
bugmojo verify <bug-key> --url <deployed-url>
Runs the bug's repro spec locally with your @playwright/test install against
--url (which becomes Playwright's baseURL). Prints pass/fail and exits 0
on pass, 1 on fail so CI can gate on it.
bugmojo verify WEB-42 --url https://preview.example.com
bugmojo verify WEB-42 --url https://preview.example.com --json
bugmojo verify WEB-42 --url https://preview.example.com --report
-u, --url <url> | Deployed URL to run the repro against (sets Playwright's baseURL). |
--report | POST the pass/fail result to the CI verify webhook (needs BUGMOJO_CI_SECRET). |
--keep | Keep the temp Playwright project dir (debugging). |
--json | Also print the raw run result as JSON. |
With --report (and BUGMOJO_CI_SECRET set) the result is POSTed to BugMojo's
CI verify webhook, which flips the bug's status:
DEV_TESTING → VERIFIED_FIXED on pass, DEV_TESTING → REOPENED on fail.
A skipped-only or empty run is not a pass — at least one test must actually
execute and pass, so a bug is never marked verified by a repro that didn't run.
bugmojo fix <bug-key>
Prints an agent-ready prompt bundle — goal, localization, error signals, and the
failing spec — ready to paste into Claude Code / Cursor.
bugmojo fix WEB-42
bugmojo fix WEB-42 --out prompt.md
bugmojo fix WEB-42 | pbcopy
bugmojo fix WEB-42 | clip
bugmojo fix WEB-42 | Set-Clipboard
bugmojo fix WEB-42 | xclip -sel clipboard
-o, --out <file> | Write the prompt to a file instead of stdout. |
bugmojo run [playwright args]
Runs your project's Playwright suite (playwright test, resolved from the
current project) and records the results in BugMojo, so a test run is never
just a claim in a chat window.
bugmojo run
bugmojo run --url https://preview.example.com
bugmojo run --project WEB --plan-version pv_1
bugmojo run --dry-run
bugmojo run -- --grep @smoke --workers=2
-u, --url <url> | Base URL for the run (PLAYWRIGHT_BASE_URL); recorded as the run's deploy_url. |
--project <key> | BugMojo project key to record against. |
--suite <id> | Regression suite id to attach the run to. |
--plan-version <id> | Test plan version the run executes. |
--commit <sha> | Commit SHA (default: GITHUB_SHA / VERCEL_GIT_COMMIT_SHA / ..., then git rev-parse HEAD). |
--deploy-url <url> | Deploy URL recorded on the run (default: --url). |
--dry-run | Run the tests, print the payload, do not send it. |
--no-record | Run the tests, do not send results. |
--json | Also print the payload that was sent. |
How a test maps to a BugMojo test case (first match wins):
- a Playwright annotation:
test.info().annotations.push({ type: 'bugmojo', description: 'WEB-42' })
- a title tag
test('[WEB-42] double click does not duplicate', ...) or the tag @WEB-42
- the spec file name:
tests/bugmojo/WEB-42.spec.ts
When playwright.config.* already lists @bugmojo/playwright-reporter (see
bugmojo init), run does not pass --reporter (a CLI reporter flag
would replace yours and silence it) and lets the reporter record results and
upload trace / video / screenshots itself. Otherwise run adds the JSON
reporter, maps the report and POSTs it to POST /api/v1/test-runs/results.
Recording problems are printed as warnings; the exit code always reflects
Playwright's own result.
bugmojo init
Teaches every coding agent that opens this repository about BugMojo. Writes a
managed block (<!-- bugmojo:start --> ... <!-- bugmojo:end -->) into:
AGENTS.md | Codex, Cursor, Copilot, Gemini, Windsurf |
CLAUDE.md | Claude Code |
.github/copilot-instructions.md | GitHub Copilot |
.cursor/rules/bugmojo.mdc | Cursor (rule with frontmatter) |
GEMINI.md | Gemini CLI |
and adds ['@bugmojo/playwright-reporter'] plus trace: 'retain-on-failure',
video: 'retain-on-failure', screenshot: 'only-on-failure' to
playwright.config.* (created from a template when the project depends on
@playwright/test but has no config yet).
bugmojo init
bugmojo init --workspace acme --project WEB
bugmojo init --only claude,playwright
bugmojo init --dry-run
--workspace <slug> | Pin the hosted MCP URL to a workspace (?workspace=...). |
--project <key> | Mention the BugMojo project key in the block. |
--mcp-url <url> | Override the hosted MCP URL entirely. |
--api-url <url> | BugMojo base URL (default https://www.bugmojo.com). |
--only <list> | Comma list of agents,claude,copilot,cursor,gemini,playwright. |
--playwright | Create playwright.config.ts even if @playwright/test is not a dependency. |
--skip-playwright | Leave playwright.config.* alone. |
--client <name> | Force the printed next step for one client instead of detecting it: claude, codex, cursor, copilot, gemini, windsurf. |
--dry-run | Show what would change without writing. |
Guarantees:
- Idempotent. Running it twice produces byte-identical files; the second
run reports
unchanged for everything.
- Yours stays yours. Everything outside the markers is preserved verbatim
(CRLF files stay CRLF). A newer block template replaces only the managed
region. In
playwright.config.* an existing trace / video /
screenshot choice is respected; only missing keys are added.
- Offline.
init needs no API token and never touches the network.
- Tells you what to do next. It detects which coding agent is running it
(from the environment —
CLAUDECODE, CURSOR_TRACE_ID, CODEX_SANDBOX,
GEMINI_CLI, TERM_PROGRAM, ...) and prints the connect + login command for
that client. --client <name> overrides the guess; when nothing matches it
prints the neutral instructions, including the headless
Authorization: Bearer bm_key_... path.
bugmojo help [command] / bugmojo version
help shows the top-level screen or one command's help (-h/--help work
everywhere); version (or -v/--version) prints the CLI version.
CI: verify a fix on every preview deploy
name: Verify bug fix
on:
workflow_dispatch:
inputs:
bug_key:
description: "BugMojo bug key (e.g. WEB-42)"
required: true
preview_url:
description: "Deployed preview URL"
required: true
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install @bugmojo/cli @playwright/test
- run: npx playwright install --with-deps chromium
- run: npx bugmojo verify "${{ inputs.bug_key }}" --url "${{ inputs.preview_url }}" --report
env:
BUGMOJO_API_TOKEN: ${{ secrets.BUGMOJO_API_TOKEN }}
BUGMOJO_CI_SECRET: ${{ secrets.BUGMOJO_CI_SECRET }}
The job fails when the repro fails (exit 1), and --report flips the bug's
status in BugMojo either way.
API contract consumed
GET /api/v1/bugs/{bug-key}/repro → { issue_id, bug_key, repro_pack }
(auth: Authorization: Bearer $BUGMOJO_API_TOKEN). Backed server-side by the
same compiler path as the get_repro_pack MCP tool. {bug-key} accepts the
human key (WEB-42) or the raw issue id.
POST /api/webhooks/ci (auth: X-CI-Secret: $BUGMOJO_CI_SECRET) — used by
verify --report. Body: { bug_key, passed, proof_url? } (the --url you
verified against is sent as the proof link).
POST /api/v1/test-runs/results (auth: Bearer) — used by bugmojo run when
@bugmojo/playwright-reporter is not configured. Body: the run-results
payload (RecordRunResultsRequest: runner, commit, deploy URL, per-test
status / duration / retries / error / attachments and the resolved test-case
key). Reply: { run_id, url?, result_ids?, evidence_upload_slots? }.
ESM-only. The CLI requires Node >= 20 and ships native ES modules. The
bugmojo bin works everywhere; programmatic consumers on CommonJS should use
dynamic import('@bugmojo/cli') (or Node >= 20.19, where require(esm) works).
Exit codes
0 | Success (or repro passed for verify). |
1 | Runtime failure (or repro failed for verify). |
2 | Usage error (missing bug key / unknown command). |
Troubleshooting / FAQ
"Missing API token" error.
Set BUGMOJO_API_TOKEN to a bm_key_… key from your BugMojo dashboard
(Settings → API Keys), or pass --token. Keys must start with bm_key_.
"@playwright/test is not installed in this project" when running verify.
verify uses the Playwright install of the directory you run it from. Fix:
pnpm add -D @playwright/test && npx playwright install chromium. repro and
fix never need a browser.
verify reports "No tests executed (all skipped)".
A skipped/empty run is deliberately treated as a failure — otherwise a repro
that never ran could mark a bug verified. Check the spec (run with --keep to
inspect the temp project) and make sure --url points at a reachable build.
I'm self-hosting BugMojo / developing locally.
Set BUGMOJO_API_URL to your deployment's base URL (e.g.
https://bugs.your-company.com or http://localhost:3000). The default is the
hosted instance at https://www.bugmojo.com.
"The repro pack response is missing a script".
The bug has no session recording to compile into a repro. Capture the bug with
the BugMojo browser extension (which records the session) and try again.
Related packages
License
MIT © Softech Infra
— docs & issues at viveksinra/bugmojo-sdk.