@sun-asterisk/sunlint 1.3.10 → 1.3.12

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.
@@ -0,0 +1,409 @@
1
+ # Quality Scoring & Summary Report Guide
2
+
3
+ ## Overview
4
+
5
+ SunLint includes a comprehensive quality scoring system and summary report generation feature designed for CI/CD integration and management dashboards.
6
+
7
+ ## Features
8
+
9
+ ### 1. Quality Scoring System
10
+
11
+ The quality score is calculated based on multiple factors:
12
+
13
+ ```javascript
14
+ Score Formula: 100 - (errorCount × 5 + warningCount × 1) × (1000 / LOC) + (rulesChecked × 0.5)
15
+ ```
16
+
17
+ **Scoring Components:**
18
+ - **Base Score**: Starts at 100 (perfect quality)
19
+ - **Error Penalty**: -5 points per error
20
+ - **Warning Penalty**: -1 point per warning
21
+ - **LOC Normalization**: Violations are normalized per 1000 lines of code
22
+ - **Rule Bonus**: +0.5 points per rule checked (max 10 points)
23
+ - **Final Range**: 0-100
24
+
25
+ **Grade Scale:**
26
+ - **A+**: 95-100
27
+ - **A**: 90-94
28
+ - **B+**: 85-89
29
+ - **B**: 80-84
30
+ - **C+**: 75-79
31
+ - **C**: 70-74
32
+ - **D**: 60-69
33
+ - **F**: Below 60
34
+
35
+ ### 2. Summary Report Format
36
+
37
+ The summary report is generated in JSON format, designed for easy integration with CI/CD pipelines and management dashboards.
38
+
39
+ **Example Output:**
40
+ ```json
41
+ {
42
+ "metadata": {
43
+ "generated_at": "2025-10-07T03:48:00.636Z",
44
+ "tool": "SunLint",
45
+ "version": "1.3.9",
46
+ "analysis_duration_ms": 390
47
+ },
48
+ "repository": {
49
+ "repository_url": "https://github.com/org/repo",
50
+ "branch": "main",
51
+ "commit_hash": "abc123"
52
+ },
53
+ "quality": {
54
+ "score": 98.9,
55
+ "grade": "A+",
56
+ "metrics": {
57
+ "errors": 0,
58
+ "warnings": 520,
59
+ "rulesChecked": 1,
60
+ "linesOfCode": 319709,
61
+ "violationsPerKLOC": 1.6
62
+ }
63
+ },
64
+ "violations": {
65
+ "total": 520,
66
+ "by_severity": {
67
+ "errors": 0,
68
+ "warnings": 520
69
+ },
70
+ "by_rule": [
71
+ {
72
+ "rule_code": "C065",
73
+ "count": 520,
74
+ "severity": "warning"
75
+ }
76
+ ]
77
+ },
78
+ "analysis": {
79
+ "files_analyzed": 1000,
80
+ "rules_checked": 1,
81
+ "lines_of_code": 319709
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## Usage
87
+
88
+ ### Basic Usage
89
+
90
+ ```bash
91
+ # Generate summary report only
92
+ node cli.js --input=src --rule=C065 --output-summary=summary.json
93
+
94
+ # Generate both detailed report and summary report
95
+ node cli.js --input=src --rule=C065 --output=report.txt --output-summary=summary.json
96
+ ```
97
+
98
+ ### CI/CD Integration
99
+
100
+ #### GitHub Actions Example
101
+
102
+ ```yaml
103
+ name: Code Quality Check
104
+
105
+ on:
106
+ pull_request:
107
+ branches: [ main ]
108
+ push:
109
+ branches: [ main ]
110
+
111
+ jobs:
112
+ quality-check:
113
+ runs-on: ubuntu-latest
114
+
115
+ steps:
116
+ - uses: actions/checkout@v3
117
+
118
+ - name: Setup Node.js
119
+ uses: actions/setup-node@v3
120
+ with:
121
+ node-version: '18'
122
+
123
+ - name: Install dependencies
124
+ run: npm install
125
+
126
+ - name: Run SunLint Analysis
127
+ run: |
128
+ node cli.js \
129
+ --input=src \
130
+ --rule=C001,C005,C015,C065 \
131
+ --output-summary=quality-report.json
132
+ env:
133
+ GITHUB_REPOSITORY: ${{ github.repository }}
134
+ GITHUB_REF_NAME: ${{ github.ref_name }}
135
+ GITHUB_SHA: ${{ github.sha }}
136
+
137
+ - name: Upload Quality Report
138
+ uses: actions/upload-artifact@v3
139
+ with:
140
+ name: quality-report
141
+ path: quality-report.json
142
+
143
+ - name: Post to Dashboard
144
+ run: |
145
+ curl -X POST https://your-dashboard.com/api/quality \
146
+ -H "Content-Type: application/json" \
147
+ -H "Authorization: Bearer ${{ secrets.DASHBOARD_TOKEN }}" \
148
+ -d @quality-report.json
149
+ ```
150
+
151
+ ### Environment Variables
152
+
153
+ The summary report automatically detects and uses Git information from environment variables (commonly available in CI/CD):
154
+
155
+ | Variable | Description | Source | Fallback |
156
+ |----------|-------------|--------|----------|
157
+ | `GITHUB_REPOSITORY` | Repository name (e.g., `owner/repo`) | GitHub Actions | Git remote URL |
158
+ | `GITHUB_REF_NAME` | Branch or tag name | GitHub Actions | `git rev-parse --abbrev-ref HEAD` |
159
+ | `GITHUB_SHA` | Commit hash | GitHub Actions | `git rev-parse HEAD` |
160
+ | `GITHUB_EVENT_PATH` | Path to event payload JSON | GitHub Actions | - |
161
+ | `GITHUB_EVENT_HEAD_COMMIT_MESSAGE` | Commit message | GitHub Actions | `git log -1 --pretty=%B` |
162
+ | `GITHUB_EVENT_HEAD_COMMIT_AUTHOR_EMAIL` | Author email | GitHub Actions | `git log -1 --pretty=%ae` |
163
+ | `GITHUB_EVENT_HEAD_COMMIT_AUTHOR_NAME` | Author name | GitHub Actions | `git log -1 --pretty=%an` |
164
+
165
+ **Additional Fields Auto-Detected:**
166
+ - **`repository_name`**: Extracted from repository URL
167
+ - **`project_path`**: Relative path from repo root (for mono-repo support)
168
+ - **`commit_message`**: From git log or GitHub event
169
+ - **`author_email`**: From git log or GitHub event
170
+ - **`author_name`**: From git log or GitHub event
171
+ - **`pr_number`**: Extracted from commit message (e.g., "#123") or branch name (e.g., "pr-123")
172
+
173
+ If environment variables are not available, the tool will automatically detect all Git information from the local repository.
174
+
175
+ ## CLI Options
176
+
177
+ ### `--output-summary <file>`
178
+
179
+ Generate a summary report in JSON format suitable for CI/CD and management dashboards.
180
+
181
+ **Differences from `--output`:**
182
+
183
+ | Feature | `--output` | `--output-summary` |
184
+ |---------|-----------|-------------------|
185
+ | Format | Text/JSON (ESLint-compatible) | JSON (Custom format) |
186
+ | Detail Level | Full violation details | Summary only |
187
+ | File Size | Large (includes all details) | Small (summary only) |
188
+ | Purpose | Detailed debugging | CI/CD integration |
189
+ | Includes Score | ❌ No | ✅ Yes |
190
+ | Includes LOC | ❌ No | ✅ Yes |
191
+ | Git Info | ❌ No | ✅ Yes |
192
+ | Violation Count by Rule | ❌ No | ✅ Yes |
193
+
194
+ **Example:**
195
+
196
+ ```bash
197
+ # Detailed report: Shows every violation with line numbers and messages
198
+ node cli.js --input=src --rule=C065 --output=detailed-report.txt
199
+
200
+ # Summary report: Shows total count per rule, score, and metrics
201
+ node cli.js --input=src --rule=C065 --output-summary=summary.json
202
+
203
+ # Both: Get detailed report for debugging + summary for dashboard
204
+ node cli.js --input=src --rule=C065 \
205
+ --output=detailed-report.txt \
206
+ --output-summary=summary.json
207
+ ```
208
+
209
+ ## Integration Examples
210
+
211
+ ### 1. Send to Management Dashboard
212
+
213
+ ```javascript
214
+ const fs = require('fs');
215
+ const axios = require('axios');
216
+
217
+ const report = JSON.parse(fs.readFileSync('summary.json', 'utf8'));
218
+
219
+ await axios.post('https://dashboard.company.com/api/quality', {
220
+ project: 'my-project',
221
+ ...report
222
+ }, {
223
+ headers: {
224
+ 'Authorization': `Bearer ${process.env.DASHBOARD_TOKEN}`
225
+ }
226
+ });
227
+ ```
228
+
229
+ ### 2. Slack Notification
230
+
231
+ ```javascript
232
+ const fs = require('fs');
233
+ const axios = require('axios');
234
+
235
+ const report = JSON.parse(fs.readFileSync('summary.json', 'utf8'));
236
+ const { quality, violations, analysis } = report;
237
+
238
+ const message = {
239
+ text: `Code Quality Report: ${quality.grade} (${quality.score})`,
240
+ blocks: [
241
+ {
242
+ type: "section",
243
+ text: {
244
+ type: "mrkdwn",
245
+ text: `*Code Quality Analysis*\n` +
246
+ `Score: *${quality.score}* (${quality.grade})\n` +
247
+ `Violations: ${violations.total} (${violations.by_severity.errors} errors, ${violations.by_severity.warnings} warnings)\n` +
248
+ `Files: ${analysis.files_analyzed} | LOC: ${analysis.lines_of_code.toLocaleString()}`
249
+ }
250
+ }
251
+ ]
252
+ };
253
+
254
+ await axios.post(process.env.SLACK_WEBHOOK_URL, message);
255
+ ```
256
+
257
+ ### 3. Quality Gate in CI/CD
258
+
259
+ ```bash
260
+ #!/bin/bash
261
+
262
+ # Run analysis
263
+ node cli.js --input=src --rule=C001,C005,C015,C065 --output-summary=quality.json
264
+
265
+ # Extract score
266
+ SCORE=$(jq -r '.quality.score' quality.json)
267
+
268
+ # Set minimum score threshold
269
+ MIN_SCORE=80
270
+
271
+ # Check if score meets threshold
272
+ if (( $(echo "$SCORE < $MIN_SCORE" | bc -l) )); then
273
+ echo "❌ Quality score $SCORE is below threshold $MIN_SCORE"
274
+ exit 1
275
+ else
276
+ echo "✅ Quality score $SCORE meets threshold"
277
+ exit 0
278
+ fi
279
+ ```
280
+
281
+ ## Best Practices
282
+
283
+ ### 1. Rule Selection
284
+
285
+ Choose rules appropriate for your quality goals:
286
+
287
+ ```bash
288
+ # Security focus
289
+ node cli.js --input=src --rule=S001,S004,S010 --output-summary=security.json
290
+
291
+ # Code organization focus
292
+ node cli.js --input=src --rule=C001,C005,C006,C015 --output-summary=organization.json
293
+
294
+ # Testing focus
295
+ node cli.js --input=src --rule=C065,C066 --output-summary=testing.json
296
+
297
+ # Comprehensive check (slower)
298
+ node cli.js --input=src --rule=security,cleancode --output-summary=full.json
299
+ ```
300
+
301
+ ### 2. Performance Optimization
302
+
303
+ For large projects:
304
+
305
+ ```bash
306
+ # Analyze only changed files (PR mode)
307
+ node cli.js --input=src --rule=C001,C005 --changed-files --output-summary=pr-quality.json
308
+
309
+ # Set file limits for faster analysis
310
+ node cli.js --input=src --rule=C001,C005 --max-files=500 --output-summary=quick-check.json
311
+ ```
312
+
313
+ ### 3. Trending Analysis
314
+
315
+ Track quality over time:
316
+
317
+ ```javascript
318
+ const fs = require('fs');
319
+
320
+ // Save with timestamp
321
+ const report = JSON.parse(fs.readFileSync('summary.json', 'utf8'));
322
+ const timestamp = new Date().toISOString();
323
+
324
+ // Store in database or time-series storage
325
+ await db.collection('quality_reports').insertOne({
326
+ ...report,
327
+ timestamp
328
+ });
329
+
330
+ // Query trends
331
+ const last30Days = await db.collection('quality_reports')
332
+ .find({
333
+ timestamp: { $gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) }
334
+ })
335
+ .sort({ timestamp: 1 })
336
+ .toArray();
337
+
338
+ // Calculate trend
339
+ const scores = last30Days.map(r => r.quality.score);
340
+ const trend = scores[scores.length - 1] - scores[0];
341
+ console.log(`Quality trend (30 days): ${trend > 0 ? '+' : ''}${trend.toFixed(1)}`);
342
+ ```
343
+
344
+ ## Scoring Interpretation
345
+
346
+ ### Score Ranges
347
+
348
+ - **95-100 (A+)**: Excellent code quality with minimal violations
349
+ - **90-94 (A)**: Very good quality, minor improvements possible
350
+ - **85-89 (B+)**: Good quality with some areas for improvement
351
+ - **80-84 (B)**: Acceptable quality, several improvements recommended
352
+ - **75-79 (C+)**: Below average, significant improvements needed
353
+ - **70-74 (C)**: Poor quality, requires immediate attention
354
+ - **60-69 (D)**: Very poor quality, major refactoring needed
355
+ - **0-59 (F)**: Critical quality issues
356
+
357
+ ### Metrics Understanding
358
+
359
+ **Violations per KLOC (Violations per 1000 Lines of Code)**
360
+
361
+ This metric normalizes violations by code size:
362
+
363
+ - **< 1**: Excellent
364
+ - **1-3**: Good
365
+ - **3-5**: Fair
366
+ - **5-10**: Poor
367
+ - **> 10**: Critical
368
+
369
+ ## Troubleshooting
370
+
371
+ ### LOC Calculation Issues
372
+
373
+ If LOC is 0 or incorrect:
374
+
375
+ ```bash
376
+ # Ensure input path is correct
377
+ node cli.js --input=./src --rule=C065 --output-summary=summary.json
378
+
379
+ # For multiple paths
380
+ node cli.js --input=./src,./lib --rule=C065 --output-summary=summary.json
381
+ ```
382
+
383
+ ### Git Information Not Detected
384
+
385
+ In CI/CD, ensure environment variables are set:
386
+
387
+ ```yaml
388
+ env:
389
+ GITHUB_REPOSITORY: ${{ github.repository }}
390
+ GITHUB_REF_NAME: ${{ github.ref_name }}
391
+ GITHUB_SHA: ${{ github.sha }}
392
+ ```
393
+
394
+ For local development:
395
+
396
+ ```bash
397
+ # Check if git is available
398
+ git rev-parse --git-dir
399
+
400
+ # Run from repository root
401
+ cd /path/to/repo
402
+ node /path/to/sunlint/cli.js --input=src --output-summary=summary.json
403
+ ```
404
+
405
+ ## See Also
406
+
407
+ - [Configuration Guide](CONFIGURATION.md)
408
+ - [CI/CD Integration Guide](CI-CD-GUIDE.md)
409
+ - [Command Examples](COMMAND-EXAMPLES.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sun-asterisk/sunlint",
3
- "version": "1.3.10",
3
+ "version": "1.3.12",
4
4
  "description": "☀️ SunLint - Multi-language static analysis tool for code quality and security | Sun* Engineering Standards",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -66,8 +66,8 @@ class C023SymbolBasedAnalyzer {
66
66
  }
67
67
  }
68
68
 
69
- checkScope(node, violations) {
70
- const seen = new Map();
69
+ checkScope(node, violations, parentSeen = new Map()) {
70
+ const seen = new Map(parentSeen);
71
71
 
72
72
  node.forEachChild((child) => {
73
73
  switch (child.getKind()) {
@@ -83,56 +83,55 @@ class C023SymbolBasedAnalyzer {
83
83
  case SyntaxKind.ArrowFunction:
84
84
  case SyntaxKind.MethodDeclaration:
85
85
  case SyntaxKind.Constructor: { // ✅ also cover constructors
86
- const func = child;
87
- // Params
88
- func.getParameters().forEach((p) =>
89
- this.checkDuplicate(p, seen, violations)
86
+ const funcSeen = new Map();
87
+ child.getParameters().forEach((p) =>
88
+ this.checkDuplicate(p, funcSeen, violations)
90
89
  );
91
- // Body as new scope
92
- const body = func.getBody?.();
93
- if (body) this.checkScope(body, violations);
90
+ const body = child.getBody && child.getBody();
91
+ if (body) this.checkScope(body, violations, funcSeen);
94
92
  break;
95
93
  }
96
94
 
97
95
  case SyntaxKind.Block: {
98
- this.checkScope(child, violations);
96
+ this.checkScope(child, violations, new Map(seen));
99
97
  break;
100
98
  }
101
99
 
102
100
  case SyntaxKind.CatchClause: {
101
+ const catchSeen = new Map(seen);
103
102
  const catchVar = child.getVariableDeclaration();
104
103
  if (catchVar) {
105
- // register catch param in scope
106
- this.checkDuplicate(catchVar, seen, violations);
104
+ this.checkDuplicate(catchVar, catchSeen, violations);
107
105
  }
108
- // Traverse catch block (same scope as catch param)
109
- this.checkScope(child.getBlock(), violations);
106
+ this.checkScope(child.getBlock(), violations, catchSeen);
110
107
  break;
111
108
  }
112
109
 
113
110
  case SyntaxKind.ForStatement:
114
111
  case SyntaxKind.ForOfStatement:
115
112
  case SyntaxKind.ForInStatement: {
116
- const initializer = child.getInitializer?.();
117
- if (initializer) {
118
- initializer.getDeclarations?.().forEach((decl) =>
119
- this.checkDuplicate(decl, seen, violations)
113
+ const loopSeen = new Map(seen);
114
+ const initializer = child.getInitializer && child.getInitializer();
115
+ if (initializer && initializer.getDeclarations) {
116
+ initializer.getDeclarations().forEach((decl) =>
117
+ this.checkDuplicate(decl, loopSeen, violations)
120
118
  );
121
119
  }
122
- const statement = child.getStatement?.();
123
- if (statement) this.checkScope(statement, violations);
120
+ const statement = child.getStatement && child.getStatement();
121
+ if (statement) this.checkScope(statement, violations, loopSeen);
124
122
  break;
125
123
  }
126
124
 
127
125
  default: {
128
- this.checkScope(child, violations);
126
+ this.checkScope(child, violations, seen);
129
127
  }
130
128
  }
131
129
  });
132
130
  }
133
131
 
134
132
  checkDuplicate(node, seen, violations) {
135
- const name = node.getName?.();
133
+ const nameNode = node.getNameNode();
134
+ const name = nameNode.getText();
136
135
  if (!name) return;
137
136
  const filePath = node.getSourceFile().getFilePath();
138
137
 
package/docs/AI.md DELETED
@@ -1,163 +0,0 @@
1
- # 🤖 AI-Powered Analysis
2
-
3
- Sunlint supports AI-powered code analysis alongside traditional pattern-based analysis for more intelligent and context-aware rule checking.
4
-
5
- ## Overview
6
-
7
- - **🎯 Smart Analysis**: Uses AI to understand code context and intent
8
- - **🔄 Fallback Strategy**: Automatically falls back to pattern analysis if AI fails
9
- - **⚡ Performance**: AI analysis runs per-file with caching support
10
- - **🔧 Configurable**: Multiple AI providers and models supported
11
-
12
- ## Configuration
13
-
14
- ### In `.sunlint.json`:
15
-
16
- ```json
17
- {
18
- "ai": {
19
- "enabled": true,
20
- "provider": "openai",
21
- "model": "gpt-4o-mini",
22
- "apiKey": "${OPENAI_API_KEY}",
23
- "fallbackToPattern": true
24
- }
25
- }
26
- ```
27
-
28
- ### Environment Variables:
29
-
30
- ```bash
31
- export OPENAI_API_KEY="your-openai-api-key"
32
- ```
33
-
34
- ## Supported Providers
35
-
36
- ### OpenAI
37
- - **Models**: `gpt-4`, `gpt-4o-mini`, `gpt-3.5-turbo`
38
- - **API Key**: Required via `OPENAI_API_KEY` environment variable
39
- - **Cost**: Pay-per-use based on OpenAI pricing
40
-
41
- ### GitHub Copilot (Planned)
42
- - **Integration**: VS Code extension integration
43
- - **Models**: GitHub Copilot models
44
- - **Authentication**: VS Code Copilot session
45
-
46
- ## AI-Enhanced Rules
47
-
48
- ### C019 - Log Level Usage
49
- ✅ **AI-Enabled**: Understands code context to determine appropriate log levels
50
-
51
- **AI Analysis Features:**
52
- - **Context Understanding**: Analyzes surrounding code to determine error criticality
53
- - **Intent Recognition**: Understands whether errors are expected or exceptional
54
- - **Semantic Analysis**: Goes beyond pattern matching to understand meaning
55
-
56
- **Example:**
57
- ```typescript
58
- // AI understands this is a validation error, suggests warn level
59
- if (!user.email) {
60
- console.error('Missing email'); // AI: Should use console.warn()
61
- }
62
-
63
- // AI understands this is a critical system error, keeps error level
64
- try {
65
- await database.connect();
66
- } catch (error) {
67
- console.error('Database connection failed:', error); // AI: Appropriate error level
68
- }
69
- ```
70
-
71
- ## Usage
72
-
73
- ### CLI Commands
74
-
75
- **Enable AI for specific rule:**
76
- ```bash
77
- sunlint --rule=C019 --input=src --ai
78
- ```
79
-
80
- **Enable AI for all rules:**
81
- ```bash
82
- sunlint --quality --input=src --ai
83
- ```
84
-
85
- **Debug AI analysis:**
86
- ```bash
87
- sunlint --rule=C019 --input=src --ai --verbose
88
- ```
89
-
90
- ### VS Code Integration
91
-
92
- 1. **Debug Configuration**: Use "Debug Sunlint - AI Analysis"
93
- 2. **Task**: Run "Sunlint: AI Analysis Test"
94
- 3. **Set API Key**: Configure `OPENAI_API_KEY` in environment
95
-
96
- ## Output Differences
97
-
98
- ### Pattern Analysis Output:
99
- ```
100
- WARNING: Error log level used for non-critical issue - should use warn/info level
101
- at src/user.ts:15:5 (C019)
102
- ```
103
-
104
- ### AI Analysis Output:
105
- ```
106
- WARNING: Email validation error should use console.warn() - this is user input validation, not a system error
107
- at src/user.ts:15:5 (C019)
108
- Suggestion: Change to console.warn('User email validation failed:', email)
109
- ```
110
-
111
- ## Performance Considerations
112
-
113
- - **Caching**: AI responses are cached per file content hash
114
- - **Concurrency**: AI calls are made concurrently with rate limiting
115
- - **Timeout**: 30-second timeout per AI request
116
- - **Cost**: Monitor API usage in OpenAI dashboard
117
-
118
- ## Troubleshooting
119
-
120
- ### Common Issues
121
-
122
- **API Key Not Found:**
123
- ```bash
124
- ⚠️ AI API key not found, falling back to pattern analysis
125
- ```
126
- Solution: Set `OPENAI_API_KEY` environment variable
127
-
128
- **API Rate Limit:**
129
- ```bash
130
- AI Analysis failed: OpenAI API error: 429 Too Many Requests
131
- ```
132
- Solution: Reduce `maxConcurrentRules` in config or wait
133
-
134
- **Network Issues:**
135
- ```bash
136
- AI Analysis failed: OpenAI API error: Network timeout
137
- ```
138
- Solution: Check internet connection, increase `timeoutMs`
139
-
140
- ### Debug AI Issues
141
-
142
- 1. **Enable verbose mode**: `--verbose`
143
- 2. **Check API key**: `echo $OPENAI_API_KEY`
144
- 3. **Test connection**: Use debug configuration
145
- 4. **Check API quota**: Visit OpenAI dashboard
146
-
147
- ## Future Enhancements
148
-
149
- - **🔄 GitHub Copilot Integration**: Direct integration with VS Code Copilot
150
- - **📊 Custom Models**: Support for fine-tuned models
151
- - **🎯 Rule-Specific Prompts**: Specialized prompts per rule type
152
- - **💾 Smart Caching**: Semantic caching across similar code patterns
153
- - **📈 Analytics**: AI vs Pattern analysis effectiveness metrics
154
-
155
- ## Cost Estimation
156
-
157
- **OpenAI API Costs** (approximate):
158
- - **gpt-4o-mini**: ~$0.001 per 1K tokens
159
- - **gpt-4**: ~$0.03 per 1K tokens
160
- - **Average file**: ~500 tokens
161
- - **1000 files with gpt-4o-mini**: ~$0.50
162
-
163
- **Recommendation**: Start with `gpt-4o-mini` for cost-effectiveness.