agentsclimarketplace

A11y tree snapshot with uids

Skill kjuhwa/skills-hub/skills/puppeteer/a11y-tree-snapshot-with-uids

Self-correcting knowledge corpus for Claude Code — 9 stable shape clusters, bias-correction pipeline baked into contribution flow. 47 papers, 45 techniques, 1.1k skills.

Install
npx -y skills add kjuhwa/skills-hub --skill a11y-tree-snapshot-with-uids

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Give agents an indented text snapshot of the page's accessibility tree where every node has a short opaque `uid` they can pass back to click/fill/hover tools, instead of asking the agent to construct CSS selectors.

SKILL.md

3.8 KB, as published. Nobody here has run it

A11y Tree Snapshot with Opaque UIDs

When to use

  • You're building browser automation for an LLM agent and want reliable element targeting without brittle CSS selectors.
  • Users / agents repeatedly fumble "select the login button" with screenshots+vision because class names change.
  • You need a compact, diffable representation of the page the agent can read and reason about.

How it works

  • Walk Chrome's accessibility tree (via Puppeteer's page.accessibility.snapshot() or CDP Accessibility.getFullAXTree). Each node gets a short unique uid generated server-side (e.g. 1, 2, … or ${frameIdx}_${nodeIdx}).
  • Serialize as indented text: uid=3 button "Submit" focused — role, name, useful booleans. Keep it narrow; two spaces per depth.
  • Provide a verbose mode that includes every a11y attribute. Default is terse — agents are more accurate on focused snapshots.
  • Store the server-side mapping uid → ElementHandle on the page object. Every tool that takes a uid (click(uid), fill(uid, value)) resolves it via page.getElementByUid(uid) before acting.
  • If the user has an element selected in DevTools, mark it in the snapshot: uid=3 button "Submit" [selected in the DevTools Elements panel]. Bridges human + agent collaboration.
  • Expose an optional filePath for snapshots to write to disk instead of the response, so very large pages don't consume context.

Example

// formatter - indent by depth, role + name + attrs
#formatNode(node: TextSnapshotNode, depth = 0): string {
  const attrs = [`uid=${node.id}`];
  if (node.role) attrs.push(node.role === 'none' ? 'ignored' : node.role);
  if (node.name) attrs.push(`"${node.name}"`);
  for (const [k, v] of Object.entries(node)) {
    if (EXCLUDED.has(k)) continue;
    if (v === true) attrs.push(k);
    else if (typeof v === 'string' || typeof v === 'number') attrs.push(`${k}="${v}"`);
  }
  let line = ' '.repeat(depth * 2) + attrs.join(' ');
  if (node.id === selectedElementUid) line += ' [selected in the DevTools Elements panel]';
  return line + '\n' + node.children.map(c => formatNode(c, depth + 1)).join('');
}

// consumer tools resolve uid back to a handle
const el = await page.getElementByUid(request.params.uid);
await el.click();

Gotchas

  • UIDs must be stable for the snapshot instance but can change across snapshots. Always tell the agent to call snapshot first, then act — never cache uids across tool calls.
  • The a11y tree does NOT include every DOM element. For elements with role="presentation" or no accessible role, give agents an escape hatch (evaluate_script or a CSS selector fallback), or emit them under a generic role with enough attrs to disambiguate.
  • A page that uses shadow DOM or iframes extensively produces a fragmented tree. Walk into shadow roots and iframes explicitly; document the constraint.
  • The verbose flag should be off by default. Verbose snapshots are 5-10x larger and agents only rarely need the extra attributes.
  • If the selected DevTools element isn't in the (non-verbose) a11y tree, emit a hint that instructs the agent to re-snapshot with verbose: true — otherwise they'll loop confused.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.