@sun-asterisk/sunlint 1.0.6 → 1.0.7

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 (165) hide show
  1. package/CHANGELOG.md +108 -169
  2. package/README.md +7 -1
  3. package/config/presets/beginner.json +1 -1
  4. package/config/presets/ci.json +3 -2
  5. package/config/presets/recommended.json +1 -1
  6. package/config/presets/strict.json +3 -2
  7. package/config/rules-registry.json +60 -0
  8. package/config/sunlint-schema.json +0 -7
  9. package/config/typescript/eslint.config.js +4 -0
  10. package/core/config-manager.js +9 -8
  11. package/core/config-merger.js +12 -0
  12. package/core/file-targeting-service.js +1 -6
  13. package/core/rule-mapping-service.js +8 -0
  14. package/package.json +2 -5
  15. package/cli-legacy.js +0 -355
  16. package/docs/AI.md +0 -163
  17. package/docs/ARCHITECTURE.md +0 -78
  18. package/docs/CI-CD-GUIDE.md +0 -315
  19. package/docs/COMMAND-EXAMPLES.md +0 -256
  20. package/docs/DEBUG.md +0 -86
  21. package/docs/DISTRIBUTION.md +0 -153
  22. package/docs/ENHANCED_FILE_TARGETING.md +0 -0
  23. package/docs/ESLINT-INTEGRATION-STRATEGY.md +0 -392
  24. package/docs/ESLINT_INTEGRATION.md +0 -238
  25. package/docs/FILE_TARGETING_COMPARISON.md +0 -0
  26. package/docs/FOLDER_STRUCTURE.md +0 -59
  27. package/docs/HEURISTIC_VS_AI.md +0 -113
  28. package/docs/README.md +0 -32
  29. package/docs/RELEASE_GUIDE.md +0 -230
  30. package/docs/RULE-RESPONSIBILITY-MATRIX.md +0 -204
  31. package/eslint-integration/.eslintrc.js +0 -98
  32. package/eslint-integration/cli.js +0 -35
  33. package/eslint-integration/eslint-plugin-custom/c002-no-duplicate-code.js +0 -204
  34. package/eslint-integration/eslint-plugin-custom/c003-no-vague-abbreviations.js +0 -246
  35. package/eslint-integration/eslint-plugin-custom/c006-function-name-verb-noun.js +0 -207
  36. package/eslint-integration/eslint-plugin-custom/c010-limit-block-nesting.js +0 -90
  37. package/eslint-integration/eslint-plugin-custom/c013-no-dead-code.js +0 -43
  38. package/eslint-integration/eslint-plugin-custom/c014-abstract-dependency-preferred.js +0 -38
  39. package/eslint-integration/eslint-plugin-custom/c017-limit-constructor-logic.js +0 -39
  40. package/eslint-integration/eslint-plugin-custom/c018-no-generic-throw.js +0 -335
  41. package/eslint-integration/eslint-plugin-custom/c023-no-duplicate-variable-name-in-scope.js +0 -142
  42. package/eslint-integration/eslint-plugin-custom/c027-limit-function-nesting.js +0 -50
  43. package/eslint-integration/eslint-plugin-custom/c029-catch-block-logging.js +0 -80
  44. package/eslint-integration/eslint-plugin-custom/c030-use-custom-error-classes.js +0 -294
  45. package/eslint-integration/eslint-plugin-custom/c034-no-implicit-return.js +0 -34
  46. package/eslint-integration/eslint-plugin-custom/c035-no-empty-catch.js +0 -32
  47. package/eslint-integration/eslint-plugin-custom/c041-no-config-inline.js +0 -64
  48. package/eslint-integration/eslint-plugin-custom/c042-boolean-name-prefix.js +0 -406
  49. package/eslint-integration/eslint-plugin-custom/c043-no-console-or-print.js +0 -300
  50. package/eslint-integration/eslint-plugin-custom/c047-no-duplicate-retry-logic.js +0 -239
  51. package/eslint-integration/eslint-plugin-custom/c048-no-var-declaration.js +0 -31
  52. package/eslint-integration/eslint-plugin-custom/index.js +0 -155
  53. package/eslint-integration/eslint-plugin-custom/package.json +0 -13
  54. package/eslint-integration/eslint-plugin-custom/package.json.bak +0 -9
  55. package/eslint-integration/eslint-plugin-custom/s003-no-unvalidated-redirect.js +0 -86
  56. package/eslint-integration/eslint-plugin-custom/s005-no-origin-auth.js +0 -95
  57. package/eslint-integration/eslint-plugin-custom/s006-activation-recovery-secret-not-plaintext.js +0 -69
  58. package/eslint-integration/eslint-plugin-custom/s008-crypto-agility.js +0 -62
  59. package/eslint-integration/eslint-plugin-custom/s009-no-insecure-crypto.js +0 -103
  60. package/eslint-integration/eslint-plugin-custom/s010-no-insecure-random-in-sensitive-context.js +0 -123
  61. package/eslint-integration/eslint-plugin-custom/s011-no-insecure-uuid.js +0 -66
  62. package/eslint-integration/eslint-plugin-custom/s012-hardcode-secret.js +0 -71
  63. package/eslint-integration/eslint-plugin-custom/s014-insecure-tls-version.js +0 -50
  64. package/eslint-integration/eslint-plugin-custom/s015-insecure-tls-certificate.js +0 -43
  65. package/eslint-integration/eslint-plugin-custom/s016-sensitive-query-parameter.js +0 -59
  66. package/eslint-integration/eslint-plugin-custom/s017-no-sql-injection.js +0 -193
  67. package/eslint-integration/eslint-plugin-custom/s018-positive-input-validation.js +0 -56
  68. package/eslint-integration/eslint-plugin-custom/s019-no-raw-user-input-in-email.js +0 -113
  69. package/eslint-integration/eslint-plugin-custom/s020-no-eval-dynamic-execution.js +0 -89
  70. package/eslint-integration/eslint-plugin-custom/s022-output-encoding.js +0 -78
  71. package/eslint-integration/eslint-plugin-custom/s023-no-json-injection.js +0 -300
  72. package/eslint-integration/eslint-plugin-custom/s025-server-side-input-validation.js +0 -217
  73. package/eslint-integration/eslint-plugin-custom/s026-json-schema-validation.js +0 -68
  74. package/eslint-integration/eslint-plugin-custom/s027-no-hardcoded-secrets.js +0 -80
  75. package/eslint-integration/eslint-plugin-custom/s029-require-csrf-protection.js +0 -79
  76. package/eslint-integration/eslint-plugin-custom/s030-no-directory-browsing.js +0 -78
  77. package/eslint-integration/eslint-plugin-custom/s033-require-samesite-cookie.js +0 -80
  78. package/eslint-integration/eslint-plugin-custom/s034-require-host-cookie-prefix.js +0 -77
  79. package/eslint-integration/eslint-plugin-custom/s035-cookie-specific-path.js +0 -74
  80. package/eslint-integration/eslint-plugin-custom/s036-no-unsafe-file-include.js +0 -68
  81. package/eslint-integration/eslint-plugin-custom/s037-require-anti-cache-headers.js +0 -70
  82. package/eslint-integration/eslint-plugin-custom/s038-no-version-disclosure.js +0 -74
  83. package/eslint-integration/eslint-plugin-custom/s039-no-session-token-in-url.js +0 -63
  84. package/eslint-integration/eslint-plugin-custom/s041-require-session-invalidate-on-logout.js +0 -211
  85. package/eslint-integration/eslint-plugin-custom/s042-require-periodic-reauthentication.js +0 -294
  86. package/eslint-integration/eslint-plugin-custom/s043-terminate-sessions-on-password-change.js +0 -254
  87. package/eslint-integration/eslint-plugin-custom/s044-require-full-session-for-sensitive-operations.js +0 -292
  88. package/eslint-integration/eslint-plugin-custom/s045-anti-automation-controls.js +0 -46
  89. package/eslint-integration/eslint-plugin-custom/s046-secure-notification-on-auth-change.js +0 -44
  90. package/eslint-integration/eslint-plugin-custom/s047-secure-random-passwords.js +0 -108
  91. package/eslint-integration/eslint-plugin-custom/s048-password-credential-recovery.js +0 -54
  92. package/eslint-integration/eslint-plugin-custom/s050-session-token-weak-hash.js +0 -94
  93. package/eslint-integration/eslint-plugin-custom/s052-secure-random-authentication-code.js +0 -66
  94. package/eslint-integration/eslint-plugin-custom/s054-verification-default-account.js +0 -109
  95. package/eslint-integration/eslint-plugin-custom/s055-verification-rest-check-the-incoming-content-type.js +0 -143
  96. package/eslint-integration/eslint-plugin-custom/s057-utc-logging.js +0 -54
  97. package/eslint-integration/eslint-plugin-custom/s058-no-ssrf.js +0 -73
  98. package/eslint-integration/eslint-plugin-custom/t002-interface-prefix-i.js +0 -42
  99. package/eslint-integration/eslint-plugin-custom/t003-ts-ignore-reason.js +0 -48
  100. package/eslint-integration/eslint-plugin-custom/t004-interface-public-only.js +0 -160
  101. package/eslint-integration/eslint-plugin-custom/t007-no-fn-in-constructor.js +0 -52
  102. package/eslint-integration/eslint-plugin-custom/t011-no-real-time-dependency.js +0 -175
  103. package/eslint-integration/eslint-plugin-custom/t019-no-empty-type.js +0 -95
  104. package/eslint-integration/eslint-plugin-custom/t025-no-nested-union-tuple.js +0 -48
  105. package/eslint-integration/eslint-plugin-custom/t026-limit-nested-generics.js +0 -377
  106. package/eslint-integration/eslint.config.js +0 -125
  107. package/eslint-integration/eslint.config.simple.js +0 -24
  108. package/eslint-integration/package.json +0 -23
  109. package/eslint-integration/sample.ts +0 -53
  110. package/eslint-integration/test-s003.js +0 -5
  111. package/eslint-integration/tsconfig.json +0 -27
  112. package/examples/.github/workflows/code-quality.yml +0 -111
  113. package/examples/README.md +0 -69
  114. package/examples/basic-typescript-demo/.eslintrc.json +0 -18
  115. package/examples/basic-typescript-demo/.next/cache/eslint/.cache_1othrmo +0 -1
  116. package/examples/basic-typescript-demo/.sunlint.json +0 -29
  117. package/examples/basic-typescript-demo/eslint.config.mjs +0 -37
  118. package/examples/basic-typescript-demo/next-env.d.ts +0 -5
  119. package/examples/basic-typescript-demo/next.config.mjs +0 -4
  120. package/examples/basic-typescript-demo/package-lock.json +0 -5656
  121. package/examples/basic-typescript-demo/package.json +0 -34
  122. package/examples/basic-typescript-demo/src/app/layout.tsx +0 -18
  123. package/examples/basic-typescript-demo/src/app/page.tsx +0 -48
  124. package/examples/basic-typescript-demo/src/config.ts +0 -14
  125. package/examples/basic-typescript-demo/src/good-practices.ts +0 -58
  126. package/examples/basic-typescript-demo/src/types.generated.ts +0 -13
  127. package/examples/basic-typescript-demo/src/user.test.ts +0 -19
  128. package/examples/basic-typescript-demo/src/violations.ts +0 -61
  129. package/examples/basic-typescript-demo/test-config-priority.sh +0 -0
  130. package/examples/basic-typescript-demo/test-file-targeting.sh +0 -0
  131. package/examples/basic-typescript-demo/tsconfig.json +0 -27
  132. package/examples/enhanced-config.json +0 -0
  133. package/examples/eslint-integration-demo/.eslintrc.js +0 -38
  134. package/examples/eslint-integration-demo/.sunlint.json +0 -42
  135. package/examples/eslint-integration-demo/next-env.d.ts +0 -5
  136. package/examples/eslint-integration-demo/next.config.js +0 -8
  137. package/examples/eslint-integration-demo/package-lock.json +0 -5740
  138. package/examples/eslint-integration-demo/package.json +0 -37
  139. package/examples/eslint-integration-demo/src/api.test.ts +0 -20
  140. package/examples/eslint-integration-demo/src/conflict-test.tsx +0 -44
  141. package/examples/eslint-integration-demo/src/naming-conflicts.ts +0 -50
  142. package/examples/eslint-integration-demo/test-file-targeting.sh +0 -0
  143. package/examples/eslint-integration-demo/tsconfig.json +0 -26
  144. package/examples/file-targeting-demo/global.d.ts +0 -11
  145. package/examples/file-targeting-demo/jest.config.js +0 -8
  146. package/examples/file-targeting-demo/sample.ts +0 -53
  147. package/examples/file-targeting-demo/src/server.js +0 -11
  148. package/examples/file-targeting-demo/src/server.test.js +0 -11
  149. package/examples/file-targeting-demo/src/types.d.ts +0 -4
  150. package/examples/file-targeting-demo/src/types.generated.ts +0 -10
  151. package/examples/file-targeting-demo/user-service.test.ts +0 -15
  152. package/examples/file-targeting-demo/user-service.ts +0 -13
  153. package/examples/file-targeting-demo/utils.js +0 -15
  154. package/examples/multi-language-project/.eslintrc.json +0 -38
  155. package/examples/multi-language-project/package.json +0 -37
  156. package/examples/multi-language-project/src/sample.ts +0 -39
  157. package/examples/rule-test-fixtures/README.md +0 -67
  158. package/examples/rule-test-fixtures/rules/C006_function_naming/clean/typescript-clean.ts +0 -64
  159. package/examples/rule-test-fixtures/rules/C006_function_naming/violations/dart-violations.dart +0 -56
  160. package/examples/rule-test-fixtures/rules/C006_function_naming/violations/typescript-violations.ts +0 -47
  161. package/examples/rule-test-fixtures/rules/C019_log_level_usage/clean/typescript-clean.ts +0 -93
  162. package/examples/rule-test-fixtures/rules/C019_log_level_usage/violations/dart-violations.dart +0 -75
  163. package/examples/rule-test-fixtures/rules/C019_log_level_usage/violations/typescript-violations.ts +0 -84
  164. package/examples/rule-test-fixtures/rules/C029_catch_block_logging/clean/typescript-clean.ts +0 -0
  165. package/examples/rule-test-fixtures/rules/C029_catch_block_logging/violations/typescript-violations.ts +0 -37
package/cli-legacy.js DELETED
@@ -1,355 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * LEGACY CLI - DO NOT USE
5
- * This is the old monolithic CLI implementation kept for reference only.
6
- * Use cli.js instead - it has the new modular architecture with ESLint integration.
7
- */
8
-
9
- const { Command } = require('commander');
10
- const chalk = require('chalk');
11
- const path = require('path');
12
- const fs = require('fs');
13
- const MultiRuleRunner = require('./core/multi-rule-runner');
14
- const ConfigManager = require('./core/config-manager');
15
- const ReportGenerator = require('./core/report-generator');
16
- const { version } = require('./package.json');
17
-
18
- const program = new Command();
19
-
20
- program
21
- .name('sunlint')
22
- .description('☀️ Sun Lint - Coding Standards Checker | Multi-rule Quality & Security Analysis')
23
- .version(version);
24
-
25
- // Rule selection
26
- program
27
- .option('-r, --rule <rule>', 'Run single rule (e.g., C019)')
28
- .option('-R, --rules <rules>', 'Run multiple rules (e.g., C019,C006,C021)')
29
- .option('-a, --all', 'Run all available rules')
30
- .option('-c, --category <category>', 'Run rules by category (quality,security,logging,naming)')
31
- .option('--quality', 'Run all code quality rules')
32
- .option('--security', 'Run all secure coding rules')
33
- .option('--preset <preset>', 'Use predefined rule preset (recommended,strict,beginner)')
34
-
35
- // Input/Output
36
- .option('-i, --input <path>', 'Input file or directory to analyze', 'src')
37
- .option('-f, --format <format>', 'Output format (eslint,json,summary,table)', 'eslint')
38
- .option('-o, --output <file>', 'Output file path')
39
- .option('--config <file>', 'Configuration file path', '.sunlint.json')
40
-
41
- // CI/CD and Git integration
42
- .option('--changed-files', 'Only analyze files changed in current branch (git diff)')
43
- .option('--staged-files', 'Only analyze staged files (git diff --cached)')
44
- .option('--diff-base <ref>', 'Compare against specific git reference (e.g., origin/main)')
45
- .option('--since <commit>', 'Only analyze files changed since specific commit')
46
- .option('--pr-mode', 'Enable PR mode (changed files + baseline comparison)')
47
- .option('--baseline <file>', 'Load baseline results to compare against')
48
- .option('--save-baseline <file>', 'Save current results as baseline')
49
- .option('--fail-on-new-violations', 'Exit with error only on new violations (not existing)')
50
-
51
- // Rule control
52
- .option('--exclude-rules <rules>', 'Exclude specific rules (e.g., C019,C006)')
53
- .option('--include-rules <rules>', 'Include only specific rules (e.g., C019,C006)')
54
- .option('--disable-rule <rule>', 'Disable specific rule')
55
- .option('--enable-rule <rule>', 'Enable specific rule')
56
- .option('--severity <level>', 'Minimum severity level (error,warning,info)', 'info')
57
- .option('--languages <langs>', 'Target languages (typescript,dart,kotlin)')
58
-
59
- // Advanced options
60
- .option('--ai', 'Enable AI-powered analysis')
61
- .option('--no-ai', 'Force disable AI analysis (use heuristic only)')
62
- .option('--no-cache', 'Disable result caching')
63
- .option('--max-concurrent <n>', 'Maximum concurrent rule execution', '5')
64
- .option('--timeout <ms>', 'Timeout for rule execution (ms)', '30000')
65
- .option('--fix', 'Auto-fix issues when possible')
66
- .option('--dry-run', 'Show what would be analyzed without running')
67
- .option('--verbose', 'Enable verbose logging')
68
- .option('--quiet', 'Suppress non-error output')
69
- .option('--debug', 'Enable debug mode');
70
-
71
- program.action(async (options) => {
72
- try {
73
- // Sun Lint banner
74
- console.log(chalk.yellow.bold('☀️ Sun Lint - Coding Standards Checker'));
75
- console.log(chalk.gray(`Version: ${version} | Sun* Engineering`));
76
-
77
- if (options.debug) {
78
- console.log(chalk.yellow('Debug mode enabled'));
79
- console.log('Options:', options);
80
- }
81
-
82
- // Handle quality/security shortcuts
83
- if (options.quality) {
84
- options.category = 'quality';
85
- }
86
- if (options.security) {
87
- options.category = 'security';
88
- }
89
-
90
- // Load configuration
91
- const configManager = new ConfigManager();
92
- const config = await configManager.loadConfig(options.config, options);
93
-
94
- if (options.verbose) {
95
- console.log(chalk.gray('Configuration loaded:'), config);
96
- }
97
-
98
- // Validate input
99
- if (!fs.existsSync(options.input)) {
100
- console.error(chalk.red(`❌ Input path not found: ${options.input}`));
101
- process.exit(1);
102
- }
103
-
104
- // Show dry run info
105
- if (options.dryRun) {
106
- console.log(chalk.yellow('🔍 Dry run mode - Analysis preview:'));
107
- await showDryRunPreview(config, options);
108
- return;
109
- }
110
-
111
- // Initialize multi-rule runner
112
- const runner = new MultiRuleRunner(config, options);
113
-
114
- // Get rules to run
115
- const rulesToRun = await getRulesToRun(config, options);
116
-
117
- if (rulesToRun.length === 0) {
118
- console.log(chalk.yellow('⚠️ No rules to run'));
119
- return;
120
- }
121
-
122
- if (!options.quiet) {
123
- const rulesByCategory = categorizeRules(rulesToRun);
124
- console.log(chalk.green(`🚀 Running ${rulesToRun.length} rules on: ${options.input}`));
125
-
126
- if (rulesByCategory.quality.length > 0) {
127
- console.log(chalk.blue(` 📋 Quality rules: ${rulesByCategory.quality.map(r => r.id).join(', ')}`));
128
- }
129
- if (rulesByCategory.security.length > 0) {
130
- console.log(chalk.red(` 🔒 Security rules: ${rulesByCategory.security.map(r => r.id).join(', ')}`));
131
- }
132
- if (rulesByCategory.other.length > 0) {
133
- console.log(chalk.gray(` ⚙️ Other rules: ${rulesByCategory.other.map(r => r.id).join(', ')}`));
134
- }
135
- }
136
-
137
- // Run analysis
138
- const startTime = Date.now();
139
- const results = await runner.runRules(rulesToRun, options.input, options);
140
- const duration = Date.now() - startTime;
141
-
142
- // Generate report
143
- const reportGenerator = new ReportGenerator(config, options);
144
- const report = await reportGenerator.generateReport(results, {
145
- duration,
146
- rulesRun: rulesToRun.length,
147
- filesAnalyzed: results.filesAnalyzed || 0
148
- });
149
-
150
- // Output results
151
- await outputResults(report, options);
152
-
153
- // Exit with appropriate code
154
- const allResults = results.results || [];
155
- const hasErrors = allResults.some(r =>
156
- r.violations && r.violations.some(v => v.severity === 'error')
157
- );
158
- process.exit(hasErrors ? 1 : 0);
159
-
160
- } catch (error) {
161
- console.error(chalk.red('❌ Sun Lint Error:'), error.message);
162
- if (options.debug) {
163
- console.error(error.stack);
164
- }
165
- process.exit(1);
166
- }
167
- });
168
-
169
- async function getRulesToRun(config, options) {
170
- const allRules = config.rules || {};
171
- const rulesRegistry = require('./config/rules-registry.json');
172
-
173
- let selectedRules = [];
174
-
175
- if (options.rule) {
176
- // Single rule
177
- selectedRules = [options.rule];
178
- } else if (options.rules) {
179
- // Multiple rules
180
- selectedRules = options.rules.split(',').map(r => r.trim());
181
- } else if (options.all) {
182
- // All rules
183
- selectedRules = Object.keys(rulesRegistry.rules);
184
- } else if (options.category) {
185
- // Rules by category
186
- const category = rulesRegistry.categories[options.category];
187
- if (category && category.rules) {
188
- selectedRules = category.rules;
189
- }
190
- } else if (options.preset) {
191
- // Load preset using ConfigManager
192
- try {
193
- const ConfigManager = require('./core/config-manager');
194
- const configManager = new ConfigManager();
195
-
196
- const presetName = options.preset.startsWith('@sun/sunlint/')
197
- ? options.preset
198
- : `@sun/sunlint/${options.preset}`;
199
- const presetConfig = await configManager.loadPreset(presetName);
200
- if (presetConfig && presetConfig.rules) {
201
- selectedRules = Object.keys(presetConfig.rules).filter(ruleId =>
202
- presetConfig.rules[ruleId] !== 'off' && presetConfig.rules[ruleId] !== false
203
- );
204
- console.log(chalk.blue(`🎯 Using preset: ${presetName}`));
205
- }
206
- } catch (error) {
207
- console.error(chalk.red(`❌ Failed to load preset '${options.preset}':`), error.message);
208
- process.exit(1);
209
- }
210
- } else {
211
- // Default: use config rules
212
- selectedRules = Object.keys(allRules).filter(ruleId =>
213
- allRules[ruleId] !== 'off' && allRules[ruleId] !== false
214
- );
215
- }
216
-
217
- // Filter out excluded rules
218
- if (options.excludeRules) {
219
- const excludedRules = options.excludeRules.split(',').map(r => r.trim());
220
- selectedRules = selectedRules.filter(rule => !excludedRules.includes(rule));
221
- }
222
-
223
- // Filter by severity
224
- if (options.severity) {
225
- const minSeverity = options.severity;
226
- const severityLevels = { info: 0, warning: 1, error: 2 };
227
- const minLevel = severityLevels[minSeverity] || 0;
228
-
229
- selectedRules = selectedRules.filter(ruleId => {
230
- const rule = rulesRegistry.rules[ruleId];
231
- if (!rule) return false;
232
- const ruleLevel = severityLevels[rule.severity] || 0;
233
- return ruleLevel >= minLevel;
234
- });
235
- }
236
-
237
- // Filter by languages
238
- if (options.languages) {
239
- const targetLanguages = options.languages.split(',').map(l => l.trim());
240
- selectedRules = selectedRules.filter(ruleId => {
241
- const rule = rulesRegistry.rules[ruleId];
242
- if (!rule) return false;
243
- return rule.languages.some(lang => targetLanguages.includes(lang));
244
- });
245
- }
246
-
247
- // Convert to rule objects
248
- return selectedRules.map(ruleId => ({
249
- id: ruleId,
250
- ...rulesRegistry.rules[ruleId]
251
- })).filter(rule => rule.name); // Filter out invalid rules
252
- }
253
-
254
- function categorizeRules(rules) {
255
- const categories = {
256
- quality: [],
257
- security: [],
258
- other: []
259
- };
260
-
261
- rules.forEach(rule => {
262
- if (rule.category === 'security' || rule.id.startsWith('S')) {
263
- categories.security.push(rule);
264
- } else if (['logging', 'naming', 'validation', 'design'].includes(rule.category)) {
265
- categories.quality.push(rule);
266
- } else {
267
- categories.other.push(rule);
268
- }
269
- });
270
-
271
- return categories;
272
- }
273
-
274
- async function showDryRunPreview(config, options) {
275
- const rulesToRun = await getRulesToRun(config, options);
276
- const rulesByCategory = categorizeRules(rulesToRun);
277
-
278
- console.log(chalk.blue('📋 Sun Lint Analysis Preview:'));
279
- console.log(chalk.gray(`Input: ${options.input}`));
280
- console.log(chalk.gray(`Format: ${options.format}`));
281
- console.log(chalk.gray(`Rules to run: ${rulesToRun.length}`));
282
-
283
- if (rulesByCategory.quality.length > 0) {
284
- console.log(chalk.blue('📋 Quality Rules:'));
285
- rulesByCategory.quality.forEach(rule => {
286
- console.log(` ${chalk.cyan(rule.id)}: ${rule.name} (${rule.severity})`);
287
- });
288
- }
289
-
290
- if (rulesByCategory.security.length > 0) {
291
- console.log(chalk.red('🔒 Security Rules:'));
292
- rulesByCategory.security.forEach(rule => {
293
- console.log(` ${chalk.cyan(rule.id)}: ${rule.name} (${rule.severity})`);
294
- });
295
- }
296
-
297
- if (rulesByCategory.other.length > 0) {
298
- console.log(chalk.white('⚙️ Other Rules:'));
299
- rulesByCategory.other.forEach(rule => {
300
- console.log(` ${chalk.cyan(rule.id)}: ${rule.name} (${rule.severity})`);
301
- });
302
- }
303
- }
304
-
305
- async function outputResults(report, options) {
306
- // Console output
307
- if (!options.quiet) {
308
- console.log(report.formatted);
309
- }
310
-
311
- // File output
312
- if (options.output) {
313
- fs.writeFileSync(options.output, JSON.stringify(report.raw, null, 2));
314
- console.log(chalk.green(`📄 Report saved to: ${options.output}`));
315
- }
316
-
317
- // Summary
318
- if (report.summary && !options.quiet) {
319
- console.log(chalk.blue('\n📊 Sun Lint Summary:'));
320
- console.log(report.summary);
321
- }
322
- }
323
-
324
- // Error handling
325
- process.on('unhandledRejection', (reason, promise) => {
326
- console.error(chalk.red('Sun Lint - Unhandled Rejection:'), promise, chalk.red('reason:'), reason);
327
- process.exit(1);
328
- });
329
-
330
- process.on('uncaughtException', (error) => {
331
- console.error(chalk.red('Sun Lint - Uncaught Exception:'), error);
332
- process.exit(1);
333
- });
334
-
335
- // Help examples
336
- program.addHelpText('after', `
337
- Examples:
338
- $ sunlint --rule=C019 --input=src
339
- $ sunlint --rules=C019,C006 --input=src --format=json
340
- $ sunlint --all --input=src --format=summary
341
- $ sunlint --quality --input=src
342
- $ sunlint --security --input=src
343
- $ sunlint --category=logging --input=src
344
- $ sunlint --preset=recommended --input=src
345
- $ sunlint --config=.sunlint.json --input=src
346
- $ sunlint --rule=C019 --input=src --output=report.json
347
- $ sunlint --all --input=src --exclude-rules=C006,C031
348
- $ sunlint --rule=C019 --input=src --ai
349
- $ sunlint --rule=C019 --input=src --no-ai
350
- $ sunlint --all --input=src --severity=error --ai
351
-
352
- Sun* Engineering - Coding Standards Made Simple ☀️
353
- `);
354
-
355
- program.parse();
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.
@@ -1,78 +0,0 @@
1
- # SunLint Modular Architecture
2
-
3
- ## Phase 1: TypeScript Focus với Kiến trúc Modular
4
-
5
- ### Cấu trúc mới:
6
-
7
- ```
8
- cli.js # CLI entry point (simplified)
9
- core/
10
- ├── cli-program.js # CLI options definition (Rule C005)
11
- ├── cli-action-handler.js # Main execution flow (Rule C005)
12
- ├── rule-selection-service.js # Rule selection logic (Rule C005)
13
- ├── analysis-orchestrator.js # Analysis coordination (Rule C005)
14
- ├── output-service.js # Output formatting (Rule C005)
15
- ├── eslint-engine-service.js # ESLint integration (future)
16
- └── sunlint-engine-service.js # Native SunLint engine
17
- ```
18
-
19
- ### Nguyên tắc thiết kế:
20
-
21
- 1. **Rule C005**: Mỗi class/file chỉ làm một việc
22
- 2. **Rule C014**: Dependency injection thay vì new trực tiếp
23
- 3. **Rule C012**: Tách rõ Command và Query
24
- 4. **Modular**: Dễ mở rộng cho Phase 2
25
-
26
- ### Luồng hoạt động:
27
-
28
- 1. `cli.js` → `CliActionHandler`
29
- 2. `CliActionHandler` → Load config, validate input
30
- 3. `RuleSelectionService` → Select rules based on options
31
- 4. `AnalysisOrchestrator` → Run analysis (SunLint or ESLint)
32
- 5. `OutputService` → Format and display results
33
-
34
- ### Các tính năng hiện tại:
35
-
36
- - ✅ Modular CLI với dependency injection
37
- - ✅ Rule selection (single, multiple, all, category)
38
- - ✅ Dry run mode
39
- - ✅ TypeScript-specific options (chuẩn bị cho Phase 1)
40
- - ✅ Graceful fallback khi không tìm thấy dependencies
41
- - ✅ Clean error handling và logging
42
-
43
- ### Phase 1 roadmap:
44
-
45
- 1. **✅ Done**: Modular CLI architecture
46
- 2. **✅ Done**: ESLint integration cho TypeScript
47
- 3. **Next**: TypeScript custom rules thông qua ESLint
48
- 4. **✅ Done**: Hybrid engine (ESLint + SunLint)
49
-
50
- ### Phase 2 roadmap:
51
-
52
- 1. Native SunLint engine cho tất cả ngôn ngữ
53
- 2. Mở rộng Dart, Kotlin rules
54
- 3. AI-powered analysis
55
- 4. VS Code extension integration
56
-
57
- ### Usage Examples:
58
-
59
- ```bash
60
- # Basic usage
61
- sunlint --rule=C006 --input=src
62
-
63
- # Category-based
64
- sunlint --quality --input=src
65
-
66
- # TypeScript-specific (Phase 1)
67
- sunlint --typescript --input=src
68
- sunlint --typescript-engine=eslint --input=src
69
-
70
- # Dry run
71
- sunlint --dry-run --all --input=src
72
- ```
73
-
74
- ### Dependencies:
75
-
76
- - Minimal core dependencies
77
- - ESLint integration sẽ được thêm trong Phase 1
78
- - Graceful fallback khi dependencies không có sẵn