ui-grab

● Local feedback for local builds

Make the UI say what you mean.

Point to a real element, describe the change in plain language, and send your agent a useful trail back to the source — file, line, context included.

A dev-server plugin for Vite. It never ships to production.

Use the live demo npm i -D vite-plugin-ui-grab
  1. Open with Alt+Shift+GNo extra app or browser extension.
  2. Keep a short queueCollect notes as you move through routes.
  3. Stay in controlReview, send, then run /grab.
live playground

See the handoff take shape.

This is the actual picker running on a small storefront. Choose an element, add a note, then send it. The dark panel on the right is the exact kind of context your agent receives. Try ask when you want an answer instead of a change.

localhost:5173
hover highlight click select Enter queue it Alt+↑ parent Esc back out
.ui-grab/queue.json
waiting

Pick something, say what should change, hit Send. What Claude Code would read shows up here.

Inspect the demo source and matched lines

The candidates come from the plugin's own ranking: exact text, then id, then aria-label and the class attribute — and a line that opens the element's tag beats one that merely mentions it. Here it runs over this page's two files; in your project, over the whole tree.

the next move

A clean handoff to Claude Code.

The batch lands in .ui-grab/queue.json. Drain it with one command, or let a zero-typing mode keep the conversation moving.

$ npm run dev
  ui-grab  queued 3 items (3 pending) → .ui-grab/queue.json
  ui-grab  woke via tmux: claude in %3

> /grab
  ⏵ Read .ui-grab/queue.json
  ⏵ Update index.html          button#place-order — 1.25×, proportions kept
  ⏵ Update src/style.css       .product-title line-height 1.35 → 1.15
  ⏵ Bash ui-grab-drain --answer g4k2f — "why is this not centred?"
  ✓ Applied 2 changes, answered 1, queue cleared

The dock says what is happening the whole time — woke Claude Code via tmux, working…, applied 3 items, or no session open in this project, which used to look exactly like everything working.

modewhat happens when you hit Send
offNothing — you run /grab yourself.
waitThe Stop hook holds each turn open a few seconds longer, so a click made just after Claude finishes still lands in the same turn.
wakeAn idle session gets poked the moment a batch arrives — typed straight into its tmux pane.
bothWait first; wake if that window passes. The default.
pointers

A pointer, not a snapshot

You might click at 2pm and drain at 4pm. A snapshot would be a lie by then; a file, a line, a class list and some text still find the right place.

ranking

Checked, not trusted

With react-grab installed it reads the component and line off the fiber, then checks that line against the source. A reading that doesn't corroborate drops below the grep hits and says line unverified.

feedback

It learns which picks were right

Elements are re-measured after the edit. One that never moved deletes its own map entry; one that did ships a single exact pointer next time.

questions

Not every pick is an edit

Half of make this bigger starts as why is this the size it is. An item marked ask gets answered, not applied — in the terminal, and back under the element you clicked.

local only

The queue is instructions

Whatever lands in it is what an agent goes on to do, so the endpoint takes writes only from a page served locally. A cross-site POST is refused outright.

revert

One click back

Every batch takes a restore point from git stash create when it is queued — free, invisible, and there when an edit lands somewhere you didn't mean.