compose-ai-tools
Health Uyari
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Basarisiz
- rm -rf — Recursive force deletion command in .github/actions/preview-baselines/action.yml
Permissions Gecti
- Permissions — No dangerous permissions requested
This is a Gradle plugin and CLI tool that discovers and renders Jetpack Compose `@Preview` annotations into PNG images, allowing developers to view their composables outside of Android Studio.
Security Assessment
Overall Risk: Low. The tool does not request dangerous permissions or make external network requests to transmit data. However, there is a minor code finding: an `rm -rf` recursive force deletion command exists within a GitHub Actions workflow file (`.github/actions/preview-baselines/action.yml`). This is commonly used to clean up CI/CD cache or baseline directories and is not inherently malicious, though it triggered an automated alert. The tool runs locally, scans compiled class files, and uses a headless subprocess to render images. No hardcoded secrets were detected.
Quality Assessment
The project is actively maintained, evidenced by a repository push occurring just today. It uses the standard, permissive Apache-2.0 open-source license and has a clear, well-documented README that explains how the discovery and rendering processes work. The only drawback is its low community visibility; with only 5 GitHub stars, the tool has not yet been widely tested or adopted by the broader developer community.
Verdict
Safe to use, though it should be evaluated as an early-stage tool given its low community adoption.
Helping the Agents Compose the Things
compose-ai-tools
A Gradle plugin and CLI that discovers @Preview composables and renders them to PNG — outside
of Android Studio. Works with both Android (Jetpack Compose) and Compose Multiplatform
Desktop projects.
See SKILL.md
$ compose-preview list --module sample-wear
com.example.samplewear.PreviewsKt.ActivityListPreview_Devices - Large Round (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ActivityListPreview_Devices - Small Round (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ActivityListFontScalesPreview_Fonts - Large (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ActivityListFontScalesPreview_Fonts - Larger (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ActivityListFontScalesPreview_Fonts - Largest (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ActivityListFontScalesPreview_Fonts - Medium (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ActivityListFontScalesPreview_Fonts - Normal (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ActivityListFontScalesPreview_Fonts - Small (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ButtonPreview_Devices - Large Round (com/example/samplewear/Previews.kt)
com.example.samplewear.PreviewsKt.ButtonPreview_Devices - Small Round (com/example/samplewear/Previews.kt)
Also provides a VS Code plugin that displays them
How it works
Discovery
Scan compiled class files for @Preview annotations → build/compose-previews/previews.json.
For each method in each compiled class:
1. Check for direct @Preview or @Preview.Container annotations on the method.
If found, extract preview parameters (name, device, dimensions, backgroundColor, etc.)
and emit a preview entry.
2. Otherwise, walk the method's annotations looking for multi-preview meta-annotations.
For each annotation, check whether *its* annotation class carries @Preview.
Recurse through meta-annotations (with cycle detection via a visited set).
Emit a preview entry for each @Preview found transitively.
Deduplicate by fully-qualified name + preview name + device + dimensions.
Rendering (Desktop)
Launch a subprocess with the module's full classpath plus the renderer-desktop module.
1. Load the target class by name and resolve the composable function
via the Compose runtime's reflection API.
2. Create a headless ImageComposeScene at the target dimensions (2x density).
3. Set the scene content to: a background fill (from the @Preview annotation's
backgroundColor), with the composable function invoked inside it.
LocalInspectionMode is enabled so preview-aware composables render correctly.
4. Render two frames (the second allows animations and effects to settle).
5. Encode the Skia surface to PNG and write to the output file.
Rendering (Android)
Launch a subprocess inside a Robolectric sandbox with native graphics.
1. Bootstrap a ComponentActivity through Robolectric's activity lifecycle.
Configure the shadow display to match the target dimensions.
2. Set the activity content to the composable (same as Desktop:
background fill + reflected composable invocation + inspection mode).
3. Advance the main looper frame-by-frame (16ms per frame, up to 20 frames).
After each frame, sample ~64 pixels and compute a checksum.
Stop when the checksum is stable for 2 consecutive frames.
4. Draw the activity's root view to a bitmap, compress as PNG, write to file.
Caching
Both discovery and rendering are Gradle cacheable tasks with declared input/output
contracts. Unchanged source files produce no re-work on subsequent runs.
Configuration caching is strict (problems=fail).
Setup
The plugin is published to Maven Central.
No authentication, no PAT — just apply it.
1. Apply the plugin
// <module>/build.gradle.kts
plugins {
id("ee.schimke.composeai.preview") version "0.3.5"
}
Most projects already have mavenCentral() in theirpluginManagement.repositories (AGP and the Kotlin Gradle Plugin are both
on Central). If yours doesn't, add it:
// settings.gradle.kts
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
CMP Desktop projects additionally needimplementation(compose.components.uiToolingPreview) — the bundled@Preview annotation has SOURCE retention and is invisible to ClassGraph.
Check Releases for
the latest version.
Testing against a snapshot
Every push to main publishes a -SNAPSHOT build to the Central snapshots
repository. To try an unreleased change, add the snapshots repo topluginManagement and bump the plugin version to the next patch-SNAPSHOT:
// settings.gradle.kts
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
maven("https://central.sonatype.com/repository/maven-snapshots/") {
mavenContent { snapshotsOnly() }
}
}
}
// <module>/build.gradle.kts
plugins {
id("ee.schimke.composeai.preview") version "0.3.5-SNAPSHOT"
}
The snapshot version is the next patch ahead of the latest release
(e.g. last tag v0.3.4 → 0.3.5-SNAPSHOT). Snapshots are unsigned. See
docs/RELEASING.md for more detail.
Install the CLI
Download compose-preview-0.3.5.tar.gz (or .zip) from the
v0.3.5 release
and put the bin/ directory on your PATH:
curl -L -o compose-preview.tar.gz \
https://github.com/yschimke/compose-ai-tools/releases/download/v0.3.5/compose-preview-0.3.4.tar.gz
tar -xzf compose-preview.tar.gz
export PATH="$PWD/compose-preview-0.3.5/bin:$PATH"
compose-preview --help
Requires Java 21 on PATH (or JAVA_HOME).
Install the VS Code extension
Install Compose Preview
from the VS Code Marketplace, or from the command line:
code --install-extension yuri-schimke.compose-preview
The extension uses the Gradle plugin to render previews, so applyee.schimke.composeai.preview version 0.3.5 in your project as shown above.
Usage
Run discovery and rendering:
./gradlew :app:discoverPreviews # scan for @Preview annotations
./gradlew :app:renderAllPreviews # discover + render to PNG
Configuration
composePreview {
variant.set("debug") // Android build variant (default: "debug")
sdkVersion.set(35) // Robolectric SDK version (default: 35)
enabled.set(true) // disable to skip registration (default: true)
}
Project structure
| Module | Purpose |
|---|---|
gradle-plugin/ |
Gradle plugin — discovery, rendering task orchestration |
renderer-desktop/ |
Desktop renderer — ImageComposeScene + Skia PNG capture |
renderer-android/ |
Android renderer — Robolectric harness |
cli/ |
CLI with GraalVM native-image support |
sample-android/ |
Android sample with colored box @Preview composables |
sample-cmp/ |
CMP Desktop sample with colored box @Preview composables |
Requirements
- Gradle 9.4.1+
- Java 21
- AGP 9.1.0 (Android projects)
- Kotlin 2.2.21
- Compose Multiplatform 1.10.3 (Desktop projects)
Contributing
See docs/DEVELOPMENT.md for building the plugin, CLI, and
VS Code extension from source and running them locally against the bundled
samples.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi