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 Actions
If you'd rather hand-write it (or already have a workflow file), add this step. It's what init writes by default — self-contained, no external action dependencies:
# .github/workflows/aislop.yml
name: aislop
on:
push:
branches: [main]
pull_request:
jobs:
quality-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
# Exits 1 when score < ci.failBelow in .aislop/config.yml
# or when any error-severity diagnostic is present.
- run: npx aislop@latest ci .
No installed dependencies required on the runner — npx aislop@latest downloads the CLI on each run. If you want deterministic builds, pin a specific version (npx aislop@0.5.0 ci .) or add aislop to your devDependencies and run npx aislop ci . after npm ci.
GitLab CI
Equivalent shape:
# .gitlab-ci.yml
aislop:
image: node:20
script:
- npx 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 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.5.0",
"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": [ ... ]
}