Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .claude/skills/docs-say-cheese/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
name: docs-say-cheese
description: Plans, captures, compares, and places screenshots for documentation pages. Claude takes screenshots of a running app with Playwright, lists the shots the user must take in Studio Pro, and swaps the images into the pages with alt text.
user-invocable: true
disable-model-invocation: true
---

The user has already updated the text of some documentation pages. Your job is the screenshots: work out which ones are needed, take the ones you can, get the rest from the user, and put them on the pages.

The **shot list** is the plan for this whole job: one entry per image on the pages. Every step below reads or updates it.

The people using this skill write documentation and are often not developers. Talk to them in short, plain sentences. Explain any technical choice in one line, and ask before installing anything.

## 1. Gather What You Need

Ask the user these questions in one message:

1. **Which pages?** Specific files, or "the pages I changed on my branch". For the second, compare the branch with `development` (`git diff --name-only development...HEAD -- content/`).
2. **Where is the app running?** The address of the running app, for example `http://localhost:8080`. If no app is involved, only Studio Pro shots are possible.
3. **Who signs in?** You open a visible browser window and the user types their own login there. You never ask for, store, or type a password.
4. **Should I check the page against the product's code?** No (most jobs), the Mendix web-widgets repo (<https://github.com/mendix/web-widgets>, or the user's local copy), or somewhere else the user gives you (a folder or a link).
5. **Are you using an external monitor?** Screenshots taken on an external monitor can look less sharp than ones taken on a laptop screen. Offer to take them at double resolution so they stay sharp, and let the user decide.

Done when every question has an answer.

## 2. Build the Shot List

For each page, add an entry for every `figure` shortcode and every `{{% todo %}}` marker that asks for a screenshot. Give each entry:

* **ID**: `SCR-001`, `SCR-002`, and so on. Search for entries by ID, never by line number; line numbers drift while you edit.
* **Type**: `new` (the page needs an image it doesn't have), `replace` (the image is outdated), `verify` (the image might still be fine; recapture it and compare), or `remove` (the image no longer belongs on the page).
* **Who takes it**: `Claude` for anything in the running app in a browser. `You` for Studio Pro: dialogs, the page editor, the Toolbox, domain models, microflows.
* **What it shows**: one line, based on what the page text says around the image.
* **File**: the image path the page uses. For `new` shots, follow the screenshot and folder rules under "Guidelines and Conventions" in `content/en/docs/community-tools/contribute-to-mendix-docs/_index.md`.

If the user asked for a check against the product's code, read the page next to the code it describes: property names, tab names, option labels, default values. Note every mismatch for the user, and add a `replace` entry for every image that shows the old UI.

For more than 5 shots, or a job that will take more than one session, keep the shot list in a file, as described in [shot-list.md](shot-list.md). For smaller jobs, keep it in the chat.

Done when every image on every page has an entry with a type and an owner.

## 3. Agree on the Plan

Show the user the shot list as a short table, and get their OK before capturing anything.

Then give them their own list: only the `You` shots, numbered, each with what to show, what to set up first, and the exact file name to save it as (`SCR-012.png`). Name one folder for all of their shots, for example `~/Desktop/<topic>-screenshots/`, and save your own shots there too.

Done when the user has approved the plan and has their list.

## 4. Take Your Shots

Take every `Claude` shot with Playwright, following [capture-playwright.md](capture-playwright.md). Look at each capture before moving on, and retake it if it doesn't show what the entry says.

Done when every `Claude` entry is captured, or marked as blocked with the reason (for example, "needs data the test app doesn't have").

## 5. Compare and Choose

When the user's shots arrive, look at each one the same way.

For every `replace` and `verify` entry, start a subagent to compare the new capture with the current image and choose one. When both show the content equally well, choose the new one. Choose the old one only when the new one is worse for what the page text describes: missing content, the wrong data, or something misleading. Ask the subagent for one line per entry: ID, new or old, a reason of 15 words or less, and suggested alt text when the new one wins.

Check the subagent's verdicts by looking at a few of the images yourself. Then show the user a simple list (use new / keep old, and why), and wait for their OK.

Done when the user has approved a choice for every entry.

## 6. Place the Images

For each approved entry:

* **Replace in place.** Overwrite the existing file under the same name, so the image URL keeps working. First, search all of `content/` for the file name. If another page uses the same file and the new image would be wrong there (for example, a page about an older version), save the new image under a new name and point only this page at it.
* **Resize big captures.** If a capture is wider than about 1400 px, it was taken at double resolution; halve it with `sips --resampleWidth <half> <in> --out <out>` (macOS), or tell the user if you can't.
* **Write the alt text** with the `docs-alt-text` skill. Keep double quotes out of the alt text, because they break the `figure` shortcode.
* **Remove the `todo` marker** for the entry, and set the entry to `placed`.
* For `remove` entries, take the `figure` shortcode off the page, and tell the user which image files are no longer used anywhere. Leave the files in place, since the docs team cleans up unused images separately.

Done when every approved entry is `placed`, and no screenshot `todo` markers remain on the pages.

## 7. Check and Report

1. For every `figure` on the pages, confirm that the file at `static/<src>` exists.
2. If Hugo is set up (`node_modules/.bin/hugo` or `hugo` on the path), build the site with `hugo --environment development` and report any errors. If it isn't, tell the user the build was skipped, and that the pull request checks will build the site.
3. Tell the user, in a few short bullets: how many images were added, replaced, and kept, which shots are still open and why, and any mismatches you found in the page text.

Leave committing and pushing to the user.

Done when the user has the report.
28 changes: 28 additions & 0 deletions .claude/skills/docs-say-cheese/capture-playwright.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Taking Screenshots with Playwright

## Getting Playwright

The docs repository doesn't include Playwright. Check in this order:

1. **Browser tools already connected** (a Playwright MCP server): use them.
2. **Otherwise**, explain to the user in one line that you need to download a browser-control tool (Playwright with Chromium, about 150 MB), and ask before installing. Install it in a temporary folder outside the repository (`npm init -y && npm i playwright && npx playwright install chromium`), and write your capture scripts there too. Leave the repository's `package.json` as it is.

## Capture Settings

* Use a visible browser (`headless: false`), so the user can sign in and see what you're doing.
* Use a fixed viewport, for example 1280 × 800, so that shots of the same page match each other.
* Use `deviceScaleFactor: 2` only if the user chose double resolution in step 1.
* Crop to the part of the page the docs talk about: screenshot the element (`locator.screenshot()`), not the whole window, unless the shot is about the whole page.
* Save each shot as `<ID>.png` in the shots folder.

## Signing In

Open the app, and tell the user: "Please sign in in the browser window that just opened, then tell me when you're done." Wait for them. Do the rest of the work in that same browser session.

## Gotchas

* **One session only.** Test apps often allow only a few signed-in users at once (a sign-in error such as HTTP 402 "license does not allow more users"). Run all captures in one browser context, one after another, and sign out at the end. Parallel captures, including from subagents, will lock you out.
* **Wait for the page to settle.** Charts, animations, and data load after the page appears. Wait for the element and for network idle, and add a short pause before capturing.
* **Missing fonts.** If text looks like a fallback font (for example, a serif where the app uses a sans-serif), the app isn't loading its font. Inject it with `@font-face` (`page.addStyleTag`), using the font files the app itself serves, and tell the user, since it's an app problem, not a docs one.
* **Things in the way.** Hide overlapping bars, banners, or cookie popups with `page.addStyleTag` (`display: none`) before capturing, and only for the shot that needs it.
* **Interactive states.** For a dropdown opened, an editor filled in, or a value selected, perform the clicks and typing in the script, then capture. Use the exact example values from the page text, so the image matches what the reader is told to do.
33 changes: 33 additions & 0 deletions .claude/skills/docs-say-cheese/shot-list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Shot List File

Use a file when the job has more than 5 shots or runs over more than one session. When the skill starts and this file already exists, read it and continue from the first entry that isn't `placed`.

## Where It Lives

Save it as `SCREENSHOTS-<topic>.md` in the repository root, and keep it out of Git by adding its name to `.git/info/exclude` (find that folder with `git rev-parse --git-common-dir`). It is a working file for this job, not documentation.

## Marking Gaps on the Page

For every `new` and `replace` entry, put a marker on the page where the image goes (or right above the image it replaces), so the gap is visible while you work:

```md
{{% todo %}}[SCR-012: Edit Series Item dialog box, Advanced tab, with the custom JSON filled in]{{% /todo %}}
```

`todo` markers don't show on the published site, but reviewers see them in the pull request.

## Format

```md
# Screenshots: <topic>

* App: <address> · Shots folder: <folder> · Double resolution: yes/no
* Status: `todo` → `captured` → `placed`. Entries of type `remove` are `done` once the image is off the page.

| ID | Page | Type | Who | What it shows | File | Status | Notes |
|---|---|---|---|---|---|---|---|
| SCR-001 | content/en/docs/.../page.md | replace | Claude | Line chart with three series and the Toggle Editor button | /attachments/.../chart.png | todo | |
| SCR-002 | content/en/docs/.../page.md | new | You | Edit Series Item dialog box, General tab | /attachments/.../series-general.png | todo | needs a chart with two series |
```

Update the `Status` column as you go, and use `Notes` for decisions (why the old image was kept, why a new file name was used, what blocked a shot).
Loading