Skills

Verify Keyboard Access

Verify that every interactive control on a page can take keyboard focus and that its...

Install

npx skills add reticlehq/reticle --skill verify-keyboard-access -g -a claude-code -y
Repository
reticlehq/reticle1.3k
Category
Design
Updated
3d ago
License
Apache-2.0
Context cost
Lightabout 1,280 tokens
Runs scripts
No, instructions only

What it does

Verify that every interactive control on a page can take keyboard focus and that its primary action fires from the keyboard rather than only the mouse, and say plainly that Tab order cannot be verified today. Use when a component was hand-tested with a mouse, a custom dropdown/modal/combobox was added, or an accessibility report flags an unreachable control.

Reachable is not the same as operable

A <div onClick> styled to look like a button can look reachable (plenty of component libraries hand out tabindex="0" for free) and still do nothing when you press Enter on it. Being able to take focus proves a control is reachable, not that it works.

Reticle can drive both halves in the running app. Not set up? Follow the reticle skill: it installs Reticle, asks the user before init changes the app's files, and proves one flow.

Read this before you start: Tab order cannot be verified today

press always goes through a synthetic key event, and a synthetic Tab does not move focus. That is true in every mode, including reticle drive: there is no mode in which an agent can prove focus order. Do not go looking for one, and do not report a Tab-order result as passed or failed. Report it as unknown.

What this skill can prove is narrower: that each control can take focus, and that its primary action fires from the keyboard.

Confirm the session is healthy

Confirm a live session exists for the page and can render and observe:

reticle_session({ action: "list" })

In a disconnected, hidden or throttled tab, a key press can be accepted while timers, rendering and later observation do not advance, so nothing you read back is trustworthy. Get a usable context first, for example a leased tab:

reticle_run({ tool: "reticle_lease", args: { action: "acquire", url } })

Pass refuseWhenThrottled: true on the action so a paused tab fails loudly instead of silently doing nothing. If you cannot get a healthy session, report the run as blocked, not passed, and do not keep retrying against it.

List the controls

List every interactive control before touching the keyboard, or you will only test the ones you already knew about:

reticle_look({ sessionId, action: "page", mode: "interactive" })
Read the whole SKILL.md on GitHub

More in Design