@mcptoolshop/accessibility-suite 0.1.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 (241) hide show
  1. package/.github/workflows/ci.yml +63 -0
  2. package/LICENSE +21 -0
  3. package/README.md +37 -0
  4. package/docs/prov-spec/.github/workflows/ci.yml +68 -0
  5. package/docs/prov-spec/CHANGELOG.md +69 -0
  6. package/docs/prov-spec/CODE_OF_CONDUCT.md +129 -0
  7. package/docs/prov-spec/CONFORMANCE_LEVELS.md +223 -0
  8. package/docs/prov-spec/CONTRIBUTING.md +145 -0
  9. package/docs/prov-spec/IMPLEMENTER_CHECKLIST.md +137 -0
  10. package/docs/prov-spec/LICENSE +21 -0
  11. package/docs/prov-spec/PRESS_RELEASE.md +74 -0
  12. package/docs/prov-spec/README.md +182 -0
  13. package/docs/prov-spec/SETUP.md +135 -0
  14. package/docs/prov-spec/WHY.md +86 -0
  15. package/docs/prov-spec/examples/artifact.example.json +14 -0
  16. package/docs/prov-spec/examples/artifact.ref.example.json +9 -0
  17. package/docs/prov-spec/examples/evidence.example.json +6 -0
  18. package/docs/prov-spec/examples/mcp.envelope.example.json +97 -0
  19. package/docs/prov-spec/examples/mcp.request.example.json +28 -0
  20. package/docs/prov-spec/examples/prov.record.example.json +35 -0
  21. package/docs/prov-spec/interop/PROOF_NODE_ENGINE.md +114 -0
  22. package/docs/prov-spec/spec/MCP_COMPATIBILITY.md +241 -0
  23. package/docs/prov-spec/spec/PROV_METHODS_CATALOG.md +142 -0
  24. package/docs/prov-spec/spec/PROV_METHODS_SPEC.md +397 -0
  25. package/docs/prov-spec/spec/methods.json +213 -0
  26. package/docs/prov-spec/spec/schemas/artifact.ref.schema.v0.1.json +58 -0
  27. package/docs/prov-spec/spec/schemas/artifact.schema.v0.1.json +61 -0
  28. package/docs/prov-spec/spec/schemas/assist.request.schema.v0.1.json +52 -0
  29. package/docs/prov-spec/spec/schemas/assist.response.schema.v0.1.json +70 -0
  30. package/docs/prov-spec/spec/schemas/cli.error.schema.v0.1.json +78 -0
  31. package/docs/prov-spec/spec/schemas/evidence.schema.v0.1.json +37 -0
  32. package/docs/prov-spec/spec/schemas/mcp.envelope.schema.v0.1.json +141 -0
  33. package/docs/prov-spec/spec/schemas/mcp.request.schema.v0.1.json +79 -0
  34. package/docs/prov-spec/spec/schemas/methods.schema.json +93 -0
  35. package/docs/prov-spec/spec/schemas/prov-capabilities.schema.json +122 -0
  36. package/docs/prov-spec/spec/schemas/prov.record.schema.v0.1.json +133 -0
  37. package/docs/prov-spec/spec/vectors/adapter.wrap.envelope_v0_1/expected.json +4 -0
  38. package/docs/prov-spec/spec/vectors/adapter.wrap.envelope_v0_1/input.json +1 -0
  39. package/docs/prov-spec/spec/vectors/adapter.wrap.envelope_v0_1/negative/double_wrapped.json +14 -0
  40. package/docs/prov-spec/spec/vectors/adapter.wrap.envelope_v0_1/negative/wrong_schema_version.json +11 -0
  41. package/docs/prov-spec/spec/vectors/engine.extract.evidence.json_pointer/expected.json +24 -0
  42. package/docs/prov-spec/spec/vectors/engine.extract.evidence.json_pointer/input.json +8 -0
  43. package/docs/prov-spec/spec/vectors/integrity.digest.sha256/expected.json +7 -0
  44. package/docs/prov-spec/spec/vectors/integrity.digest.sha256/input.json +1 -0
  45. package/docs/prov-spec/spec/vectors/integrity.digest.sha256/negative/non_hex_chars.json +16 -0
  46. package/docs/prov-spec/spec/vectors/integrity.digest.sha256/negative/uppercase_hex.json +16 -0
  47. package/docs/prov-spec/spec/vectors/integrity.digest.sha256/negative/wrong_length.json +16 -0
  48. package/docs/prov-spec/spec/vectors/method_id_syntax/negative/hyphen_separator.json +8 -0
  49. package/docs/prov-spec/spec/vectors/method_id_syntax/negative/reserved_namespace.json +8 -0
  50. package/docs/prov-spec/spec/vectors/method_id_syntax/negative/starts_with_digit.json +8 -0
  51. package/docs/prov-spec/spec/vectors/method_id_syntax/negative/uppercase.json +8 -0
  52. package/docs/prov-spec/spec/vectors/method_id_syntax/positive/valid_ids.json +18 -0
  53. package/docs/prov-spec/tools/python/prov_validator.py +428 -0
  54. package/examples/a11y-demo-site/.github/workflows/a11y-artifacts.yml +81 -0
  55. package/examples/a11y-demo-site/.github/workflows/a11y.yml +34 -0
  56. package/examples/a11y-demo-site/CODE_OF_CONDUCT.md +129 -0
  57. package/examples/a11y-demo-site/CONTRIBUTING.md +83 -0
  58. package/examples/a11y-demo-site/LICENSE +21 -0
  59. package/examples/a11y-demo-site/README.md +155 -0
  60. package/examples/a11y-demo-site/html/contact.html +15 -0
  61. package/examples/a11y-demo-site/html/index.html +20 -0
  62. package/examples/a11y-demo-site/scripts/a11y.sh +20 -0
  63. package/package.json +26 -0
  64. package/src/a11y-assist/.github/workflows/publish.yml +52 -0
  65. package/src/a11y-assist/.github/workflows/test.yml +30 -0
  66. package/src/a11y-assist/A11Y_ASSIST_TEST_COVERAGE_REQUIREMENTS.md +104 -0
  67. package/src/a11y-assist/CODE_OF_CONDUCT.md +129 -0
  68. package/src/a11y-assist/CONTRIBUTING.md +98 -0
  69. package/src/a11y-assist/ENGINE.md +363 -0
  70. package/src/a11y-assist/LICENSE +21 -0
  71. package/src/a11y-assist/PRESS_RELEASE.md +71 -0
  72. package/src/a11y-assist/QUICKSTART.md +101 -0
  73. package/src/a11y-assist/README.md +192 -0
  74. package/src/a11y-assist/RELEASE_NOTES.md +319 -0
  75. package/src/a11y-assist/a11y_assist/__init__.py +3 -0
  76. package/src/a11y-assist/a11y_assist/cli.py +599 -0
  77. package/src/a11y-assist/a11y_assist/from_cli_error.py +149 -0
  78. package/src/a11y-assist/a11y_assist/guard.py +444 -0
  79. package/src/a11y-assist/a11y_assist/ingest.py +407 -0
  80. package/src/a11y-assist/a11y_assist/methods.py +137 -0
  81. package/src/a11y-assist/a11y_assist/parse_raw.py +71 -0
  82. package/src/a11y-assist/a11y_assist/profiles/__init__.py +29 -0
  83. package/src/a11y-assist/a11y_assist/profiles/cognitive_load.py +245 -0
  84. package/src/a11y-assist/a11y_assist/profiles/cognitive_load_render.py +86 -0
  85. package/src/a11y-assist/a11y_assist/profiles/dyslexia.py +144 -0
  86. package/src/a11y-assist/a11y_assist/profiles/dyslexia_render.py +77 -0
  87. package/src/a11y-assist/a11y_assist/profiles/plain_language.py +119 -0
  88. package/src/a11y-assist/a11y_assist/profiles/plain_language_render.py +66 -0
  89. package/src/a11y-assist/a11y_assist/profiles/screen_reader.py +348 -0
  90. package/src/a11y-assist/a11y_assist/profiles/screen_reader_render.py +89 -0
  91. package/src/a11y-assist/a11y_assist/render.py +95 -0
  92. package/src/a11y-assist/a11y_assist/schemas/assist.request.schema.v0.1.json +52 -0
  93. package/src/a11y-assist/a11y_assist/schemas/assist.response.schema.v0.1.json +70 -0
  94. package/src/a11y-assist/a11y_assist/schemas/cli.error.schema.v0.1.json +78 -0
  95. package/src/a11y-assist/a11y_assist/storage.py +31 -0
  96. package/src/a11y-assist/pyproject.toml +60 -0
  97. package/src/a11y-assist/tests/__init__.py +1 -0
  98. package/src/a11y-assist/tests/fixtures/base_inputs/cli_error_high.json +18 -0
  99. package/src/a11y-assist/tests/fixtures/base_inputs/cli_error_medium.json +16 -0
  100. package/src/a11y-assist/tests/fixtures/base_inputs/raw_text_low.txt +3 -0
  101. package/src/a11y-assist/tests/fixtures/cli_error_good.json +9 -0
  102. package/src/a11y-assist/tests/fixtures/cli_error_missing_id.json +7 -0
  103. package/src/a11y-assist/tests/fixtures/cli_error_string_format.json +7 -0
  104. package/src/a11y-assist/tests/fixtures/expected/cognitive_load_high.txt +20 -0
  105. package/src/a11y-assist/tests/fixtures/expected/dyslexia_high.txt +20 -0
  106. package/src/a11y-assist/tests/fixtures/expected/lowvision_high.txt +18 -0
  107. package/src/a11y-assist/tests/fixtures/expected/plain_language_high.txt +14 -0
  108. package/src/a11y-assist/tests/fixtures/expected/screen_reader_high.txt +19 -0
  109. package/src/a11y-assist/tests/fixtures/golden_screen_reader_cli_error.txt +16 -0
  110. package/src/a11y-assist/tests/fixtures/golden_screen_reader_raw_no_id.txt +14 -0
  111. package/src/a11y-assist/tests/fixtures/golden_screen_reader_raw_with_id.txt +14 -0
  112. package/src/a11y-assist/tests/fixtures/raw_good.txt +11 -0
  113. package/src/a11y-assist/tests/fixtures/raw_no_id.txt +2 -0
  114. package/src/a11y-assist/tests/test_cognitive_load.py +469 -0
  115. package/src/a11y-assist/tests/test_dyslexia.py +337 -0
  116. package/src/a11y-assist/tests/test_explain.py +74 -0
  117. package/src/a11y-assist/tests/test_golden.py +127 -0
  118. package/src/a11y-assist/tests/test_guard.py +819 -0
  119. package/src/a11y-assist/tests/test_guard_integration.py +457 -0
  120. package/src/a11y-assist/tests/test_ingest.py +311 -0
  121. package/src/a11y-assist/tests/test_methods_metadata.py +236 -0
  122. package/src/a11y-assist/tests/test_plain_language.py +348 -0
  123. package/src/a11y-assist/tests/test_render.py +117 -0
  124. package/src/a11y-assist/tests/test_screen_reader.py +703 -0
  125. package/src/a11y-assist/tests/test_storage_last.py +61 -0
  126. package/src/a11y-assist/tests/test_triage.py +86 -0
  127. package/src/a11y-ci/.github/workflows/ci.yml +43 -0
  128. package/src/a11y-ci/.github/workflows/test.yml +30 -0
  129. package/src/a11y-ci/A11Y_CI_TEST_COVERAGE_REQUIREMENTS.md +94 -0
  130. package/src/a11y-ci/CODE_OF_CONDUCT.md +129 -0
  131. package/src/a11y-ci/CONTRIBUTING.md +142 -0
  132. package/src/a11y-ci/LICENSE +21 -0
  133. package/src/a11y-ci/README.md +105 -0
  134. package/src/a11y-ci/a11y_ci/__init__.py +3 -0
  135. package/src/a11y-ci/a11y_ci/allowlist.py +83 -0
  136. package/src/a11y-ci/a11y_ci/cli.py +145 -0
  137. package/src/a11y-ci/a11y_ci/gate.py +131 -0
  138. package/src/a11y-ci/a11y_ci/render.py +48 -0
  139. package/src/a11y-ci/a11y_ci/schemas/allowlist.schema.json +24 -0
  140. package/src/a11y-ci/a11y_ci/scorecard.py +99 -0
  141. package/src/a11y-ci/npm/package.json +35 -0
  142. package/src/a11y-ci/pyproject.toml +64 -0
  143. package/src/a11y-ci/tests/__init__.py +1 -0
  144. package/src/a11y-ci/tests/fixtures/allowlist_expired.json +10 -0
  145. package/src/a11y-ci/tests/fixtures/allowlist_ok.json +10 -0
  146. package/src/a11y-ci/tests/fixtures/baseline_ok.json +7 -0
  147. package/src/a11y-ci/tests/fixtures/current_fail.json +6 -0
  148. package/src/a11y-ci/tests/fixtures/current_ok.json +6 -0
  149. package/src/a11y-ci/tests/fixtures/current_regresses.json +7 -0
  150. package/src/a11y-ci/tests/test_gate.py +134 -0
  151. package/src/a11y-evidence-engine/.github/workflows/ci.yml +53 -0
  152. package/src/a11y-evidence-engine/CODE_OF_CONDUCT.md +129 -0
  153. package/src/a11y-evidence-engine/CONTRIBUTING.md +128 -0
  154. package/src/a11y-evidence-engine/LICENSE +21 -0
  155. package/src/a11y-evidence-engine/README.md +71 -0
  156. package/src/a11y-evidence-engine/bin/a11y-engine.js +11 -0
  157. package/src/a11y-evidence-engine/fixtures/bad/button-no-name.html +30 -0
  158. package/src/a11y-evidence-engine/fixtures/bad/img-missing-alt.html +19 -0
  159. package/src/a11y-evidence-engine/fixtures/bad/input-missing-label.html +26 -0
  160. package/src/a11y-evidence-engine/fixtures/bad/missing-lang.html +11 -0
  161. package/src/a11y-evidence-engine/fixtures/good/index.html +29 -0
  162. package/src/a11y-evidence-engine/package-lock.json +109 -0
  163. package/src/a11y-evidence-engine/package.json +45 -0
  164. package/src/a11y-evidence-engine/src/cli.js +74 -0
  165. package/src/a11y-evidence-engine/src/evidence/canonicalize.js +52 -0
  166. package/src/a11y-evidence-engine/src/evidence/json_pointer.js +34 -0
  167. package/src/a11y-evidence-engine/src/evidence/prov_emit.js +153 -0
  168. package/src/a11y-evidence-engine/src/fswalk.js +56 -0
  169. package/src/a11y-evidence-engine/src/html_parse.js +117 -0
  170. package/src/a11y-evidence-engine/src/ids.js +53 -0
  171. package/src/a11y-evidence-engine/src/rules/document_missing_lang.js +50 -0
  172. package/src/a11y-evidence-engine/src/rules/form_control_missing_label.js +105 -0
  173. package/src/a11y-evidence-engine/src/rules/img_missing_alt.js +77 -0
  174. package/src/a11y-evidence-engine/src/rules/index.js +37 -0
  175. package/src/a11y-evidence-engine/src/rules/interactive_missing_name.js +129 -0
  176. package/src/a11y-evidence-engine/src/scan.js +128 -0
  177. package/src/a11y-evidence-engine/test/scan.test.js +149 -0
  178. package/src/a11y-evidence-engine/test/vectors.test.js +200 -0
  179. package/src/a11y-lint/.github/workflows/ci.yml +46 -0
  180. package/src/a11y-lint/.github/workflows/test.yml +34 -0
  181. package/src/a11y-lint/CODE_OF_CONDUCT.md +129 -0
  182. package/src/a11y-lint/CONTRIBUTING.md +70 -0
  183. package/src/a11y-lint/GOVERNANCE.md +57 -0
  184. package/src/a11y-lint/LICENSE +21 -0
  185. package/src/a11y-lint/PRESS_RELEASE.md +50 -0
  186. package/src/a11y-lint/README.md +276 -0
  187. package/src/a11y-lint/RELEASE_NOTES.md +57 -0
  188. package/src/a11y-lint/RELEASING.md +57 -0
  189. package/src/a11y-lint/a11y_lint/__init__.py +64 -0
  190. package/src/a11y-lint/a11y_lint/cli.py +319 -0
  191. package/src/a11y-lint/a11y_lint/errors.py +252 -0
  192. package/src/a11y-lint/a11y_lint/render.py +293 -0
  193. package/src/a11y-lint/a11y_lint/report_md.py +289 -0
  194. package/src/a11y-lint/a11y_lint/scan_cli_text.py +434 -0
  195. package/src/a11y-lint/a11y_lint/schemas/cli.error.schema.v0.1.json +83 -0
  196. package/src/a11y-lint/a11y_lint/scorecard.py +244 -0
  197. package/src/a11y-lint/a11y_lint/validate.py +225 -0
  198. package/src/a11y-lint/pyproject.toml +75 -0
  199. package/src/a11y-lint/tests/__init__.py +1 -0
  200. package/src/a11y-lint/tests/test_cli.py +200 -0
  201. package/src/a11y-lint/tests/test_errors.py +188 -0
  202. package/src/a11y-lint/tests/test_render.py +202 -0
  203. package/src/a11y-lint/tests/test_report_md.py +188 -0
  204. package/src/a11y-lint/tests/test_scan_cli_text.py +290 -0
  205. package/src/a11y-lint/tests/test_scorecard.py +195 -0
  206. package/src/a11y-lint/tests/test_validate.py +257 -0
  207. package/src/a11y-mcp-tools/.github/workflows/ci.yml +53 -0
  208. package/src/a11y-mcp-tools/CODE_OF_CONDUCT.md +129 -0
  209. package/src/a11y-mcp-tools/CONTRIBUTING.md +136 -0
  210. package/src/a11y-mcp-tools/LICENSE +21 -0
  211. package/src/a11y-mcp-tools/PROV_METHODS_CATALOG.md +104 -0
  212. package/src/a11y-mcp-tools/README.md +168 -0
  213. package/src/a11y-mcp-tools/bin/cli.js +452 -0
  214. package/src/a11y-mcp-tools/bin/server.js +244 -0
  215. package/src/a11y-mcp-tools/fixtures/requests/a11y.diagnose.ok.json +27 -0
  216. package/src/a11y-mcp-tools/fixtures/requests/a11y.evidence.ok.json +25 -0
  217. package/src/a11y-mcp-tools/fixtures/responses/a11y.diagnose.ok.json +139 -0
  218. package/src/a11y-mcp-tools/fixtures/responses/a11y.diagnose.provenance_fail.json +13 -0
  219. package/src/a11y-mcp-tools/fixtures/responses/a11y.evidence.ok.json +88 -0
  220. package/src/a11y-mcp-tools/package-lock.json +189 -0
  221. package/src/a11y-mcp-tools/package.json +49 -0
  222. package/src/a11y-mcp-tools/src/envelope.js +197 -0
  223. package/src/a11y-mcp-tools/src/index.js +9 -0
  224. package/src/a11y-mcp-tools/src/schemas/artifact.js +85 -0
  225. package/src/a11y-mcp-tools/src/schemas/diagnosis.schema.v0.1.json +137 -0
  226. package/src/a11y-mcp-tools/src/schemas/envelope.schema.v0.1.json +108 -0
  227. package/src/a11y-mcp-tools/src/schemas/evidence.bundle.schema.v0.1.json +129 -0
  228. package/src/a11y-mcp-tools/src/schemas/evidence.js +97 -0
  229. package/src/a11y-mcp-tools/src/schemas/index.js +11 -0
  230. package/src/a11y-mcp-tools/src/schemas/provenance.js +140 -0
  231. package/src/a11y-mcp-tools/src/schemas/tools/a11y.diagnose.request.schema.v0.1.json +77 -0
  232. package/src/a11y-mcp-tools/src/schemas/tools/a11y.diagnose.response.schema.v0.1.json +50 -0
  233. package/src/a11y-mcp-tools/src/schemas/tools/a11y.evidence.request.schema.v0.1.json +120 -0
  234. package/src/a11y-mcp-tools/src/schemas/tools/a11y.evidence.response.schema.v0.1.json +50 -0
  235. package/src/a11y-mcp-tools/src/tools/diagnose.js +597 -0
  236. package/src/a11y-mcp-tools/src/tools/evidence.js +481 -0
  237. package/src/a11y-mcp-tools/src/tools/index.js +10 -0
  238. package/src/a11y-mcp-tools/test/contract.test.mjs +154 -0
  239. package/src/a11y-mcp-tools/test/diagnose.test.js +485 -0
  240. package/src/a11y-mcp-tools/test/evidence.test.js +183 -0
  241. package/src/a11y-mcp-tools/test/schema.test.js +327 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 mcp-tool-shop
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,50 @@
1
+ # Introducing a11y-lint
2
+ ## Accessibility as a Contract for CLI Tools
3
+
4
+ Today we're releasing **a11y-lint**, an accessibility linter built specifically for command-line tools.
5
+
6
+ Most accessibility tooling focuses on web interfaces. But developers, operators, and data professionals spend much of their time in terminals — and terminal output is often inaccessible by default.
7
+
8
+ a11y-lint treats accessibility as a **hard interface**, not a suggestion.
9
+
10
+ ---
11
+
12
+ ## What a11y-lint Does
13
+
14
+ a11y-lint scans CLI output and enforces a strict, low-vision-first accessibility contract:
15
+
16
+ - Clear textual status indicators: `[OK]`, `[WARN]`, `[ERROR]`
17
+ - Deterministic error structure:
18
+ - What happened
19
+ - Why it happened
20
+ - How to fix it
21
+ - No reliance on color, emojis, or visual tricks
22
+ - Machine-parseable output suitable for CI
23
+ - Human-readable output under stress
24
+
25
+ If output fails checks, a11y-lint explains **what's wrong and how to fix it**.
26
+
27
+ ---
28
+
29
+ ## Philosophy
30
+
31
+ Accessibility should not rely on memory, heroics, or good intentions.
32
+
33
+ It should be:
34
+ - explicit
35
+ - testable
36
+ - enforceable
37
+ - boring
38
+
39
+ That's what a11y-lint is for.
40
+
41
+ ---
42
+
43
+ ## Get Started
44
+
45
+ ```bash
46
+ pip install a11y-lint
47
+ a11y-lint scan output.txt
48
+ ```
49
+
50
+ a11y-lint is open source and welcomes contributors who care about building tools that respect real humans.
@@ -0,0 +1,276 @@
1
+ # a11y-lint
2
+
3
+ ![a11y](https://img.shields.io/badge/a11y-low--vision--first-blue)
4
+ ![contract](https://img.shields.io/badge/output-contract--stable-green)
5
+ ![tests](https://img.shields.io/badge/tests-176%2B-brightgreen)
6
+ ![license](https://img.shields.io/badge/license-MIT-black)
7
+
8
+ **Low-vision-first accessibility linting for CLI output.**
9
+
10
+ Validates that error messages follow accessible patterns with the **[OK]/[WARN]/[ERROR] + What/Why/Fix** structure.
11
+
12
+ ## Philosophy
13
+
14
+ ### Rule Categories
15
+
16
+ This tool distinguishes between two types of rules:
17
+
18
+ - **WCAG Rules**: Mapped to specific WCAG success criteria. Violations may constitute accessibility barriers.
19
+ - **Policy Rules**: Best practices for cognitive accessibility. Not WCAG requirements, but improve usability for users with cognitive disabilities.
20
+
21
+ Currently, only `no-color-only` (WCAG SC 1.4.1) is a WCAG-mapped rule. All other rules are policy rules that improve message clarity and readability.
22
+
23
+ ### Grades vs. CI Gating
24
+
25
+ **Important:** Letter grades (A-F) are *derived summaries* for executive reporting. They should **never** be the primary mechanism for CI gating.
26
+
27
+ For CI pipelines, gate on:
28
+ - Specific rule failures (especially WCAG-mapped rules like `no-color-only`)
29
+ - Error count thresholds
30
+ - Regressions from a baseline
31
+
32
+ ```bash
33
+ # Good: Gate on errors
34
+ a11y-lint scan output.txt && echo "Passed" || echo "Failed"
35
+
36
+ # Good: Gate on specific rules
37
+ a11y-lint scan --enable=no-color-only output.txt
38
+
39
+ # Avoid: Gating purely on letter grades
40
+ ```
41
+
42
+ ### Badges and Conformance
43
+
44
+ Scores and badges are **informational only**. They do NOT imply WCAG conformance or accessibility certification. This tool checks policy rules beyond minimum WCAG requirements.
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install a11y-lint
50
+ ```
51
+
52
+ Or install from source:
53
+
54
+ ```bash
55
+ git clone https://github.com/mcp-tool-shop-org/a11y-lint.git
56
+ cd a11y-lint
57
+ pip install -e ".[dev]"
58
+ ```
59
+
60
+ ## Quick Start
61
+
62
+ Scan CLI output for accessibility issues:
63
+
64
+ ```bash
65
+ # Scan a file
66
+ a11y-lint scan output.txt
67
+
68
+ # Scan from stdin
69
+ echo "ERROR: It failed" | a11y-lint scan --stdin
70
+
71
+ # Generate a report
72
+ a11y-lint report output.txt -o report.md
73
+ ```
74
+
75
+ ## CLI Commands
76
+
77
+ ### `scan` - Check for accessibility issues
78
+
79
+ ```bash
80
+ a11y-lint scan [OPTIONS] INPUT
81
+
82
+ Options:
83
+ --stdin Read from stdin instead of file
84
+ --color [auto|always|never] Color output mode (default: auto)
85
+ --json Output results as JSON
86
+ --format [plain|json|markdown] Output format
87
+ --disable RULE Disable specific rules (can repeat)
88
+ --enable RULE Enable only specific rules (can repeat)
89
+ --strict Treat warnings as errors
90
+ ```
91
+
92
+ The `--color` option controls colored output:
93
+ - `auto` (default): Respect `NO_COLOR` and `FORCE_COLOR` environment variables, auto-detect TTY
94
+ - `always`: Force colored output
95
+ - `never`: Disable colored output
96
+
97
+ ### `validate` - Validate JSON messages against schema
98
+
99
+ ```bash
100
+ a11y-lint validate messages.json
101
+ a11y-lint validate -v messages.json # Verbose output
102
+ ```
103
+
104
+ ### `scorecard` - Generate accessibility scorecard
105
+
106
+ ```bash
107
+ a11y-lint scorecard output.txt
108
+ a11y-lint scorecard --json output.txt # JSON output
109
+ a11y-lint scorecard --badge output.txt # shields.io badge
110
+ ```
111
+
112
+ ### `report` - Generate markdown report
113
+
114
+ ```bash
115
+ a11y-lint report output.txt
116
+ a11y-lint report output.txt -o report.md
117
+ a11y-lint report --title="My Report" output.txt
118
+ ```
119
+
120
+ ### `list-rules` - Show available rules
121
+
122
+ ```bash
123
+ a11y-lint list-rules # Simple list
124
+ a11y-lint list-rules -v # Verbose with categories and WCAG refs
125
+ ```
126
+
127
+ ### `schema` - Print the JSON schema
128
+
129
+ ```bash
130
+ a11y-lint schema
131
+ ```
132
+
133
+ ## Environment Variables
134
+
135
+ | Variable | Description |
136
+ |----------|-------------|
137
+ | `NO_COLOR` | Disable colored output (any value) |
138
+ | `FORCE_COLOR` | Force colored output (any value, overrides NO_COLOR=false) |
139
+
140
+ See [no-color.org](https://no-color.org/) for the standard.
141
+
142
+ ## Rules
143
+
144
+ ### WCAG Rules
145
+
146
+ | Rule | Code | WCAG | Description |
147
+ |------|------|------|-------------|
148
+ | `no-color-only` | CLR001 | 1.4.1 | Don't convey information only through color |
149
+
150
+ ### Policy Rules
151
+
152
+ | Rule | Code | Description |
153
+ |------|------|-------------|
154
+ | `line-length` | FMT001 | Lines should be 120 characters or fewer |
155
+ | `no-all-caps` | LNG002 | Avoid all-caps text (hard to read) |
156
+ | `plain-language` | LNG001 | Avoid technical jargon (EOF, STDIN, etc.) |
157
+ | `emoji-moderation` | SCR001 | Limit emoji use (confuses screen readers) |
158
+ | `punctuation` | LNG003 | Error messages should end with punctuation |
159
+ | `error-structure` | A11Y003 | Errors should explain why and how to fix |
160
+ | `no-ambiguous-pronouns` | LNG004 | Avoid starting with "it", "this", etc. |
161
+
162
+ ## Error Message Format
163
+
164
+ All error messages follow the What/Why/Fix structure:
165
+
166
+ ```
167
+ [ERROR] CODE: What happened
168
+ Why: Explanation of why this matters
169
+ Fix: Actionable suggestion
170
+
171
+ [WARN] CODE: What to improve
172
+ Why: Why this matters
173
+ Fix: How to improve (optional)
174
+
175
+ [OK] CODE: What was checked
176
+ ```
177
+
178
+ ## JSON Schema
179
+
180
+ Messages conform to the CLI error schema (`schemas/cli.error.schema.v0.1.json`):
181
+
182
+ ```json
183
+ {
184
+ "level": "ERROR",
185
+ "code": "A11Y001",
186
+ "what": "Brief description of what happened",
187
+ "why": "Explanation of why this matters",
188
+ "fix": "How to fix the issue",
189
+ "location": {
190
+ "file": "path/to/file.txt",
191
+ "line": 10,
192
+ "column": 5,
193
+ "context": "relevant text snippet"
194
+ },
195
+ "rule": "rule-name",
196
+ "metadata": {}
197
+ }
198
+ ```
199
+
200
+ ## Python API
201
+
202
+ ```python
203
+ from a11y_lint import scan, Scanner, A11yMessage, Level
204
+
205
+ # Quick scan
206
+ messages = scan("ERROR: It failed")
207
+
208
+ # Custom scanner
209
+ scanner = Scanner()
210
+ scanner.disable_rule("line-length")
211
+ messages = scanner.scan_text(text)
212
+
213
+ # Create messages programmatically
214
+ msg = A11yMessage.error(
215
+ code="APP001",
216
+ what="Configuration file missing",
217
+ why="The app cannot start without config.yaml",
218
+ fix="Create config.yaml in the project root"
219
+ )
220
+
221
+ # Validate against schema
222
+ from a11y_lint import is_valid, validate_message
223
+ assert is_valid(msg)
224
+
225
+ # Generate scorecard
226
+ from a11y_lint import create_scorecard
227
+ card = create_scorecard(messages)
228
+ print(card.summary())
229
+ print(f"Score: {card.overall_score}% ({card.overall_grade})")
230
+
231
+ # Generate markdown report
232
+ from a11y_lint import render_report_md
233
+ markdown = render_report_md(messages, title="My Report")
234
+ ```
235
+
236
+ ## CI Integration
237
+
238
+ ### GitHub Actions Example
239
+
240
+ ```yaml
241
+ - name: Check CLI accessibility
242
+ run: |
243
+ # Capture CLI output
244
+ ./your-cli --help > cli_output.txt 2>&1 || true
245
+
246
+ # Lint for accessibility issues
247
+ # Exit code 1 = errors found, 0 = clean
248
+ a11y-lint scan cli_output.txt
249
+
250
+ # Or strict mode (warnings = errors)
251
+ a11y-lint scan --strict cli_output.txt
252
+ ```
253
+
254
+ ### Best Practices
255
+
256
+ 1. **Gate on errors, not grades**: Use exit codes, not letter grades
257
+ 2. **Enable specific rules**: For WCAG compliance, enable `no-color-only`
258
+ 3. **Track baselines**: Use JSON output to detect regressions
259
+ 4. **Treat badges as informational**: They don't imply conformance
260
+
261
+ ## Development
262
+
263
+ ```bash
264
+ # Install dev dependencies
265
+ pip install -e ".[dev]"
266
+
267
+ # Run tests
268
+ pytest
269
+
270
+ # Type check
271
+ pyright
272
+ ```
273
+
274
+ ## License
275
+
276
+ MIT
@@ -0,0 +1,57 @@
1
+ # Release Notes
2
+
3
+ ## v0.1.0 (2026-01-26)
4
+
5
+ First stable release of **a11y-lint**, a low-vision-first accessibility linter for command-line tools.
6
+
7
+ ### Highlights
8
+
9
+ - **Stable CLI output contract**: `[OK] / [WARN] / [ERROR]` + `What / Why / Fix` structure
10
+ - **Ground-truth JSON schema**: `cli.error.schema.v0.1.json`
11
+ - **Low-vision-first rule set** covering:
12
+ - Line length and spacing
13
+ - Color-only meaning detection (WCAG SC 1.4.1)
14
+ - Emoji-only signaling
15
+ - Technical jargon
16
+ - Ambiguous pronouns
17
+ - Error message structure
18
+ - **Deterministic rendering** suitable for CI and diffing
19
+ - **Reports and scorecards** in Markdown format
20
+ - **176+ tests** with comprehensive coverage
21
+
22
+ ### CLI Commands
23
+
24
+ - `a11y-lint scan` — Check CLI output for accessibility issues
25
+ - `a11y-lint validate` — Validate JSON messages against schema
26
+ - `a11y-lint scorecard` — Generate accessibility scorecard
27
+ - `a11y-lint report` — Generate Markdown report
28
+ - `a11y-lint list-rules` — Show available rules
29
+ - `a11y-lint schema` — Print JSON schema
30
+
31
+ ### Rule Categories
32
+
33
+ Rules are classified as:
34
+ - **WCAG**: Mapped to WCAG success criteria (e.g., `no-color-only` → SC 1.4.1)
35
+ - **Policy**: Best practices for cognitive accessibility
36
+
37
+ ### Stability Guarantees
38
+
39
+ - CLI output structure is **stable**
40
+ - JSON schema `cli.error.v0.1` is **frozen**
41
+ - Rule coverage may expand, but guarantees will not be weakened
42
+ - Breaking changes require a major version bump
43
+
44
+ ### Environment Variables
45
+
46
+ - `NO_COLOR` — Disable colored output
47
+ - `FORCE_COLOR` — Force colored output
48
+
49
+ ### Known Limitations
50
+
51
+ - Focused on CLI text output only
52
+ - Single accessibility profile (low vision)
53
+ - No AI-assisted suggestions in v0.1
54
+
55
+ ---
56
+
57
+ This release establishes the foundation for accessible CLI tooling.
@@ -0,0 +1,57 @@
1
+ # Releasing a11y-lint
2
+
3
+ ## Pre-Release Checklist
4
+
5
+ Before tagging a release:
6
+
7
+ - [ ] All tests pass (`pytest tests/ -v`)
8
+ - [ ] Type checks pass (`pyright`)
9
+ - [ ] CLI output contract unchanged (or major version bump)
10
+ - [ ] Schema version unchanged (or major version bump)
11
+ - [ ] No regressions in accessibility findings
12
+ - [ ] README updated with any new features
13
+ - [ ] RELEASE_NOTES.md updated
14
+
15
+ ---
16
+
17
+ ## Release Process
18
+
19
+ 1. **Update version** in `pyproject.toml`
20
+ 2. **Update RELEASE_NOTES.md** with changes
21
+ 3. **Run full test suite**:
22
+ ```bash
23
+ pytest tests/ -v
24
+ ```
25
+ 4. **Create git tag**:
26
+ ```bash
27
+ git tag -a v0.x.x -m "Release v0.x.x"
28
+ git push origin v0.x.x
29
+ ```
30
+ 5. **Create GitHub release** with release notes
31
+ 6. **Publish to PyPI**:
32
+ ```bash
33
+ python -m build
34
+ twine upload dist/*
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Release Blockers
40
+
41
+ The following block releases:
42
+
43
+ - Failing tests
44
+ - Accessibility regressions
45
+ - Breaking changes without major version bump
46
+ - Schema changes without major version bump
47
+
48
+ ---
49
+
50
+ ## Hotfix Process
51
+
52
+ For critical bugs:
53
+
54
+ 1. Create branch from latest release tag
55
+ 2. Fix the issue with minimal changes
56
+ 3. Add regression test
57
+ 4. Tag as patch release (e.g., v0.1.1)
@@ -0,0 +1,64 @@
1
+ """a11y-lint: Accessibility linter for CLI output.
2
+
3
+ Validates that CLI error messages follow accessible patterns
4
+ with [OK]/[WARN]/[ERROR] + What/Why/Fix structure.
5
+ """
6
+
7
+ __version__ = "0.1.0"
8
+
9
+ from .errors import A11yMessage, Level, Location, ErrorCodes
10
+ from .render import render, render_plain, render_colored, Renderer, should_use_color
11
+ from .scan_cli_text import Scanner, scan, get_rule_names, Rule, RULES, RuleCategory
12
+ from .scorecard import Scorecard, RuleScore, ScorecardBuilder, create_scorecard
13
+ from .report_md import (
14
+ MarkdownReporter,
15
+ render_report_md,
16
+ render_scorecard_md,
17
+ generate_badge_md,
18
+ )
19
+ from .validate import (
20
+ validate_dict,
21
+ validate_message,
22
+ is_valid,
23
+ validate_json_file,
24
+ MessageValidator,
25
+ )
26
+
27
+ __all__ = [
28
+ # Version
29
+ "__version__",
30
+ # Errors
31
+ "A11yMessage",
32
+ "Level",
33
+ "Location",
34
+ "ErrorCodes",
35
+ # Rendering
36
+ "render",
37
+ "render_plain",
38
+ "render_colored",
39
+ "Renderer",
40
+ "should_use_color",
41
+ # Scanning
42
+ "Scanner",
43
+ "scan",
44
+ "get_rule_names",
45
+ "Rule",
46
+ "RULES",
47
+ "RuleCategory",
48
+ # Scorecard
49
+ "Scorecard",
50
+ "RuleScore",
51
+ "ScorecardBuilder",
52
+ "create_scorecard",
53
+ # Markdown Reports
54
+ "MarkdownReporter",
55
+ "render_report_md",
56
+ "render_scorecard_md",
57
+ "generate_badge_md",
58
+ # Validation
59
+ "validate_dict",
60
+ "validate_message",
61
+ "is_valid",
62
+ "validate_json_file",
63
+ "MessageValidator",
64
+ ]