AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Linting Audit

skill-bensheridanedwards-architectplaybook-linting-audit · by BenSheridanEdwards

Audit a TypeScript project's lint configuration against an opinionated baseline spanning configuration shape, rule coverage, strictness and enforcement, and suppressions hygiene. Auto-detects ESLint or Biome. Static-first with optional --with-run enrichment. Optionally generates an implementation plan for the gaps.

No reviews yet
0 installs
23 views
0.0% view→install

Install

$ agentstack add skill-bensheridanedwards-architectplaybook-linting-audit

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-bensheridanedwards-architectplaybook-linting-audit)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Linting Audit? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

/linting-audit

Audit a TypeScript project's lint configuration against an opinionated baseline organised in four layers — configuration shape, rule coverage, strictness and enforcement, suppressions hygiene — preceded by a diagnostic snapshot. Then offer to generate an implementation plan for the gaps.

The default mental model is TypeScript and React. The skill auto-detects and supports both ESLint (with the modern flat configuration format) and Biome. It audits the linter actually in use; dual-installation is itself a Layer 1 violation.

How this differs from /quality-gates-audit

/quality-gates-audit checks whether linting runs in pre-commit, pre-push, and continuous integration — that's a lifecycle question. /linting-audit checks whether the linting itself is well-configured — coverage, strictness, suppressions hygiene. They complement; they do not duplicate. A project can pass quality-gates-audit (the linter runs at every stage) and still fail linting-audit (the linter is misconfigured to ignore most things), and vice versa.

Static-first design with optional run enrichment

This skill is read-only. ESLint and Biome are themselves read-only when invoked for linting (no side effects, no file changes), so opting into a real run is safe — just slow on large codebases. Two modes:

  • Static (default). Read the lint configuration files, package.json, source files (for suppression detection), and continuous-integration workflow files. Counts and rule-coverage analysis are based on configuration shape; suppressions are counted from comment text.
  • Static plus opt-in --with-run. Additionally invoke the project's lint command in JSON-reporter mode (eslint . --format json, or biome lint --reporter json), capture the output, and use the actual warnings and errors to enrich the diagnostic snapshot and a small number of run-required checks.

The skill never invokes any linter with --fix or any other mutating flag. Running with --fix is the user's job (or a separate fix skill); keeping this audit fully read-only is what makes it safe to run in any working tree at any time.

Usage

/linting-audit                                    # default: concise Top 5 + full report saved + ask about plan
/linting-audit --worktree                          # create an isolated Git worktree, then run the audit there
/linting-audit --learn                            # mid-level engineer teaching mode (detailed explanations + file/line examples)
/linting-audit --teach                            # alias for --learn
/linting-audit --with-run                         # static plus enrichment from a real lint run
/linting-audit --threshold-suppressions-per-file=10  # override default 5

💡 Pro tip: Add --worktree to run this audit in an isolated Git worktree.

The skill never accepts --apply. The implementation plan is descriptive Markdown.

💡 Pro tip: Run /preflight --audit=linting first to detect — and optionally install — the development dependency that makes --with-run useful (eslint or @biomejs/biome, depending on which linter your project uses). Skip if you already know the tooling is wired up.

The opinionated baseline

A check resolves to one of four statuses:

  • present — the invariant holds.
  • partial — most signals resolve, with a small number of exceptions, or the codebase shows mixed adherence to a soft check.
  • missing — a structural prerequisite is absent (no linter installed, for example).
  • violation — the audit identified concrete configuration that breaks the invariant.

Layer 0 is informational only and has no status.

Layer 0 — Diagnostic snapshot (always written, no pass/fail)

  • Detected linter and version (ESLint 9.x, Biome 1.x, or none).
  • Configuration files and their format (flat config eslint.config.{js,ts,mjs}, legacy .eslintrc.*, biome.json/biome.jsonc).
  • Approximate enabled-rule count: sum of rules introduced by extends plus rules explicitly set in the configuration.
  • Source-file count in scope, post-ignore patterns.
  • Total suppression count: eslint-disable* and biome-ignore comments across the codebase.
  • Top 10 most-suppressed rules. Sourced from the actual lint output when running with --with-run; otherwise inferred by parsing the rule names from suppression comments.
  • Top 10 files with the most suppressions, with their suppression count.
  • Total warnings and errors from the actual lint run (only when --with-run).

Layer 1 — Configuration shape

| Check | Expectation | Violation signal | | --- | --- | --- | | Exactly one linter installed | Either ESLint or Biome, not both. | Both eslint and @biomejs/biome present in package.json dependencies. | | Modern configuration format | ESLint uses flat config (eslint.config.{js,ts,mjs}); Biome uses biome.json or biome.jsonc. | ESLint legacy format (.eslintrc.*) in use, deprecated as of ESLint 9. | | Single configuration source | Exactly one configuration file at the repository root (or workspace package root). | Multiple top-level configuration files, or both flat and legacy formats present simultaneously. | | TypeScript parser configured (ESLint only) | The configuration registers @typescript-eslint/parser and either parserOptions.project or parserOptions.projectService so type-aware rules can run. Biome's TypeScript support is implicit. | ESLint configuration without a TypeScript parser despite tsconfig.json being present. | | Declarative configuration | The configuration does not require side-effectful evaluation: no environment-dependent rule selection, no asynchronous configuration loaders. Soft check — reported as partial. | Configuration that branches on process.env in non-trivial ways. |

Layer 2 — Rule coverage

The audit dispatches based on the detected linter. Whichever path runs, every check below is scoped to that linter.

When ESLint is detected

| Check | Expectation | Violation signal | | --- | --- | --- | | Base recommended set extended | The base recommended ruleset is extended (in flat config: js.configs.recommended from @eslint/js; in legacy: eslint:recommended). | No base ruleset extended. | | @typescript-eslint recommended-type-checked or stronger | At least recommended-type-checked is extended; strict-type-checked is preferred. The plain recommended set is reported as partial because it skips the type-aware rules. | No @typescript-eslint configuration; or recommended only (reported as partial). | | eslint-plugin-react/recommended (React only) | When React is detected, the React recommended config is extended. | React project without the plugin configured. | | eslint-plugin-react-hooks/recommended (React only) | When React is detected, the hooks plugin's recommended rules are enabled. | React project without it. | | eslint-plugin-jsx-a11y/recommended (React only) | When React is detected, the accessibility plugin's recommended rules are enabled. (Surfaces the gap here as well as in /accessibility-audit, so a single fix passes both.) | React project without it. | | eslint-plugin-import configured | The import plugin is configured with the TypeScript resolver (eslint-import-resolver-typescript) plus rules for unresolved imports, import order, and no-cycle. | Plugin missing, or installed without the TypeScript resolver. | | eslint-config-prettier last in extends | When Prettier is in the project, eslint-config-prettier is the last entry in the extends list so it disables formatting rules that would conflict with Prettier. | Prettier installed but config not added; or added but not last. | | Node best-practices plugin | When the project has Node-only entry points (server code, build scripts), eslint-plugin-n's recommended rules are enabled. Skipped silently for browser-only frontends. | Node entry points present without the plugin. |

When Biome is detected

| Check | Expectation | Violation signal | | --- | --- | --- | | Linter enabled | linter.enabled is true in biome.json. | Linter disabled. | | Recommended rules enabled | linter.rules.recommended is true. | Recommended rules off. | | Domain rule sets enabled | Each of correctness, suspicious, complexity, performance, security, style, plus a11y (when React detected) has recommended: true, or rule-by-rule coverage of equivalent strength. | Any of the above set off without rule-by-rule replacement. | | Type-aware rules enabled | The configuration does not opt out of TypeScript-specific rules. | javascript.parser.disabled or analogues set in a way that disables TypeScript-aware checks. |

Layer 3 — Strictness and enforcement

| Check | Expectation | Violation signal | | --- | --- | --- | | Lint script in package.json | A lint script exists and invokes the detected linter against the project. | No lint script, or the script invokes a different tool. | | Continuous integration enforces zero warnings | The continuous-integration lint step uses --max-warnings=0 for ESLint, or --error-on-warnings for Biome. | Workflow runs lint without the zero-warnings flag, or lint failures don't fail the build. | | Type-aware rules actually enabled (ESLint only) | When @typescript-eslint/parser is configured, parserOptions.project (or the flat-config parserOptions.projectService) is set so type-aware rules can run. | Parser configured but the project pointer is missing — type-aware rules silently no-op. | | No globally disabled rules without justification | The configuration does not turn off rules from extended recommended sets globally without an inline comment explaining why. | A rule overridden to 'off' (or 0) at the top level of the configuration without a comment. | | Lint errors fail the build | Continuous integration treats lint errors as build failures: no || true, no continue-on-error: true on the lint step. | Workflow patterns that swallow lint failures. | | Editor integration available | A workspace-level recommendation exists for the linter's editor extension (.vscode/extensions.json for VS Code, equivalent for other editors), so the linter runs locally in the same configuration as continuous integration. Soft check — reported as partial. | No editor-recommendation configuration. |

Layer 4 — Suppressions hygiene

| Check | Expectation | Violation signal | | --- | --- | --- | | No blanket file-level disables without justification | /* eslint-disable */ (no rule list) at the top of a file is reported as violation unless the same line (or the line above) carries a free-text justification. Equivalent: // biome-ignore-all at the top of a file in Biome. | Blanket disable with no following justification. | | Each disable specifies rules | eslint-disable-next-line and inline disable comments specify which rules they disable, never blanket. Same expectation for Biome's biome-ignore comments. | Bare eslint-disable-next-line (or analogous) with no rule names. | | Each suppression carries a justification | Every suppression comment is followed by free-text justification (on the same line or the line above). Soft check — reported as partial when adherence is mixed. | Suppression comments with no surrounding explanation. | | ignores/.eslintignore does not exclude production source | The ignore patterns do not exclude entire production source directories, individual feature folders, or *.ts/*.tsx blanketly. | Patterns that ignore production code under src/ (or the framework equivalent). | | No stale ignore entries | Every entry in the ignore list resolves to at least one existing file or directory. | Entries pointing at paths that no longer exist. | | Suppression density is reasonable | Files contain at most the threshold suppressions each (default 5; tunable via --threshold-suppressions-per-file). Soft check — reported as partial above the threshold. | Files exceeding the threshold. |

What this skill does

  1. Reads the knowledge graph when present. Soft dependency: when graphify-out/graph.json exists, the implementation plan can rank suppression-heavy files by graph centrality — a suppression in a god node is more consequential than one in a leaf utility, and the plan recommends those for cleanup first. The audit still runs in full when the graph is absent.
  2. Confirms a TypeScript project. Detects package.json, tsconfig.json, and a TypeScript dependency. If absent, the skill stops and tells the user it currently supports TypeScript projects only.
  3. Detects the linter. Looks for eslint and/or @biomejs/biome in package.json dependencies, then for the configuration files of each. When neither is detected, the audit stops with a clear message: a project with no linter is a /quality-gates-audit problem first.
  4. Detects React for the React-conditional rule-coverage checks.
  5. When --with-run is set, invokes the detected linter in JSON-reporter mode, captures the output, and parses it. If the lint command fails to start (binary missing, configuration syntactically invalid), records the failure and degrades run-dependent checks to partial.
  6. Writes Layer 0 — the diagnostic snapshot to .architect-audits/linting-audit/snapshot.md and prepends the same content to findings.md.
  7. Walks each check in the active layer list, dispatching to the ESLint or Biome variant where the layer 2 checks differ. Records a status, evidence, and (where relevant) sample file references per check.
  8. Writes phase 1 outputs to .architect-audits/linting-audit/:
  • findings.md — diagnostic snapshot followed by check results, grouped by layer.
  • findings.json — machine-readable.
  • snapshot.md — diagnostic snapshot on its own.
  • metadata.json — skill version, run timestamp, Graphify revision (when present), detected linter and version, React-detected flag, applied thresholds, applied filters, run output presence.
  1. Phase 2 — offers to plan the gaps. Summarises the findings in chat and asks the user a single yes-or-no question:

> "Generate an implementation plan for the linting gaps? (yes/no)"

On yes, writes .architect-audits/linting-audit/implementation-plan.md describing exactly which configuration entries to add or change, which plugins to install, which suppressions to clean up first (graph-prioritised when the graph is present), and which continuous-integration steps to tighten — ordered by layer. The plan does not modify any project files.

On no, exits cleanly.

Implementation steps

Step 1 — Confirm the prerequisites

test -f package.json || { echo "linting-audit: no package.json detected. This skill currently supports TypeScript projects only."; exit 1; }
test -f tsconfig.json || { echo "linting-audit: no tsconfig.json detected. This skill currently supports TypeScript projects only."; exit 1; }

Step 2 — Detect the linter

Read package.json dependencies:

  • eslint present → ESLint path.
  • @biomejs/biome present → Biome path.
  • Both present → record both, run the appropriate path for whichever is configured (presence of eslint.config.*/.eslintrc.* vs biome.json), and surface the dual-installation as a violation on the layer 1 "exactly one linter installed" check.
  • Neither present → stop with a clear message:

> linting-audit requires a linter (ESLint or Biome). No linter detected. Install one and configure it before running this audit; /quality-gates-audit will surface the gap as well.

Step 3 — Detect React

Look for react in dependencies (directly or via Next.js, Remix, etc.). Determines whether the React-specific rule-coverage checks run.

Step 4 — Optionally run the linter

When --with-run is set, invoke the detected linter:

  • ESLint: npx eslint . --format json (capture stdout, parse JSON).
  • Biome: npx biome lint --reporter json . (capture stdout, parse JSON).

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.