Visual UI Annotation SDK for AI Coding Agents
Click any element on any webpage. Leave a note. Export structured, AI-ready context in one click.
UI-Referee is a single JavaScript file you drop into any webpage.
It injects a floating toolbar that lets you:
- Flag any element on the page with a click
- Describe the change you want in plain English
- Export a structured JSON payload or a ready-to-paste AI prompt
No build tools. No npm. No React. No backend. No accounts.
It just works β on any site, any stack, any browser.
<script src="https://idiotinnovators.com/ui-referee.js"></script>Drop this tag anywhere in your HTML β <head> or before </body>.
UI-Referee auto-initialises. The toolbar appears in the bottom-right corner.
# Download the single file
curl -o ui-referee.js https://idiotinnovators.com/ui-referee.js<script src="/path/to/ui-referee.js"></script>Create a browser bookmark and set the URL to:
javascript:(function(){var s=document.createElement('script');s.src='https://idiotinnovators.com/ui-referee.js';document.head.appendChild(s);})();Click the bookmark on any webpage to inject UI-Referee on the fly.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. Open any webpage β
β 2. Click π© Flag Element in the toolbar β
β 3. Hover over elements β red dashed highlight appears β
β 4. Click the element you want to annotate β
β 5. Type your instruction in the modal β Save Flag β
β 6. Repeat for all elements that need changes β
β 7. Click β Export β copy JSON or AI Prompt β
β 8. Paste the prompt into Claude Code, Cursor, Cline, etc. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Injected into any page at z-index: 2,147,483,000 β always on top, never breaks layout.
| Button | Action |
|---|---|
| π© Flag Element | Toggle annotation mode |
β Export n |
Open export modal (JSON + AI Prompt) |
| β | Clear all flags |
Keyboard shortcut: Alt + A β toggle annotation mode from anywhere.
When annotation mode is active, hover any element to see a red dashed outline and a tag label showing <tag>#id.class.
Clicking opens the annotation modal, which shows:
- Tag name
- ID attribute
- Class list
- Auto-generated CSS selector
- Visible text content
UI-Referee builds the shortest, most reliable CSS selector for each element:
| Priority | Example |
|---|---|
Unique id |
#submit-btn |
data-testid |
[data-testid="checkout-btn"] |
data-cy |
[data-cy="nav-link"] |
data-test |
[data-test="hero-cta"] |
| Parent + class chain | .hero .btn-primary |
nth-of-type fallback |
body > div:nth-of-type(2) > button |
{
"meta": {
"tool": "UI-Referee",
"version": "1.0.0",
"cdn": "https://idiotinnovators.com/ui-referee.js"
},
"page": {
"url": "https://example.com/pricing",
"title": "Pricing β Example"
},
"annotations": [
{
"id": "ref_abc123",
"timestamp": 1719000000000,
"selector": "#pricing-cta",
"tag": "button",
"idAttribute": "pricing-cta",
"classes": ["btn", "btn-primary", "btn-lg"],
"text": "Start Free Trial",
"note": "Change text to 'Get Started Free' and make the background #00c853",
"pageUrl": "https://example.com/pricing",
"pageTitle": "Pricing β Example",
"context": {
"outerHTML": "<button id=\"pricing-cta\" class=\"btn btn-primary btn-lg\">Start Free Trial</button>",
"innerText": "Start Free Trial",
"parentHTML": "...",
"boundingRect": { "top": 480, "left": 640, "width": 200, "height": 48 },
"computedStyles": {
"display": "inline-flex",
"position": "static",
"width": "200px",
"height": "48px",
"color": "rgb(255,255,255)",
"backgroundColor": "rgb(232,0,28)",
"fontSize": "16px"
}
}
}
]
}Produces a structured, agent-ready prompt:
# UI-Referee β AI Agent Change Request
You are an expert frontend developer modifying a live webpage.
Below are flagged UI elements with specific change instructions.
Implement all changes, producing production-ready code.
ββββββββββββββββββββββββββββββββββββββββββββββββ
PAGE CONTEXT
ββββββββββββββββββββββββββββββββββββββββββββββββ
Title : Pricing β Example
URL : https://example.com/pricing
Flags : 2
ββββββββββββββββββββββββββββββββββββββββββββββββ
FLAG 1 of 2
ββββββββββββββββββββββββββββββββββββββββββββββββ
Selector : #pricing-cta
Tag : <button>
...
ββ Requested Change ββ
Change text to 'Get Started Free' and make the background #00c853
After saving a flag, a small red numbered badge appears on the annotated element.
Badges reposition automatically on scroll and window resize.
Click a badge to see a toast with its note.
Annotations are saved to localStorage under the key uireferee_annotations.
Reload the page β your flags are still there.
UI-Referee exposes a global UIReferee object:
// Auto-initialised on load β call manually only if needed
UIReferee.init()
// Annotation mode
UIReferee.enable() // enter annotation mode
UIReferee.disable() // exit annotation mode
// Export
UIReferee.exportJSON() // download ui-referee-annotations.json
UIReferee.exportPrompt() // copy AI prompt to clipboard
// Data
UIReferee.getAnnotations() // returns array of annotation objects
UIReferee.clear() // clears all annotations + localStorage
// Meta
UIReferee.version // "1.0.0"// You can trigger annotation on any element via the internal SDK:
const el = document.querySelector('#my-button');
UIReferee._sdk.addAnnotation(el, 'Change this button color to green');const json = JSON.parse(UIReferee._sdk.exportJSON(false));
fetch('/api/annotations', {
method : 'POST',
headers: { 'Content-Type': 'application/json' },
body : JSON.stringify(json),
});# Paste the exported prompt directly into Claude Code
claude "$(pbpaste)" # macOS β pbpaste reads clipboard
claude "$(xclip -o)" # Linux- Click β Export β AI Prompt β β Copy Prompt
- Open your AI agent's chat panel
- Paste β the agent will implement all flagged changes
gemini -p "$(pbpaste)"const prompt = UIReferee._sdk.exportPrompt(false);
const response = await openai.chat.completions.create({
model : 'gpt-4o',
messages: [{ role: 'user', content: prompt }],
});Each annotation object has this shape:
interface Annotation {
id : string; // "ref_abc123def"
timestamp : number; // Unix ms
selector : string; // "#submit-btn"
tag : string; // "button"
idAttribute : string; // "submit-btn"
classes : string[]; // ["btn", "btn-primary"]
text : string; // Visible text (max 300 chars)
note : string; // Your instruction
pageUrl : string; // Current page URL
pageTitle : string; // document.title
context: {
outerHTML : string; // Element's HTML (max 2000 chars)
innerText : string; // Visible text (max 500 chars)
parentHTML : string; // Parent element HTML
boundingRect: {
top: number; left: number;
width: number; height: number;
};
computedStyles: {
display: string; position: string;
width: string; height: string;
color: string; backgroundColor: string;
margin: string; padding: string;
fontSize: string;
};
};
}| Browser | Support |
|---|---|
| Chrome 90+ | β Full |
| Firefox 88+ | β Full |
| Safari 14+ | β Full |
| Edge 90+ | β Full |
| Opera 76+ | β Full |
Requires: CSS.escape, getBoundingClientRect, localStorage, Blob / URL.createObjectURL.
Contributions are welcome!
git clone https://github.com/idiotinnovators/ui-referee.git
cd ui-referee
# Edit the single source file
code ui-referee.js
# Test by opening the example page
open examples/basic.htmlPlease read CONTRIBUTING.md before opening a pull request.
- Floating toolbar with flag / export / clear
- Hover highlight with element tag label
- Annotation modal with smart selector generation
- JSON export with full DOM context
- AI-prompt export (Claude Code, Cursor, Windsurf, Cline, Gemini CLI, Codex)
- Numbered badges with scroll repositioning
localStoragepersistence across page reloadsAlt+Akeyboard shortcut- Bookmarklet support
- Zero dependencies Β· single file Β· ~18kb
MIT Β© 2025 Idiot Innovators
Made with love by Idiot Innovators Research And Development Β· CDN: https://idiotinnovators.com/ui-referee.js
