agentic-qe 3.2.3 → 3.3.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/.claude/agents/v3/qe-accessibility-auditor.md +90 -0
- package/README.md +43 -5
- package/package.json +3 -2
- package/scripts/cloud-db-config.json +37 -0
- package/scripts/cloud-db-connect.sh +37 -0
- package/scripts/cloud-db-tunnel.sh +23 -0
- package/v3/CHANGELOG.md +165 -0
- package/v3/README.md +59 -1
- package/v3/assets/agents/v3/qe-accessibility-auditor.md +90 -0
- package/v3/dist/adapters/claude-flow/index.d.ts +54 -0
- package/v3/dist/adapters/claude-flow/index.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/index.js +79 -0
- package/v3/dist/adapters/claude-flow/index.js.map +1 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts +70 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.js +203 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts +73 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js +276 -0
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts +70 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js +205 -0
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js.map +1 -0
- package/v3/dist/adapters/claude-flow/types.d.ts +99 -0
- package/v3/dist/adapters/claude-flow/types.d.ts.map +1 -0
- package/v3/dist/adapters/claude-flow/types.js +6 -0
- package/v3/dist/adapters/claude-flow/types.js.map +1 -0
- package/v3/dist/causal-discovery/causal-graph.d.ts +80 -1
- package/v3/dist/causal-discovery/causal-graph.d.ts.map +1 -1
- package/v3/dist/causal-discovery/causal-graph.js +111 -1
- package/v3/dist/causal-discovery/causal-graph.js.map +1 -1
- package/v3/dist/cli/bundle.js +11612 -4929
- package/v3/dist/cli/commands/claude-flow-setup.d.ts +82 -0
- package/v3/dist/cli/commands/claude-flow-setup.d.ts.map +1 -0
- package/v3/dist/cli/commands/claude-flow-setup.js +334 -0
- package/v3/dist/cli/commands/claude-flow-setup.js.map +1 -0
- package/v3/dist/cli/commands/hooks.d.ts +2 -0
- package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
- package/v3/dist/cli/commands/hooks.js +13 -2
- package/v3/dist/cli/commands/hooks.js.map +1 -1
- package/v3/dist/cli/commands/init.d.ts +19 -0
- package/v3/dist/cli/commands/init.d.ts.map +1 -0
- package/v3/dist/cli/commands/init.js +345 -0
- package/v3/dist/cli/commands/init.js.map +1 -0
- package/v3/dist/cli/index.js +110 -2
- package/v3/dist/cli/index.js.map +1 -1
- package/v3/dist/coordination/mincut/interfaces.d.ts +8 -2
- package/v3/dist/coordination/mincut/interfaces.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/interfaces.js.map +1 -1
- package/v3/dist/coordination/mincut/mincut-health-monitor.d.ts +5 -0
- package/v3/dist/coordination/mincut/mincut-health-monitor.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/mincut-health-monitor.js +22 -4
- package/v3/dist/coordination/mincut/mincut-health-monitor.js.map +1 -1
- package/v3/dist/coordination/mincut/queen-integration.d.ts +4 -0
- package/v3/dist/coordination/mincut/queen-integration.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/queen-integration.js +14 -1
- package/v3/dist/coordination/mincut/queen-integration.js.map +1 -1
- package/v3/dist/coordination/queen-coordinator.d.ts +5 -0
- package/v3/dist/coordination/queen-coordinator.d.ts.map +1 -1
- package/v3/dist/coordination/queen-coordinator.js +45 -7
- package/v3/dist/coordination/queen-coordinator.js.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.d.ts +5 -0
- package/v3/dist/domains/learning-optimization/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.js +79 -0
- package/v3/dist/domains/learning-optimization/coordinator.js.map +1 -1
- package/v3/dist/domains/test-generation/coherence-gate.d.ts +245 -0
- package/v3/dist/domains/test-generation/coherence-gate.d.ts.map +1 -0
- package/v3/dist/domains/test-generation/coherence-gate.js +454 -0
- package/v3/dist/domains/test-generation/coherence-gate.js.map +1 -0
- package/v3/dist/domains/test-generation/coordinator.d.ts +32 -1
- package/v3/dist/domains/test-generation/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/coordinator.js +70 -1
- package/v3/dist/domains/test-generation/coordinator.js.map +1 -1
- package/v3/dist/domains/test-generation/index.d.ts +1 -0
- package/v3/dist/domains/test-generation/index.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/index.js +4 -0
- package/v3/dist/domains/test-generation/index.js.map +1 -1
- package/v3/dist/domains/test-generation/services/index.d.ts +1 -0
- package/v3/dist/domains/test-generation/services/index.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/services/index.js +2 -0
- package/v3/dist/domains/test-generation/services/index.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/index.d.ts +2 -1
- package/v3/dist/domains/visual-accessibility/index.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/index.js +1 -0
- package/v3/dist/domains/visual-accessibility/index.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/interfaces.d.ts +131 -0
- package/v3/dist/domains/visual-accessibility/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.d.ts +26 -0
- package/v3/dist/domains/visual-accessibility/plugin.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.js +151 -0
- package/v3/dist/domains/visual-accessibility/plugin.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts +42 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js +69 -0
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.d.ts +138 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.d.ts.map +1 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.js +830 -0
- package/v3/dist/domains/visual-accessibility/services/eu-compliance.js.map +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.d.ts +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/index.js +1 -0
- package/v3/dist/domains/visual-accessibility/services/index.js.map +1 -1
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts +84 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts.map +1 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.js +250 -0
- package/v3/dist/init/enhancements/claude-flow-adapter.js.map +1 -0
- package/v3/dist/init/enhancements/detector.d.ts +10 -0
- package/v3/dist/init/enhancements/detector.d.ts.map +1 -0
- package/v3/dist/init/enhancements/detector.js +87 -0
- package/v3/dist/init/enhancements/detector.js.map +1 -0
- package/v3/dist/init/enhancements/index.d.ts +13 -0
- package/v3/dist/init/enhancements/index.d.ts.map +1 -0
- package/v3/dist/init/enhancements/index.js +25 -0
- package/v3/dist/init/enhancements/index.js.map +1 -0
- package/v3/dist/init/enhancements/types.d.ts +93 -0
- package/v3/dist/init/enhancements/types.d.ts.map +1 -0
- package/v3/dist/init/enhancements/types.js +6 -0
- package/v3/dist/init/enhancements/types.js.map +1 -0
- package/v3/dist/init/index.d.ts +8 -0
- package/v3/dist/init/index.d.ts.map +1 -1
- package/v3/dist/init/index.js +4 -0
- package/v3/dist/init/index.js.map +1 -1
- package/v3/dist/init/migration/config-migrator.d.ts +31 -0
- package/v3/dist/init/migration/config-migrator.d.ts.map +1 -0
- package/v3/dist/init/migration/config-migrator.js +133 -0
- package/v3/dist/init/migration/config-migrator.js.map +1 -0
- package/v3/dist/init/migration/data-migrator.d.ts +72 -0
- package/v3/dist/init/migration/data-migrator.d.ts.map +1 -0
- package/v3/dist/init/migration/data-migrator.js +233 -0
- package/v3/dist/init/migration/data-migrator.js.map +1 -0
- package/v3/dist/init/migration/detector.d.ts +44 -0
- package/v3/dist/init/migration/detector.d.ts.map +1 -0
- package/v3/dist/init/migration/detector.js +106 -0
- package/v3/dist/init/migration/detector.js.map +1 -0
- package/v3/dist/init/migration/index.d.ts +8 -0
- package/v3/dist/init/migration/index.d.ts.map +1 -0
- package/v3/dist/init/migration/index.js +8 -0
- package/v3/dist/init/migration/index.js.map +1 -0
- package/v3/dist/init/orchestrator.d.ts +68 -0
- package/v3/dist/init/orchestrator.d.ts.map +1 -0
- package/v3/dist/init/orchestrator.js +239 -0
- package/v3/dist/init/orchestrator.js.map +1 -0
- package/v3/dist/init/phases/01-detection.d.ts +30 -0
- package/v3/dist/init/phases/01-detection.d.ts.map +1 -0
- package/v3/dist/init/phases/01-detection.js +143 -0
- package/v3/dist/init/phases/01-detection.js.map +1 -0
- package/v3/dist/init/phases/02-analysis.d.ts +18 -0
- package/v3/dist/init/phases/02-analysis.d.ts.map +1 -0
- package/v3/dist/init/phases/02-analysis.js +28 -0
- package/v3/dist/init/phases/02-analysis.js.map +1 -0
- package/v3/dist/init/phases/03-configuration.d.ts +26 -0
- package/v3/dist/init/phases/03-configuration.d.ts.map +1 -0
- package/v3/dist/init/phases/03-configuration.js +98 -0
- package/v3/dist/init/phases/03-configuration.js.map +1 -0
- package/v3/dist/init/phases/04-database.d.ts +22 -0
- package/v3/dist/init/phases/04-database.d.ts.map +1 -0
- package/v3/dist/init/phases/04-database.js +88 -0
- package/v3/dist/init/phases/04-database.js.map +1 -0
- package/v3/dist/init/phases/05-learning.d.ts +28 -0
- package/v3/dist/init/phases/05-learning.d.ts.map +1 -0
- package/v3/dist/init/phases/05-learning.js +98 -0
- package/v3/dist/init/phases/05-learning.js.map +1 -0
- package/v3/dist/init/phases/06-code-intelligence.d.ts +33 -0
- package/v3/dist/init/phases/06-code-intelligence.d.ts.map +1 -0
- package/v3/dist/init/phases/06-code-intelligence.js +115 -0
- package/v3/dist/init/phases/06-code-intelligence.js.map +1 -0
- package/v3/dist/init/phases/07-hooks.d.ts +27 -0
- package/v3/dist/init/phases/07-hooks.d.ts.map +1 -0
- package/v3/dist/init/phases/07-hooks.js +209 -0
- package/v3/dist/init/phases/07-hooks.js.map +1 -0
- package/v3/dist/init/phases/08-mcp.d.ts +22 -0
- package/v3/dist/init/phases/08-mcp.d.ts.map +1 -0
- package/v3/dist/init/phases/08-mcp.js +62 -0
- package/v3/dist/init/phases/08-mcp.js.map +1 -0
- package/v3/dist/init/phases/09-assets.d.ts +23 -0
- package/v3/dist/init/phases/09-assets.d.ts.map +1 -0
- package/v3/dist/init/phases/09-assets.js +82 -0
- package/v3/dist/init/phases/09-assets.js.map +1 -0
- package/v3/dist/init/phases/10-workers.d.ts +23 -0
- package/v3/dist/init/phases/10-workers.d.ts.map +1 -0
- package/v3/dist/init/phases/10-workers.js +111 -0
- package/v3/dist/init/phases/10-workers.js.map +1 -0
- package/v3/dist/init/phases/11-claude-md.d.ts +26 -0
- package/v3/dist/init/phases/11-claude-md.d.ts.map +1 -0
- package/v3/dist/init/phases/11-claude-md.js +121 -0
- package/v3/dist/init/phases/11-claude-md.js.map +1 -0
- package/v3/dist/init/phases/12-verification.d.ts +38 -0
- package/v3/dist/init/phases/12-verification.d.ts.map +1 -0
- package/v3/dist/init/phases/12-verification.js +187 -0
- package/v3/dist/init/phases/12-verification.js.map +1 -0
- package/v3/dist/init/phases/index.d.ts +46 -0
- package/v3/dist/init/phases/index.d.ts.map +1 -0
- package/v3/dist/init/phases/index.js +64 -0
- package/v3/dist/init/phases/index.js.map +1 -0
- package/v3/dist/init/phases/phase-interface.d.ts +193 -0
- package/v3/dist/init/phases/phase-interface.d.ts.map +1 -0
- package/v3/dist/init/phases/phase-interface.js +119 -0
- package/v3/dist/init/phases/phase-interface.js.map +1 -0
- package/v3/dist/integrations/coherence/coherence-service.d.ts +323 -0
- package/v3/dist/integrations/coherence/coherence-service.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/coherence-service.js +799 -0
- package/v3/dist/integrations/coherence/coherence-service.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.d.ts +170 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.js +403 -0
- package/v3/dist/integrations/coherence/engines/category-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.d.ts +159 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.js +348 -0
- package/v3/dist/integrations/coherence/engines/causal-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.d.ts +174 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.js +401 -0
- package/v3/dist/integrations/coherence/engines/cohomology-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.d.ts +201 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.js +324 -0
- package/v3/dist/integrations/coherence/engines/homotopy-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/index.d.ts +20 -0
- package/v3/dist/integrations/coherence/engines/index.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/index.js +26 -0
- package/v3/dist/integrations/coherence/engines/index.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.d.ts +193 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.js +476 -0
- package/v3/dist/integrations/coherence/engines/spectral-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.d.ts +175 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.js +377 -0
- package/v3/dist/integrations/coherence/engines/witness-adapter.js.map +1 -0
- package/v3/dist/integrations/coherence/index.d.ts +84 -0
- package/v3/dist/integrations/coherence/index.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/index.js +114 -0
- package/v3/dist/integrations/coherence/index.js.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts +396 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.js +538 -0
- package/v3/dist/integrations/coherence/threshold-tuner.js.map +1 -0
- package/v3/dist/integrations/coherence/types.d.ts +879 -0
- package/v3/dist/integrations/coherence/types.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/types.js +134 -0
- package/v3/dist/integrations/coherence/types.js.map +1 -0
- package/v3/dist/integrations/coherence/wasm-loader.d.ts +351 -0
- package/v3/dist/integrations/coherence/wasm-loader.d.ts.map +1 -0
- package/v3/dist/integrations/coherence/wasm-loader.js +842 -0
- package/v3/dist/integrations/coherence/wasm-loader.js.map +1 -0
- package/v3/dist/integrations/embeddings/index/HNSWIndex.d.ts.map +1 -1
- package/v3/dist/integrations/embeddings/index/HNSWIndex.js +4 -1
- package/v3/dist/integrations/embeddings/index/HNSWIndex.js.map +1 -1
- package/v3/dist/kernel/interfaces.d.ts +8 -1
- package/v3/dist/kernel/interfaces.d.ts.map +1 -1
- package/v3/dist/learning/aqe-learning-engine.d.ts +272 -0
- package/v3/dist/learning/aqe-learning-engine.d.ts.map +1 -0
- package/v3/dist/learning/aqe-learning-engine.js +708 -0
- package/v3/dist/learning/aqe-learning-engine.js.map +1 -0
- package/v3/dist/learning/causal-verifier.d.ts +244 -0
- package/v3/dist/learning/causal-verifier.d.ts.map +1 -0
- package/v3/dist/learning/causal-verifier.js +300 -0
- package/v3/dist/learning/causal-verifier.js.map +1 -0
- package/v3/dist/learning/experience-capture.d.ts +266 -0
- package/v3/dist/learning/experience-capture.d.ts.map +1 -0
- package/v3/dist/learning/experience-capture.js +647 -0
- package/v3/dist/learning/experience-capture.js.map +1 -0
- package/v3/dist/learning/index.d.ts +8 -0
- package/v3/dist/learning/index.d.ts.map +1 -1
- package/v3/dist/learning/index.js +16 -0
- package/v3/dist/learning/index.js.map +1 -1
- package/v3/dist/learning/memory-auditor.d.ts +235 -0
- package/v3/dist/learning/memory-auditor.d.ts.map +1 -0
- package/v3/dist/learning/memory-auditor.js +478 -0
- package/v3/dist/learning/memory-auditor.js.map +1 -0
- package/v3/dist/learning/pattern-store.d.ts.map +1 -1
- package/v3/dist/learning/pattern-store.js +27 -6
- package/v3/dist/learning/pattern-store.js.map +1 -1
- package/v3/dist/learning/qe-patterns.d.ts +15 -1
- package/v3/dist/learning/qe-patterns.d.ts.map +1 -1
- package/v3/dist/learning/qe-patterns.js +26 -5
- package/v3/dist/learning/qe-patterns.js.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.d.ts +38 -2
- package/v3/dist/learning/qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/qe-reasoning-bank.js +86 -4
- package/v3/dist/learning/qe-reasoning-bank.js.map +1 -1
- package/v3/dist/learning/real-qe-reasoning-bank.d.ts +32 -2
- package/v3/dist/learning/real-qe-reasoning-bank.d.ts.map +1 -1
- package/v3/dist/learning/real-qe-reasoning-bank.js +61 -6
- package/v3/dist/learning/real-qe-reasoning-bank.js.map +1 -1
- package/v3/dist/mcp/bundle.js +6303 -266
- package/v3/dist/mcp/tools/coherence/audit.d.ts +107 -0
- package/v3/dist/mcp/tools/coherence/audit.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/audit.js +236 -0
- package/v3/dist/mcp/tools/coherence/audit.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/check.d.ts +106 -0
- package/v3/dist/mcp/tools/coherence/check.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/check.js +205 -0
- package/v3/dist/mcp/tools/coherence/check.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/collapse.d.ts +123 -0
- package/v3/dist/mcp/tools/coherence/collapse.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/collapse.js +279 -0
- package/v3/dist/mcp/tools/coherence/collapse.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/consensus.d.ts +100 -0
- package/v3/dist/mcp/tools/coherence/consensus.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/consensus.js +201 -0
- package/v3/dist/mcp/tools/coherence/consensus.js.map +1 -0
- package/v3/dist/mcp/tools/coherence/index.d.ts +31 -0
- package/v3/dist/mcp/tools/coherence/index.d.ts.map +1 -0
- package/v3/dist/mcp/tools/coherence/index.js +42 -0
- package/v3/dist/mcp/tools/coherence/index.js.map +1 -0
- package/v3/dist/mcp/tools/index.d.ts +6 -1
- package/v3/dist/mcp/tools/index.d.ts.map +1 -1
- package/v3/dist/mcp/tools/index.js +9 -1
- package/v3/dist/mcp/tools/index.js.map +1 -1
- package/v3/dist/mcp/tools/mincut/index.d.ts +1 -1
- package/v3/dist/mcp/tools/mincut/index.d.ts.map +1 -1
- package/v3/dist/mcp/tools/mincut/index.js.map +1 -1
- package/v3/dist/mcp/tools/registry.d.ts +4 -0
- package/v3/dist/mcp/tools/registry.d.ts.map +1 -1
- package/v3/dist/mcp/tools/registry.js +5 -0
- package/v3/dist/mcp/tools/registry.js.map +1 -1
- package/v3/dist/mcp/types.d.ts +1 -1
- package/v3/dist/mcp/types.d.ts.map +1 -1
- package/v3/dist/strange-loop/belief-reconciler.d.ts +357 -0
- package/v3/dist/strange-loop/belief-reconciler.d.ts.map +1 -0
- package/v3/dist/strange-loop/belief-reconciler.js +696 -0
- package/v3/dist/strange-loop/belief-reconciler.js.map +1 -0
- package/v3/dist/strange-loop/index.d.ts +1 -0
- package/v3/dist/strange-loop/index.d.ts.map +1 -1
- package/v3/dist/strange-loop/index.js +2 -0
- package/v3/dist/strange-loop/index.js.map +1 -1
- package/v3/dist/strange-loop/strange-loop.d.ts +177 -5
- package/v3/dist/strange-loop/strange-loop.d.ts.map +1 -1
- package/v3/dist/strange-loop/strange-loop.js +452 -9
- package/v3/dist/strange-loop/strange-loop.js.map +1 -1
- package/v3/dist/strange-loop/types.d.ts +205 -1
- package/v3/dist/strange-loop/types.d.ts.map +1 -1
- package/v3/dist/strange-loop/types.js +5 -0
- package/v3/dist/strange-loop/types.js.map +1 -1
- package/v3/package.json +5 -1
|
@@ -0,0 +1,830 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - EU Compliance Service
|
|
3
|
+
*
|
|
4
|
+
* Implements EN 301 549 (European Standard for ICT Accessibility) mapping
|
|
5
|
+
* and EU Accessibility Act (Directive 2019/882) compliance validation.
|
|
6
|
+
*
|
|
7
|
+
* EN 301 549 V3.2.1 (2021-03) is the harmonized European standard that
|
|
8
|
+
* references WCAG 2.1 for web accessibility requirements.
|
|
9
|
+
*
|
|
10
|
+
* @module domains/visual-accessibility/services/eu-compliance
|
|
11
|
+
*/
|
|
12
|
+
import { ok, err } from '../../../shared/types/index.js';
|
|
13
|
+
/**
|
|
14
|
+
* EN 301 549 V3.2.1 Chapter 9 - Web content
|
|
15
|
+
* Maps WCAG 2.1 Level AA criteria to EN 301 549 clauses
|
|
16
|
+
*/
|
|
17
|
+
const EN_301_549_WEB_CLAUSES = [
|
|
18
|
+
// Chapter 9.1 - Perceivable
|
|
19
|
+
{
|
|
20
|
+
id: '9.1.1.1',
|
|
21
|
+
title: 'Non-text content',
|
|
22
|
+
chapter: '9.1.1',
|
|
23
|
+
wcagMapping: ['1.1.1'],
|
|
24
|
+
description: 'All non-text content that is presented to the user has a text alternative that serves the equivalent purpose.',
|
|
25
|
+
testMethod: 'automated',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: '9.1.2.1',
|
|
29
|
+
title: 'Audio-only and video-only (prerecorded)',
|
|
30
|
+
chapter: '9.1.2',
|
|
31
|
+
wcagMapping: ['1.2.1'],
|
|
32
|
+
description: 'For prerecorded audio-only and prerecorded video-only media, alternatives are provided.',
|
|
33
|
+
testMethod: 'manual',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: '9.1.2.2',
|
|
37
|
+
title: 'Captions (prerecorded)',
|
|
38
|
+
chapter: '9.1.2',
|
|
39
|
+
wcagMapping: ['1.2.2'],
|
|
40
|
+
description: 'Captions are provided for all prerecorded audio content in synchronized media.',
|
|
41
|
+
testMethod: 'hybrid',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: '9.1.2.3',
|
|
45
|
+
title: 'Audio description or media alternative (prerecorded)',
|
|
46
|
+
chapter: '9.1.2',
|
|
47
|
+
wcagMapping: ['1.2.3'],
|
|
48
|
+
description: 'An alternative for time-based media or audio description is provided.',
|
|
49
|
+
testMethod: 'manual',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: '9.1.2.5',
|
|
53
|
+
title: 'Audio description (prerecorded)',
|
|
54
|
+
chapter: '9.1.2',
|
|
55
|
+
wcagMapping: ['1.2.5'],
|
|
56
|
+
description: 'Audio description is provided for all prerecorded video content.',
|
|
57
|
+
testMethod: 'manual',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: '9.1.3.1',
|
|
61
|
+
title: 'Info and relationships',
|
|
62
|
+
chapter: '9.1.3',
|
|
63
|
+
wcagMapping: ['1.3.1'],
|
|
64
|
+
description: 'Information, structure, and relationships conveyed through presentation can be programmatically determined.',
|
|
65
|
+
testMethod: 'automated',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: '9.1.3.2',
|
|
69
|
+
title: 'Meaningful sequence',
|
|
70
|
+
chapter: '9.1.3',
|
|
71
|
+
wcagMapping: ['1.3.2'],
|
|
72
|
+
description: 'When the sequence affects meaning, a correct reading sequence can be programmatically determined.',
|
|
73
|
+
testMethod: 'hybrid',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: '9.1.3.3',
|
|
77
|
+
title: 'Sensory characteristics',
|
|
78
|
+
chapter: '9.1.3',
|
|
79
|
+
wcagMapping: ['1.3.3'],
|
|
80
|
+
description: 'Instructions do not rely solely on sensory characteristics.',
|
|
81
|
+
testMethod: 'manual',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: '9.1.3.4',
|
|
85
|
+
title: 'Orientation',
|
|
86
|
+
chapter: '9.1.3',
|
|
87
|
+
wcagMapping: ['1.3.4'],
|
|
88
|
+
description: 'Content does not restrict its view and operation to a single display orientation.',
|
|
89
|
+
testMethod: 'hybrid',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: '9.1.3.5',
|
|
93
|
+
title: 'Identify input purpose',
|
|
94
|
+
chapter: '9.1.3',
|
|
95
|
+
wcagMapping: ['1.3.5'],
|
|
96
|
+
description: 'The purpose of each input field collecting user information can be programmatically determined.',
|
|
97
|
+
testMethod: 'automated',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: '9.1.4.1',
|
|
101
|
+
title: 'Use of colour',
|
|
102
|
+
chapter: '9.1.4',
|
|
103
|
+
wcagMapping: ['1.4.1'],
|
|
104
|
+
description: 'Colour is not used as the only visual means of conveying information.',
|
|
105
|
+
testMethod: 'manual',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
id: '9.1.4.2',
|
|
109
|
+
title: 'Audio control',
|
|
110
|
+
chapter: '9.1.4',
|
|
111
|
+
wcagMapping: ['1.4.2'],
|
|
112
|
+
description: 'A mechanism is available to pause or stop audio that plays automatically.',
|
|
113
|
+
testMethod: 'manual',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
id: '9.1.4.3',
|
|
117
|
+
title: 'Contrast (minimum)',
|
|
118
|
+
chapter: '9.1.4',
|
|
119
|
+
wcagMapping: ['1.4.3'],
|
|
120
|
+
description: 'Visual presentation of text has a contrast ratio of at least 4.5:1.',
|
|
121
|
+
testMethod: 'automated',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: '9.1.4.4',
|
|
125
|
+
title: 'Resize text',
|
|
126
|
+
chapter: '9.1.4',
|
|
127
|
+
wcagMapping: ['1.4.4'],
|
|
128
|
+
description: 'Text can be resized without assistive technology up to 200 percent.',
|
|
129
|
+
testMethod: 'hybrid',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
id: '9.1.4.5',
|
|
133
|
+
title: 'Images of text',
|
|
134
|
+
chapter: '9.1.4',
|
|
135
|
+
wcagMapping: ['1.4.5'],
|
|
136
|
+
description: 'Text is used to convey information rather than images of text.',
|
|
137
|
+
testMethod: 'hybrid',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: '9.1.4.10',
|
|
141
|
+
title: 'Reflow',
|
|
142
|
+
chapter: '9.1.4',
|
|
143
|
+
wcagMapping: ['1.4.10'],
|
|
144
|
+
description: 'Content can be presented without loss of information or functionality at 320 CSS pixels.',
|
|
145
|
+
testMethod: 'hybrid',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
id: '9.1.4.11',
|
|
149
|
+
title: 'Non-text contrast',
|
|
150
|
+
chapter: '9.1.4',
|
|
151
|
+
wcagMapping: ['1.4.11'],
|
|
152
|
+
description: 'Visual presentation of UI components and graphical objects has a contrast ratio of at least 3:1.',
|
|
153
|
+
testMethod: 'automated',
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
id: '9.1.4.12',
|
|
157
|
+
title: 'Text spacing',
|
|
158
|
+
chapter: '9.1.4',
|
|
159
|
+
wcagMapping: ['1.4.12'],
|
|
160
|
+
description: 'No loss of content or functionality occurs when text spacing is adjusted.',
|
|
161
|
+
testMethod: 'hybrid',
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: '9.1.4.13',
|
|
165
|
+
title: 'Content on hover or focus',
|
|
166
|
+
chapter: '9.1.4',
|
|
167
|
+
wcagMapping: ['1.4.13'],
|
|
168
|
+
description: 'Additional content triggered by hover or focus is dismissible, hoverable, and persistent.',
|
|
169
|
+
testMethod: 'manual',
|
|
170
|
+
},
|
|
171
|
+
// Chapter 9.2 - Operable
|
|
172
|
+
{
|
|
173
|
+
id: '9.2.1.1',
|
|
174
|
+
title: 'Keyboard',
|
|
175
|
+
chapter: '9.2.1',
|
|
176
|
+
wcagMapping: ['2.1.1'],
|
|
177
|
+
description: 'All functionality is operable through a keyboard interface.',
|
|
178
|
+
testMethod: 'hybrid',
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: '9.2.1.2',
|
|
182
|
+
title: 'No keyboard trap',
|
|
183
|
+
chapter: '9.2.1',
|
|
184
|
+
wcagMapping: ['2.1.2'],
|
|
185
|
+
description: 'Keyboard focus can be moved away from any component using only a keyboard.',
|
|
186
|
+
testMethod: 'hybrid',
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: '9.2.1.4',
|
|
190
|
+
title: 'Character key shortcuts',
|
|
191
|
+
chapter: '9.2.1',
|
|
192
|
+
wcagMapping: ['2.1.4'],
|
|
193
|
+
description: 'Keyboard shortcuts using only letter, punctuation, number, or symbol characters can be turned off or remapped.',
|
|
194
|
+
testMethod: 'manual',
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
id: '9.2.2.1',
|
|
198
|
+
title: 'Timing adjustable',
|
|
199
|
+
chapter: '9.2.2',
|
|
200
|
+
wcagMapping: ['2.2.1'],
|
|
201
|
+
description: 'Users can turn off, adjust, or extend time limits.',
|
|
202
|
+
testMethod: 'manual',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
id: '9.2.2.2',
|
|
206
|
+
title: 'Pause, stop, hide',
|
|
207
|
+
chapter: '9.2.2',
|
|
208
|
+
wcagMapping: ['2.2.2'],
|
|
209
|
+
description: 'Moving, blinking, scrolling, or auto-updating information can be paused, stopped, or hidden.',
|
|
210
|
+
testMethod: 'manual',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
id: '9.2.3.1',
|
|
214
|
+
title: 'Three flashes or below threshold',
|
|
215
|
+
chapter: '9.2.3',
|
|
216
|
+
wcagMapping: ['2.3.1'],
|
|
217
|
+
description: 'Web pages do not contain anything that flashes more than three times in any one second period.',
|
|
218
|
+
testMethod: 'automated',
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
id: '9.2.4.1',
|
|
222
|
+
title: 'Bypass blocks',
|
|
223
|
+
chapter: '9.2.4',
|
|
224
|
+
wcagMapping: ['2.4.1'],
|
|
225
|
+
description: 'A mechanism is available to bypass blocks of content that are repeated on multiple web pages.',
|
|
226
|
+
testMethod: 'hybrid',
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
id: '9.2.4.2',
|
|
230
|
+
title: 'Page titled',
|
|
231
|
+
chapter: '9.2.4',
|
|
232
|
+
wcagMapping: ['2.4.2'],
|
|
233
|
+
description: 'Web pages have titles that describe topic or purpose.',
|
|
234
|
+
testMethod: 'automated',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
id: '9.2.4.3',
|
|
238
|
+
title: 'Focus order',
|
|
239
|
+
chapter: '9.2.4',
|
|
240
|
+
wcagMapping: ['2.4.3'],
|
|
241
|
+
description: 'Focusable components receive focus in an order that preserves meaning and operability.',
|
|
242
|
+
testMethod: 'hybrid',
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
id: '9.2.4.4',
|
|
246
|
+
title: 'Link purpose (in context)',
|
|
247
|
+
chapter: '9.2.4',
|
|
248
|
+
wcagMapping: ['2.4.4'],
|
|
249
|
+
description: 'The purpose of each link can be determined from the link text or its context.',
|
|
250
|
+
testMethod: 'hybrid',
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
id: '9.2.4.5',
|
|
254
|
+
title: 'Multiple ways',
|
|
255
|
+
chapter: '9.2.4',
|
|
256
|
+
wcagMapping: ['2.4.5'],
|
|
257
|
+
description: 'More than one way is available to locate a web page within a set of web pages.',
|
|
258
|
+
testMethod: 'manual',
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
id: '9.2.4.6',
|
|
262
|
+
title: 'Headings and labels',
|
|
263
|
+
chapter: '9.2.4',
|
|
264
|
+
wcagMapping: ['2.4.6'],
|
|
265
|
+
description: 'Headings and labels describe topic or purpose.',
|
|
266
|
+
testMethod: 'hybrid',
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
id: '9.2.4.7',
|
|
270
|
+
title: 'Focus visible',
|
|
271
|
+
chapter: '9.2.4',
|
|
272
|
+
wcagMapping: ['2.4.7'],
|
|
273
|
+
description: 'Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.',
|
|
274
|
+
testMethod: 'hybrid',
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
id: '9.2.5.1',
|
|
278
|
+
title: 'Pointer gestures',
|
|
279
|
+
chapter: '9.2.5',
|
|
280
|
+
wcagMapping: ['2.5.1'],
|
|
281
|
+
description: 'All functionality that uses multipoint or path-based gestures can be operated with a single pointer.',
|
|
282
|
+
testMethod: 'manual',
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
id: '9.2.5.2',
|
|
286
|
+
title: 'Pointer cancellation',
|
|
287
|
+
chapter: '9.2.5',
|
|
288
|
+
wcagMapping: ['2.5.2'],
|
|
289
|
+
description: 'Functions triggered by single pointer can be cancelled.',
|
|
290
|
+
testMethod: 'manual',
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
id: '9.2.5.3',
|
|
294
|
+
title: 'Label in name',
|
|
295
|
+
chapter: '9.2.5',
|
|
296
|
+
wcagMapping: ['2.5.3'],
|
|
297
|
+
description: 'User interface components with visible labels have accessible names that include the visible text.',
|
|
298
|
+
testMethod: 'automated',
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
id: '9.2.5.4',
|
|
302
|
+
title: 'Motion actuation',
|
|
303
|
+
chapter: '9.2.5',
|
|
304
|
+
wcagMapping: ['2.5.4'],
|
|
305
|
+
description: 'Functionality operated by device motion can be operated by user interface components.',
|
|
306
|
+
testMethod: 'manual',
|
|
307
|
+
},
|
|
308
|
+
// Chapter 9.3 - Understandable
|
|
309
|
+
{
|
|
310
|
+
id: '9.3.1.1',
|
|
311
|
+
title: 'Language of page',
|
|
312
|
+
chapter: '9.3.1',
|
|
313
|
+
wcagMapping: ['3.1.1'],
|
|
314
|
+
description: 'The default human language of each web page can be programmatically determined.',
|
|
315
|
+
testMethod: 'automated',
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
id: '9.3.1.2',
|
|
319
|
+
title: 'Language of parts',
|
|
320
|
+
chapter: '9.3.1',
|
|
321
|
+
wcagMapping: ['3.1.2'],
|
|
322
|
+
description: 'The human language of each passage or phrase can be programmatically determined.',
|
|
323
|
+
testMethod: 'hybrid',
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
id: '9.3.2.1',
|
|
327
|
+
title: 'On focus',
|
|
328
|
+
chapter: '9.3.2',
|
|
329
|
+
wcagMapping: ['3.2.1'],
|
|
330
|
+
description: 'Receiving focus does not initiate a change of context.',
|
|
331
|
+
testMethod: 'hybrid',
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
id: '9.3.2.2',
|
|
335
|
+
title: 'On input',
|
|
336
|
+
chapter: '9.3.2',
|
|
337
|
+
wcagMapping: ['3.2.2'],
|
|
338
|
+
description: 'Changing the setting of a user interface component does not automatically cause a change of context.',
|
|
339
|
+
testMethod: 'hybrid',
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
id: '9.3.2.3',
|
|
343
|
+
title: 'Consistent navigation',
|
|
344
|
+
chapter: '9.3.2',
|
|
345
|
+
wcagMapping: ['3.2.3'],
|
|
346
|
+
description: 'Navigational mechanisms that are repeated are in the same relative order.',
|
|
347
|
+
testMethod: 'manual',
|
|
348
|
+
},
|
|
349
|
+
{
|
|
350
|
+
id: '9.3.2.4',
|
|
351
|
+
title: 'Consistent identification',
|
|
352
|
+
chapter: '9.3.2',
|
|
353
|
+
wcagMapping: ['3.2.4'],
|
|
354
|
+
description: 'Components with the same functionality are identified consistently.',
|
|
355
|
+
testMethod: 'manual',
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
id: '9.3.3.1',
|
|
359
|
+
title: 'Error identification',
|
|
360
|
+
chapter: '9.3.3',
|
|
361
|
+
wcagMapping: ['3.3.1'],
|
|
362
|
+
description: 'If an input error is detected, the item in error is identified and described to the user.',
|
|
363
|
+
testMethod: 'hybrid',
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
id: '9.3.3.2',
|
|
367
|
+
title: 'Labels or instructions',
|
|
368
|
+
chapter: '9.3.3',
|
|
369
|
+
wcagMapping: ['3.3.2'],
|
|
370
|
+
description: 'Labels or instructions are provided when content requires user input.',
|
|
371
|
+
testMethod: 'hybrid',
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
id: '9.3.3.3',
|
|
375
|
+
title: 'Error suggestion',
|
|
376
|
+
chapter: '9.3.3',
|
|
377
|
+
wcagMapping: ['3.3.3'],
|
|
378
|
+
description: 'If an input error is detected and suggestions for correction are known, the suggestions are provided.',
|
|
379
|
+
testMethod: 'hybrid',
|
|
380
|
+
},
|
|
381
|
+
{
|
|
382
|
+
id: '9.3.3.4',
|
|
383
|
+
title: 'Error prevention (legal, financial, data)',
|
|
384
|
+
chapter: '9.3.3',
|
|
385
|
+
wcagMapping: ['3.3.4'],
|
|
386
|
+
description: 'Submissions are reversible, checked, or confirmed for legal, financial, or data-deletion actions.',
|
|
387
|
+
testMethod: 'manual',
|
|
388
|
+
},
|
|
389
|
+
// Chapter 9.4 - Robust
|
|
390
|
+
{
|
|
391
|
+
id: '9.4.1.1',
|
|
392
|
+
title: 'Parsing',
|
|
393
|
+
chapter: '9.4.1',
|
|
394
|
+
wcagMapping: ['4.1.1'],
|
|
395
|
+
description: 'In content implemented using markup languages, elements have complete start and end tags.',
|
|
396
|
+
testMethod: 'automated',
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
id: '9.4.1.2',
|
|
400
|
+
title: 'Name, role, value',
|
|
401
|
+
chapter: '9.4.1',
|
|
402
|
+
wcagMapping: ['4.1.2'],
|
|
403
|
+
description: 'User interface components have name and role programmatically determined.',
|
|
404
|
+
testMethod: 'automated',
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
id: '9.4.1.3',
|
|
408
|
+
title: 'Status messages',
|
|
409
|
+
chapter: '9.4.1',
|
|
410
|
+
wcagMapping: ['4.1.3'],
|
|
411
|
+
description: 'Status messages can be programmatically determined without receiving focus.',
|
|
412
|
+
testMethod: 'hybrid',
|
|
413
|
+
},
|
|
414
|
+
];
|
|
415
|
+
/**
|
|
416
|
+
* EU Accessibility Act requirements for web services (e-commerce)
|
|
417
|
+
*/
|
|
418
|
+
const EAA_WEB_REQUIREMENTS = [
|
|
419
|
+
{
|
|
420
|
+
id: 'EAA-I.1',
|
|
421
|
+
title: 'Perceivable information',
|
|
422
|
+
article: 'Annex I, Section I',
|
|
423
|
+
description: 'Information shall be perceivable through more than one sensory channel.',
|
|
424
|
+
applicableTo: ['e-commerce', 'banking-services', 'transport-services'],
|
|
425
|
+
en301549Mapping: ['9.1.1.1', '9.1.2.1', '9.1.2.2', '9.1.3.1'],
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
id: 'EAA-I.2',
|
|
429
|
+
title: 'Operable user interface',
|
|
430
|
+
article: 'Annex I, Section I',
|
|
431
|
+
description: 'User interface shall be operable through multiple input modalities.',
|
|
432
|
+
applicableTo: ['e-commerce', 'banking-services', 'transport-services', 'e-books'],
|
|
433
|
+
en301549Mapping: ['9.2.1.1', '9.2.1.2', '9.2.4.1', '9.2.4.3'],
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
id: 'EAA-I.3',
|
|
437
|
+
title: 'Understandable operation',
|
|
438
|
+
article: 'Annex I, Section I',
|
|
439
|
+
description: 'Operation of the product and its user interface shall be understandable.',
|
|
440
|
+
applicableTo: ['e-commerce', 'banking-services', 'transport-services'],
|
|
441
|
+
en301549Mapping: ['9.3.1.1', '9.3.2.1', '9.3.3.1', '9.3.3.2'],
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
id: 'EAA-I.4',
|
|
445
|
+
title: 'Robust content',
|
|
446
|
+
article: 'Annex I, Section I',
|
|
447
|
+
description: 'Content shall be robust enough to be interpreted by assistive technologies.',
|
|
448
|
+
applicableTo: ['e-commerce', 'banking-services', 'transport-services', 'e-books', 'audiovisual-media'],
|
|
449
|
+
en301549Mapping: ['9.4.1.1', '9.4.1.2', '9.4.1.3'],
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
id: 'EAA-II.1',
|
|
453
|
+
title: 'Accessible support services',
|
|
454
|
+
article: 'Annex I, Section II',
|
|
455
|
+
description: 'Support services shall provide information on accessibility features.',
|
|
456
|
+
applicableTo: ['e-commerce', 'banking-services', 'transport-services'],
|
|
457
|
+
en301549Mapping: [],
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
id: 'EAA-III.1',
|
|
461
|
+
title: 'Electronic identification',
|
|
462
|
+
article: 'Annex I, Section III',
|
|
463
|
+
description: 'Electronic identification and authentication shall be accessible.',
|
|
464
|
+
applicableTo: ['banking-services', 'e-commerce'],
|
|
465
|
+
en301549Mapping: ['9.2.1.1', '9.3.3.1', '9.3.3.2'],
|
|
466
|
+
},
|
|
467
|
+
];
|
|
468
|
+
/**
|
|
469
|
+
* WCAG to EN 301 549 mapping table
|
|
470
|
+
*/
|
|
471
|
+
const WCAG_TO_EN301549_MAP = EN_301_549_WEB_CLAUSES.flatMap((clause) => clause.wcagMapping.map((wcag) => ({
|
|
472
|
+
wcagCriterion: wcag,
|
|
473
|
+
wcagLevel: getWCAGLevel(wcag),
|
|
474
|
+
en301549Clause: clause.id,
|
|
475
|
+
en301549Chapter: clause.chapter,
|
|
476
|
+
conformanceLevel: 'required',
|
|
477
|
+
})));
|
|
478
|
+
/**
|
|
479
|
+
* Get WCAG level from criterion ID
|
|
480
|
+
*/
|
|
481
|
+
function getWCAGLevel(criterionId) {
|
|
482
|
+
// WCAG 2.1 Level A criteria
|
|
483
|
+
const levelA = [
|
|
484
|
+
'1.1.1', '1.2.1', '1.2.2', '1.2.3', '1.3.1', '1.3.2', '1.3.3',
|
|
485
|
+
'1.4.1', '1.4.2', '2.1.1', '2.1.2', '2.1.4', '2.2.1', '2.2.2',
|
|
486
|
+
'2.3.1', '2.4.1', '2.4.2', '2.4.3', '2.4.4', '2.5.1', '2.5.2',
|
|
487
|
+
'2.5.3', '2.5.4', '3.1.1', '3.2.1', '3.2.2', '3.3.1', '3.3.2',
|
|
488
|
+
'4.1.1', '4.1.2',
|
|
489
|
+
];
|
|
490
|
+
// WCAG 2.1 Level AA criteria
|
|
491
|
+
const levelAA = [
|
|
492
|
+
'1.2.4', '1.2.5', '1.3.4', '1.3.5', '1.4.3', '1.4.4', '1.4.5',
|
|
493
|
+
'1.4.10', '1.4.11', '1.4.12', '1.4.13', '2.4.5', '2.4.6', '2.4.7',
|
|
494
|
+
'3.1.2', '3.2.3', '3.2.4', '3.3.3', '3.3.4', '4.1.3',
|
|
495
|
+
];
|
|
496
|
+
if (levelA.includes(criterionId))
|
|
497
|
+
return 'A';
|
|
498
|
+
if (levelAA.includes(criterionId))
|
|
499
|
+
return 'AA';
|
|
500
|
+
return 'AAA';
|
|
501
|
+
}
|
|
502
|
+
const DEFAULT_CONFIG = {
|
|
503
|
+
en301549Version: '3.2.1',
|
|
504
|
+
includeEAA: true,
|
|
505
|
+
defaultProductCategory: 'e-commerce',
|
|
506
|
+
cacheTTL: 3600,
|
|
507
|
+
};
|
|
508
|
+
/**
|
|
509
|
+
* EU Compliance Service
|
|
510
|
+
*
|
|
511
|
+
* Provides EN 301 549 and EU Accessibility Act compliance validation
|
|
512
|
+
* by mapping WCAG audit results to European accessibility standards.
|
|
513
|
+
*
|
|
514
|
+
* @example
|
|
515
|
+
* ```typescript
|
|
516
|
+
* const service = new EUComplianceService(memory);
|
|
517
|
+
* const report = await service.validateCompliance(wcagReport, {
|
|
518
|
+
* includeEAA: true,
|
|
519
|
+
* productCategory: 'e-commerce',
|
|
520
|
+
* });
|
|
521
|
+
* ```
|
|
522
|
+
*/
|
|
523
|
+
export class EUComplianceService {
|
|
524
|
+
memory;
|
|
525
|
+
config;
|
|
526
|
+
constructor(memory, config = {}) {
|
|
527
|
+
this.memory = memory;
|
|
528
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Validate EU compliance based on WCAG audit results
|
|
532
|
+
*
|
|
533
|
+
* @param wcagReport - WCAG accessibility report
|
|
534
|
+
* @param options - EU compliance options
|
|
535
|
+
* @returns Full EU compliance report
|
|
536
|
+
*/
|
|
537
|
+
async validateCompliance(wcagReport, options) {
|
|
538
|
+
try {
|
|
539
|
+
const en301549Version = options?.en301549Version ?? this.config.en301549Version;
|
|
540
|
+
const includeEAA = options?.includeEAA ?? this.config.includeEAA;
|
|
541
|
+
const productCategory = options?.productCategory ?? this.config.defaultProductCategory;
|
|
542
|
+
const excludeClauses = options?.excludeClauses ?? [];
|
|
543
|
+
// Validate EN 301 549 compliance
|
|
544
|
+
const en301549Result = this.validateEN301549(wcagReport, en301549Version, excludeClauses);
|
|
545
|
+
// Validate EAA compliance if requested
|
|
546
|
+
let eaaCompliance;
|
|
547
|
+
if (includeEAA) {
|
|
548
|
+
eaaCompliance = this.validateEAA(en301549Result, productCategory);
|
|
549
|
+
}
|
|
550
|
+
// Calculate overall status
|
|
551
|
+
const overallStatus = this.calculateOverallStatus(en301549Result, eaaCompliance);
|
|
552
|
+
const complianceScore = en301549Result.score;
|
|
553
|
+
const certificationReady = en301549Result.passed && (!eaaCompliance || eaaCompliance.passed);
|
|
554
|
+
const report = {
|
|
555
|
+
url: wcagReport.url,
|
|
556
|
+
timestamp: new Date(),
|
|
557
|
+
en301549: en301549Result,
|
|
558
|
+
eaaCompliance,
|
|
559
|
+
overallStatus,
|
|
560
|
+
complianceScore,
|
|
561
|
+
certificationReady,
|
|
562
|
+
nextReviewDate: this.calculateNextReviewDate(),
|
|
563
|
+
};
|
|
564
|
+
// Cache the report
|
|
565
|
+
await this.cacheReport(report);
|
|
566
|
+
return ok(report);
|
|
567
|
+
}
|
|
568
|
+
catch (error) {
|
|
569
|
+
return err(error instanceof Error ? error : new Error(String(error)));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Validate EN 301 549 compliance
|
|
574
|
+
*/
|
|
575
|
+
validateEN301549(wcagReport, version, excludeClauses) {
|
|
576
|
+
const failedClauses = [];
|
|
577
|
+
const passedClauses = [];
|
|
578
|
+
const partialClauses = [];
|
|
579
|
+
// Build violation map by WCAG criterion
|
|
580
|
+
const violationsByWCAG = new Map();
|
|
581
|
+
for (const violation of wcagReport.violations) {
|
|
582
|
+
for (const criterion of violation.wcagCriteria) {
|
|
583
|
+
const existing = violationsByWCAG.get(criterion.id) ?? [];
|
|
584
|
+
existing.push(violation);
|
|
585
|
+
violationsByWCAG.set(criterion.id, existing);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
// Evaluate each EN 301 549 clause
|
|
589
|
+
for (const clause of EN_301_549_WEB_CLAUSES) {
|
|
590
|
+
if (excludeClauses.includes(clause.id)) {
|
|
591
|
+
continue;
|
|
592
|
+
}
|
|
593
|
+
const clauseViolations = [];
|
|
594
|
+
let hasViolations = false;
|
|
595
|
+
// Check violations for mapped WCAG criteria
|
|
596
|
+
for (const wcagId of clause.wcagMapping) {
|
|
597
|
+
const violations = violationsByWCAG.get(wcagId);
|
|
598
|
+
if (violations && violations.length > 0) {
|
|
599
|
+
clauseViolations.push(...violations);
|
|
600
|
+
hasViolations = true;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const result = {
|
|
604
|
+
clause,
|
|
605
|
+
status: hasViolations ? 'failed' : 'passed',
|
|
606
|
+
violations: clauseViolations,
|
|
607
|
+
};
|
|
608
|
+
if (hasViolations) {
|
|
609
|
+
// Check if partial (some criteria passed)
|
|
610
|
+
const totalCriteria = clause.wcagMapping.length;
|
|
611
|
+
const failedCriteria = clause.wcagMapping.filter((wcag) => violationsByWCAG.has(wcag)).length;
|
|
612
|
+
if (failedCriteria < totalCriteria && totalCriteria > 1) {
|
|
613
|
+
// Partial: some criteria failed but not all
|
|
614
|
+
partialClauses.push({ ...result, status: 'partial' });
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
// Failed: all criteria failed (or single criterion failed)
|
|
618
|
+
failedClauses.push(result);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
passedClauses.push(result);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
// Calculate score
|
|
626
|
+
const totalClauses = failedClauses.length + passedClauses.length + partialClauses.length;
|
|
627
|
+
const passedWeight = passedClauses.length + partialClauses.length * 0.5;
|
|
628
|
+
const score = totalClauses > 0 ? Math.round((passedWeight / totalClauses) * 100) : 100;
|
|
629
|
+
// Generate recommendations
|
|
630
|
+
const recommendations = this.generateRecommendations(failedClauses, partialClauses);
|
|
631
|
+
return {
|
|
632
|
+
standard: 'EN301549',
|
|
633
|
+
version,
|
|
634
|
+
passed: failedClauses.length === 0,
|
|
635
|
+
score,
|
|
636
|
+
failedClauses,
|
|
637
|
+
passedClauses,
|
|
638
|
+
partialClauses,
|
|
639
|
+
wcagMapping: WCAG_TO_EN301549_MAP,
|
|
640
|
+
recommendations,
|
|
641
|
+
};
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Validate EU Accessibility Act compliance
|
|
645
|
+
*/
|
|
646
|
+
validateEAA(en301549Result, productCategory) {
|
|
647
|
+
// Filter requirements applicable to the product category
|
|
648
|
+
const applicableRequirements = EAA_WEB_REQUIREMENTS.filter((req) => req.applicableTo.includes(productCategory));
|
|
649
|
+
const failedRequirements = [];
|
|
650
|
+
// Check each requirement against EN 301 549 results
|
|
651
|
+
for (const requirement of applicableRequirements) {
|
|
652
|
+
// A requirement fails if any of its mapped EN 301 549 clauses failed
|
|
653
|
+
const failedMappings = requirement.en301549Mapping.filter((clauseId) => en301549Result.failedClauses.some((fc) => fc.clause.id === clauseId));
|
|
654
|
+
if (failedMappings.length > 0) {
|
|
655
|
+
failedRequirements.push({
|
|
656
|
+
requirement,
|
|
657
|
+
status: failedMappings.length === requirement.en301549Mapping.length ? 'not-met' : 'partially-met',
|
|
658
|
+
evidence: `Failed EN 301 549 clauses: ${failedMappings.join(', ')}`,
|
|
659
|
+
remediationRequired: true,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return {
|
|
664
|
+
productCategory,
|
|
665
|
+
passed: failedRequirements.length === 0,
|
|
666
|
+
applicableRequirements,
|
|
667
|
+
failedRequirements,
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Generate remediation recommendations
|
|
672
|
+
*/
|
|
673
|
+
generateRecommendations(failedClauses, partialClauses) {
|
|
674
|
+
const recommendations = [];
|
|
675
|
+
// Prioritize by impact and test method
|
|
676
|
+
const prioritizedClauses = [...failedClauses, ...partialClauses].sort((a, b) => {
|
|
677
|
+
// Automated tests first (easier to fix)
|
|
678
|
+
if (a.clause.testMethod !== b.clause.testMethod) {
|
|
679
|
+
return a.clause.testMethod === 'automated' ? -1 : 1;
|
|
680
|
+
}
|
|
681
|
+
// Then by number of violations
|
|
682
|
+
return b.violations.length - a.violations.length;
|
|
683
|
+
});
|
|
684
|
+
for (const clauseResult of prioritizedClauses) {
|
|
685
|
+
const priority = this.calculatePriority(clauseResult);
|
|
686
|
+
const effort = this.estimateEffort(clauseResult);
|
|
687
|
+
recommendations.push({
|
|
688
|
+
priority,
|
|
689
|
+
clause: clauseResult.clause.id,
|
|
690
|
+
description: `${clauseResult.clause.title}: ${clauseResult.clause.description}`,
|
|
691
|
+
remediation: this.generateRemediationText(clauseResult),
|
|
692
|
+
estimatedEffort: effort,
|
|
693
|
+
deadline: priority === 'high' ? this.getDeadline(30) : undefined,
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
return recommendations.slice(0, 10); // Top 10 recommendations
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Calculate priority for a failed clause
|
|
700
|
+
*/
|
|
701
|
+
calculatePriority(clauseResult) {
|
|
702
|
+
// Check if any violations are critical or serious
|
|
703
|
+
const hasCritical = clauseResult.violations.some((v) => v.impact === 'critical');
|
|
704
|
+
const hasSerious = clauseResult.violations.some((v) => v.impact === 'serious');
|
|
705
|
+
if (hasCritical)
|
|
706
|
+
return 'high';
|
|
707
|
+
if (hasSerious)
|
|
708
|
+
return 'medium';
|
|
709
|
+
return 'low';
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Estimate remediation effort
|
|
713
|
+
*/
|
|
714
|
+
estimateEffort(clauseResult) {
|
|
715
|
+
const violationCount = clauseResult.violations.length;
|
|
716
|
+
const testMethod = clauseResult.clause.testMethod;
|
|
717
|
+
// Automated tests are typically easier to fix
|
|
718
|
+
if (testMethod === 'automated') {
|
|
719
|
+
if (violationCount <= 3)
|
|
720
|
+
return 'trivial';
|
|
721
|
+
if (violationCount <= 10)
|
|
722
|
+
return 'minor';
|
|
723
|
+
return 'moderate';
|
|
724
|
+
}
|
|
725
|
+
// Manual/hybrid tests require more effort
|
|
726
|
+
if (violationCount <= 2)
|
|
727
|
+
return 'minor';
|
|
728
|
+
if (violationCount <= 5)
|
|
729
|
+
return 'moderate';
|
|
730
|
+
return 'major';
|
|
731
|
+
}
|
|
732
|
+
/**
|
|
733
|
+
* Generate remediation text for a clause
|
|
734
|
+
*/
|
|
735
|
+
generateRemediationText(clauseResult) {
|
|
736
|
+
const wcagIds = clauseResult.clause.wcagMapping.join(', ');
|
|
737
|
+
const violationCount = clauseResult.violations.length;
|
|
738
|
+
return (`Fix ${violationCount} violation(s) related to WCAG ${wcagIds}. ` +
|
|
739
|
+
`Refer to EN 301 549 clause ${clauseResult.clause.id} (${clauseResult.clause.title}) ` +
|
|
740
|
+
`for detailed requirements. Test method: ${clauseResult.clause.testMethod}.`);
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Calculate overall compliance status
|
|
744
|
+
*/
|
|
745
|
+
calculateOverallStatus(en301549Result, eaaCompliance) {
|
|
746
|
+
if (!en301549Result.passed) {
|
|
747
|
+
// Check if mostly compliant (score >= 80)
|
|
748
|
+
if (en301549Result.score >= 80) {
|
|
749
|
+
return 'partially-compliant';
|
|
750
|
+
}
|
|
751
|
+
return 'non-compliant';
|
|
752
|
+
}
|
|
753
|
+
if (eaaCompliance && !eaaCompliance.passed) {
|
|
754
|
+
return 'partially-compliant';
|
|
755
|
+
}
|
|
756
|
+
return 'compliant';
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Calculate next review date (annual review recommended)
|
|
760
|
+
*/
|
|
761
|
+
calculateNextReviewDate() {
|
|
762
|
+
const nextYear = new Date();
|
|
763
|
+
nextYear.setFullYear(nextYear.getFullYear() + 1);
|
|
764
|
+
return nextYear;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Get deadline date
|
|
768
|
+
*/
|
|
769
|
+
getDeadline(days) {
|
|
770
|
+
const deadline = new Date();
|
|
771
|
+
deadline.setDate(deadline.getDate() + days);
|
|
772
|
+
return deadline;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Cache compliance report
|
|
776
|
+
*/
|
|
777
|
+
async cacheReport(report) {
|
|
778
|
+
const cacheKey = `eu-compliance:${this.hashUrl(report.url)}`;
|
|
779
|
+
await this.memory.set(cacheKey, report, {
|
|
780
|
+
namespace: 'visual-accessibility',
|
|
781
|
+
ttl: this.config.cacheTTL,
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Get cached compliance report
|
|
786
|
+
*/
|
|
787
|
+
async getCachedReport(url) {
|
|
788
|
+
const cacheKey = `eu-compliance:${this.hashUrl(url)}`;
|
|
789
|
+
const cached = await this.memory.get(cacheKey);
|
|
790
|
+
return cached ?? null;
|
|
791
|
+
}
|
|
792
|
+
/**
|
|
793
|
+
* Get all EN 301 549 clauses
|
|
794
|
+
*/
|
|
795
|
+
getEN301549Clauses() {
|
|
796
|
+
return [...EN_301_549_WEB_CLAUSES];
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Get all EAA requirements
|
|
800
|
+
*/
|
|
801
|
+
getEAARequirements() {
|
|
802
|
+
return [...EAA_WEB_REQUIREMENTS];
|
|
803
|
+
}
|
|
804
|
+
/**
|
|
805
|
+
* Get WCAG to EN 301 549 mapping
|
|
806
|
+
*/
|
|
807
|
+
getWCAGMapping() {
|
|
808
|
+
return [...WCAG_TO_EN301549_MAP];
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Get clauses for a specific WCAG criterion
|
|
812
|
+
*/
|
|
813
|
+
getClausesForWCAG(wcagCriterion) {
|
|
814
|
+
return EN_301_549_WEB_CLAUSES.filter((clause) => clause.wcagMapping.includes(wcagCriterion));
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Hash URL for cache key
|
|
818
|
+
*/
|
|
819
|
+
hashUrl(url) {
|
|
820
|
+
let hash = 0;
|
|
821
|
+
for (let i = 0; i < url.length; i++) {
|
|
822
|
+
const char = url.charCodeAt(i);
|
|
823
|
+
hash = (hash << 5) - hash + char;
|
|
824
|
+
hash = hash & hash;
|
|
825
|
+
}
|
|
826
|
+
return Math.abs(hash).toString(36);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
export { EN_301_549_WEB_CLAUSES, EAA_WEB_REQUIREMENTS, WCAG_TO_EN301549_MAP, getWCAGLevel, };
|
|
830
|
+
//# sourceMappingURL=eu-compliance.js.map
|