@codebakers/mcp 5.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.
Files changed (140) hide show
  1. package/INSTALL.md +221 -0
  2. package/LICENSE +21 -0
  3. package/README.md +412 -0
  4. package/dist/cli.d.ts +9 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +236 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/index.d.ts +12 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +526 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/tools/analyze-mockups.d.ts +18 -0
  13. package/dist/tools/analyze-mockups.d.ts.map +1 -0
  14. package/dist/tools/analyze-mockups.js +497 -0
  15. package/dist/tools/analyze-mockups.js.map +1 -0
  16. package/dist/tools/autonomous-build.d.ts +19 -0
  17. package/dist/tools/autonomous-build.d.ts.map +1 -0
  18. package/dist/tools/autonomous-build.js +287 -0
  19. package/dist/tools/autonomous-build.js.map +1 -0
  20. package/dist/tools/check-gate.d.ts +21 -0
  21. package/dist/tools/check-gate.d.ts.map +1 -0
  22. package/dist/tools/check-gate.js +446 -0
  23. package/dist/tools/check-gate.js.map +1 -0
  24. package/dist/tools/check-scope.d.ts +22 -0
  25. package/dist/tools/check-scope.d.ts.map +1 -0
  26. package/dist/tools/check-scope.js +251 -0
  27. package/dist/tools/check-scope.js.map +1 -0
  28. package/dist/tools/deploy-vercel.d.ts +18 -0
  29. package/dist/tools/deploy-vercel.d.ts.map +1 -0
  30. package/dist/tools/deploy-vercel.js +178 -0
  31. package/dist/tools/deploy-vercel.js.map +1 -0
  32. package/dist/tools/diagnose-error.d.ts +20 -0
  33. package/dist/tools/diagnose-error.d.ts.map +1 -0
  34. package/dist/tools/diagnose-error.js +351 -0
  35. package/dist/tools/diagnose-error.js.map +1 -0
  36. package/dist/tools/enforce-feature.d.ts +25 -0
  37. package/dist/tools/enforce-feature.d.ts.map +1 -0
  38. package/dist/tools/enforce-feature.js +387 -0
  39. package/dist/tools/enforce-feature.js.map +1 -0
  40. package/dist/tools/execute-atomic-unit.d.ts +23 -0
  41. package/dist/tools/execute-atomic-unit.d.ts.map +1 -0
  42. package/dist/tools/execute-atomic-unit.js +107 -0
  43. package/dist/tools/execute-atomic-unit.js.map +1 -0
  44. package/dist/tools/fix-commit.d.ts +23 -0
  45. package/dist/tools/fix-commit.d.ts.map +1 -0
  46. package/dist/tools/fix-commit.js +213 -0
  47. package/dist/tools/fix-commit.js.map +1 -0
  48. package/dist/tools/fix-mockups.d.ts +21 -0
  49. package/dist/tools/fix-mockups.d.ts.map +1 -0
  50. package/dist/tools/fix-mockups.js +595 -0
  51. package/dist/tools/fix-mockups.js.map +1 -0
  52. package/dist/tools/generate-api-route.d.ts +18 -0
  53. package/dist/tools/generate-api-route.d.ts.map +1 -0
  54. package/dist/tools/generate-api-route.js +212 -0
  55. package/dist/tools/generate-api-route.js.map +1 -0
  56. package/dist/tools/generate-chatbot.d.ts +20 -0
  57. package/dist/tools/generate-chatbot.d.ts.map +1 -0
  58. package/dist/tools/generate-chatbot.js +555 -0
  59. package/dist/tools/generate-chatbot.js.map +1 -0
  60. package/dist/tools/generate-component.d.ts +18 -0
  61. package/dist/tools/generate-component.d.ts.map +1 -0
  62. package/dist/tools/generate-component.js +159 -0
  63. package/dist/tools/generate-component.js.map +1 -0
  64. package/dist/tools/generate-docs.d.ts +21 -0
  65. package/dist/tools/generate-docs.d.ts.map +1 -0
  66. package/dist/tools/generate-docs.js +782 -0
  67. package/dist/tools/generate-docs.js.map +1 -0
  68. package/dist/tools/generate-e2e-tests.d.ts +12 -0
  69. package/dist/tools/generate-e2e-tests.d.ts.map +1 -0
  70. package/dist/tools/generate-e2e-tests.js +37 -0
  71. package/dist/tools/generate-e2e-tests.js.map +1 -0
  72. package/dist/tools/generate-migration.d.ts +21 -0
  73. package/dist/tools/generate-migration.d.ts.map +1 -0
  74. package/dist/tools/generate-migration.js +94 -0
  75. package/dist/tools/generate-migration.js.map +1 -0
  76. package/dist/tools/generate-schema.d.ts +18 -0
  77. package/dist/tools/generate-schema.d.ts.map +1 -0
  78. package/dist/tools/generate-schema.js +422 -0
  79. package/dist/tools/generate-schema.js.map +1 -0
  80. package/dist/tools/generate-spec.d.ts +18 -0
  81. package/dist/tools/generate-spec.d.ts.map +1 -0
  82. package/dist/tools/generate-spec.js +446 -0
  83. package/dist/tools/generate-spec.js.map +1 -0
  84. package/dist/tools/generate-store-contracts.d.ts +17 -0
  85. package/dist/tools/generate-store-contracts.d.ts.map +1 -0
  86. package/dist/tools/generate-store-contracts.js +356 -0
  87. package/dist/tools/generate-store-contracts.js.map +1 -0
  88. package/dist/tools/generate-store.d.ts +16 -0
  89. package/dist/tools/generate-store.d.ts.map +1 -0
  90. package/dist/tools/generate-store.js +166 -0
  91. package/dist/tools/generate-store.js.map +1 -0
  92. package/dist/tools/generate-unit-tests.d.ts +14 -0
  93. package/dist/tools/generate-unit-tests.d.ts.map +1 -0
  94. package/dist/tools/generate-unit-tests.js +85 -0
  95. package/dist/tools/generate-unit-tests.js.map +1 -0
  96. package/dist/tools/get-context.d.ts +35 -0
  97. package/dist/tools/get-context.d.ts.map +1 -0
  98. package/dist/tools/get-context.js +367 -0
  99. package/dist/tools/get-context.js.map +1 -0
  100. package/dist/tools/init-session.d.ts +22 -0
  101. package/dist/tools/init-session.d.ts.map +1 -0
  102. package/dist/tools/init-session.js +232 -0
  103. package/dist/tools/init-session.js.map +1 -0
  104. package/dist/tools/map-dependencies.d.ts +25 -0
  105. package/dist/tools/map-dependencies.d.ts.map +1 -0
  106. package/dist/tools/map-dependencies.js +480 -0
  107. package/dist/tools/map-dependencies.js.map +1 -0
  108. package/dist/tools/optimize-performance.d.ts +18 -0
  109. package/dist/tools/optimize-performance.d.ts.map +1 -0
  110. package/dist/tools/optimize-performance.js +285 -0
  111. package/dist/tools/optimize-performance.js.map +1 -0
  112. package/dist/tools/run-interview.d.ts +23 -0
  113. package/dist/tools/run-interview.d.ts.map +1 -0
  114. package/dist/tools/run-interview.js +371 -0
  115. package/dist/tools/run-interview.js.map +1 -0
  116. package/dist/tools/run-tests.d.ts +12 -0
  117. package/dist/tools/run-tests.d.ts.map +1 -0
  118. package/dist/tools/run-tests.js +30 -0
  119. package/dist/tools/run-tests.js.map +1 -0
  120. package/dist/tools/scan-security.d.ts +19 -0
  121. package/dist/tools/scan-security.d.ts.map +1 -0
  122. package/dist/tools/scan-security.js +358 -0
  123. package/dist/tools/scan-security.js.map +1 -0
  124. package/dist/tools/validate-accessibility.d.ts +18 -0
  125. package/dist/tools/validate-accessibility.d.ts.map +1 -0
  126. package/dist/tools/validate-accessibility.js +251 -0
  127. package/dist/tools/validate-accessibility.js.map +1 -0
  128. package/dist/tools/validate-mockups.d.ts +21 -0
  129. package/dist/tools/validate-mockups.d.ts.map +1 -0
  130. package/dist/tools/validate-mockups.js +433 -0
  131. package/dist/tools/validate-mockups.js.map +1 -0
  132. package/dist/tools/verify-completeness.d.ts +13 -0
  133. package/dist/tools/verify-completeness.d.ts.map +1 -0
  134. package/dist/tools/verify-completeness.js +68 -0
  135. package/dist/tools/verify-completeness.js.map +1 -0
  136. package/dist/tools/verify-mockups.d.ts +14 -0
  137. package/dist/tools/verify-mockups.d.ts.map +1 -0
  138. package/dist/tools/verify-mockups.js +85 -0
  139. package/dist/tools/verify-mockups.js.map +1 -0
  140. package/package.json +50 -0
@@ -0,0 +1,358 @@
1
+ /**
2
+ * codebakers_scan_security
3
+ *
4
+ * Security Vulnerability Scanner
5
+ *
6
+ * Scans for:
7
+ * - Dependency vulnerabilities (npm audit)
8
+ * - XSS vulnerabilities
9
+ * - SQL injection risks
10
+ * - Exposed secrets
11
+ * - Insecure authentication patterns
12
+ * - Missing security headers
13
+ */
14
+ import * as fs from 'fs/promises';
15
+ import * as path from 'path';
16
+ import { execSync } from 'child_process';
17
+ export async function scanSecurity(args = {}) {
18
+ const cwd = process.cwd();
19
+ const { block_on_critical = true } = args;
20
+ console.error('🍞 CodeBakers: Scanning Security');
21
+ try {
22
+ const issues = [];
23
+ // Scan 1: Dependency vulnerabilities
24
+ const depIssues = await scanDependencies(cwd);
25
+ issues.push(...depIssues);
26
+ // Scan 2: Code vulnerabilities
27
+ const codeIssues = await scanCodeSecurity(cwd);
28
+ issues.push(...codeIssues);
29
+ // Scan 3: Environment variables
30
+ const envIssues = await scanEnvSecurity(cwd);
31
+ issues.push(...envIssues);
32
+ // Scan 4: API routes security
33
+ const apiIssues = await scanApiSecurity(cwd);
34
+ issues.push(...apiIssues);
35
+ // Calculate risk score
36
+ const criticalCount = issues.filter(i => i.severity === 'critical').length;
37
+ const highCount = issues.filter(i => i.severity === 'high').length;
38
+ // Generate report
39
+ const report = generateSecurityReport(issues, block_on_critical);
40
+ // Save detailed report
41
+ const reportPath = path.join(cwd, '.codebakers', 'SECURITY-REPORT.md');
42
+ await fs.mkdir(path.dirname(reportPath), { recursive: true });
43
+ await fs.writeFile(reportPath, generateDetailedSecurityReport(issues), 'utf-8');
44
+ return report;
45
+ }
46
+ catch (error) {
47
+ return `🍞 CodeBakers: Security Scan Failed\n\nError: ${error instanceof Error ? error.message : String(error)}`;
48
+ }
49
+ }
50
+ async function scanDependencies(cwd) {
51
+ const issues = [];
52
+ try {
53
+ // Run npm audit
54
+ const output = execSync('npm audit --json', {
55
+ cwd,
56
+ encoding: 'utf-8',
57
+ stdio: ['pipe', 'pipe', 'ignore']
58
+ });
59
+ const audit = JSON.parse(output);
60
+ if (audit.vulnerabilities) {
61
+ for (const [pkg, vulnData] of Object.entries(audit.vulnerabilities)) {
62
+ const data = vulnData;
63
+ const severity = data.severity;
64
+ issues.push({
65
+ severity,
66
+ category: 'Dependencies',
67
+ title: `Vulnerable dependency: ${pkg}`,
68
+ description: data.via?.[0]?.title || `${pkg} has known vulnerabilities`,
69
+ fix: `Run: npm audit fix${severity === 'critical' || severity === 'high' ? ' --force' : ''}`
70
+ });
71
+ }
72
+ }
73
+ }
74
+ catch (error) {
75
+ // npm audit failed or no vulnerabilities
76
+ }
77
+ return issues;
78
+ }
79
+ async function scanCodeSecurity(cwd) {
80
+ const issues = [];
81
+ const srcDir = path.join(cwd, 'src');
82
+ try {
83
+ await scanDirectorySecurity(srcDir, issues);
84
+ }
85
+ catch {
86
+ // src/ doesn't exist
87
+ }
88
+ return issues;
89
+ }
90
+ async function scanDirectorySecurity(dir, issues) {
91
+ try {
92
+ const entries = await fs.readdir(dir, { withFileTypes: true });
93
+ for (const entry of entries) {
94
+ const fullPath = path.join(dir, entry.name);
95
+ if (entry.isDirectory()) {
96
+ await scanDirectorySecurity(fullPath, issues);
97
+ }
98
+ else if (entry.name.match(/\.(ts|tsx|js|jsx)$/)) {
99
+ await scanFileSecurity(fullPath, issues);
100
+ }
101
+ }
102
+ }
103
+ catch {
104
+ // Directory doesn't exist
105
+ }
106
+ }
107
+ async function scanFileSecurity(file, issues) {
108
+ const content = await fs.readFile(file, 'utf-8');
109
+ const lines = content.split('\n');
110
+ for (let i = 0; i < lines.length; i++) {
111
+ const line = lines[i];
112
+ const lineNumber = i + 1;
113
+ // Check 1: Dangerous innerHTML usage
114
+ if (line.includes('dangerouslySetInnerHTML') && !line.includes('DOMPurify')) {
115
+ issues.push({
116
+ severity: 'high',
117
+ category: 'XSS',
118
+ title: 'Potential XSS vulnerability',
119
+ description: 'dangerouslySetInnerHTML without sanitization',
120
+ file,
121
+ line: lineNumber,
122
+ fix: 'Use DOMPurify to sanitize HTML before rendering'
123
+ });
124
+ }
125
+ // Check 2: eval() usage
126
+ if (line.includes('eval(')) {
127
+ issues.push({
128
+ severity: 'critical',
129
+ category: 'Code Injection',
130
+ title: 'eval() usage detected',
131
+ description: 'eval() can execute arbitrary code',
132
+ file,
133
+ line: lineNumber,
134
+ fix: 'Avoid eval() - use safe alternatives'
135
+ });
136
+ }
137
+ // Check 3: Weak password regex
138
+ if (line.match(/password.*length.*[<>]\s*[1-5]/) || line.match(/password.*minLength.*[1-5]/)) {
139
+ issues.push({
140
+ severity: 'medium',
141
+ category: 'Authentication',
142
+ title: 'Weak password requirements',
143
+ description: 'Password minimum length is too short',
144
+ file,
145
+ line: lineNumber,
146
+ fix: 'Require passwords to be at least 8 characters'
147
+ });
148
+ }
149
+ // Check 4: Hardcoded secrets
150
+ const secretPatterns = [
151
+ /api[_-]?key\s*=\s*['"][a-zA-Z0-9]{20,}['"]/i,
152
+ /secret\s*=\s*['"][a-zA-Z0-9]{20,}['"]/i,
153
+ /password\s*=\s*['"][^'"]{5,}['"]/i,
154
+ /token\s*=\s*['"][a-zA-Z0-9]{20,}['"]/i
155
+ ];
156
+ for (const pattern of secretPatterns) {
157
+ if (pattern.test(line) && !line.includes('process.env')) {
158
+ issues.push({
159
+ severity: 'critical',
160
+ category: 'Secrets',
161
+ title: 'Hardcoded secret detected',
162
+ description: 'Secret value found in code',
163
+ file,
164
+ line: lineNumber,
165
+ fix: 'Move secrets to environment variables'
166
+ });
167
+ }
168
+ }
169
+ // Check 5: SQL injection risk (if using raw SQL)
170
+ if (line.includes('queryRawUnsafe') || line.includes('executeRawUnsafe')) {
171
+ issues.push({
172
+ severity: 'critical',
173
+ category: 'SQL Injection',
174
+ title: 'SQL injection risk',
175
+ description: 'Using raw SQL queries without parameterization',
176
+ file,
177
+ line: lineNumber,
178
+ fix: 'Use parameterized queries or query builder'
179
+ });
180
+ }
181
+ // Check 6: Missing authentication check
182
+ if ((line.includes('async function POST') || line.includes('async function DELETE')) && !content.includes('auth') && !content.includes('session')) {
183
+ issues.push({
184
+ severity: 'high',
185
+ category: 'Authentication',
186
+ title: 'Missing authentication check',
187
+ description: 'API route might be missing auth verification',
188
+ file,
189
+ line: lineNumber,
190
+ fix: 'Add authentication check before processing request'
191
+ });
192
+ }
193
+ }
194
+ }
195
+ async function scanEnvSecurity(cwd) {
196
+ const issues = [];
197
+ // Check if .env is in .gitignore
198
+ const gitignorePath = path.join(cwd, '.gitignore');
199
+ try {
200
+ const gitignore = await fs.readFile(gitignorePath, 'utf-8');
201
+ if (!gitignore.includes('.env')) {
202
+ issues.push({
203
+ severity: 'high',
204
+ category: 'Secrets',
205
+ title: '.env not in .gitignore',
206
+ description: 'Environment variables might be committed to git',
207
+ file: '.gitignore',
208
+ fix: 'Add .env to .gitignore'
209
+ });
210
+ }
211
+ }
212
+ catch {
213
+ // .gitignore doesn't exist
214
+ }
215
+ // Check for .env.example
216
+ const envExamplePath = path.join(cwd, '.env.example');
217
+ try {
218
+ await fs.access(envExamplePath);
219
+ }
220
+ catch {
221
+ issues.push({
222
+ severity: 'low',
223
+ category: 'Configuration',
224
+ title: 'Missing .env.example',
225
+ description: 'No example environment file for developers',
226
+ fix: 'Create .env.example with placeholder values'
227
+ });
228
+ }
229
+ return issues;
230
+ }
231
+ async function scanApiSecurity(cwd) {
232
+ const issues = [];
233
+ const apiDir = path.join(cwd, 'src', 'app', 'api');
234
+ try {
235
+ await scanApiRoutes(apiDir, issues);
236
+ }
237
+ catch {
238
+ // API directory doesn't exist
239
+ }
240
+ return issues;
241
+ }
242
+ async function scanApiRoutes(dir, issues) {
243
+ try {
244
+ const entries = await fs.readdir(dir, { withFileTypes: true });
245
+ for (const entry of entries) {
246
+ const fullPath = path.join(dir, entry.name);
247
+ if (entry.isDirectory()) {
248
+ await scanApiRoutes(fullPath, issues);
249
+ }
250
+ else if (entry.name === 'route.ts' || entry.name === 'route.js') {
251
+ const content = await fs.readFile(fullPath, 'utf-8');
252
+ // Check for CORS misconfiguration
253
+ if (content.includes("'Access-Control-Allow-Origin', '*'")) {
254
+ issues.push({
255
+ severity: 'medium',
256
+ category: 'CORS',
257
+ title: 'Permissive CORS policy',
258
+ description: 'Allow-Origin set to * (allows all domains)',
259
+ file: fullPath,
260
+ fix: 'Restrict CORS to specific domains'
261
+ });
262
+ }
263
+ // Check for rate limiting
264
+ if (!content.includes('ratelimit') && !content.includes('rate-limit')) {
265
+ issues.push({
266
+ severity: 'medium',
267
+ category: 'Rate Limiting',
268
+ title: 'Missing rate limiting',
269
+ description: 'API route might be vulnerable to abuse',
270
+ file: fullPath,
271
+ fix: 'Add rate limiting middleware'
272
+ });
273
+ }
274
+ }
275
+ }
276
+ }
277
+ catch {
278
+ // Directory doesn't exist
279
+ }
280
+ }
281
+ function generateSecurityReport(issues, blockOnCritical) {
282
+ const critical = issues.filter(i => i.severity === 'critical').length;
283
+ const high = issues.filter(i => i.severity === 'high').length;
284
+ const medium = issues.filter(i => i.severity === 'medium').length;
285
+ const low = issues.filter(i => i.severity === 'low').length;
286
+ const blocked = blockOnCritical && critical > 0;
287
+ let report = `🍞 CodeBakers: Security Scan\n\n`;
288
+ report += `**Status:** ${blocked ? '❌ BLOCKED' : critical === 0 && high === 0 ? '✅ PASS' : '⚠️ WARNINGS'}\n\n`;
289
+ report += `## Vulnerabilities\n\n`;
290
+ report += `- Critical: ${critical} ${critical === 0 ? '✅' : '❌'}\n`;
291
+ report += `- High: ${high} ${high === 0 ? '✅' : '⚠️'}\n`;
292
+ report += `- Medium: ${medium}\n`;
293
+ report += `- Low: ${low}\n\n`;
294
+ if (critical > 0) {
295
+ report += `## 🚨 Critical Issues (Must Fix)\n\n`;
296
+ for (const issue of issues.filter(i => i.severity === 'critical').slice(0, 5)) {
297
+ report += `**${issue.title}**\n`;
298
+ report += `- Category: ${issue.category}\n`;
299
+ report += `- ${issue.description}\n`;
300
+ if (issue.file) {
301
+ report += `- File: ${path.basename(issue.file)}${issue.line ? `:${issue.line}` : ''}\n`;
302
+ }
303
+ report += `- Fix: ${issue.fix}\n\n`;
304
+ }
305
+ if (critical > 5) {
306
+ report += `... and ${critical - 5} more critical issues\n\n`;
307
+ }
308
+ }
309
+ if (high > 0 && critical === 0) {
310
+ report += `## ⚠️ High Severity Issues\n\n`;
311
+ for (const issue of issues.filter(i => i.severity === 'high').slice(0, 3)) {
312
+ report += `- ${issue.title}: ${issue.description}\n`;
313
+ }
314
+ report += `\n`;
315
+ }
316
+ if (blocked) {
317
+ report += `## ❌ Deployment Blocked\n\n`;
318
+ report += `Critical security issues must be fixed before deployment.\n\n`;
319
+ report += `**Next steps:**\n`;
320
+ report += `1. Fix critical issues above\n`;
321
+ report += `2. Re-run: codebakers_scan_security\n`;
322
+ report += `3. Proceed to deployment\n\n`;
323
+ }
324
+ else if (critical === 0 && high === 0) {
325
+ report += `## ✅ Security Check Passed\n\n`;
326
+ report += `No critical or high severity issues found.\n\n`;
327
+ }
328
+ report += `**Full report:** .codebakers/SECURITY-REPORT.md\n`;
329
+ return report;
330
+ }
331
+ function generateDetailedSecurityReport(issues) {
332
+ let report = `# Security Scan Report\n\n`;
333
+ report += `**Generated:** ${new Date().toISOString()}\n\n`;
334
+ report += `## Summary\n\n`;
335
+ report += `| Severity | Count |\n`;
336
+ report += `|----------|-------|\n`;
337
+ report += `| Critical | ${issues.filter(i => i.severity === 'critical').length} |\n`;
338
+ report += `| High | ${issues.filter(i => i.severity === 'high').length} |\n`;
339
+ report += `| Medium | ${issues.filter(i => i.severity === 'medium').length} |\n`;
340
+ report += `| Low | ${issues.filter(i => i.severity === 'low').length} |\n\n`;
341
+ for (const severity of ['critical', 'high', 'medium', 'low']) {
342
+ const filtered = issues.filter(i => i.severity === severity);
343
+ if (filtered.length === 0)
344
+ continue;
345
+ report += `## ${severity.charAt(0).toUpperCase() + severity.slice(1)} Issues\n\n`;
346
+ for (const issue of filtered) {
347
+ report += `### ${issue.title}\n\n`;
348
+ report += `- **Category:** ${issue.category}\n`;
349
+ report += `- **Description:** ${issue.description}\n`;
350
+ if (issue.file) {
351
+ report += `- **File:** ${issue.file}${issue.line ? `:${issue.line}` : ''}\n`;
352
+ }
353
+ report += `- **Fix:** ${issue.fix}\n\n`;
354
+ }
355
+ }
356
+ return report;
357
+ }
358
+ //# sourceMappingURL=scan-security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-security.js","sourceRoot":"","sources":["../../src/tools/scan-security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * codebakers_validate_accessibility
3
+ *
4
+ * Accessibility Validation - WCAG Compliance
5
+ *
6
+ * Scans components for accessibility violations:
7
+ * - Missing ARIA labels
8
+ * - Low contrast ratios
9
+ * - Missing alt text
10
+ * - Keyboard navigation issues
11
+ * - Screen reader compatibility
12
+ */
13
+ interface A11yArgs {
14
+ threshold?: number;
15
+ }
16
+ export declare function validateAccessibility(args?: A11yArgs): Promise<string>;
17
+ export {};
18
+ //# sourceMappingURL=validate-accessibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-accessibility.d.ts","sourceRoot":"","sources":["../../src/tools/validate-accessibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,UAAU,QAAQ;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAWD,wBAAsB,qBAAqB,CAAC,IAAI,GAAE,QAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAmChF"}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * codebakers_validate_accessibility
3
+ *
4
+ * Accessibility Validation - WCAG Compliance
5
+ *
6
+ * Scans components for accessibility violations:
7
+ * - Missing ARIA labels
8
+ * - Low contrast ratios
9
+ * - Missing alt text
10
+ * - Keyboard navigation issues
11
+ * - Screen reader compatibility
12
+ */
13
+ import * as fs from 'fs/promises';
14
+ import * as path from 'path';
15
+ export async function validateAccessibility(args = {}) {
16
+ const cwd = process.cwd();
17
+ const { threshold = 90 } = args;
18
+ console.error('🍞 CodeBakers: Validating Accessibility');
19
+ try {
20
+ const issues = [];
21
+ // Scan all component files
22
+ const components = await findComponents(cwd);
23
+ for (const file of components) {
24
+ const content = await fs.readFile(file, 'utf-8');
25
+ const fileIssues = await scanFile(file, content);
26
+ issues.push(...fileIssues);
27
+ }
28
+ // Calculate score
29
+ const criticalCount = issues.filter(i => i.severity === 'critical').length;
30
+ const warningCount = issues.filter(i => i.severity === 'warning').length;
31
+ const score = calculateA11yScore(components.length, criticalCount, warningCount);
32
+ // Generate report
33
+ const report = generateA11yReport(score, threshold, issues);
34
+ // Save detailed report
35
+ const reportPath = path.join(cwd, '.codebakers', 'ACCESSIBILITY-REPORT.md');
36
+ await fs.mkdir(path.dirname(reportPath), { recursive: true });
37
+ await fs.writeFile(reportPath, generateDetailedReport(score, issues), 'utf-8');
38
+ return report;
39
+ }
40
+ catch (error) {
41
+ return `🍞 CodeBakers: Accessibility Validation Failed\n\nError: ${error instanceof Error ? error.message : String(error)}`;
42
+ }
43
+ }
44
+ async function findComponents(cwd) {
45
+ const components = [];
46
+ const srcDir = path.join(cwd, 'src');
47
+ try {
48
+ await scanDirectory(srcDir, components);
49
+ }
50
+ catch {
51
+ // src/ might not exist yet
52
+ }
53
+ return components;
54
+ }
55
+ async function scanDirectory(dir, results) {
56
+ try {
57
+ const entries = await fs.readdir(dir, { withFileTypes: true });
58
+ for (const entry of entries) {
59
+ const fullPath = path.join(dir, entry.name);
60
+ if (entry.isDirectory()) {
61
+ await scanDirectory(fullPath, results);
62
+ }
63
+ else if (entry.name.match(/\.(tsx|jsx)$/)) {
64
+ results.push(fullPath);
65
+ }
66
+ }
67
+ }
68
+ catch {
69
+ // Directory doesn't exist or permission denied
70
+ }
71
+ }
72
+ async function scanFile(file, content) {
73
+ const issues = [];
74
+ const lines = content.split('\n');
75
+ for (let i = 0; i < lines.length; i++) {
76
+ const line = lines[i];
77
+ const lineNumber = i + 1;
78
+ // Check 1: Images without alt text
79
+ if (line.includes('<img') && !line.includes('alt=')) {
80
+ issues.push({
81
+ file,
82
+ line: lineNumber,
83
+ severity: 'critical',
84
+ rule: 'WCAG 1.1.1',
85
+ message: 'Image missing alt attribute',
86
+ fix: 'Add alt="descriptive text" to <img> tag'
87
+ });
88
+ }
89
+ // Check 2: Buttons without accessible labels
90
+ if (line.match(/<button[^>]*>[\s]*<[^>]*\/>/)) {
91
+ if (!line.includes('aria-label') && !line.includes('title')) {
92
+ issues.push({
93
+ file,
94
+ line: lineNumber,
95
+ severity: 'critical',
96
+ rule: 'WCAG 4.1.2',
97
+ message: 'Button with icon only - missing accessible label',
98
+ fix: 'Add aria-label="action description" to button'
99
+ });
100
+ }
101
+ }
102
+ // Check 3: Input fields without labels
103
+ if (line.includes('<input') && !line.includes('aria-label') && !line.includes('placeholder')) {
104
+ const hasLabel = lines.slice(Math.max(0, i - 3), i).some(l => l.includes('<label'));
105
+ if (!hasLabel) {
106
+ issues.push({
107
+ file,
108
+ line: lineNumber,
109
+ severity: 'critical',
110
+ rule: 'WCAG 3.3.2',
111
+ message: 'Input field missing label',
112
+ fix: 'Add <label> or aria-label attribute'
113
+ });
114
+ }
115
+ }
116
+ // Check 4: Low contrast color combinations
117
+ const lowContrastPatterns = [
118
+ /text-gray-400.*bg-gray-300/,
119
+ /text-gray-300.*bg-white/,
120
+ /text-yellow-200.*bg-yellow-100/
121
+ ];
122
+ for (const pattern of lowContrastPatterns) {
123
+ if (pattern.test(line)) {
124
+ issues.push({
125
+ file,
126
+ line: lineNumber,
127
+ severity: 'warning',
128
+ rule: 'WCAG 1.4.3',
129
+ message: 'Potentially low contrast color combination',
130
+ fix: 'Ensure contrast ratio is at least 4.5:1 for normal text'
131
+ });
132
+ }
133
+ }
134
+ // Check 5: Missing heading hierarchy
135
+ if (line.match(/<h[1-6]/)) {
136
+ const headingLevel = parseInt(line.match(/<h([1-6])/)?.[1] || '1');
137
+ const previousHeadings = lines.slice(0, i).filter(l => l.match(/<h[1-6]/));
138
+ if (previousHeadings.length > 0) {
139
+ const lastHeading = previousHeadings[previousHeadings.length - 1];
140
+ const lastLevel = parseInt(lastHeading.match(/<h([1-6])/)?.[1] || '1');
141
+ if (headingLevel > lastLevel + 1) {
142
+ issues.push({
143
+ file,
144
+ line: lineNumber,
145
+ severity: 'warning',
146
+ rule: 'WCAG 1.3.1',
147
+ message: `Heading hierarchy skipped (h${lastLevel} to h${headingLevel})`,
148
+ fix: `Use sequential heading levels (h${lastLevel} to h${lastLevel + 1})`
149
+ });
150
+ }
151
+ }
152
+ }
153
+ // Check 6: Click handlers on non-interactive elements
154
+ if (line.match(/onClick.*<div|onClick.*<span/) && !line.includes('role=') && !line.includes('tabIndex')) {
155
+ issues.push({
156
+ file,
157
+ line: lineNumber,
158
+ severity: 'warning',
159
+ rule: 'WCAG 2.1.1',
160
+ message: 'Click handler on non-interactive element',
161
+ fix: 'Add role="button" and tabIndex={0} or use <button> instead'
162
+ });
163
+ }
164
+ // Check 7: Form submission without accessible feedback
165
+ if (line.includes('onSubmit') || line.includes('type="submit"')) {
166
+ const hasAriaLive = content.includes('aria-live') || content.includes('role="status"');
167
+ if (!hasAriaLive) {
168
+ issues.push({
169
+ file,
170
+ line: lineNumber,
171
+ severity: 'info',
172
+ rule: 'WCAG 4.1.3',
173
+ message: 'Form submission - consider adding status feedback',
174
+ fix: 'Add aria-live="polite" region for submission status'
175
+ });
176
+ }
177
+ }
178
+ }
179
+ return issues;
180
+ }
181
+ function calculateA11yScore(totalComponents, critical, warnings) {
182
+ if (totalComponents === 0)
183
+ return 100;
184
+ const criticalPenalty = critical * 10;
185
+ const warningPenalty = warnings * 2;
186
+ const totalPenalty = criticalPenalty + warningPenalty;
187
+ const score = Math.max(0, 100 - totalPenalty);
188
+ return Math.round(score);
189
+ }
190
+ function generateA11yReport(score, threshold, issues) {
191
+ const critical = issues.filter(i => i.severity === 'critical').length;
192
+ const warnings = issues.filter(i => i.severity === 'warning').length;
193
+ const passed = score >= threshold;
194
+ let report = `🍞 CodeBakers: Accessibility Validation\n\n`;
195
+ report += `**Score:** ${score}/100 ${passed ? '✅' : '❌'}\n`;
196
+ report += `**Threshold:** ${threshold}/100\n`;
197
+ report += `**Status:** ${passed ? 'PASS' : 'FAIL'}\n\n`;
198
+ report += `## Issues Found\n\n`;
199
+ report += `- Critical: ${critical} ${critical === 0 ? '✅' : '❌'}\n`;
200
+ report += `- Warnings: ${warnings}\n`;
201
+ report += `- Info: ${issues.filter(i => i.severity === 'info').length}\n\n`;
202
+ if (critical > 0) {
203
+ report += `## Critical Issues (Must Fix)\n\n`;
204
+ for (const issue of issues.filter(i => i.severity === 'critical').slice(0, 5)) {
205
+ report += `**${path.basename(issue.file)}:${issue.line}**\n`;
206
+ report += `- Rule: ${issue.rule}\n`;
207
+ report += `- Issue: ${issue.message}\n`;
208
+ report += `- Fix: ${issue.fix}\n\n`;
209
+ }
210
+ if (critical > 5) {
211
+ report += `... and ${critical - 5} more critical issues\n\n`;
212
+ }
213
+ }
214
+ if (!passed) {
215
+ report += `## Next Steps\n\n`;
216
+ report += `1. Fix critical issues above\n`;
217
+ report += `2. Run: codebakers_fix_accessibility (auto-fix)\n`;
218
+ report += `3. Re-validate: codebakers_validate_accessibility\n\n`;
219
+ }
220
+ else {
221
+ report += `## ✅ Accessibility Compliant\n\n`;
222
+ report += `Your app meets WCAG ${threshold >= 95 ? 'AAA' : 'AA'} standards.\n\n`;
223
+ }
224
+ report += `**Full report:** .codebakers/ACCESSIBILITY-REPORT.md\n`;
225
+ return report;
226
+ }
227
+ function generateDetailedReport(score, issues) {
228
+ let report = `# Accessibility Report\n\n`;
229
+ report += `**Generated:** ${new Date().toISOString()}\n`;
230
+ report += `**Score:** ${score}/100\n\n`;
231
+ report += `## Summary\n\n`;
232
+ report += `| Severity | Count |\n`;
233
+ report += `|----------|-------|\n`;
234
+ report += `| Critical | ${issues.filter(i => i.severity === 'critical').length} |\n`;
235
+ report += `| Warning | ${issues.filter(i => i.severity === 'warning').length} |\n`;
236
+ report += `| Info | ${issues.filter(i => i.severity === 'info').length} |\n\n`;
237
+ for (const severity of ['critical', 'warning', 'info']) {
238
+ const filtered = issues.filter(i => i.severity === severity);
239
+ if (filtered.length === 0)
240
+ continue;
241
+ report += `## ${severity.charAt(0).toUpperCase() + severity.slice(1)} Issues\n\n`;
242
+ for (const issue of filtered) {
243
+ report += `### ${path.basename(issue.file)}:${issue.line}\n\n`;
244
+ report += `- **Rule:** ${issue.rule}\n`;
245
+ report += `- **Issue:** ${issue.message}\n`;
246
+ report += `- **Fix:** ${issue.fix}\n\n`;
247
+ }
248
+ }
249
+ return report;
250
+ }
251
+ //# sourceMappingURL=validate-accessibility.js.map