prodlint 0.5.0 → 0.6.0
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 +31 -11
- package/action.yml +2 -2
- package/dist/cli.js +1076 -3
- package/dist/index.js +1075 -2
- package/dist/mcp.js +1077 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,16 +4,16 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/prodlint)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The linter for vibe-coded apps.
|
|
8
8
|
|
|
9
|
-
|
|
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
10
|
|
|
11
11
|
```bash
|
|
12
12
|
npx prodlint
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
```
|
|
16
|
-
prodlint v0.
|
|
16
|
+
prodlint v0.6.0
|
|
17
17
|
Scanned 148 files · 3 critical · 5 warnings
|
|
18
18
|
|
|
19
19
|
src/app/api/checkout/route.ts
|
|
@@ -40,9 +40,9 @@ npx prodlint
|
|
|
40
40
|
|
|
41
41
|
## Why?
|
|
42
42
|
|
|
43
|
-
|
|
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
44
|
|
|
45
|
-
prodlint catches what TypeScript and ESLint miss: **
|
|
45
|
+
prodlint catches what TypeScript and ESLint miss: **the bugs AI coding tools consistently write**.
|
|
46
46
|
|
|
47
47
|
## Install
|
|
48
48
|
|
|
@@ -62,9 +62,9 @@ npm i -D prodlint # Project dependency
|
|
|
62
62
|
npm i -g prodlint # Global install
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
##
|
|
65
|
+
## 52 Rules across 4 Categories
|
|
66
66
|
|
|
67
|
-
### Security (
|
|
67
|
+
### Security (27 rules)
|
|
68
68
|
|
|
69
69
|
| Rule | What it catches |
|
|
70
70
|
|------|----------------|
|
|
@@ -82,8 +82,21 @@ npm i -g prodlint # Global install
|
|
|
82
82
|
| `leaked-env-in-logs` | `process.env.*` inside console.log calls |
|
|
83
83
|
| `insecure-random` | `Math.random()` used for tokens, secrets, or session IDs |
|
|
84
84
|
| `next-server-action-validation` | Server actions using formData without Zod/schema validation |
|
|
85
|
-
|
|
86
|
-
|
|
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)
|
|
87
100
|
|
|
88
101
|
| Rule | What it catches |
|
|
89
102
|
|------|----------------|
|
|
@@ -94,8 +107,12 @@ npm i -g prodlint # Global install
|
|
|
94
107
|
| `missing-loading-state` | Client components that fetch without a loading state |
|
|
95
108
|
| `missing-error-boundary` | Route layouts without a matching error.tsx |
|
|
96
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 |
|
|
97
114
|
|
|
98
|
-
### Performance (
|
|
115
|
+
### Performance (6 rules)
|
|
99
116
|
|
|
100
117
|
| Rule | What it catches |
|
|
101
118
|
|------|----------------|
|
|
@@ -103,8 +120,10 @@ npm i -g prodlint # Global install
|
|
|
103
120
|
| `no-n-plus-one` | Database calls inside loops |
|
|
104
121
|
| `no-unbounded-query` | `.findMany()` / `.select('*')` with no limit |
|
|
105
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 |
|
|
106
125
|
|
|
107
|
-
### AI Quality (
|
|
126
|
+
### AI Quality (8 rules)
|
|
108
127
|
|
|
109
128
|
| Rule | What it catches |
|
|
110
129
|
|------|----------------|
|
|
@@ -115,6 +134,7 @@ npm i -g prodlint # Global install
|
|
|
115
134
|
| `comprehension-debt` | Functions over 80 lines, deep nesting, too many parameters |
|
|
116
135
|
| `codebase-consistency` | Mixed naming conventions across the project |
|
|
117
136
|
| `dead-exports` | Exported functions that nothing imports |
|
|
137
|
+
| `use-client-overuse` | `"use client"` on files that don't use any client-side APIs |
|
|
118
138
|
|
|
119
139
|
## Smart Detection
|
|
120
140
|
|
package/action.yml
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
name: 'Prodlint'
|
|
2
|
-
description: '
|
|
2
|
+
description: 'The linter for vibe-coded apps — catch what AI coding tools miss'
|
|
3
3
|
branding:
|
|
4
4
|
icon: 'shield'
|
|
5
5
|
color: 'green'
|
|
@@ -24,7 +24,7 @@ inputs:
|
|
|
24
24
|
|
|
25
25
|
outputs:
|
|
26
26
|
score:
|
|
27
|
-
description: 'Overall
|
|
27
|
+
description: 'Overall prodlint score (0-100)'
|
|
28
28
|
value: ${{ steps.scan.outputs.score }}
|
|
29
29
|
critical:
|
|
30
30
|
description: 'Number of critical findings'
|