CI / CD.
aislop ci is the quality gate: same scan as local, exits non-zero when the score drops below your threshold or any error is present. Wire it wherever your CI runs.
Fastest path — let init write it
npx aislop init will ask "Add a GitHub Actions workflow?" — say yes and it drops a ready-to-run .github/workflows/aislop.yml. Commit it alongside .aislop/config.yml. That's the whole setup.
.github/workflows/aislop.yml is the GitHub Actions workflow file. You can rename it, but it must stay under .github/workflows/. .aislop/config.yml is the policy file: thresholds, engines, scoring, and telemetry live there.
npx aislop init GitHub Actions
If you'd rather hand-write it, use the Marketplace Action. It wraps setup-node and runs the same aislop ci gate:
# .github/workflows/aislop.yml
name: aislop
on:
pull_request:
push:
branches: [main]
jobs:
quality-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: scanaislop/aislop@v0.10.2
with:
version: latest
There are two versions here. uses: scanaislop/aislop@v0.10.2 pins the GitHub Action wrapper to a real Git tag. version: latest tells the wrapper to run the latest npm CLI. GitHub does not resolve uses: ...@latest unless the repo maintains a branch or tag named latest.
For deterministic CI, pin both layers:
- uses: actions/checkout@v4
- uses: scanaislop/aislop@v0.10.2
with:
version: "0.10.2"
If you do not want the Marketplace Action, keep the workflow self-contained:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npx --yes aislop@latest ci
GitLab CI
Equivalent shape:
# .gitlab-ci.yml
aislop:
image: node:20
script:
- npx --yes aislop@latest ci
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
CircleCI
# .circleci/config.yml
version: 2.1
jobs:
aislop:
docker:
- image: cimg/node:20.0
steps:
- checkout
- run: npx --yes aislop@latest ci
workflows:
quality-gate:
jobs:
- aislop
Pre-commit hook
Run aislop on only staged files before a commit lands — catches slop before CI even sees it. Any pre-commit tool (Husky, lefthook, pre-commit.com) works.
--staged only scans files staged for commit, so the hook stays fast. Use aislop fix --staged in a pre-commit flow to auto-fix staged files, then re-add them.
Branch protection
Once aislop runs on every PR, make it required. In GitHub: Settings → Branches → Branch protection rules → Require status checks to pass before merging, then tick the aislop job. From that point, a PR that drops the score below ci.failBelow can't be merged without an explicit override.
This is where the quality gate becomes real. A CI check that only lints is advisory; a required status check is policy.
Exit codes
0 — score ≥ ci.failBelow and no error-severity diagnostics. CI passes.1 — score below threshold, or at least one error-severity diagnostic. CI fails.non-zero — other runtime failures (bad config, missing Node, etc). Check stderr.Reading the JSON output
aislop ci emits JSON on stdout. Shape:
{
"schemaVersion": "1",
"cliVersion": "0.10.2",
"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": [ ... ]
}