@bugmojo/cli
v0.1.0
Published
BugMojo CLI — pull a bug's Playwright repro pack, verify a fix locally, and generate an agent-ready fix prompt.
Maintainers
Readme
@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 BugMojoInstall
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/cliOnly 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 chromiumQuickstart
# 1. Get an API key: BugMojo Dashboard → Settings → API Keys (starts with bm_key_)
export BUGMOJO_API_TOKEN="bm_key_xxxxxxxxxxxxxxxxxxxx"
# 2. Pull the repro pack for a bug:
npx @bugmojo/cli repro WEB-42
# → ./bugmojo-repro/WEB-42/ (spec, logs.md, localization.md, pack.json, README.md)
# 3. Hand the fix to your AI agent (Claude Code / Cursor):
npx @bugmojo/cli fix WEB-42 | pbcopy # macOS (Windows: | clip · Linux: | xclip -selection clipboard)
# 4. Verify the fix against a preview deploy and report it:
npx @bugmojo/cli verify WEB-42 --url https://preview.example.com --report
# → PASSED ✓ → the bug flips DEV_TESTING → VERIFIED_FIXEDFeatures
- One-command repro — a self-contained, runnable
@playwright/testproject written to disk from a bug key. - Real verification — the repro runs on your build with your Playwright install; exit
0/1so CI can gate merges on it. - CI status reporting —
verify --reportflips the bugDEV_TESTING → VERIFIED_FIXED(pass) orREOPENED(fail) via the CI verify webhook. - Agent-ready prompts —
fixrenders 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_SECRETare 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)
| Variable | Required | Description |
| ------------------- | ------------------- | -------------------------------------------------------------------------------------------------------------------- |
| 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-urlas 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/
bugmojo repro WEB-42 --out ./repros # custom directory
bugmojo repro WEB-42 --json # print the raw pack to stdout instead
bugmojo repro WEB-42 --force # overwrite an existing directory| Option | Description |
| ----------------- | ----------------------------------------------------------------- |
| -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:
| File | Contents |
| ----------------- | ----------------------------------------------------- |
| <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 # machine output
bugmojo verify WEB-42 --url https://preview.example.com --report # POST result to CI| Option | Description |
| ----------------- | --------------------------------------------------------------------------- |
| -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 # to stdout
bugmojo fix WEB-42 --out prompt.md # to a file
bugmojo fix WEB-42 | pbcopy # clipboard — macOS
bugmojo fix WEB-42 | clip # clipboard — Windows (cmd)
bugmojo fix WEB-42 | Set-Clipboard # clipboard — Windows (PowerShell)
bugmojo fix WEB-42 | xclip -sel clipboard # clipboard — Linux (X11; Wayland: wl-copy)| Option | Description |
| ------------------ | ------------------------------------------- |
| -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 # whole suite, LOCAL runner
bugmojo run --url https://preview.example.com # sets PLAYWRIGHT_BASE_URL + deploy_url
bugmojo run --project WEB --plan-version pv_1 # bind the run to a plan version
bugmojo run --dry-run # run, print the payload, send nothing
bugmojo run -- --grep @smoke --workers=2 # everything after -- goes to playwright| Option | Description |
| --------------------- | ---------------------------------------------------------------------------------------- |
| -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:
| File | Read by |
| --------------------------------- | ------------------------------------------ |
| 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 # all files, hosted MCP URL
bugmojo init --workspace acme --project WEB # pin the workspace, mention the project key
bugmojo init --only claude,playwright # a subset of targets
bugmojo init --dry-run # show what would change| Option | Description |
| -------------------- | ------------------------------------------------------------------------------ |
| --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
unchangedfor 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 existingtrace/video/screenshotchoice is respected; only missing keys are added. - Offline.
initneeds 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 headlessAuthorization: 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
# .github/workflows/verify-bug.yml
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 theget_repro_packMCP 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 byverify --report. Body:{ bug_key, passed, proof_url? }(the--urlyou verified against is sent as the proof link).POST /api/v1/test-runs/results(auth: Bearer) — used bybugmojo runwhen@bugmojo/playwright-reporteris 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
bugmojobin works everywhere; programmatic consumers on CommonJS should use dynamicimport('@bugmojo/cli')(or Node >= 20.19, whererequire(esm)works).
Exit codes
| Code | Meaning |
| ---- | ------------------------------------------------ |
| 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
| Package | Use it for |
| ------- | ---------- |
| @bugmojo/widget | Framework-agnostic on-site feedback + capture widget core |
| @bugmojo/react | React / Next.js SDK — provider, error boundary, hooks |
| @bugmojo/react-native | React Native + Expo SDK — shake-to-report |
| @bugmojo/mcp-server | Connect AI coding agents (Claude Code, Cursor) to BugMojo |
License
MIT © Softech Infra — docs & issues at viveksinra/bugmojo-sdk.
