prodlint 0.3.0 → 0.5.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 CHANGED
@@ -1,130 +1,175 @@
1
1
  # prodlint
2
2
 
3
- [![CI](https://github.com/prodlint/prodlint/actions/workflows/ci.yml/badge.svg)](https://github.com/prodlint/prodlint/actions/workflows/ci.yml)
4
3
  [![npm version](https://img.shields.io/npm/v/prodlint.svg)](https://www.npmjs.com/package/prodlint)
5
4
  [![npm downloads](https://img.shields.io/npm/dm/prodlint.svg)](https://www.npmjs.com/package/prodlint)
6
- [![prodlint](https://img.shields.io/badge/prodlint-99%2F100-brightgreen)](https://prodlint.com)
7
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
6
 
9
- Scan AI-generated projects for production readiness issues.
7
+ Catch the bugs AI leaves behind.
10
8
 
11
- prodlint is a deterministic, zero-config CLI that checks your codebase for common problems in AI-generated and vibe-coded projects. No LLM required just pattern matching against known anti-patterns.
12
-
13
- ## Why?
14
-
15
- AI code generators (Cursor, Copilot, v0, Bolt) ship code that works in demos but breaks in production. Hardcoded secrets, hallucinated packages, missing auth checks, XSS vectors — these issues slip through because they're syntactically valid and pass type-checks.
16
-
17
- prodlint catches what TypeScript and ESLint miss: **production readiness gaps**.
18
-
19
- ## Quick Start
9
+ prodlint scans AI-generated JavaScript and TypeScript projects for production readiness issues hallucinated imports, missing auth, exposed secrets, N+1 queries, and more. No LLM required, just fast static analysis against known failure modes.
20
10
 
21
11
  ```bash
22
12
  npx prodlint
23
13
  ```
24
14
 
25
- ## Example Output
26
-
27
15
  ```
28
- prodlint v0.2.2
29
- Scanned 142 files in 87ms
16
+ prodlint v0.5.0
17
+ Scanned 148 files · 3 critical · 5 warnings
30
18
 
31
- src/app/api/users/route.ts
32
- 8:1 CRIT API route has no authentication check auth-checks
33
- 8:1 WARN API route has no rate limiting rate-limiting
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
34
22
 
35
- src/components/chat.tsx
36
- 24:5 CRIT Hardcoded Stripe secret key detected secrets
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))
37
26
 
38
27
  src/lib/db.ts
39
- 15:1 CRIT SQL query built with template literal interpolation sql-injection
28
+ 1:1 CRIT Package "drizzle-orm" is imported but not in package.json hallucinated-imports
40
29
 
41
30
  Scores
42
- security 40 ████████░░░░░░░░░░░░
43
- reliability 70 ██████████████░░░░░░
44
- performance 95 ███████████████████░
45
- ai-quality 88 ██████████████████░░
31
+ security 72 ████████████████░░░░ (8 issues)
32
+ reliability 85 █████████████████░░░ (4 issues)
33
+ performance 95 ███████████████████░ (1 issue)
34
+ ai-quality 90 ██████████████████░░ (3 issues)
46
35
 
47
- Overall: 73/100
36
+ Overall: 82/100 (weighted)
48
37
 
49
- 3 critical · 4 warnings · 2 info
38
+ 3 critical · 5 warnings · 3 info
50
39
  ```
51
40
 
52
- ## Usage
41
+ ## Why?
53
42
 
54
- ```bash
55
- npx prodlint # Scan current directory
56
- npx prodlint ./my-app # Scan specific path
57
- npx prodlint --json # JSON output
58
- npx prodlint --ignore "*.test.ts" # Ignore patterns
59
- ```
43
+ AI code generators (Cursor, Copilot, v0, Bolt, Claude) write code that works in demos but breaks in production. Hardcoded secrets, hallucinated packages, missing auth, XSS vectors — these pass type-checks and look correct but aren't.
44
+
45
+ prodlint catches what TypeScript and ESLint miss: **production readiness gaps**.
60
46
 
61
- ## What It Checks
62
-
63
- prodlint runs **11 rules** across 3 categories:
64
-
65
- ### Security
66
- | Rule | Severity | What it detects |
67
- |------|----------|----------------|
68
- | `secrets` | critical | Hardcoded API keys (Stripe, AWS, Supabase, OpenAI, GitHub, SendGrid) |
69
- | `env-exposure` | critical | Server env vars in client components, `.env` not in `.gitignore` |
70
- | `auth-checks` | critical | API routes without authentication (middleware-aware) |
71
- | `unsafe-html` | critical | `dangerouslySetInnerHTML`, direct `innerHTML` assignment |
72
- | `sql-injection` | critical | SQL queries built with template literals or string concatenation |
73
- | `input-validation` | warning | API routes accessing request body without validation |
74
- | `rate-limiting` | warning | API routes without rate limiting |
75
- | `cors-config` | warning | `Access-Control-Allow-Origin: *`, `cors()` with no config |
76
-
77
- ### Reliability
78
- | Rule | Severity | What it detects |
79
- |------|----------|----------------|
80
- | `hallucinated-imports` | critical | Imports of packages not in `package.json` and not Node built-ins |
81
- | `error-handling` | warning | API routes without try/catch, empty catch blocks |
82
-
83
- ### AI Quality
84
- | Rule | Severity | What it detects |
85
- |------|----------|----------------|
86
- | `ai-smells` | mixed | TODOs, placeholder functions, console.log spam, excessive `any`, commented-out code |
47
+ ## Install
87
48
 
88
- ## Scoring
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
+ ```
89
57
 
90
- Each category starts at 100 points. Deductions:
58
+ Or install it:
91
59
 
92
- - **Critical**: -10 points
93
- - **Warning**: -3 points
94
- - **Info**: -1 point
60
+ ```bash
61
+ npm i -D prodlint # Project dependency
62
+ npm i -g prodlint # Global install
63
+ ```
95
64
 
96
- Overall score = average of all category scores. Exit code is `1` if any critical findings exist, `0` otherwise.
65
+ ## 32 Rules across 4 Categories
66
+
67
+ ### Security (14 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
+
86
+ ### Reliability (7 rules)
87
+
88
+ | Rule | What it catches |
89
+ |------|----------------|
90
+ | `hallucinated-imports` | Imports of packages not in package.json |
91
+ | `error-handling` | Async operations without try/catch |
92
+ | `unhandled-promise` | Floating promises with no await or .catch |
93
+ | `shallow-catch` | Empty catch blocks that swallow errors |
94
+ | `missing-loading-state` | Client components that fetch without a loading state |
95
+ | `missing-error-boundary` | Route layouts without a matching error.tsx |
96
+ | `missing-transaction` | Multiple Prisma writes without `$transaction` |
97
+
98
+ ### Performance (4 rules)
99
+
100
+ | Rule | What it catches |
101
+ |------|----------------|
102
+ | `no-sync-fs` | `readFileSync` in API routes |
103
+ | `no-n-plus-one` | Database calls inside loops |
104
+ | `no-unbounded-query` | `.findMany()` / `.select('*')` with no limit |
105
+ | `no-dynamic-import-loop` | `import()` inside loops |
106
+
107
+ ### AI Quality (7 rules)
108
+
109
+ | Rule | What it catches |
110
+ |------|----------------|
111
+ | `ai-smells` | `any` types, `console.log`, TODO comments piling up |
112
+ | `placeholder-content` | Lorem ipsum, example emails, "your-api-key-here" left in production code |
113
+ | `hallucinated-api` | `.flatten()`, `.contains()`, `.substr()` — methods AI invents |
114
+ | `stale-fallback` | `localhost:3000` hardcoded in production code |
115
+ | `comprehension-debt` | Functions over 80 lines, deep nesting, too many parameters |
116
+ | `codebase-consistency` | Mixed naming conventions across the project |
117
+ | `dead-exports` | Exported functions that nothing imports |
97
118
 
98
119
  ## Smart Detection
99
120
 
100
121
  prodlint avoids common false positives:
101
122
 
102
- - **Block comment awareness** — patterns inside `/* */` comments are ignored
103
- - **Middleware auth detection** — if your project uses Clerk/NextAuth/Supabase middleware, auth findings are downgraded to info
104
- - **TypeScript path aliases** — `@/`, `~/`, and custom tsconfig paths aren't flagged as hallucinated imports
123
+ - **AST parsing** — Babel-based analysis for loops, imports, and SQL templates with regex fallback
124
+ - **Framework awareness** — Prisma, Drizzle, Supabase, Knex, and Sequelize whitelists prevent false SQL injection flags
125
+ - **Middleware detection** — Clerk, NextAuth, Supabase middleware detected auth findings downgraded
126
+ - **Block comment awareness** — patterns inside `/* */` are ignored
127
+ - **Path alias support** — `@/`, `~/`, and tsconfig paths aren't flagged as hallucinated imports
105
128
  - **Route exemptions** — auth, webhook, health, and cron routes are exempt from auth/rate-limit checks
129
+ - **Test/script file awareness** — lower severity for non-production files
130
+ - **Fix suggestions** — findings include actionable `fix` hints with remediation code
131
+
132
+ ## Scoring
133
+
134
+ Each category starts at 100. Deductions per finding:
135
+
136
+ | Severity | Deduction | Per-rule cap |
137
+ |----------|-----------|--------------|
138
+ | critical | -8 | max 1 |
139
+ | warning | -2 | max 2 |
140
+ | info | -0.5 | max 3 |
141
+
142
+ **Diminishing returns**: after 30 points deducted in a category, further deductions are halved; after 50, quartered.
143
+
144
+ **Weighted overall**: security 40%, reliability 30%, performance 15%, ai-quality 15%. Floor at 0. Exit code `1` if any critical findings exist.
106
145
 
107
146
  ## GitHub Action
108
147
 
109
- Add prodlint to your CI pipeline. It posts a score summary as a PR comment and can fail builds below a threshold.
148
+ Add to `.github/workflows/prodlint.yml`:
110
149
 
111
150
  ```yaml
112
- - uses: prodlint/prodlint@v1
113
- with:
114
- threshold: 70 # Fail if score < 70 (optional)
115
- comment: true # Post PR comment (default: true)
116
- ignore: '*.test.ts, __mocks__/**' # Ignore patterns (optional)
151
+ name: Prodlint
152
+ on: [pull_request]
153
+
154
+ jobs:
155
+ scan:
156
+ runs-on: ubuntu-latest
157
+ steps:
158
+ - uses: actions/checkout@v4
159
+ - uses: prodlint/prodlint@v1
160
+ with:
161
+ threshold: 50
117
162
  ```
118
163
 
119
- **Inputs:**
164
+ Posts a score breakdown as a PR comment and fails the build if below threshold.
165
+
120
166
  | Input | Default | Description |
121
167
  |-------|---------|-------------|
122
168
  | `path` | `.` | Path to scan |
123
169
  | `threshold` | `0` | Minimum score to pass (0-100) |
124
- | `ignore` | `''` | Comma-separated glob patterns to ignore |
125
- | `comment` | `true` | Post a PR comment with results |
170
+ | `ignore` | | Comma-separated glob patterns to ignore |
171
+ | `comment` | `true` | Post PR comment with results |
126
172
 
127
- **Outputs:**
128
173
  | Output | Description |
129
174
  |--------|-------------|
130
175
  | `score` | Overall score (0-100) |
@@ -132,46 +177,33 @@ Add prodlint to your CI pipeline. It posts a score summary as a PR comment and c
132
177
 
133
178
  ## MCP Server
134
179
 
135
- prodlint ships an MCP server for AI coding tools (Cursor, Claude Code, Windsurf, etc.).
136
-
137
- ```bash
138
- npx prodlint-mcp
139
- ```
140
-
141
- ### Claude Code
180
+ Use prodlint inside Cursor, Claude Code, or any MCP-compatible editor:
142
181
 
182
+ **Claude Code:**
143
183
  ```bash
144
184
  claude mcp add prodlint npx prodlint-mcp
145
185
  ```
146
186
 
147
- ### Cursor / Windsurf
148
-
149
- Add to your MCP config:
150
-
187
+ **Cursor / Windsurf:**
151
188
  ```json
152
189
  {
153
190
  "mcpServers": {
154
191
  "prodlint": {
155
192
  "command": "npx",
156
- "args": ["prodlint-mcp"]
193
+ "args": ["-y", "prodlint-mcp"]
157
194
  }
158
195
  }
159
196
  }
160
197
  ```
161
198
 
162
- The MCP server exposes a single `scan` tool that accepts a project path and returns the full score breakdown with findings.
199
+ Ask your AI: *"Run prodlint on this project"* and it calls the `scan` tool directly.
163
200
 
164
- ## Suppressing Findings
201
+ ## Suppression
165
202
 
166
203
  Suppress a single line:
167
204
  ```ts
168
205
  // prodlint-disable-next-line secrets
169
- const key = "sk_test_example_for_documentation"
170
- ```
171
-
172
- Suppress multiple rules:
173
- ```ts
174
- // prodlint-disable-next-line secrets, auth-checks
206
+ const key = "sk_test_example_for_docs"
175
207
  ```
176
208
 
177
209
  Suppress an entire file (place at top):
@@ -189,9 +221,11 @@ console.log(result.overallScore) // 0-100
189
221
  console.log(result.findings) // Finding[]
190
222
  ```
191
223
 
192
- ## Contributing
224
+ ## Badge
193
225
 
194
- See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and how to add new rules.
226
+ ```md
227
+ [![prodlint](https://img.shields.io/badge/prodlint-85%2F100-brightgreen)](https://prodlint.com)
228
+ ```
195
229
 
196
230
  ## License
197
231