@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.
- package/README.md +174 -0
- package/dist/evaluators/accessibility.d.ts +3 -0
- package/dist/evaluators/accessibility.d.ts.map +1 -0
- package/dist/evaluators/accessibility.js +306 -0
- package/dist/evaluators/accessibility.js.map +1 -0
- package/dist/evaluators/api-design.d.ts +3 -0
- package/dist/evaluators/api-design.d.ts.map +1 -0
- package/dist/evaluators/api-design.js +224 -0
- package/dist/evaluators/api-design.js.map +1 -0
- package/dist/evaluators/cloud-readiness.d.ts +3 -0
- package/dist/evaluators/cloud-readiness.d.ts.map +1 -0
- package/dist/evaluators/cloud-readiness.js +181 -0
- package/dist/evaluators/cloud-readiness.js.map +1 -0
- package/dist/evaluators/compliance.d.ts +3 -0
- package/dist/evaluators/compliance.d.ts.map +1 -0
- package/dist/evaluators/compliance.js +213 -0
- package/dist/evaluators/compliance.js.map +1 -0
- package/dist/evaluators/concurrency.d.ts +3 -0
- package/dist/evaluators/concurrency.d.ts.map +1 -0
- package/dist/evaluators/concurrency.js +220 -0
- package/dist/evaluators/concurrency.js.map +1 -0
- package/dist/evaluators/cost-effectiveness.d.ts +3 -0
- package/dist/evaluators/cost-effectiveness.d.ts.map +1 -0
- package/dist/evaluators/cost-effectiveness.js +206 -0
- package/dist/evaluators/cost-effectiveness.js.map +1 -0
- package/dist/evaluators/cybersecurity.d.ts +3 -0
- package/dist/evaluators/cybersecurity.d.ts.map +1 -0
- package/dist/evaluators/cybersecurity.js +282 -0
- package/dist/evaluators/cybersecurity.js.map +1 -0
- package/dist/evaluators/data-security.d.ts +3 -0
- package/dist/evaluators/data-security.d.ts.map +1 -0
- package/dist/evaluators/data-security.js +286 -0
- package/dist/evaluators/data-security.js.map +1 -0
- package/dist/evaluators/dependency-health.d.ts +3 -0
- package/dist/evaluators/dependency-health.d.ts.map +1 -0
- package/dist/evaluators/dependency-health.js +197 -0
- package/dist/evaluators/dependency-health.js.map +1 -0
- package/dist/evaluators/documentation.d.ts +3 -0
- package/dist/evaluators/documentation.d.ts.map +1 -0
- package/dist/evaluators/documentation.js +216 -0
- package/dist/evaluators/documentation.js.map +1 -0
- package/dist/evaluators/ethics-bias.d.ts +3 -0
- package/dist/evaluators/ethics-bias.d.ts.map +1 -0
- package/dist/evaluators/ethics-bias.js +205 -0
- package/dist/evaluators/ethics-bias.js.map +1 -0
- package/dist/evaluators/index.d.ts +12 -0
- package/dist/evaluators/index.d.ts.map +1 -0
- package/dist/evaluators/index.js +127 -0
- package/dist/evaluators/index.js.map +1 -0
- package/dist/evaluators/internationalization.d.ts +3 -0
- package/dist/evaluators/internationalization.d.ts.map +1 -0
- package/dist/evaluators/internationalization.js +176 -0
- package/dist/evaluators/internationalization.js.map +1 -0
- package/dist/evaluators/observability.d.ts +3 -0
- package/dist/evaluators/observability.d.ts.map +1 -0
- package/dist/evaluators/observability.js +171 -0
- package/dist/evaluators/observability.js.map +1 -0
- package/dist/evaluators/performance.d.ts +3 -0
- package/dist/evaluators/performance.d.ts.map +1 -0
- package/dist/evaluators/performance.js +306 -0
- package/dist/evaluators/performance.js.map +1 -0
- package/dist/evaluators/reliability.d.ts +3 -0
- package/dist/evaluators/reliability.d.ts.map +1 -0
- package/dist/evaluators/reliability.js +215 -0
- package/dist/evaluators/reliability.js.map +1 -0
- package/dist/evaluators/scalability.d.ts +3 -0
- package/dist/evaluators/scalability.d.ts.map +1 -0
- package/dist/evaluators/scalability.js +171 -0
- package/dist/evaluators/scalability.js.map +1 -0
- package/dist/evaluators/shared.d.ts +18 -0
- package/dist/evaluators/shared.d.ts.map +1 -0
- package/dist/evaluators/shared.js +147 -0
- package/dist/evaluators/shared.js.map +1 -0
- package/dist/evaluators/software-practices.d.ts +3 -0
- package/dist/evaluators/software-practices.d.ts.map +1 -0
- package/dist/evaluators/software-practices.js +272 -0
- package/dist/evaluators/software-practices.js.map +1 -0
- package/dist/evaluators/testing.d.ts +3 -0
- package/dist/evaluators/testing.d.ts.map +1 -0
- package/dist/evaluators/testing.js +185 -0
- package/dist/evaluators/testing.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +238 -0
- package/dist/index.js.map +1 -0
- package/dist/judges/accessibility.d.ts +3 -0
- package/dist/judges/accessibility.d.ts.map +1 -0
- package/dist/judges/accessibility.js +28 -0
- package/dist/judges/accessibility.js.map +1 -0
- package/dist/judges/api-design.d.ts +3 -0
- package/dist/judges/api-design.d.ts.map +1 -0
- package/dist/judges/api-design.js +30 -0
- package/dist/judges/api-design.js.map +1 -0
- package/dist/judges/cloud-readiness.d.ts +3 -0
- package/dist/judges/cloud-readiness.d.ts.map +1 -0
- package/dist/judges/cloud-readiness.js +28 -0
- package/dist/judges/cloud-readiness.js.map +1 -0
- package/dist/judges/compliance.d.ts +3 -0
- package/dist/judges/compliance.d.ts.map +1 -0
- package/dist/judges/compliance.js +28 -0
- package/dist/judges/compliance.js.map +1 -0
- package/dist/judges/concurrency.d.ts +3 -0
- package/dist/judges/concurrency.d.ts.map +1 -0
- package/dist/judges/concurrency.js +30 -0
- package/dist/judges/concurrency.js.map +1 -0
- package/dist/judges/cost-effectiveness.d.ts +3 -0
- package/dist/judges/cost-effectiveness.d.ts.map +1 -0
- package/dist/judges/cost-effectiveness.js +27 -0
- package/dist/judges/cost-effectiveness.js.map +1 -0
- package/dist/judges/cybersecurity.d.ts +3 -0
- package/dist/judges/cybersecurity.d.ts.map +1 -0
- package/dist/judges/cybersecurity.js +27 -0
- package/dist/judges/cybersecurity.js.map +1 -0
- package/dist/judges/data-security.d.ts +3 -0
- package/dist/judges/data-security.d.ts.map +1 -0
- package/dist/judges/data-security.js +25 -0
- package/dist/judges/data-security.js.map +1 -0
- package/dist/judges/dependency-health.d.ts +3 -0
- package/dist/judges/dependency-health.d.ts.map +1 -0
- package/dist/judges/dependency-health.js +30 -0
- package/dist/judges/dependency-health.js.map +1 -0
- package/dist/judges/documentation.d.ts +3 -0
- package/dist/judges/documentation.d.ts.map +1 -0
- package/dist/judges/documentation.js +30 -0
- package/dist/judges/documentation.js.map +1 -0
- package/dist/judges/ethics-bias.d.ts +3 -0
- package/dist/judges/ethics-bias.d.ts.map +1 -0
- package/dist/judges/ethics-bias.js +30 -0
- package/dist/judges/ethics-bias.js.map +1 -0
- package/dist/judges/index.d.ts +23 -0
- package/dist/judges/index.d.ts.map +1 -0
- package/dist/judges/index.js +63 -0
- package/dist/judges/index.js.map +1 -0
- package/dist/judges/internationalization.d.ts +3 -0
- package/dist/judges/internationalization.d.ts.map +1 -0
- package/dist/judges/internationalization.js +28 -0
- package/dist/judges/internationalization.js.map +1 -0
- package/dist/judges/observability.d.ts +3 -0
- package/dist/judges/observability.d.ts.map +1 -0
- package/dist/judges/observability.js +28 -0
- package/dist/judges/observability.js.map +1 -0
- package/dist/judges/performance.d.ts +3 -0
- package/dist/judges/performance.d.ts.map +1 -0
- package/dist/judges/performance.js +30 -0
- package/dist/judges/performance.js.map +1 -0
- package/dist/judges/reliability.d.ts +3 -0
- package/dist/judges/reliability.d.ts.map +1 -0
- package/dist/judges/reliability.js +30 -0
- package/dist/judges/reliability.js.map +1 -0
- package/dist/judges/scalability.d.ts +3 -0
- package/dist/judges/scalability.d.ts.map +1 -0
- package/dist/judges/scalability.js +28 -0
- package/dist/judges/scalability.js.map +1 -0
- package/dist/judges/software-practices.d.ts +3 -0
- package/dist/judges/software-practices.d.ts.map +1 -0
- package/dist/judges/software-practices.js +30 -0
- package/dist/judges/software-practices.js.map +1 -0
- package/dist/judges/testing.d.ts +3 -0
- package/dist/judges/testing.d.ts.map +1 -0
- package/dist/judges/testing.js +30 -0
- package/dist/judges/testing.js.map +1 -0
- package/dist/types.d.ts +80 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
- 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 @@
|
|
|
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 @@
|
|
|
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"}
|