eslint-plugin-ai-guard 1.2.8 โ†’ 1.3.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,393 +1,457 @@
1
- <p align="center">
2
- <img src="./assets/logo.png" alt="AI Guard Logo" width="80" />
3
- <h1 align="center">eslint-plugin-ai-guard</h1>
4
- <p align="center">
5
- <strong>๐Ÿ›ก๏ธ GitHub-native guardrails for AI-generated code.</strong>
6
- </p>
7
- <p align="center">
8
- <a href="https://www.npmjs.com/package/eslint-plugin-ai-guard"><img src="https://img.shields.io/npm/v/eslint-plugin-ai-guard.svg?style=flat-square&color=7c3aed" alt="npm version"></a>
9
- <a href="https://github.com/YashJadhav21/eslint-plugin-ai-guard/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/YashJadhav21/eslint-plugin-ai-guard/ci.yml?style=flat-square&label=CI&color=10b981" alt="CI"></a>
10
- <a href="https://www.npmjs.com/package/eslint-plugin-ai-guard"><img src="https://img.shields.io/npm/dm/eslint-plugin-ai-guard.svg?style=flat-square&color=3b82f6" alt="downloads"></a>
11
- <a href="https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/eslint-plugin-ai-guard.svg?style=flat-square&color=64748b" alt="MIT License"></a>
12
- <a href="https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/SECURITY.md"><img src="https://img.shields.io/badge/security-policy-orange?style=flat-square" alt="Security Policy"></a>
13
- </p>
14
- </p>
15
-
16
- ---
17
-
18
- ## What is ai-guard?
19
-
20
- **ai-guard** is an ESLint plugin and GitHub Action that catches reliability and security bugs
21
- specific to AI-generated code โ€” the patterns Copilot, Claude, Cursor, and Gemini consistently get wrong.
22
-
23
- It integrates directly into GitHub pull request workflows: blocking dangerous merges, generating
24
- SARIF reports for GitHub Code Scanning, and posting inline PR annotations at the exact line where
25
- the bug lives.
26
-
27
- ```bash
28
- # Scan immediately โ€” no config needed
29
- npx ai-guard run
30
-
31
- # PR-aware changed-only scan with GitHub Advanced Security
32
- npx ai-guard changed --sarif --sarif-output results.sarif
33
- ```
34
-
35
- > [SCREENSHOT PLACEHOLDER โ€” GitHub PR annotation showing ai-guard finding on a floating promise]
36
-
37
- ---
38
-
39
- ## The Problem
40
-
41
- AI coding assistants generate code that **looks correct but isn't.** The patterns they get wrong
42
- are consistent, predictable, and existing linters don't catch them:
43
-
44
- | Pattern | Why AI Gets It Wrong |
45
- |---------|---------------------|
46
- | `try {} catch (e) {}` | AI adds catch blocks without handling the error |
47
- | `array.map(async ...)` | AI generates async callbacks returning `Promise[]`, not values |
48
- | `fetch(url)` without await | AI forgets to await or handle promise rejection |
49
- | `const apiKey = 'sk-...'` | AI uses placeholder credentials that get committed |
50
- | `eval(userInput)` | AI generates dynamic evaluation without security context |
51
- | `if (true) { ... }` | AI leaves dead scaffolding branches in generated code |
52
-
53
- ai-guard is purpose-built to catch what AI tools consistently get wrong โ€” before those bugs reach production.
54
-
55
- ---
56
-
57
- ## Install
58
-
59
- ```bash
60
- npm install --save-dev eslint-plugin-ai-guard
61
- ```
62
-
63
- **Requirements:** Node.js โ‰ฅ 18 ยท ESLint โ‰ฅ 8
64
-
65
- ---
66
-
67
- ## Quick Start
68
-
69
- ```bash
70
- # Zero-config project scan
71
- npx ai-guard run
72
-
73
- # Security-focused scan
74
- npx ai-guard run --security
75
-
76
- # Strict mode โ€” all 18 rules at error
77
- npx ai-guard run --strict
78
-
79
- # Scan only changed files (PR-aware)
80
- npx ai-guard changed --pr
81
- ```
82
-
83
- **No configuration required.** ai-guard ships with a production-tuned `recommended` preset.
84
-
85
- ---
86
-
87
- ## GitHub Actions Integration
88
-
89
- Drop this into any repository to get PR validation, SARIF-based Code Scanning, and
90
- GitHub Advanced Security integration in under 5 minutes:
91
-
92
- ```yaml
93
- # .github/workflows/ai-guard.yml
94
- name: AI Guard
95
-
96
- on: [pull_request]
97
-
98
- permissions:
99
- security-events: write
100
- contents: read
101
-
102
- jobs:
103
- scan:
104
- runs-on: ubuntu-latest
105
- steps:
106
- - uses: actions/checkout@v4
107
- with:
108
- fetch-depth: 0 # Required for changed-file detection
109
-
110
- - uses: actions/setup-node@v4
111
- with:
112
- node-version: 20
113
- cache: 'npm'
114
-
115
- - run: npm ci
116
-
117
- - name: Scan changed files
118
- run: |
119
- npx ai-guard changed \
120
- --pr \
121
- --strict \
122
- --sarif \
123
- --sarif-output ai-guard-results.sarif \
124
- --fail-on high
125
-
126
- - name: Upload to GitHub Code Scanning
127
- uses: github/codeql-action/upload-sarif@v3
128
- if: always()
129
- with:
130
- sarif_file: ai-guard-results.sarif
131
- category: ai-guard
132
- ```
133
-
134
- This produces:
135
- - โœ… Inline PR annotations at the exact line of each finding
136
- - โœ… GitHub Advanced Security summary ("4 new alerts including 1 high severity")
137
- - โœ… Persistent alerts in `Security โ†’ Code scanning`
138
- - โœ… PR status check that blocks merges on high-severity findings
139
-
140
- > [SCREENSHOT PLACEHOLDER โ€” GitHub Advanced Security summary showing ai-guard findings]
141
-
142
- > [SCREENSHOT PLACEHOLDER โ€” GitHub Code Scanning view with persistent ai-guard alerts]
143
-
144
- > [SCREENSHOT PLACEHOLDER โ€” PR check failing due to high-severity ai-guard finding]
145
-
146
- See [`docs/github-actions.md`](./docs/github-actions.md) for the complete workflow reference
147
- including full-scan mode, baseline mode, and SARIF debugging.
148
-
149
- ---
150
-
151
- ## CLI Commands
152
-
153
- | Command | Description |
154
- |---------|-------------|
155
- | `ai-guard run` | Scan your project with the recommended preset |
156
- | `ai-guard run --strict` | All 18 rules at error โ€” for CI enforcement |
157
- | `ai-guard run --security` | Security rules only |
158
- | `ai-guard run --sarif` | Output SARIF for GitHub Code Scanning |
159
- | `ai-guard run --json` | Output results as JSON (CI-friendly) |
160
- | `ai-guard changed --pr` | Scan only files changed in this PR |
161
- | `ai-guard changed --staged` | Scan only staged files (pre-commit hook) |
162
- | `ai-guard init` | Auto-configure ESLint for your project |
163
- | `ai-guard init-context` | Generate AI agent rules (CLAUDE.md, .cursorrules, etc.) |
164
- | `ai-guard baseline` | Save current issues, track only new ones going forward |
165
- | `ai-guard report` | Generate a shareable HTML report |
166
- | `ai-guard doctor` | Diagnose your ESLint and ai-guard setup |
167
-
168
- ### Fail Strategies
169
-
170
- ```bash
171
- --fail-on errors # Fail on any error-level finding (default)
172
- --fail-on high # Fail only on high-severity findings
173
- --fail-on none # Never fail โ€” always continue
174
- --max-warnings 0 # Fail on any warning
175
- ```
176
-
177
- ### Example Output
178
-
179
- ```
180
- AI GUARD
181
-
182
- Files scanned: 142 ยท Issues in: 7 files ยท Duration: 312ms ยท Preset: strict
183
-
184
- โ”€โ”€ Summary by Category โ”€โ”€
185
-
186
- ๐Ÿ”ด Security 3 errors
187
- ๐ŸŸ  Reliability 2 errors
188
- ๐ŸŸก Async Stability 2 warnings
189
-
190
- Total: 5 errors ยท 2 warnings
191
-
192
- โ”€โ”€ By Rule โ”€โ”€
193
- โ€ข no-hardcoded-secret: 3
194
- โ€ข no-empty-catch: 2
195
- โ€ข no-floating-promise: 2
196
-
197
- โ”€โ”€ Next Steps โ”€โ”€
198
- โ„น Run ai-guard baseline to save these issues and track only new ones
199
- โ„น Run ai-guard report to generate a shareable HTML report
200
- ```
201
-
202
- ---
203
-
204
- ## Rules
205
-
206
- ### ๐Ÿ”ด Security
207
-
208
- | Rule | Recommended | What it catches |
209
- |------|------------|------------------|
210
- | [`no-hardcoded-secret`](./docs/rules/no-hardcoded-secret.md) | **error** | API keys, passwords, tokens in source. Autofix: `process.env.*` |
211
- | [`no-eval-dynamic`](./docs/rules/no-eval-dynamic.md) | **error** | `eval()` / `new Function()` with non-literal args |
212
- | [`no-sql-string-concat`](./docs/rules/no-sql-string-concat.md) | warn | SQL built by string concatenation โ€” SQL injection risk |
213
- | [`no-unsafe-deserialize`](./docs/rules/no-unsafe-deserialize.md) | warn | `JSON.parse(req.body)` without validation |
214
- | [`require-auth-middleware`](./docs/rules/require-auth-middleware.md) | warn | Express/Fastify routes without authentication middleware |
215
- | [`require-authz-check`](./docs/rules/require-authz-check.md) | warn | Resource access without ownership checks |
216
-
217
- ### ๐ŸŸ  Reliability
218
-
219
- | Rule | Recommended | What it catches |
220
- |------|------------|------------------|
221
- | [`no-empty-catch`](./docs/rules/no-empty-catch.md) | **error** | `catch (e) {}` โ€” errors silently vanish. Autofix: inserts TODO |
222
- | [`no-broad-exception`](./docs/rules/no-broad-exception.md) | warn | `catch (e: any)` that hides the real error type |
223
- | [`no-catch-log-rethrow`](./docs/rules/no-catch-log-rethrow.md) | off* | Catch blocks that only `console.log` + rethrow |
224
- | [`no-catch-without-use`](./docs/rules/no-catch-without-use.md) | off* | Caught error variable never used |
225
-
226
- ### ๐ŸŸก Async Stability
227
-
228
- | Rule | Recommended | What it catches |
229
- |------|------------|------------------|
230
- | [`no-floating-promise`](./docs/rules/no-floating-promise.md) | **error** | Async calls with no `await`, return, or `.catch()`. Autofix: adds `void` |
231
- | [`no-async-array-callback`](./docs/rules/no-async-array-callback.md) | warn | `array.map(async ...)` โ€” returns `Promise[]` not values |
232
- | [`no-await-in-loop`](./docs/rules/no-await-in-loop.md) | warn | Sequential `await` in loops โ€” use `Promise.all` |
233
- | [`no-async-without-await`](./docs/rules/no-async-without-await.md) | warn | `async` function that never uses `await` |
234
- | [`no-redundant-await`](./docs/rules/no-redundant-await.md) | off* | `return await` outside try/catch |
235
-
236
- ### ๐Ÿ”ต AI Patterns
237
-
238
- | Rule | Recommended | What it catches |
239
- |------|------------|------------------|
240
- | [`no-dead-branch`](./docs/rules/no-dead-branch.md) | warn | `if (true)`, `if (false)`, `x && !x` โ€” scaffolding leftovers |
241
- | [`no-duplicate-logic-block`](./docs/rules/no-duplicate-logic-block.md) | off* | Consecutive duplicate code blocks |
242
- | [`no-console-in-handler`](./docs/rules/no-console-in-handler.md) | off* | `console.log` in route handlers โ€” use a logger |
243
-
244
- *Enabled at `error` in the `strict` preset.
245
-
246
- Full rule documentation: [`docs/rules/`](./docs/rules/)
247
-
248
- ---
249
-
250
- ## Presets
251
-
252
- | Preset | Purpose | Best For |
253
- |--------|---------|----------|
254
- | `recommended` | Critical issues at `error`, context-sensitive at `warn` | All projects on day one |
255
- | `strict` | All 18 rules at `error` | CI enforcement in mature codebases |
256
- | `security` | Security rules only | Security-focused scanning |
257
-
258
- ### ESLint Flat Config
259
-
260
- ```javascript
261
- // eslint.config.mjs
262
- import aiGuard from 'eslint-plugin-ai-guard';
263
-
264
- export default [
265
- {
266
- plugins: { 'ai-guard': aiGuard },
267
- rules: { ...aiGuard.configs.recommended.rules },
268
- },
269
- ];
270
- ```
271
-
272
- ---
273
-
274
- ## AI Agent Integration
275
-
276
- Generate instruction files so **Claude Code, Cursor, and GitHub Copilot** automatically avoid
277
- the 18 most common AI-generated anti-patterns at generation time:
278
-
279
- ```bash
280
- npx ai-guard init-context
281
- ```
282
-
283
- This writes:
284
- - `CLAUDE.md` โ€” loaded automatically by Claude Code
285
- - `.cursorrules` โ€” loaded automatically by Cursor
286
- - `.github/copilot-instructions.md` โ€” loaded automatically by GitHub Copilot
287
-
288
- Your AI tools will avoid these patterns **before you even run the linter.**
289
-
290
- See [`docs/ai-agents.md`](./docs/ai-agents.md) for the complete integration guide.
291
-
292
- ---
293
-
294
- ## Real-World Example
295
-
296
- ```typescript
297
- // โŒ Typical AI-generated code โ€” 4 issues in one function
298
- async function processUserOrders(userId: string) {
299
- const apiKey = 'sk-prod-1234567890abcdef'; // no-hardcoded-secret
300
-
301
- const orders = await db.query(
302
- 'SELECT * FROM orders WHERE id = ' + userId // no-sql-string-concat
303
- );
304
-
305
- for (const order of orders) {
306
- await sendEmail(order.email); // no-await-in-loop
307
- }
308
-
309
- updateAnalytics(userId); // no-floating-promise
310
- }
311
-
312
- // โœ… After ai-guard fixes
313
- async function processUserOrders(userId: string) {
314
- const apiKey = process.env.API_KEY;
315
-
316
- const orders = await db.query(
317
- 'SELECT * FROM orders WHERE id = $1', [userId]
318
- );
319
-
320
- await Promise.all(orders.map(async (order) => sendEmail(order.email)));
321
-
322
- void updateAnalytics(userId);
323
- }
324
- ```
325
-
326
- ---
327
-
328
- ## Autofix Support
329
-
330
- ```bash
331
- npx eslint src --fix
332
- ```
333
-
334
- | Rule | What Gets Fixed |
335
- |------|-----------------|
336
- | `no-hardcoded-secret` | Literal โ†’ `process.env.VAR_NAME` |
337
- | `no-empty-catch` | Inserts `/* TODO: handle error */` |
338
- | `no-floating-promise` | Marks with `void` |
339
- | `no-await-in-loop` | Rewrites simple loops to `Promise.all(...)` |
340
- | `no-async-without-await` | Removes unnecessary `async` keyword |
341
-
342
- ---
343
-
344
- ## Philosophy
345
-
346
- - **Precision over recall** โ€” we'd rather miss a bug than create noise
347
- - **Low false positives** โ€” a rule that fires on valid code goes to `warn` or gets disabled
348
- - **Gradual adoption** โ€” `recommended` is safe for day-one; `strict` is opt-in
349
- - **Self-validating** โ€” ai-guard scans its own source in CI with the strict preset
350
- - **GitHub-native** โ€” SARIF output, Code Scanning, PR annotations are first-class features
351
-
352
- ---
353
-
354
- ## Development
355
-
356
- ```bash
357
- git clone https://github.com/YashJadhav21/eslint-plugin-ai-guard.git
358
- cd eslint-plugin-ai-guard
359
- npm install
360
- npm run test # 667 tests across 39 test files
361
- npm run build # Build CJS + ESM bundles
362
- npm run typecheck # TypeScript strict check
363
- npm run lint:self # Scan own source with ai-guard
364
- ```
365
-
366
- See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development guide.
367
-
368
- ---
369
-
370
- ## Documentation
371
-
372
- | Doc | Purpose |
373
- |-----|---------|
374
- | [`docs/github-actions.md`](./docs/github-actions.md) | GitHub Actions workflow reference |
375
- | [`docs/ai-agents.md`](./docs/ai-agents.md) | AI agent integration guide |
376
- | [`docs/architecture.md`](./docs/architecture.md) | Architecture and internals |
377
- | [`docs/rules/`](./docs/rules/) | Per-rule documentation |
378
- | [`CONTRIBUTING.md`](./CONTRIBUTING.md) | Contribution guide |
379
- | [`SECURITY.md`](./SECURITY.md) | Security policy |
380
- | [`CHANGELOG.md`](./CHANGELOG.md) | Release history |
381
- | [`ROADMAP.md`](./ROADMAP.md) | Planned features |
382
-
383
- ---
384
-
385
- ## License
386
-
387
- [MIT](LICENSE) โ€” free forever. No rules behind a paywall.
388
-
389
- ---
390
-
391
- <p align="center">
392
- Built to make AI-assisted development reliable and trustworthy. โšก
393
- </p>
1
+ <p align="center">
2
+ <img src="./assets/logo.png" alt="AI Guard Logo" width="80" />
3
+ <h1 align="center">eslint-plugin-ai-guard</h1>
4
+ <p align="center">
5
+ <strong>๐Ÿ›ก๏ธ GitHub-native guardrails for AI-generated code.</strong>
6
+ </p>
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/eslint-plugin-ai-guard"><img src="https://img.shields.io/npm/v/eslint-plugin-ai-guard.svg?style=flat-square&color=7c3aed" alt="npm version"></a>
9
+ <a href="https://github.com/YashJadhav21/eslint-plugin-ai-guard/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/YashJadhav21/eslint-plugin-ai-guard/ci.yml?style=flat-square&label=CI&color=10b981" alt="CI"></a>
10
+ <a href="https://www.npmjs.com/package/eslint-plugin-ai-guard"><img src="https://img.shields.io/npm/dm/eslint-plugin-ai-guard.svg?style=flat-square&color=3b82f6" alt="downloads"></a>
11
+ <a href="https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/eslint-plugin-ai-guard.svg?style=flat-square&color=64748b" alt="MIT License"></a>
12
+ <a href="https://github.com/YashJadhav21/eslint-plugin-ai-guard/blob/main/SECURITY.md"><img src="https://img.shields.io/badge/security-policy-orange?style=flat-square" alt="Security Policy"></a>
13
+ </p>
14
+ </p>
15
+
16
+ ---
17
+
18
+ ## What is ai-guard?
19
+
20
+ **ai-guard** is an ESLint plugin and GitHub Action that catches reliability and security bugs
21
+ specific to AI-generated code โ€” the patterns Copilot, Claude, Cursor, and Gemini consistently get wrong.
22
+
23
+ It integrates directly into GitHub pull request workflows: blocking dangerous merges, generating
24
+ SARIF reports for GitHub Code Scanning, and posting inline PR annotations at the exact line where
25
+ the bug lives.
26
+
27
+ ```bash
28
+ # Scan immediately โ€” no config needed
29
+ npx ai-guard run
30
+
31
+ # PR-aware changed-only scan with GitHub Advanced Security
32
+ npx ai-guard changed --sarif --sarif-output results.sarif
33
+ ```
34
+
35
+ <img src="./assets/ss8.jpg" alt="GitHub PR Inline Annotations by AI Guard" width="1000" />
36
+
37
+ ---
38
+
39
+ ## The Problem
40
+
41
+ AI coding assistants generate code that **looks correct but isn't.** The patterns they get wrong
42
+ are consistent, predictable, and existing linters don't catch them:
43
+
44
+ | Pattern | Why AI Gets It Wrong |
45
+ |---------|---------------------|
46
+ | `try {} catch (e) {}` | AI adds catch blocks without handling the error |
47
+ | `array.map(async ...)` | AI generates async callbacks returning `Promise[]`, not values |
48
+ | `fetch(url)` without await | AI forgets to await or handle promise rejection |
49
+ | `const apiKey = 'sk-...'` | AI uses placeholder credentials that get committed |
50
+ | `eval(userInput)` | AI generates dynamic evaluation without security context |
51
+ | `if (true) { ... }` | AI leaves dead scaffolding branches in generated code |
52
+
53
+ ai-guard is purpose-built to catch what AI tools consistently get wrong โ€” before those bugs reach production.
54
+
55
+ ---
56
+
57
+ ## Install
58
+
59
+ ```bash
60
+ npm install --save-dev eslint-plugin-ai-guard
61
+ ```
62
+
63
+ **Requirements:** Node.js โ‰ฅ 18 ยท ESLint โ‰ฅ 8
64
+
65
+ ---
66
+
67
+ ## Quick Start
68
+
69
+ ```bash
70
+ # Zero-config project scan
71
+ npx ai-guard run
72
+
73
+ # Security-focused scan
74
+ npx ai-guard run --security
75
+
76
+ # Strict mode โ€” all 18 rules at error
77
+ npx ai-guard run --strict
78
+
79
+ # Scan only changed files (PR-aware)
80
+ npx ai-guard changed --pr
81
+ ```
82
+
83
+ **No configuration required.** ai-guard ships with a production-tuned `recommended` preset.
84
+
85
+ ---
86
+
87
+ ## GitHub Actions Integration
88
+
89
+ Drop this into any repository to get PR validation, SARIF-based Code Scanning, and
90
+ GitHub Advanced Security integration in under 5 minutes:
91
+
92
+ ```yaml
93
+ # .github/workflows/ai-guard.yml
94
+ name: AI Guard
95
+
96
+ on: [pull_request]
97
+
98
+ permissions:
99
+ security-events: write
100
+ contents: read
101
+
102
+ jobs:
103
+ scan:
104
+ runs-on: ubuntu-latest
105
+ steps:
106
+ - uses: actions/checkout@v4
107
+ with:
108
+ fetch-depth: 0 # Required for changed-file detection
109
+
110
+ - uses: actions/setup-node@v4
111
+ with:
112
+ node-version: 20
113
+ cache: 'npm'
114
+
115
+ - run: npm ci
116
+
117
+ - name: Scan changed files
118
+ run: |
119
+ npx ai-guard changed \
120
+ --pr \
121
+ --strict \
122
+ --sarif \
123
+ --sarif-output ai-guard-results.sarif \
124
+ --fail-on high
125
+
126
+ - name: Upload to GitHub Code Scanning
127
+ uses: github/codeql-action/upload-sarif@v3
128
+ if: always()
129
+ with:
130
+ sarif_file: ai-guard-results.sarif
131
+ category: ai-guard
132
+ ```
133
+
134
+ This produces:
135
+ - โœ… Inline PR annotations at the exact line of each finding
136
+ - โœ… GitHub Advanced Security summary ("17 new alerts including 3 high severity")
137
+ - โœ… Persistent alerts in `Security โ†’ Code scanning`
138
+ - โœ… PR status check that blocks merges on high-severity findings
139
+
140
+ ### Inline PR Annotations
141
+ <img src="./assets/ss9.jpg" alt="AI Guard PR Inline Annotations" width="1000" />
142
+
143
+ ### GitHub Advanced Security Summary
144
+ <img src="./assets/ss10.jpg" alt="GitHub Advanced Security Summary for AI Guard" width="1000" />
145
+
146
+ ### GitHub Code Scanning Alerts
147
+ <img src="./assets/ss11.jpg" alt="GitHub Code Scanning Alerts List" width="1000" />
148
+
149
+ See [`docs/github-actions.md`](./docs/github-actions.md) for the complete workflow reference
150
+ including full-scan mode, baseline mode, and SARIF debugging.
151
+
152
+ ---
153
+
154
+ ## CLI Commands
155
+
156
+ | Command | Description |
157
+ |---------|-------------|
158
+ | `ai-guard run` | Scan your project with the recommended preset |
159
+ | `ai-guard run --strict` | All 18 rules at error โ€” for CI enforcement |
160
+ | `ai-guard run --security` | Security rules only |
161
+ | `ai-guard run --sarif` | Output SARIF for GitHub Code Scanning |
162
+ | `ai-guard run --json` | Output results as JSON (CI-friendly) |
163
+ | `ai-guard changed --pr` | Scan only files changed in this PR |
164
+ | `ai-guard changed --staged` | Scan only staged files (pre-commit hook) |
165
+ | `ai-guard init` | Auto-configure ESLint + workflow + agent context |
166
+ | `ai-guard init --yes` | Zero-prompt setup โ€” recommended for CI/scripts |
167
+ | `ai-guard init-context` | Generate AI agent rules (CLAUDE.md, .cursorrules, etc.) |
168
+ | `ai-guard baseline` | Save current issues, track only new ones going forward |
169
+ | `ai-guard report` | Generate a shareable HTML report |
170
+ | `ai-guard doctor` | Diagnose your ESLint and ai-guard setup |
171
+
172
+ ### Fail Strategies
173
+
174
+ ```bash
175
+ --fail-on errors # Fail on any error-level finding (default)
176
+ --fail-on high # Fail only on high-severity findings
177
+ --fail-on none # Never fail โ€” always continue
178
+ --max-warnings 0 # Fail on any warning
179
+ ```
180
+
181
+ ### Example Output
182
+
183
+ ```
184
+ AI GUARD
185
+
186
+ Files scanned: 142 ยท Issues in: 7 files ยท Duration: 312ms ยท Preset: strict
187
+
188
+ โ”€โ”€ Summary by Category โ”€โ”€
189
+
190
+ ๐Ÿ”ด Security 3 errors
191
+ ๐ŸŸ  Reliability 2 errors
192
+ ๐ŸŸก Async Stability 2 warnings
193
+
194
+ Total: 5 errors ยท 2 warnings
195
+
196
+ โ”€โ”€ By Rule โ”€โ”€
197
+ โ€ข no-hardcoded-secret: 3
198
+ โ€ข no-empty-catch: 2
199
+ โ€ข no-floating-promise: 2
200
+
201
+ โ”€โ”€ Next Steps โ”€โ”€
202
+ โ„น Run ai-guard baseline to save these issues and track only new ones
203
+ โ„น Run ai-guard report to generate a shareable HTML report
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Rules
209
+
210
+ ### ๐Ÿ”ด Security
211
+
212
+ | Rule | Recommended | What it catches |
213
+ |------|------------|------------------|
214
+ | [`no-hardcoded-secret`](./docs/rules/no-hardcoded-secret.md) | **error** | API keys, passwords, tokens in source. Autofix: `process.env.*` |
215
+ | [`no-eval-dynamic`](./docs/rules/no-eval-dynamic.md) | **error** | `eval()` / `new Function()` with non-literal args |
216
+ | [`no-sql-string-concat`](./docs/rules/no-sql-string-concat.md) | warn | SQL built by string concatenation โ€” SQL injection risk |
217
+ | [`no-unsafe-deserialize`](./docs/rules/no-unsafe-deserialize.md) | warn | `JSON.parse(req.body)` without validation |
218
+ | [`require-auth-middleware`](./docs/rules/require-auth-middleware.md) | warn | Express/Fastify routes without authentication middleware |
219
+ | [`require-authz-check`](./docs/rules/require-authz-check.md) | warn | Resource access without ownership checks |
220
+
221
+ ### ๐ŸŸ  Reliability
222
+
223
+ | Rule | Recommended | What it catches |
224
+ |------|------------|------------------|
225
+ | [`no-empty-catch`](./docs/rules/no-empty-catch.md) | **error** | `catch (e) {}` โ€” errors silently vanish. Autofix: inserts TODO |
226
+ | [`no-broad-exception`](./docs/rules/no-broad-exception.md) | warn | `catch (e: any)` that hides the real error type |
227
+ | [`no-catch-log-rethrow`](./docs/rules/no-catch-log-rethrow.md) | off* | Catch blocks that only `console.log` + rethrow |
228
+ | [`no-catch-without-use`](./docs/rules/no-catch-without-use.md) | off* | Caught error variable never used |
229
+
230
+ ### ๐ŸŸก Async Stability
231
+
232
+ | Rule | Recommended | What it catches |
233
+ |------|------------|------------------|
234
+ | [`no-floating-promise`](./docs/rules/no-floating-promise.md) | **error** | Async calls with no `await`, return, or `.catch()`. Autofix: adds `void` |
235
+ | [`no-async-array-callback`](./docs/rules/no-async-array-callback.md) | warn | `array.map(async ...)` โ€” returns `Promise[]` not values |
236
+ | [`no-await-in-loop`](./docs/rules/no-await-in-loop.md) | warn | Sequential `await` in loops โ€” use `Promise.all` |
237
+ | [`no-async-without-await`](./docs/rules/no-async-without-await.md) | warn | `async` function that never uses `await` |
238
+ | [`no-redundant-await`](./docs/rules/no-redundant-await.md) | off* | `return await` outside try/catch |
239
+
240
+ ### ๐Ÿ”ต AI Patterns
241
+
242
+ | Rule | Recommended | What it catches |
243
+ |------|------------|------------------|
244
+ | [`no-dead-branch`](./docs/rules/no-dead-branch.md) | warn | `if (true)`, `if (false)`, `x && !x` โ€” scaffolding leftovers |
245
+ | [`no-duplicate-logic-block`](./docs/rules/no-duplicate-logic-block.md) | off* | Consecutive duplicate code blocks |
246
+ | [`no-console-in-handler`](./docs/rules/no-console-in-handler.md) | off* | `console.log` in route handlers โ€” use a logger |
247
+
248
+ *Enabled at `error` in the `strict` preset.
249
+
250
+ Full rule documentation: [`docs/rules/`](./docs/rules/)
251
+
252
+ ---
253
+
254
+ ## Presets
255
+
256
+ | Preset | Purpose | Best For |
257
+ |--------|---------|----------|
258
+ | `recommended` | Critical issues at `error`, context-sensitive at `warn` | All projects on day one |
259
+ | `strict` | All 18 rules at `error` | CI enforcement in mature codebases |
260
+ | `security` | Security rules only | Security-focused scanning |
261
+
262
+ ### ESLint Flat Config
263
+
264
+ ```javascript
265
+ // eslint.config.mjs
266
+ import aiGuard from 'eslint-plugin-ai-guard';
267
+
268
+ export default [
269
+ {
270
+ plugins: { 'ai-guard': aiGuard },
271
+ rules: { ...aiGuard.configs.recommended.rules },
272
+ },
273
+ ];
274
+ ```
275
+
276
+ ---
277
+
278
+ ## AI Agent Integration
279
+
280
+ Generate instruction files so **Claude Code, Cursor, and GitHub Copilot** automatically avoid
281
+ the 18 most common AI-generated anti-patterns at generation time:
282
+
283
+ ```bash
284
+ npx ai-guard init-context
285
+ ```
286
+
287
+ This writes:
288
+ - `CLAUDE.md` โ€” loaded automatically by Claude Code
289
+ - `.cursorrules` โ€” loaded automatically by Cursor
290
+ - `.github/copilot-instructions.md` โ€” loaded automatically by GitHub Copilot
291
+
292
+ Your AI tools will avoid these patterns **before you even run the linter.**
293
+
294
+ See [`docs/ai-agents.md`](./docs/ai-agents.md) for the complete integration guide.
295
+
296
+ ---
297
+
298
+ ## Real-World Example
299
+
300
+ ```typescript
301
+ // โŒ Typical AI-generated code โ€” 4 issues in one function
302
+ async function processUserOrders(userId: string) {
303
+ const apiKey = 'sk-prod-1234567890abcdef'; // no-hardcoded-secret
304
+
305
+ const orders = await db.query(
306
+ 'SELECT * FROM orders WHERE id = ' + userId // no-sql-string-concat
307
+ );
308
+
309
+ for (const order of orders) {
310
+ await sendEmail(order.email); // no-await-in-loop
311
+ }
312
+
313
+ updateAnalytics(userId); // no-floating-promise
314
+ }
315
+
316
+ // โœ… After ai-guard fixes
317
+ async function processUserOrders(userId: string) {
318
+ const apiKey = process.env.API_KEY;
319
+
320
+ const orders = await db.query(
321
+ 'SELECT * FROM orders WHERE id = $1', [userId]
322
+ );
323
+
324
+ await Promise.all(orders.map(async (order) => sendEmail(order.email)));
325
+
326
+ void updateAnalytics(userId);
327
+ }
328
+ ```
329
+
330
+ ---
331
+
332
+ ## Autofix Support
333
+
334
+ ```bash
335
+ npx eslint src --fix
336
+ ```
337
+
338
+ | Rule | What Gets Fixed |
339
+ |------|-----------------|
340
+ | `no-hardcoded-secret` | Literal โ†’ `process.env.VAR_NAME` |
341
+ | `no-empty-catch` | Inserts `/* TODO: handle error */` |
342
+ | `no-floating-promise` | Marks with `void` |
343
+ | `no-await-in-loop` | Rewrites simple loops to `Promise.all(...)` |
344
+ | `no-async-without-await` | Removes unnecessary `async` keyword |
345
+
346
+ ---
347
+
348
+ ## Philosophy
349
+
350
+ - **Precision over recall** โ€” we'd rather miss a bug than create noise
351
+ - **Low false positives** โ€” a rule that fires on valid code goes to `warn` or gets disabled
352
+ - **Gradual adoption** โ€” `recommended` is safe for day-one; `strict` is opt-in
353
+ - **Self-validating** โ€” ai-guard scans its own source in CI with the strict preset
354
+ - **GitHub-native** โ€” SARIF output, Code Scanning, PR annotations are first-class features
355
+
356
+ ---
357
+
358
+ ## Development
359
+
360
+ ```bash
361
+ git clone https://github.com/YashJadhav21/eslint-plugin-ai-guard.git
362
+ cd eslint-plugin-ai-guard
363
+ npm install
364
+ npm run test # 678 tests across 39 test files
365
+ npm run build # Build CJS + ESM bundles
366
+ npm run typecheck # TypeScript strict check
367
+ npm run lint:self # Scan own source with ai-guard
368
+ npm run lint:full # Strict scan of src/ + cli/
369
+ ```
370
+
371
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development guide.
372
+
373
+ ---
374
+
375
+ ## Documentation
376
+
377
+ | Doc | Purpose |
378
+ |-----|---------|
379
+ | [`docs/github-actions.md`](./docs/github-actions.md) | GitHub Actions workflow reference |
380
+ | [`docs/ai-agents.md`](./docs/ai-agents.md) | AI agent integration guide |
381
+ | [`docs/architecture.md`](./docs/architecture.md) | Architecture and internals |
382
+ | [`docs/benchmarks.md`](./docs/benchmarks.md) | Benchmarks vs ESLint, @typescript-eslint |
383
+ | [`docs/rules/`](./docs/rules/) | Per-rule documentation |
384
+ | [`CONTRIBUTING.md`](./CONTRIBUTING.md) | Contribution guide |
385
+ | [`SECURITY.md`](./SECURITY.md) | Security policy |
386
+ | [`CHANGELOG.md`](./CHANGELOG.md) | Release history |
387
+ | [`ROADMAP.md`](./ROADMAP.md) | Planned features |
388
+
389
+ ---
390
+
391
+ ## FAQ
392
+
393
+ <details>
394
+ <summary><strong>Is ai-guard a replacement for ESLint?</strong></summary>
395
+
396
+ No. ai-guard runs *on top of* ESLint. It adds 18 rules specifically tuned for AI-generated
397
+ code patterns. Your existing ESLint rules continue to work as normal.
398
+ </details>
399
+
400
+ <details>
401
+ <summary><strong>Does ai-guard require TypeScript type information?</strong></summary>
402
+
403
+ No. All rules use AST heuristics, not type analysis. This makes ai-guard faster than
404
+ type-aware linters and zero-config for JavaScript projects. See
405
+ [benchmarks](./docs/benchmarks.md) for performance comparison.
406
+ </details>
407
+
408
+ <details>
409
+ <summary><strong>Will ai-guard slow down my CI?</strong></summary>
410
+
411
+ Typically adds 1โ€“2 seconds to a CI run. Changed-only mode (`ai-guard changed --pr`)
412
+ is even faster because it only scans files modified in the PR.
413
+ </details>
414
+
415
+ <details>
416
+ <summary><strong>How do I reduce false positives?</strong></summary>
417
+
418
+ Start with `recommended` preset (default). The `strict` preset enables all rules,
419
+ which may be noisy for some codebases. You can also:
420
+ - Use `ai-guard baseline` to ignore pre-existing issues
421
+ - Configure per-rule options (e.g., `allowedLoggers` for `no-console-in-handler`)
422
+ - Use `// eslint-disable-next-line ai-guard/rule-name` for intentional overrides
423
+ </details>
424
+
425
+ <details>
426
+ <summary><strong>Does ai-guard work with Copilot / Cursor / Claude Code?</strong></summary>
427
+
428
+ Yes โ€” in two ways:
429
+ 1. **Lint after generation**: ai-guard catches issues after AI generates code
430
+ 2. **Prevent before generation**: `ai-guard init-context` creates instruction files
431
+ (CLAUDE.md, .cursorrules) that teach AI agents to avoid these patterns
432
+ </details>
433
+
434
+ ---
435
+
436
+ ## Troubleshooting
437
+
438
+ | Symptom | Fix |
439
+ |---------|-----|
440
+ | `Cannot find module 'eslint-plugin-ai-guard'` | Run `npm install --save-dev eslint-plugin-ai-guard` |
441
+ | Config parse errors after `init` | Run `ai-guard doctor` to diagnose |
442
+ | SARIF upload fails in GitHub Actions | Ensure `permissions: security-events: write` is set |
443
+ | Too many findings in strict mode | Switch to `recommended` preset or use `ai-guard baseline` |
444
+ | Rules not firing on `.ts` files | Install `@typescript-eslint/parser` |
445
+ | `ai-guard init` skips workflow/context | Use `ai-guard init --yes` for zero-prompt setup |
446
+
447
+ ---
448
+
449
+ ## License
450
+
451
+ [MIT](LICENSE) โ€” free forever. No rules behind a paywall.
452
+
453
+ ---
454
+
455
+ <p align="center">
456
+ Built to make AI-assisted development reliable and trustworthy. โšก
457
+ </p>