{"id":"41e42b03-1e7c-420c-beca-1d6cb95cba54","shortId":"NRjzQq","kind":"skill","title":"compose-preview","tagline":"Render Compose @Preview functions to PNG outside Android Studio. Use this to verify UI changes, iterate on designs, and compare before/after states across Android (Jetpack Compose) and Compose Multiplatform Desktop projects.","description":"# Compose Preview\n\nRender `@Preview` composables to PNG images without launching Android Studio.\nWorks on both Android (Jetpack Compose via Robolectric) and Compose Multiplatform\nDesktop (via `ImageComposeScene` + Skia).\n\nMaintained at [github.com/yschimke/compose-ai-tools](https://github.com/yschimke/compose-ai-tools)\nunder `skills/compose-preview/`. The bundle this documentation ships with is\n<!-- x-release-please-start-version -->\n**v0.10.10**.\n<!-- x-release-please-end -->\nRun `compose-preview --version` to check the installed bundle, `compose-preview doctor`\nto compare against the latest release (warns when the local copy trails), and\n`compose-preview update` to re-run the bootstrap installer.\n\n## What this skill provides\n\n- A Gradle plugin (`ee.schimke.composeai.preview`) that discovers `@Preview`\n  annotations from compiled classes and registers rendering tasks.\n- A `compose-preview` CLI that drives the Gradle build via the Tooling API\n  and surfaces rendered PNG paths.\n- A VS Code extension with a preview panel, CodeLens and hover actions on\n  `@Preview` functions, and commands for rendering all or a single file.\n\n## Gradle tasks\n\nApplied to each module that declares the plugin:\n\n| Task | Purpose |\n|------|---------|\n| `:<module>:discoverPreviews` | Scan compiled classes, emit `build/compose-previews/previews.json`. |\n| `:<module>:renderAllPreviews` | Discover + render every `@Preview` to PNG under `build/compose-previews/`. |\n| `:<module>:discoverAndroidResources` | Walk `res/drawable*` + `res/mipmap*`, parse `AndroidManifest.xml`, emit `build/compose-previews/resources.json`. See [design/RESOURCE_PREVIEWS.md](./design/RESOURCE_PREVIEWS.md). |\n| `:<module>:renderAndroidResources` | Render every discovered XML drawable / mipmap to PNG / GIF under `build/compose-previews/renders/resources/`. |\n\nAll Gradle-cacheable with strict configuration caching — unchanged inputs\nproduce no re-work.\n\n## CLI\n\nThe CLI auto-detects the Gradle project root (walks up for `gradlew`) and, by\ndefault, every module that has the plugin applied.\n\n```\ncompose-preview <command> [options]\n\nCommands:\n  show     Discover + render previews; print id, path, sha256, changed flag\n  list     List discovered previews\n  render   Render previews; with --output copies a single match to disk\n  a11y     Render previews and print ATF accessibility findings\n  extensions run a11y-annotated-preview.render\n           One-shot a11y hierarchy + ATF + annotated overlay render\n  doctor   Verify Java 17+ + project compatibility (run before Setup)\n\nOptions:\n  --module <name>      Target a single module (default: auto-detect)\n  --variant <variant>  Android build variant (default: debug)\n  --filter <pattern>   Case-insensitive substring match on preview id\n  --id <exact>         Exact match on preview id\n  --json               Emit JSON (show, list)\n  --output <path>      Copy matched preview PNG to this path (render)\n  --progress           Print per-task milestone/heartbeat lines to stderr\n  --verbose, -v        Full Gradle build output (implies --progress)\n  --timeout <seconds>  Gradle build timeout (default: 300)\n  --force=<reason>     Sanctioned escape hatch for stale renders: passes\n                       --rerun-tasks to Gradle. Does NOT run :clean and\n                       does NOT touch build/classes/. Logs the reason and\n                       points at issue #924 — please report.\n```\n\nOSC 9;4 terminal progress (native taskbar/tab progress bar) is on by default\nin a TTY and auto-disables when stdout is piped. Textual progress lines are\nopt-in via `--progress`.\n\nExit codes: `0` success, `1` build failure, `2` render failure, `3` no previews.\n\n`--json` output per entry includes the full `PreviewParams` (device, widthDp,\nheightDp, fontScale, uiMode, …), the absolute `pngPath`, the `sha256` of\nthe PNG bytes, and a `changed` boolean computed against the previous\ninvocation. State is persisted per-module under\n`<module>/build/compose-previews/.cli-state.json` and gets wiped by\n`./gradlew clean`.\n\n## Iterating on a design\n\n`list` → edit → `show --json` → read the PNGs whose `changed: true`. Gradle\ncaching means re-renders only redo what changed; the `changed` flag lets\nagents skip reading PNGs that didn't move. Always read the PNG after a UI\nchange — don't assume the change looks correct.\n\n## Designing composables for previewability\n\n`@Preview` only calls composables with zero arguments (or all-default), so\nanything taking a `ViewModel`, repository, or DI-injected service can't be\npreviewed directly. Apply **state hoisting**: split each screen into a\nstateful wrapper (wires runtime deps) and a stateless inner composable that\ntakes state + callbacks. Preview the stateless layer with hand-rolled\nfixtures.\n\n**Agent guidance:** if asked to iterate on a composable that accepts a\nViewModel or injected dependency, first propose extracting a stateless\ninner composable and preview that. The one-time extraction unlocks the\nfast `compose-preview` iteration loop for every future change on that\nscreen. See [design/STATE_HOISTING.md](./design/STATE_HOISTING.md) for\nthe pattern with code.\n\n## Setup\n\nThe plugin is on Maven Central — most projects already have `mavenCentral()`\nin their plugin repositories, so no credentials or extra registry config.\n\n**Agents: check first, install only when missing.** Run\n`compose-preview --version && compose-preview doctor` to see whether the CLI\nis already available — if it is, you're done. Don't blindly re-run the\ninstaller between previews; the script is idempotent for same-version runs\nbut still does network probes.\n\nIf the CLI is missing, surface this command to the user and let them run\nit (or copy it back to you):\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/yschimke/compose-ai-tools/main/scripts/install.sh \\\n  | bash\ncompose-preview doctor\n```\n\nRe-running the same command upgrades to the latest release; pin a specific\nversion by appending it (`… | bash -s -- 0.10.8`).\n\n`doctor` verifies Java 17+ on `PATH` (JDK 21/25 are fine — the renderer is\ncompiled to JDK 17 bytecode). If the install path isn't on `PATH`, the\nscript prints the exact command to add it.\n\nFrom a Compose project root, install the MCP server descriptors:\n\n```sh\ncompose-preview mcp install                  # auto-detects Antigravity\ncompose-preview mcp install --antigravity    # force the Antigravity config write\n```\n\n`mcp install` is a one-time bootstrap. If a render misbehaves, do **not**\nre-run it and do **not** kill the daemon — run `compose-preview mcp doctor`\nfirst and follow the verdict it prints. The supervisor respawns daemons\nautomatically on classpath changes. See\n[design/MCP.md § Troubleshooting](./design/MCP.md#troubleshooting-first--when-not-to-act).\n\nApply the plugin in `<module>/build.gradle.kts`:\n\n<!-- x-release-please-start-version -->\n```kotlin\nplugins {\n    id(\"ee.schimke.composeai.preview\") version \"0.10.10\"\n}\n\ncomposePreview {\n    variant.set(\"debug\")   // Android build variant (default: \"debug\")\n    sdkVersion.set(35)     // Robolectric SDK version (default: 35)\n    enabled.set(true)      // set false to skip task registration\n}\n```\n<!-- x-release-please-end -->\n\n### Zero-Code Integration (Alternative)\n\nYou can apply the plugin dynamically without modifying the project's source code by using a Gradle init script. This is useful for agents operating in environments where they shouldn't or cannot modify the build files directly.\n\n> **VS Code users:** the [`Compose Preview` extension](../../vscode-extension/) already passes a bundled init script via `--init-script` on every Gradle invocation it makes, so its renders pick up Android / Compose projects with no extra setup. The instructions below are for CLI and CI flows that go through `./gradlew` directly.\n\nCreate a file named `~/.gradle/init.d/compose-ai-tools.gradle` with the following content:\n\n```groovy\nallprojects {\n    buildscript {\n        repositories {\n            gradlePluginPortal()\n            mavenCentral()\n        }\n        dependencies {\n            classpath \"ee.schimke.composeai.preview:ee.schimke.composeai.preview.gradle.plugin:latest.release\"\n        }\n    }\n\n    afterEvaluate { project ->\n        if (System.getenv(\"COMPOSE_AI_TOOLS\") == \"true\") {\n            if (project.plugins.hasPlugin(\"com.android.application\")) {\n                if (!project.plugins.hasPlugin(\"ee.schimke.composeai.preview\")) {\n                    project.pluginManager.apply(\"ee.schimke.composeai.preview\")\n                    println \"Applied ee.schimke.composeai.preview to ${project.name} via init script\"\n                }\n            }\n        }\n    }\n}\n```\n\nTo enable it, set the environment variable:\n```sh\nexport COMPOSE_AI_TOOLS=true\n```\n\nCMP Desktop projects additionally need\n`implementation(compose.components.uiToolingPreview)` — the bundled `@Preview`\nannotation has `SOURCE` retention and is invisible to classpath scanning\notherwise.\n\nThe Android variant relies on Robolectric with native graphics; the plugin\ntakes care of the relevant test/tooling dependencies. Agents MUST NOT run\ninternal tasks like `collectPreviewInfo` — they're wired by the plugin itself.\n\n## Reference docs\n\nLoaded on demand. Read only what the current task needs.\n\n| Path | When to read |\n|---|---|\n| [design/PERMISSIONS.md](./design/PERMISSIONS.md) | Setting up agent allowlists; staging PNGs outside `build/`. |\n| [design/STATE_HOISTING.md](./design/STATE_HOISTING.md) | Full state-hoisting pattern with code examples. |\n| [design/CAPTURE_MODES.md](./design/CAPTURE_MODES.md) | Multi-preview annotations, `@AnimatedPreview` GIFs, MCP scripted recordings, paused-clock snapshots, scrolling captures. |\n| [design/A11Y.md](./design/A11Y.md) | ATF accessibility checks (`compose-preview a11y`). |\n| [design/DATA_PRODUCTS.md](./design/DATA_PRODUCTS.md) | Structured per-render data (a11y findings + hierarchy, layout tree, recomposition heat-map, …) via MCP tools and on-disk Gradle output. |\n| [design/MCP.md](./design/MCP.md) | Driving compose-preview from an MCP-aware agent host (push notifications, multi-workspace, in-process server bundled in the CLI). |\n| [design/CMP_SHARED.md](./design/CMP_SHARED.md) | Compose Multiplatform `:shared` modules (`commonMain` previews via Desktop pipeline). |\n| [design/RESOURCE_PREVIEWS.md](./design/RESOURCE_PREVIEWS.md) | Android XML resources (`<vector>`, `<animated-vector>`, `<adaptive-icon>`). |\n| [design/WEAR_UI.md](./design/WEAR_UI.md) | Wear OS Material 3 Expressive design. |\n| [design/WEAR_TILES.md](./design/WEAR_TILES.md) | Wear Tiles (protolayout, not Compose). |\n| [design/REMOTE_COMPOSE.md](./design/REMOTE_COMPOSE.md) | Remote Compose dialect + `RemoteDocument`. |\n| [design/AGENT_CLOUD.md](./design/AGENT_CLOUD.md) | Running compose-preview in Claude Code cloud sandboxes (allowlist, JDK, install paths). |\n| [design/VSCODE.md](./design/VSCODE.md) | VS Code extension (humans, not agents). |\n\n## Related skill\n\nPR-review and CI workflows live in the sibling\n[**compose-preview-review** skill](../compose-preview-review/SKILL.md):\nauthoring agent-opened PRs, reviewing UI PRs locally (base + head render,\ndiff, text comment), and wiring `compose-preview/main` baselines +\nPR-comment GitHub Actions. The bootstrap installer\n([`scripts/install.sh`](https://raw.githubusercontent.com/yschimke/compose-ai-tools/main/scripts/install.sh))\nsets up both skills together.","tags":["compose","preview","tools","yschimke","agent-skills","android","claude-code","claude-skills","compose-multiplatform","compose-preview","gradle-plugin","jetpack-compose"],"capabilities":["skill","source-yschimke","skill-compose-preview","topic-agent-skills","topic-android","topic-claude-code","topic-claude-skills","topic-compose-multiplatform","topic-compose-preview","topic-gradle-plugin","topic-jetpack-compose","topic-kotlin","topic-skill-md","topic-vscode-extension","topic-wear-os"],"categories":["compose-ai-tools"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/yschimke/compose-ai-tools/compose-preview","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add yschimke/compose-ai-tools","source_repo":"https://github.com/yschimke/compose-ai-tools","install_from":"skills.sh"}},"qualityScore":"0.488","qualityRationale":"deterministic score 0.49 from registry signals: · indexed on github topic:agent-skills · 76 github stars · SKILL.md body (11,384 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-14T06:57:17.515Z","embedding":null,"createdAt":"2026-04-29T13:05:05.160Z","updatedAt":"2026-05-14T06:57:17.515Z","lastSeenAt":"2026-05-14T06:57:17.515Z","tsv":"'/../vscode-extension':1021 '/.gradle/init.d/compose-ai-tools.gradle':1068 '/build.gradle.kts':941 '/build/compose-previews/.cli-state.json':509 '/compose-preview-review/skill.md':1365 '/design/a11y.md':1229 '/design/agent_cloud.md':1326 '/design/capture_modes.md':1212 '/design/cmp_shared.md':1289 '/design/data_products.md':1238 '/design/mcp.md':928,1263 '/design/permissions.md':1192 '/design/remote_compose.md':1320 '/design/resource_previews.md':214,1300 '/design/state_hoisting.md':677,1202 '/design/vscode.md':1341 '/design/wear_tiles.md':1313 '/design/wear_ui.md':1305 '/gradlew':514,1062 '/main':1386 '/yschimke/compose-ai-tools/main/scripts/install.sh':787 '/yschimke/compose-ai-tools/main/scripts/install.sh))':1399 '/yschimke/compose-ai-tools](https://github.com/yschimke/compose-ai-tools)':66 '0':460 '0.10.10':947 '0.10.8':813 '1':462 '17':319,817,830 '2':465 '21/25':821 '3':468,1309 '300':392 '35':957,962 '4':427 '9':426 '924':422 'a11y':296,310,1236,1244 'a11y-annotated-preview.render':306 'absolut':485 'accept':639 'access':302,1231 'across':26 'act':936 'action':164,1392 'add':847 'addit':1124 'afterevalu':1084 'agent':544,629,706,999,1160,1195,1273,1347,1368 'agent-open':1367 'ai':1089,1118 'all-default':579 'allowlist':1196,1336 'allproject':1074 'alreadi':692,728,1022 'altern':975 'alway':552 'android':11,27,45,50,336,951,1043,1143,1301 'androidmanifest.xml':209 'animatedpreview':1217 'annot':126,313,1131,1216 'antigrav':868,874,877 'anyth':583 'api':147 'append':809 'appli':179,265,598,937,978,1101 'argument':577 'ask':632 'assum':562 'atf':301,312,1230 'author':1366 'auto':246,333,443,866 'auto-detect':245,332,865 'auto-dis':442 'automat':921 'avail':729 'awar':1272 'back':779 'bar':433 'base':1375 'baselin':1387 'bash':788,811 'before/after':24 'blind':738 'boolean':496 'bootstrap':113,887,1394 'build':143,337,383,389,463,952,1011,1200 'build/classes':414 'build/compose-previews':203 'build/compose-previews/previews.json':194 'build/compose-previews/renders/resources':226 'build/compose-previews/resources.json':211 'buildscript':1075 'bundl':70,86,1025,1129,1284 'byte':492 'bytecod':831 'cach':234,531 'cacheabl':230 'call':573 'callback':619 'cannot':1008 'captur':1227 'care':1154 'case':343 'case-insensit':342 'central':689 'chang':18,279,495,528,539,541,559,564,671,924 'check':83,707,1232 'ci':1057,1354 'class':129,192 'classpath':923,1080,1139 'claud':1332 'clean':409,515 'cli':138,242,244,726,762,1055,1287 'clock':1224 'cloud':1334 'cmp':1121 'code':155,459,682,973,988,1015,1209,1333,1343 'codelen':161 'collectpreviewinfo':1167 'com.android.application':1094 'command':169,270,767,798,845 'comment':1380,1390 'commonmain':1294 'compar':23,92 'compat':321 'compil':128,191,827 'compos':2,5,29,31,35,39,52,56,79,88,105,136,267,568,574,615,637,651,664,715,719,790,851,861,870,906,1018,1044,1088,1117,1234,1266,1290,1318,1322,1329,1361,1384 'compose-preview':1,78,87,104,135,266,663,714,718,789,860,869,905,1233,1265,1328,1383 'compose-preview-review':1360 'compose.components.uitoolingpreview':1127 'composepreview':948 'comput':497 'config':705,878 'configur':233 'content':1072 'copi':101,290,362,777 'correct':566 'creat':1064 'credenti':701 'curl':783 'current':1184 'daemon':903,920 'data':1243 'debug':340,950,955 'declar':184 'default':258,331,339,391,437,581,954,961 'demand':1179 'dep':610 'depend':644,1079,1159 'descriptor':858 'design':21,519,567,1311 'design/a11y.md':1228 'design/agent_cloud.md':1325 'design/capture_modes.md':1211 'design/cmp_shared.md':1288 'design/data_products.md':1237 'design/mcp.md':926,1262 'design/permissions.md':1191 'design/remote_compose.md':1319 'design/resource_previews.md':213,1299 'design/state_hoisting.md':676,1201 'design/vscode.md':1340 'design/wear_tiles.md':1312 'design/wear_ui.md':1304 'desktop':33,58,1122,1297 'detect':247,334,867 'devic':479 'di':590 'di-inject':589 'dialect':1323 'didn':549 'diff':1378 'direct':597,1013,1063 'disabl':444 'discov':124,196,218,272,283 'discoverandroidresourc':204 'discoverpreview':189 'disk':295,1259 'doc':1176 'doctor':90,316,721,792,814,909 'document':72 'done':735 'drawabl':220 'drive':140,1264 'dynam':981 'edit':521 'ee.schimke.composeai.preview':122,945,1081,1097,1099,1102 'ee.schimke.composeai.preview.gradle.plugin':1082 'emit':193,210,357 'enabl':1109 'enabled.set':963 'entri':474 'environ':1002,1113 'escap':395 'everi':198,217,259,669,1033 'exact':351,844 'exampl':1210 'exit':458 'export':1116 'express':1310 'extens':156,304,1020,1344 'extra':703,1048 'extract':647,659 'failur':464,467 'fals':966 'fast':662 'file':176,1012,1066 'filter':341 'find':303,1245 'fine':823 'first':645,708,910,931 'fixtur':628 'flag':280,542 'flow':1058 'follow':912,1071 'fontscal':482 'forc':393,875 'fssl':784 'full':381,477,1203 'function':7,167 'futur':670 'get':511 'gif':224,1218 'github':1391 'github.com':65 'github.com/yschimke/compose-ai-tools](https://github.com/yschimke/compose-ai-tools)':64 'go':1060 'gradl':120,142,177,229,249,382,388,405,530,992,1034,1260 'gradle-cach':228 'gradlepluginport':1077 'gradlew':255 'graphic':1150 'groovi':1073 'guidanc':630 'hand':626 'hand-rol':625 'hatch':396 'head':1376 'heat':1251 'heat-map':1250 'heightdp':481 'hierarchi':311,1246 'hoist':600,1206 'host':1274 'hover':163 'human':1345 'id':276,349,350,355,944 'idempot':749 'imag':42 'imagecomposescen':60 'implement':1126 'impli':385 'in-process':1280 'includ':475 'init':993,1026,1030,1106 'init-script':1029 'inject':591,643 'inner':614,650 'input':236 'insensit':344 'instal':85,114,709,743,834,854,864,873,881,1338,1395 'instruct':1051 'integr':974 'intern':1164 'invis':1137 'invoc':501,1035 'isn':836 'issu':421 'iter':19,516,634,666 'java':318,816 'jdk':820,829,1337 'jetpack':28,51 'json':356,358,471,523 'kill':901 'kotlin':942 'latest':95,802 'latest.release':1083 'launch':44 'layer':623 'layout':1247 'let':543,772 'like':1166 'line':376,451 'list':281,282,360,520 'live':1356 'load':1177 'local':100,1374 'log':415 'look':565 'loop':667 'maintain':62 'make':1037 'map':1252 'match':293,346,352,363 'materi':1308 'maven':688 'mavencentr':694,1078 'mcp':856,863,872,880,908,1219,1254,1271 'mcp-awar':1270 'mean':532 'milestone/heartbeat':375 'mipmap':221 'misbehav':891 'miss':712,764 'modifi':983,1009 'modul':182,260,326,330,507,1293 'move':551 'multi':1214,1278 'multi-preview':1213 'multi-workspac':1277 'multiplatform':32,57,1291 'must':1161 'name':1067 'nativ':430,1149 'need':1125,1186 'network':758 'notif':1276 'on-disk':1257 'one':308,657,885 'one-shot':307 'one-tim':656,884 'open':1369 'oper':1000 'opt':454 'opt-in':453 'option':269,325 'os':1307 'osc':425 'otherwis':1141 'output':289,361,384,472,1261 'outsid':10,1199 'overlay':314 'panel':160 'pars':208 'pass':400,1023 'path':152,277,368,819,835,839,1187,1339 'pattern':680,1207 'paus':1223 'paused-clock':1222 'per':373,473,506,1241 'per-modul':505 'per-rend':1240 'per-task':372 'persist':504 'pick':1041 'pin':804 'pipe':448 'pipelin':1298 'pleas':423 'plugin':121,186,264,685,697,939,943,980,1152,1173 'png':9,41,151,201,223,365,491,555 'pngpath':486 'pngs':526,547,1198 'point':419 'pr':1351,1389 'pr-comment':1388 'pr-review':1350 'preview':3,6,36,38,80,89,106,125,137,159,166,199,268,274,284,287,298,348,354,364,470,570,571,596,620,653,665,716,720,745,791,862,871,907,1019,1130,1215,1235,1267,1295,1330,1362,1385 'previewparam':478 'previous':500 'print':275,300,371,842,916 'println':1100 'probe':759 'process':1282 'produc':237 'progress':370,386,429,432,450,457 'project':34,250,320,691,852,985,1045,1085,1123 'project.name':1104 'project.pluginmanager.apply':1098 'project.plugins.hasplugin':1093,1096 'propos':646 'protolayout':1316 'provid':118 'prs':1370,1373 'purpos':188 'push':1275 'raw.githubusercontent.com':786,1398 'raw.githubusercontent.com/yschimke/compose-ai-tools/main/scripts/install.sh':785 'raw.githubusercontent.com/yschimke/compose-ai-tools/main/scripts/install.sh))':1397 're':110,240,534,734,740,794,895,1169 're-rend':533 're-run':109,739,793,894 're-work':239 'read':524,546,553,1180,1190 'reason':417 'recomposit':1249 'record':1221 'redo':537 'refer':1175 'regist':131 'registr':970 'registri':704 'relat':1348 'releas':96,803 'relev':1157 'reli':1145 'remot':1321 'remotedocu':1324 'render':4,37,132,150,171,197,216,273,285,286,297,315,369,399,466,535,825,890,1040,1242,1377 'renderallpreview':195 'renderandroidresourc':215 'report':424 'repositori':587,698,1076 'rerun':402 'rerun-task':401 'res/drawable':206 'res/mipmap':207 'resourc':1303 'respawn':919 'retent':1134 'review':1352,1363,1371 'robolectr':54,958,1147 'roll':627 'root':251,853 'run':77,111,305,322,408,713,741,754,774,795,896,904,1163,1327 'runtim':609 'same-vers':751 'sanction':394 'sandbox':1335 'scan':190,1140 'screen':603,674 'script':747,841,994,1027,1031,1107,1220 'scripts/install.sh':1396 'scroll':1226 'sdk':959 'sdkversion.set':956 'see':212,675,723,925 'server':857,1283 'servic':592 'set':965,1111,1193,1400 'setup':324,683,1049 'sh':782,859,1115 'sha256':278,488 'share':1292 'ship':73 'shot':309 'shouldn':1005 'show':271,359,522 'sibl':1359 'singl':175,292,329 'skia':61 'skill':117,1349,1364,1403 'skill-compose-preview' 'skills/compose-preview':68 'skip':545,968 'snapshot':1225 'sourc':987,1133 'source-yschimke' 'specif':806 'split':601 'stage':1197 'stale':398 'state':25,502,599,606,618,1205 'state-hoist':1204 'stateless':613,622,649 'stderr':378 'stdout':446 'still':756 'strict':232 'structur':1239 'studio':12,46 'substr':345 'success':461 'supervisor':918 'surfac':149,765 'system.getenv':1087 'take':584,617,1153 'target':327 'task':133,178,187,374,403,969,1165,1185 'taskbar/tab':431 'termin':428 'test/tooling':1158 'text':1379 'textual':449 'tile':1315 'time':658,886 'timeout':387,390 'togeth':1404 'tool':146,1090,1119,1255 'topic-agent-skills' 'topic-android' 'topic-claude-code' 'topic-claude-skills' 'topic-compose-multiplatform' 'topic-compose-preview' 'topic-gradle-plugin' 'topic-jetpack-compose' 'topic-kotlin' 'topic-skill-md' 'topic-vscode-extension' 'topic-wear-os' 'touch':413 'trail':102 'tree':1248 'troubleshoot':927,930 'troubleshooting-first':929 'true':529,964,1091,1120 'tti':440 'ui':17,558,1372 'uimod':483 'unchang':235 'unlock':660 'updat':107 'upgrad':799 'use':13,990,997 'user':770,1016 'v':380 'v0.10.10':76 'variabl':1114 'variant':335,338,953,1144 'variant.set':949 'verbos':379 'verdict':914 'verifi':16,317,815 'version':81,717,753,807,946,960 'via':53,59,144,456,1028,1105,1253,1296 'viewmodel':586,641 'vs':154,1014,1342 'walk':205,252 'warn':97 'wear':1306,1314 'when-not-to-act':932 'whether':724 'whose':527 'widthdp':480 'wipe':512 'wire':608,1170,1382 'without':43,982 'work':47,241 'workflow':1355 'workspac':1279 'wrapper':607 'write':879 'xml':219,1302 'zero':576,972 'zero-cod':971","prices":[{"id":"bce61587-5b38-4a59-b2b0-e2ab8e7f254a","listingId":"41e42b03-1e7c-420c-beca-1d6cb95cba54","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"yschimke","category":"compose-ai-tools","install_from":"skills.sh"},"createdAt":"2026-04-29T13:05:05.160Z"}],"sources":[{"listingId":"41e42b03-1e7c-420c-beca-1d6cb95cba54","source":"github","sourceId":"yschimke/compose-ai-tools/compose-preview","sourceUrl":"https://github.com/yschimke/compose-ai-tools/tree/main/skills/compose-preview","isPrimary":false,"firstSeenAt":"2026-04-29T13:05:05.160Z","lastSeenAt":"2026-05-14T06:57:17.515Z"}],"details":{"listingId":"41e42b03-1e7c-420c-beca-1d6cb95cba54","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"yschimke","slug":"compose-preview","github":{"repo":"yschimke/compose-ai-tools","stars":76,"topics":["agent-skills","android","claude-code","claude-skills","compose-multiplatform","compose-preview","gradle-plugin","jetpack-compose","kotlin","skill-md","vscode-extension","wear-os"],"license":"apache-2.0","html_url":"https://github.com/yschimke/compose-ai-tools","pushed_at":"2026-05-14T06:56:29Z","description":"Helping the Agents Compose the Things","skill_md_sha":"dbcace0237b628d0e58d88518d0df347b636cc89","skill_md_path":"skills/compose-preview/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/yschimke/compose-ai-tools/tree/main/skills/compose-preview"},"layout":"multi","source":"github","category":"compose-ai-tools","frontmatter":{"name":"compose-preview","description":"Render Compose @Preview functions to PNG outside Android Studio. Use this to verify UI changes, iterate on designs, and compare before/after states across Android (Jetpack Compose) and Compose Multiplatform Desktop projects."},"skills_sh_url":"https://skills.sh/yschimke/compose-ai-tools/compose-preview"},"updatedAt":"2026-05-14T06:57:17.515Z"}}