git:20261101.c6e32f6 to git:20261104.b686c03

5 added, 0 removed. Audit A to A.

---
name: compose-preview
description: Render a Jetpack Compose or Compose Multiplatform @Preview to PNG and look at it. Use when asked to render, show or check what a composable, @Preview or Material/Wear library component looks like, to verify a Compose UI edit, to compare before/after, or to review previews against design guidelines. Also to run an Android APK without an emulator.
---
# Compose Preview
Render `@Preview` composables to PNG without Android Studio (Android via
Robolectric, CMP Desktop via Skia). CLI, Gradle plugin and renderers ship from
[compose-ai-tools](https://github.com/yschimke/compose-ai-tools); the MCP server
from [compose-preview-server](https://github.com/yschimke/compose-preview-server).
## Render first
For a request to render or show a preview, follow the short loop below. For a
requested guidelines review, use
[the review checklist](./references/design-guidelines.md) to choose the local,
hosted or UI Builder lane before invoking tools. Published catalogs and
server-homed designs use hosted tools first; a missing local checkout does not
require cloning, Gradle or a cloud environment. If tools are unavailable,
report blocked evidence and follow the integration's setup guidance.
With the local MCP server attached (compose-preview-server 3.78.0+), its
`initialize` instructions say how to call it: `render_preview
preview=<FunctionName>`, no exploring or registering first, no hand-built
mocks. Follow them. This skill adds the budget: a routine render is at most
three tool calls, with no base64 in the reply and images only when you need to
see them.
Your first call is the render. Don't grep for the preview or read its source
first: the server finds it by function name. Look things up only if the render
fails.
1. **Render.** If your client reads local files (Claude Code, Codex, Gemini
CLI, OpenCode, Antigravity), pass `inline=false`. The result is `pngPath`,
`sha256`, dimensions and `changed`, with no image tokens. If it lists
`otherMatches`, render one only if the person asked about it.
**If it carries a `variantChoice` whose `message` says to ask** (several
previews matched and the host showed no chooser), the person picks, not
you: reply with the rendered match and every entry in `choices` as a
numbered list, ask which one they meant, and stop. Don't pick one or
shorten the list to "other variants are available". A grid result or a
declined choice needs no question.
2. **Look only when you need to.** Read `pngPath` with your file reader
before you describe or judge the UI; that is what the person sees. Skip the
read when `changed` or `sha256` already answers the question, such as
"did my edit land?". Describe only what you saw. If you can't view images
here, say so plainly.
+ **Never claim a visual check you didn't make.** `changed` only means the
+ pixels differ from an earlier render; it can be `true` on the first render
+ of a session and it says nothing about *how* they changed. To say an edit
+ looks right ("the title is bigger", "verified", "fixed"), read `pngPath`
+ first. If you didn't, or a render failed, say the result is unverified.
3. **Reply** briefly, with `pngPath` so the person can open the same image.
Don't write "the image above": in a terminal or print-mode harness the
person doesn't see images your tools return. Point at `pngPath` instead.
**Library components come from the catalog.** When the person names a
library component (Material 3, Wear M3 `EdgeButton`, …) rather than one of
their own previews, use the hosted catalog server (`compose-preview-catalog`):
`catalog_list_previews`, then read the published snapshot with
`resources/read`. Request `live` access only to change knobs with
`catalog_render_preview`. **Never** add preview files to the person's project
to show a library component unless they ask for one. See
[catalog-mcp.md](./references/catalog-mcp.md#resourcesread-before-catalog_render_preview).
**Sweeps use hashes.** For more than one render (variants, devices, font
scales, locales, a before/after check), pass `observe=hash` or use
`render_matrix` with `contactSheet: false`, which returns per-cell hashes
only. Fetch pixels only for the final screen or the cells whose hash moved,
or that you must judge by eye: one `render_preview` per such cell (its
`overrides` or `uri`, `inline=false`) and one read of its `pngPath`.
**Design guidelines review.** When asked to review a preview or catalog design
against Android design guidance, read
[design-guidelines.md](./references/design-guidelines.md). It covers keyless
agent review, published results and the CLI's `compose-preview review` loop,
including explicit surface selection, required pictures and incomplete
coverage. A project with no guidelines of its own reviews against the shared
rule packs chosen by what each preview draws (widgets need the widget packs
and a `@LauncherWidgetPreview`), not a component catalog. It is in the default
skill bundle; the optional PR-review bundle is not required.
**Hand multi-render reviews to `design-reviewer`.** If a `design-reviewer`
subagent is available (the compose-agent-plugins plugins ship one), delegate
accessibility, font-scale, round-device and other matrix checks to it so the
images stay out of your context, and relay its verdict and paths. Give it the
subject, home/revision, catalog rules and requested coverage. Without one, run
the same checklist yourself and report that delegation was unavailable.
For a routine hash sweep, keep `contactSheet: false`. A requested visual
guidelines comparison needs pixels: inspect its required frames even in your
own context when no reviewer exists. Prefer only the relevant individual
images or a bounded comparison sheet, and never claim visual coverage from
hashes alone.
**After a source edit**, call `render_preview` again. `notify_file_changed` is
optional. **If the result says it is stale**, make exactly one more call with
`force: {"reason": "<why>"}`. **Never** run `./gradlew`, `clean`, or delete
`build/` dirs to chase a render; if a forced render is still wrong, read
[mcp.md § Troubleshooting](./references/mcp.md#troubleshooting-first--when-not-to-act)
(start with `compose-preview mcp doctor`).
**Details on request.** Add `details: ["a11y", "layout"]` only when the
person asks about accessibility or layout. `observe=png` returns inline pixels
for clients that can't read files.
**No MCP tool?** Use the CLI: `compose-preview show --json --filter <Name>`,
then read the entry's `pngPath`. Stale: `--force=<reason>`, once. See
[cli.md](./references/cli.md). On either path, only output from the render
tools is a render: never a hand-built HTML, CSS or SVG mock. Report a failed
render with its error.
**Running the whole app, not one composable?** To drive or test an APK the
way an emulator would (navigation, deep links, runtime permissions, foldable
postures, a second display, offline or slow networks, BLE peripherals, home-screen
widgets, a Wear app with its tiles, ambient mode and phone sync), or to see an
edit running with live reload (`launch --project`, `reload`), use
`compose-preview launch <app.apk>` or the MCP `simulator_*` tools: Robolectric's
simulator, no emulator or device. Read [simulator.md](./references/simulator.md)
first; a `@Preview` render stays the cheaper check for a single screen.
**Not previewable** (takes a ViewModel or injected service)? Propose extracting
a stateless inner composable and preview that
([state-hoisting.md](./references/state-hoisting.md)).
## Install / update (only if missing)
Check with `compose-preview --version`. If it's missing, run this skill's stub,
`bash <this skill's dir>/scripts/compose-preview --version`: its first run
installs the CLI and puts it on `PATH`. Every other route, updating, and the
Gradle plugin are in [setup.md](./references/setup.md); MCP wiring (the local
server and the one hosted URL) is in [mcp.md](./references/mcp.md).
## Working with platform skills
An official platform skill, such as Android's
[Wear Compose Material 3 skill](https://developer.android.com/agents/skills/wear/wear-compose-m3/skill),
owns API, dependency and migration choices. This skill only renders and
verifies:
- **Defer.** Follow the platform skill for which component, API or version to
use. Don't treat this skill's references as a second API guide.
- **Changes are expected.** During a migration a changed hash or image is
information, not a regression. Only a render failure or a new accessibility
error blocks. Don't restore old screenshots or tune the UI to match them.
- **Mind the catalog version.** A hosted catalog renders one fixed library
version, which may differ from the project's `libs.versions.toml`. See
[catalog-mcp.md § Choosing a component](./references/catalog-mcp.md#choosing-a-component-with-a-platform-skill).
**Migration workflow.** Before editing, `find_previews_for_file` for each file
and record a baseline with `render_preview observe=hash`. Make the platform
skill's edits, re-render, and report failures and new accessibility errors
(`get_preview_data kind=a11y/atf`) as blockers. Show a before/after for one to
three key screens, and check a small round device and the largest font scale
on Wear. Details:
[wear-ui.md § Verification workflow](./references/wear-ui.md#verification-workflow).
## Reference index
Read only what the task needs.
| Topic | Read |
|---|---|
| Install, update, which skills, apply the Gradle plugin, zero-code init script | [setup.md](./references/setup.md) |
| CLI commands, `--filter`/`--id`/`--force`, `counts` buckets, render filenames, SVG output, Gradle tasks, `build-brief` for non-preview builds | [cli.md](./references/cli.md) |
| **Which MCP server** (local vs hosted `https://preview.coo.ee/mcp`); local server setup, tools, history, multi-workspace, **troubleshooting** | [mcp.md](./references/mcp.md) |
| Interaction loop: semantic refs, `observe` modes, `diff_semantics`, crop, `render_matrix` (variants/matrix), record → test, failure `kind`s | [agent-loop.md](./references/agent-loop.md) |
| Accessibility (ATF, `compose-preview a11y`) | [a11y.md](./references/a11y.md) |
| Per-render data (a11y, layout, recomposition, SVG) | [data-products.md](./references/data-products.md) |
| Multi-preview, GIFs, `@SettledPreview`, scrolling captures | [capture-modes.md](./references/capture-modes.md) |
| Run an APK in the simulator (`launch`, `simulator_*`): drive an app, adb equivalents, form factors, folds, multiple displays, home screen and widgets, permission `ask` policy, Play services state | [simulator.md](./references/simulator.md) |
| Simulator network modes, real-traffic gating, Wi-Fi requests, Bluetooth / BLE / GATT | [simulator-network.md](./references/simulator-network.md) |
| Simulator on Wear: watch face, tiles, notifications, ambient and screen power, `--pair`, `--data-layer agent`, `ChannelClient`, companion devices | [simulator-wear.md](./references/simulator-wear.md) |
| Simulator edit-run loop: `restart`, `update`, live reload (`--project`, `reload`, `--live`), `--adb` | [simulator-iterate.md](./references/simulator-iterate.md) |
| Wear Compose UI / Wear Tiles | [wear-ui.md](./references/wear-ui.md), [wear-tiles.md](./references/wear-tiles.md) |
| CMP `:shared` modules | [cmp-shared.md](./references/cmp-shared.md) |
| Android XML drawables / icons | [resource-previews.md](./references/resource-previews.md) |
| Runtime permissions per render | [runtime-permissions.md](./references/runtime-permissions.md) |
| Editable override knobs | [override-knobs.md](./references/override-knobs.md) |
| Display filters | [display-filters.md](./references/display-filters.md) |
| Remote Compose, `compose-preview rc` | [remote-compose.md](./references/remote-compose.md) |
| Hosted catalog MCP tools and grant flow (`serve`, no checkout) | [catalog-mcp.md](./references/catalog-mcp.md) |
| Gated server access (`compose-preview auth request`) | [server-access.md](./references/server-access.md) |
| Agent allowlists, staging PNGs | [permissions.md](./references/permissions.md) |
| Cloud sandboxes | [agent-cloud.md](./references/agent-cloud.md) |
| VS Code extension (humans) | [vscode.md](./references/vscode.md) |
CI and PR review are the opt-in [compose-preview-ci](../compose-preview-ci/SKILL.md)
and [compose-preview-review](../compose-preview-review/SKILL.md) skills;
[setup.md § Which skills](./references/setup.md#which-skills) adds them.
## Offer the next step
When one of these signals is visible, you may end a reply with its one-sentence
offer. At most one offer per reply, and never repeat an offer the person
ignored.
| Signal | Offer |
|---|---|
| A PR that changes UI, and the repo has no preview CI | "I can set up CI that posts before/after renders on PRs." Needs the review skills: `scripts/install.sh --skills compose-preview-review,compose-preview-ci`, or `/plugin install compose-review@compose-agent-plugins`. |
| Reviewing a UI PR | "I can render base and head and diff them for this review." Same review skills as above. |
| They want to browse every preview themselves | "`compose-preview browse` or the [VS Code extension](./references/vscode.md) shows them all." |
| They need navigation or a running app | "I can run the whole app without an emulator." See [simulator.md](./references/simulator.md). |
| They want to design a new screen rather than edit code | "The UI Builder can design it with you first: <https://ui.coo.ee/start>." |