@reticular/speakable 1.0.3 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -159,6 +159,35 @@ Verify that the accessibility model serializes and deserializes consistently:
159
159
  speakable page.html --validate
160
160
  ```
161
161
 
162
+ ## MCP Integration (AI Assistants)
163
+
164
+ Speakable includes a Model Context Protocol (MCP) server that lets AI coding assistants analyze accessibility in real-time. Ask your assistant "check if this component is accessible" and it calls Speakable automatically.
165
+
166
+ ### Setup
167
+
168
+ Add to your MCP config (Kiro, VS Code, Cursor, Claude Desktop, Windsurf):
169
+
170
+ ```json
171
+ {
172
+ "mcpServers": {
173
+ "speakable": {
174
+ "command": "npx",
175
+ "args": ["-y", "@reticular/speakable-mcp"]
176
+ }
177
+ }
178
+ }
179
+ ```
180
+
181
+ ### Available Tools
182
+
183
+ | Tool | Description |
184
+ |------|-------------|
185
+ | `analyze_html` | Predict screen reader output for NVDA, JAWS, and VoiceOver |
186
+ | `audit_html` | Generate accessibility audit report with issues and remediation |
187
+ | `diff_html` | Compare two HTML versions for accessibility regressions |
188
+
189
+ All tools run locally — no network requests, no data leaves your machine. See the [MCP Integration docs](https://getspeakable.dev/docs/mcp-integration) for full setup instructions.
190
+
162
191
  ## CI/CD Integration
163
192
 
164
193
  ### GitHub Actions
package/dist/cli.js CHANGED
@@ -1402,6 +1402,12 @@ function renderNodeNVDA(node, announcements, c) {
1402
1402
  announcements.push(announcement);
1403
1403
  }
1404
1404
  for (const child of node.children) {
1405
+ if (child.name && child.name === node.name && node.children.length === 1) {
1406
+ for (const grandchild of child.children) {
1407
+ renderNodeNVDA(grandchild, announcements, c);
1408
+ }
1409
+ continue;
1410
+ }
1405
1411
  renderNodeNVDA(child, announcements, c);
1406
1412
  }
1407
1413
  }
@@ -1591,6 +1597,12 @@ function renderNodeJAWS(node, announcements, c) {
1591
1597
  announcements.push(announcement);
1592
1598
  }
1593
1599
  for (const child of node.children) {
1600
+ if (child.name && child.name === node.name && node.children.length === 1) {
1601
+ for (const grandchild of child.children) {
1602
+ renderNodeJAWS(grandchild, announcements, c);
1603
+ }
1604
+ continue;
1605
+ }
1594
1606
  renderNodeJAWS(child, announcements, c);
1595
1607
  }
1596
1608
  }
@@ -1800,6 +1812,12 @@ function renderNodeVoiceOver(node, announcements, c) {
1800
1812
  announcements.push(announcement);
1801
1813
  }
1802
1814
  for (const child of node.children) {
1815
+ if (child.name && child.name === node.name && node.children.length === 1) {
1816
+ for (const grandchild of child.children) {
1817
+ renderNodeVoiceOver(grandchild, announcements, c);
1818
+ }
1819
+ continue;
1820
+ }
1803
1821
  renderNodeVoiceOver(child, announcements, c);
1804
1822
  }
1805
1823
  }