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...
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:
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 |
edit command |
REPLACED with inject command |
For live editing, use agent-canvas --with-edit instead.
uv package managerplaywright install chromiumSKILL_DIR=".claude/skills/canvas-edit/scripts"
# 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
# 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
The floating toolbar (top-right by default) provides:
Status Display
Actions
Dragging
Each issue appears as a numbered badge on its target element:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā #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 ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
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"
}
]
| Field | Type | Description |
|---|---|---|
id |
number | Unique identifier |
selector |
string | CSS selector for target element |
severity |
string | "blocking", "major", or "minor" |
title |
string | Short issue title |
| Field | Type | Description |
|---|---|---|
description |
string | Detailed explanation |
pillar |
string | Design pillar category |
checkId |
string | Identifier for the check that found this |
recommendation |
string | Suggested fix |
Canvas-edit integrates with other skills via the canvas bus event system.
| Event | Payload | When |
|---|---|---|
annotation.clicked |
{issueId, selector, severity} |
User clicks a badge |
screenshot.requested |
{directory, filename, issueCount} |
Screenshot button clicked |
screenshot.captured |
{path, issueCount} |
Screenshot saved (Python-side) |
annotations.cleared |
{} |
Dismiss button clicked |
filter.changed |
{severity, pillars} |
Filter settings changed |
| Event | Action |
|---|---|
review.started |
Show "Scanning..." state |
review.issue_found |
Add badge for new issue |
review.completed |
Show final count or success message |
capture_mode.changed |
Hide/show toolbar for agent-eyes |
// 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'
});
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:
| 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 review.started |
Success messages rotate randomly:
| Key | Action |
|---|---|
Tab |
Navigate toolbar controls |
1-9 |
Jump to badge by number |
Arrow keys |
Navigate between visible badges |
Enter/Space |
Activate focused button/badge |
Escape |
Close open popover |
The toolbar is rendered inside a closed Shadow DOM:
document.querySelector()