Skip to content

yschimke/compose-ai-tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,100 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

compose-ai-tools

Documentation — install, VS Code Marketplace, and one-page-per-product reference for each data extension.

Render @Preview composables to PNG outside Android Studio, so AI coding agents can see what they're changing. Works with Jetpack Compose (Android, via Robolectric) and Compose Multiplatform Desktop (via ImageComposeScene).

Renders include paused-clock animation captures (GIF or single frame) and opt-in ATF accessibility checks with annotated overlays.

Also renders Android XML resources — vector drawables, adaptive launcher icons, animated-vector drawables — and indexes the icon attributes in AndroidManifest.xml so tooling can link manifest lines to the same rendered PNG. Modules without any matching resources self-no-op, so this comes along for free with the plugin.

What it ships

  • Agent skills — the compose-preview and compose-preview-review skill bundles live in yschimke/skills. Point any agent that can fetch a URL at them; each skill is a complete install-and-iterate playbook. Bootstrap a host machine (CLI + skills in one shot) with the installer in yschimke/skills:

    curl -fsSL https://raw.githubusercontent.com/yschimke/skills/main/scripts/install.sh | bash
  • VS Code extension — published to the VS Code Marketplace and Open VSX (for VSCodium / Cursor / Windsurf). Install from inside the IDE: open the Extensions view (⇧⌘X / Ctrl+Shift+X), search Compose Preview, click Install. Source in vscode-extension/.

  • GitHub Actions — composite actions for CI: install (CLI on $PATH), preview-baselines (push baselines), preview-comment (before/after PR comments), a11y-report (accessibility findings).

Setup

The plugin is published to Maven Central — no auth, no PAT.

// <module>/build.gradle.kts
plugins {
    id("ee.schimke.composeai.preview") version "0.10.19"
}

Working examples: samples/android/build.gradle.kts, samples/wear/build.gradle.kts, samples/cmp/build.gradle.kts.

Zero-Code Integration (Alternative)

You can apply the plugin dynamically without modifying the project's source code, useful for AI agents on the CLI, in CI, or when exploring the tool without committing changes. The compose-preview CLI ships a bundled Gradle init script and passes it via --init-script on every invocation, so projects that already apply com.android.application / com.android.library / org.jetbrains.compose pick up the preview plugin without an edit to build.gradle.kts:

compose-preview list                # scan @Preview annotations
compose-preview render              # render every @Preview to PNG

For direct ./gradlew use (e.g., a CI step that needs extra Gradle flags), materialise the same init script once and thread its path through each invocation:

INIT_SCRIPT="$(compose-preview init-script --path)"
./gradlew --init-script "$INIT_SCRIPT" :app:discoverPreviews
./gradlew --init-script "$INIT_SCRIPT" :app:renderAllPreviews

VS Code users: the Compose Preview extension already auto-injects via --init-script on every Gradle invocation it makes — no extra setup needed.

The CLI's auto-inject script detects projects that already declare the plugin (either literally as id("ee.schimke.composeai.preview") version "..." or via a gradle/libs.versions.toml alias resolved through alias(libs.plugins.<x>)) and skips the classpath injection for those builds, so mixed setups work without conflicts.

Requires Java 17+, Gradle 8.13+, AGP 8.13.0+ (Android), Kotlin 2.0.21+, Compose Multiplatform 1.10.3+ (Desktop). The bottom edge of the supported consumer envelope is exercised on every push by the agp8-min job against the fixture under .github/ci/fixtures/agp8-min/; the project's own build runs on a newer toolchain (see docs/AGENTS.md).

Samples

Source under samples/. Rendered baselines (PNGs and animation GIFs, regenerated on every push to main) are browsable inline on the compose-preview/main branch:

ATF a11y findings for the same samples are on the compose-preview/a11y/main branch.

Agent PR hall of fame

Real-world PRs opened by AI coding agents that used compose-preview to verify their changes.

  • yschimke/meshcore-mobile#36 — renders Play Store listing screenshots (phone + 7"/10" tablet) directly from Play Store — … @Preview composables, replacing hand-crafted PNGs.

Have one to add? Open a PR or an issue.

More

Reusable Codex PR review workflow (Preview-gated)

Use .github/workflows/codex-pr-review-reusable.yml to run AI PR review only after preview generation succeeds and with both code + visual context. The reusable workflow supports Codex, Claude, or Gemini based on which API key is configured (exactly one).

Minimal caller setup

This repository wires the reusable workflow in .github/workflows/codex-pr-review.yml using a preview job plus a thin uses: call to the reusable workflow.

To avoid duplicate PR review comments in this repository, .github/workflows/preview-comment.yml is kept manual (workflow_dispatch). Consumer repos can still choose either workflow (or both) based on their needs.

name: PR Review (Codex + Preview)

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  preview:
    runs-on: ubuntu-latest
    outputs:
      preview_status: ${{ job.status }}
    steps:
      - uses: actions/checkout@v4
      - run: ./gradlew :app:renderAllPreviews
      - uses: actions/upload-artifact@v4
        with:
          name: compose-preview-images
          path: app/build/compose-previews/renders
      - uses: actions/upload-artifact@v4
        with:
          name: compose-preview-diff-images
          path: app/build/compose-previews/diffs
      - uses: actions/upload-artifact@v4
        with:
          name: compose-preview-metadata
          path: app/build/compose-previews/**/*.json

  codex-review:
    needs: [preview]
    uses: yschimke/compose-ai-tools/.github/workflows/codex-pr-review-reusable.yml@main
    with:
      preview_status: ${{ needs.preview.result }}
      strict_mode: true
    secrets:
      codex_api_key: ${{ secrets.CODEX_API_KEY }}
      claude_api_key: ${{ secrets.CLAUDE_API_KEY }}
      gemini_api_key: ${{ secrets.GEMINI_API_KEY }}
      github_token: ${{ secrets.GITHUB_TOKEN }}

Artifact contract

  • Agent selection is key-driven: set exactly one of codex_api_key, claude_api_key, or gemini_api_key.
  • Codex has a built-in default command. Claude/Gemini require claude_review_command / gemini_review_command inputs unless you wrap them in your own caller.
  • compose-preview-images: rendered head/PR preview images.
  • compose-preview-diff-images: visual diffs (baseline vs PR/head), if your preview pipeline generates them.
  • compose-preview-baseline: optional baseline images used to generate diffs.
  • compose-preview-metadata: preview index and mapping files (for example: preview id → file path/module).

Runtime/toolchain provided by reusable workflow

  • Java 21 (actions/setup-java, JAVA_HOME from the action).
  • Android SDK (android-actions/setup-android).
  • compose-preview-review skill installation from yschimke/skills.
  • Code diff capture (git diff) plus artifact download for visual review.

Failure modes / troubleshooting

  • Preview failed/cancelled/skipped: workflow posts a blocked comment and does not run Codex visual review.
  • Artifacts missing: workflow posts a blocked comment with “missing context” details.
  • Strict mode enabled + blocking findings: reusable workflow fails its check.
  • PR branch update (update_pr_branch, default true): workflow attempts to commit .codex/review-output/{codex-review.md,codex-review.json} to the PR branch; for fork PRs or restricted tokens it skips with a warning.
  • No preview diffs available: Codex still reviews code + available preview images and explicitly marks missing visual-diff context.

Optional integration patterns

  • needs: pattern (shown above): same workflow, same run.
  • workflow_run pattern: trigger a second workflow after preview workflow completion and pass preview_status: success plus artifact names into the reusable workflow call.

Example review comment template

## Codex PR Review

### Code findings
- [blocking] `ui/ProfileCard.kt:84` Null-state branch removed; can crash in empty profile payload.
- [warning] `ui/Theme.kt:42` Hard-coded color bypasses design token.

### Preview findings
- [blocking] `ProfileCard_Default.png` text overlaps avatar at 320dp width.
- [warning] `SettingsScreen_Dark.png` contrast drop on secondary action.

### Missing context / blocked checks
- Baseline metadata for `WearSummaryPreview` missing.
- Visual diff for `TabletLandscape` not present in uploaded artifacts.

Validation recipe with intentional bad UI change

  1. Intentionally regress a composable (for example, shrink parent width and increase fixed text size to force clipping).
  2. Run your preview job to regenerate preview images and visual diffs.
  3. Open/update a PR and confirm:
    • Preview job succeeds.
    • Reusable Codex workflow runs after preview (needs/workflow_run gate).
    • PR comment includes both code and preview findings.
    • In strict mode, blocking visual regression findings fail the check.