@sun-asterisk/sunlint 1.3.0 → 1.3.1

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +68 -1
  2. package/CONTRIBUTING.md +1179 -54
  3. package/README.md +3 -4
  4. package/config/ci-cd.json +54 -0
  5. package/config/development.json +56 -0
  6. package/config/large-project.json +143 -0
  7. package/config/presets/all.json +0 -1
  8. package/config/release.json +70 -0
  9. package/config/rule-analysis-strategies.js +23 -4
  10. package/config/rules/S027-categories.json +122 -0
  11. package/config/rules/enhanced-rules-registry.json +136 -75
  12. package/config/rules/rules-registry-generated.json +2 -2
  13. package/config/rules/rules-registry.json +13 -1
  14. package/core/cli-action-handler.js +24 -30
  15. package/core/cli-program.js +11 -3
  16. package/core/config-merger.js +29 -2
  17. package/core/enhanced-rules-registry.js +3 -3
  18. package/core/semantic-engine.js +117 -19
  19. package/core/unified-rule-registry.js +1 -1
  20. package/docs/COMMAND-EXAMPLES.md +134 -0
  21. package/docs/LARGE-PROJECT-GUIDE.md +324 -0
  22. package/engines/heuristic-engine.js +71 -13
  23. package/integrations/eslint/plugin/index.js +0 -2
  24. package/origin-rules/common-en.md +8 -8
  25. package/package.json +1 -1
  26. package/rules/common/C017_constructor_logic/analyzer.js +254 -17
  27. package/rules/common/C017_constructor_logic/semantic-analyzer.js +340 -0
  28. package/rules/common/C033_separate_service_repository/README.md +78 -0
  29. package/rules/common/C033_separate_service_repository/analyzer.js +160 -0
  30. package/rules/common/C033_separate_service_repository/config.json +50 -0
  31. package/rules/common/C033_separate_service_repository/regex-based-analyzer.js +585 -0
  32. package/rules/common/C033_separate_service_repository/symbol-based-analyzer.js +368 -0
  33. package/rules/common/C035_error_logging_context/STRATEGY.md +99 -0
  34. package/rules/common/C035_error_logging_context/analyzer.js +230 -0
  35. package/rules/common/C035_error_logging_context/config.json +54 -0
  36. package/rules/common/C035_error_logging_context/regex-based-analyzer.js +299 -0
  37. package/rules/common/C035_error_logging_context/symbol-based-analyzer.js +454 -0
  38. package/rules/common/C040_centralized_validation/analyzer.js +165 -0
  39. package/rules/common/C040_centralized_validation/config.json +46 -0
  40. package/rules/common/C040_centralized_validation/regex-based-analyzer.js +243 -0
  41. package/rules/common/C040_centralized_validation/symbol-based-analyzer.js +416 -0
  42. package/rules/common/{C076_single_test_behavior → C072_single_test_behavior}/analyzer.js +6 -6
  43. package/rules/common/C076_explicit_function_types/README.md +30 -0
  44. package/rules/common/C076_explicit_function_types/analyzer.js +172 -0
  45. package/rules/common/C076_explicit_function_types/config.json +15 -0
  46. package/rules/common/C076_explicit_function_types/semantic-analyzer.js +341 -0
  47. package/rules/index.js +1 -0
  48. package/rules/parser/rule-parser.js +13 -2
  49. package/rules/security/S005_no_origin_auth/README.md +226 -0
  50. package/rules/security/S005_no_origin_auth/analyzer.js +184 -0
  51. package/rules/security/S005_no_origin_auth/ast-analyzer.js +406 -0
  52. package/rules/security/S005_no_origin_auth/config.json +85 -0
  53. package/rules/security/S006_no_plaintext_recovery_codes/README.md +139 -0
  54. package/rules/security/S006_no_plaintext_recovery_codes/analyzer.js +306 -0
  55. package/rules/security/S006_no_plaintext_recovery_codes/config.json +48 -0
  56. package/rules/security/S007_no_plaintext_otp/README.md +198 -0
  57. package/rules/security/S007_no_plaintext_otp/analyzer.js +406 -0
  58. package/rules/security/S007_no_plaintext_otp/config.json +79 -0
  59. package/rules/security/S007_no_plaintext_otp/semantic-analyzer.js +609 -0
  60. package/rules/security/S007_no_plaintext_otp/semantic-config.json +195 -0
  61. package/rules/security/S007_no_plaintext_otp/semantic-wrapper.js +280 -0
  62. package/rules/security/S027_no_hardcoded_secrets/analyzer.js +180 -366
  63. package/rules/security/S027_no_hardcoded_secrets/categories.json +153 -0
  64. package/rules/security/S027_no_hardcoded_secrets/categorized-analyzer.js +250 -0
  65. package/scripts/prepare-release.sh +1 -1
  66. package/docs/ESLINT-INTEGRATION-STRATEGY.md +0 -392
  67. package/docs/FUTURE_PACKAGES.md +0 -83
  68. package/docs/HEURISTIC_VS_AI.md +0 -113
  69. package/docs/PRODUCTION_DEPLOYMENT_ANALYSIS.md +0 -112
  70. package/docs/PRODUCTION_SIZE_IMPACT.md +0 -183
  71. package/docs/RELEASE_GUIDE.md +0 -230
  72. package/docs/STANDARDIZED-CATEGORY-FILTERING.md +0 -156
  73. package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +0 -254
@@ -8,6 +8,7 @@
8
8
 
9
9
  const path = require('path');
10
10
  const fs = require('fs').promises;
11
+ const { Project, SyntaxKind } = require('ts-morph');
11
12
 
12
13
  class SemanticEngine {
13
14
  constructor(options = {}) {
@@ -49,8 +50,9 @@ class SemanticEngine {
49
50
  /**
50
51
  * Initialize ts-morph project with optimized memory configuration
51
52
  * Designed for large projects (3000+ files, 800-1000 lines each)
53
+ * OPTIMIZED: Accept targetFiles parameter to avoid loading unnecessary files
52
54
  */
53
- async initialize(projectPath) {
55
+ async initialize(projectPath, targetFiles = null) {
54
56
  try {
55
57
  // Load ts-morph conditionally
56
58
  const { Project } = await import('ts-morph');
@@ -59,8 +61,8 @@ class SemanticEngine {
59
61
  const tsConfigPath = await this.findTsConfig(projectPath);
60
62
 
61
63
  // Initialize project with memory-optimized settings
62
- this.project = new Project({
63
- tsConfigFilePath: tsConfigPath,
64
+ // When using targetFiles, skip tsconfig to avoid auto-discovery
65
+ const projectOptions = {
64
66
  compilerOptions: {
65
67
  ...this.options.compilerOptions,
66
68
  // Memory optimization flags
@@ -78,22 +80,118 @@ class SemanticEngine {
78
80
  // Performance settings for large codebases
79
81
  resolutionHost: undefined, // Disable resolution host
80
82
  libFolderPath: undefined, // Don't load TypeScript libs
81
- });
83
+ };
84
+
85
+ // Only use tsconfig when auto-discovering files (no targetFiles)
86
+ if (!targetFiles && tsConfigPath) {
87
+ projectOptions.tsConfigFilePath = tsConfigPath;
88
+ }
89
+
90
+ this.project = new Project(projectOptions);
91
+
92
+ // Use provided targetFiles if available, otherwise discover
93
+ const sourceFiles = targetFiles || await this.discoverTargetFiles(projectPath);
94
+
95
+ // Filter to TypeScript/JavaScript files only for semantic analysis
96
+ const semanticFiles = sourceFiles.filter(filePath =>
97
+ /\.(ts|tsx|js|jsx)$/i.test(filePath)
98
+ );
99
+
100
+ if (targetFiles) {
101
+ console.log(`🎯 Targeted files received: ${targetFiles.length} total, ${semanticFiles.length} TS/JS files`);
102
+ if (semanticFiles.length < 10) {
103
+ console.log(` Files: ${semanticFiles.map(f => path.basename(f)).join(', ')}`);
104
+ }
105
+ }
82
106
 
83
- // Only add target files, not entire project
84
- const sourceFiles = await this.discoverTargetFiles(projectPath);
85
- if (sourceFiles.length > 100) {
86
- console.warn(`⚠️ Large project detected (${sourceFiles.length} files) - limited analysis mode`);
87
- // For large projects, only add first 50 files to avoid memory issues
88
- this.project.addSourceFilesAtPaths(sourceFiles.slice(0, 50));
107
+ // Adaptive loading strategy based on project size and user preference
108
+ const userMaxFiles = this.options.maxSemanticFiles;
109
+ let maxFiles;
110
+
111
+ if (userMaxFiles === -1) {
112
+ // Unlimited: Load all files
113
+ maxFiles = semanticFiles.length;
114
+ console.log(`🔧 Semantic Engine config: UNLIMITED analysis (all ${semanticFiles.length} files)`);
115
+ } else if (userMaxFiles === 0) {
116
+ // Disable semantic analysis
117
+ maxFiles = 0;
118
+ console.log(`🔧 Semantic Engine config: DISABLED semantic analysis (heuristic only)`);
119
+ } else if (userMaxFiles > 0) {
120
+ // User-specified limit
121
+ maxFiles = Math.min(userMaxFiles, semanticFiles.length);
122
+ console.log(`🔧 Semantic Engine config: USER limit ${maxFiles} files (requested: ${userMaxFiles})`);
89
123
  } else {
90
- this.project.addSourceFilesAtPaths(sourceFiles);
124
+ // Auto-detect based on project size
125
+ maxFiles = semanticFiles.length > 1000 ? 1000 : semanticFiles.length;
126
+ console.log(`🔧 Semantic Engine config: AUTO limit ${maxFiles} files (project has ${semanticFiles.length} files)`);
127
+ }
128
+
129
+ if (this.options.verbose) {
130
+ console.log(`🔧 Semantic Engine detailed config:`);
131
+ console.log(` 📊 maxSemanticFiles option: ${this.options.maxSemanticFiles}`);
132
+ console.log(` 📈 Total semantic files: ${semanticFiles.length}`);
133
+ console.log(` 🎯 Files to load: ${maxFiles}`);
134
+ console.log(` 📉 Coverage: ${maxFiles > 0 ? Math.round(maxFiles/semanticFiles.length*100) : 0}%`);
135
+ }
136
+
137
+ // Skip semantic analysis if disabled
138
+ if (maxFiles === 0) {
139
+ console.log(`⚠️ Semantic analysis DISABLED - using heuristic rules only`);
140
+ console.log(`💡 To enable semantic analysis, use --max-semantic-files=1000 (or higher)`);
141
+ this.initialized = true;
142
+ return true;
143
+ }
144
+
145
+ if (semanticFiles.length > maxFiles && maxFiles !== semanticFiles.length) {
146
+ console.warn(`⚠️ Large semantic project detected (${semanticFiles.length} files)`);
147
+ console.warn(`⚠️ Loading ${maxFiles} files for memory optimization (${Math.round(maxFiles/semanticFiles.length*100)}% coverage)`);
148
+ if (userMaxFiles !== -1) {
149
+ console.warn(`⚠️ Use --max-semantic-files=-1 to analyze ALL files (unlimited)`);
150
+ console.warn(`⚠️ Use --max-semantic-files=${semanticFiles.length} to analyze exactly this project`);
151
+ }
152
+
153
+ const filesToLoad = semanticFiles.slice(0, maxFiles);
154
+
155
+ // Load files one by one to handle any parse errors gracefully
156
+ let successCount = 0;
157
+ let errorCount = 0;
158
+
159
+ for (const filePath of filesToLoad) {
160
+ try {
161
+ if (require('fs').existsSync(filePath)) {
162
+ this.project.addSourceFileAtPath(filePath);
163
+ successCount++;
164
+ } else {
165
+ errorCount++;
166
+ }
167
+ } catch (error) {
168
+ if (this.options.verbose) {
169
+ console.warn(`❌ Failed to load: ${path.basename(filePath)} - ${error.message}`);
170
+ }
171
+ errorCount++;
172
+ }
173
+ }
174
+
175
+ console.log(`📊 Semantic analysis: ${successCount} files loaded, ${errorCount} skipped`);
176
+
177
+ } else {
178
+ console.log(`📊 Loading all ${semanticFiles.length} files for complete semantic analysis`);
179
+ // For projects within limits, load all files
180
+ this.project.addSourceFilesAtPaths(semanticFiles);
181
+ }
182
+
183
+ // Debug what ts-morph actually loaded
184
+ const actualFiles = this.project.getSourceFiles();
185
+ console.log(`📊 ts-morph loaded: ${actualFiles.length} files (expected: ${semanticFiles.length})`);
186
+ if (actualFiles.length > semanticFiles.length * 2) {
187
+ console.warn(`⚠️ ts-morph auto-discovered additional files (dependency resolution)`);
91
188
  }
92
189
 
93
190
  console.log(`🔧 Semantic Engine initialized (Memory Optimized):`);
94
191
  console.log(` 📁 Project: ${projectPath}`);
95
192
  console.log(` 📋 TS Config: ${tsConfigPath || 'default (minimal)'}`);
96
193
  console.log(` 📄 Files loaded: ${this.project.getSourceFiles().length}`);
194
+ console.log(` 🎯 Targeting mode: ${targetFiles ? 'Filtered files' : 'Auto-discovery'}`);
97
195
  console.log(` 💾 Memory mode: Optimized for large projects`);
98
196
 
99
197
  this.initialized = true;
@@ -199,7 +297,7 @@ class SemanticEngine {
199
297
  const namedImports = importDecl.getNamedImports().map(namedImport => ({
200
298
  name: namedImport.getName(),
201
299
  alias: namedImport.getAliasNode()?.getText(),
202
- line: namedImport.getStartLineNumber()
300
+ line: sourceFile.getLineAndColumnAtPos(namedImport.getStart()).line
203
301
  }));
204
302
 
205
303
  // Default import
@@ -209,7 +307,7 @@ class SemanticEngine {
209
307
  module: moduleSpecifier,
210
308
  defaultImport: defaultImport?.getText(),
211
309
  namedImports,
212
- line: importDecl.getStartLineNumber(),
310
+ line: sourceFile.getLineAndColumnAtPos(importDecl.getStart()).line,
213
311
  isTypeOnly: importDecl.isTypeOnly(),
214
312
  resolvedPath: this.resolveModule(moduleSpecifier, sourceFile)
215
313
  });
@@ -224,7 +322,7 @@ class SemanticEngine {
224
322
  extractFunctionCalls(sourceFile) {
225
323
  const calls = [];
226
324
 
227
- sourceFile.getDescendantsOfKind(sourceFile.getKindName().CallExpression || 210).forEach(callExpr => {
325
+ sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).forEach(callExpr => {
228
326
  const expression = callExpr.getExpression();
229
327
 
230
328
  calls.push({
@@ -232,10 +330,10 @@ class SemanticEngine {
232
330
  arguments: callExpr.getArguments().map(arg => ({
233
331
  text: arg.getText(),
234
332
  type: this.getExpressionType(arg),
235
- line: arg.getStartLineNumber()
333
+ line: sourceFile.getLineAndColumnAtPos(arg.getStart()).line
236
334
  })),
237
- line: callExpr.getStartLineNumber(),
238
- column: callExpr.getStartColumnNumber(),
335
+ line: sourceFile.getLineAndColumnAtPos(callExpr.getStart()).line,
336
+ column: sourceFile.getLineAndColumnAtPos(callExpr.getStart()).column,
239
337
 
240
338
  // Detailed analysis for retry patterns
241
339
  isRetryPattern: this.isRetryPattern(callExpr),
@@ -253,7 +351,7 @@ class SemanticEngine {
253
351
  extractHooks(sourceFile) {
254
352
  const hooks = [];
255
353
 
256
- sourceFile.getDescendantsOfKind(sourceFile.getKindName().CallExpression || 210).forEach(callExpr => {
354
+ sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).forEach(callExpr => {
257
355
  const expression = callExpr.getExpression();
258
356
  const functionName = expression.getText();
259
357
 
@@ -262,7 +360,7 @@ class SemanticEngine {
262
360
  hooks.push({
263
361
  hookName: functionName,
264
362
  arguments: callExpr.getArguments().map(arg => arg.getText()),
265
- line: callExpr.getStartLineNumber(),
363
+ line: sourceFile.getLineAndColumnAtPos(callExpr.getStart()).line,
266
364
 
267
365
  // Special analysis for useQuery, useMutation, etc.
268
366
  isQueryHook: this.isQueryHook(functionName),
@@ -481,4 +481,4 @@ module.exports = {
481
481
  }
482
482
  return instance;
483
483
  }
484
- };
484
+ };
@@ -113,6 +113,22 @@ node cli.js --all --input=. --timeout=60000 --format=summary --no-ai
113
113
  # Disable caching
114
114
  node cli.js --all --input=. --no-cache --format=summary --no-ai
115
115
 
116
+ # **Control semantic analysis for large projects**
117
+ # Default limit: 1000 files for performance balance
118
+ node cli.js --all --input=. --max-semantic-files=1000 --format=summary
119
+
120
+ # For small projects: Analyze all files
121
+ node cli.js --all --input=. --max-semantic-files=0 --format=summary
122
+
123
+ # For large projects: Conservative analysis
124
+ node cli.js --all --input=. --max-semantic-files=500 --format=summary
125
+
126
+ # For massive projects: Minimal semantic analysis
127
+ node cli.js --all --input=. --max-semantic-files=100 --format=summary
128
+
129
+ # Unlimited semantic analysis (use with caution!)
130
+ node cli.js --all --input=. --max-semantic-files=-1 --format=summary
131
+
116
132
  # Verbose logging
117
133
  node cli.js --all --input=. --verbose --format=summary --no-ai
118
134
 
@@ -203,6 +219,124 @@ node cli.js --all --changed-files --diff-base=origin/main --format=github --no-a
203
219
  node cli.js --all --changed-files --ai --format=detailed
204
220
  ```
205
221
 
222
+ ## 🏗️ **Large Project Strategies**
223
+
224
+ > **⚡ Performance Note**: SunLint uses semantic analysis for advanced rules (like C047). For projects with 1000+ files, you can control semantic analysis scope to balance accuracy vs performance.
225
+
226
+ ### **Strategy 1: Incremental Analysis** 📈
227
+ ```bash
228
+ # Start with changed files only (fastest)
229
+ node cli.js --all --changed-files --format=summary --no-ai
230
+
231
+ # Focus on specific directories
232
+ node cli.js --all --input=src/critical --max-semantic-files=2000 --format=summary
233
+
234
+ # Target important file patterns only
235
+ node cli.js --all --include="src/**/*.ts" --exclude="**/*.test.*,**/*.d.ts" --input=.
236
+
237
+ # Use directory-based analysis
238
+ node cli.js --all --input=src/auth --format=summary # Most critical module first
239
+ node cli.js --all --input=src/api --format=summary # Then API layer
240
+ node cli.js --all --input=src/utils --format=summary # Finally utilities
241
+ ```
242
+
243
+ ### **Strategy 2: Semantic Analysis Tuning** 🔧
244
+ ```bash
245
+ # Conservative: 500 files for faster analysis
246
+ node cli.js --all --input=. --max-semantic-files=500 --format=summary
247
+
248
+ # Balanced: 1000 files (default) for medium projects
249
+ node cli.js --all --input=. --max-semantic-files=1000 --format=summary
250
+
251
+ # Comprehensive: 2000+ files for complete analysis
252
+ node cli.js --all --input=. --max-semantic-files=2000 --format=summary
253
+
254
+ # Unlimited: All files (use for final validation)
255
+ node cli.js --all --input=. --max-semantic-files=-1 --format=summary
256
+
257
+ # Disable semantic analysis completely (heuristic only)
258
+ node cli.js --all --input=. --max-semantic-files=0 --format=summary
259
+ ```
260
+
261
+ ### **Strategy 3: Rule-Based Prioritization** 🎯
262
+ ```bash
263
+ # Phase 1: Critical security issues (fast heuristic rules)
264
+ node cli.js --security --input=. --max-semantic-files=0 --format=summary
265
+
266
+ # Phase 2: Code quality basics
267
+ node cli.js --rules=C006,C019,C029 --input=. --max-semantic-files=500 --format=summary
268
+
269
+ # Phase 3: Advanced semantic rules (targeted)
270
+ node cli.js --rules=C047 --input=src --max-semantic-files=1000 --format=summary
271
+
272
+ # Phase 4: Full comprehensive scan
273
+ node cli.js --all --input=. --max-semantic-files=-1 --format=detailed
274
+ ```
275
+
276
+ ### **Strategy 4: CI/CD Optimization** ⚡
277
+ ```bash
278
+ # PR checks: Fast semantic analysis
279
+ node cli.js --all --changed-files --max-semantic-files=300 --format=github --no-ai
280
+
281
+ # Nightly builds: Medium semantic analysis
282
+ node cli.js --all --input=. --max-semantic-files=1000 --format=json --output=nightly.json
283
+
284
+ # Weekly reports: Full semantic analysis
285
+ node cli.js --all --input=. --max-semantic-files=-1 --format=detailed --output=weekly.json
286
+
287
+ # Release validation: Comprehensive with baselines
288
+ node cli.js --all --input=. --max-semantic-files=2000 --baseline=last-release.json
289
+ ```
290
+
291
+ ### **Strategy 5: Memory & Performance Monitoring** 📊
292
+ ```bash
293
+ # Monitor file loading (debug mode)
294
+ node cli.js --all --input=. --max-semantic-files=1000 --verbose --debug
295
+
296
+ # Track performance with different limits
297
+ time node cli.js --all --input=. --max-semantic-files=500 --format=summary
298
+ time node cli.js --all --input=. --max-semantic-files=1000 --format=summary
299
+ time node cli.js --all --input=. --max-semantic-files=2000 --format=summary
300
+
301
+ # Memory-conscious analysis for CI
302
+ node cli.js --all --input=. --max-semantic-files=300 --max-concurrent=2 --format=summary
303
+ ```
304
+
305
+ ### **📋 Recommended Limits by Project Size**
306
+
307
+ | Project Size | Files Count | Recommended Limit | Use Case |
308
+ |-------------|-------------|-------------------|----------|
309
+ | Small | < 100 files | `--max-semantic-files=0` (all) | Complete analysis |
310
+ | Medium | 100-500 files | `--max-semantic-files=500` | Balanced |
311
+ | Large | 500-2000 files | `--max-semantic-files=1000` | Default recommended |
312
+ | Enterprise | 2000-5000 files | `--max-semantic-files=1500` | Conservative |
313
+ | Massive | 5000+ files | `--max-semantic-files=500` | Targeted analysis |
314
+
315
+ > **💡 Pro Tips for Large Projects:**
316
+ > 1. Use `--changed-files` for daily development
317
+ > 2. Use `--max-semantic-files=500` for CI/CD pipelines
318
+ > 3. Use `--max-semantic-files=-1` for release validation
319
+ > 4. Combine with `--include` patterns to focus on critical code
320
+ > 5. Monitor analysis time and adjust limits accordingly
321
+
322
+ ### **Example 1: Monorepo with 5000+ Files**
323
+ ```bash
324
+ # Daily development: Changed files only
325
+ node cli.js --all --changed-files --max-semantic-files=300 --format=summary
326
+
327
+ # Module-specific analysis
328
+ node cli.js --all --input=packages/core --max-semantic-files=1000 --format=summary
329
+ node cli.js --all --input=packages/api --max-semantic-files=1000 --format=summary
330
+
331
+ # CI pipeline: Conservative semantic analysis
332
+ node cli.js --all --changed-files --max-semantic-files=500 --format=github
333
+
334
+ # Release validation: Full analysis by modules
335
+ for dir in packages/*/; do
336
+ node cli.js --all --input="$dir" --max-semantic-files=2000 --format=json --output="${dir//\//-}-report.json"
337
+ done
338
+ ```
339
+
206
340
  ### **Example 2: Legacy Code Improvement**
207
341
  ```bash
208
342
  # Step 1: Baseline assessment
@@ -0,0 +1,324 @@
1
+ # 🏗️ Large Project Analysis Guide
2
+
3
+ > **For projects with 1000+ files**: Complete strategies to optimize SunLint performance while maintaining comprehensive analysis coverage.
4
+
5
+ ## 📊 Overview
6
+
7
+ SunLint uses **semantic analysis** for advanced rules like `C047` (retry pattern detection). For large projects, you can control the scope of semantic analysis to balance accuracy vs performance.
8
+
9
+ ### 🎯 Key Benefits
10
+
11
+ - **Configurable file limits**: Control memory usage and analysis time
12
+ - **Smart defaults**: Automatic optimization for different project sizes
13
+ - **Multiple strategies**: Choose the best approach for your workflow
14
+ - **Full coverage options**: Ensure no violations are missed
15
+
16
+ ## ⚙️ Configuration Options
17
+
18
+ ### CLI Option: `--max-semantic-files`
19
+
20
+ Controls how many files are loaded for semantic analysis:
21
+
22
+ ```bash
23
+ # Default behavior (auto-detect)
24
+ node cli.js --all --input=.
25
+
26
+ # Conservative analysis (500 files)
27
+ node cli.js --all --input=. --max-semantic-files=500
28
+
29
+ # Balanced analysis (1000 files - default)
30
+ node cli.js --all --input=. --max-semantic-files=1000
31
+
32
+ # Comprehensive analysis (2000 files)
33
+ node cli.js --all --input=. --max-semantic-files=2000
34
+
35
+ # Unlimited analysis (all files)
36
+ node cli.js --all --input=. --max-semantic-files=-1
37
+
38
+ # Disable semantic analysis (heuristic only)
39
+ node cli.js --all --input=. --max-semantic-files=0
40
+ ```
41
+
42
+ ### 📋 Recommended Limits by Project Size
43
+
44
+ | Project Size | Files Count | Recommended Limit | Memory Usage | Analysis Time |
45
+ |-------------|-------------|-------------------|--------------|---------------|
46
+ | **Small** | < 100 files | `0` (all files) | Low | Fast |
47
+ | **Medium** | 100-500 files | `500` | Medium | Medium |
48
+ | **Large** | 500-2000 files | `1000` ⭐ | Medium-High | Medium |
49
+ | **Enterprise** | 2000-5000 files | `1500` | High | Slow |
50
+ | **Massive** | 5000+ files | `500-1000` | Controlled | Reasonable |
51
+
52
+ ⭐ **Default recommended setting**
53
+
54
+ ## 🚀 Analysis Strategies
55
+
56
+ ### Strategy 1: Incremental Development
57
+
58
+ Perfect for daily development work:
59
+
60
+ ```bash
61
+ # Focus on changed files only (fastest)
62
+ node cli.js --all --changed-files --max-semantic-files=300 --format=summary
63
+
64
+ # Target specific modules
65
+ node cli.js --all --input=src/auth --max-semantic-files=1000 --format=summary
66
+ node cli.js --all --input=src/api --max-semantic-files=1000 --format=summary
67
+
68
+ # Use file patterns to focus on critical code
69
+ node cli.js --all --include="src/**/*.ts" --exclude="**/*.test.*" --max-semantic-files=1500
70
+ ```
71
+
72
+ ### Strategy 2: CI/CD Pipeline Optimization
73
+
74
+ Optimize for different CI stages:
75
+
76
+ ```bash
77
+ # PR checks: Fast semantic analysis
78
+ node cli.js --all --changed-files --max-semantic-files=300 --format=github --no-ai
79
+
80
+ # Nightly builds: Medium coverage
81
+ node cli.js --all --input=. --max-semantic-files=1000 --format=json --output=nightly.json
82
+
83
+ # Weekly reports: Comprehensive analysis
84
+ node cli.js --all --input=. --max-semantic-files=-1 --format=detailed --output=weekly.json
85
+
86
+ # Release validation: Full coverage with baseline
87
+ node cli.js --all --input=. --max-semantic-files=2000 --baseline=last-release.json
88
+ ```
89
+
90
+ ### Strategy 3: Rule-Based Prioritization
91
+
92
+ Different limits for different rule types:
93
+
94
+ ```bash
95
+ # Phase 1: Critical security (fast heuristic rules)
96
+ node cli.js --security --input=. --max-semantic-files=0 --format=summary
97
+
98
+ # Phase 2: Code quality basics
99
+ node cli.js --rules=C006,C019,C029 --input=. --max-semantic-files=500 --format=summary
100
+
101
+ # Phase 3: Advanced semantic rules (targeted)
102
+ node cli.js --rules=C047 --input=src --max-semantic-files=1000 --format=summary
103
+
104
+ # Phase 4: Full comprehensive scan
105
+ node cli.js --all --input=. --max-semantic-files=-1 --format=detailed
106
+ ```
107
+
108
+ ### Strategy 4: Monorepo Management
109
+
110
+ For large monorepos with multiple packages:
111
+
112
+ ```bash
113
+ # Analyze each package separately
114
+ for package in packages/*/; do
115
+ node cli.js --all --input="$package" --max-semantic-files=1000 \
116
+ --format=json --output="${package//\//-}-report.json"
117
+ done
118
+
119
+ # Focus on core packages first
120
+ node cli.js --all --input=packages/core --max-semantic-files=2000 --format=summary
121
+ node cli.js --all --input=packages/api --max-semantic-files=1500 --format=summary
122
+ node cli.js --all --input=packages/ui --max-semantic-files=1000 --format=summary
123
+
124
+ # Changed files across the entire monorepo
125
+ node cli.js --all --changed-files --max-semantic-files=500 --format=summary
126
+ ```
127
+
128
+ ## 📈 Performance Monitoring
129
+
130
+ ### Memory & Time Tracking
131
+
132
+ ```bash
133
+ # Monitor performance with different limits
134
+ time node cli.js --all --input=. --max-semantic-files=500 --format=summary
135
+ time node cli.js --all --input=. --max-semantic-files=1000 --format=summary
136
+ time node cli.js --all --input=. --max-semantic-files=2000 --format=summary
137
+
138
+ # Memory-conscious analysis for CI
139
+ node cli.js --all --input=. --max-semantic-files=300 --max-concurrent=2 --format=summary
140
+
141
+ # Debug file loading behavior
142
+ node cli.js --all --input=. --max-semantic-files=1000 --verbose --debug
143
+ ```
144
+
145
+ ### Coverage Analysis
146
+
147
+ Check what percentage of your project is being analyzed:
148
+
149
+ ```bash
150
+ # Show file loading statistics
151
+ node cli.js --all --input=. --max-semantic-files=1000 --verbose --format=summary
152
+
153
+ # Compare different limits
154
+ node cli.js --all --input=. --max-semantic-files=500 --verbose --dry-run
155
+ node cli.js --all --input=. --max-semantic-files=1000 --verbose --dry-run
156
+ node cli.js --all --input=. --max-semantic-files=-1 --verbose --dry-run
157
+ ```
158
+
159
+ ## 🎛️ Configuration Files
160
+
161
+ ### sunlint.config.json
162
+
163
+ Create a configuration file for consistent settings:
164
+
165
+ ```json
166
+ {
167
+ "performance": {
168
+ "maxSemanticFiles": 1000,
169
+ "maxConcurrentRules": 5,
170
+ "timeoutMs": 30000
171
+ },
172
+ "input": ["src", "lib"],
173
+ "exclude": [
174
+ "**/*.test.*",
175
+ "**/*.d.ts",
176
+ "**/generated/**"
177
+ ],
178
+ "output": {
179
+ "format": "summary"
180
+ },
181
+ "engines": {
182
+ "semantic": {
183
+ "enabled": true,
184
+ "fileLimit": 1000
185
+ }
186
+ }
187
+ }
188
+ ```
189
+
190
+ ### Environment-Specific Configs
191
+
192
+ Different configs for different environments:
193
+
194
+ ```bash
195
+ # Development (fast feedback)
196
+ cp config/sunlint.dev.json sunlint.config.json
197
+ node cli.js --all --input=.
198
+
199
+ # CI (balanced coverage)
200
+ cp config/sunlint.ci.json sunlint.config.json
201
+ node cli.js --all --changed-files
202
+
203
+ # Release (comprehensive)
204
+ cp config/sunlint.release.json sunlint.config.json
205
+ node cli.js --all --input=.
206
+ ```
207
+
208
+ ## 💡 Best Practices
209
+
210
+ ### 1. Start Conservative, Scale Up
211
+
212
+ ```bash
213
+ # Begin with conservative limits
214
+ node cli.js --all --input=. --max-semantic-files=500 --format=summary
215
+
216
+ # Gradually increase if performance allows
217
+ node cli.js --all --input=. --max-semantic-files=1000 --format=summary
218
+ node cli.js --all --input=. --max-semantic-files=1500 --format=summary
219
+ ```
220
+
221
+ ### 2. Use Different Limits for Different Contexts
222
+
223
+ ```bash
224
+ # Daily development: Focus on changed files
225
+ alias sunlint-dev="node cli.js --all --changed-files --max-semantic-files=300"
226
+
227
+ # Code review: Medium coverage
228
+ alias sunlint-review="node cli.js --all --changed-files --max-semantic-files=500"
229
+
230
+ # Release preparation: Full coverage
231
+ alias sunlint-release="node cli.js --all --input=. --max-semantic-files=-1"
232
+ ```
233
+
234
+ ### 3. Monitor and Adjust
235
+
236
+ Track your analysis performance over time:
237
+
238
+ ```bash
239
+ # Create performance baseline
240
+ echo "Project size: $(find . -name '*.ts' -o -name '*.js' | wc -l) files"
241
+ time node cli.js --all --input=. --max-semantic-files=1000 --format=summary
242
+
243
+ # Adjust based on CI constraints
244
+ if [[ $CI_MEMORY_LIMIT -lt 4096 ]]; then
245
+ SEMANTIC_LIMIT=500
246
+ else
247
+ SEMANTIC_LIMIT=1000
248
+ fi
249
+
250
+ node cli.js --all --input=. --max-semantic-files=$SEMANTIC_LIMIT --format=summary
251
+ ```
252
+
253
+ ### 4. Combine with File Targeting
254
+
255
+ Use semantic limits together with file patterns:
256
+
257
+ ```bash
258
+ # Focus semantic analysis on source files only
259
+ node cli.js --all --include="src/**/*.ts" --exclude="**/*.test.*" --max-semantic-files=1500
260
+
261
+ # Analyze tests separately with lower limits
262
+ node cli.js --all --include="**/*.test.*" --max-semantic-files=500
263
+
264
+ # Target critical modules with higher limits
265
+ node cli.js --all --input=src/security --max-semantic-files=2000
266
+ node cli.js --all --input=src/api --max-semantic-files=1500
267
+ ```
268
+
269
+ ## 🔍 Troubleshooting
270
+
271
+ ### Memory Issues
272
+
273
+ If you encounter out-of-memory errors:
274
+
275
+ ```bash
276
+ # Reduce semantic file limit
277
+ node cli.js --all --input=. --max-semantic-files=500
278
+
279
+ # Disable semantic analysis completely
280
+ node cli.js --all --input=. --max-semantic-files=0
281
+
282
+ # Reduce concurrent rules
283
+ node cli.js --all --input=. --max-semantic-files=1000 --max-concurrent=2
284
+ ```
285
+
286
+ ### Slow Analysis
287
+
288
+ If analysis takes too long:
289
+
290
+ ```bash
291
+ # Use incremental analysis
292
+ node cli.js --all --changed-files --max-semantic-files=300
293
+
294
+ # Focus on specific directories
295
+ node cli.js --all --input=src/critical --max-semantic-files=1000
296
+
297
+ # Use timeout limits
298
+ node cli.js --all --input=. --max-semantic-files=1000 --timeout=60000
299
+ ```
300
+
301
+ ### Missed Violations
302
+
303
+ If you suspect violations are being missed:
304
+
305
+ ```bash
306
+ # Run comprehensive analysis periodically
307
+ node cli.js --all --input=. --max-semantic-files=-1 --format=detailed
308
+
309
+ # Compare different limits
310
+ node cli.js --all --input=. --max-semantic-files=1000 --output=report-1k.json
311
+ node cli.js --all --input=. --max-semantic-files=-1 --output=report-full.json
312
+ diff report-1k.json report-full.json
313
+ ```
314
+
315
+ ## 📚 Related Documentation
316
+
317
+ - [Command Examples](./COMMAND-EXAMPLES.md) - Complete CLI usage examples
318
+ - [Configuration Guide](./CONFIGURATION.md) - Detailed configuration options
319
+ - [CI/CD Guide](./CI-CD-GUIDE.md) - Integration with CI/CD pipelines
320
+ - [Architecture](./ARCHITECTURE.md) - Technical implementation details
321
+
322
+ ---
323
+
324
+ **💡 Pro Tip**: For projects with 2000+ files, consider breaking analysis into modules and running them in parallel, rather than analyzing everything at once.