skills/visual-tree/SKILL.md
Capture a spatial hierarchy of rendered DOM elements from any webpage. Injects a pre-built script via playwright-cli that walks the DOM, detects layout grids, extracts backgrounds, prunes invisible nodes, promotes elements rendered outside their DOM parent (overlays, fixed navs, modals), and tags overlay nodes with occlusion metadata. Returns three outputs: LLM-friendly indented text, structured JSON tree, and a nodeMap mapping positional IDs to CSS selectors with background and overlay data. Use before page decomposition, overlay detection, brand extraction, or any workflow that needs structured page analysis. Triggers on: visual tree, capture tree, page structure, page hierarchy, DOM tree, capture visual, page analysis, extract tree.
npx skillsauth add catalan-adobe/skills visual-treeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Capture a spatial hierarchy of rendered DOM elements from any webpage via
playwright-cli. Returns three outputs for downstream consumption.
playwright-cli available (run playwright-cli help to verify)if [[ -n "${CLAUDE_SKILL_DIR:-}" ]]; then
VT_BUNDLE="${CLAUDE_SKILL_DIR}/scripts/visual-tree-bundle.js"
else
VT_BUNDLE="$(find ~/.claude \
-path "*/visual-tree/scripts/visual-tree-bundle.js" \
-type f 2>/dev/null | head -1)"
fi
Verify the path is non-empty before continuing.
| Parameter | Default | Description |
|-----------|---------|-------------|
| minWidth | 900 | Minimum element width in px. Elements narrower than this are excluded. position: fixed elements always pass regardless. Lower for more detail (e.g., 300 for mobile). |
Run the script location block above and store the path in VT_BUNDLE.
If the path is empty, report an error and stop.
Inject the bundle via initScript in the playwright-cli config, then
capture with a pure expression eval. Do NOT use inline $(cat) or IIFE
wrappers — playwright-cli eval only accepts pure expressions (it wraps
them as () => (EXPR) internally, so function bodies with statements
fail).
MINWIDTH=900 # or caller-specified value
# Build config with initScript — injects bundle before navigation
VT_CONFIG="/tmp/vt-config-$$.json"
echo "{\"browser\":{\"initScript\":[\"$VT_BUNDLE\"]}}" > "$VT_CONFIG"
# Open page (or use existing session) — bundle creates window.__visualTree
playwright-cli --config="$VT_CONFIG" open "$URL"
sleep 2
# Capture — pure expression, no IIFE
VT_RESULT=$(playwright-cli eval \
"JSON.stringify(window.__visualTree.captureVisualTree($MINWIDTH))")
rm -f "$VT_CONFIG"
Parse the returned JSON string.
Present three sections to the caller:
1. Visual Tree (text format)
The primary output for LLM consumers. Show in a code block:
r @0,0 1440x5667
rc1 [3x1] @0,0 1440x83 "Header text..."
rc2 @0,83 1440x5216
rc2c1 [bg:image] @0,83 1440x410 "Hero text..."
...
Format: ID [role] [CxR] [bg:type] @x,y wxh "text..."
2. Node Map
Positional ID to metadata lookup. Show as JSON. Each entry contains:
selector: CSS selector for the DOM elementbackground (optional): { type, value, raw, source }overlay (optional): { occluding: [sibling IDs this node covers] }Overlay entries indicate the node was promoted from a deeper DOM position to root level because it rendered outside its parent's bounds (e.g., cookie banners, fixed navs, modals).
3. JSON Tree
Full structured tree. Show as JSON only if the caller requests it, otherwise mention it is available. Each node contains: tag, selector, bounds, text, role, layout, background, children.
The bundle runs 6 passes on the DOM:
document.body, captures bounding boxes,
backgrounds, text, roles, layout detection. Filters by minWidth.
position: fixed elements bypass the width filter.overlay.occluding listing which siblings they visually cover.playwright-cli goto <url> then
wait for network idle) for best results.tools
Reduce a webpage to a structural skeleton with semantic tokens. Two-phase pipeline: Phase 1 injects a browser script that tokenizes content ({TEXT}, {HEADING:n}, {IMAGE:WxH}, {CTA:label}, {LINK:label}, {INPUT:type}, {VIDEO}, {ICON}). Phase 2 applies LLM structural reasoning to collapse repeated patterns ({REPEAT:N}), remove decorative wrappers, strip utility classes, and produce skeleton.html + manifest.json. Use when migrating pages to EDS, analyzing page structure, extracting page blueprints, or preparing input for GenAI block generation. Triggers on: reduce page, page skeleton, page blueprint, extract structure, tokenize page, page reduction, structural skeleton, reduce URL.
tools
Summarize any video by analyzing both audio and visuals. Downloads via yt-dlp, extracts transcript (YouTube captions or Whisper), pulls scene-detected keyframes, and produces a multimodal summary with clickable timestamped YouTube links. Use this skill whenever the user wants to summarize a YouTube video, digest a talk or tutorial, get notes from a video, extract key points from a recording, or says things like "tl;dw", "summarize this video", "what's in this video", or pastes a YouTube URL and asks for a summary. Also triggers for non-YouTube URLs that yt-dlp supports.
development
Design and build web UIs with Adobe Spectrum 2 design system. Applies S2 layout principles, visual hierarchy, spacing, and component composition to produce accessible interfaces. Outputs vanilla CSS with Spectrum tokens (static pages) or Spectrum Web Components (interactive apps). Recommends tier based on complexity. Covers sp-theme setup, side-effect imports, overlay system, form patterns, --mod-* token customization, and 14 critical gotchas. Use for: spectrum 2 web, SWC, sp-button, sp-theme, build UI with spectrum, S2 layout, spectrum application, adobe design system, web component form, spectrum overlay.
development
Control Slack via CDP or headless API tokens. Navigate channels, read/send messages, search conversations, check unreads, and manage status. Two modes: CDP (Slack desktop with --remote-debugging-port) for full UI control, or headless (xoxp/xoxb token) for data operations without Slack running. Triggers on: slack, read slack, search slack, slack unreads, send slack message, slack status, navigate slack, check slack, slack messages, go to channel, slack DM.