Claude-skill-registry canvas-edit
Live Annotation Feedback Toolbar that overlays design review findings directly on web pages. Displays numbered badges on elements with issues, severity indicators, filtering, and screenshot capture. Integrates with design-review for real-time issue display. Triggers on "show annotations", "display issues", "annotate page", "overlay findings", or after running design-review.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/canvas-edit" ~/.claude/skills/majiayu000-claude-skill-registry-canvas-edit && rm -rf "$T"
skills/data/canvas-edit/SKILL.mdCanvas Edit - Live Annotation Toolbar
Floating toolbar that overlays design review findings directly on web pages in real-time. Displays numbered badges on problematic elements with severity-colored borders, hover popovers for issue details, and one-click screenshot capture.
Key features:
- Live annotations - Numbered badges appear on elements as issues are found
- Severity indicators - Color-coded badges (red/orange/blue) with counts
- Issue popovers - Click badges to see full issue details and recommendations
- Screenshot capture - Capture annotated page (toolbar hidden, annotations visible)
- Shadow DOM - Toolbar is invisible to agent-eyes screenshots
- Filtering - Filter by severity or pillar category
Breaking Changes from v1
This is a complete redesign. Canvas-edit is now a viewing tool, not an editing tool.
| Old Functionality | New Behavior |
|---|---|
| Text editing via textarea | REMOVED |
| Style sliders (fontSize, etc.) | REMOVED |
| "Save All to Code" button | REPLACED with screenshot capture |
| contentEditable toggle | REMOVED |
command | REPLACED with command |
For live editing, use
agent-canvas --with-edit instead.
Prerequisites
- Python 3.10+
package manageruv- Playwright browsers:
playwright install chromium
Commands
SKILL_DIR=".claude/skills/canvas-edit/scripts"
Inject Annotations onto Page
# Inject toolbar with issues from JSON file uv run $SKILL_DIR/canvas_edit.py inject http://localhost:3000 --issues issues.json # Inject with issues from stdin echo '[{"id": 1, "selector": "h1", "severity": "major", "title": "Contrast issue"}]' | \ uv run $SKILL_DIR/canvas_edit.py inject http://localhost:3000 --issues - # Auto-screenshot on load uv run $SKILL_DIR/canvas_edit.py inject http://localhost:3000 --issues issues.json --screenshot
Typical Workflow: Design Review + Annotations
# 1. Run design review to find issues uv run .claude/skills/design-review/scripts/design_review.py review http://localhost:3000 \ --output-json issues.json # 2. Inject annotations onto the page uv run $SKILL_DIR/canvas_edit.py inject http://localhost:3000 --issues issues.json # 3. User interacts with annotations, takes screenshots, closes browser
Toolbar Controls
The floating toolbar (top-right by default) provides:
Status Display
- Issue count ("5 Issues" or "All looks good!")
- Severity badges: 🔴 blocking, 🟡 major, 🔵 minor
Actions
- 👁 Visibility: Show/hide all annotations
- ⚙ Filter: Filter by severity or pillar category
- 📸 Screenshot: Capture page with annotations (toolbar hidden)
- ↕/↔ Orientation: Toggle vertical/horizontal toolbar
- ✕ Dismiss: Remove toolbar and all annotations
Dragging
- Grab the ☰ handle to drag toolbar anywhere on screen
- Position persists during session
Annotation Badges
Each issue appears as a numbered badge on its target element:
- Position: Top-right of target element (auto-adjusts at screen edges)
- Color: Border matches severity (red/orange/blue)
- Click: Opens popover with full issue details
- Hover: Highlights the target element
Badge Popover Contents
┌─────────────────────────────────────┐ │ #3 Contrast issue [major] │ ├─────────────────────────────────────┤ │ Color contrast ratio 3.2:1 fails │ │ WCAG AA requirement of 4.5:1 │ │ │ │ Pillar: Quality Craft │ │ Check: color-contrast │ ├─────────────────────────────────────┤ │ Recommendation: │ │ Change text color to #1a1a1a or │ │ background to #ffffff │ └─────────────────────────────────────┘
Issue JSON Format
Issues can come from design-review output or be manually constructed:
[ { "id": 1, "selector": ".hero-title", "severity": "major", "title": "Contrast ratio insufficient", "description": "Text contrast 3.2:1 fails WCAG AA (4.5:1 required)", "pillar": "Quality Craft", "checkId": "color-contrast", "recommendation": "Use darker text (#1a1a1a) or lighter background" }, { "id": 2, "selector": "button.submit", "severity": "minor", "title": "Touch target too small", "description": "Button is 36x28px, minimum is 44x44px", "pillar": "Quality Craft", "checkId": "touch-target-size" } ]
Required Fields
| Field | Type | Description |
|---|---|---|
| number | Unique identifier |
| string | CSS selector for target element |
| string | , , or |
| string | Short issue title |
Optional Fields
| Field | Type | Description |
|---|---|---|
| string | Detailed explanation |
| string | Design pillar category |
| string | Identifier for the check that found this |
| string | Suggested fix |
Event API (Canvas Bus)
Canvas-edit integrates with other skills via the canvas bus event system.
Events Emitted
| Event | Payload | When |
|---|---|---|
| | User clicks a badge |
| | Screenshot button clicked |
| | Screenshot saved (Python-side) |
| | Dismiss button clicked |
| | Filter settings changed |
Events Subscribed
| Event | Action |
|---|---|
| Show "Scanning..." state |
| Add badge for new issue |
| Show final count or success message |
| Hide/show toolbar for agent-eyes |
Integration Example
// In another skill's JavaScript const bus = window.__canvasBus; // Listen for annotation clicks bus.subscribe('annotation.clicked', (payload) => { console.log(`Issue ${payload.issueId} clicked: ${payload.selector}`); }); // Add an issue programmatically window.__annotationLayer.addIssue({ id: 99, selector: '.problematic-element', severity: 'major', title: 'New issue found' });
Screenshot Output
Screenshots are saved to
.canvas/screenshots/ with timestamp filenames:
.canvas/screenshots/ ├── 2026-01-23T15-30-45_5-issues.png └── 2026-01-23T15-45-12_0-issues.png
Filename format:
YYYY-MM-DDTHH-MM-SS_N-issues.png
Screenshots capture:
- Full page content
- All visible annotation badges
- Element highlights (if active)
- NOT the toolbar (hidden during capture)
Toolbar States
| State | Display | Trigger |
|---|---|---|
| Issues Found | "N Issues" + severity badges | Default when issues > 0 |
| All Clear | "✓ All looks good!" (randomized) | Zero issues after review completes |
| Scanning | "⟳ Analyzing..." with spinner | During |
Success messages rotate randomly:
- "All looks good!"
- "Ship it!"
- "Pixel perfect"
- "Zero issues found"
- "Looking sharp!"
Keyboard Navigation
| Key | Action |
|---|---|
| Navigate toolbar controls |
| Jump to badge by number |
| Navigate between visible badges |
| Activate focused button/badge |
| Close open popover |
Shadow DOM Isolation
The toolbar is rendered inside a closed Shadow DOM:
- Invisible to
document.querySelector() - Excluded from agent-eyes DOM snapshots
- Hidden from screenshots (annotations remain visible)
- Page styles cannot affect toolbar appearance
Notes
- Toolbar auto-repositions to stay on screen when dragged or resized
- Badges reposition when window resizes or scrolls
- Multiple badges on the same element stack with offset
- Orphaned badges (element removed) are automatically cleaned up
- Filter state persists during session but resets on page reload