Release and CI hardening: safer exact-version GitHub Action pins, reproducible init workflows, and rule catalog/docs that match the detectors users actually run.
| Change | Details |
|---|---|
| Action pin safety | The GitHub Action now runs exact npm pins from an isolated temp directory, so a checked-out local package cannot shadow the published CLI. The repository smoke-tests default latest, explicit latest, pinned npm versions, JSON, human output, and node-version overrides. |
| Reproducible init workflows | aislop init now emits a pinned scanaislop/aislop@v0.10.2 workflow with an explicit npm CLI version, while the Action itself still supports floating latest for teams that want it. |
| Rule catalog consistency | aislop rules, rule labels, and the docs now cover the implemented camel-case and newer rule IDs consistently, including duplicate exports, dependency-audit skips, React dangerouslySetInnerHTML, and fixed empty-function detection. |
We read a paper. SlopCodeBench (SCBench) measures verbosity, the redundant and duplicated code agents accrete over long-horizon tasks. We shipped the four most repeatable Python signals as deterministic rules.
| Change | Details |
|---|---|
| SCBench-derived Python rules | ai-slop/python-chained-dict-get, ai-slop/python-isinstance-ladder, ai-slop/python-range-len-loop, and ai-slop/python-repetitive-dispatch translate the verbosity signal from SlopCodeBench (SCBench, arXiv 2603.24755) into deterministic detectors, each with positive and negative fixtures. |
| Community | Opened GitHub Discussions, and the CLI now prints a one-time prompt to star the repo. |
Rule precision pass: fewer false positives across idiomatic docs, local imports, eval-like method calls, wrappers, JSON-LD, and bundled files.
| Change | Details |
|---|---|
| Documentation-aware comment rules | ai-slop/narrative-comment and ai-slop/trivial-comment now recognize JSDoc, Javadoc, PHPDoc, Ruby YARD/RDoc, Go struct-field docs, and explicit WHY markers. The broad length-based fallback was replaced with explicit AI narration signals. |
| Import + language precision | Python package discovery now scans root, src/, and lib/ packages with __init__.py. PEP 484 re-exports are respected. Thin-wrapper patterns are extension-gated to JS and Python so PHP and Java methods are not matched accidentally. |
| Security noise reduction | security/eval now skips method-call forms like binding.eval while keeping top-level eval(). dangerouslySetInnerHTML respects ignore directives and JSON-LD / JSON.stringify use cases. |
| Scan filters and globals | Bundled assets like *.min.js, *.bundle.js, and .pnpm-store/ are skipped. Oxlint now registers conventional bundler-injected globals and ambient globals from project .d.ts files. |
Restored build-cache filtering in the source-file walk.
- + Build-cache artifacts are filtered before hallucinated-import checks run.
- + Regression tests now cover real cache filenames and the source-filter chain.
Scan accuracy, lower noise, top findings, include patterns, and strict bootstrap.
- + Fewer false positives across modern JS frameworks, virtual modules, generated imports, and ignored variables.
- + Added include filters, top-rule summaries, aggregated dependency findings, and language-aware complexity budgets.
- + Strict init now sets up all engines, typecheck, an 85 CI gate, GitHub workflow, agent metadata, and MCP output.
Telemetry v2: anonymous, opt-out, structured events across CLI, MCP, and hooks.
- + Replaced legacy events with command lifecycle, MCP server/tool, and hook scan events using flattened, indexable properties.
- + Added a stable anonymous install ID, strict redaction allowlist, debug and dry-run modes, and awaited flush on command completion.
- + Telemetry can be disabled from environment variables or project config across CLI, MCP, hooks, and CI.
Hallucinated-import detector now respects TypeScript path aliases.
| Change | Details |
|---|---|
tsconfig.json path aliases respected | Imports matching a compilerOptions.paths alias (e.g. import x from "@/components/Foo" when paths: { "@/*": ["./src/*"] } is set) are no longer flagged as hallucinated. Walks root and every workspace package; supports wildcard (@/*) and exact (#shared) keys; reads tsconfig.json and jsconfig.json. Malformed config is skipped silently — same flagging behavior as 0.8.2, no regression. Closes 146 false positives observed on a real Vite + workspace project. |
| Breaking changes | None. The new check is additive — projects without a tsconfig or paths config behave exactly as in 0.8.2. |
Narrative-comment false-positive reduction on JSDoc + semver downgrade-detection utilities.
| Change | Details |
|---|---|
| JSDoc no longer false-positives | ai-slop/narrative-comment now requires explicit slop signals (explanatory openers, justification patterns, cross-references) before flagging a JSDoc block. Added e.g. and i.e. as documentation indicators. Line-comment preambles (3+ lines before a declaration) are still flagged. |
parseSemverMin & isDowngrade helpers | Detect when a dependency update would downgrade a package (e.g. ^13.6.0 → ^12.1.0). Handles wildcard specs like ^11.x.x and ignores non-semver shapes (workspace:*, git URLs). Powers safer behavior in aislop fix --force. |
| Breaking changes | None. JSDoc handling is strictly less aggressive than 0.8.1. |
Documentation polish to improve first-run experience.
- ~ README restructured: instant scan command (
npx aislop scan) at the top, badge snippet integrated into Quick start,npxprefix on all commands for consistency. Length dropped from 407 to 287 lines. - ~ Added context to Fix and Hand off to agent sections so the README explains what each does without forcing a scroll to the docs.
MCP server, TypeScript typecheck engine, hallucinated-import detection, eight new detectors across Python / Go / Rust + JS, and ~4,100 false positives eliminated via OSS validation against 25 real projects.
| Change | Details |
|---|---|
MCP server (aislop-mcp) | The package now ships an aislop-mcp binary that speaks Model Context Protocol. scan, fix, why, and baseline are exposed as MCP tools so AI coding assistants (Claude Desktop, Claude Code, Codex, anything with MCP support) can invoke aislop directly without a shell hand-off. See docs/mcp for client configuration. |
| TypeScript typecheck engine | New lint-engine entry runs tsc --noEmit and folds compiler diagnostics into the lint score. Respects tsconfig.json project references. Type errors now surface alongside eslint / oxlint findings on every scan. |
| Hallucinated-import detector | New ai-slop/hallucinated-import rule flags imports of packages that don't exist in any package.json in the workspace. Walks manifests up to depth 4 for monorepos. Catches LLM-fabricated package names before they hit CI. (Note: respects tsconfig path aliases as of 0.8.3.) |
| Eight new detectors across the polyglot map | Python: placeholder exception handlers, generic print debugging. Go: library panics in exported functions, TODO/FIXME markers in production paths. Rust: unwrap() chains, unimplemented!() in library code, excessive .clone(). JS/TS: ai-slop/duplicate-import for redundant imports of the same symbol or module. |
| Hook envelope v2 + auto-rescan | New hook protocol version with structured responses. Claude Code integration watches .aislop/config.yml, .aislop/rules.yml, and package.json for changes and re-scans automatically — the agent never sees a stale ruleset. |
| GitHub Step Summary writer | CI runs output rich Markdown summaries in the GitHub Actions UI: per-finding help text, severity badges, quick-fix suggestions. No more digging through raw logs to triage a failed quality gate. |
| Scoring improvements | New formula with per-engine caps, file-aware density smoothing, and a fixable-issue discount. More stable scores across project sizes; less penalty for findings that aislop fix can resolve. |
| ~4,100 false positives eliminated | Validated detectors against 25 real OSS projects (requests, flask, fastapi, cobra, gin, hugo, clap, ripgrep, tokio, serde, prisma, trpc, zod, vitest, nest, express, lodash, axios, chalk, commander, and more). narrative-comment now skips Rust /// doc comments, Go doc conventions, and JSDoc with WHY markers. console-leftover exempts CLI command source directories. go-library-panic exempts nil-check preconditions. All detectors now skip test files, migrations, fixtures, snapshots, mocks, and generated output across every language. |
| Breaking changes | None at the CLI contract level. Flags, exit codes, and JSON field names stable. New aislop-mcp binary is additive. |
Config inheritance via extends: for monorepo and team setups, public score badge, and a postcss security floor.
| Change | Details |
|---|---|
extends: in .aislop/config.yml | Project configs can inherit a parent and override only the keys they need. Useful for monorepos: one strict parent config at the root, per-package overrides for ci.failBelow or specific weights. Multiple parents via an array; later entries win. Nested objects deep-merge key-by-key, arrays replace wholesale. Cycles and chains > 5 are rejected at load time. |
| Public score badge | Shields-compatible SVG at badges.scanaislop.com/score/<owner>/<repo>.svg, edge-cached on Cloudflare. Bands: green ≥ 85, amber 70–84, red < 70, grey if no scans yet. Drop it in any README next to your CI and npm version badges. |
Security: postcss floor | pnpm.overrides pins postcss to ≥ 8.5.10 (resolves to 8.5.13). Closes the security/vulnerable-dependency finding aislop's own scan reported on the repo. No top-level dep used postcss directly — an override is the right tool. |
| Breaking changes | None. All flags, exit codes, and JSON field names stable. extends: is additive; configs without it are unchanged. |
Single focused fix: knip/binaries no longer false-positives on .github/workflows/**.
| Change | Details |
|---|---|
knip/binaries on CI workflow files | Every runner-provided binary (gh, aws, docker, jq, kubectl, …) invoked from .github/workflows/** was flagged as an "Unlisted binary" because they can't be declared in package.json. A self-scan of this repo dropped the score to 97/100 on the fix. A new shouldIncludeIssue predicate in src/engines/code-quality/knip.ts drops knip/binaries for paths under .github/workflows/. The rule stays active everywhere else. |
| Breaking changes | None. Packaged size unchanged. |
Hook UX polish, three new deterministic rules, config-driven file exclusion, and internal refactors driven by the new rules catching real slop in aislop's own source.
| Change | Details |
|---|---|
| Hook UX fixes | aislop hook install --claude (or --cursor, --gemini, etc.) now matches the fix --claude pattern. Positional args work: hook install claude cursor. Interactive multi-select picker when no agents are passed and stdin is a TTY. Internal callbacks (hook claude/cursor/gemini) now print a hint instead of silently no-op'ing when invoked from a terminal. |
| Three new detection rules | code-quality/repeated-chained-call catches 5+ consecutive method calls on the same chain differing only in string literals (the .option("--flag", "help") × 14 parade). code-quality/duplicate-block catches real copy-paste via sliding 10-line window. ai-slop/narrative-comment widened: bare section-label detection (// Subcommands), expanded trivial-verb list (Write, Run, Parse, Cleanup, Setup, 20+ more), in-function prose detection exempted when a WHY marker is present (because, workaround, note:, etc.). |
| Config-driven file exclusion | Shoutout to @myke-awoniran — new exclude: key in .aislop/config.yml plus --exclude <pattern> on the CLI, glob support via micromatch. Defaults cover node_modules, .git, dist, build, coverage. Priority: CLI > config > defaults. |
| Suppression mechanism | // aislop-ignore-file <rule> at the top of a file, or // aislop-ignore-next-block <rule> above a construct. Opts out of a rule on code where the pattern is intentional: diagnostic-push tables, component-library conventions, static-asset generators. |
| Self-refactor | The new rules caught 40+ real findings in aislop's own source on the first run. Refactored doctor.ts (data tables replacing six plan-by-language branches), source-masker.ts (state-machine extraction), dead-patterns.ts (slop() factory), cli.ts (extracted runScan helper + FIX_AGENT_FLAGS data table). Back to 100/100. |
| Breaking changes | None. --agent <names> still works; it's one of four equivalent ways to select agents now. |
Agent hooks: Claude, Cursor, Gemini, + 6 rules-only agents. Findings flow back to the agent on the turn it wrote the code.
| Change | Details |
|---|---|
aislop hook install | One command wires aislop into the agent's native hook lifecycle. Runtime adapters for Claude Code (PostToolUse), Cursor (afterFileEdit), Gemini CLI (AfterTool) scan what was just touched and feed findings back. Rules-only installers for Codex, Windsurf, Cline + Roo, Kilo Code, Antigravity, and Copilot write an AISLOP.md the agent reads. Every install is sentinel-guarded with a SHA-256 hash fence so re-runs are idempotent and uninstall is exact. |
Structured feedback (aislop.hook.v1) | The agent receives score, counts, top-20 findings with file / line / rule / severity, a nextSteps list it can act on, and a regressed flag when --quality-gate is set. With quality-gate on, the Claude Stop hook blocks the session if the project score drops below the baseline captured at install. |
| Swagger / OpenAPI / apidoc safe | Critical bug surfaced in a real repo: the narrative-comment rule was flagging @swagger, @openapi, @route, @api* (apidoc), @responses, @requestBody, @tags, @security, @path, @body, @query, @header and others as narrative, and auto-fix deleted them. One known repo lost 1,340 lines of OpenAPI documentation on a single fix run. All API-doc JSDoc tags now in MEANINGFUL_JSDOC_TAGS, covered by tests, safe to regenerate. |
| Safety rails | .aislop/hook.lock recursion guard (30s stale window) stops aislop scanning itself through its own hook. git diff fallback when stdin doesn't carry a file path. Every JSON write is atomic (tempfile + rename) and every Markdown write is fenced (<!-- aislop:begin -->) so uninstall removes exactly what install added. |
| Breaking changes | None at the CLI contract. Flags, exit codes, and JSON field names stable. New hook subcommand is additive. |
Two bug fixes: JSX file-too-large respects config, pnpm dep-audit fix actually works
| Change | Details |
|---|---|
complexity/file-too-large on JSX/TSX | Previous behaviour silently applied 2× multiplier + 10% soft buffer for .jsx / .tsx, so maxFileLoc: 400 actually fired at 881 lines. Big React pages sailed past 400 unflagged. Now 1.5× with no soft buffer (400 → 600), and every non-JSX extension hits the exact configured value. TSX files over 600 lines that were quiet under 0.5.0 will now flag; bump .aislop/config.yml → maxFileLoc if needed. |
aislop fix -f pnpm audit | Previously tried to run pnpm audit --fix, which doesn't exist, and silently skipped the vulnerability step. Now parses pnpm audit --json and writes surgical pnpm.overrides entries into the root package.json. |
| Breaking changes | None at the CLI contract level. Flags, exit codes, and JSON field names stable. The JSX cap tightening may surface previously-hidden warnings, but that's the intent. |
New CLI, own AST fix engine, stable output, better experience
| Change | Details |
|---|---|
| Full CLI UX rehaul | Rounded step markers, connector lines, live spinners while work runs, and accent-green next-step hints (built on @clack/prompts). Live concurrent engine grid for scan, live rail flows for fix / init / doctor. Invocation-aware hints so npx aislop and global installs both copy-paste correctly. |
| Our own AST fix engine | aislop now owns every destructive fix through the TypeScript compiler API. Parse-check before write, revert on any failure. No more oxlint --fix or knip --fix corrupting user code. |
| Stable fix-then-scan | Running fix a second time on a clean repo produces zero changes. No more phantom diffs. |
| Change | Details |
|---|---|
aislop ci --human | Re-enables the full visual design when you want human-readable CI output. |
| JSON schema metadata | Output gains schemaVersion: "1" and cliVersion at the top of the envelope. |
| SQL-injection tightened | Template literals only flag when preceded by a database-like receiver, so log.raw no longer false-positives. |
typescript dependency | Moved from devDependencies to dependencies. Required at runtime by the new AST engine. |
| Breaking changes | None at the CLI contract level. All flags, exit codes, and JSON field names stayed stable. |
Agent Handoff + Smarter Fix Pipeline
- + 14 agent handoffs: Claude Code, Codex, Cursor, Windsurf, Gemini, Amp, VS Code, Aider, Goose, OpenCode, Warp, Kimi, Antigravity, Deep Agents
- + Improved code quality: diagnostic deduplication, unused file removal in fix, directory validation
- + Better error handling: graceful config loading, improved CLI command handling
- ~ Formatting issues downgraded from error to warning. Indentation no longer blocks PRs
- ~ Fix no longer touches files when scan reports 0 issues. No more phantom diffs
- ~ Clean output. Removed redundant "Next steps" when everything passes
- ~ Respects biome.json lineWidth config
- ~ npm audit fallback when pnpm audit endpoint is retired
Patch release with bug fixes.
- ~ Fix destructured parameter rename bug. Default values in destructured params now renamed correctly
- ~ Filter noisy "would have printed" messages from biome format output
- ~ Add defensive null safety to
parseRuleCode
- ~ Fix destructured parameter rename bug
- ~ Filter noisy biome output
- ~ Defensive null safety in
parseRuleCode
Aggressive Auto-Fix Engine
- + Unused variables: Removes declarations, keeps side-effectful expressions
- + Unused default imports: Strips unused default imports while keeping named imports
- + Trivial comments: Removes AI-generated comments that restate the code
- + Console.log leftovers: Removes debugging statements
- + Duplicate object keys: Removes the second occurrence
- + Post-fix summary: Shows resolved count, remaining issues, manual effort
- + Animated progress spinner during fix
- ~ Fix ordering: imports/lint/deps first, formatting last
- ~ No more interactive pager in terminal workflows
- ~ oxlint now includes
--fix-suggestionsfor more auto-fixes - ~ Telemetry flushes before process exit
- + Dedicated unused-import fixer module
- + Demo recording assets (scan.gif, fix.gif)
Unused Dependency Detection
- + 5 new rules powered by knip: unused deps, devDeps, unlisted, unresolved, binaries
- +
aislop fixauto-removes unused packages from package.json - + Published as
@scanaislop/aislopon GitHub Packages - ~ Documentation overhaul: README slimmed, reference docs in
docs/ - ~ Project infrastructure: .editorconfig, biome.json, AGENTS.md, knip.json
- ~ Scoring penalties now proportional to codebase size (fixes #9)
- ~ Fix
calculateScoreto passsourceFileCountcorrectly - + 52 comprehensive scoring tests
- + Configurable
scoring.smoothingoption
- ~
template.innerHTMLno longer flagged as XSS.<template>elements are inert by spec (fixes #7) - ~
aislop scannow exits with code 1 on error-severity diagnostics (fixes #8) - + 3 new security tests for template innerHTML exception
- + Anonymous opt-out telemetry via PostHog (respects
AISLOP_NO_TELEMETRY=1,DO_NOT_TRACK=1) - ~ Fix false-positive
function-too-longonisBlockArrow(brace counter miscounting regex literals)
Initial Release
- + TypeScript and Python support
- + AI slop pattern detection: trivial comments, swallowed exceptions, generic naming, type abuse
- + Formatting engine (Biome, ruff) and linting engine (oxlint, ruff)
- + Score 0-100 with quality gate threshold
- +
aislop scan,aislop fix,aislop cicommands