taste-lint 0.0.1 → 0.0.4

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
@@ -1,141 +1,62 @@
1
1
  <div align="center">
2
2
 
3
- # [taste-lint](https://github.com/mblode/taste-lint)
3
+ # Taste Lint
4
4
 
5
- **Taste rules from [Agent Skills](https://github.com/mblode/agent-skills) and [Taste Training](https://blode.co/taste-training), run as a linter**
5
+ **Catch AI slop before you ship.**
6
6
 
7
- Point it at Markdown, MDX, TSX or a rendered page and get findings with a severity and a probability.
7
+ Scan your project with local checks and [Jev by TypeSafe AI](https://docs.typesafe.ai/introduction).
8
8
 
9
- </div>
9
+ <p align="center">
10
+ <a href="https://www.npmjs.com/package/taste-lint"><img alt="npm version" src="https://img.shields.io/npm/v/taste-lint?style=flat&colorA=000000&colorB=000000" /></a>
11
+ <a href="https://github.com/mblode/taste-lint/blob/main/LICENSE.md"><img alt="MIT license" src="https://img.shields.io/npm/l/taste-lint?style=flat&colorA=000000&colorB=000000" /></a>
12
+ </p>
10
13
 
11
- ## Quickstart
14
+ </div>
12
15
 
13
- Requires Node 24.11 or later. Bring your own [Vercel AI Gateway API key](https://vercel.com/docs/ai-gateway/authentication-and-byok/api-keys): open **AI Gateway → API Keys → Create Key** in your Vercel dashboard.
16
+ ## Install
14
17
 
15
18
  ```bash
16
- npm install -g taste-lint
17
- export AI_GATEWAY_API_KEY="your-vercel-ai-gateway-key"
18
-
19
- # Run from your project directory
20
- taste-lint scan .
21
- ```
22
-
23
- No taste-lint account or configuration file is required. Model usage is billed to your Vercel AI Gateway account. Taste-lint reads the key from your environment and sends selected text and rule context directly to the gateway.
24
-
25
- Preview scope and estimated cost with `taste-lint scan . --dry-run`. Try local checks without a key using `taste-lint scan . --mechanical-only`. The default scan focuses on product interfaces; use `--profile writing` for documentation or `--profile instructions` for agent instructions.
26
-
27
- Semantic rules remain advisory until calibrated against independent holdout evidence. Mechanical checks can fail a run immediately.
28
-
29
- ## Where the rules come from
30
-
31
- [Agent Skills](https://github.com/mblode/agent-skills) provides reusable instructions for coding agents. [Taste Training](https://blode.co/taste-training) teaches people to spot and fix problems in typography, copy, interaction, and motion. Taste-lint turns applicable guidance into repeatable checks, with source references attached to individual rules.
32
-
33
- ## Example findings
34
-
35
- ```text
36
- PASS: 161 active rules in data/rules
37
-
38
- notes.md
39
- [MINOR] typography-straight-quotes (p=1.00) notes.md:3:1
40
- Straight quotes in rendered copy
41
- 2 matches: "'", "'"
42
- Fix: Replace with the matching curly mark. Opening after whitespace or at the start, closing otherwise; an apostrophe is always the right single quote.
43
- [MINOR?] copywriting-claim-without-evidence (p=0.95) notes.md:3:1
44
- Quality claimed, nothing the reader could check
45
- 3 matches: "fast", "powerful", "seamless"; p=0.95
46
- Fix: Replace the adjective with the mechanism, the number or the standard it stands for. If none exists, cut the sentence.
47
-
48
- Units: 3 | Rules: 161 | Act: 1 | Review: 4 | Unknown: 0
49
- Jev: 2 requests, 0 cached answers, 7238 input tokens, $0.0003
50
- FAIL - 1 finding in the act band
19
+ npx taste-lint@latest init
51
20
  ```
52
21
 
53
- ## Two answers per finding
54
-
55
- - **Severity:** how bad the finding is if real, `major` or `minor`. Set by the rule, never by the model.
56
- - **Band:** how sure the tool is. `act` fails the run (mechanical hits, or Jev at or above the rule's act threshold), `review` prints a note with a `?`, below that is silent.
57
- - **Cost:** eligible questions about one unit are batched into requests. Preview estimated cost with `--dry-run`; runs report usage and reuse cached answers. Current rates are listed in the [Vercel AI Gateway model catalog](https://vercel.com/ai-gateway/models).
58
-
59
- ## Rule packs
60
-
61
- - **Typography:** straight quotes, dashes, ellipses, primes and units from `typography-audit`, plus size, weight, tracking and line-height checks over resolved Tailwind classes or computed styles.
62
- - **Copywriting:** claims without evidence, vague errors, friction CTAs, hedges and register shifts from `docs-writing` and the ui-design copy guideline, and Every's published AI-tell checker: 19 of its 21 questions, one rule each, with phrase candidates from the MIT `cw-ai-check` skill where it has them. Not ported: `uniform_cadence` (sentence-length arithmetic) and `formatting_overuse` (needs headings and bullets a paragraph never sees). The two authorship verdicts are excluded on purpose: taste-lint reports defects, not authorship.
63
- - **Interaction and craft:** the static checks of `ui-design/rules` as whole-file patterns (focus traps, error and empty states, target size, i18n, lazy loading) plus the shadcn/lint class hygiene rules (raw palette colours, arbitrary values, interpolated class strings).
64
- - **Motion and product:** the `ui-animation` flag-on-sight table (ease-in, linear easing, transitions over 300ms, `transition-all`, entrances from scale zero, no reduced-motion variant) and the two deterministic `product-design` rules.
22
+ Requires Node 24.11 or later. Run from your project directory to install locally and add check scripts.
65
23
 
66
- Every rule names the file and line of the skill or lesson it came from, and `taste-lint rules list` prints tier, status and category per rule.
24
+ ## Quickstart
67
25
 
68
- ## Rendered mode
26
+ Create a [Vercel AI Gateway key](https://vercel.com/docs/ai-gateway/authentication-and-byok/api-keys). From your project directory, set your key and run:
69
27
 
70
28
  ```bash
71
- taste-lint lint --url https://example.com/pricing --selector main
29
+ export AI_GATEWAY_API_KEY="your-vercel-ai-gateway-key"
30
+ npm run taste
72
31
  ```
73
32
 
74
- Runs [style-capture](https://www.npmjs.com/package/style-capture) in headless Chromium and lints computed styles: real pixel sizes, line heights, weights and letter-spacing, so the typography rules judge what the reader sees rather than what the class list implies. `--capture file.json` lints a saved capture.
33
+ No account or config for taste-lint. AI checks send selected text and rule context to Vercel AI Gateway, billed to your account. Answers are cached for repeat runs.
75
34
 
76
- ## API
35
+ Run `npm run check:taste` for local checks without a key. Use your package manager in place of npm. Add `--agent` to init for agent instructions, or `--dry-run` to preview setup.
77
36
 
78
- ```typescript
79
- import { runLint } from "taste-lint";
37
+ ## What it checks
80
38
 
81
- const result = await runLint({ root: process.cwd(), targets: ["content"] });
82
- console.log(result.scorecard.byDomain, result.usage.costUsd);
83
- ```
39
+ - **Product interfaces:** copy, typography, interaction, and motion in JSX, TSX, and CSS.
40
+ - **Writing:** Markdown, MDX, and READMEs with `--profile writing`.
41
+ - **Agent instructions:** AGENTS.md and skills with `--profile instructions`.
84
42
 
85
- `runLint` takes the same options as the `lint` command and returns findings, unknowns, the scorecard and usage. `taste-lint schema` prints every command, flag and default as JSON, and `--output json` turns an error into a `{ error, code, message }` envelope on stdout.
43
+ Rules draw on [Agent Skills](https://github.com/mblode/agent-skills) and [Taste Training](https://blode.co/taste-training). Local checks handle measurable rules. Jev judges meaning and returns probabilities. Uncalibrated AI rules stay advisory; active findings can fail a run.
86
44
 
87
- ## Agent skill
45
+ ## Useful options
88
46
 
89
- ```bash
90
- npx skills add mblode/taste-lint
91
- ```
47
+ | Option | What it does |
48
+ | ------------------- | ---------------------------------------------------- |
49
+ | `--dry-run` | Preview scope and estimated cost without model calls |
50
+ | `--mechanical-only` | Run local checks without an API key |
51
+ | `--output json` | Save findings for scripts and agents |
52
+ | `--output sarif` | Export findings for code review tools |
92
53
 
93
- Installs the `taste-lint` skill for Claude Code, Codex, Cursor and OpenCode: how to read a finding, the dry-run-first workflow, and the gotchas. Source: [skills/taste-lint/SKILL.md](skills/taste-lint/SKILL.md).
94
-
95
- ## Options
96
-
97
- | Flag | Default | Description |
98
- | --- | --- | --- |
99
- | `--dry-run` | | Plan and print units, requests and estimated cost without calling Jev |
100
- | `--mechanical-only` | | Skip every Jev-backed rule; no key needed |
101
- | `--only <ids>` | | Comma-separated rule ids |
102
- | `--exclude <globs>` | | Comma-separated globs to skip, added to `taste-lint.config.json` |
103
- | `--fail-on <severity>` | `minor` | Lowest severity that fails the run |
104
- | `--fix` | | Apply deterministic fixes (curly quotes, ellipsis, multiplication sign, unit spaces) to act-band findings |
105
- | `--output <format>` | `tty` | `tty`, `json` or `sarif` |
106
- | `--url <url>` | | Lint a rendered page through style-capture |
107
-
108
- `taste-lint eval` scores every rule against its labelled corpus (precision, recall, Wilson intervals, a calibration table) and `taste-lint tune` picks act thresholds from the dev split, promoting a rule only when the fixed threshold also clears the precision lower bound on an independent holdout. Both label classes, enough evaluated items, complete scoring, and source/text separation are required. `taste-lint eval coverage` reports class balance and split leakage without API calls; add `--output json` to coverage or evaluation for structured results.
54
+ Run `taste-lint scan --help` for all options. See the [scan guide](https://github.com/mblode/taste-lint/blob/main/docs/SCANS.md), [usage reference](https://github.com/mblode/taste-lint/blob/main/docs/USAGE.md), and [changelog](https://github.com/mblode/taste-lint/blob/main/CHANGELOG.md) for more.
109
55
 
110
56
  ## License
111
57
 
112
58
  MIT
113
59
 
114
- ## Reading a repository run
115
-
116
- The default text report summarizes scope, top rules and up to 30 examples. Use `--verbose` for the full list; every completed or incomplete run also saves a complete JSON report and prints its path. JSON v1 keeps the original grouped `findings`; `ruleFindings` preserves every rule's evidence and `coverage` counts eligible checks. `summary.failing` respects `--fail-on`, and determines the exit code together with run completeness.
117
-
118
- ```bash
119
- taste-lint lint --root ../my-site apps/web --dry-run
120
- taste-lint lint --root ../my-site apps/web --progress --output json > audit.json
121
- ```
122
-
123
- Progress goes to stderr. A fully cached run needs no API key. An incomplete report includes a retry command that reuses successful answers. Cost is reported from known usage, excluding any unreported provider billing for failures.
124
-
125
- Configuration is optional at `taste-lint.config.json` in the scan root. Its editor schema ships at `node_modules/taste-lint/data/config.schema.json`. Unknown fields and invalid types fail before evaluation. Select the scope explicitly: documentation and agent instructions remain included when you request a whole repository.
126
-
127
- ```json
128
- {
129
- "$schema": "./node_modules/taste-lint/data/config.schema.json",
130
- "exclude": ["docs/archive/**"],
131
- "docTypes": [
132
- { "glob": "apps/web/content/writing/**/*.mdx", "type": "explanation" }
133
- ]
134
- }
135
- ```
136
-
137
- See [TypeSafe contracts](docs/TYPESAFE.md) and the [review-rule evaluation](docs/evaluations/blode-co-review.md) for the implementation evidence and current calibration limits.
138
-
139
- See [skill packs](docs/SKILL-PACKS.md) for repository checks, architecture policy, personal-writing context, and source discovery.
60
+ ---
140
61
 
141
- Use `taste-lint scan . --profile product --dry-run` to preview a focused scan. The [scan workflow](docs/SCANS.md) covers profiles, baselines, review decisions, changed-code SARIF, calibration samples, graph-tool reports, and remediation exports.
62
+ Crafted by [<img src="https://blode.co/avatar-circle.png" width="20" align="top" alt="" />](https://blode.co) [Matthew Blode](https://blode.co)
@@ -1,3 +1,4 @@
1
+ # Disabled after real-project review: this pattern lacks evidence of a defect.
1
2
  # Ported from mblode/agent-skills skills/ui-design/rules/slop-affordance-mismatch.md by scripts/port-rules.ts.
2
3
  # Keys listed in handWritten are preserved on re-run; everything else is regenerated.
3
4
  id: craft-affordance-mismatch
@@ -20,4 +21,4 @@ mechanical:
20
21
  severity: minor
21
22
  fix:
22
23
  hint: A card lifts on hover, the cursor turns into a hand, the border brightens, and clicking does nothing. The user has already committed to the click by the time they learn it was a decoration; they click again, assume the page is broken or slow, and then trust the next hover state less. This is worse t
23
- status: review-only
24
+ status: draft
@@ -1,3 +1,4 @@
1
+ # Disabled after real-project review: this pattern lacks evidence of a defect.
1
2
  # Ported from mblode/agent-skills skills/ui-design/rules/perf-virtualize-large-lists.md by scripts/port-rules.ts.
2
3
  # Keys listed in handWritten are preserved on re-run; everything else is regenerated.
3
4
  id: craft-virtualize-large-lists
@@ -21,4 +22,4 @@ mechanical:
21
22
  severity: minor
22
23
  fix:
23
24
  hint: Large lists (roughly >50 visible items) should use virtualization/windowing. Rendering the whole dataset stalls scrolling and grows memory with the list.
24
- status: review-only
25
+ status: draft
@@ -14,13 +14,13 @@ scope:
14
14
  - "**/README.md"
15
15
  unit: [heading, jsx-text, attr-string]
16
16
  mechanical:
17
- # Three or more consecutive capitalised words. Proper nouns also match, so Jev decides.
18
- regex: "\\b[A-Z][a-z]+(?: (?:[A-Z][a-z]+|of|the|and|for|to|a|in|on|with)){2,}\\b"
19
- flags: gu
17
+ # Whole-label candidate: embedded capitalised names in a sentence are not Title Case.
18
+ regex: "^(?:[A-Z][a-z]+|of|the|and|for|to|a|in|on|with)(?: (?:[A-Z][a-z]+|of|the|and|for|to|a|in|on|with)){2,}[?!:.]?$"
19
+ flags: u
20
20
  question:
21
21
  context: [role]
22
22
  instructions: >-
23
- The TEXT is a heading, button label, tab or field label. Return true when most of its words start with a capital letter because it is set in Title Case, not because those words are names of people, products, places or organisations. Return false when the capitals are proper nouns or acronyms, when the TEXT is a single word, or when it is an ordinary sentence with one capital at the start.
23
+ Evaluate capitalisation of ordinary words only. Ignore the initial word and all words belonging to a product, person, place or organisation name. An imperative followed by a product name is sentence case, even when every word begins with a capital. If the supplied text does not establish that a capitalised phrase is ordinary words rather than a name, return false. The TEXT is a heading, button label, tab or field label. Return true when most of its words start with a capital letter because it is set in Title Case, not because those words are names of people, products, places or organisations. Return false when the capitals are proper nouns or acronyms, when the TEXT is a single word, or when it is an ordinary sentence with one capital at the start.
24
24
  criteria:
25
25
  true:
26
26
  what: Ordinary words capitalised as a heading style.
@@ -34,6 +34,8 @@ question:
34
34
  - "Connect Google Drive and Microsoft Teams"
35
35
  - "Manage your team settings"
36
36
  - "New York office hours"
37
+ - "Open Cedar Notes"
38
+ - "Ask River Desk"
37
39
  thresholds: { review: 0.4, act: 0.75 }
38
40
  severity: minor
39
41
  fix: