Skip to main content
aislop’s ci command is designed to run identically on every CI provider. It scans your codebase, outputs structured JSON, and exits with a non-zero code when the score drops below your configured threshold or any error-severity diagnostic is present. Because npx --yes aislop@latest ci always fetches the latest published CLI, there is no version pin to maintain across your pipelines.

GitLab CI

Add an aislop job to your .gitlab-ci.yml. The job runs on merge requests and pushes to main by default — adjust the rules block to match your branching strategy.
# .gitlab-ci.yml
aislop:
  image: node:24
  script:
    - npx --yes aislop@latest ci
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    - if: $CI_COMMIT_BRANCH == "main"

CircleCI

Add an aislop job to your CircleCI config and include it in your quality-gate workflow.
# .circleci/config.yml
version: 2.1

jobs:
  aislop:
    docker:
      - image: cimg/node:24.0
    steps:
      - checkout
      - run: npx --yes aislop@latest ci

workflows:
  quality-gate:
    jobs:
      - aislop

Bitbucket Pipelines

Bitbucket clones repositories with a shallow history by default. Branch diffs require full history, and the PR target branch is exposed as $BITBUCKET_PR_DESTINATION_BRANCH. Fetch the target branch before running aislop, then gate on only the changed files using --changes --base FETCH_HEAD.
# bitbucket-pipelines.yml
pipelines:
  pull-requests:
    "**":
      - step:
          name: aislop gate
          image: node:24
          clone:
            depth: full   # branch diffs need history
          script:
            - git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
            - npx --yes aislop@latest ci --changes --base FETCH_HEAD
Bitbucket’s clone contains only the source branch. Running git fetch origin <branch> sets FETCH_HEAD without creating a local origin/<branch> ref — use --base FETCH_HEAD rather than --base origin/<branch> to avoid a ref-resolution error.

PR-scoped gating

By default, aislop ci scores your entire codebase. Passing --changes --base <ref> restricts the scan to files that differ between the current HEAD and the base branch, making the gate faster and more actionable on large repositories.
npx aislop@latest ci --changes --base origin/main
Both scan and ci accept --changes and --base, and the score gate and exit code apply to the scoped set of files. If --base cannot be resolved, the run fails rather than silently passing an empty scan.
A plain --changes (without --base) diffs the working tree against HEAD. In CI, PR changes are already committed, so this sees nothing. Always pass --base <ref> when gating a pull request.
npx aislop@latest ci --changes --base origin/main
Works directly when the repository was cloned with full history.

Quality gate configuration

Set your minimum acceptable score in .aislop/config.yml. aislop exits with code 1 when the score falls below failBelow or when any error-severity diagnostic is present.
# .aislop/config.yml
ci:
  failBelow: 70
  format: json
To extend a base config from a parent directory or shared policy file:
# .aislop/config.yml
extends: ../../.aislop/base.yml
ci:
  failBelow: 80    # override specific keys

JSON output format

Both aislop ci and aislop scan --json emit structured JSON that you can parse in scripts or forward to dashboards. The shape looks like this:
{
  "schemaVersion": "1",
  "cliVersion": "<version>",
  "score": 87,
  "label": "Healthy",
  "engines": {
    "format":       { "issues": 0, "skipped": false, "elapsed": 406 },
    "lint":         { "issues": 0, "skipped": false, "elapsed": 378 },
    "code-quality": { "issues": 1, "skipped": false, "elapsed": 812 },
    "ai-slop":      { "issues": 2, "skipped": false, "elapsed": 455 },
    "security":     { "issues": 0, "skipped": false, "elapsed": 1103 }
  },
  "diagnostics": []
}
Use aislop ci --human when you want readable terminal output in CI logs instead of JSON — useful during initial setup and debugging.