eslint-plugin-ai-guard 1.2.6 โ 1.2.8
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 +195 -139
- package/dist/cli/index.js +100 -4
- package/dist/cli/index.js.map +1 -1
- package/package.json +97 -83
package/README.md
CHANGED
|
@@ -2,36 +2,55 @@
|
|
|
2
2
|
<img src="./assets/logo.png" alt="AI Guard Logo" width="80" />
|
|
3
3
|
<h1 align="center">eslint-plugin-ai-guard</h1>
|
|
4
4
|
<p align="center">
|
|
5
|
-
<strong>๐ก๏ธ
|
|
5
|
+
<strong>๐ก๏ธ GitHub-native guardrails for AI-generated code.</strong>
|
|
6
6
|
</p>
|
|
7
7
|
<p align="center">
|
|
8
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"><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>
|
|
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
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="
|
|
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>
|
|
12
13
|
</p>
|
|
13
14
|
</p>
|
|
14
15
|
|
|
15
16
|
---
|
|
16
17
|
|
|
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
|
|
18
30
|
|
|
19
|
-
|
|
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
|
|
20
40
|
|
|
21
|
-
The patterns they get wrong
|
|
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:
|
|
22
43
|
|
|
23
44
|
| Pattern | Why AI Gets It Wrong |
|
|
24
45
|
|---------|---------------------|
|
|
25
|
-
| `try {} catch (e) {}` | AI adds catch blocks without
|
|
26
|
-
| `array.map(async ...)` | AI generates async callbacks
|
|
27
|
-
| `fetch(url)`
|
|
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 |
|
|
28
49
|
| `const apiKey = 'sk-...'` | AI uses placeholder credentials that get committed |
|
|
29
|
-
| `eval(userInput)` | AI generates dynamic evaluation without security
|
|
50
|
+
| `eval(userInput)` | AI generates dynamic evaluation without security context |
|
|
30
51
|
| `if (true) { ... }` | AI leaves dead scaffolding branches in generated code |
|
|
31
52
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`ai-guard` is purpose-built to catch what AI tools consistently get wrong.
|
|
53
|
+
ai-guard is purpose-built to catch what AI tools consistently get wrong โ before those bugs reach production.
|
|
35
54
|
|
|
36
55
|
---
|
|
37
56
|
|
|
@@ -41,27 +60,91 @@ The patterns they get wrong are consistent and predictable:
|
|
|
41
60
|
npm install --save-dev eslint-plugin-ai-guard
|
|
42
61
|
```
|
|
43
62
|
|
|
44
|
-
|
|
63
|
+
**Requirements:** Node.js โฅ 18 ยท ESLint โฅ 8
|
|
45
64
|
|
|
46
65
|
---
|
|
47
66
|
|
|
48
|
-
## Quick Start
|
|
67
|
+
## Quick Start
|
|
49
68
|
|
|
50
69
|
```bash
|
|
51
|
-
#
|
|
70
|
+
# Zero-config project scan
|
|
52
71
|
npx ai-guard run
|
|
53
72
|
|
|
54
73
|
# Security-focused scan
|
|
55
74
|
npx ai-guard run --security
|
|
56
75
|
|
|
57
|
-
# Strict mode โ all rules at error
|
|
76
|
+
# Strict mode โ all 18 rules at error
|
|
58
77
|
npx ai-guard run --strict
|
|
59
78
|
|
|
60
|
-
# Scan
|
|
61
|
-
npx ai-guard
|
|
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
|
|
62
132
|
```
|
|
63
133
|
|
|
64
|
-
|
|
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.
|
|
65
148
|
|
|
66
149
|
---
|
|
67
150
|
|
|
@@ -70,23 +153,33 @@ npx ai-guard run --path src/api
|
|
|
70
153
|
| Command | Description |
|
|
71
154
|
|---------|-------------|
|
|
72
155
|
| `ai-guard run` | Scan your project with the recommended preset |
|
|
73
|
-
| `ai-guard run --strict` | All rules at error โ for CI enforcement |
|
|
156
|
+
| `ai-guard run --strict` | All 18 rules at error โ for CI enforcement |
|
|
74
157
|
| `ai-guard run --security` | Security rules only |
|
|
158
|
+
| `ai-guard run --sarif` | Output SARIF for GitHub Code Scanning |
|
|
75
159
|
| `ai-guard run --json` | Output results as JSON (CI-friendly) |
|
|
76
|
-
| `ai-guard
|
|
160
|
+
| `ai-guard changed --pr` | Scan only files changed in this PR |
|
|
161
|
+
| `ai-guard changed --staged` | Scan only staged files (pre-commit hook) |
|
|
77
162
|
| `ai-guard init` | Auto-configure ESLint for your project |
|
|
78
163
|
| `ai-guard init-context` | Generate AI agent rules (CLAUDE.md, .cursorrules, etc.) |
|
|
79
|
-
| `ai-guard
|
|
80
|
-
| `ai-guard baseline` | Save current issues, track only new ones |
|
|
164
|
+
| `ai-guard baseline` | Save current issues, track only new ones going forward |
|
|
81
165
|
| `ai-guard report` | Generate a shareable HTML report |
|
|
82
|
-
| `ai-guard
|
|
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
|
+
```
|
|
83
176
|
|
|
84
|
-
###
|
|
177
|
+
### Example Output
|
|
85
178
|
|
|
86
179
|
```
|
|
87
180
|
AI GUARD
|
|
88
181
|
|
|
89
|
-
Files scanned: 142 ยท Issues in: 7 files ยท Duration: 312ms ยท Preset:
|
|
182
|
+
Files scanned: 142 ยท Issues in: 7 files ยท Duration: 312ms ยท Preset: strict
|
|
90
183
|
|
|
91
184
|
โโ Summary by Category โโ
|
|
92
185
|
|
|
@@ -112,59 +205,57 @@ npx ai-guard run --path src/api
|
|
|
112
205
|
|
|
113
206
|
### ๐ด Security
|
|
114
207
|
|
|
115
|
-
| Rule |
|
|
116
|
-
|
|
117
|
-
| `no-hardcoded-secret` | **error** | API keys, passwords, tokens in source
|
|
118
|
-
| `no-eval-dynamic` | **error** | `eval()` / `new Function()` with non-literal
|
|
119
|
-
| `no-sql-string-concat` | warn | SQL
|
|
120
|
-
| `no-unsafe-deserialize` | warn | `JSON.parse(req.body)` without validation |
|
|
121
|
-
| `require-auth-middleware` | warn | Express/Fastify routes without authentication middleware |
|
|
122
|
-
| `require-authz-check` | warn | Resource access without ownership checks |
|
|
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 |
|
|
123
216
|
|
|
124
217
|
### ๐ Reliability
|
|
125
218
|
|
|
126
|
-
| Rule |
|
|
127
|
-
|
|
128
|
-
| `no-empty-catch` | **error** | `catch (e) {}` โ errors vanish
|
|
129
|
-
| `no-broad-exception` | warn | `catch (e: any)` that hides the real error type |
|
|
130
|
-
| `no-catch-log-rethrow` | off* | Catch blocks that only `console.log` + rethrow |
|
|
131
|
-
| `no-catch-without-use` | off* |
|
|
132
|
-
|
|
133
|
-
*Enabled at `error` in `strict` preset.
|
|
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 |
|
|
134
225
|
|
|
135
226
|
### ๐ก Async Stability
|
|
136
227
|
|
|
137
|
-
| Rule |
|
|
138
|
-
|
|
139
|
-
| `no-floating-promise` | **error** | Async calls with no `await`, return, or `.catch()`. Autofix: adds `void` |
|
|
140
|
-
| `no-async-array-callback` | warn | `array.map(async ...)`
|
|
141
|
-
| `no-await-in-loop` | warn | Sequential `await` in loops
|
|
142
|
-
| `no-async-without-await` | warn | `async` function that never uses `await` |
|
|
143
|
-
| `no-redundant-await` | off* | `return await` outside try/catch |
|
|
144
|
-
|
|
145
|
-
*Enabled at `error` in `strict` preset.
|
|
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 |
|
|
146
235
|
|
|
147
236
|
### ๐ต AI Patterns
|
|
148
237
|
|
|
149
|
-
| Rule |
|
|
150
|
-
|
|
151
|
-
| `no-dead-branch` | warn | `if (true)`, `if (false)`, `x && !x
|
|
152
|
-
| `no-duplicate-logic-block` | off* | Consecutive duplicate code
|
|
153
|
-
| `no-console-in-handler` | off* | `console.log` in route handlers
|
|
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.
|
|
154
245
|
|
|
155
|
-
|
|
246
|
+
Full rule documentation: [`docs/rules/`](./docs/rules/)
|
|
156
247
|
|
|
157
248
|
---
|
|
158
249
|
|
|
159
250
|
## Presets
|
|
160
251
|
|
|
161
|
-
| Preset | Purpose |
|
|
162
|
-
|
|
163
|
-
| `recommended` |
|
|
252
|
+
| Preset | Purpose | Best For |
|
|
253
|
+
|--------|---------|----------|
|
|
254
|
+
| `recommended` | Critical issues at `error`, context-sensitive at `warn` | All projects on day one |
|
|
164
255
|
| `strict` | All 18 rules at `error` | CI enforcement in mature codebases |
|
|
165
256
|
| `security` | Security rules only | Security-focused scanning |
|
|
166
257
|
|
|
167
|
-
### ESLint
|
|
258
|
+
### ESLint Flat Config
|
|
168
259
|
|
|
169
260
|
```javascript
|
|
170
261
|
// eslint.config.mjs
|
|
@@ -178,82 +269,43 @@ export default [
|
|
|
178
269
|
];
|
|
179
270
|
```
|
|
180
271
|
|
|
181
|
-
```javascript
|
|
182
|
-
// Strict preset
|
|
183
|
-
export default [
|
|
184
|
-
{
|
|
185
|
-
plugins: { 'ai-guard': aiGuard },
|
|
186
|
-
rules: { ...aiGuard.configs.strict.rules },
|
|
187
|
-
},
|
|
188
|
-
];
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## CI Integration
|
|
194
|
-
|
|
195
|
-
### GitHub Actions
|
|
196
|
-
|
|
197
|
-
```yaml
|
|
198
|
-
# .github/workflows/ai-guard.yml
|
|
199
|
-
name: AI Guard
|
|
200
|
-
|
|
201
|
-
on: [pull_request]
|
|
202
|
-
|
|
203
|
-
jobs:
|
|
204
|
-
scan:
|
|
205
|
-
runs-on: ubuntu-latest
|
|
206
|
-
steps:
|
|
207
|
-
- uses: actions/checkout@v4
|
|
208
|
-
- uses: actions/setup-node@v4
|
|
209
|
-
with:
|
|
210
|
-
node-version: 20
|
|
211
|
-
cache: 'npm'
|
|
212
|
-
- run: npm ci
|
|
213
|
-
- run: npx ai-guard run --max-warnings 0
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
See [`examples/ci/`](./examples/ci/) for more templates (GitLab CI, baseline mode, JSON output).
|
|
217
|
-
|
|
218
|
-
### Exit Codes
|
|
219
|
-
|
|
220
|
-
| Code | Meaning |
|
|
221
|
-
|------|---------|
|
|
222
|
-
| `0` | No issues (or only warnings below `--max-warnings` threshold) |
|
|
223
|
-
| `1` | Errors found, or warnings exceed `--max-warnings` |
|
|
224
|
-
|
|
225
272
|
---
|
|
226
273
|
|
|
227
|
-
## AI Agent
|
|
274
|
+
## AI Agent Integration
|
|
228
275
|
|
|
229
|
-
Generate instruction files so **Claude Code, Cursor, and GitHub Copilot** automatically avoid
|
|
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:
|
|
230
278
|
|
|
231
279
|
```bash
|
|
232
280
|
npx ai-guard init-context
|
|
233
281
|
```
|
|
234
282
|
|
|
235
283
|
This writes:
|
|
236
|
-
- `CLAUDE.md` โ
|
|
237
|
-
- `.cursorrules` โ
|
|
238
|
-
- `.github/copilot-instructions.md` โ
|
|
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.**
|
|
239
289
|
|
|
240
|
-
|
|
290
|
+
See [`docs/ai-agents.md`](./docs/ai-agents.md) for the complete integration guide.
|
|
241
291
|
|
|
242
292
|
---
|
|
243
293
|
|
|
244
294
|
## Real-World Example
|
|
245
295
|
|
|
246
296
|
```typescript
|
|
247
|
-
// โ
|
|
297
|
+
// โ Typical AI-generated code โ 4 issues in one function
|
|
248
298
|
async function processUserOrders(userId: string) {
|
|
249
299
|
const apiKey = 'sk-prod-1234567890abcdef'; // no-hardcoded-secret
|
|
250
|
-
|
|
251
|
-
const orders = await db.query(
|
|
252
|
-
|
|
300
|
+
|
|
301
|
+
const orders = await db.query(
|
|
302
|
+
'SELECT * FROM orders WHERE id = ' + userId // no-sql-string-concat
|
|
303
|
+
);
|
|
304
|
+
|
|
253
305
|
for (const order of orders) {
|
|
254
306
|
await sendEmail(order.email); // no-await-in-loop
|
|
255
307
|
}
|
|
256
|
-
|
|
308
|
+
|
|
257
309
|
updateAnalytics(userId); // no-floating-promise
|
|
258
310
|
}
|
|
259
311
|
|
|
@@ -261,7 +313,9 @@ async function processUserOrders(userId: string) {
|
|
|
261
313
|
async function processUserOrders(userId: string) {
|
|
262
314
|
const apiKey = process.env.API_KEY;
|
|
263
315
|
|
|
264
|
-
const orders = await db.query(
|
|
316
|
+
const orders = await db.query(
|
|
317
|
+
'SELECT * FROM orders WHERE id = $1', [userId]
|
|
318
|
+
);
|
|
265
319
|
|
|
266
320
|
await Promise.all(orders.map(async (order) => sendEmail(order.email)));
|
|
267
321
|
|
|
@@ -273,17 +327,13 @@ async function processUserOrders(userId: string) {
|
|
|
273
327
|
|
|
274
328
|
## Autofix Support
|
|
275
329
|
|
|
276
|
-
Run autofixes via ESLint:
|
|
277
|
-
|
|
278
330
|
```bash
|
|
279
331
|
npx eslint src --fix
|
|
280
332
|
```
|
|
281
333
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
|
285
|
-
|------|-----|
|
|
286
|
-
| `no-hardcoded-secret` | Replaces literal with `process.env.VAR_NAME` |
|
|
334
|
+
| Rule | What Gets Fixed |
|
|
335
|
+
|------|-----------------|
|
|
336
|
+
| `no-hardcoded-secret` | Literal โ `process.env.VAR_NAME` |
|
|
287
337
|
| `no-empty-catch` | Inserts `/* TODO: handle error */` |
|
|
288
338
|
| `no-floating-promise` | Marks with `void` |
|
|
289
339
|
| `no-await-in-loop` | Rewrites simple loops to `Promise.all(...)` |
|
|
@@ -294,9 +344,10 @@ Rules with autofix:
|
|
|
294
344
|
## Philosophy
|
|
295
345
|
|
|
296
346
|
- **Precision over recall** โ we'd rather miss a bug than create noise
|
|
297
|
-
- **Low false positives** โ
|
|
298
|
-
- **Gradual adoption** โ `recommended` is
|
|
299
|
-
- **Self-validating** โ
|
|
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
|
|
300
351
|
|
|
301
352
|
---
|
|
302
353
|
|
|
@@ -306,23 +357,28 @@ Rules with autofix:
|
|
|
306
357
|
git clone https://github.com/YashJadhav21/eslint-plugin-ai-guard.git
|
|
307
358
|
cd eslint-plugin-ai-guard
|
|
308
359
|
npm install
|
|
309
|
-
npm run test #
|
|
360
|
+
npm run test # 667 tests across 39 test files
|
|
310
361
|
npm run build # Build CJS + ESM bundles
|
|
311
|
-
npm run typecheck # TypeScript check
|
|
362
|
+
npm run typecheck # TypeScript strict check
|
|
312
363
|
npm run lint:self # Scan own source with ai-guard
|
|
313
364
|
```
|
|
314
365
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
## Contributing
|
|
318
|
-
|
|
319
|
-
Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
|
|
366
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for the full development guide.
|
|
320
367
|
|
|
321
|
-
|
|
368
|
+
---
|
|
322
369
|
|
|
323
|
-
|
|
370
|
+
## Documentation
|
|
324
371
|
|
|
325
|
-
|
|
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 |
|
|
326
382
|
|
|
327
383
|
---
|
|
328
384
|
|
|
@@ -333,5 +389,5 @@ See the [Roadmap](ROADMAP.md) for planned features.
|
|
|
333
389
|
---
|
|
334
390
|
|
|
335
391
|
<p align="center">
|
|
336
|
-
Built to make AI-assisted development
|
|
392
|
+
Built to make AI-assisted development reliable and trustworthy. โก
|
|
337
393
|
</p>
|