prodlint 0.7.0 → 0.7.1

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 prodlint contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 prodlint contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,252 +1,253 @@
1
- # prodlint
2
-
3
- [![npm version](https://img.shields.io/npm/v/prodlint.svg)](https://www.npmjs.com/package/prodlint)
4
- [![npm downloads](https://img.shields.io/npm/dm/prodlint.svg)](https://www.npmjs.com/package/prodlint)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
-
7
- The linter for vibe-coded apps.
8
-
9
- Cursor, v0, Bolt, and Copilot build fast. prodlint catches what they miss — hallucinated imports, missing auth, hardcoded secrets, unvalidated server actions, and the other production bugs that compile just fine. Zero config, no LLM, fast static analysis.
10
-
11
- ```bash
12
- npx prodlint
13
- ```
14
-
15
- ```
16
- prodlint v0.6.0
17
- Scanned 148 files · 3 critical · 5 warnings
18
-
19
- src/app/api/checkout/route.ts
20
- 12:1 CRIT No rate limiting — anyone could spam this endpoint and run up your API costs rate-limiting
21
- 28:5 WARN Empty catch block silently swallows error shallow-catch
22
-
23
- src/actions/submit.ts
24
- 5:3 CRIT Server action uses formData without validation next-server-action-validation
25
- ↳ Validate with Zod: const data = schema.safeParse(Object.fromEntries(formData))
26
-
27
- src/lib/db.ts
28
- 1:1 CRIT Package "drizzle-orm" is imported but not in package.json hallucinated-imports
29
-
30
- Scores
31
- security 72 ████████████████░░░░ (8 issues)
32
- reliability 85 █████████████████░░░ (4 issues)
33
- performance 95 ███████████████████░ (1 issue)
34
- ai-quality 90 ██████████████████░░ (3 issues)
35
-
36
- Overall: 82/100 (weighted)
37
-
38
- 3 critical · 5 warnings · 3 info
39
- ```
40
-
41
- ## Why?
42
-
43
- Vibe coding is the fastest way to build. It's also the fastest way to ship hardcoded secrets, hallucinated packages, missing auth, and XSS vectors to production. These pass type-checks and look correct — but they aren't.
44
-
45
- prodlint catches what TypeScript and ESLint miss: **the bugs AI coding tools consistently write**.
46
-
47
- ## Install
48
-
49
- ```bash
50
- npx prodlint # Run directly (no install)
51
- npx prodlint ./my-app # Scan specific path
52
- npx prodlint --json # JSON output for CI
53
- npx prodlint --ignore "*.test.ts" # Ignore patterns
54
- npx prodlint --min-severity warning # Only warnings and criticals
55
- npx prodlint --quiet # Suppress badge output
56
- ```
57
-
58
- Or install it:
59
-
60
- ```bash
61
- npm i -D prodlint # Project dependency
62
- npm i -g prodlint # Global install
63
- ```
64
-
65
- ## 52 Rules across 4 Categories
66
-
67
- ### Security (27 rules)
68
-
69
- | Rule | What it catches |
70
- |------|----------------|
71
- | `secrets` | API keys, tokens, passwords hardcoded in source |
72
- | `auth-checks` | API routes with no authentication |
73
- | `env-exposure` | `NEXT_PUBLIC_` on server-only secrets |
74
- | `input-validation` | Request body used without validation |
75
- | `cors-config` | `Access-Control-Allow-Origin: *` |
76
- | `unsafe-html` | `dangerouslySetInnerHTML` with user data |
77
- | `sql-injection` | String-interpolated SQL queries (ORM-aware) |
78
- | `open-redirect` | User input passed to `redirect()` |
79
- | `rate-limiting` | API routes with no rate limiter |
80
- | `phantom-dependency` | Packages in node_modules but missing from package.json |
81
- | `insecure-cookie` | Session cookies missing httpOnly/secure/sameSite |
82
- | `leaked-env-in-logs` | `process.env.*` inside console.log calls |
83
- | `insecure-random` | `Math.random()` used for tokens, secrets, or session IDs |
84
- | `next-server-action-validation` | Server actions using formData without Zod/schema validation |
85
- | `env-fallback-secret` | Security-sensitive env vars with hardcoded fallback values |
86
- | `verbose-error-response` | Error stack traces or messages leaked in API responses |
87
- | `missing-webhook-verification` | Webhook routes without signature verification |
88
- | `server-action-auth` | Server actions with mutations but no auth check |
89
- | `eval-injection` | `eval()`, `new Function()`, dynamic code execution |
90
- | `next-public-sensitive` | `NEXT_PUBLIC_` prefix on secret env vars |
91
- | `ssrf-risk` | User-controlled URLs passed to fetch in server code |
92
- | `path-traversal` | File system operations with unsanitized user input |
93
- | `unsafe-file-upload` | File upload handlers without type or size validation |
94
- | `supabase-missing-rls` | `CREATE TABLE` in migrations without enabling RLS |
95
- | `deprecated-oauth-flow` | OAuth Implicit Grant (response_type=token) |
96
- | `jwt-no-expiry` | JWT tokens signed without an expiration |
97
- | `client-side-auth-only` | Password comparisons or auth logic in client components |
98
-
99
- ### Reliability (11 rules)
100
-
101
- | Rule | What it catches |
102
- |------|----------------|
103
- | `hallucinated-imports` | Imports of packages not in package.json |
104
- | `error-handling` | Async operations without try/catch |
105
- | `unhandled-promise` | Floating promises with no await or .catch |
106
- | `shallow-catch` | Empty catch blocks that swallow errors |
107
- | `missing-loading-state` | Client components that fetch without a loading state |
108
- | `missing-error-boundary` | Route layouts without a matching error.tsx |
109
- | `missing-transaction` | Multiple Prisma writes without `$transaction` |
110
- | `redirect-in-try-catch` | `redirect()` inside try/catch — Next.js redirect throws, catch swallows it |
111
- | `missing-revalidation` | Server actions with DB mutations but no `revalidatePath` |
112
- | `missing-useeffect-cleanup` | useEffect with subscriptions/timers but no cleanup return |
113
- | `hydration-mismatch` | `window`/`Date.now()`/`Math.random()` in server component render path |
114
-
115
- ### Performance (6 rules)
116
-
117
- | Rule | What it catches |
118
- |------|----------------|
119
- | `no-sync-fs` | `readFileSync` in API routes |
120
- | `no-n-plus-one` | Database calls inside loops |
121
- | `no-unbounded-query` | `.findMany()` / `.select('*')` with no limit |
122
- | `no-dynamic-import-loop` | `import()` inside loops |
123
- | `server-component-fetch-self` | Server components fetching their own API routes |
124
- | `missing-abort-controller` | Fetch calls without timeout or AbortController |
125
-
126
- ### AI Quality (8 rules)
127
-
128
- | Rule | What it catches |
129
- |------|----------------|
130
- | `ai-smells` | `any` types, `console.log`, TODO comments piling up |
131
- | `placeholder-content` | Lorem ipsum, example emails, "your-api-key-here" left in production code |
132
- | `hallucinated-api` | `.flatten()`, `.contains()`, `.substr()` — methods AI invents |
133
- | `stale-fallback` | `localhost:3000` hardcoded in production code |
134
- | `comprehension-debt` | Functions over 80 lines, deep nesting, too many parameters |
135
- | `codebase-consistency` | Mixed naming conventions across the project |
136
- | `dead-exports` | Exported functions that nothing imports |
137
- | `use-client-overuse` | `"use client"` on files that don't use any client-side APIs |
138
-
139
- ## Smart Detection
140
-
141
- prodlint avoids common false positives:
142
-
143
- - **AST parsing** — Babel-based analysis for loops, imports, and SQL templates with regex fallback
144
- - **Framework awareness** — Prisma, Drizzle, Supabase, Knex, and Sequelize whitelists prevent false SQL injection flags
145
- - **Middleware detection** — Clerk, NextAuth, Supabase middleware detected auth findings downgraded
146
- - **Block comment awareness** — patterns inside `/* */` are ignored
147
- - **Path alias support** — `@/`, `~/`, and tsconfig paths aren't flagged as hallucinated imports
148
- - **Route exemptions** — auth, webhook, health, and cron routes are exempt from auth/rate-limit checks
149
- - **Test/script file awareness** — lower severity for non-production files
150
- - **Fix suggestions** — findings include actionable `fix` hints with remediation code
151
-
152
- ## Scoring
153
-
154
- Each category starts at 100. Deductions per finding:
155
-
156
- | Severity | Deduction | Per-rule cap |
157
- |----------|-----------|--------------|
158
- | critical | -8 | max 1 |
159
- | warning | -2 | max 2 |
160
- | info | -0.5 | max 3 |
161
-
162
- **Diminishing returns**: after 30 points deducted in a category, further deductions are halved; after 50, quartered.
163
-
164
- **Weighted overall**: security 40%, reliability 30%, performance 15%, ai-quality 15%. Floor at 0. Exit code `1` if any critical findings exist.
165
-
166
- ## GitHub Action
167
-
168
- Add to `.github/workflows/prodlint.yml`:
169
-
170
- ```yaml
171
- name: Prodlint
172
- on: [pull_request]
173
-
174
- jobs:
175
- scan:
176
- runs-on: ubuntu-latest
177
- steps:
178
- - uses: actions/checkout@v4
179
- - uses: prodlint/prodlint@v1
180
- with:
181
- threshold: 50
182
- ```
183
-
184
- Posts a score breakdown as a PR comment and fails the build if below threshold.
185
-
186
- | Input | Default | Description |
187
- |-------|---------|-------------|
188
- | `path` | `.` | Path to scan |
189
- | `threshold` | `0` | Minimum score to pass (0-100) |
190
- | `ignore` | | Comma-separated glob patterns to ignore |
191
- | `comment` | `true` | Post PR comment with results |
192
-
193
- | Output | Description |
194
- |--------|-------------|
195
- | `score` | Overall score (0-100) |
196
- | `critical` | Number of critical findings |
197
-
198
- ## MCP Server
199
-
200
- Use prodlint inside Cursor, Claude Code, or any MCP-compatible editor:
201
-
202
- **Claude Code:**
203
- ```bash
204
- claude mcp add prodlint npx prodlint-mcp
205
- ```
206
-
207
- **Cursor / Windsurf:**
208
- ```json
209
- {
210
- "mcpServers": {
211
- "prodlint": {
212
- "command": "npx",
213
- "args": ["-y", "prodlint-mcp"]
214
- }
215
- }
216
- }
217
- ```
218
-
219
- Ask your AI: *"Run prodlint on this project"* and it calls the `scan` tool directly.
220
-
221
- ## Suppression
222
-
223
- Suppress a single line:
224
- ```ts
225
- // prodlint-disable-next-line secrets
226
- const key = "sk_test_example_for_docs"
227
- ```
228
-
229
- Suppress an entire file (place at top):
230
- ```ts
231
- // prodlint-disable secrets
232
- ```
233
-
234
- ## Programmatic API
235
-
236
- ```ts
237
- import { scan } from 'prodlint'
238
-
239
- const result = await scan({ path: './my-project' })
240
- console.log(result.overallScore) // 0-100
241
- console.log(result.findings) // Finding[]
242
- ```
243
-
244
- ## Badge
245
-
246
- ```md
247
- [![prodlint](https://img.shields.io/badge/prodlint-85%2F100-brightgreen)](https://prodlint.com)
248
- ```
249
-
250
- ## License
251
-
252
- MIT
1
+ # prodlint
2
+
3
+ [![npm version](https://img.shields.io/npm/v/prodlint.svg)](https://www.npmjs.com/package/prodlint)
4
+ [![npm downloads](https://img.shields.io/npm/dm/prodlint.svg)](https://www.npmjs.com/package/prodlint)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ The linter for vibe-coded apps.
8
+
9
+ Cursor, v0, Bolt, and Copilot build fast. prodlint catches what they miss — hallucinated imports, missing auth, hardcoded secrets, unvalidated server actions, and the other production bugs that compile just fine. Zero config, no LLM, fast static analysis.
10
+
11
+ ```bash
12
+ npx prodlint
13
+ ```
14
+
15
+ ```
16
+ prodlint v0.7.0
17
+ Scanned 148 files · 3 critical · 5 warnings
18
+
19
+ src/app/api/checkout/route.ts
20
+ 12:1 CRIT No rate limiting — anyone could spam this endpoint and run up your API costs rate-limiting
21
+ 28:5 WARN Empty catch block silently swallows error shallow-catch
22
+
23
+ src/actions/submit.ts
24
+ 5:3 CRIT Server action uses formData without validation next-server-action-validation
25
+ ↳ Validate with Zod: const data = schema.safeParse(Object.fromEntries(formData))
26
+
27
+ src/lib/db.ts
28
+ 1:1 CRIT Package "drizzle-orm" is imported but not in package.json hallucinated-imports
29
+
30
+ Scores
31
+ security 72 ████████████████░░░░ (8 issues)
32
+ reliability 85 █████████████████░░░ (4 issues)
33
+ performance 95 ███████████████████░ (1 issue)
34
+ ai-quality 90 ██████████████████░░ (3 issues)
35
+
36
+ Overall: 82/100 (weighted)
37
+
38
+ 3 critical · 5 warnings · 3 info
39
+ ```
40
+
41
+ ## Why?
42
+
43
+ Vibe coding is the fastest way to build. It's also the fastest way to ship hardcoded secrets, hallucinated packages, missing auth, and XSS vectors to production. These pass type-checks and look correct — but they aren't.
44
+
45
+ prodlint catches what TypeScript and ESLint miss: **the bugs AI coding tools consistently write**.
46
+
47
+ ## Install
48
+
49
+ ```bash
50
+ npx prodlint # Run directly (no install)
51
+ npx prodlint ./my-app # Scan specific path
52
+ npx prodlint --json # JSON output for CI
53
+ npx prodlint --ignore "*.test.ts" # Ignore patterns
54
+ npx prodlint --min-severity warning # Only warnings and criticals
55
+ npx prodlint --quiet # Suppress badge output
56
+ ```
57
+
58
+ Or install it:
59
+
60
+ ```bash
61
+ npm i -D prodlint # Project dependency
62
+ npm i -g prodlint # Global install
63
+ ```
64
+
65
+ ## 52 Rules across 4 Categories
66
+
67
+ ### Security (27 rules)
68
+
69
+ | Rule | What it catches |
70
+ |------|----------------|
71
+ | `secrets` | API keys, tokens, passwords hardcoded in source |
72
+ | `auth-checks` | API routes with no authentication |
73
+ | `env-exposure` | `NEXT_PUBLIC_` on server-only secrets |
74
+ | `input-validation` | Request body used without validation |
75
+ | `cors-config` | `Access-Control-Allow-Origin: *` |
76
+ | `unsafe-html` | `dangerouslySetInnerHTML` with user data |
77
+ | `sql-injection` | String-interpolated SQL queries (ORM-aware) |
78
+ | `open-redirect` | User input passed to `redirect()` |
79
+ | `rate-limiting` | API routes with no rate limiter |
80
+ | `phantom-dependency` | Packages in node_modules but missing from package.json |
81
+ | `insecure-cookie` | Session cookies missing httpOnly/secure/sameSite |
82
+ | `leaked-env-in-logs` | `process.env.*` inside console.log calls |
83
+ | `insecure-random` | `Math.random()` used for tokens, secrets, or session IDs |
84
+ | `next-server-action-validation` | Server actions using formData without Zod/schema validation |
85
+ | `env-fallback-secret` | Security-sensitive env vars with hardcoded fallback values |
86
+ | `verbose-error-response` | Error stack traces or messages leaked in API responses |
87
+ | `missing-webhook-verification` | Webhook routes without signature verification |
88
+ | `server-action-auth` | Server actions with mutations but no auth check |
89
+ | `eval-injection` | `eval()`, `new Function()`, dynamic code execution |
90
+ | `next-public-sensitive` | `NEXT_PUBLIC_` prefix on secret env vars |
91
+ | `ssrf-risk` | User-controlled URLs passed to fetch in server code |
92
+ | `path-traversal` | File system operations with unsanitized user input |
93
+ | `unsafe-file-upload` | File upload handlers without type or size validation |
94
+ | `supabase-missing-rls` | `CREATE TABLE` in migrations without enabling RLS |
95
+ | `deprecated-oauth-flow` | OAuth Implicit Grant (response_type=token) |
96
+ | `jwt-no-expiry` | JWT tokens signed without an expiration |
97
+ | `client-side-auth-only` | Password comparisons or auth logic in client components |
98
+
99
+ ### Reliability (11 rules)
100
+
101
+ | Rule | What it catches |
102
+ |------|----------------|
103
+ | `hallucinated-imports` | Imports of packages not in package.json |
104
+ | `error-handling` | Async operations without try/catch |
105
+ | `unhandled-promise` | Floating promises with no await or .catch |
106
+ | `shallow-catch` | Empty catch blocks that swallow errors |
107
+ | `missing-loading-state` | Client components that fetch without a loading state |
108
+ | `missing-error-boundary` | Route layouts without a matching error.tsx |
109
+ | `missing-transaction` | Multiple Prisma writes without `$transaction` |
110
+ | `redirect-in-try-catch` | `redirect()` inside try/catch — Next.js redirect throws, catch swallows it |
111
+ | `missing-revalidation` | Server actions with DB mutations but no `revalidatePath` |
112
+ | `missing-useeffect-cleanup` | useEffect with subscriptions/timers but no cleanup return |
113
+ | `hydration-mismatch` | `window`/`Date.now()`/`Math.random()` in server component render path |
114
+
115
+ ### Performance (6 rules)
116
+
117
+ | Rule | What it catches |
118
+ |------|----------------|
119
+ | `no-sync-fs` | `readFileSync` in API routes |
120
+ | `no-n-plus-one` | Database calls inside loops |
121
+ | `no-unbounded-query` | `.findMany()` / `.select('*')` with no limit |
122
+ | `no-dynamic-import-loop` | `import()` inside loops |
123
+ | `server-component-fetch-self` | Server components fetching their own API routes |
124
+ | `missing-abort-controller` | Fetch calls without timeout or AbortController |
125
+
126
+ ### AI Quality (8 rules)
127
+
128
+ | Rule | What it catches |
129
+ |------|----------------|
130
+ | `ai-smells` | `any` types, `console.log`, TODO comments piling up |
131
+ | `placeholder-content` | Lorem ipsum, example emails, "your-api-key-here" left in production code |
132
+ | `hallucinated-api` | `.flatten()`, `.contains()`, `.substr()` — methods AI invents |
133
+ | `stale-fallback` | `localhost:3000` hardcoded in production code |
134
+ | `comprehension-debt` | Functions over 80 lines, deep nesting, too many parameters |
135
+ | `codebase-consistency` | Mixed naming conventions across the project |
136
+ | `dead-exports` | Exported functions that nothing imports |
137
+ | `use-client-overuse` | `"use client"` on files that don't use any client-side APIs |
138
+
139
+ ## Smart Detection
140
+
141
+ prodlint avoids common false positives:
142
+
143
+ - **AST parsing** — Babel-based analysis for 12 rules (imports, catch blocks, redirects, SSRF, path traversal, JWT, HTML injection, hydration, transactions, env leaks, loops, SQL) with regex fallback
144
+ - **Monorepo support** — npm/yarn/pnpm workspace dependencies resolved automatically
145
+ - **Framework awareness** — Prisma, Drizzle, Supabase, Knex, and Sequelize whitelists prevent false SQL injection flags
146
+ - **Middleware detection** — Clerk, NextAuth, Supabase middleware detected — auth findings downgraded
147
+ - **Block comment awareness** — patterns inside `/* */` are ignored
148
+ - **Path alias support** — `@/`, `~/`, and tsconfig paths aren't flagged as hallucinated imports
149
+ - **Route exemptions** — auth, webhook, health, and cron routes are exempt from auth/rate-limit checks
150
+ - **Test/script file awareness** — lower severity for non-production files
151
+ - **Fix suggestions** — findings include actionable `fix` hints with remediation code
152
+
153
+ ## Scoring
154
+
155
+ Each category starts at 100. Deductions per finding:
156
+
157
+ | Severity | Deduction | Per-rule cap |
158
+ |----------|-----------|--------------|
159
+ | critical | -8 | max 1 |
160
+ | warning | -2 | max 2 |
161
+ | info | -0.5 | max 3 |
162
+
163
+ **Diminishing returns**: after 30 points deducted in a category, further deductions are halved; after 50, quartered.
164
+
165
+ **Weighted overall**: security 40%, reliability 30%, performance 15%, ai-quality 15%. Floor at 0. Exit code `1` if any critical findings exist.
166
+
167
+ ## GitHub Action
168
+
169
+ Add to `.github/workflows/prodlint.yml`:
170
+
171
+ ```yaml
172
+ name: Prodlint
173
+ on: [pull_request]
174
+
175
+ jobs:
176
+ scan:
177
+ runs-on: ubuntu-latest
178
+ steps:
179
+ - uses: actions/checkout@v4
180
+ - uses: prodlint/prodlint@v1
181
+ with:
182
+ threshold: 50
183
+ ```
184
+
185
+ Posts a score breakdown as a PR comment and fails the build if below threshold.
186
+
187
+ | Input | Default | Description |
188
+ |-------|---------|-------------|
189
+ | `path` | `.` | Path to scan |
190
+ | `threshold` | `0` | Minimum score to pass (0-100) |
191
+ | `ignore` | | Comma-separated glob patterns to ignore |
192
+ | `comment` | `true` | Post PR comment with results |
193
+
194
+ | Output | Description |
195
+ |--------|-------------|
196
+ | `score` | Overall score (0-100) |
197
+ | `critical` | Number of critical findings |
198
+
199
+ ## MCP Server
200
+
201
+ Use prodlint inside Cursor, Claude Code, or any MCP-compatible editor:
202
+
203
+ **Claude Code:**
204
+ ```bash
205
+ claude mcp add prodlint npx prodlint-mcp
206
+ ```
207
+
208
+ **Cursor / Windsurf:**
209
+ ```json
210
+ {
211
+ "mcpServers": {
212
+ "prodlint": {
213
+ "command": "npx",
214
+ "args": ["-y", "prodlint-mcp"]
215
+ }
216
+ }
217
+ }
218
+ ```
219
+
220
+ Ask your AI: *"Run prodlint on this project"* and it calls the `scan` tool directly.
221
+
222
+ ## Suppression
223
+
224
+ Suppress a single line:
225
+ ```ts
226
+ // prodlint-disable-next-line secrets
227
+ const key = "sk_test_example_for_docs"
228
+ ```
229
+
230
+ Suppress an entire file (place at top):
231
+ ```ts
232
+ // prodlint-disable secrets
233
+ ```
234
+
235
+ ## Programmatic API
236
+
237
+ ```ts
238
+ import { scan } from 'prodlint'
239
+
240
+ const result = await scan({ path: './my-project' })
241
+ console.log(result.overallScore) // 0-100
242
+ console.log(result.findings) // Finding[]
243
+ ```
244
+
245
+ ## Badge
246
+
247
+ ```md
248
+ [![prodlint](https://img.shields.io/badge/prodlint-85%2F100-brightgreen)](https://prodlint.com)
249
+ ```
250
+
251
+ ## License
252
+
253
+ MIT