@behavioral-contracts/verify-cli 1.0.0 → 1.2.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/dist/ai-prompt-generator.d.ts +16 -0
- package/dist/ai-prompt-generator.d.ts.map +1 -0
- package/dist/ai-prompt-generator.js +481 -0
- package/dist/ai-prompt-generator.js.map +1 -0
- package/dist/analyzer.d.ts +41 -0
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/analyzer.js +93 -1
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzers/event-listener-analyzer.d.ts +39 -4
- package/dist/analyzers/event-listener-analyzer.d.ts.map +1 -1
- package/dist/analyzers/event-listener-analyzer.js +123 -10
- package/dist/analyzers/event-listener-analyzer.js.map +1 -1
- package/dist/cli/suppressions.d.ts +9 -0
- package/dist/cli/suppressions.d.ts.map +1 -0
- package/dist/cli/suppressions.js +242 -0
- package/dist/cli/suppressions.js.map +1 -0
- package/dist/index.js +93 -38
- package/dist/index.js.map +1 -1
- package/dist/suppressions/config-loader.d.ts +47 -0
- package/dist/suppressions/config-loader.d.ts.map +1 -0
- package/dist/suppressions/config-loader.js +214 -0
- package/dist/suppressions/config-loader.js.map +1 -0
- package/dist/suppressions/dead-suppression-detector.d.ts +45 -0
- package/dist/suppressions/dead-suppression-detector.d.ts.map +1 -0
- package/dist/suppressions/dead-suppression-detector.js +101 -0
- package/dist/suppressions/dead-suppression-detector.js.map +1 -0
- package/dist/suppressions/index.d.ts +12 -0
- package/dist/suppressions/index.d.ts.map +1 -0
- package/dist/suppressions/index.js +18 -0
- package/dist/suppressions/index.js.map +1 -0
- package/dist/suppressions/manifest.d.ts +114 -0
- package/dist/suppressions/manifest.d.ts.map +1 -0
- package/dist/suppressions/manifest.js +281 -0
- package/dist/suppressions/manifest.js.map +1 -0
- package/dist/suppressions/matcher.d.ts +73 -0
- package/dist/suppressions/matcher.d.ts.map +1 -0
- package/dist/suppressions/matcher.js +163 -0
- package/dist/suppressions/matcher.js.map +1 -0
- package/dist/suppressions/parser.d.ts +59 -0
- package/dist/suppressions/parser.d.ts.map +1 -0
- package/dist/suppressions/parser.js +156 -0
- package/dist/suppressions/parser.js.map +1 -0
- package/dist/suppressions/types.d.ts +121 -0
- package/dist/suppressions/types.d.ts.map +1 -0
- package/dist/suppressions/types.js +8 -0
- package/dist/suppressions/types.js.map +1 -0
- package/package.json +4 -2
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Agent Prompt Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates a comprehensive prompt file for AI agents to review violations,
|
|
5
|
+
* identify false positives, and create an action plan for fixes.
|
|
6
|
+
*/
|
|
7
|
+
import type { AuditRecord } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Generate AI agent prompt file
|
|
10
|
+
*
|
|
11
|
+
* @param auditRecord - The audit record from analysis
|
|
12
|
+
* @param outputPath - Path to the output directory
|
|
13
|
+
* @returns Path to the generated prompt file, or null if no violations found
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateAIPrompt(auditRecord: AuditRecord, outputPath: string): Promise<string | null>;
|
|
16
|
+
//# sourceMappingURL=ai-prompt-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-prompt-generator.d.ts","sourceRoot":"","sources":["../src/ai-prompt-generator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,WAAW,EACxB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsdxB"}
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Agent Prompt Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates a comprehensive prompt file for AI agents to review violations,
|
|
5
|
+
* identify false positives, and create an action plan for fixes.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
/**
|
|
10
|
+
* Generate AI agent prompt file
|
|
11
|
+
*
|
|
12
|
+
* @param auditRecord - The audit record from analysis
|
|
13
|
+
* @param outputPath - Path to the output directory
|
|
14
|
+
* @returns Path to the generated prompt file, or null if no violations found
|
|
15
|
+
*/
|
|
16
|
+
export async function generateAIPrompt(auditRecord, outputPath) {
|
|
17
|
+
const violationCount = auditRecord.violations.length;
|
|
18
|
+
// Skip generation if there are no violations - nothing to review!
|
|
19
|
+
if (violationCount === 0) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const outputDir = path.dirname(outputPath);
|
|
23
|
+
const promptPath = path.join(outputDir, 'ai-agent-prompt.md');
|
|
24
|
+
const indexHtmlPath = path.join(outputDir, 'index.html');
|
|
25
|
+
const errorCount = auditRecord.violations.filter(v => v.severity === 'error').length;
|
|
26
|
+
const warningCount = auditRecord.violations.filter(v => v.severity === 'warning').length;
|
|
27
|
+
// Extract project name from tsconfig path
|
|
28
|
+
// Handle both directory paths and file paths correctly
|
|
29
|
+
let projectDir;
|
|
30
|
+
if (auditRecord.tsconfig.endsWith('tsconfig.json')) {
|
|
31
|
+
// If it's a file path, use the parent directory
|
|
32
|
+
projectDir = path.dirname(auditRecord.tsconfig);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// If it's a directory path, use it directly
|
|
36
|
+
projectDir = auditRecord.tsconfig;
|
|
37
|
+
}
|
|
38
|
+
const projectName = path.basename(path.resolve(projectDir));
|
|
39
|
+
const prompt = `# AI Agent Instructions: Behavioral Contract Violation Review
|
|
40
|
+
|
|
41
|
+
**Project:** ${projectName}
|
|
42
|
+
**Scan Date:** ${new Date(auditRecord.timestamp).toLocaleString()}
|
|
43
|
+
**Total Violations:** ${violationCount} (${errorCount} errors, ${warningCount} warnings)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Important: Working Directory
|
|
48
|
+
|
|
49
|
+
All analysis files and reports are stored in the \`.behavioral-contracts/\` directory at the project root.
|
|
50
|
+
|
|
51
|
+
**This directory is automatically:**
|
|
52
|
+
- Created for you
|
|
53
|
+
- Added to \`.gitignore\` (won't be committed by default)
|
|
54
|
+
- Safe for storing analysis results, fix proposals, and documentation
|
|
55
|
+
|
|
56
|
+
**Recommendation:** Save any analysis files (reports, fix proposals, notes) to \`.behavioral-contracts/analysis/\` so they're organized and won't clutter the codebase.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Your Mission
|
|
61
|
+
|
|
62
|
+
1. **Review all violations** - Check if each is a true positive or false positive
|
|
63
|
+
2. **Suppress false positives** - Mark invalid violations using the suppression system
|
|
64
|
+
3. **Create action plan** - Propose fixes for real violations
|
|
65
|
+
4. **Verify fixes** - Re-run the analyzer to confirm everything is resolved
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Step 1: Review Violations
|
|
70
|
+
|
|
71
|
+
### Where to Find Results
|
|
72
|
+
|
|
73
|
+
📊 **Interactive Visualization (Recommended):**
|
|
74
|
+
Open this file in your browser:
|
|
75
|
+
\`\`\`
|
|
76
|
+
file://${indexHtmlPath}
|
|
77
|
+
\`\`\`
|
|
78
|
+
|
|
79
|
+
📄 **Full Report:**
|
|
80
|
+
\`\`\`bash
|
|
81
|
+
cat ${path.relative(process.cwd(), path.join(outputDir, 'output.txt'))}
|
|
82
|
+
\`\`\`
|
|
83
|
+
|
|
84
|
+
📋 **JSON Data:**
|
|
85
|
+
\`\`\`bash
|
|
86
|
+
cat ${path.relative(process.cwd(), outputPath)}
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
### How to Review
|
|
90
|
+
|
|
91
|
+
For each violation, ask:
|
|
92
|
+
|
|
93
|
+
1. **Is this a real issue?**
|
|
94
|
+
- Does the code lack proper error handling?
|
|
95
|
+
- Would this cause problems in production?
|
|
96
|
+
- Is the contract's requirement valid?
|
|
97
|
+
|
|
98
|
+
2. **Is this a false positive?**
|
|
99
|
+
- Does a framework handle this error?
|
|
100
|
+
- Is there a global error handler?
|
|
101
|
+
- Is this test code that intentionally triggers errors?
|
|
102
|
+
- Does the analyzer misunderstand the code pattern?
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Step 2: Suppress False Positives
|
|
107
|
+
|
|
108
|
+
### Method A: Inline Comment (Recommended for Specific Cases)
|
|
109
|
+
|
|
110
|
+
Add a comment **before** the violating line:
|
|
111
|
+
|
|
112
|
+
\`\`\`typescript
|
|
113
|
+
// @behavioral-contract-ignore <package>/<postcondition-id>: <reason>
|
|
114
|
+
await problematicCode();
|
|
115
|
+
\`\`\`
|
|
116
|
+
|
|
117
|
+
**Examples:**
|
|
118
|
+
|
|
119
|
+
\`\`\`typescript
|
|
120
|
+
// @behavioral-contract-ignore axios/network-failure: Global error handler in src/middleware/errors.ts handles all network failures
|
|
121
|
+
const response = await axios.get('/api/data');
|
|
122
|
+
|
|
123
|
+
// @behavioral-contract-ignore @prisma/client/p2002: NestJS exception filter handles unique constraint violations
|
|
124
|
+
await prisma.user.create({ data });
|
|
125
|
+
|
|
126
|
+
// @behavioral-contract-ignore */timeout-not-set: Timeout configured globally in axios.defaults.timeout
|
|
127
|
+
await axios.post('/api/users', userData);
|
|
128
|
+
\`\`\`
|
|
129
|
+
|
|
130
|
+
### Method B: Config File (Recommended for Global Rules)
|
|
131
|
+
|
|
132
|
+
Create \`.behavioralcontractsrc.json\` in project root:
|
|
133
|
+
|
|
134
|
+
\`\`\`json
|
|
135
|
+
{
|
|
136
|
+
"ignore": [
|
|
137
|
+
{
|
|
138
|
+
"file": "src/test/**",
|
|
139
|
+
"reason": "Test files intentionally trigger errors to validate error handling"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"file": "**/*.test.ts",
|
|
143
|
+
"reason": "Test files"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"file": "**/*.spec.ts",
|
|
147
|
+
"reason": "Test files"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"package": "axios",
|
|
151
|
+
"postconditionId": "network-failure",
|
|
152
|
+
"file": "src/api/legacy.ts",
|
|
153
|
+
"reason": "Legacy code with global error handler - refactor scheduled for Q3 2026"
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
\`\`\`
|
|
158
|
+
|
|
159
|
+
### Suppression Best Practices
|
|
160
|
+
|
|
161
|
+
✅ **DO:**
|
|
162
|
+
- Provide meaningful, specific reasons (minimum 10 characters)
|
|
163
|
+
- Reference where the error is actually handled
|
|
164
|
+
- Include ticket numbers for planned fixes (e.g., "TODO: Fix in JIRA-1234")
|
|
165
|
+
- Use config file for entire directories (tests, legacy)
|
|
166
|
+
- Use inline comments for specific exceptions
|
|
167
|
+
|
|
168
|
+
❌ **DON'T:**
|
|
169
|
+
- Use vague reasons like "false positive" or "not needed"
|
|
170
|
+
- Suppress legitimate errors without good justification
|
|
171
|
+
- Use wildcards excessively (\`*/*\` suppresses everything!)
|
|
172
|
+
- Forget to document WHY it's safe to suppress
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Step 3: Create Action Plan
|
|
177
|
+
|
|
178
|
+
### Categorize Violations
|
|
179
|
+
|
|
180
|
+
**Group by Package:**
|
|
181
|
+
\`\`\`
|
|
182
|
+
axios violations: 12
|
|
183
|
+
- network-failure: 8
|
|
184
|
+
- timeout-not-set: 4
|
|
185
|
+
|
|
186
|
+
@prisma/client violations: 5
|
|
187
|
+
- p2002 (unique constraint): 3
|
|
188
|
+
- p2025 (not found): 2
|
|
189
|
+
\`\`\`
|
|
190
|
+
|
|
191
|
+
**Group by Severity:**
|
|
192
|
+
\`\`\`
|
|
193
|
+
Errors (critical): 8
|
|
194
|
+
Warnings (important): 4
|
|
195
|
+
\`\`\`
|
|
196
|
+
|
|
197
|
+
### Prioritize Fixes
|
|
198
|
+
|
|
199
|
+
1. **Critical Errors** - Production crashes
|
|
200
|
+
2. **High-Frequency Patterns** - Same mistake repeated
|
|
201
|
+
3. **Simple Wins** - Easy fixes with big impact
|
|
202
|
+
4. **Warnings** - Important but not urgent
|
|
203
|
+
|
|
204
|
+
### Fix Strategies
|
|
205
|
+
|
|
206
|
+
**Strategy 1: Create Wrapper Functions**
|
|
207
|
+
|
|
208
|
+
Instead of fixing each instance:
|
|
209
|
+
|
|
210
|
+
\`\`\`typescript
|
|
211
|
+
// utils/api.ts
|
|
212
|
+
import axios, { AxiosRequestConfig } from 'axios';
|
|
213
|
+
|
|
214
|
+
export async function apiGet<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
|
|
215
|
+
try {
|
|
216
|
+
const response = await axios.get(url, config);
|
|
217
|
+
return response.data;
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (axios.isAxiosError(error)) {
|
|
220
|
+
if (error.response) {
|
|
221
|
+
throw new ApiError(\`HTTP \${error.response.status}: \${error.response.statusText}\`, error.response.status);
|
|
222
|
+
} else if (error.request) {
|
|
223
|
+
throw new NetworkError('Network request failed');
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Usage everywhere
|
|
231
|
+
const user = await apiGet<User>('/api/users/123'); // ✅ Error handling built-in
|
|
232
|
+
\`\`\`
|
|
233
|
+
|
|
234
|
+
**Strategy 2: Use Interceptors**
|
|
235
|
+
|
|
236
|
+
For axios violations:
|
|
237
|
+
|
|
238
|
+
\`\`\`typescript
|
|
239
|
+
// config/axios.ts
|
|
240
|
+
import axios from 'axios';
|
|
241
|
+
|
|
242
|
+
axios.interceptors.response.use(
|
|
243
|
+
(response) => response,
|
|
244
|
+
(error) => {
|
|
245
|
+
if (axios.isAxiosError(error)) {
|
|
246
|
+
if (error.response?.status === 429) {
|
|
247
|
+
return handleRateLimit(error);
|
|
248
|
+
}
|
|
249
|
+
if (!error.response) {
|
|
250
|
+
console.error('Network error:', error.message);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return Promise.reject(error);
|
|
254
|
+
}
|
|
255
|
+
);
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
Then suppress violations with:
|
|
259
|
+
\`\`\`typescript
|
|
260
|
+
// @behavioral-contract-ignore axios/*: Global interceptor handles all errors (see config/axios.ts)
|
|
261
|
+
\`\`\`
|
|
262
|
+
|
|
263
|
+
**Strategy 3: Framework Exception Filters**
|
|
264
|
+
|
|
265
|
+
For NestJS, create a global filter:
|
|
266
|
+
|
|
267
|
+
\`\`\`typescript
|
|
268
|
+
// filters/prisma-exception.filter.ts
|
|
269
|
+
@Catch(PrismaClientKnownRequestError)
|
|
270
|
+
export class PrismaExceptionFilter implements ExceptionFilter {
|
|
271
|
+
catch(exception: PrismaClientKnownRequestError, host: ArgumentsHost) {
|
|
272
|
+
const ctx = host.switchToHttp();
|
|
273
|
+
const response = ctx.getResponse();
|
|
274
|
+
|
|
275
|
+
switch (exception.code) {
|
|
276
|
+
case 'P2002':
|
|
277
|
+
return response.status(409).json({
|
|
278
|
+
message: 'Unique constraint violation',
|
|
279
|
+
field: exception.meta?.target
|
|
280
|
+
});
|
|
281
|
+
// ... handle other codes
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
\`\`\`
|
|
286
|
+
|
|
287
|
+
Then suppress with config file:
|
|
288
|
+
\`\`\`json
|
|
289
|
+
{
|
|
290
|
+
"ignore": [{
|
|
291
|
+
"package": "@prisma/client",
|
|
292
|
+
"file": "src/api/**",
|
|
293
|
+
"reason": "Global PrismaExceptionFilter handles all database errors"
|
|
294
|
+
}]
|
|
295
|
+
}
|
|
296
|
+
\`\`\`
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## Step 4: Implement Fixes
|
|
301
|
+
|
|
302
|
+
### Example Report Format
|
|
303
|
+
|
|
304
|
+
\`\`\`markdown
|
|
305
|
+
# Behavioral Contract Violations - Fix Report
|
|
306
|
+
|
|
307
|
+
## Summary
|
|
308
|
+
- Total Violations: ${violationCount}
|
|
309
|
+
- False Positives: [TBD after review]
|
|
310
|
+
- Actual Issues: [TBD after review]
|
|
311
|
+
|
|
312
|
+
## False Positives (Suppressed)
|
|
313
|
+
|
|
314
|
+
### 1. Test Files (8 violations)
|
|
315
|
+
**Reason:** Test files intentionally trigger errors to validate error handling
|
|
316
|
+
**Action:** Created \`.behavioralcontractsrc.json\` with test file pattern
|
|
317
|
+
**Files:** src/test/**, **/*.test.ts, **/*.spec.ts
|
|
318
|
+
|
|
319
|
+
### 2. Global Error Handler (3 violations)
|
|
320
|
+
**Reason:** Express error middleware handles all axios errors
|
|
321
|
+
**Location:** src/middleware/error-handler.ts
|
|
322
|
+
**Action:** Added inline suppressions with reference to middleware
|
|
323
|
+
**Files:**
|
|
324
|
+
- src/api/users.ts:42
|
|
325
|
+
- src/api/posts.ts:78
|
|
326
|
+
- src/api/auth.ts:123
|
|
327
|
+
|
|
328
|
+
## Actual Issues (Fixed)
|
|
329
|
+
|
|
330
|
+
### 1. Missing Try-Catch in API Routes (5 violations)
|
|
331
|
+
**Strategy:** Created \`apiGet\` wrapper function
|
|
332
|
+
**Files:**
|
|
333
|
+
- Created: src/utils/api.ts (wrapper)
|
|
334
|
+
- Updated: src/api/products.ts, src/api/orders.ts, src/api/customers.ts
|
|
335
|
+
**Test:** ✅ Manual testing confirms error handling works
|
|
336
|
+
|
|
337
|
+
### 2. Missing Prisma Error Handling (3 violations)
|
|
338
|
+
**Strategy:** Created NestJS exception filter
|
|
339
|
+
**Files:**
|
|
340
|
+
- Created: src/filters/prisma-exception.filter.ts
|
|
341
|
+
- Updated: src/app.module.ts (registered filter globally)
|
|
342
|
+
**Test:** ✅ Unit tests added, all passing
|
|
343
|
+
|
|
344
|
+
## Testing
|
|
345
|
+
|
|
346
|
+
\`\`\`bash
|
|
347
|
+
# Re-run analyzer
|
|
348
|
+
npx @behavioral-contracts/verify-cli --tsconfig ./tsconfig.json
|
|
349
|
+
|
|
350
|
+
# Result: 0 violations ✅
|
|
351
|
+
\`\`\`
|
|
352
|
+
\`\`\`
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## Step 5: Verify Fixes
|
|
357
|
+
|
|
358
|
+
After implementing fixes and suppressions, re-run:
|
|
359
|
+
|
|
360
|
+
\`\`\`bash
|
|
361
|
+
npx @behavioral-contracts/verify-cli --tsconfig ./tsconfig.json --check-dead-suppressions
|
|
362
|
+
\`\`\`
|
|
363
|
+
|
|
364
|
+
**Expected Results:**
|
|
365
|
+
- ✅ All real violations fixed (0 errors)
|
|
366
|
+
- ✅ False positives suppressed
|
|
367
|
+
- ✅ No dead suppressions (yet - they appear after analyzer upgrades)
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Advanced: Suppression Management
|
|
372
|
+
|
|
373
|
+
### List All Suppressions
|
|
374
|
+
|
|
375
|
+
\`\`\`bash
|
|
376
|
+
npx @behavioral-contracts/verify-cli suppressions list
|
|
377
|
+
\`\`\`
|
|
378
|
+
|
|
379
|
+
### Show Suppression Statistics
|
|
380
|
+
|
|
381
|
+
\`\`\`bash
|
|
382
|
+
npx @behavioral-contracts/verify-cli suppressions stats
|
|
383
|
+
\`\`\`
|
|
384
|
+
|
|
385
|
+
### Check for Dead Suppressions
|
|
386
|
+
|
|
387
|
+
\`\`\`bash
|
|
388
|
+
npx @behavioral-contracts/verify-cli --tsconfig ./tsconfig.json --check-dead-suppressions
|
|
389
|
+
\`\`\`
|
|
390
|
+
|
|
391
|
+
Dead suppressions are suppressions that are no longer needed because the analyzer has improved.
|
|
392
|
+
|
|
393
|
+
### Clean Up Dead Suppressions
|
|
394
|
+
|
|
395
|
+
\`\`\`bash
|
|
396
|
+
npx @behavioral-contracts/verify-cli suppressions clean --auto
|
|
397
|
+
\`\`\`
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Common Patterns to Look For
|
|
402
|
+
|
|
403
|
+
### ✅ Valid Suppressions
|
|
404
|
+
|
|
405
|
+
**Global Error Handler:**
|
|
406
|
+
\`\`\`typescript
|
|
407
|
+
// @behavioral-contract-ignore axios/*: Global error middleware (src/middleware/errors.ts)
|
|
408
|
+
\`\`\`
|
|
409
|
+
|
|
410
|
+
**Framework Exception Filter:**
|
|
411
|
+
\`\`\`typescript
|
|
412
|
+
// @behavioral-contract-ignore @prisma/client/*: NestJS PrismaExceptionFilter handles all errors
|
|
413
|
+
\`\`\`
|
|
414
|
+
|
|
415
|
+
**Test Code:**
|
|
416
|
+
\`\`\`json
|
|
417
|
+
{ "file": "**/*.test.ts", "reason": "Test files" }
|
|
418
|
+
\`\`\`
|
|
419
|
+
|
|
420
|
+
**Legacy Code with Plan:**
|
|
421
|
+
\`\`\`typescript
|
|
422
|
+
// @behavioral-contract-ignore */*: Legacy code - scheduled for refactor in Q3 2026 (JIRA-1234)
|
|
423
|
+
\`\`\`
|
|
424
|
+
|
|
425
|
+
### ❌ Invalid Suppressions (Don't Do This)
|
|
426
|
+
|
|
427
|
+
**Lazy Suppression:**
|
|
428
|
+
\`\`\`typescript
|
|
429
|
+
// @behavioral-contract-ignore axios/network-failure: false positive
|
|
430
|
+
// ❌ Doesn't explain WHY it's safe
|
|
431
|
+
\`\`\`
|
|
432
|
+
|
|
433
|
+
**Hiding Real Issues:**
|
|
434
|
+
\`\`\`typescript
|
|
435
|
+
// @behavioral-contract-ignore axios/network-failure: TODO fix later
|
|
436
|
+
// ❌ Suppressing a real bug without a plan
|
|
437
|
+
\`\`\`
|
|
438
|
+
|
|
439
|
+
**Overly Broad:**
|
|
440
|
+
\`\`\`typescript
|
|
441
|
+
// @behavioral-contract-ignore */*: not needed
|
|
442
|
+
// ❌ Suppresses EVERYTHING - defeats the purpose
|
|
443
|
+
\`\`\`
|
|
444
|
+
|
|
445
|
+
---
|
|
446
|
+
|
|
447
|
+
## Resources
|
|
448
|
+
|
|
449
|
+
📚 **Documentation:**
|
|
450
|
+
- Suppression System Guide: [docs/cli-reference/suppressions.md](https://github.com/behavioral-contracts/verify-cli/blob/main/docs/cli-reference/suppressions.md)
|
|
451
|
+
- Fixing Violations: [docs/getting-started/fixing-violations.md](https://github.com/behavioral-contracts/verify-cli/blob/main/docs/getting-started/fixing-violations.md)
|
|
452
|
+
|
|
453
|
+
🔧 **Tools:**
|
|
454
|
+
- Interactive Visualization: file://${indexHtmlPath}
|
|
455
|
+
- Full Report: ${path.relative(process.cwd(), path.join(outputDir, 'output.txt'))}
|
|
456
|
+
- JSON Data: ${path.relative(process.cwd(), outputPath)}
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Your Task Checklist
|
|
461
|
+
|
|
462
|
+
- [ ] Review all ${violationCount} violations using the interactive visualization
|
|
463
|
+
- [ ] Identify false positives (framework-handled, global handlers, test code)
|
|
464
|
+
- [ ] Add suppressions for false positives (inline comments or config file)
|
|
465
|
+
- [ ] Categorize real violations by package and severity
|
|
466
|
+
- [ ] Create fix strategy (wrappers, interceptors, filters, or direct fixes)
|
|
467
|
+
- [ ] Implement fixes following best practices
|
|
468
|
+
- [ ] Re-run analyzer to verify: \`npx @behavioral-contracts/verify-cli --tsconfig ./tsconfig.json\`
|
|
469
|
+
- [ ] Create detailed report of changes made
|
|
470
|
+
- [ ] Document any suppressions in code comments
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
**Good luck! 🚀**
|
|
475
|
+
|
|
476
|
+
*Generated by @behavioral-contracts/verify-cli v${auditRecord.tool_version}*
|
|
477
|
+
`;
|
|
478
|
+
await fs.promises.writeFile(promptPath, prompt, 'utf-8');
|
|
479
|
+
return promptPath;
|
|
480
|
+
}
|
|
481
|
+
//# sourceMappingURL=ai-prompt-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-prompt-generator.js","sourceRoot":"","sources":["../src/ai-prompt-generator.ts"],"names":[],"mappings":"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"}
|
package/dist/analyzer.d.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* AST Analyzer - uses TypeScript Compiler API to detect behavioral contract violations
|
|
3
3
|
*/
|
|
4
4
|
import type { PackageContract, Violation, AnalyzerConfig } from './types.js';
|
|
5
|
+
import type { DeadSuppression } from './suppressions/types.js';
|
|
5
6
|
/**
|
|
6
7
|
* Main analyzer that coordinates the verification process
|
|
7
8
|
*/
|
|
@@ -10,8 +11,10 @@ export declare class Analyzer {
|
|
|
10
11
|
private typeChecker;
|
|
11
12
|
private contracts;
|
|
12
13
|
private violations;
|
|
14
|
+
private suppressedViolations;
|
|
13
15
|
private projectRoot;
|
|
14
16
|
private includeTests;
|
|
17
|
+
private analyzerVersion;
|
|
15
18
|
private typeToPackage;
|
|
16
19
|
private classToPackage;
|
|
17
20
|
private factoryToPackage;
|
|
@@ -26,6 +29,10 @@ export declare class Analyzer {
|
|
|
26
29
|
* Analyzes all files in the program and returns violations
|
|
27
30
|
*/
|
|
28
31
|
analyze(): Violation[];
|
|
32
|
+
/**
|
|
33
|
+
* Filters out suppressed violations and updates manifest
|
|
34
|
+
*/
|
|
35
|
+
private filterSuppressedViolations;
|
|
29
36
|
/**
|
|
30
37
|
* Extracts all package imports from a source file
|
|
31
38
|
*/
|
|
@@ -362,5 +369,39 @@ export declare class Analyzer {
|
|
|
362
369
|
* Maps S3 command types to their corresponding postcondition IDs
|
|
363
370
|
*/
|
|
364
371
|
private mapS3CommandToPostcondition;
|
|
372
|
+
/**
|
|
373
|
+
* Get all suppressed violations
|
|
374
|
+
*/
|
|
375
|
+
getSuppressedViolations(): Array<{
|
|
376
|
+
violation: Violation;
|
|
377
|
+
suppression: any;
|
|
378
|
+
}>;
|
|
379
|
+
/**
|
|
380
|
+
* Get suppression statistics
|
|
381
|
+
*/
|
|
382
|
+
getSuppressionStatistics(): {
|
|
383
|
+
totalSuppressions: number;
|
|
384
|
+
activeSuppressions: number;
|
|
385
|
+
deadSuppressions: number;
|
|
386
|
+
bySource: {
|
|
387
|
+
inlineComment: number;
|
|
388
|
+
configFile: number;
|
|
389
|
+
aiAgent: number;
|
|
390
|
+
cli: number;
|
|
391
|
+
};
|
|
392
|
+
byPackage: Map<string, number>;
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Get suppression manifest
|
|
396
|
+
*/
|
|
397
|
+
getSuppressionManifest(): import("./suppressions/types.js").SuppressionManifest;
|
|
398
|
+
/**
|
|
399
|
+
* Detect dead suppressions (suppressions that are no longer needed)
|
|
400
|
+
*/
|
|
401
|
+
detectDeadSuppressions(): DeadSuppression[];
|
|
402
|
+
/**
|
|
403
|
+
* Format dead suppression for display
|
|
404
|
+
*/
|
|
405
|
+
formatDeadSuppression(dead: DeadSuppression): string;
|
|
365
406
|
}
|
|
366
407
|
//# sourceMappingURL=analyzer.d.ts.map
|
package/dist/analyzer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EACV,eAAe,EACf,SAAS,EAGT,cAAc,EAEf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"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"}
|