@kevinrabun/judges 1.0.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 (167) hide show
  1. package/README.md +174 -0
  2. package/dist/evaluators/accessibility.d.ts +3 -0
  3. package/dist/evaluators/accessibility.d.ts.map +1 -0
  4. package/dist/evaluators/accessibility.js +306 -0
  5. package/dist/evaluators/accessibility.js.map +1 -0
  6. package/dist/evaluators/api-design.d.ts +3 -0
  7. package/dist/evaluators/api-design.d.ts.map +1 -0
  8. package/dist/evaluators/api-design.js +224 -0
  9. package/dist/evaluators/api-design.js.map +1 -0
  10. package/dist/evaluators/cloud-readiness.d.ts +3 -0
  11. package/dist/evaluators/cloud-readiness.d.ts.map +1 -0
  12. package/dist/evaluators/cloud-readiness.js +181 -0
  13. package/dist/evaluators/cloud-readiness.js.map +1 -0
  14. package/dist/evaluators/compliance.d.ts +3 -0
  15. package/dist/evaluators/compliance.d.ts.map +1 -0
  16. package/dist/evaluators/compliance.js +213 -0
  17. package/dist/evaluators/compliance.js.map +1 -0
  18. package/dist/evaluators/concurrency.d.ts +3 -0
  19. package/dist/evaluators/concurrency.d.ts.map +1 -0
  20. package/dist/evaluators/concurrency.js +220 -0
  21. package/dist/evaluators/concurrency.js.map +1 -0
  22. package/dist/evaluators/cost-effectiveness.d.ts +3 -0
  23. package/dist/evaluators/cost-effectiveness.d.ts.map +1 -0
  24. package/dist/evaluators/cost-effectiveness.js +206 -0
  25. package/dist/evaluators/cost-effectiveness.js.map +1 -0
  26. package/dist/evaluators/cybersecurity.d.ts +3 -0
  27. package/dist/evaluators/cybersecurity.d.ts.map +1 -0
  28. package/dist/evaluators/cybersecurity.js +282 -0
  29. package/dist/evaluators/cybersecurity.js.map +1 -0
  30. package/dist/evaluators/data-security.d.ts +3 -0
  31. package/dist/evaluators/data-security.d.ts.map +1 -0
  32. package/dist/evaluators/data-security.js +286 -0
  33. package/dist/evaluators/data-security.js.map +1 -0
  34. package/dist/evaluators/dependency-health.d.ts +3 -0
  35. package/dist/evaluators/dependency-health.d.ts.map +1 -0
  36. package/dist/evaluators/dependency-health.js +197 -0
  37. package/dist/evaluators/dependency-health.js.map +1 -0
  38. package/dist/evaluators/documentation.d.ts +3 -0
  39. package/dist/evaluators/documentation.d.ts.map +1 -0
  40. package/dist/evaluators/documentation.js +216 -0
  41. package/dist/evaluators/documentation.js.map +1 -0
  42. package/dist/evaluators/ethics-bias.d.ts +3 -0
  43. package/dist/evaluators/ethics-bias.d.ts.map +1 -0
  44. package/dist/evaluators/ethics-bias.js +205 -0
  45. package/dist/evaluators/ethics-bias.js.map +1 -0
  46. package/dist/evaluators/index.d.ts +12 -0
  47. package/dist/evaluators/index.d.ts.map +1 -0
  48. package/dist/evaluators/index.js +127 -0
  49. package/dist/evaluators/index.js.map +1 -0
  50. package/dist/evaluators/internationalization.d.ts +3 -0
  51. package/dist/evaluators/internationalization.d.ts.map +1 -0
  52. package/dist/evaluators/internationalization.js +176 -0
  53. package/dist/evaluators/internationalization.js.map +1 -0
  54. package/dist/evaluators/observability.d.ts +3 -0
  55. package/dist/evaluators/observability.d.ts.map +1 -0
  56. package/dist/evaluators/observability.js +171 -0
  57. package/dist/evaluators/observability.js.map +1 -0
  58. package/dist/evaluators/performance.d.ts +3 -0
  59. package/dist/evaluators/performance.d.ts.map +1 -0
  60. package/dist/evaluators/performance.js +306 -0
  61. package/dist/evaluators/performance.js.map +1 -0
  62. package/dist/evaluators/reliability.d.ts +3 -0
  63. package/dist/evaluators/reliability.d.ts.map +1 -0
  64. package/dist/evaluators/reliability.js +215 -0
  65. package/dist/evaluators/reliability.js.map +1 -0
  66. package/dist/evaluators/scalability.d.ts +3 -0
  67. package/dist/evaluators/scalability.d.ts.map +1 -0
  68. package/dist/evaluators/scalability.js +171 -0
  69. package/dist/evaluators/scalability.js.map +1 -0
  70. package/dist/evaluators/shared.d.ts +18 -0
  71. package/dist/evaluators/shared.d.ts.map +1 -0
  72. package/dist/evaluators/shared.js +147 -0
  73. package/dist/evaluators/shared.js.map +1 -0
  74. package/dist/evaluators/software-practices.d.ts +3 -0
  75. package/dist/evaluators/software-practices.d.ts.map +1 -0
  76. package/dist/evaluators/software-practices.js +272 -0
  77. package/dist/evaluators/software-practices.js.map +1 -0
  78. package/dist/evaluators/testing.d.ts +3 -0
  79. package/dist/evaluators/testing.d.ts.map +1 -0
  80. package/dist/evaluators/testing.js +185 -0
  81. package/dist/evaluators/testing.js.map +1 -0
  82. package/dist/index.d.ts +16 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +238 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/judges/accessibility.d.ts +3 -0
  87. package/dist/judges/accessibility.d.ts.map +1 -0
  88. package/dist/judges/accessibility.js +28 -0
  89. package/dist/judges/accessibility.js.map +1 -0
  90. package/dist/judges/api-design.d.ts +3 -0
  91. package/dist/judges/api-design.d.ts.map +1 -0
  92. package/dist/judges/api-design.js +30 -0
  93. package/dist/judges/api-design.js.map +1 -0
  94. package/dist/judges/cloud-readiness.d.ts +3 -0
  95. package/dist/judges/cloud-readiness.d.ts.map +1 -0
  96. package/dist/judges/cloud-readiness.js +28 -0
  97. package/dist/judges/cloud-readiness.js.map +1 -0
  98. package/dist/judges/compliance.d.ts +3 -0
  99. package/dist/judges/compliance.d.ts.map +1 -0
  100. package/dist/judges/compliance.js +28 -0
  101. package/dist/judges/compliance.js.map +1 -0
  102. package/dist/judges/concurrency.d.ts +3 -0
  103. package/dist/judges/concurrency.d.ts.map +1 -0
  104. package/dist/judges/concurrency.js +30 -0
  105. package/dist/judges/concurrency.js.map +1 -0
  106. package/dist/judges/cost-effectiveness.d.ts +3 -0
  107. package/dist/judges/cost-effectiveness.d.ts.map +1 -0
  108. package/dist/judges/cost-effectiveness.js +27 -0
  109. package/dist/judges/cost-effectiveness.js.map +1 -0
  110. package/dist/judges/cybersecurity.d.ts +3 -0
  111. package/dist/judges/cybersecurity.d.ts.map +1 -0
  112. package/dist/judges/cybersecurity.js +27 -0
  113. package/dist/judges/cybersecurity.js.map +1 -0
  114. package/dist/judges/data-security.d.ts +3 -0
  115. package/dist/judges/data-security.d.ts.map +1 -0
  116. package/dist/judges/data-security.js +25 -0
  117. package/dist/judges/data-security.js.map +1 -0
  118. package/dist/judges/dependency-health.d.ts +3 -0
  119. package/dist/judges/dependency-health.d.ts.map +1 -0
  120. package/dist/judges/dependency-health.js +30 -0
  121. package/dist/judges/dependency-health.js.map +1 -0
  122. package/dist/judges/documentation.d.ts +3 -0
  123. package/dist/judges/documentation.d.ts.map +1 -0
  124. package/dist/judges/documentation.js +30 -0
  125. package/dist/judges/documentation.js.map +1 -0
  126. package/dist/judges/ethics-bias.d.ts +3 -0
  127. package/dist/judges/ethics-bias.d.ts.map +1 -0
  128. package/dist/judges/ethics-bias.js +30 -0
  129. package/dist/judges/ethics-bias.js.map +1 -0
  130. package/dist/judges/index.d.ts +23 -0
  131. package/dist/judges/index.d.ts.map +1 -0
  132. package/dist/judges/index.js +63 -0
  133. package/dist/judges/index.js.map +1 -0
  134. package/dist/judges/internationalization.d.ts +3 -0
  135. package/dist/judges/internationalization.d.ts.map +1 -0
  136. package/dist/judges/internationalization.js +28 -0
  137. package/dist/judges/internationalization.js.map +1 -0
  138. package/dist/judges/observability.d.ts +3 -0
  139. package/dist/judges/observability.d.ts.map +1 -0
  140. package/dist/judges/observability.js +28 -0
  141. package/dist/judges/observability.js.map +1 -0
  142. package/dist/judges/performance.d.ts +3 -0
  143. package/dist/judges/performance.d.ts.map +1 -0
  144. package/dist/judges/performance.js +30 -0
  145. package/dist/judges/performance.js.map +1 -0
  146. package/dist/judges/reliability.d.ts +3 -0
  147. package/dist/judges/reliability.d.ts.map +1 -0
  148. package/dist/judges/reliability.js +30 -0
  149. package/dist/judges/reliability.js.map +1 -0
  150. package/dist/judges/scalability.d.ts +3 -0
  151. package/dist/judges/scalability.d.ts.map +1 -0
  152. package/dist/judges/scalability.js +28 -0
  153. package/dist/judges/scalability.js.map +1 -0
  154. package/dist/judges/software-practices.d.ts +3 -0
  155. package/dist/judges/software-practices.d.ts.map +1 -0
  156. package/dist/judges/software-practices.js +30 -0
  157. package/dist/judges/software-practices.js.map +1 -0
  158. package/dist/judges/testing.d.ts +3 -0
  159. package/dist/judges/testing.d.ts.map +1 -0
  160. package/dist/judges/testing.js +30 -0
  161. package/dist/judges/testing.js.map +1 -0
  162. package/dist/types.d.ts +80 -0
  163. package/dist/types.d.ts.map +1 -0
  164. package/dist/types.js +2 -0
  165. package/dist/types.js.map +1 -0
  166. package/package.json +53 -0
  167. package/server.json +21 -0
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # Judges Panel
2
+
3
+ An MCP (Model Context Protocol) server that provides a panel of **18 specialized judges** to evaluate AI-generated code — acting as an independent quality gate regardless of which project is being reviewed.
4
+
5
+ ## The Judge Panel
6
+
7
+ | Judge | Domain | Rule Prefix | What It Evaluates |
8
+ |-------|--------|-------------|-------------------|
9
+ | **Judge Data Security** | Data Security & Privacy | `DATA-` | Encryption, PII handling, secrets management, access controls, GDPR/CCPA/HIPAA compliance |
10
+ | **Judge Cybersecurity** | Cybersecurity & Threat Defense | `CYBER-` | Injection attacks, XSS, CSRF, auth flaws, dependency CVEs, OWASP Top 10 |
11
+ | **Judge Cost Effectiveness** | Cost Optimization | `COST-` | Algorithm efficiency, N+1 queries, memory waste, caching strategy, cloud spend |
12
+ | **Judge Scalability** | Scalability & Performance | `SCALE-` | Statelessness, horizontal scaling, concurrency, bottlenecks, rate limiting |
13
+ | **Judge Cloud Readiness** | Cloud-Native & DevOps | `CLOUD-` | 12-Factor compliance, containerization, observability, graceful shutdown, IaC |
14
+ | **Judge Software Practices** | Engineering Best Practices | `SWDEV-` | SOLID principles, type safety, error handling, testing, input validation, clean code |
15
+ | **Judge Accessibility** | Accessibility (a11y) | `A11Y-` | WCAG compliance, screen reader support, keyboard navigation, ARIA, color contrast |
16
+ | **Judge API Design** | API Design & Contracts | `API-` | REST conventions, versioning, pagination, error responses, consistency |
17
+ | **Judge Reliability** | Reliability & Resilience | `REL-` | Error handling, timeouts, retries, circuit breakers, graceful degradation |
18
+ | **Judge Observability** | Observability & Monitoring | `OBS-` | Structured logging, health checks, metrics, tracing, correlation IDs |
19
+ | **Judge Performance** | Performance & Efficiency | `PERF-` | N+1 queries, sync I/O, caching, memory leaks, algorithmic complexity |
20
+ | **Judge Compliance** | Regulatory Compliance | `COMP-` | GDPR/CCPA, PII protection, consent, data retention, audit trails |
21
+ | **Judge Testing** | Testing & Quality Assurance | `TEST-` | Test coverage, assertions, test isolation, naming, external dependencies |
22
+ | **Judge Documentation** | Documentation & Readability | `DOC-` | JSDoc/docstrings, magic numbers, TODOs, code comments, module docs |
23
+ | **Judge Internationalization** | Internationalization (i18n) | `I18N-` | Hardcoded strings, locale handling, currency formatting, RTL support |
24
+ | **Judge Dependency Health** | Dependency Management | `DEPS-` | Version pinning, deprecated packages, supply chain, import hygiene |
25
+ | **Judge Concurrency** | Concurrency & Async Safety | `CONC-` | Race conditions, unbounded parallelism, missing await, resource cleanup |
26
+ | **Judge Ethics & Bias** | Ethics & Bias | `ETHICS-` | Demographic logic, explainability, dark patterns, inclusive language |
27
+
28
+ ## How It Works
29
+
30
+ The tribunal operates in two modes:
31
+
32
+ 1. **Pattern-Based Analysis (Tools)** — The `evaluate_code` and `evaluate_code_single_judge` tools perform heuristic analysis using pattern matching to catch common anti-patterns. This works entirely offline with zero external API calls.
33
+
34
+ 2. **LLM-Powered Deep Analysis (Prompts)** — The server exposes MCP prompts (`judge-data-security`, `judge-cybersecurity`, etc., and `full-tribunal`) that provide each judge's expert persona as a system prompt. When used by an LLM-based client, this enables much deeper, context-aware analysis.
35
+
36
+ ## MCP Tools
37
+
38
+ ### `get_judges`
39
+ List all available judges with their domains and descriptions.
40
+
41
+ ### `evaluate_code`
42
+ Submit code to the **full judges panel**. All 18 judges evaluate independently and return a combined verdict.
43
+
44
+ **Parameters:**
45
+ - `code` (string, required) — The source code to evaluate
46
+ - `language` (string, required) — Programming language (e.g., "typescript", "python")
47
+ - `context` (string, optional) — Additional context about the code
48
+
49
+ **Returns:** Combined verdict with overall score, per-judge scores, all findings, and recommendations.
50
+
51
+ ### `evaluate_code_single_judge`
52
+ Submit code to a **specific judge** for targeted review.
53
+
54
+ **Parameters:**
55
+ - `code` (string, required) — The source code to evaluate
56
+ - `language` (string, required) — Programming language
57
+ - `judgeId` (string, required) — One of: `data-security`, `cybersecurity`, `cost-effectiveness`, `scalability`, `cloud-readiness`, `software-practices`, `accessibility`, `api-design`, `reliability`, `observability`, `performance`, `compliance`, `testing`, `documentation`, `internationalization`, `dependency-health`, `concurrency`, `ethics-bias`
58
+ - `context` (string, optional) — Additional context
59
+
60
+ ## MCP Prompts
61
+
62
+ - `judge-data-security` — Deep data security review via LLM
63
+ - `judge-cybersecurity` — Deep cybersecurity review via LLM
64
+ - `judge-cost-effectiveness` — Deep cost optimization review via LLM
65
+ - `judge-scalability` — Deep scalability review via LLM
66
+ - `judge-cloud-readiness` — Deep cloud readiness review via LLM
67
+ - `judge-software-practices` — Deep software practices review via LLM
68
+ - `judge-accessibility` — Deep accessibility/WCAG review via LLM
69
+ - `judge-api-design` — Deep API design review via LLM
70
+ - `judge-reliability` — Deep reliability & resilience review via LLM
71
+ - `judge-observability` — Deep observability & monitoring review via LLM
72
+ - `judge-performance` — Deep performance optimization review via LLM
73
+ - `judge-compliance` — Deep regulatory compliance review via LLM
74
+ - `judge-testing` — Deep testing quality review via LLM
75
+ - `judge-documentation` — Deep documentation quality review via LLM
76
+ - `judge-internationalization` — Deep i18n review via LLM
77
+ - `judge-dependency-health` — Deep dependency health review via LLM
78
+ - `judge-concurrency` — Deep concurrency & async safety review via LLM
79
+ - `judge-ethics-bias` — Deep ethics & bias review via LLM
80
+ - `full-tribunal` — All 18 judges via LLM in a single prompt
81
+
82
+ ## Setup
83
+
84
+ ### Build
85
+
86
+ ```bash
87
+ npm install
88
+ npm run build
89
+ ```
90
+
91
+ ### Configure in VS Code (GitHub Copilot / Claude Desktop)
92
+
93
+ Add to your MCP settings (`.vscode/mcp.json`, `claude_desktop_config.json`, etc.):
94
+
95
+ ```json
96
+ {
97
+ "mcpServers": {
98
+ "judges": {
99
+ "command": "node",
100
+ "args": ["<path-to>/judges/dist/index.js"]
101
+ }
102
+ }
103
+ }
104
+ ```
105
+
106
+ ### Configure in VS Code Settings (settings.json)
107
+
108
+ ```json
109
+ {
110
+ "mcp": {
111
+ "servers": {
112
+ "judges": {
113
+ "command": "node",
114
+ "args": ["<path-to>/judges/dist/index.js"]
115
+ }
116
+ }
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## Scoring
122
+
123
+ Each judge scores the code from **0 to 100**:
124
+
125
+ | Severity | Score Deduction |
126
+ |----------|----------------|
127
+ | Critical | -20 points |
128
+ | High | -12 points |
129
+ | Medium | -6 points |
130
+ | Low | -3 points |
131
+ | Info | 0 points |
132
+
133
+ **Verdict logic:**
134
+ - **FAIL** — Any critical finding, or score < 50
135
+ - **WARNING** — Any high finding, or score < 75
136
+ - **PASS** — Score ≥ 75 with no critical or high findings
137
+
138
+ The **overall tribunal score** is the average of all 18 judges. The overall verdict fails if **any** judge fails.
139
+
140
+ ## Example Output
141
+
142
+ ```
143
+ # Judges Panel — Verdict
144
+
145
+ **Overall Verdict: WARNING** | **Score: 68/100**
146
+ Total critical findings: 1 | Total high findings: 3
147
+
148
+ ## Individual Judge Results
149
+
150
+ ❌ **Judge Data Security** (FAIL, 60/100) — 3 finding(s)
151
+ ⚠️ **Judge Cybersecurity** (WARNING, 76/100) — 2 finding(s)
152
+ ✅ **Judge Cost Effectiveness** (PASS, 88/100) — 1 finding(s)
153
+ ⚠️ **Judge Scalability** (WARNING, 70/100) — 2 finding(s)
154
+ ✅ **Judge Cloud Readiness** (PASS, 82/100) — 1 finding(s)
155
+ ⚠️ **Judge Software Practices** (WARNING, 72/100) — 3 finding(s)
156
+ ```
157
+
158
+ ## Project Structure
159
+
160
+ ```
161
+ judges/
162
+ ├── src/
163
+ │ ├── index.ts # MCP server entry point — tools, prompts, transport
164
+ │ ├── types.ts # TypeScript interfaces for judges, findings, verdicts
165
+ │ ├── judges.ts # Judge definitions with expert system prompts
166
+ │ └── evaluator.ts # Pattern-based analysis engine + scoring
167
+ ├── package.json
168
+ ├── tsconfig.json
169
+ └── README.md
170
+ ```
171
+
172
+ ## License
173
+
174
+ MIT
@@ -0,0 +1,3 @@
1
+ import { Finding } from "../types.js";
2
+ export declare function analyzeAccessibility(code: string, language: string): Finding[];
3
+ //# sourceMappingURL=accessibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessibility.d.ts","sourceRoot":"","sources":["../../src/evaluators/accessibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAiU9E"}
@@ -0,0 +1,306 @@
1
+ export function analyzeAccessibility(code, language) {
2
+ const findings = [];
3
+ const lines = code.split("\n");
4
+ const prefix = "A11Y";
5
+ let ruleNum = 1;
6
+ // Detect images without alt attributes
7
+ const imgNoAltLines = [];
8
+ lines.forEach((line, i) => {
9
+ if (/<img\b/i.test(line) && !/alt\s*=/i.test(line)) {
10
+ imgNoAltLines.push(i + 1);
11
+ }
12
+ });
13
+ if (imgNoAltLines.length > 0) {
14
+ findings.push({
15
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
16
+ severity: "high",
17
+ title: "Image missing alt attribute",
18
+ description: "Images must have descriptive alt text for screen readers and assistive technologies.",
19
+ lineNumbers: imgNoAltLines,
20
+ recommendation: "Add meaningful alt text describing the image content. Use alt=\"\" only for purely decorative images.",
21
+ reference: "WCAG 2.1 SC 1.1.1 Non-text Content",
22
+ });
23
+ }
24
+ // Detect click handlers without keyboard equivalents
25
+ const clickNoKeyLines = [];
26
+ lines.forEach((line, i) => {
27
+ if (/onClick/i.test(line) && !/onKeyDown|onKeyUp|onKeyPress/i.test(line)) {
28
+ clickNoKeyLines.push(i + 1);
29
+ }
30
+ });
31
+ if (clickNoKeyLines.length > 0) {
32
+ findings.push({
33
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
34
+ severity: "medium",
35
+ title: "Click handler without keyboard equivalent",
36
+ description: "Interactive elements with onClick must also support keyboard interaction for users who cannot use a mouse.",
37
+ lineNumbers: clickNoKeyLines,
38
+ recommendation: "Add onKeyDown or onKeyPress handlers alongside onClick. Ensure all interactive elements are keyboard accessible.",
39
+ reference: "WCAG 2.1 SC 2.1.1 Keyboard",
40
+ });
41
+ }
42
+ // Detect non-semantic elements used for structure
43
+ const nonSemanticLines = [];
44
+ lines.forEach((line, i) => {
45
+ if (/<div\b/i.test(line) && /role\s*=\s*["'](button|link|heading|navigation|main)/i.test(line)) {
46
+ nonSemanticLines.push(i + 1);
47
+ }
48
+ });
49
+ if (nonSemanticLines.length > 0) {
50
+ findings.push({
51
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
52
+ severity: "medium",
53
+ title: "Non-semantic element used with ARIA role",
54
+ description: "Using div with an ARIA role instead of the appropriate semantic HTML element reduces accessibility and adds unnecessary complexity.",
55
+ lineNumbers: nonSemanticLines,
56
+ recommendation: "Use semantic HTML elements (button, a, h1-h6, nav, main) instead of divs with ARIA roles.",
57
+ reference: "WCAG 2.1 SC 4.1.2 Name, Role, Value",
58
+ });
59
+ }
60
+ // Detect missing form labels
61
+ const inputNoLabelLines = [];
62
+ lines.forEach((line, i) => {
63
+ if (/<input\b/i.test(line) && !/aria-label|aria-labelledby|id\s*=/i.test(line) && !/type\s*=\s*["']hidden/i.test(line)) {
64
+ inputNoLabelLines.push(i + 1);
65
+ }
66
+ });
67
+ if (inputNoLabelLines.length > 0) {
68
+ findings.push({
69
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
70
+ severity: "high",
71
+ title: "Form input missing label association",
72
+ description: "Form inputs without associated labels are inaccessible to screen reader users.",
73
+ lineNumbers: inputNoLabelLines,
74
+ recommendation: "Associate each input with a <label> element using for/id, or use aria-label / aria-labelledby.",
75
+ reference: "WCAG 2.1 SC 1.3.1 Info and Relationships",
76
+ });
77
+ }
78
+ // Detect tabIndex > 0
79
+ const tabIndexLines = [];
80
+ lines.forEach((line, i) => {
81
+ if (/tabIndex\s*=\s*{?\s*[1-9]/i.test(line) || /tabindex\s*=\s*["'][1-9]/i.test(line)) {
82
+ tabIndexLines.push(i + 1);
83
+ }
84
+ });
85
+ if (tabIndexLines.length > 0) {
86
+ findings.push({
87
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
88
+ severity: "medium",
89
+ title: "Positive tabIndex used",
90
+ description: "Using positive tabIndex values disrupts the natural tab order and creates confusing navigation for keyboard users.",
91
+ lineNumbers: tabIndexLines,
92
+ recommendation: "Use tabIndex={0} to add to natural tab order or tabIndex={-1} for programmatic focus only. Never use positive values.",
93
+ reference: "WCAG 2.1 SC 2.4.3 Focus Order",
94
+ });
95
+ }
96
+ // Detect color-only status indicators
97
+ const colorOnlyLines = [];
98
+ lines.forEach((line, i) => {
99
+ if (/color\s*[:=].*(?:red|green|#f00|#0f0|#ff0000|#00ff00)/i.test(line) && /(?:status|error|success|warning|valid|invalid)/i.test(line)) {
100
+ colorOnlyLines.push(i + 1);
101
+ }
102
+ });
103
+ if (colorOnlyLines.length > 0) {
104
+ findings.push({
105
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
106
+ severity: "medium",
107
+ title: "Possible color-only status indication",
108
+ description: "Relying solely on color to convey status information excludes users with color vision deficiencies.",
109
+ lineNumbers: colorOnlyLines,
110
+ recommendation: "Use text labels, icons, or patterns in addition to color to convey status information.",
111
+ reference: "WCAG 2.1 SC 1.4.1 Use of Color",
112
+ });
113
+ }
114
+ // Detect autoplay media
115
+ const autoplayLines = [];
116
+ lines.forEach((line, i) => {
117
+ if (/autoplay|autoPlay/i.test(line)) {
118
+ autoplayLines.push(i + 1);
119
+ }
120
+ });
121
+ if (autoplayLines.length > 0) {
122
+ findings.push({
123
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
124
+ severity: "medium",
125
+ title: "Auto-playing media detected",
126
+ description: "Auto-playing audio or video can be disorienting for screen reader users and those with cognitive disabilities.",
127
+ lineNumbers: autoplayLines,
128
+ recommendation: "Avoid autoplay or provide a mechanism to pause/stop/mute within the first 3 seconds.",
129
+ reference: "WCAG 2.1 SC 1.4.2 Audio Control",
130
+ });
131
+ }
132
+ // Missing lang attribute on html element
133
+ const htmlNoLangLines = [];
134
+ lines.forEach((line, i) => {
135
+ if (/<html\b/i.test(line) && !/lang\s*=/i.test(line)) {
136
+ htmlNoLangLines.push(i + 1);
137
+ }
138
+ });
139
+ if (htmlNoLangLines.length > 0) {
140
+ findings.push({
141
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
142
+ severity: "high",
143
+ title: "Missing lang attribute on <html>",
144
+ description: "The html element must have a lang attribute so screen readers pronounce content in the correct language.",
145
+ lineNumbers: htmlNoLangLines,
146
+ recommendation: "Add lang attribute: <html lang=\"en\">. Use the appropriate BCP 47 language tag.",
147
+ reference: "WCAG 2.1 SC 3.1.1 Language of Page",
148
+ });
149
+ }
150
+ // Skip navigation link missing
151
+ const hasNav = /<nav\b|role\s*=\s*["']navigation/i.test(code);
152
+ const hasSkipLink = /skip.*nav|skip.*content|skipToContent|#main-content/i.test(code);
153
+ if (hasNav && !hasSkipLink) {
154
+ findings.push({
155
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
156
+ severity: "medium",
157
+ title: "No skip navigation link detected",
158
+ description: "Pages with navigation should include a 'Skip to main content' link so keyboard users can bypass repetitive navigation.",
159
+ recommendation: "Add a visually hidden 'Skip to main content' link as the first focusable element on the page.",
160
+ reference: "WCAG 2.1 SC 2.4.1 Bypass Blocks",
161
+ });
162
+ }
163
+ // Focus management — outline:none without replacement
164
+ const outlineNoneLines = [];
165
+ lines.forEach((line, i) => {
166
+ if (/outline\s*:\s*(?:none|0)\b/i.test(line)) {
167
+ const context = lines.slice(i, Math.min(lines.length, i + 5)).join("\n");
168
+ if (!/focus-visible|box-shadow|border.*focus|ring/i.test(context)) {
169
+ outlineNoneLines.push(i + 1);
170
+ }
171
+ }
172
+ });
173
+ if (outlineNoneLines.length > 0) {
174
+ findings.push({
175
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
176
+ severity: "high",
177
+ title: "Focus indicator removed (outline: none)",
178
+ description: "Removing the focus outline without providing an alternative focus indicator makes the page unusable for keyboard users.",
179
+ lineNumbers: outlineNoneLines,
180
+ recommendation: "If removing outline, provide a visible alternative focus indicator (box-shadow, border, custom :focus-visible styles).",
181
+ reference: "WCAG 2.1 SC 2.4.7 Focus Visible",
182
+ });
183
+ }
184
+ // Missing ARIA live regions for dynamic content
185
+ const dynamicUpdateLines = [];
186
+ lines.forEach((line, i) => {
187
+ if (/(?:toast|notification|alert|snackbar|banner)\s*[=(]/i.test(line) || /setState.*(?:error|message|notification)/i.test(line)) {
188
+ dynamicUpdateLines.push(i + 1);
189
+ }
190
+ });
191
+ const hasAriaLive = /aria-live|role\s*=\s*["'](?:alert|status|log)/i.test(code);
192
+ if (dynamicUpdateLines.length > 0 && !hasAriaLive) {
193
+ findings.push({
194
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
195
+ severity: "medium",
196
+ title: "Dynamic content updates without ARIA live region",
197
+ description: "Dynamic notifications, toasts, or alerts must use aria-live regions so screen readers announce them.",
198
+ lineNumbers: dynamicUpdateLines.slice(0, 5),
199
+ recommendation: "Wrap dynamic notification areas with aria-live='polite' (or role='alert' for urgent messages).",
200
+ reference: "WCAG 2.1 SC 4.1.3 Status Messages",
201
+ });
202
+ }
203
+ // Heading hierarchy issues
204
+ const headingLevels = [];
205
+ lines.forEach((line, i) => {
206
+ const match = line.match(/<h([1-6])\b/i);
207
+ if (match) {
208
+ headingLevels.push({ level: parseInt(match[1]), line: i + 1 });
209
+ }
210
+ });
211
+ const skippedHeadingLines = [];
212
+ for (let i = 1; i < headingLevels.length; i++) {
213
+ if (headingLevels[i].level > headingLevels[i - 1].level + 1) {
214
+ skippedHeadingLines.push(headingLevels[i].line);
215
+ }
216
+ }
217
+ if (skippedHeadingLines.length > 0) {
218
+ findings.push({
219
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
220
+ severity: "medium",
221
+ title: "Heading level skipped",
222
+ description: "Heading levels should be sequential (h1->h2->h3). Skipping levels creates a confusing document hierarchy for assistive technology users.",
223
+ lineNumbers: skippedHeadingLines,
224
+ recommendation: "Use headings in sequential order. Don't skip from h1 to h3. Use CSS for visual styling instead of choosing heading levels by appearance.",
225
+ reference: "WCAG 2.1 SC 1.3.1 Info and Relationships",
226
+ });
227
+ }
228
+ // Touch target size too small
229
+ const smallTargetLines = [];
230
+ lines.forEach((line, i) => {
231
+ if (/(?:width|height|size)\s*[:=]\s*(?:['"]?\d{1,2}(?:px)?['"]?|{\s*\d{1,2}\s*})/i.test(line) && /(?:button|btn|icon|close|toggle|checkbox|radio)/i.test(line)) {
232
+ smallTargetLines.push(i + 1);
233
+ }
234
+ });
235
+ if (smallTargetLines.length > 0) {
236
+ findings.push({
237
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
238
+ severity: "medium",
239
+ title: "Interactive element may have small touch target",
240
+ description: "Interactive elements with very small dimensions may not meet the 44x44px minimum touch target size.",
241
+ lineNumbers: smallTargetLines,
242
+ recommendation: "Ensure interactive elements have a minimum touch/click target size of 44x44 CSS pixels (WCAG) or 48x48dp (Material Design).",
243
+ reference: "WCAG 2.1 SC 2.5.5 Target Size",
244
+ });
245
+ }
246
+ // Motion/animation without reduced-motion support
247
+ const animationLines = [];
248
+ lines.forEach((line, i) => {
249
+ if (/animation\s*:|transition\s*:|@keyframes|animate\s*\(|gsap|framer-motion|spring/i.test(line)) {
250
+ animationLines.push(i + 1);
251
+ }
252
+ });
253
+ const hasReducedMotion = /prefers-reduced-motion|prefersReducedMotion|reducedMotion/i.test(code);
254
+ if (animationLines.length > 0 && !hasReducedMotion) {
255
+ findings.push({
256
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
257
+ severity: "medium",
258
+ title: "Animations without reduced-motion support",
259
+ description: "Animations can trigger vestibular disorders in some users. The prefers-reduced-motion media query should be respected.",
260
+ lineNumbers: animationLines.slice(0, 5),
261
+ recommendation: "Add @media (prefers-reduced-motion: reduce) { ... } to disable or simplify animations for users who prefer reduced motion.",
262
+ reference: "WCAG 2.1 SC 2.3.3 Animation from Interactions",
263
+ });
264
+ }
265
+ // Video/audio without captions/transcript
266
+ const mediaLines = [];
267
+ lines.forEach((line, i) => {
268
+ if (/<video\b|<audio\b|<iframe.*(?:youtube|vimeo)/i.test(line)) {
269
+ const context = lines.slice(i, Math.min(lines.length, i + 5)).join("\n");
270
+ if (!/track\b|caption|subtitle|transcript/i.test(context)) {
271
+ mediaLines.push(i + 1);
272
+ }
273
+ }
274
+ });
275
+ if (mediaLines.length > 0) {
276
+ findings.push({
277
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
278
+ severity: "high",
279
+ title: "Media without captions or transcript",
280
+ description: "Audio and video content must have captions (for deaf users) and ideally transcripts for full accessibility.",
281
+ lineNumbers: mediaLines,
282
+ recommendation: "Add <track kind='captions'> for videos, provide transcripts for audio, and ensure embedded videos have captions enabled.",
283
+ reference: "WCAG 2.1 SC 1.2.2 Captions (Prerecorded)",
284
+ });
285
+ }
286
+ // Form error messages not associated with inputs
287
+ const errorMsgLines = [];
288
+ lines.forEach((line, i) => {
289
+ if (/(?:error|invalid|validation).*(?:message|msg|text)/i.test(line) && !/aria-describedby|aria-errormessage|aria-invalid/i.test(line)) {
290
+ errorMsgLines.push(i + 1);
291
+ }
292
+ });
293
+ if (errorMsgLines.length > 0) {
294
+ findings.push({
295
+ ruleId: `${prefix}-${String(ruleNum++).padStart(3, "0")}`,
296
+ severity: "medium",
297
+ title: "Form error not associated with input via ARIA",
298
+ description: "Error messages near form inputs should be programmatically associated so screen readers announce them.",
299
+ lineNumbers: errorMsgLines.slice(0, 5),
300
+ recommendation: "Use aria-describedby to link error messages to inputs, and aria-invalid='true' on invalid inputs.",
301
+ reference: "WCAG 2.1 SC 3.3.1 Error Identification",
302
+ });
303
+ }
304
+ return findings;
305
+ }
306
+ //# sourceMappingURL=accessibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessibility.js","sourceRoot":"","sources":["../../src/evaluators/accessibility.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Finding } from "../types.js";
2
+ export declare function analyzeApiDesign(code: string, language: string): Finding[];
3
+ //# sourceMappingURL=api-design.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-design.d.ts","sourceRoot":"","sources":["../../src/evaluators/api-design.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAGtC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CA2O1E"}