ER

erhe-headless-verify

Automates E2E verification of editor behavior using headless Vulkan builds and programmatic MCP scripts.

Install

mkdir -p .claude/skills/erhe-headless-verify && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/16874" && unzip -o skill.zip -d .claude/skills/erhe-headless-verify && rm skill.zip

Installs to .claude/skills/erhe-headless-verify

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.

Verify editor behavior end-to-end without a display -- build the headless Vulkan editor, launch it, wait for its embedded MCP server, drive it with scripts/mcp_call.py (scene queries and mutations, geometry graph tools, undo/redo, capture_screenshot), read the screenshot PNG to SEE the result, then clean up. Use this whenever a change needs runtime verification and no interactive UI is required or no live display is available -- "does the mesh render", "does save/load round-trip", "does undo restore state", "what does the viewport look like now". This is the standard verification loop for editor changes on Windows; the windowed build cannot capture screenshots (returns "Frame capture not available") and aborts at startup when the display is off/asleep.
762 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • →Build the headless Vulkan editor
  • →Launch the editor and wait for its MCP server
  • →Drive the editor with `scripts/mcp_call.py`
  • →Read screenshot PNGs to verify visual results
  • →Clean up editor processes and temporary files
  • →Verify editor behavior end-to-end without a display

How it works

The skill builds and launches a headless Vulkan editor, drives it via an embedded MCP server using Python scripts, captures screenshots, and reads them to verify editor behavior without a display.

Inputs & outputs

You give it
Editor changes or verification tasks
You get back
Screenshot PNGs, server info, or tool output verifying editor behavior

When to use erhe-headless-verify

  • →verify mesh rendering headlessly
  • →test undo/redo functionality
  • →verify save/load round-trip

About this skill

erhe headless verification (headless Vulkan build + in-editor MCP)

The condensed run-book for the loop used to verify editor changes headlessly. Full reference: doc/agents/editor_runs.md.

Step 1 -- build

cmake --build build_vs2026_vulkan_headless --target editor --config Debug

If build_vs2026_vulkan_headless/ does not exist, configure once with scripts\configure_vs2026_vulkan_headless.bat. (The windowed ninja build scripts\build_ninja_win_vulkan.bat editor verifies compilation faster; capture_screenshot works in both builds since 2026-08-08, so headless mainly buys display independence.)

Step 2 -- launch and wait for the MCP server (NEVER blind-sleep)

FIRST kill any editor left over from a previous run. A stale editor.exe keeps port 3743 and SILENTLY eats every MCP call, so you drive an OLD binary and see impossible results (a fix that "does nothing", node counts that grow across runs) -- this wastes a lot of time. Then launch from the repo root (config/, res/, logs/ are cwd-relative) and poll logs/log.txt for the listening line (startup takes a variable few seconds; the port can fall back within [3743, 3763)):

Get-Process editor -ErrorAction SilentlyContinue | Stop-Process -Force   # no stale server on 3743
Start-Sleep -Milliseconds 800
if (Test-Path logs\log.txt) { Clear-Content logs\log.txt }
$p = Start-Process -FilePath "build_vs2026_vulkan_headless\bin\Debug\editor.exe" -WorkingDirectory (Get-Location) -PassThru -WindowStyle Hidden
for ($i = 0; $i -lt 60; $i++) {
    Start-Sleep -Milliseconds 1000
    if ((Test-Path logs\log.txt) -and (Select-String -Path logs\log.txt -Pattern "MCP server: listening" -Quiet)) { break }
}
Select-String -Path logs\log.txt -Pattern "MCP server: listening"   # "... on 127.0.0.1:3743 (pid <pid>, built <ts>)"

Then CONFIRM you are talking to the process you just launched (not a stale one):

py -3 scripts/mcp_call.py get_server_info    # { name, version, pid, build, port }

Assert the reported pid == $p.Id and build is your just-built binary; a mismatch, or a fallback port (3744+) in the listening line, means another editor.exe owns 3743. When that editor is a leftover of yours, kill it and relaunch; when it may be the user's own editor, leave it running and drive yours on the port from the listening line (ERHE_MCP_PORT=<port> or --port <port>). Remember $p.Id for cleanup.

Step 3 -- drive it with scripts/mcp_call.py

py -3 scripts/mcp_call.py --list                          # discover tools (--list <substring> filters)
py -3 scripts/mcp_call.py list_scenes
py -3 scripts/mcp_call.py render_scene_image b64:<base64-of-{"camera":{"eye":[0,2,5],"target":[0,0,0]}}>  # -> logs/render_scene_image.png
py -3 scripts/mcp_call.py capture_screenshot              # -> logs/mcp_screenshot.png
py -3 scripts/mcp_call.py get_scene_nodes b64:<base64-of-{"scene_name":"Default Scene"}>
  • Pass tool arguments as b64:<base64 of the JSON object> (or - + stdin). Do NOT inline JSON with spaces on a PowerShell command line -- PowerShell 5.1 mangles the quotes. In PowerShell: $b64 = "b64:" + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($json)).
  • Non-default port: --port <n> (from the listening line).
  • Mutations (create_shape, geometry_graph_*, transform_selection, ...) take effect synchronously -- query tools immediately reflect them, and the geometry graph tools are undoable (drive undo / redo as tools, inspect with get_undo_redo_stack).
  • Long evaluations: a mutation that triggers heavy main-thread work makes the server reply "Request timed out" (-32000) -- but the queued request STILL EXECUTES when the main thread gets to it ("Server busy: request queue full" requests are dropped instead). Retry queries freely; NEVER blindly re-issue a timed-out mutation (it double-executes and corrupts undo/redo counts) -- poll a cheap query until the server drains. Reference implementation: call() / mutate() in scripts/geometry_nodes_smoke_test.py.
  • Geometry nodes regression sweep: py -3 scripts/geometry_nodes_smoke_test.py (65 checks; exit 0 = pass). Its incremental section needs config/editor/logging.json "editor.graph_editor": "trace" before launch -- revert before committing. Clean up res/editor/graphs/smoke_*.json after.
  • Pick the image tool by what is verified. Scene content (rendering, lighting, GI, materials, A/B comparisons): render_scene_image renders the scene offscreen through an explicit camera (camera {eye, target, fov_y_degrees, ...} or camera_node) at an explicit width x height; no ImGui window, viewport size or overlay (grid, gizmo, selection outline) affects it, and output: "linear" gives HDR floats (.pfm) plus luminance stats. Editor UI (windows, widgets, gizmos, hover / selection feedback): capture_screenshot of the whole editor window. Details: doc/agents/mcp_server_usage.md "Image Tools". Neither can run inside batch.
  • After render_scene_image / capture_screenshot, Read the PNG to actually see the frame. A useful trick to identify an object visually: select it and transform_selection it, then re-screenshot and diff by eye.
  • Missing capability? Add a new MCP tool (handler + dispatch entry in src/editor/mcp/mcp_server*.{hpp,cpp}, schema in config/editor/mcp_tools.json) rather than working around it -- doc/agents/editor_runs.md calls this out as first-class debugging infrastructure.

Step 4 -- clean up (always)

Stop-Process -Id <pid> -Force
git status --short    # confirm the run dirtied no tracked file

An ERHE_AI_DRIVER=1 run writes no config file (doc/agents/editor_runs.md): the tracked config/editor/*.json files and the gitignored ImGui ini (config/editor/desktop_window_imgui_host_imgui.ini) are read but never written, so git status stays clean. Leave the ini alone.

Gotchas

  • capture_screenshot works in BOTH builds (windowed since 2026-08-08: one-shot swapchain readback with a one-frame deferral inside the MCP server -- transparent to the caller). For deeper windowed GPU inspection (textures, pixel debugging) use the RenderDoc fork / erhe-renderdoc-gpu-debug.
  • The windowed editor needs a live, awake display; headless does not.
  • The scripted startup scene comes from config/editor/commands.json -- adjust it when a test needs a reproducible scene before init completes.
  • One editor instance at a time. A second instance binds the next port in [3743, 3763), so your mcp_call.py (which defaults to 3743) keeps hitting the FIRST, stale one. Always kill all editors before launching (Step 2) and verify get_server_info reports the pid/build you expect. get_server_info + the (pid ..., built ...) suffix on the listening line exist precisely for this.

When not to use it

  • →When an interactive UI is required
  • →When a live display is available for verification
  • →When the windowed build is sufficient for testing

Limitations

  • →Requires a headless Vulkan build
  • →Windowed build cannot capture screenshots
  • →Requires manual cleanup of editor processes

How it compares

This skill enables end-to-end editor verification without a display by using a headless build, an embedded server, and programmatic screenshot capture, which is not possible with the windowed build.

Compared to similar skills

erhe-headless-verify side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
erhe-headless-verify (this skill)03moReviewAdvanced
amc-run-sample-calibration03moCautionIntermediate
webapp-testing3536moReviewIntermediate
dev-browser537moReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

amc-run-sample-calibration

NVIDIA

Run end-to-end calibration on the shipped sample dataset (sdg_08_2_sample_data_010926.zip) against a running AMC microservice. Use when user says 'test sample dataset', 'run sample calibration', 'verify AMC install', or 'launch and test'.

00

webapp-testing

anthropics

Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.

353585

dev-browser

SawyerHood

Browser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include "go to [url]", "click on", "fill out the form", "take a screenshot", "scrape", "automate", "test the website", "log into", or any browser interaction request.

53176

playwright-browser-automation

lackeyjb

Complete browser automation with Playwright. Auto-detects dev servers, writes clean test scripts to /tmp. Test pages, fill forms, take screenshots, check responsive design, validate UX, test login flows, check links, automate any browser task. Use when user wants to test websites, automate browser interactions, validate web functionality, or perform any browser-based testing.

29146

windows-ui-automation

martinholovsky

Expert in Windows UI Automation (UIA) and Win32 APIs for desktop automation. Specializes in accessible, secure automation of Windows applications including element discovery, input simulation, and process interaction. HIGH-RISK skill requiring strict security controls for system access.

17126

qa-tester

svilupp

Browser automation QA testing skill. Systematically tests web applications for functionality, security, and usability issues. Reports findings by severity (CRITICAL/HIGH/MEDIUM/LOW) with immediate alerts for critical failures.

29113

Search skills

Search the agent skills registry