Skip to content

Commit e66b21d

Browse files
authored
Fix doc screenshots skill Markdown (#4239)
## What Repair malformed Markdown in the `doc-screenshots` skill's Workflow section so its instructions render correctly and commands remain copyable. Additionally, remove the line wrapping from other lines to be consistent in raw form. ## Problems fixed - Fenced JavaScript and shell examples were over-indented inside numbered list items, causing them to be parsed as malformed nested content instead of normal fenced code blocks. - The Playwright installation command was split by a blank line across separate Markdown paragraphs. - The virtual-environment and Pillow installation command was also split across paragraphs. - Inline code lacked required surrounding spacing, producing text such as `` `config error:`message `` and `` `output` must be a`.webp` ``. ## What was not the issue Ordinary prose wrapping was not the underlying bug, and skill files are not categorically forbidden from containing wrapped prose. The edited paragraphs are kept unwrapped to follow this repository's Markdown convention, but the functional problem was malformed Markdown structure and broken commands. ## Impact This changes only the skill instructions. The annotation script, examples, and runtime behavior are unchanged. ## Checks - `quick_validate.py .agents/skills/doc-screenshots` - `prettier --check .agents/skills/doc-screenshots/SKILL.md` - `git diff --check` ## Created screenshots <img width="767" height="2043" alt="Screenshot 2026-08-03 at 18 09 49" src="https://github.com/user-attachments/assets/ad433cd2-6a5b-4367-ae38-6b160c2d569b" />
1 parent 635bb91 commit e66b21d

1 file changed

Lines changed: 40 additions & 110 deletions

File tree

.agents/skills/doc-screenshots/SKILL.md

Lines changed: 40 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -5,129 +5,59 @@ description: Annotate UI screenshots with documentation callouts in Fellyph's es
55

66
# Documentation Screenshot Annotations
77

8-
Produce annotated UI screenshots in one specific house style: uniform-width
9-
orange (#e8590c) arrows with white halos, double-stroke blue outlines around
10-
targets, and (for overviews) a row of numbered callout cards over a dimmed
11-
screenshot. Never use stock arrow shapes, stroked polylines, or ad-hoc styles.
8+
Produce annotated UI screenshots in one specific house style: uniform-width orange (#e8590c) arrows with white halos, double-stroke blue outlines around targets, and (for overviews) a row of numbered callout cards over a dimmed screenshot. Never use stock arrow shapes, stroked polylines, or ad-hoc styles.
129

13-
The geometry engine lives in `scripts/annotate.py`. Your job is to produce
14-
accurate coordinates and a config JSON; the script renders everything
15-
(supersampling, Bézier ribbons, halos, cards, shadows, WEBP export) exactly
16-
to spec. Do not reimplement the drawing by hand.
10+
The geometry engine lives in `scripts/annotate.py`. Your job is to produce accurate coordinates and a config JSON; the script renders everything (supersampling, Bézier ribbons, halos, cards, shadows, WEBP export) exactly to spec. Do not reimplement the drawing by hand.
1711

1812
## Workflow
1913

20-
1. **Capture.** Take screenshots at `deviceScaleFactor: 2`. Never eyeball
21-
coordinates: record every target's bounding box programmatically and save
22-
the boxes to JSON — including _regions_ (panels, sidebars, block trees),
23-
not just buttons; eyeballed region outlines are the most common
24-
quality-gate failure. With Playwright:
25-
26-
```js
27-
const page = await browser.newPage({ viewport: { width: 1440, height: 900 }, deviceScaleFactor: 2 });
28-
// ... navigate, prepare UI state ...
29-
const box = await page.locator('button:has-text("Export")').boundingBox();
30-
await page.screenshot({ path: 'shot.png' });
31-
```
32-
33-
**Iframes:** Playwright's `locator(...).boundingBox()` already returns
34-
main-viewport coordinates, even inside nested iframes (Playground nests
35-
main page → `remote.html` wrapper → the WordPress scope frame) — use
36-
the boxes as-is, no offsets. Only raw `getBoundingClientRect()` inside a
37-
frame's own `evaluate()` (or the Chrome DevTools MCP tools) needs the
38-
enclosing iframe's box offset added.
39-
40-
**WordPress modals:** editor screens open welcome guides ("Edit your
41-
site" → Get started) whose overlay swallows clicks; some have no
42-
`aria-label="Close"` button. Dismiss with an Escape loop — while
43-
`.components-modal__screen-overlay` exists, press Escape on the frame's
44-
body, wait ~1s — and retry the blocked click between attempts. The modal
45-
can appear _after_ the page looks loaded, so dismiss lazily around the
46-
click, not once up front.
47-
48-
Prefer driving the browser from Node with the repo's own
49-
`node_modules/playwright`; otherwise `pip install playwright &&
50-
51-
playwright install chromium`, or use the Chrome DevTools MCP capture
52-
tools.
53-
54-
Before capturing, clean up dev-environment artifacts: update nags, debug
55-
badges, plugin notices. They must not appear in docs imagery.
56-
57-
2. **Author the config.** All geometry is in CSS px relative to the
58-
screenshot's top-left. Write a config JSON (schema in the script's
59-
docstring — read it; runnable examples of both modes are in `examples/`,
60-
sharing the bundled `sample-shot.webp`) and run:
61-
62-
```bash
63-
python .agents/skills/doc-screenshots/scripts/annotate.py config.json --crops crops/
64-
```
65-
66-
The script needs Python with Pillow. If no suitable interpreter is
67-
active, create a venv in the session scratchpad (`python3 -m venv
68-
69-
<scratchpad>/venv && <scratchpad>/venv/bin/pip install Pillow`) and call
70-
that interpreter directly. The script validates the config up front and
71-
exits with a readable `config error:`message on bad input;`output` must be a`.webp` path.
72-
73-
3. **Quality gate — actually look.** Read the rendered WEBP at full size,
74-
plus the zoomed crops the script saves of every arrowhead and outline
75-
(named `<output-stem>-NN-<spot>.png`, so one crops dir can serve all
76-
configs of a batch).
77-
Check: tip gaps even (5–7px short of each outline), halos unbroken,
78-
no arrow crosses another arrow or a sibling annotation, no card text
79-
overflow warnings on stderr, artifacts removed. Also sanity-check
80-
legibility at docs width (~860px) and mobile (~343px) — if labels become
81-
unreadable, simplify rather than shrink. Fix and re-render until clean.
14+
1. **Capture.** Take screenshots at `deviceScaleFactor: 2`. Never eyeball coordinates: record every target's bounding box programmatically and save the boxes to JSON — including _regions_ (panels, sidebars, block trees), not just buttons; eyeballed region outlines are the most common quality-gate failure. With Playwright:
15+
16+
```js
17+
const viewport = { width: 1440, height: 900 };
18+
const page = await browser.newPage({ viewport, deviceScaleFactor: 2 });
19+
// ... navigate, prepare UI state ...
20+
const box = await page.locator('button:has-text("Export")').boundingBox();
21+
await page.screenshot({ path: 'shot.png' });
22+
```
23+
24+
**Iframes:** Playwright's `locator(...).boundingBox()` already returns main-viewport coordinates, even inside nested iframes (Playground nests main page → `remote.html` wrapper → the WordPress scope frame) — use the boxes as-is, no offsets. Only raw `getBoundingClientRect()` inside a frame's own `evaluate()` (or the Chrome DevTools MCP tools) needs the enclosing iframe's box offset added.
25+
26+
**WordPress modals:** Editor screens open welcome guides ("Edit your site" → Get started) whose overlay swallows clicks; some have no `aria-label="Close"` button. Dismiss with an Escape loop — while `.components-modal__screen-overlay` exists, press Escape on the frame's body, wait ~1s — and retry the blocked click between attempts. The modal can appear _after_ the page looks loaded, so dismiss lazily around the click, not once up front.
27+
28+
Prefer driving the browser from Node with the repo's own `node_modules/playwright`; otherwise run `python3 -m pip install playwright && python3 -m playwright install chromium`, or use the Chrome DevTools MCP capture tools.
29+
30+
Before capturing, clean up dev-environment artifacts such as update nags, debug badges, and plugin notices. They must not appear in docs imagery.
31+
32+
2. **Author the config.** All geometry is in CSS px relative to the screenshot's top-left. Write a config JSON using the schema in the script's docstring; read it first. Runnable examples of both modes are in `examples/` and share the bundled `sample-shot.webp`. Then run:
33+
34+
```bash
35+
python .agents/skills/doc-screenshots/scripts/annotate.py config.json --crops crops/
36+
```
37+
38+
The script needs Python with Pillow. If no suitable interpreter is active, create a virtual environment in the session scratchpad with `python3 -m venv <scratchpad>/venv && <scratchpad>/venv/bin/python -m pip install Pillow`, then call that interpreter directly. The script validates the config up front and exits with a readable `config error:` message on bad input; `output` must be a `.webp` path.
39+
40+
3. **Quality gate — actually look.** Read the rendered WEBP at full size, plus the zoomed crops the script saves of every arrowhead and outline (named `<output-stem>-NN-<spot>.png`, so one crops directory can serve every config in a batch). Check that tip gaps are even (5–7px short of each outline), halos are unbroken, no arrow crosses another arrow or a sibling annotation, stderr has no card-text overflow warnings, and artifacts are removed. Also sanity-check legibility at docs width (~860px) and mobile (~343px); if labels become unreadable, simplify rather than shrink. Fix and re-render until clean.
8241
8342
## Choosing the annotation mode
8443
85-
- **Pointing at specific controls** (a dialog walkthrough, "click here"):
86-
use `outlines` + free `arrows`. No dim, no cards. One arrow per target,
87-
tail starting from empty space, arriving straight onto the outline.
88-
- **Overview with a legend** ("these are the three persistence controls"):
89-
use `cards` + `outlines` + `dim`. Cards get `target` indexes and the
90-
script auto-draws vertical arrows from each card's bottom edge onto its
91-
outline. Set `dim.region` to the area holding the documented controls so
92-
they stay at full brightness while the rest dims 24% toward #28313b.
93-
- Add `chrome_bar` (44px bar, traffic lights, URL pill) only when browser
94-
context matters to the reader.
44+
- **Pointing at specific controls** (a dialog walkthrough, "click here"): use `outlines` + free `arrows`. No dim, no cards. One arrow per target, tail starting from empty space, arriving straight onto the outline.
45+
- **Overview with a legend** ("these are the three persistence controls"): use `cards` + `outlines` + `dim`. Cards get `target` indexes and the script auto-draws vertical arrows from each card's bottom edge onto its outline. Set `dim.region` to the area holding the documented controls so they stay at full brightness while the rest dims 24% toward #28313b.
46+
- Add `chrome_bar` (44px bar, traffic lights, URL pill) only when browser context matters to the reader.
9547

9648
## Placement rules the script cannot decide for you
9749

98-
- Arrow endpoints: the tip must stop 5–7px short of the target's outline
99-
(for card arrows the script handles the 6px gap; for free arrows, place
100-
`to` accordingly). Both tangents are axis-parallel — pick `axis` so the
101-
arrow leaves and arrives straight, giving the calm S-curve.
102-
- Arrows must never cross each other or overlap another annotation. If a
103-
layout forces a crossing, move the tail, flip the axis, or reorder cards
104-
so each card sits roughly above its target.
105-
- Outlines must enclose the whole control including secondary lines (a
106-
row's timestamp, a button's icon), not just the text node you queried
107-
for. Pad 6–10px, radius 10–14 for rounded rects; plain circles r≈25 for
108-
icon-only buttons.
109-
- Card copy: title 2–3 words, subtitle one short clause. The script warns
110-
on stderr if text overflows its card — treat that as a hard failure.
50+
- Arrow endpoints: the tip must stop 57px short of the target's outline (for card arrows the script handles the 6px gap; for free arrows, place `to` accordingly). Both tangents are axis-parallel — pick `axis` so the arrow leaves and arrives straight, giving the calm S-curve.
51+
- Arrows must never cross each other or overlap another annotation. If a layout forces a crossing, move the tail, flip the axis, or reorder cards so each card sits roughly above its target.
52+
- Outlines must enclose the whole control including secondary lines (a row's timestamp, a button's icon), not just the text node you queried for. Pad 6–10px, radius 10–14 for rounded rects; plain circles r≈25 for icon-only buttons.
53+
- Card copy: title 2–3 words, subtitle one short clause. The script warns on stderr if text overflows its card — treat that as a hard failure.
11154
11255
## Style constants (already baked into the script — do not override)
11356
114-
Arrows are orange #e8590c on pure white halos; outlines, badges and cards stay blue #3858e9. The shaft is a uniform 9px line (constant
115-
top to bottom, round caps) ending in an open chevron head — two 16px
116-
diagonal strokes of the same width sweeping back from the tip at ±35°;
117-
halo expanded 3.2px per side. Outline = white width 9 on
118-
the bbox expanded 2.5px, blue width 4 on the exact bbox. Canvas #f6f7f7,
119-
36px margins, rounded frame with 1px #dcdcde border and soft shadow. Cards:
120-
white, radius 16, 1px #ccced0 border, double shadow, blue badge r22,
121-
Helvetica Neue (27px bold title #101517 / 19px subtitle #2c3338). Export is
122-
WEBP quality ~89 after a single LANCZOS downsample from the supersampled
123-
canvas.
124-
125-
Reference outputs in this style: an action walkthrough
126-
(free arrows onto dialog controls) and an overview legend (three cards over
127-
a dimmed page) — match their look, spacing and restraint.
57+
Arrows are orange #e8590c on pure white halos; outlines, badges and cards stay blue #3858e9. The shaft is a uniform 9px line (constant top to bottom, round caps) ending in an open chevron head — two 16px diagonal strokes of the same width sweeping back from the tip at ±35°; halo expanded 3.2px per side. Outline = white width 9 on the bbox expanded 2.5px, blue width 4 on the exact bbox. Canvas #f6f7f7, 36px margins, rounded frame with 1px #dcdcde border and soft shadow. Cards: white, radius 16, 1px #ccced0 border, double shadow, blue badge r22, Helvetica Neue (27px bold title #101517 / 19px subtitle #2c3338). Export is WEBP quality ~89 after a single LANCZOS downsample from the supersampled canvas.
58+
59+
Reference outputs in this style: an action walkthrough (free arrows onto dialog controls) and an overview legend (three cards over a dimmed page) — match their look, spacing and restraint.
12860
12961
## Repo layout
13062
131-
The source of truth is `.agents/skills/doc-screenshots/`. `.claude/skills`
132-
is a committed symlink to `../.agents/skills`, so Claude Code loads the same
133-
files — edit only under `.agents/skills/` and never create a separate copy.
63+
The source of truth is `.agents/skills/doc-screenshots/`. `.claude/skills` is a committed symlink to `../.agents/skills`, so Claude Code loads the same files — edit only under `.agents/skills/` and never create a separate copy.

0 commit comments

Comments
 (0)