src/main/skills/verifying_compose_ui/SKILL.md
Visually verifies Compose UI components by rendering @Composable/@Preview functions to images from the project's JVM runtime; STRONGLY PREFERRED for rapid UI iteration and visual feedback on any composable. Do NOT use for build lifecycle tasks or dependency auditing.
npx skillsauth add rnett/gradle-mcp verifying_compose_uiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
IMPORTANT: runComposeUiTest and image capture methods (node.captureToImage()) are NOT supported on Android and CANNOT work.
The runComposeUiTest function requires a JVM-based test runtime with desktop Compose rendering (via Skiko on JVM/Desktop). Android's ART (Android Runtime) does not support the desktop Compose testing APIs, and image capture via
captureToImage() relies on desktop-specific rendering pipelines that are fundamentally incompatible with Android.
For visual verification of Composables, you MUST use a JVM or Desktop target source set. This is not a workaround—it is the only supported method.
Recommended approach:
commonMain) that is shared across all targetsjvmMain, desktopMain) that depends on commonMainsourceSet: "jvmMain" or sourceSet: "jvmTest")This is the standard KMP pattern and allows you to verify your UI code without needing an Android device or emulator.
sourceSet: "androidMain"sourceSet: "androidTest"runComposeUiTest on AndroidcaptureToImage() on AndroidsourceSet: "jvmMain" or sourceSet: "jvmTest"sourceSet: "desktopMain" or sourceSet: "desktopTest"runComposeUiTest with captureToImage() on JVM/Desktop targetsVisually verifies and renders any @Composable or @Preview directly to high-quality images from the project-aware REPL for instant, authoritative visual feedback.
kotlin_repl to render Compose components instead of running the full application for visual checks.projectRoot.node.captureToImage() and responder.render(bitmap) to return the visual output.additionalDependencies if necessary.@Preview functions in the project source code before creating new ones.projectRoot: Ensure projectRoot is an absolute file system path for all kotlin_repl calls.androidx.compose.ui:ui-test-junit4) are on the classpath.runComposeUiTest.node.captureToImage() and responder.render(bitmap) to return the visual output.kotlin_repl currently only supports JVM-based source sets. ALWAYS select a JVM or Desktop target source set for visual checks.envSource: SHELL if environment variables are missing: Set env: { envSource: "SHELL" } (REPL start) or invocationArguments: { envSource: "SHELL" } (Gradle tasks) if expected env vars (e.g., JAVA_HOME) are not found.@Preview functions.@Composable or @Preview function.grep_search(pattern="@Preview").test source set (preferred) or main with additionalDependencies.kotlin_repl(command="start").kotlin_repl(command="run") to execute the rendering script.runComposeUiTest to render and capture the component.import androidx.compose.ui.test.*
import com.example.ui.MyButton
runComposeUiTest {
setContent {
MyButton(text = "Click Me")
}
val node = onRoot()
responder.render(node.captureToImage())
}
// Reasoning: Using kotlin_repl to render a specific component and retrieve its visual representation via the responder API.
import androidx.compose.ui.test.*
import com.example.ui.MyButtonPreview // Top-level preview function
runComposeUiTest {
setContent {
MyButtonPreview()
}
val node = onRoot()
responder.render(node.captureToImage())
}
// Reasoning: Reusing an existing authoritative preview function to verify its visual correctness.
import androidx.compose.ui.test.*
import com.example.ui.MyCounter
import com.example.viewmodel.MyViewModel
runComposeUiTest {
val viewModel = MyViewModel()
setContent {
MyCounter(viewModel)
}
// Capture state before interaction
responder.render("State before: ${viewModel.count}")
responder.render(onRoot().captureToImage())
// Perform interaction
onNodeWithText("Increment").performClick()
// Capture state after interaction
responder.render("State after: ${viewModel.count}")
responder.render(onRoot().captureToImage())
}
// Reasoning: Capturing visual snapshots before and after an interaction to verify state-dependent UI changes.
responder.render(bitmap).tools
Provides authoritative guidance for ALL Gradle operations: executing builds, running tests with surgical filtering, introspecting project structure, creating modules, and diagnosing failures; ALWAYS use instead of raw shell `./gradlew` for build execution, test runs, task introspection, module creation, performance audits, and documentation research. Do NOT use for dependency graph auditing/updates (use `managing_gradle_dependencies`) or dependency/plugin/Gradle source exploration (use `exploring_dependency_sources`).
tools
Reads and searches source code across ALL scopes: external library dependencies, plugins (buildscript), and Gradle Build Tool internal source code; use whenever you need to UNDERSTAND an API — its shape, signature, parameters, overloads, or implementation — before writing any code that calls it; covers project dependencies (via project/configuration/source set scope), plugins (via `sourceSetPath=":buildscript"`), and Gradle internals (via `gradleSource: true`). Prefer this over the REPL for all API research; reading source is instantaneous and complete. Do NOT use for project source code (use grep/tilth), Gradle documentation (use `gradle_docs` via the `gradle` skill), or Maven Central discovery (use `managing_gradle_dependencies`).
development
Audits and manages Gradle dependency graphs with high-resolution update checks, transitive tree analysis, and Maven Central discovery; use for dependency auditing, finding stable updates, and resolving GAV coordinates. Do NOT use for exploring dependency source code (use `exploring_dependency_sources`) or running builds/tests (use `gradle`).
development
Executes Kotlin code interactively within the project's full JVM classpath. Use when you need to RUN code: verify runtime behavior, experiment with logic, or render Compose UI previews. Do NOT use to understand an API's shape or signature — read its source with `exploring_dependency_sources` instead.