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 +457 -393
- package/dist/cli/index.js +3955 -3732
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.mts +17 -2
- package/dist/index.d.ts +17 -2
- package/dist/index.js +94 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +94 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
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
|
-
|
|
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 ("
|
|
137
|
-
- โ
Persistent alerts in `Security โ Code scanning`
|
|
138
|
-
- โ
PR status check that blocks merges on high-severity findings
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
|
157
|
-
|
|
158
|
-
| `ai-guard run
|
|
159
|
-
| `ai-guard run --
|
|
160
|
-
| `ai-guard
|
|
161
|
-
| `ai-guard
|
|
162
|
-
| `ai-guard
|
|
163
|
-
| `ai-guard
|
|
164
|
-
| `ai-guard
|
|
165
|
-
| `ai-guard
|
|
166
|
-
| `ai-guard
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
|
213
|
-
|
|
214
|
-
| [`
|
|
215
|
-
| [`
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
|
233
|
-
|
|
234
|
-
| [`no-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
|
339
|
-
|
|
340
|
-
| `no-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
- **
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
npm
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
|
378
|
-
|
|
379
|
-
| [`
|
|
380
|
-
| [`
|
|
381
|
-
| [`
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
[
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
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>
|