aislop 0.10.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,30 +2,37 @@
2
2
 
3
3
  **Catch the slop AI coding agents leave in your code.**
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/aislop.svg)](https://www.npmjs.com/package/aislop)
6
- [![npm downloads](https://img.shields.io/npm/dm/aislop.svg)](https://www.npmjs.com/package/aislop)
7
- [![CI](https://github.com/scanaislop/aislop/actions/workflows/ci.yml/badge.svg)](https://github.com/scanaislop/aislop/actions/workflows/ci.yml)
8
- [![aislop score](https://badges.scanaislop.com/score/scanaislop/aislop.svg)](https://scanaislop.com/scanaislop/aislop)
9
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
10
- [![Node >= 20](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org)
5
+ [![npm version](https://img.shields.io/npm/v/aislop.svg)](https://www.npmjs.com/package/aislop) [![npm downloads](https://img.shields.io/npm/dm/aislop.svg)](https://www.npmjs.com/package/aislop) [![PyPI downloads](https://img.shields.io/pepy/dt/aislop.svg?label=PyPI%20downloads)](https://pypi.org/project/aislop/) [![Homebrew tap](https://img.shields.io/badge/Homebrew-scanaislop%2Ftap-2f855a.svg)](https://github.com/scanaislop/homebrew-tap) [![CI](https://github.com/scanaislop/aislop/actions/workflows/ci.yml/badge.svg)](https://github.com/scanaislop/aislop/actions/workflows/ci.yml) [![aislop score](https://badges.scanaislop.com/score/scanaislop/aislop.svg)](https://scanaislop.com/scanaislop/aislop) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Node >= 20](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](https://nodejs.org)
11
6
 
12
7
  The patterns Claude Code, Cursor, Codex, and OpenCode leave behind: narrative comments above self-explanatory code, swallowed exceptions, `as any` casts, hallucinated imports, duplicated helpers, dead code, todo stubs, oversized functions. Tests pass. Lint passes. The code rots anyway.
13
8
 
14
- aislop catches them. 40+ rules across 7 languages (TS/JS, Python, Go, Rust, Ruby, PHP, Java). Scores every change 0–100. Sub-second. Deterministic — no LLM in the runtime path, same code in, same score out. MIT-licensed, free CLI.
9
+ aislop catches them. 50+ rules across 8 language targets (TypeScript, JavaScript, Expo / React Native, Python, Go, Rust, Ruby, PHP). Scores every change 0–100. Sub-second. Deterministic — no LLM in the runtime path, same code in, same score out. MIT-licensed, free CLI.
15
10
 
16
11
  ## Quick start
17
12
 
18
13
  ```bash
19
- npx aislop scan
14
+ npx aislop@latest scan
20
15
  ```
21
16
 
22
17
  No install needed. Works on any project. Get your score in seconds.
23
18
 
19
+ Also available on npm, Yarn, Bun, Homebrew, and PyPI:
20
+
21
+ ```bash
22
+ npm install -g aislop # npm
23
+ yarn dlx aislop scan # Yarn (no install)
24
+ bun add -g aislop # Bun
25
+ brew install scanaislop/tap/aislop # Homebrew
26
+ pipx install aislop # Python
27
+ ```
28
+
29
+ See [Installation](#installation) for every option.
30
+
24
31
  ```bash
25
- npx aislop fix # auto-fix issues
26
- npx aislop fix -f # aggressive fixes (deps, unused files)
27
- npx aislop ci # CI mode (JSON + gate)
28
- npx aislop hook install --claude # per-edit hook
32
+ aislop fix # auto-fix issues after installing
33
+ aislop fix -f # aggressive fixes (deps, unused files)
34
+ aislop ci # CI mode (JSON + gate)
35
+ aislop hook install --claude # per-edit hook
29
36
  ```
30
37
 
31
38
  **Public badge**: Show your score on your README
@@ -34,7 +41,7 @@ npx aislop hook install --claude # per-edit hook
34
41
  [![aislop](https://badges.scanaislop.com/score/<owner>/<repo>.svg)](https://scanaislop.com)
35
42
  ```
36
43
 
37
- Run `npx aislop badge` to auto-generate. Free at [scanaislop.com](https://scanaislop.com).
44
+ Run `npx aislop@latest badge` to auto-generate. Free at [scanaislop.com](https://scanaislop.com).
38
45
 
39
46
  ## See it in action
40
47
 
@@ -46,9 +53,13 @@ Run `npx aislop badge` to auto-generate. Free at [scanaislop.com](https://scanai
46
53
 
47
54
  ## Installation
48
55
 
56
+ The same CLI is published to npm, Homebrew, and PyPI. Pick whichever fits your stack.
57
+
58
+ **Node / npm**
59
+
49
60
  ```bash
50
61
  # Run without installing
51
- npx aislop scan
62
+ npx aislop@latest scan
52
63
 
53
64
  # npm
54
65
  npm install --save-dev aislop
@@ -59,25 +70,64 @@ yarn add --dev aislop
59
70
  # pnpm
60
71
  pnpm add -D aislop
61
72
 
73
+ # bun
74
+ bun add -d aislop
75
+
62
76
  # Global
63
77
  npm install -g aislop
64
78
  ```
65
79
 
66
80
  Also available as [`@scanaislop/aislop`](docs/installation.md) on GitHub Packages.
67
81
 
82
+ **Homebrew** (macOS / Linux)
83
+
84
+ ```bash
85
+ brew install scanaislop/tap/aislop
86
+ ```
87
+
88
+ Homebrew installs Node.js as a dependency if it isn't already present. Details: [homebrew-tap](https://github.com/scanaislop/homebrew-tap).
89
+
90
+ **Python / pipx**
91
+
92
+ ```bash
93
+ pipx install aislop
94
+ ```
95
+
96
+ `pipx` keeps `aislop` in its own isolated environment. Needs Node.js on `PATH`. Details: [PyPI package](https://pypi.org/project/aislop/).
97
+
98
+ Full reference for every channel, bundled tooling, and external tools: [docs/installation.md](docs/installation.md).
99
+
68
100
  ---
69
101
 
70
102
  ## Usage
71
103
 
104
+ Examples below use the installed `aislop` binary. For a one-off latest run, prefix the command with `npx aislop@latest`, for example `npx aislop@latest scan`.
105
+
106
+ ### Command reference
107
+
108
+ ```bash
109
+ aislop --help # clean overview
110
+ aislop commands # every public command and major flag
111
+ aislop <command> --help # detailed help for one command
112
+ aislop version # installed version
113
+ aislop -V # installed version
114
+ aislop update # current and latest npm versions
115
+ ```
116
+
72
117
  ### Scan
73
118
 
74
119
  ```bash
75
- npx aislop scan # current directory
76
- npx aislop scan ./src # specific directory
77
- npx aislop scan --changes # changed files from HEAD
78
- npx aislop scan --staged # staged files only
79
- npx aislop scan --json # JSON output
80
- npx aislop scan --sarif # SARIF 2.1.0 output (GitHub code scanning)
120
+ aislop scan # current directory
121
+ aislop scan ./src # specific directory
122
+ aislop scan --changes # changed files from HEAD
123
+ aislop scan --changes --base origin/main # changed vs a base branch (PRs)
124
+ aislop scan --staged # staged files only
125
+ aislop scan -d # verbose file/rule detail
126
+ aislop scan --json # JSON output
127
+ aislop scan --sarif # SARIF 2.1.0 output (GitHub code scanning)
128
+ aislop scan --format json # alternate JSON form
129
+ aislop scan --include "src/**" # only matching paths
130
+ aislop scan --exclude "dist,gen" # skip extra paths
81
131
  ```
82
132
 
83
133
  **Exclude files**: `node_modules`, `.git`, `dist`, `build`, `coverage` excluded by default. Add more in `.aislop/config.yml`:
@@ -88,7 +138,9 @@ exclude:
88
138
  - src/generated
89
139
  ```
90
140
 
91
- Or via CLI: `npx aislop scan --exclude "**/*.test.ts,dist"`
141
+ Or via CLI: `aislop scan --exclude "**/*.test.ts,dist"`
142
+
143
+ **Unsupported languages**: aislop only analyses the 8 language targets above. If a repo is mostly something else (C, C++, C#, Swift, Kotlin, …), scoring a handful of incidental files would misrepresent it, so aislop **withholds the score** and says so rather than printing a number off code it never read. `--json` returns `score: null`, `scoreable: false`, and a `coverage` breakdown.
92
144
 
93
145
  **Per-rule severity**: Override the severity of any rule by id, or turn it off:
94
146
 
@@ -102,6 +154,25 @@ rules:
102
154
 
103
155
  `off` drops matching diagnostics; `error`/`warning` rewrites severity before scoring and reporting. Absent map keeps default behavior.
104
156
 
157
+ **Suppress findings inline**: Silence a specific line when you know better, with an optional reason after `--`:
158
+
159
+ ```ts
160
+ // aislop-ignore-next-line ai-slop/empty-fallback -- options is validated upstream
161
+ const opts = { ...defaults, ...(input || {}) };
162
+
163
+ const legacy = doThing(); // aislop-ignore-line
164
+ ```
165
+
166
+ `aislop-ignore-next-line` covers the line below, `aislop-ignore-line` the line it sits on, and `aislop-ignore-file` (place anywhere in the file) the whole file. Name one or more rules to scope the suppression, or omit them to silence every rule on that line. The directive works in any comment syntax (`//`, `#`, `<!-- -->`). Suppressed findings are removed before scoring, and the run reports how many were silenced.
167
+
168
+ **Ignore whole paths**: Add an `.aislopignore` at the project root (same glob semantics as `exclude`, `#` comments allowed):
169
+
170
+ ```
171
+ src/generated
172
+ **/*.snap
173
+ legacy
174
+ ```
175
+
105
176
  **Extend config**: Project config can extend a parent:
106
177
 
107
178
  ```yaml
@@ -118,46 +189,59 @@ ci:
118
189
  Auto-fix what's mechanical (formatters, unused imports, dead code). For issues that need context, hand off to your agent with full diagnostic info.
119
190
 
120
191
  ```bash
121
- npx aislop fix # safe auto-fixes
122
- npx aislop fix -f # aggressive: deps, unused files
192
+ aislop fix # auto-fixes
193
+ aislop fix -d # detailed fix progress
194
+ aislop fix --safe # only reversible fixes (imports, comment removal, formatting)
195
+ aislop fix -f # aggressive: deps, unused files
196
+ aislop fix -p # print an agent handoff prompt
123
197
  ```
124
198
 
199
+ `--safe` restricts the run to fixes that cannot change behaviour — unused-import removal, import merging, narrative-comment removal, and formatting. Anything that deletes code or rewrites behaviour/attributes (console/dead-code removal, lint autofixes, unused-declaration and dependency pruning) is skipped, so a `--safe` run is genuinely "apply and commit".
200
+
125
201
  ### Hand off to agent
126
202
 
127
203
  When auto-fix can't solve it, pass the remaining issues to your coding agent with full context:
128
204
 
129
205
  ```bash
130
- npx aislop fix --claude # Claude Code
131
- npx aislop fix --cursor # Cursor (copies to clipboard)
132
- npx aislop fix --gemini # Gemini CLI
133
- npx aislop fix --codex # Codex CLI
134
- # Also: --windsurf, --amp, --aider, --goose, --pi, --crush, --opencode, --warp, --kimi, --antigravity, --deep-agents, --vscode
135
- npx aislop fix --prompt # print prompt (agent-agnostic)
206
+ aislop fix --claude # Claude Code
207
+ aislop fix --codex # Codex CLI
208
+ aislop fix --cursor # Cursor (copies to clipboard)
209
+ aislop fix --gemini # Gemini CLI
210
+ aislop fix --prompt # print prompt (agent-agnostic)
136
211
  ```
137
212
 
213
+ Other fix handoff flags: `--windsurf`, `--vscode`, `--amp`, `--antigravity`, `--deep-agents`, `--kimi`, `--opencode`, `--warp`, `--aider`, `--goose`, `--pi`, `--crush`.
214
+
138
215
  ### Install hook
139
216
 
140
217
  Runs after every agent edit. Feedback flows back immediately.
141
218
 
142
219
  ```bash
143
- npx aislop hook install --claude # Claude Code
144
- npx aislop hook install --cursor # Cursor
145
- npx aislop hook install --gemini # Gemini CLI
146
- npx aislop hook install --pi # pi
147
- npx aislop hook install # all supported agents
148
- npx aislop hook install claude cursor # specific agents
220
+ aislop hook install --claude # Claude Code
221
+ aislop hook install --cursor # Cursor
222
+ aislop hook install --gemini # Gemini CLI
223
+ aislop hook install --pi # pi
224
+ aislop hook install # pick agents interactively
225
+ aislop hook install claude cursor # specific agents
226
+ aislop hook install --agent claude,pi # comma-separated agents
227
+ aislop install claude cursor # alias for hook install
228
+ aislop install hooks --claude # natural alias for hook install
149
229
  ```
150
230
 
151
231
  **Runtime adapters** (scan + feedback): `claude`, `cursor`, `gemini`, `pi`.
152
232
  **Rules-only** (agent reads rules): `codex`, `windsurf`, `cline`, `kilocode`, `antigravity`, `copilot`.
153
233
 
234
+ Hook install flags: `--agent <names>`, `-g, --global`, `--project`, `--dry-run`, `--yes`, `--quality-gate`, plus per-agent shortcuts `--claude`, `--cursor`, `--gemini`, `--pi`, `--codex`, `--windsurf`, `--cline`, `--kilocode`, `--antigravity`, `--copilot`.
235
+
154
236
  **Quality-gate mode**: Blocks if score regresses below baseline.
155
237
 
156
238
  ```bash
157
- npx aislop hook install --claude --quality-gate
158
- npx aislop hook baseline # re-capture baseline
159
- npx aislop hook status # list installed
160
- npx aislop hook uninstall --claude # remove
239
+ aislop hook install --claude --quality-gate
240
+ aislop hook baseline # re-capture baseline
241
+ aislop hook status # list installed
242
+ aislop hook uninstall --claude # remove
243
+ aislop uninstall claude # alias for hook uninstall
244
+ aislop uninstall hooks --claude # natural alias for hook uninstall
161
245
  ```
162
246
 
163
247
  Docs: [`/docs/hooks`](https://scanaislop.com/docs/hooks)
@@ -183,18 +267,30 @@ Expose aislop as MCP tools for Claude Desktop, Cursor, Codex:
183
267
  ### CI
184
268
 
185
269
  ```bash
186
- npx aislop ci # JSON output, exits 1 if score < threshold
270
+ aislop ci # JSON output, exits 1 if score < threshold
271
+ aislop ci --changes --base origin/main # gate only the files a PR changes
272
+ aislop ci --human # human-friendly CI output
273
+ aislop ci --sarif # SARIF output for code scanning
187
274
  ```
188
275
 
276
+ `ci` accepts the same `--changes` / `--staged` / `--base <ref>` scoping as `scan`. Use `--changes --base origin/<target>` to gate a pull request on only the files it touches; the score gate and exit code still apply.
277
+
189
278
  ### Other commands
190
279
 
191
280
  ```bash
192
- npx aislop init # create .aislop/config.yml
193
- npx aislop init --strict # enterprise-grade gate: all engines, typecheck, failBelow 85
194
- npx aislop rules # list rules
195
- npx aislop badge # print badge URL
196
- npx aislop trend # show score history over time
197
- npx aislop # interactive menu
281
+ aislop # interactive menu
282
+ aislop init # create .aislop/config.yml
283
+ aislop init --strict # enterprise-grade gate: all engines, typecheck, failBelow 85
284
+ aislop doctor # check which engines can run here
285
+ aislop rules # list rules
286
+ aislop rules --search # searchable rule explorer
287
+ aislop badge # print badge URL
288
+ aislop badge --owner o --repo r --json
289
+ aislop trend # show score history over time
290
+ aislop trend --limit 20
291
+ aislop update # show current and latest npm versions
292
+ aislop upgrade # alias for update
293
+ aislop commands # full command list
198
294
  ```
199
295
 
200
296
  **Score history**: a normal (full-project, interactive) `scan` appends a compact record to `.aislop/history.jsonl` (timestamp, score, error/warning counts, file count, CLI version). `aislop trend` reads it and prints a table plus an ASCII sparkline of recent scores. History is a local side effect only: it is never written for `--json`/`--sarif` output, in CI, or when `AISLOP_NO_HISTORY=1` is set, so machine output stays clean.
@@ -210,7 +306,7 @@ Docs: [commands](docs/commands.md)
210
306
  Run directly on staged files:
211
307
 
212
308
  ```bash
213
- npx aislop scan --staged
309
+ aislop scan --staged
214
310
  ```
215
311
 
216
312
  Or wire it into the [pre-commit](https://pre-commit.com) framework via the bundled hook:
@@ -219,28 +315,41 @@ Or wire it into the [pre-commit](https://pre-commit.com) framework via the bundl
219
315
  # .pre-commit-config.yaml
220
316
  repos:
221
317
  - repo: https://github.com/scanaislop/aislop
222
- rev: v0.9.4
318
+ rev: v1
223
319
  hooks:
224
320
  - id: aislop
225
321
  ```
226
322
 
227
323
  ### GitHub Actions
228
324
 
229
- Run `npx aislop init` and accept the workflow prompt, or add manually:
325
+ Run `aislop init` and accept the workflow prompt, or add manually. The self-contained form always runs the latest CLI, so there's nothing to bump:
230
326
 
231
327
  ```yaml
232
- - uses: actions/checkout@v4
233
- - uses: actions/setup-node@v4
234
- with:
235
- node-version: 20
236
- - run: npx aislop@latest ci .
328
+ name: aislop
329
+
330
+ on:
331
+ pull_request:
332
+ push:
333
+ branches: [main]
334
+
335
+ jobs:
336
+ quality-gate:
337
+ runs-on: ubuntu-latest
338
+ steps:
339
+ - uses: actions/checkout@v4
340
+ - uses: actions/setup-node@v4
341
+ with:
342
+ node-version: 24
343
+ - run: npx --yes aislop@latest ci
237
344
  ```
238
345
 
239
- **Composite action**:
346
+ Prefer the Marketplace Action? `@v1` tracks the latest release and `version: latest` keeps the CLI current. Pin `@v0.10.2` and a `version` for reproducible builds:
240
347
 
241
348
  ```yaml
242
349
  - uses: actions/checkout@v4
243
- - uses: scanaislop/aislop@v0.8
350
+ - uses: scanaislop/aislop@v1
351
+ with:
352
+ version: latest
244
353
  ```
245
354
 
246
355
  **GitHub code scanning (SARIF)**: emit a SARIF 2.1.0 report and upload it so findings appear in the Security tab:
@@ -252,6 +361,27 @@ Run `npx aislop init` and accept the workflow prompt, or add manually:
252
361
  sarif_file: aislop.sarif
253
362
  ```
254
363
 
364
+ ### Bitbucket Pipelines
365
+
366
+ Bitbucket clones shallow by default, so fetch the PR target branch and gate on only the changed files with `ci --changes --base`:
367
+
368
+ ```yaml
369
+ # bitbucket-pipelines.yml
370
+ pipelines:
371
+ pull-requests:
372
+ "**":
373
+ - step:
374
+ name: aislop gate
375
+ image: node:24
376
+ clone:
377
+ depth: full # branch diffs need history
378
+ script:
379
+ - git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
380
+ - npx --yes aislop@latest ci --changes --base FETCH_HEAD
381
+ ```
382
+
383
+ `ci` applies the score gate and exit code, so no JSON parsing or hand-rolled threshold is needed. More providers: [CI/CD](docs/ci.md).
384
+
255
385
  ### Quality gate
256
386
 
257
387
  Set minimum score in `.aislop/config.yml`:
@@ -285,7 +415,7 @@ AI coding tools generate code that compiles and passes tests but ships with patt
285
415
  - **One score**: 0-100, enforced in CI. Weighted so sloppy patterns hit harder than style noise.
286
416
  - **Auto-fix first**: Clears formatters, unused imports, dead code mechanically. Hands off the rest to your agent with full context.
287
417
  - **Deterministic**: Regex + AST + standard tooling. No LLMs, no API calls. Same code in, same score out.
288
- - **Zero-config start**: `npx aislop scan` works on any repo. Add `.aislop/config.yml` to tune.
418
+ - **Zero-config start**: `npx aislop@latest scan` works on any repo. Add `.aislop/config.yml` to tune.
289
419
 
290
420
  ## What it catches
291
421