@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,70 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://a11y-assist.dev/schemas/assist.response.schema.v0.1.json",
4
+ "title": "assist.response.v0.1",
5
+ "description": "Response schema for a11y-assist with optional audit metadata",
6
+ "type": "object",
7
+ "required": ["confidence", "safest_next_step", "plan"],
8
+ "properties": {
9
+ "anchored_id": {
10
+ "type": ["string", "null"],
11
+ "description": "Error ID this assist is anchored to, if found"
12
+ },
13
+ "confidence": {
14
+ "type": "string",
15
+ "enum": ["High", "Medium", "Low"],
16
+ "description": "Confidence level of the assist"
17
+ },
18
+ "safest_next_step": {
19
+ "type": "string",
20
+ "description": "Single safest next action to take"
21
+ },
22
+ "plan": {
23
+ "type": "array",
24
+ "items": { "type": "string" },
25
+ "minItems": 1,
26
+ "description": "Ordered list of steps to resolve the issue"
27
+ },
28
+ "next_safe_commands": {
29
+ "type": "array",
30
+ "items": { "type": "string" },
31
+ "description": "SAFE-only commands that can be run"
32
+ },
33
+ "notes": {
34
+ "type": "array",
35
+ "items": { "type": "string" },
36
+ "description": "Additional notes and context"
37
+ },
38
+ "methods_applied": {
39
+ "type": "array",
40
+ "items": { "type": "string" },
41
+ "minItems": 0,
42
+ "description": "Stable method identifiers applied to produce this assist output (audit-only)"
43
+ },
44
+ "evidence": {
45
+ "type": "array",
46
+ "items": {
47
+ "type": "object",
48
+ "required": ["field", "source"],
49
+ "properties": {
50
+ "field": {
51
+ "type": "string",
52
+ "description": "Which output field this evidence supports (e.g., safest_next_step, plan[0])"
53
+ },
54
+ "source": {
55
+ "type": "string",
56
+ "description": "Source anchor (e.g., cli.error.fix[1], cli.error.why[0], raw_text:Fix:2)"
57
+ },
58
+ "note": {
59
+ "type": "string",
60
+ "description": "Optional short note clarifying the mapping"
61
+ }
62
+ },
63
+ "additionalProperties": false
64
+ },
65
+ "minItems": 0,
66
+ "description": "Trace anchors mapping assist content back to input (audit-only)"
67
+ }
68
+ },
69
+ "additionalProperties": false
70
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://a11y-lint.dev/schemas/cli.error.schema.v0.1.json",
4
+ "title": "CLI Ground Truth Message",
5
+ "description": "Schema for accessible CLI error messages with What/Why/Fix structure",
6
+ "type": "object",
7
+ "required": ["level", "code", "what"],
8
+ "properties": {
9
+ "level": {
10
+ "type": "string",
11
+ "enum": ["OK", "WARN", "ERROR"],
12
+ "description": "Severity level of the message"
13
+ },
14
+ "code": {
15
+ "type": "string",
16
+ "pattern": "^[A-Z][A-Z0-9]{1,3}[0-9]{3}$",
17
+ "description": "Unique error code (e.g., A11Y001, CLI002)",
18
+ "examples": ["A11Y001", "CLI002", "FMT003"]
19
+ },
20
+ "id": {
21
+ "type": "string",
22
+ "description": "Alternate ID field (NAMESPACE.CATEGORY.DETAIL format)"
23
+ },
24
+ "title": {
25
+ "type": "string",
26
+ "description": "Human-readable title"
27
+ },
28
+ "what": {
29
+ "oneOf": [
30
+ { "type": "string", "minLength": 1, "maxLength": 200 },
31
+ { "type": "array", "items": { "type": "string" }, "minItems": 1 }
32
+ ],
33
+ "description": "Brief description of what happened or was checked"
34
+ },
35
+ "why": {
36
+ "oneOf": [
37
+ { "type": "string", "minLength": 1, "maxLength": 500 },
38
+ { "type": "array", "items": { "type": "string" }, "minItems": 1 }
39
+ ],
40
+ "description": "Explanation of why this matters for accessibility"
41
+ },
42
+ "fix": {
43
+ "oneOf": [
44
+ { "type": "string", "minLength": 1, "maxLength": 500 },
45
+ { "type": "array", "items": { "type": "string" }, "minItems": 1 }
46
+ ],
47
+ "description": "Actionable suggestion for how to fix the issue"
48
+ },
49
+ "location": {
50
+ "type": "object",
51
+ "description": "Location of the issue in the source",
52
+ "properties": {
53
+ "file": { "type": "string" },
54
+ "line": { "type": "integer", "minimum": 1 },
55
+ "column": { "type": "integer", "minimum": 1 },
56
+ "context": { "type": "string", "maxLength": 200 }
57
+ }
58
+ },
59
+ "rule": {
60
+ "type": "string",
61
+ "description": "Name of the accessibility rule that was checked"
62
+ },
63
+ "metadata": {
64
+ "type": "object",
65
+ "description": "Additional rule-specific metadata",
66
+ "additionalProperties": true
67
+ }
68
+ },
69
+ "if": {
70
+ "properties": {
71
+ "level": { "const": "ERROR" }
72
+ }
73
+ },
74
+ "then": {
75
+ "required": ["level", "code", "what", "why", "fix"]
76
+ },
77
+ "additionalProperties": true
78
+ }
@@ -0,0 +1,31 @@
1
+ """Storage for last.log capture."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+
7
+
8
+ def default_state_dir() -> Path:
9
+ """Get the default state directory (~/.a11y-assist)."""
10
+ home = Path.home()
11
+ return home / ".a11y-assist"
12
+
13
+
14
+ def last_log_path() -> Path:
15
+ """Get the path to last.log."""
16
+ return default_state_dir() / "last.log"
17
+
18
+
19
+ def write_last_log(text: str) -> None:
20
+ """Write text to last.log, creating directory if needed."""
21
+ p = last_log_path()
22
+ p.parent.mkdir(parents=True, exist_ok=True)
23
+ p.write_text(text, encoding="utf-8", errors="replace")
24
+
25
+
26
+ def read_last_log() -> str:
27
+ """Read last.log, returning empty string if not found."""
28
+ p = last_log_path()
29
+ if not p.exists():
30
+ return ""
31
+ return p.read_text(encoding="utf-8", errors="replace")
@@ -0,0 +1,60 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "a11y-assist"
7
+ version = "0.2.1"
8
+ description = "Low-vision-first assistant for CLI failures (additive, deterministic)."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = {text = "MIT"}
12
+ authors = [
13
+ {name = "mcp-tool-shop", email = "64996768+mcp-tool-shop@users.noreply.github.com"}
14
+ ]
15
+ keywords = [
16
+ "accessibility",
17
+ "a11y",
18
+ "cli",
19
+ "assistant",
20
+ "low-vision",
21
+ "provenance",
22
+ "safe"
23
+ ]
24
+ classifiers = [
25
+ "Development Status :: 4 - Beta",
26
+ "Intended Audience :: Developers",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Programming Language :: Python :: 3",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Topic :: Software Development :: Quality Assurance",
33
+ "Topic :: Software Development :: User Interfaces",
34
+ ]
35
+ dependencies = [
36
+ "click>=8.1.7",
37
+ "jsonschema>=4.22.0"
38
+ ]
39
+
40
+ [project.urls]
41
+ Homepage = "https://github.com/mcp-tool-shop-org/a11y-assist"
42
+ Repository = "https://github.com/mcp-tool-shop-org/a11y-assist"
43
+ Issues = "https://github.com/mcp-tool-shop-org/a11y-assist/issues"
44
+ Changelog = "https://github.com/mcp-tool-shop-org/a11y-assist/blob/main/RELEASE_NOTES.md"
45
+
46
+ [project.optional-dependencies]
47
+ dev = [
48
+ "pytest>=8.0.0",
49
+ "ruff>=0.6.0",
50
+ ]
51
+
52
+ [project.scripts]
53
+ a11y-assist = "a11y_assist.cli:main"
54
+ assist-run = "a11y_assist.cli:assist_run"
55
+
56
+ [tool.ruff]
57
+ line-length = 100
58
+
59
+ [tool.pytest.ini_options]
60
+ testpaths = ["tests"]
@@ -0,0 +1 @@
1
+ """Tests for a11y-assist."""
@@ -0,0 +1,18 @@
1
+ {
2
+ "level": "ERROR",
3
+ "code": "NET001",
4
+ "id": "DEMO.NETWORK.TIMEOUT",
5
+ "title": "Request timed out",
6
+ "what": [
7
+ "The HTTP request did not complete within 30 seconds."
8
+ ],
9
+ "why": [
10
+ "The server did not respond before the timeout limit.",
11
+ "This may indicate network congestion or server overload."
12
+ ],
13
+ "fix": [
14
+ "Check your network connection.",
15
+ "Verify the server is reachable: ping api.example.com",
16
+ "Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run"
17
+ ]
18
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "level": "WARN",
3
+ "code": "CFG001",
4
+ "id": "DEMO.CONFIG.DEPRECATED",
5
+ "title": "Deprecated configuration",
6
+ "what": [
7
+ "The 'timeout' field in config.json is deprecated."
8
+ ],
9
+ "why": [
10
+ "This field will be removed in v2.0."
11
+ ],
12
+ "fix": [
13
+ "Use 'request_timeout_ms' instead.",
14
+ "Re-run: demo-cli validate config.json --dry-run"
15
+ ]
16
+ }
@@ -0,0 +1,3 @@
1
+ Error: Connection refused
2
+ The server at 192.168.1.100:8080 is not responding.
3
+ Please check the service is running.
@@ -0,0 +1,9 @@
1
+ {
2
+ "level": "ERROR",
3
+ "code": "PAY001",
4
+ "id": "PAY.EXPORT.SFTP.AUTH",
5
+ "title": "Payment export failed",
6
+ "what": ["Could not upload the file."],
7
+ "why": ["Credentials were rejected."],
8
+ "fix": ["Verify credentials.", "Re-run: payroll export --batch 2026-01-26 --dry-run"]
9
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "level": "ERROR",
3
+ "title": "Payment export failed",
4
+ "what": ["Could not upload the file."],
5
+ "why": ["Credentials were rejected."],
6
+ "fix": ["Verify credentials."]
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "level": "ERROR",
3
+ "code": "CFG001",
4
+ "what": "Configuration file missing",
5
+ "why": "The app cannot start without config.yaml",
6
+ "fix": "Create config.yaml in the project root"
7
+ }
@@ -0,0 +1,20 @@
1
+ ASSIST (Cognitive Load):
2
+ - Anchored to: DEMO.NETWORK.TIMEOUT
3
+ - Confidence: High
4
+
5
+ Goal: Get back to a known-good state.
6
+
7
+ Safest next step:
8
+ Start by confirming the cause described under 'Why'.
9
+
10
+ Plan:
11
+ First: Check your network connection.
12
+ Next: Verify the server is reachable: ping api.example.com.
13
+ Last: Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run.
14
+
15
+ Next (SAFE):
16
+ Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run
17
+
18
+ Notes:
19
+ - Original title: Request timed out
20
+ - This assist block is additive; it does not replace the tool's output.
@@ -0,0 +1,20 @@
1
+ ASSIST (Dyslexia):
2
+
3
+ Anchored ID: DEMO.NETWORK.TIMEOUT
4
+
5
+ Confidence: High
6
+
7
+ Safest next step:
8
+ Start by confirming the cause described under 'Why', then apply the first Fix step.
9
+
10
+ Plan:
11
+ - Step 1: Check your network connection.
12
+ - Step 2: Verify the server is reachable: ping api.example.com
13
+ - Step 3: Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run
14
+
15
+ Next safe command:
16
+ Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run
17
+
18
+ Notes:
19
+ - Original title: Request timed out
20
+ - This assist block is additive; it does not replace the tool's output.
@@ -0,0 +1,18 @@
1
+ ASSIST (Low Vision):
2
+ - Anchored to: DEMO.NETWORK.TIMEOUT
3
+ - Confidence: High
4
+
5
+ Safest next step:
6
+ Start by confirming the cause described under 'Why', then apply the first Fix step.
7
+
8
+ Plan:
9
+ 1) Check your network connection.
10
+ 2) Verify the server is reachable: ping api.example.com
11
+ 3) Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run
12
+
13
+ Next (SAFE):
14
+ Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run
15
+
16
+ Notes:
17
+ - Original title: Request timed out
18
+ - This assist block is additive; it does not replace the tool's output.
@@ -0,0 +1,14 @@
1
+ ASSIST (Plain Language)
2
+ ID: DEMO.NETWORK.TIMEOUT
3
+ Confidence: High
4
+
5
+ What to do next:
6
+ Start by confirming the cause described under 'Why', then apply the first Fix step.
7
+
8
+ Steps:
9
+ 1. Check your network connection.
10
+ 2. Verify the server is reachable: ping api.example.com.
11
+ 3. Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run.
12
+
13
+ Safe command:
14
+ Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run
@@ -0,0 +1,19 @@
1
+ ASSIST. Profile: Screen reader.
2
+ Anchored I D: DEMO.NETWORK.TIMEOUT.
3
+ Confidence: High.
4
+
5
+ Summary: Request timed out.
6
+
7
+ Safest next step: Start by confirming the cause described under 'Why', then apply the first Fix step.
8
+
9
+ Steps:
10
+ Step 1: Check your network connection.
11
+ Step 2: Verify the server is reachable: ping api.example.com.
12
+ Step 3: Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run.
13
+
14
+ Next safe command:
15
+ Re-run with increased timeout: demo-cli network-timeout --timeout 60 --dry-run
16
+
17
+ Notes:
18
+ Original title: Request timed out.
19
+ This assist block is additive.
@@ -0,0 +1,16 @@
1
+ ASSIST. Profile: Screen reader.
2
+ Anchored I D: PAY.EXPORT.SFTP.AUTH.
3
+ Confidence: High.
4
+
5
+ Summary: Payment export failed.
6
+
7
+ Safest next step: Confirm the cause described under Why.
8
+
9
+ Steps:
10
+ Step 1: Verify credentials.
11
+ Step 2: Re-run: payroll export to batch 2026-01-26 to dry-run.
12
+
13
+ Next safe command:
14
+ payroll export --batch 2026-01-26 --dry-run
15
+
16
+ Note: Original title: Payment export failed.
@@ -0,0 +1,14 @@
1
+ ASSIST. Profile: Screen reader.
2
+ Anchored I D: none.
3
+ Confidence: Low.
4
+
5
+ Summary: The input did not include a stable error identifier.
6
+
7
+ Safest next step: Follow the tool's Fix steps.
8
+
9
+ Steps:
10
+ Step 1: Re-run the command with increased verbosity/logging.
11
+ Step 2: Update the tool to emit I D and What/Why/Fix blocks.
12
+ Step 3: If this is your tool.
13
+
14
+ Note: No I D found.
@@ -0,0 +1,14 @@
1
+ ASSIST. Profile: Screen reader.
2
+ Anchored I D: PAY.EXPORT.SFTP.AUTH.
3
+ Confidence: Medium.
4
+
5
+ Summary: An error was detected with partial information.
6
+
7
+ Safest next step: Follow the tool's Fix steps.
8
+
9
+ Steps:
10
+ Step 1: Verify username/password or S S H key.
11
+ Step 2: Re-run: payroll export to batch 2026-01-26 to dry-run.
12
+
13
+ Next safe command:
14
+ payroll export --batch 2026-01-26 --dry-run
@@ -0,0 +1,11 @@
1
+ [ERROR] Payment export failed (ID: PAY.EXPORT.SFTP.AUTH)
2
+
3
+ What:
4
+ Could not upload the NACHA file.
5
+
6
+ Why:
7
+ Credentials were rejected.
8
+
9
+ Fix:
10
+ Verify username/password or SSH key.
11
+ Re-run: payroll export --batch 2026-01-26 --dry-run
@@ -0,0 +1,2 @@
1
+ ERROR: It failed
2
+ Please try again