Refreshing docs screenshots
Read the screenshot descriptions in product docs, reproduce their states in the real local dashboard, and replace only images that need an update. Use AI to choose seed data and browser actions. Do not require fixed scenario scripts or build a substitute UI.
Choose a mode
Use one of these two modes:
all: Find everyDashboardScreenshotdeclaration underdocs/product/. Check each image against the current dashboard and its surrounding docs. Refresh outdated or missing images. Leave accurate images unchanged. Report every declaration as current, refreshed, or blocked.specific <target-or-src>: Match a root-relativesrcpath, or atargetname if it identifies exactly one declaration. Check and, if needed, refresh only that screenshot and its theme variants. If several declarations use the same target, ask for thesrc. If a page contains several declarations, ask which image they mean. Stop on missing or duplicate matches.
Example requests:
Use refreshing-docs-screenshots in all mode to check the product docs.
Use refreshing-docs-screenshots in specific mode for root-key-permissions.
A monthly run can use all. Do not create a schedule unless the user explicitly
asks for one. An audit or refresh request does not authorize a push or PR.
Read the declarations
Read docs/product/snippets/dashboard-screenshot.jsx before interpreting its
props. Discover declarations with a scoped search, then read the MDX and nearby
text. Ignore component names inside explanatory code blocks. Read capture
metadata from the MDX source, not the rendered docs HTML. The docs component
only renders images; it does not emit capture metadata or execute the workflow.
rg -n '<DashboardScreenshot' docs/product --glob '*.mdx'
The declaration's contract is:
target: Value ofdata-docs-targeton an existing dashboard element.description: Desired data, UI state, navigation hints, and capture constraints.capture:target,viewport, orfull-page. Usetargetwhen omitted.src: Root-relative image path without the theme suffix or extension. The component renders${src}-light.pngand${src}-dark.png. This identifies the saved illustration; no separateidis needed.alt: Reader-facing description of the image.width: Optional maximum display width in CSS pixels, not a capture viewport.capturedAt: ISO 8601 UTC timestamp for the saved capture, for example2026-09-11T04:48:23Z. It stays in the MDX source, not the docs DOM.
Use capturedAt to prioritize old or unknown captures. An image older than about
a month deserves attention, but age alone does not make it outdated. Recent
captures can also become wrong after UI changes. In all mode, account for every
declaration regardless of age. Treat missing, invalid, or future timestamps as
unknown, not fresh.
The timestamp records capture time, not the last audit. Never set it from the render clock or advance it merely because an old image still looks correct. Only update it after both theme images have been captured, inspected, and saved. Do not invent a timestamp for an existing image with unknown capture history.
Plain <img> screenshots have no capture instructions. Report them as outside
this declaration-based workflow when relevant; do not silently claim they were
checked or convert them all without a request.
Prepare the real dashboard
Read repository guidance and
docs/engineering/contributing/local/development.mdx. Use mise for tools.
Inspect running services before starting anything. Reuse a healthy local stack.
- On a developer machine,
mise run dashboardis the dashboard setup task. Read its effects before running it, especially its database seeding step. - In an orb, use the declared
.amp/services.yamlservices and supervised service commands. Loadusing-agent-browserbefore browser work. Share portal URLs with the user, not localhost URLs. - Confirm local authentication and disposable local database connections before writing data. Never dump credentials or environment files into the transcript.
Use synthetic fixtures and create only the data needed by the description. Prefer existing local seed helpers or the dashboard's normal creation flows. Do not use production accounts, shared databases, real customer data, or real credentials. Stop dependent work if a safe local environment is unavailable.
Locate the target in web/apps/dashboard/. Use the existing route and UI.
Do not create a preview component, mock dashboard, or new route to make capture
easier. If a marker is missing, report it as blocked unless the user authorized
adding it. An authorized marker belongs on an existing DOM container or a
component that forwards it to that container, including portaled dialog content.
Check and capture
For each declaration:
- Inspect the saved images and the surrounding docs. Identify what the image must teach. Use source changes as supporting evidence, not a substitute for checking the rendered UI.
- Navigate the actual dashboard to the described state. Follow the description, but adapt navigation when the UI changes. Do not create a root key or perform another sensitive action if opening its form is sufficient.
- Apply any declared viewport and locale. Otherwise use a 1440 by 1000 CSS-pixel viewport and record that choice. Capture at device scale 2. Wait for data, fonts, and opening animations to finish; a successful click is not readiness.
- Find
[data-docs-target="<target>"]in the dashboard document. Require exactly one visible match with nonzero bounds. Missing or ambiguous targets block capture. The docs page does not contain these markers. - For
target, capture that element. Forviewport, capture the current viewport after confirming the target identifies the expected state. Forfull-page, capture the document's scrollable page. A full-page capture does not expand independently scrolling panels. Follow browser-tool guidance for scrolled element crops; never accept a blank or truncated result. - Compare the current UI with the saved image. Refresh for changed controls,
layout, labels, missing content, or a mismatch with the docs description.
Different synthetic names or dates alone need not cause a replacement unless
those values matter to the explanation. If the image remains accurate, leave
it and its
capturedAtunchanged. - Capture both light and dark variants before replacing either. Switch themes through the app or its supported system-theme behavior. Do not recolor an image or alter application CSS to fabricate a state. For isolated dialogs, use the capture-only adjustments below.
- Inspect both captures with the media tool. Check the intended content, crop, readability, theme, and absence of secrets. Keep the existing pair if either capture fails. Do not make docs prose agree with a wrong screenshot.
- Save the verified pair at the paths derived from
srcunderdocs/product/. Keep paths within that directory. SetcapturedAtto the UTC time the pair was captured, not when a later audit runs. Keep output paths stable.
Save review images in .amp/in/artifacts/ in an orb. Keep temporary comparison
files elsewhere and remove them when finished. Do not use image generation for
dashboard screenshots.
Capture isolated dialogs
For dialog target captures, use a transparent PNG without outer shadows and
24 CSS pixels of transparent padding on each side. If the description explicitly
needs the surrounding dashboard, retain that context instead. Do not apply this
treatment to viewport or full-page captures.
- Record the target's bounds and original inline styles before changing anything. Keep the real target in place. Temporarily hide surrounding sibling branches and clear ancestor backgrounds without changing layout. Include portaled overlays and ancestor pseudo-elements when they paint behind the target.
- Remove only the target's outer
box-shadowanddrop-shadow()filters for capture. Preserve other filters, child control shadows, borders, background, and the target's actual corner radius. Never add a fixed radius in docs. - Capture with the browser's transparent background option. Clearing HTML and
body backgrounds alone does not make a PNG transparent. If the browser CLI
lacks this option, use its existing Chromium CDP connection with
Emulation.setDefaultBackgroundColorOverride(alpha 0) andPage.captureScreenshot. Confirm the PNG dimensions are twice the padded CSS bounds; device scale alone may not set the CDP clip scale. - Restore every changed style and the browser background override in
finally, including on failure. Confirm the target's bounds and appearance are restored. - Check that exterior pixels have alpha 0 and no shadow remains. Inspect both
themes over the real docs frame, not only in an image viewer that may display
transparency as black. Keep
widthat the target's CSS width plus 48 pixels.
If isolation changes layout, content, or the target's appearance beyond removing its outer shadows, report the capture as blocked. Do not flatten the image onto a solid color or use background-removal image processing to hide a failed capture.
Verify and report
Load docs-writing for documentation changes. Use the Mintlify version pinned
in docs/product/Dockerfile; run it through mise exec. Run mintlify validate
from docs/product/ after changes. Preview the affected real product docs page,
check both theme images load, and inspect the rendered result. Avoid enlarging
a narrow crop beyond its original CSS width; use width when needed.
Run scoped formatting or code checks if source changed, and git diff --check.
Preserve unrelated work. Close browser sessions and clean up only resources
created for this run. Do not stop a teammate's development stack.
Report the selected mode, image paths checked, current/refreshed/blocked results, reasons for replacements, capture timestamps, verification, and any coverage gaps. Include an inspected representative image or a real docs preview link.
Leave changes local unless the user authorizes publishing. If asked to open a
PR, load creating-pull-requests and create a draft with the before/after images,
reasons, and verification results. This skill does not grant permission to push,
open a PR, or schedule future runs.