visual-feedback-loop
Skill9 starsChanged 29 days agoMITView on GitHub
AI agent visual feedback loop for any web app. Use when iterating on visual code (UI, canvas, 3D, SVG, charts, animations) and you need to SEE the rendered result to evaluate quality. Covers: dev-screenshot API pattern (GET trigger → SSE → client capture → POST back → file saved), parameterized rendering, metadata sidecars, visual regression with pixel diff, WebMCP tool registration, and console fallbacks. Activate on: 'take a screenshot', 'show me the render', 'visual QA', 'compare before/after', 'pixel diff', or any iterative visual work where the agent needs to inspect rendered output.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- sbrudz/agent-skillstheir own version, first seen Nov 1, 2026
- yogvidwankhede/vishwakarmatheir own version, first seen Sep 26, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- sbrudz/agent-skills★ 2same name
- yogvidwankhede/vishwakarma★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository13 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agent-sessionsSkill
- apple-books-mcpSkill
- blender-mcpSkill
- cinema4d-mcpSkill
- figma-bridgeSkill
- figma-context-mcpSkill
- fluid-interfacesSkill
- pdf-look-scannedSkill
- reverse-engineer-jsSkill
- threejs-perf-loadingSkill
- time-lensSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 2 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 66
Use this to trace which code state + params produced a screenshot — critical when iterating across multiple code changes.
- Distinctive: line 74
Read diff image + check RMSE value
- Very specific: line 80
Always
Read .screenshots/latest.webpafter capture: Never assume the render is correct.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Visual Feedback Loop
Capture, inspect, and compare visual output from a running web app during iterative development.
How It Works
Agent (CLI) Server Browser
|--- GET /api/dev-screenshot -->|--- SSE "capture" ----------->|
| ?param=value | |-- capture canvas
| |<-- POST { dataUrl } ---------|
| | writes:
| | .screenshots/{UTC}.webp
| | .screenshots/{UTC}.json (metadata)
| | .screenshots/latest.webp (convenience copy)
|<-- { ok, path, latest } ------|Agent can't access the browser directly. Server relays: GET triggers → SSE notifies browser → browser captures and POSTs back → GET resolves.
Usage
Capture current view:
curl http://localhost:3000/api/dev-screenshotCapture with params (app-specific — browser client interprets them):
curl 'http://localhost:3000/api/dev-screenshot?component=header&theme=dark'
curl 'http://localhost:3000/api/dev-screenshot?letter=б&depth=0.8'Then read the result. Response includes path (timestamped file) and latest (convenience copy):
Read .screenshots/latest.webpVisual Regression (pixel diff)
Compare against a ground truth screenshot using ImageMagick:
magick compare -metric RMSE .screenshots/ground-truth.webp .screenshots/latest.webp .screenshots/diff.webpRMSE output: 0.01 = ~1% difference (rendering noise), 0.03+ = visible change. Save diff image for inspection.
Metadata Sidecars
Each screenshot gets a JSON sidecar with the same UTC timestamp:
{
"timestamp": "2026-02-25T08:22:12.655Z",
"git": { "commit": "0a5726f", "dirty": true },
"params": { "letter": "о", "chamferModel": "membrane", "cameraView": "front" },
"format": "webp",
"file": "2026-02-25T08-22-12-655Z.webp"
}Use this to trace which code state + params produced a screenshot — critical when iterating across multiple code changes.
A/B Comparison Workflow
- Capture ground truth:
curl '...?letter=о'→ note the{UTC}.webpfilename - Make code changes, refresh browser
- Capture again:
curl '...?letter=о' - Diff:
magick compare -metric RMSE .screenshots/{ground-truth}.webp .screenshots/latest.webp .screenshots/diff.webp - Read diff image + check RMSE value
Console fallback: await window.__takeDevScreenshot()
Rules
- Always
Read .screenshots/latest.webpafter capture. Never assume the render is correct. - Browser tab must be open at the app URL. Timeout = no SSE connection = ask user to refresh.
- One request at a time. Second GET returns 409. Wait for first to resolve (success/error/10s timeout).
- Errors return instantly, not as timeouts. Client POSTs errors back:
{ ok: false, error: "..." }. - HMR resilience. Store server-side SSE state on
globalThisso it survives module reloads. EventSource auto-reconnects on the client. If screenshots still fail after code changes, ask user to refresh. - HMR does NOT update offscreen render paths. Closures in
useEffectcapture stale module references. After code changes to rendering logic, always ask user to hard refresh (Cmd+Shift+R on macOS, Ctrl+Shift+R on Windows/Linux).
Troubleshooting
| Symptom | Fix |
| Timeout: browser did not respond | Open/refresh app in browser |
| 409: already in progress | Wait for timeout (10s) |
| Black/empty image | Refresh browser tab |
| Works once, then times out | HMR broke SSE — refresh tab (rare if using globalThis pattern) |
| Code changes not reflected in screenshots | HMR doesn't update offscreen renderers — hard refresh (Cmd+Shift+R on macOS, Ctrl+Shift+R on Windows/Linux) |
| Comparing screenshots from different code states | Check JSON sidecar for git commit + dirty flag |
See references/errors.md for full error reference.
Setup
The pattern is framework-agnostic — it only requires an HTTP server with GET/POST routes and SSE. The reference implementation uses Next.js, but the same approach works with Express, Fastify, Hono, Vite dev server plugins, or any Node.js HTTP server.
See references/setup-nextjs.md for a complete Next.js implementation (API route, SSE listener, WebMCP registration). Adapt the route handler to your framework — the client-side SSE listener and capture logic are identical regardless of server framework.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

