One file, no dependencies.
The CLI is a single Node.js file and needs Node.js 18 or newer. This line installs the pinned v0.2.0 release (to /usr/local/bin when it is writable, else ~/.local/bin):
curl -fsSL https://raw.githubusercontent.com/OhMyX-AI/ohmybug-cli/e0bb97417cbf12f495f060684b3489b9f9394bb2/install.sh | OHMYBUG_CLI_URL=https://raw.githubusercontent.com/OhMyX-AI/ohmybug-cli/e0bb97417cbf12f495f060684b3489b9f9394bb2/ohmybug.mjs sh
Or download ohmybug.mjs from that commit and run it with node ohmybug.mjs. The source and release tags are on GitHub.
A key on CI billing.
Create a key for a program on your account page and set its billing to CI billing. A new program key starts on confirm billing, which waits for an agent's verdicts that a CI job never sends. Store the key as a secret: a masked CI/CD variable in GitLab, a credential in Jenkins.
From the repository folder.
ohmybug # review <base>...HEAD: the commits of this branch
ohmybug --base develop # the same against another base
ohmybug --uncommitted # the working tree against HEAD
The base is --base, else $CI_MERGE_REQUEST_TARGET_BRANCH_NAME in a GitLab merge request pipeline, else origin/main. The CI clone must contain the base: fetch it, or clone with enough depth.
The CLI runs the fast review by default; --deep runs the deep hunt of a pushed GitHub HEAD. It prints each finding with its severity, file:line, title and failure scenario, plus a link to the full report.
| Variable | Meaning |
|---|---|
OHMYBUG_API_KEY | Required. Your key on CI billing. |
OHMYBUG_TIMEOUT_S | How long to wait for the review, 30 to 86400 seconds. Default 1800, or 10800 with --deep. |
The job fails on a medium or worse bug.
| Exit code | Meaning |
|---|---|
| 0 | No medium or worse bug. Low findings are printed and do not fail the job. |
| 1 | At least one medium or worse bug, or a finding whose severity the CLI does not know: the gate fails closed. |
| 2 | The review could not run: no key, a refused key, a network error, a failed review, or a run cut short with no medium or worse bug. A wait that times out leaves the hunt running, and it is charged if it ends with a medium or worse bug. |
On every merge request.
For Bitbucket Pipelines, the CLI README has the matching step. Add this job to .gitlab-ci.yml and set OHMYBUG_API_KEY as a CI/CD variable with Mask variable ticked and Protect variable unticked (a protected variable never reaches merge request pipelines on unprotected branches). An unprotected variable can be read by anyone who can push a branch and change .gitlab-ci.yml in it, and the key pays for hunts. If that is too wide, keep the variable protected and protect the branches merge requests come from:
ohmybug:
image: node:22
stage: test
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
variables:
GIT_DEPTH: 0
script:
- git fetch origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
- curl -fsSL https://raw.githubusercontent.com/OhMyX-AI/ohmybug-cli/e0bb97417cbf12f495f060684b3489b9f9394bb2/install.sh | OHMYBUG_CLI_URL=https://raw.githubusercontent.com/OhMyX-AI/ohmybug-cli/e0bb97417cbf12f495f060684b3489b9f9394bb2/ohmybug.mjs sh
- ohmybug
A stage for pull requests.
In a multibranch pipeline, store the key as a Secret text credential (here ohmybug-api-key) and add this stage to the Jenkinsfile. The agent needs Node.js 18 or newer. The fetch of the target branch runs outside the checkout step, so it needs the repository credentials again: git-https here is the username and password (or token) credential your checkout uses. For an SSH remote, wrap the step in sshagent instead. Anyone who can change the Jenkinsfile on a branch the job builds can read the key, and the key pays for hunts.
stage('OhMyBug') {
when { changeRequest() }
environment { OHMYBUG_API_KEY = credentials('ohmybug-api-key') }
steps {
withCredentials([gitUsernamePassword(credentialsId: 'git-https')]) {
sh 'git fetch origin "+refs/heads/$CHANGE_TARGET:refs/remotes/origin/$CHANGE_TARGET"'
}
sh '''
curl -fsSL https://raw.githubusercontent.com/OhMyX-AI/ohmybug-cli/e0bb97417cbf12f495f060684b3489b9f9394bb2/ohmybug.mjs -o ohmybug.mjs
node ohmybug.mjs --base "origin/$CHANGE_TARGET"
'''
}
}
Pay for a bug, not for a run.
CI billing needs no confirm step: $4 a hunt ($12 deep, or $24 deep on a very wide change), charged when the result holds a medium or worse finding, whether or not anyone checks it. A clean or failed hunt costs $0, and so does a hunt with only low findings. One bug or ten costs the same. The run prints what it was charged.
With a coding agent the price grid is the same, but nothing is billed until your agent confirms a finding is real. See the FAQ and the Terms.
What leaves the CI runner.
There is no manifest to approve. The CLI sends the diff, the list of file paths at the reviewed head and up to 29 related files: the changed files, project manifests, and files that mention a changed module. While the review runs, the reviewers may ask for more files by path. Every file is read from the reviewed commit (with --uncommitted, from a snapshot of the working tree), and nothing outside the repository or under .git is ever sent. With the review go the branch name and, in a GitLab merge request pipeline, the merge request title and description.
How the code is held and removed is in How it works and the Privacy Policy.