ai-code-audit 0.1.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 +150 -0
- package/dist/auditor.d.ts +6 -0
- package/dist/auditor.js +197 -0
- package/dist/auditor.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +231 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/rules/ai-specific.d.ts +6 -0
- package/dist/rules/ai-specific.js +125 -0
- package/dist/rules/ai-specific.js.map +1 -0
- package/dist/rules/index.d.ts +6 -0
- package/dist/rules/index.js +15 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/quality.d.ts +7 -0
- package/dist/rules/quality.js +126 -0
- package/dist/rules/quality.js.map +1 -0
- package/dist/rules/security.d.ts +8 -0
- package/dist/rules/security.js +171 -0
- package/dist/rules/security.js.map +1 -0
- package/dist/types.d.ts +29 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
- package/src/auditor.ts +226 -0
- package/src/cli.ts +274 -0
- package/src/index.ts +5 -0
- package/src/rules/ai-specific.ts +170 -0
- package/src/rules/index.ts +12 -0
- package/src/rules/quality.ts +169 -0
- package/src/rules/security.ts +247 -0
- package/src/types.ts +33 -0
- package/tsconfig.json +17 -0
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# ai-code-audit
|
|
2
|
+
|
|
3
|
+
Security and quality linter specifically designed for AI-generated code.
|
|
4
|
+
|
|
5
|
+
## The Problem
|
|
6
|
+
|
|
7
|
+
AI coding assistants can introduce security vulnerabilities and quality issues:
|
|
8
|
+
- SQL injection through string concatenation
|
|
9
|
+
- Command injection via unsanitized inputs
|
|
10
|
+
- Hardcoded secrets and credentials
|
|
11
|
+
- Missing error handling
|
|
12
|
+
- Unsafe deserialization
|
|
13
|
+
- Over-complex "clever" solutions
|
|
14
|
+
|
|
15
|
+
Traditional linters catch some of these, but AI code has unique patterns that need specific attention.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g ai-code-audit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
### Audit Files
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Audit a single file
|
|
29
|
+
aca src/api.ts
|
|
30
|
+
|
|
31
|
+
# Audit multiple files
|
|
32
|
+
aca src/**/*.ts
|
|
33
|
+
|
|
34
|
+
# Audit a git diff
|
|
35
|
+
git diff HEAD~1 | aca --stdin
|
|
36
|
+
|
|
37
|
+
# Audit staged changes
|
|
38
|
+
git diff --cached | aca --stdin
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Options
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
Options:
|
|
45
|
+
-s, --stdin Read diff from stdin
|
|
46
|
+
-f, --format <type> Output format: text, json, sarif (default: text)
|
|
47
|
+
-c, --config <file> Config file path
|
|
48
|
+
--severity <level> Minimum severity: info, warning, error (default: warning)
|
|
49
|
+
-q, --quiet Only output errors
|
|
50
|
+
-h, --help Show help
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Git Hook Integration
|
|
54
|
+
|
|
55
|
+
Add to `.git/hooks/pre-commit`:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
#!/bin/bash
|
|
59
|
+
git diff --cached | aca --stdin --severity error
|
|
60
|
+
if [ $? -ne 0 ]; then
|
|
61
|
+
echo "AI code audit found issues. Please review before committing."
|
|
62
|
+
exit 1
|
|
63
|
+
fi
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### CI Integration
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
# GitHub Actions
|
|
70
|
+
- name: AI Code Audit
|
|
71
|
+
run: |
|
|
72
|
+
npm install -g ai-code-audit
|
|
73
|
+
git diff ${{ github.event.before }} ${{ github.sha }} | aca --stdin --format sarif > results.sarif
|
|
74
|
+
|
|
75
|
+
- name: Upload SARIF
|
|
76
|
+
uses: github/codeql-action/upload-sarif@v2
|
|
77
|
+
with:
|
|
78
|
+
sarif_file: results.sarif
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Rules
|
|
82
|
+
|
|
83
|
+
### Security Rules
|
|
84
|
+
|
|
85
|
+
| Rule | Severity | Description |
|
|
86
|
+
|------|----------|-------------|
|
|
87
|
+
| `sql-injection` | error | Detects SQL queries with string interpolation |
|
|
88
|
+
| `command-injection` | error | Detects shell commands with unsanitized input |
|
|
89
|
+
| `hardcoded-secret` | error | Detects hardcoded API keys, passwords, tokens |
|
|
90
|
+
| `unsafe-eval` | error | Detects use of eval() or Function() |
|
|
91
|
+
| `unsafe-regex` | warning | Detects potentially catastrophic regex |
|
|
92
|
+
| `path-traversal` | error | Detects unsanitized file path operations |
|
|
93
|
+
| `xss-risk` | warning | Detects potential XSS in HTML generation |
|
|
94
|
+
|
|
95
|
+
### Quality Rules
|
|
96
|
+
|
|
97
|
+
| Rule | Severity | Description |
|
|
98
|
+
|------|----------|-------------|
|
|
99
|
+
| `missing-error-handling` | warning | Detects async operations without try/catch |
|
|
100
|
+
| `empty-catch` | warning | Detects empty catch blocks that swallow errors |
|
|
101
|
+
| `console-log` | info | Detects console.log left in code |
|
|
102
|
+
| `todo-fixme` | info | Detects TODO/FIXME comments |
|
|
103
|
+
| `magic-number` | info | Detects unexplained numeric literals |
|
|
104
|
+
| `deep-nesting` | warning | Detects deeply nested code (>4 levels) |
|
|
105
|
+
|
|
106
|
+
### AI-Specific Rules
|
|
107
|
+
|
|
108
|
+
| Rule | Severity | Description |
|
|
109
|
+
|------|----------|-------------|
|
|
110
|
+
| `ai-placeholder` | error | Detects placeholder text like "// Add implementation" |
|
|
111
|
+
| `incomplete-impl` | warning | Detects `throw new Error('Not implemented')` |
|
|
112
|
+
| `excessive-comments` | info | Detects over-commented obvious code |
|
|
113
|
+
| `type-any-abuse` | warning | Detects excessive use of `any` type |
|
|
114
|
+
|
|
115
|
+
## Configuration
|
|
116
|
+
|
|
117
|
+
Create `.ai-code-audit.json`:
|
|
118
|
+
|
|
119
|
+
```json
|
|
120
|
+
{
|
|
121
|
+
"rules": {
|
|
122
|
+
"sql-injection": "error",
|
|
123
|
+
"console-log": "off",
|
|
124
|
+
"magic-number": "warning"
|
|
125
|
+
},
|
|
126
|
+
"ignore": [
|
|
127
|
+
"**/*.test.ts",
|
|
128
|
+
"**/fixtures/**"
|
|
129
|
+
],
|
|
130
|
+
"languages": ["typescript", "javascript", "python"]
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Output Example
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
src/api/users.ts
|
|
138
|
+
12:5 error SQL injection risk: query uses string interpolation sql-injection
|
|
139
|
+
24:3 warning Missing error handling for async operation missing-error-handling
|
|
140
|
+
45:1 error Hardcoded secret detected: API_KEY = "sk-..." hardcoded-secret
|
|
141
|
+
|
|
142
|
+
src/utils/shell.ts
|
|
143
|
+
8:12 error Command injection: exec() with unsanitized input command-injection
|
|
144
|
+
|
|
145
|
+
4 problems (3 errors, 1 warning)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## License
|
|
149
|
+
|
|
150
|
+
MIT
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Finding, AuditResult, Config } from './types.js';
|
|
2
|
+
export declare function auditFile(filename: string, config?: Config): Finding[];
|
|
3
|
+
export declare function auditContent(content: string, filename: string, config?: Config): Finding[];
|
|
4
|
+
export declare function auditDiff(diff: string, config?: Config): Finding[];
|
|
5
|
+
export declare function summarize(findings: Finding[]): AuditResult;
|
|
6
|
+
export declare function loadConfig(configPath?: string): Config;
|
package/dist/auditor.js
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.auditFile = auditFile;
|
|
4
|
+
exports.auditContent = auditContent;
|
|
5
|
+
exports.auditDiff = auditDiff;
|
|
6
|
+
exports.summarize = summarize;
|
|
7
|
+
exports.loadConfig = loadConfig;
|
|
8
|
+
const node_fs_1 = require("node:fs");
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const index_js_1 = require("./rules/index.js");
|
|
11
|
+
const EXTENSION_MAP = {
|
|
12
|
+
'.ts': 'typescript',
|
|
13
|
+
'.tsx': 'typescript',
|
|
14
|
+
'.js': 'javascript',
|
|
15
|
+
'.jsx': 'javascript',
|
|
16
|
+
'.mjs': 'javascript',
|
|
17
|
+
'.cjs': 'javascript',
|
|
18
|
+
'.py': 'python',
|
|
19
|
+
'.rb': 'ruby',
|
|
20
|
+
'.go': 'go',
|
|
21
|
+
};
|
|
22
|
+
const DEFAULT_CONFIG = {
|
|
23
|
+
rules: {},
|
|
24
|
+
ignore: [],
|
|
25
|
+
languages: ['typescript', 'javascript', 'python'],
|
|
26
|
+
};
|
|
27
|
+
function getLanguage(filename) {
|
|
28
|
+
const ext = (0, node_path_1.extname)(filename).toLowerCase();
|
|
29
|
+
return EXTENSION_MAP[ext] || null;
|
|
30
|
+
}
|
|
31
|
+
function shouldIgnore(finding, config) {
|
|
32
|
+
const ruleSeverity = config.rules[finding.rule];
|
|
33
|
+
return ruleSeverity === 'off';
|
|
34
|
+
}
|
|
35
|
+
function adjustSeverity(finding, config) {
|
|
36
|
+
const ruleSeverity = config.rules[finding.rule];
|
|
37
|
+
if (ruleSeverity && ruleSeverity !== 'off') {
|
|
38
|
+
return { ...finding, severity: ruleSeverity };
|
|
39
|
+
}
|
|
40
|
+
return finding;
|
|
41
|
+
}
|
|
42
|
+
function auditFile(filename, config = DEFAULT_CONFIG) {
|
|
43
|
+
const language = getLanguage(filename);
|
|
44
|
+
if (!language) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
if (!config.languages.includes(language)) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
let content;
|
|
51
|
+
try {
|
|
52
|
+
content = (0, node_fs_1.readFileSync)(filename, 'utf-8');
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
const findings = [];
|
|
58
|
+
for (const rule of index_js_1.allRules) {
|
|
59
|
+
if (!rule.languages.includes(language)) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const ruleFindings = rule.check(content, filename);
|
|
63
|
+
for (const finding of ruleFindings) {
|
|
64
|
+
if (!shouldIgnore(finding, config)) {
|
|
65
|
+
findings.push(adjustSeverity(finding, config));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return findings;
|
|
70
|
+
}
|
|
71
|
+
function auditContent(content, filename, config = DEFAULT_CONFIG) {
|
|
72
|
+
const language = getLanguage(filename);
|
|
73
|
+
if (!language) {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
const findings = [];
|
|
77
|
+
for (const rule of index_js_1.allRules) {
|
|
78
|
+
if (!rule.languages.includes(language)) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
const ruleFindings = rule.check(content, filename);
|
|
82
|
+
for (const finding of ruleFindings) {
|
|
83
|
+
if (!shouldIgnore(finding, config)) {
|
|
84
|
+
findings.push(adjustSeverity(finding, config));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return findings;
|
|
89
|
+
}
|
|
90
|
+
function auditDiff(diff, config = DEFAULT_CONFIG) {
|
|
91
|
+
const findings = [];
|
|
92
|
+
let currentFile = '';
|
|
93
|
+
let lineOffset = 0;
|
|
94
|
+
const addedLines = new Map();
|
|
95
|
+
// Parse the diff
|
|
96
|
+
const lines = diff.split('\n');
|
|
97
|
+
for (const line of lines) {
|
|
98
|
+
// New file
|
|
99
|
+
if (line.startsWith('+++ b/')) {
|
|
100
|
+
currentFile = line.slice(6);
|
|
101
|
+
addedLines.set(currentFile, []);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
// Hunk header
|
|
105
|
+
if (line.startsWith('@@')) {
|
|
106
|
+
const match = line.match(/@@ -\d+(?:,\d+)? \+(\d+)/);
|
|
107
|
+
if (match) {
|
|
108
|
+
lineOffset = parseInt(match[1], 10) - 1;
|
|
109
|
+
}
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
// Added line
|
|
113
|
+
if (line.startsWith('+') && !line.startsWith('+++')) {
|
|
114
|
+
lineOffset++;
|
|
115
|
+
const fileLines = addedLines.get(currentFile);
|
|
116
|
+
if (fileLines) {
|
|
117
|
+
fileLines.push({
|
|
118
|
+
line: lineOffset,
|
|
119
|
+
content: line.slice(1),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
// Context or removed line
|
|
125
|
+
if (!line.startsWith('-')) {
|
|
126
|
+
lineOffset++;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Audit added lines for each file
|
|
130
|
+
for (const [filename, lines] of addedLines) {
|
|
131
|
+
if (lines.length === 0)
|
|
132
|
+
continue;
|
|
133
|
+
const content = lines.map((l) => l.content).join('\n');
|
|
134
|
+
const contentFindings = auditContent(content, filename, config);
|
|
135
|
+
// Adjust line numbers back to original file
|
|
136
|
+
for (const finding of contentFindings) {
|
|
137
|
+
const originalLine = lines[finding.line - 1];
|
|
138
|
+
if (originalLine) {
|
|
139
|
+
findings.push({
|
|
140
|
+
...finding,
|
|
141
|
+
line: originalLine.line,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return findings;
|
|
147
|
+
}
|
|
148
|
+
function summarize(findings) {
|
|
149
|
+
let errorCount = 0;
|
|
150
|
+
let warningCount = 0;
|
|
151
|
+
let infoCount = 0;
|
|
152
|
+
const files = new Set();
|
|
153
|
+
for (const finding of findings) {
|
|
154
|
+
files.add(finding.file);
|
|
155
|
+
switch (finding.severity) {
|
|
156
|
+
case 'error':
|
|
157
|
+
errorCount++;
|
|
158
|
+
break;
|
|
159
|
+
case 'warning':
|
|
160
|
+
warningCount++;
|
|
161
|
+
break;
|
|
162
|
+
case 'info':
|
|
163
|
+
infoCount++;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
findings,
|
|
169
|
+
filesScanned: files.size,
|
|
170
|
+
errorCount,
|
|
171
|
+
warningCount,
|
|
172
|
+
infoCount,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function loadConfig(configPath) {
|
|
176
|
+
const paths = configPath
|
|
177
|
+
? [configPath]
|
|
178
|
+
: ['.ai-code-audit.json', '.ai-code-audit.config.json'];
|
|
179
|
+
for (const path of paths) {
|
|
180
|
+
if ((0, node_fs_1.existsSync)(path)) {
|
|
181
|
+
try {
|
|
182
|
+
const content = (0, node_fs_1.readFileSync)(path, 'utf-8');
|
|
183
|
+
const userConfig = JSON.parse(content);
|
|
184
|
+
return {
|
|
185
|
+
...DEFAULT_CONFIG,
|
|
186
|
+
...userConfig,
|
|
187
|
+
rules: { ...DEFAULT_CONFIG.rules, ...userConfig.rules },
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// Invalid config, use defaults
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return DEFAULT_CONFIG;
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=auditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auditor.js","sourceRoot":"","sources":["../src/auditor.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const node_path_1 = require("node:path");
|
|
5
|
+
const auditor_js_1 = require("./auditor.js");
|
|
6
|
+
const VERSION = '0.1.0';
|
|
7
|
+
const COLORS = {
|
|
8
|
+
reset: '\x1b[0m',
|
|
9
|
+
bold: '\x1b[1m',
|
|
10
|
+
dim: '\x1b[2m',
|
|
11
|
+
red: '\x1b[31m',
|
|
12
|
+
yellow: '\x1b[33m',
|
|
13
|
+
blue: '\x1b[34m',
|
|
14
|
+
cyan: '\x1b[36m',
|
|
15
|
+
gray: '\x1b[90m',
|
|
16
|
+
};
|
|
17
|
+
const SEVERITY_COLORS = {
|
|
18
|
+
error: COLORS.red,
|
|
19
|
+
warning: COLORS.yellow,
|
|
20
|
+
info: COLORS.blue,
|
|
21
|
+
};
|
|
22
|
+
const HELP = `
|
|
23
|
+
${COLORS.bold}ai-code-audit${COLORS.reset} v${VERSION}
|
|
24
|
+
Security and quality linter for AI-generated code
|
|
25
|
+
|
|
26
|
+
${COLORS.bold}USAGE:${COLORS.reset}
|
|
27
|
+
aca [options] <files...>
|
|
28
|
+
git diff | aca --stdin
|
|
29
|
+
|
|
30
|
+
${COLORS.bold}OPTIONS:${COLORS.reset}
|
|
31
|
+
-s, --stdin Read diff from stdin
|
|
32
|
+
-f, --format <type> Output format: text, json, sarif (default: text)
|
|
33
|
+
-c, --config <file> Config file path
|
|
34
|
+
--severity <level> Minimum severity: info, warning, error (default: warning)
|
|
35
|
+
-q, --quiet Only output errors
|
|
36
|
+
-h, --help Show help
|
|
37
|
+
-v, --version Show version
|
|
38
|
+
|
|
39
|
+
${COLORS.bold}EXAMPLES:${COLORS.reset}
|
|
40
|
+
aca src/api.ts # Audit a single file
|
|
41
|
+
aca src/**/*.ts # Audit multiple files
|
|
42
|
+
git diff HEAD~1 | aca --stdin # Audit a diff
|
|
43
|
+
git diff --cached | aca --stdin # Audit staged changes
|
|
44
|
+
|
|
45
|
+
${COLORS.bold}GIT HOOK:${COLORS.reset}
|
|
46
|
+
Add to .git/hooks/pre-commit:
|
|
47
|
+
git diff --cached | aca --stdin --severity error
|
|
48
|
+
|
|
49
|
+
`;
|
|
50
|
+
function parseArgs(args) {
|
|
51
|
+
const options = {
|
|
52
|
+
stdin: false,
|
|
53
|
+
format: 'text',
|
|
54
|
+
severity: 'warning',
|
|
55
|
+
quiet: false,
|
|
56
|
+
files: [],
|
|
57
|
+
};
|
|
58
|
+
for (let i = 0; i < args.length; i++) {
|
|
59
|
+
const arg = args[i];
|
|
60
|
+
switch (arg) {
|
|
61
|
+
case '-h':
|
|
62
|
+
case '--help':
|
|
63
|
+
console.log(HELP);
|
|
64
|
+
process.exit(0);
|
|
65
|
+
break;
|
|
66
|
+
case '-v':
|
|
67
|
+
case '--version':
|
|
68
|
+
console.log(`ai-code-audit v${VERSION}`);
|
|
69
|
+
process.exit(0);
|
|
70
|
+
break;
|
|
71
|
+
case '-s':
|
|
72
|
+
case '--stdin':
|
|
73
|
+
options.stdin = true;
|
|
74
|
+
break;
|
|
75
|
+
case '-f':
|
|
76
|
+
case '--format':
|
|
77
|
+
options.format = args[++i];
|
|
78
|
+
break;
|
|
79
|
+
case '-c':
|
|
80
|
+
case '--config':
|
|
81
|
+
options.configPath = args[++i];
|
|
82
|
+
break;
|
|
83
|
+
case '--severity':
|
|
84
|
+
options.severity = args[++i];
|
|
85
|
+
break;
|
|
86
|
+
case '-q':
|
|
87
|
+
case '--quiet':
|
|
88
|
+
options.quiet = true;
|
|
89
|
+
options.severity = 'error';
|
|
90
|
+
break;
|
|
91
|
+
default:
|
|
92
|
+
if (!arg.startsWith('-')) {
|
|
93
|
+
options.files.push(arg);
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return options;
|
|
99
|
+
}
|
|
100
|
+
function filterBySeverity(findings, minSeverity) {
|
|
101
|
+
const severityOrder = ['info', 'warning', 'error'];
|
|
102
|
+
const minIndex = severityOrder.indexOf(minSeverity);
|
|
103
|
+
return findings.filter((f) => severityOrder.indexOf(f.severity) >= minIndex);
|
|
104
|
+
}
|
|
105
|
+
function formatText(result) {
|
|
106
|
+
const output = [];
|
|
107
|
+
// Group findings by file
|
|
108
|
+
const byFile = new Map();
|
|
109
|
+
for (const finding of result.findings) {
|
|
110
|
+
const existing = byFile.get(finding.file) || [];
|
|
111
|
+
existing.push(finding);
|
|
112
|
+
byFile.set(finding.file, existing);
|
|
113
|
+
}
|
|
114
|
+
for (const [file, findings] of byFile) {
|
|
115
|
+
output.push(`\n${COLORS.bold}${file}${COLORS.reset}`);
|
|
116
|
+
for (const f of findings) {
|
|
117
|
+
const color = SEVERITY_COLORS[f.severity];
|
|
118
|
+
const loc = `${f.line}:${f.column}`.padEnd(8);
|
|
119
|
+
const sev = f.severity.padEnd(8);
|
|
120
|
+
output.push(` ${COLORS.gray}${loc}${COLORS.reset} ${color}${sev}${COLORS.reset} ${f.message} ${COLORS.dim}${f.rule}${COLORS.reset}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
output.push('');
|
|
124
|
+
const { errorCount, warningCount, infoCount } = result;
|
|
125
|
+
const total = errorCount + warningCount + infoCount;
|
|
126
|
+
if (total === 0) {
|
|
127
|
+
output.push(`${COLORS.cyan}✓ No issues found${COLORS.reset}`);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
const parts = [];
|
|
131
|
+
if (errorCount > 0)
|
|
132
|
+
parts.push(`${COLORS.red}${errorCount} error${errorCount !== 1 ? 's' : ''}${COLORS.reset}`);
|
|
133
|
+
if (warningCount > 0)
|
|
134
|
+
parts.push(`${COLORS.yellow}${warningCount} warning${warningCount !== 1 ? 's' : ''}${COLORS.reset}`);
|
|
135
|
+
if (infoCount > 0)
|
|
136
|
+
parts.push(`${COLORS.blue}${infoCount} info${COLORS.reset}`);
|
|
137
|
+
output.push(parts.join(', '));
|
|
138
|
+
}
|
|
139
|
+
return output.join('\n');
|
|
140
|
+
}
|
|
141
|
+
function formatJson(result) {
|
|
142
|
+
return JSON.stringify(result, null, 2);
|
|
143
|
+
}
|
|
144
|
+
function formatSarif(result) {
|
|
145
|
+
const sarif = {
|
|
146
|
+
$schema: 'https://json.schemastore.org/sarif-2.1.0.json',
|
|
147
|
+
version: '2.1.0',
|
|
148
|
+
runs: [
|
|
149
|
+
{
|
|
150
|
+
tool: {
|
|
151
|
+
driver: {
|
|
152
|
+
name: 'ai-code-audit',
|
|
153
|
+
version: VERSION,
|
|
154
|
+
rules: result.findings.map((f) => ({
|
|
155
|
+
id: f.rule,
|
|
156
|
+
shortDescription: { text: f.message },
|
|
157
|
+
})),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
results: result.findings.map((f) => ({
|
|
161
|
+
ruleId: f.rule,
|
|
162
|
+
level: f.severity === 'error' ? 'error' : f.severity === 'warning' ? 'warning' : 'note',
|
|
163
|
+
message: { text: f.message },
|
|
164
|
+
locations: [
|
|
165
|
+
{
|
|
166
|
+
physicalLocation: {
|
|
167
|
+
artifactLocation: { uri: f.file },
|
|
168
|
+
region: { startLine: f.line, startColumn: f.column },
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
})),
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
};
|
|
176
|
+
return JSON.stringify(sarif, null, 2);
|
|
177
|
+
}
|
|
178
|
+
async function main() {
|
|
179
|
+
const args = process.argv.slice(2);
|
|
180
|
+
if (args.length === 0) {
|
|
181
|
+
console.log(HELP);
|
|
182
|
+
process.exit(0);
|
|
183
|
+
}
|
|
184
|
+
const options = parseArgs(args);
|
|
185
|
+
const config = (0, auditor_js_1.loadConfig)(options.configPath);
|
|
186
|
+
let findings = [];
|
|
187
|
+
if (options.stdin) {
|
|
188
|
+
// Read diff from stdin
|
|
189
|
+
const chunks = [];
|
|
190
|
+
for await (const chunk of process.stdin) {
|
|
191
|
+
chunks.push(chunk);
|
|
192
|
+
}
|
|
193
|
+
const diff = Buffer.concat(chunks).toString('utf-8');
|
|
194
|
+
findings = (0, auditor_js_1.auditDiff)(diff, config);
|
|
195
|
+
}
|
|
196
|
+
else if (options.files.length > 0) {
|
|
197
|
+
// Audit files
|
|
198
|
+
for (const file of options.files) {
|
|
199
|
+
const filePath = (0, node_path_1.resolve)(file);
|
|
200
|
+
findings.push(...(0, auditor_js_1.auditFile)(filePath, config));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
console.error('Error: No files specified. Use --stdin for diff input.');
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
// Filter by severity
|
|
208
|
+
findings = filterBySeverity(findings, options.severity);
|
|
209
|
+
const result = (0, auditor_js_1.summarize)(findings);
|
|
210
|
+
// Output
|
|
211
|
+
switch (options.format) {
|
|
212
|
+
case 'json':
|
|
213
|
+
console.log(formatJson(result));
|
|
214
|
+
break;
|
|
215
|
+
case 'sarif':
|
|
216
|
+
console.log(formatSarif(result));
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
console.log(formatText(result));
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
// Exit with error if there are errors
|
|
223
|
+
if (result.errorCount > 0) {
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
main().catch((err) => {
|
|
228
|
+
console.error('Fatal error:', err);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
});
|
|
231
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ai-code-audit - Security and quality linter for AI-generated code
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.aiSpecificRules = exports.qualityRules = exports.securityRules = exports.allRules = exports.loadConfig = exports.summarize = exports.auditDiff = exports.auditContent = exports.auditFile = void 0;
|
|
5
|
+
var auditor_js_1 = require("./auditor.js");
|
|
6
|
+
Object.defineProperty(exports, "auditFile", { enumerable: true, get: function () { return auditor_js_1.auditFile; } });
|
|
7
|
+
Object.defineProperty(exports, "auditContent", { enumerable: true, get: function () { return auditor_js_1.auditContent; } });
|
|
8
|
+
Object.defineProperty(exports, "auditDiff", { enumerable: true, get: function () { return auditor_js_1.auditDiff; } });
|
|
9
|
+
Object.defineProperty(exports, "summarize", { enumerable: true, get: function () { return auditor_js_1.summarize; } });
|
|
10
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return auditor_js_1.loadConfig; } });
|
|
11
|
+
var index_js_1 = require("./rules/index.js");
|
|
12
|
+
Object.defineProperty(exports, "allRules", { enumerable: true, get: function () { return index_js_1.allRules; } });
|
|
13
|
+
Object.defineProperty(exports, "securityRules", { enumerable: true, get: function () { return index_js_1.securityRules; } });
|
|
14
|
+
Object.defineProperty(exports, "qualityRules", { enumerable: true, get: function () { return index_js_1.qualityRules; } });
|
|
15
|
+
Object.defineProperty(exports, "aiSpecificRules", { enumerable: true, get: function () { return index_js_1.aiSpecificRules; } });
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,oEAAoE;;;AAEpE,2CAAyF;AAAhF,uGAAA,SAAS,OAAA;AAAE,0GAAA,YAAY,OAAA;AAAE,uGAAA,SAAS,OAAA;AAAE,uGAAA,SAAS,OAAA;AAAE,wGAAA,UAAU,OAAA;AAClE,6CAA0F;AAAjF,oGAAA,QAAQ,OAAA;AAAE,yGAAA,aAAa,OAAA;AAAE,wGAAA,YAAY,OAAA;AAAE,2GAAA,eAAe,OAAA"}
|