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