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 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;
@@ -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
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { auditFile, auditContent, auditDiff, summarize, loadConfig } from './auditor.js';
2
+ export { allRules, securityRules, qualityRules, aiSpecificRules } from './rules/index.js';
3
+ export type { Finding, Rule, AuditResult, Config, Severity } from './types.js';
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"}
@@ -0,0 +1,6 @@
1
+ import type { Rule } from '../types.js';
2
+ export declare const aiPlaceholder: Rule;
3
+ export declare const incompleteImpl: Rule;
4
+ export declare const typeAnyAbuse: Rule;
5
+ export declare const excessiveComments: Rule;
6
+ export declare const aiSpecificRules: Rule[];