mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 06:06:37 +03:00
* Add inline, in-file ignore comments for the detector (issue #283) Complement config ignores with eslint-disable-style waivers that live where they apply and travel with the file when it leaves the repo. The motivating case is a generated/exported standalone document that legitimately uses a first-party brand typeface (on the overused-font list) and is later scanned without .impeccable/config.json present. Marker is comment-syntax-agnostic (works in //, /* */, <!-- -->, #, {/* */}): impeccable-disable <rule>[, <rule>...] [-- reason | : reason] whole file impeccable-disable-line <rule>... same line impeccable-disable-next-line <rule>... next line Bare directive or * means every rule; reason is optional and discarded at scan time. Behavior is suppression, for parity with config ignores. Implementation: - New pure module cli/engine/shared/inline-ignores.mjs (parser + filter, no Node deps). Static-HTML findings have no line number, so only whole-file directives apply there -- exactly the standalone-document case; the regex/text engine additionally honors the line-scoped forms. - Wired into detectText and detectHtml, gated by options.inlineIgnores. - detect CLI applies inline ignores by default; --no-inline-ignores skips just them, --no-config skips config and inline ignores together. Docs: config.md (new section), detector.md, README. skill/reference/hooks.md reversed its prior "inline comments are not supported" guidance and now points the agent to inline waivers for the travels-with-the-file case. Changelog 3.x. Tests: tests/inline-ignores.test.mjs (parser units, detectText/detectHtml integration, CLI end-to-end), registered in the detector suite. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reconcile design hook wording with inline ignores Two hook-side fixes prompted by review of the new inline-ignore feature: 1. Clean-ack steer line. The old line ("Keep typography hierarchy, spacing rhythm, and color contrast intentional on the next change.") read as an odd non-sequitur after "No anti-patterns." Reworded the whole clean ack to say what it means: a clean scan only clears the deterministic rule set, not overall design quality, so keep following the design system and skill guidance. Now: "Design hook scanned X. No deterministic design-quality issues found. That does not mean the design is good: keep following the project design system and the impeccable skill guidance." 2. Directive footer. It still told the agent "Do not add source comments such as `impeccable: ignore`; those pollute the code and do not suppress hook findings." That is now misleading: the hook runs the same detector engine as the CLI, which honors inline `impeccable-disable` waivers, so they DO suppress hook findings (consistent with config ignores, which filterFindings already honors). Reworded to: don't silence a real finding to skip fixing it; suppress only after the user confirms intent; prefer a config ignore, and reach for an inline `impeccable-disable <rule>` comment only when the waiver must travel with a file that leaves the repo. Added a hook test asserting an inline `impeccable-disable-line` comment makes the hook scan the file clean (locks in the cross-cutting behavior), and updated the clean-ack / footer assertions to the new wording. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address review on inline-ignores parser - Case-insensitive fast-path bail-out (Cursor): the cheap substring guard was lowercase-only while DIRECTIVE_RE has the `i` flag, so a mixed-case marker like `Impeccable-Disable` skipped parsing entirely and never suppressed. Switched the guard to `/impeccable-disable/i.test(...)`. Added a regression test. - Removed the unreachable `-->` branch from TRAILING_CLOSER_RE (Greptile): `--+>` already matches `-->` and any longer dash run. - Replaced the always-truthy lazy-match + `if (sep)` reason strip with an explicit first-separator slice (Greptile): clearer and drops the dead branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Align inline-ignore line numbering with the detector (CRLF/CR endings) parseInlineIgnores split lines with /\r\n|\r|\n/, but detectText numbers lines with split('\n'). On classic `\r`-only endings the two diverged, so a disable-line / disable-next-line directive could key a different line than the finding it should waive (Cursor review). Split on '\n' only, matching the detector exactly; the directive regex already excludes '\r', so a trailing '\r' on CRLF files is never captured into the rule list. Added a CRLF regression test through the real detectText. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
127 lines
4.7 KiB
Markdown
127 lines
4.7 KiB
Markdown
---
|
|
title: Detector CLI
|
|
tagline: "Run Impeccable's deterministic design checks without an AI harness."
|
|
description: "Use npx impeccable detect on files, directories, stdin, and URLs; understand findings, exit codes, ignores, and design-system-aware checks."
|
|
section: automation
|
|
order: 1
|
|
---
|
|
|
|
`npx impeccable detect` runs Impeccable's deterministic design checks directly from the terminal. Use it when you want a fast signal without asking an AI command to review the work.
|
|
|
|
## Fast path
|
|
|
|
Scan the source folder:
|
|
|
|
```bash
|
|
npx impeccable detect src/
|
|
```
|
|
|
|
Scan one file:
|
|
|
|
```bash
|
|
npx impeccable detect src/components/Card.tsx
|
|
```
|
|
|
|
Scan a rendered page:
|
|
|
|
```bash
|
|
npx impeccable detect https://example.com
|
|
```
|
|
|
|
Use JSON when another script or CI job needs to read the result:
|
|
|
|
```bash
|
|
npx impeccable detect --json src/
|
|
```
|
|
|
|
## What it checks
|
|
|
|
The detector looks for design and implementation patterns that are usually visible to users: contrast problems, typography drift, layout overflow, generic AI-design tells, brittle motion, and design-system violations when `DESIGN.md` exists.
|
|
|
|
Directories are walked for design-relevant files. HTML files include linked local CSS. Framework files such as JSX, TSX, Vue, Svelte, Astro, and CSS modules get source-text checks. URL targets use a browser and inspect the rendered page.
|
|
|
|
## How to read results
|
|
|
|
Plain output groups findings by file and prints the rule id, snippet, and explanation. Exit codes are:
|
|
|
|
| Code | Meaning |
|
|
|---|---|
|
|
| `0` | No findings. |
|
|
| `2` | Findings were detected. |
|
|
| `1` | The command failed. |
|
|
|
|
That makes CI usage straightforward: fail the job on `2`, then decide whether to fix the issue or add a narrow ignore.
|
|
|
|
## DESIGN.md awareness
|
|
|
|
When a local `DESIGN.md` exists, `detect` loads it by default and enables design-system checks for fonts, literal colors, and border radii. The generated `.impeccable/design.json` sidecar gives those checks richer token and ramp data.
|
|
|
|
If the design file is stale, refresh it:
|
|
|
|
```text
|
|
/impeccable document
|
|
```
|
|
|
|
If you need one scan without design-system checks:
|
|
|
|
```bash
|
|
npx impeccable detect --no-design-system src/
|
|
```
|
|
|
|
## Managing intentional findings
|
|
|
|
Detector ignores are shared with the design hook:
|
|
|
|
```bash
|
|
npx impeccable ignores list
|
|
npx impeccable ignores add-value overused-font Inter --reason "Brand font"
|
|
npx impeccable ignores add-file "src/legacy/**"
|
|
```
|
|
|
|
For a waiver that should travel with one file instead of living in the repo config, drop an inline comment in the file itself:
|
|
|
|
```html
|
|
<!-- impeccable-disable overused-font: exported brand doc -->
|
|
```
|
|
|
|
Use [Config and ignores](/docs/config) for the full ignore workflow, including the line-scoped `impeccable-disable-line` and `impeccable-disable-next-line` forms.
|
|
|
|
## Details when the default path is not enough
|
|
|
|
<details class="docs-prose-details">
|
|
<summary>Scan stdin</summary>
|
|
<div>
|
|
<p>If you pipe text into the command with no target, it scans stdin:</p>
|
|
<pre><code>cat component.css | npx impeccable detect</code></pre>
|
|
</div>
|
|
</details>
|
|
|
|
<details class="docs-prose-details">
|
|
<summary>Project config and raw scans</summary>
|
|
<div>
|
|
<p>By default, <code>detect</code> reads <code>.impeccable/config.json</code> and <code>.impeccable/config.local.json</code>.</p>
|
|
<p>It respects <code>detector.ignoreRules</code>, <code>detector.ignoreFiles</code>, <code>detector.ignoreValues</code>, and <code>detector.designSystem.enabled</code>.</p>
|
|
<p>It does not respect <code>hook.enabled</code>; manual scans still run when the automatic hook is disabled.</p>
|
|
<p>In-file <code>impeccable-disable*</code> comments are honored too, so a waiver can travel with a file. <code>--no-inline-ignores</code> skips just those; <code>--no-config</code> skips config and inline ignores together.</p>
|
|
<p>Use <code>--no-config</code> only when you want a raw detector run with no project config, no detector ignores, and no <code>DESIGN.md</code> context.</p>
|
|
</div>
|
|
</details>
|
|
|
|
<details class="docs-prose-details">
|
|
<summary>Provider-specific checks</summary>
|
|
<div>
|
|
<p>Some rules are provider-specific and opt in:</p>
|
|
<pre><code>npx impeccable detect --gpt src/
|
|
npx impeccable detect --gemini src/</code></pre>
|
|
<p>Leave them off for normal project quality checks. Turn them on when you specifically want to catch model-family fingerprints.</p>
|
|
</div>
|
|
</details>
|
|
|
|
<details class="docs-prose-details">
|
|
<summary>Where the detector fits</summary>
|
|
<div>
|
|
<p>The same detector also powers the design hook, <code>/impeccable audit</code>, the public <a href="/slop">slop catalog</a>, the browser extension, and the local detector lab.</p>
|
|
<p>Use <a href="/docs/hooks">Design hooks</a> when you want findings inside the agent flow. Use <code>detect</code> when you want a direct terminal signal.</p>
|
|
</div>
|
|
</details>
|