A command-line tool for analyzing the visual tree, layout, and framework of Windows desktop applications.

Install

mkdir -p .claude/skills/lvt && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/10104" && unzip -o skill.zip -d .claude/skills/lvt && rm skill.zip

Installs to .claude/skills/lvt

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Inspect running Windows application UIs using the lvt (Live Visual Tree) CLI tool. Use this skill when you need to understand a Windows app's visual tree structure, capture annotated screenshots, detect UI frameworks, or find specific UI elements for verification or interaction planning.
288 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

Key capabilities

  • Inspect visual tree
  • Capture annotated screenshots
  • Detect UI frameworks
  • Find UI elements
  • Plan UI interactions

How it works

It inspects the visual tree of running Windows applications, providing element IDs, bounds, and framework information.

Inputs & outputs

You give it
Target Windows process
You get back
Visual tree structure or screenshot

When to use lvt

  • Locate specific UI elements for automation
  • Verify UI changes after a build update
  • Capture an annotated screenshot for documentation

About this skill

Inspect Windows application UI with lvt

When to use

Use lvt whenever you need to understand the visual content or structure of a running Windows application. Common scenarios:

  • UI verification — confirm that a UI change was applied correctly (e.g. a button label changed, a dialog appeared)
  • Finding UI elements — locate a specific control, menu item, or text field in an app's visual tree
  • Screenshot capture — take an annotated screenshot of an app with element IDs overlaid
  • Framework detection — determine which UI frameworks an app uses (Win32, ComCtl, XAML, WinUI 3)
  • Automated UI interaction planning — get element IDs and bounds to plan mouse clicks or keyboard input
  • Automation identity — get AutomationIds, control types, and supported patterns with --uia
  • Driving an app — click, toggle, type, set values, and wait for the UI to settle

Prerequisites

Before using lvt, ensure lvt.exe and lvt_tap.dll are available. If they are not already on PATH or in the current directory, download and extract them automatically:

# Download the latest release zip and extract to ~/.lvt
$lvtDir = "$env:USERPROFILE\.lvt"
if (-not (Test-Path "$lvtDir\lvt.exe")) {
  New-Item -ItemType Directory -Path $lvtDir -Force | Out-Null
  $release = Invoke-RestMethod "https://api.github.com/repos/asklar/lvt/releases/latest"
  $asset = $release.assets | Where-Object { $_.name -like "lvt-*-x64.zip" } | Select-Object -First 1
  $zip = "$env:TEMP\lvt.zip"
  Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $zip
  Expand-Archive -Path $zip -DestinationPath $lvtDir -Force
  Remove-Item $zip
}
# Run lvt from the install directory
& "$lvtDir\lvt.exe" --help

Once downloaded, lvt.exe persists in ~/.lvt/ and does not need to be downloaded again.

Usage

Target an application

You must specify exactly one target. Pick the most convenient option:

# By process name (most common — omit .exe extension if you like)
lvt --name notepad

# By window title substring
lvt --title "Untitled - Notepad"

# By PID
lvt --pid 1234

# By HWND (hex)
lvt --hwnd 0x1A0B3C

Get the visual tree

# JSON output (default) — best for programmatic parsing
lvt --name notepad

# XML output — more compact, easier to read
lvt --name notepad --format xml

# Write to a file instead of stdout
lvt --name notepad --output tree.json

Capture a screenshot

# Screenshot only (no tree output)
lvt screenshot --name notepad --output out.png

# Screenshot + tree output together
lvt screenshot --name notepad --output out.png
lvt dump --name notepad

Screenshots are annotated with element IDs (e0, e1, …) overlaid on each element, making it easy to correlate visual positions with tree nodes.

Scope to a subtree

When the full tree is too large, scope to a specific element:

# Only show element e5 and its descendants, up to 3 levels deep
lvt dump --name myapp --element e5 --depth 3

Detect frameworks only

lvt frameworks --name notepad

Get the UI Automation tree

Use --uia when you need to act on the app rather than just describe it. It emits the UI Automation tree, where elements carry the identifiers and state an automation client needs.

# Automation-grade view
lvt dump --uia --name myapp

# Narrower (content) or wider (raw) views
lvt dump --uia --uia-view content --name myapp

# Look up one element by its UIA RuntimeId
lvt query uia:42.3150138.4.5 --name myapp

Prefer --uia when you want to answer "which control do I click, and can I?" — AutomationId gives a stable handle and SupportedPatterns tells you what the element can actually do (Invoke = clickable, Value = settable text, Toggle = checkable, ExpandCollapse = expandable).

--uia also works when the target's architecture differs from lvt's, which the visual tree cannot do.

Drive the app

lvt can act on elements, not just read them. Every interaction verb resolves its <ref> against a UIA walk, so it implies --uia.

# Click a button. Uses the Invoke pattern where possible, which does not steal
# focus or move the cursor.
lvt click e6 --name myapp

# Flip a checkbox, set a text box, type, send a chord
lvt toggle e7 --name myapp
lvt set-value e4 "hello" --name myapp
lvt type "some text" --focus-first e4 --name myapp
lvt press-key "Ctrl+S" --name myapp

# Wait for the UI to catch up before the next step
lvt wait-for e9 --wait-prop IsEnabled=true --name myapp

The result JSON reports how the action was performed:

{ "action": "click", "ok": true, "method": "InvokePattern",
  "result": { "AutomationId": "PrimaryButton", "...": "..." } }
  • method distinguishes a quiet UIA pattern from SendInput. Synthetic input steals focus and needs the window on top; a pattern does not.
  • result is the element after the action, so the effect can be confirmed without a second walk.
  • On failure ok is false, error explains whether the pattern was missing or present but refused, and the exit code is non-zero.

Use SupportedPatterns from the tree to choose the verb: Invoke means clickable, Toggle checkable, Value settable, ExpandCollapse expandable.

After any action that changes the UI, prefer wait-for over sleeping.

Choosing a reference matters when the UI changes shape: eN is positional and uia:<RuntimeId> is tied to the element's current host window, so expanding a combo box (which reparents it into a popup) invalidates both. The durable key survives. Use eN for one-shot commands against a static UI, and the durable key when acting across a structural change.

Interpreting the output

Element IDs

Every element gets a stable ID like e0, e1, e2, etc., assigned in depth-first order. These IDs are consistent within a single invocation — use them to:

  • Reference specific elements in follow-up commands (--element e5)
  • Correlate screenshot annotations with tree nodes
  • Identify click targets by combining element ID with its bounds

Key element properties

PropertyDescription
idStable element ID (e.g. e0)
typeElement type name (e.g. Window, Button, TextBlock)
frameworkWhich framework owns this element (win32, comctl, xaml, winui3)
classNameWin32 window class name (Win32/ComCtl elements)
textVisible text content or window title
boundsScreen-relative bounding rectangle {x, y, width, height}
childrenNested child elements

Key --uia element properties

With --uia, elements carry automation identity instead of framework internals. These live under properties in JSON output:

PropertyDescription
AutomationIdStable, developer-assigned identifier — the best handle for a control
ControlTypeUIA control type (Button, Edit, CheckBox, TreeItem, …)
SupportedPatternsWhat the element can do (Invoke, Value, Toggle, ExpandCollapse, Scroll, …)
RuntimeIdPer-element handle usable as query uia:<RuntimeId>
FrameworkIdUnderlying framework (Win32, XAML, WPF, WinForm, …)
IsEnabled, IsOffscreen, HasKeyboardFocusWhether the element is actually actionable right now
Value.Value, Toggle.ToggleState, ExpandCollapse.StateCurrent state, present only when the owning pattern is supported

Pattern state is only emitted where the pattern is supported, so the presence of Toggle.ToggleState is itself a reliable signal that the element is checkable.

JSON example

{
  "target": { "hwnd": "0x001A0B3C", "pid": 12345, "processName": "Notepad.exe" },
  "frameworks": ["win32", "winui3"],
  "root": {
    "id": "e0",
    "type": "Window",
    "framework": "win32",
    "className": "Notepad",
    "text": "Untitled - Notepad",
    "bounds": { "x": 100, "y": 100, "width": 800, "height": 600 },
    "children": [ ... ]
  }
}

XML example

<LiveVisualTree hwnd="0x001A0B3C" pid="12345" process="Notepad.exe" frameworks="win32,winui3">
  <Window id="e0" framework="win32" className="Notepad" text="Untitled - Notepad" bounds="100,100,800,600">
    <ContentPresenter id="e1" framework="winui3" bounds="108,140,784,552" />
  </Window>
</LiveVisualTree>

Recommended workflow

  1. Start the target app if it isn't already running
  2. Run lvt --name <app> --format xml to get a quick overview of the UI tree
  3. Take a screenshot with lvt screenshot --name <app> --output ui.png to see the visual layout with element IDs
  4. Drill into a subtree with --element <id> --depth <n> if the tree is large
  5. Use element IDs and bounds to plan any UI interactions (clicks, keyboard input)

Tips

  • Use --format xml for human-readable output and --format json for programmatic parsing
  • If the tree is very large, use --depth to limit traversal depth first, then drill deeper with --element
  • Element IDs change between invocations if the UI structure changes — always re-query before acting on stale IDs
  • The tool requires no special permissions beyond being able to read the target process (same user session)
  • For XAML/WinUI 3 apps, lvt injects a helper DLL into the target — this is safe and non-destructive but means lvt_tap.dll must be next to lvt.exe

When not to use it

  • Non-Windows applications

Prerequisites

lvt.exelvt_tap.dll

Limitations

  • Requires read access to target process

How it compares

It allows for programmatic inspection of Windows UI elements, facilitating automated interaction planning.

Compared to similar skills

lvt side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
lvt (this skill)05moNo flagsIntermediate
web-design-guidelines326moNo flagsBeginner
tui-validate45moReviewIntermediate
ui-visual-validator14moNo flagsIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry