AgentPreview

Let agents inspect the UI they are changing.

Add the published Gradle plugin, capture one Compose preview, and hand the screenshot plus JSON bundle to your coding agent without opening Android Studio.

Published as dev.staticvar.agentpreview for Android and Compose Multiplatform projects with an Android target. Keep the concrete plugin version in your Gradle version catalog or pluginManagement block.

0:build/agentPreviewSnapshots*
$ tree build/agentPreviewSnapshots

app-main-LoginPreview/android-phone/
  screenshot.png
  snapshot.json

app-main-ProfileCard-previewParam-0/android-phone/
  screenshot.png
  snapshot.json
screenshot.png

Pixels for visual inspection.

snapshot.json

Preview metadata, viewport, semantics, layout hints, and source hints.

AndroidX @Preview PreviewParameter Compose semantics layoutTree hints CMP via Android target

Use the right layer

Each tool has a place.

AgentPreview focuses on pre-launch Compose preview artifacts. Android CLI focuses on the Android runtime and device workflow. A2UI focuses on agent-generated UI protocols. Official screenshot testing focuses on regression gates.

01 / Gradle preview artifacts

AgentPreview

Use when an agent edits Compose UI and needs a focused screenshot plus snapshot.json from a specific @Preview, preview parameter, or viewport before launching the app.

Less useful for full navigation flows, permissions, backend state, or device-only behavior.

02 / Device and emulator runtime

Android CLI

Use when the task needs Android SDK setup, emulator lifecycle, APK deployment, runtime screen capture, layout-tree inspection, or visual element targeting on a connected device or emulator.

Less useful for discovering Compose previews or rendering isolated preview states without a running app.

03 / Agent-generated interfaces

A2UI

Use when an agent should send declarative UI messages that a host app renders with trusted native components, catalogs, data binding, and action handling.

Less useful as an Android inspection tool; renderer behavior depends on the client implementation.

04 / Golden regression gates

Compose Preview Screenshot Testing

Use when a team wants approved reference images, validation tasks, and HTML diff reports around selected Compose previews in CI or release checks.

Less useful for ad hoc agent iteration when you do not want to create or update golden files.

What agents receive

A screenshot for vision. JSON for reasoning.

Each capture is designed to be small enough for automated review and specific enough for UI iteration: preview metadata, viewport details, semantics nodes, optional layout-tree data, and best-effort source hints.

Preview-aware

Discovers AndroidX previews, expands @PreviewParameter values, and keeps generated capture IDs filterable.

Agent-readable

Pairs screenshot.png with snapshot.json so an agent can compare pixels with structure.

Source-oriented

Includes source file, line, component, and modifier hints when Compose tooling data makes them available.

Viewport controlled

Capture focused Android phone, tablet, or custom viewports without running a full visual test suite.

snapshot.json
{
  "schemaVersion": 1,
  "preview": {
    "id": ":app:main:LoginPreview:previewParam-0",
    "name": "Login",
    "group": "Auth",
    "source": "LoginPreview.kt:12",
    "previewParameter": {
      "providerClassName": "dev.example.LoginStateProvider",
      "index": 0
    }
  },
  "viewport": {
    "platform": "android",
    "name": "phone",
    "width": 393,
    "height": 852,
    "density": 1.0
  },
  "nodes": [{
    "id": "semantics-12",
    "role": "Button",
    "text": "Continue",
    "bounds": { "x": 48, "y": 720, "width": 297, "height": 56 },
    "actions": ["OnClick"],
    "tag": "continue-button",
    "source": "LoginScreen.kt:84"
  }],
  "layoutTree": [{
    "id": "layout-3",
    "boundsPx": { "x": 24, "y": 96, "width": 345, "height": 640 },
    "boundsDp": { "x": 24.0, "y": 96.0, "width": 345.0, "height": 640.0 },
    "componentHint": "androidx.compose.foundation.layout.Column",
    "sourceName": "LoginCard",
    "sourceFile": "LoginScreen.kt",
    "sourceLine": 84,
    "sourceHintKind": "tooling-nearest-app-ancestor"
  }],
  "render": { "mode": "robolectric" }
}

Focused by default

Use Gradle commands agents already know how to run.

AgentPreview stays close to the build. List previews, dry-run a plan, narrow by preview or viewport, then capture only the UI states that matter for the current change.

Gradle does not auto-select the latest community plugin version. Define the AgentPreview plugin version once in your version catalog or pluginManagement, then apply that alias in the module that owns previews.

01

Add the plugin

// build.gradle.kts
// Version comes from your Gradle version catalog.
plugins {
  alias(libs.plugins.agentpreview)
}
02

Configure captures

agentPreview {
  maxPreviewParameterValues.set(8)
  android {
    viewport("phone", 393, 852)
    screenshot {
      cropToContent.set(true)
      cropPaddingDp.set(20)
    }
  }
}
03

List and plan

./gradlew :app:listComposePreviews

./gradlew :app:captureComposePreviews \
  -PagentPreview.dryRun=true \
  -PagentPreview.previewNameFilter=:app:main:LoginPreview \
  -PagentPreview.viewportFilter=preview \
  -PagentPreview.maxCaptures=1
04

Capture the target states

./gradlew :app:captureComposePreviews \
  -PagentPreview.previewNameFilter=:app:main:LoginPreview \
  -PagentPreview.viewportFilter=preview \
  -PagentPreview.maxCaptures=1

Published setup

Use the same plugin in Android apps, CMP apps, and Android KMP design systems.

AgentPreview runs from the Android side of your build. Apply the plugin to the Android app module, the CMP Android application module, or the Android KMP library/design-system module that owns the previews.

  • Android app: apply it beside com.android.application or com.android.library.
  • CMP app: apply it to the Compose app module with the Android target, such as :composeApp.
  • Design system: apply it to the Android KMP library module, such as :designSystem.
  • All variants use the same tasks: listComposePreviews and captureComposePreviews.

Consumption examples

Pick the module that owns your previews.

A

Android app or library

// app/build.gradle.kts
plugins {
  id("com.android.application")
  id("org.jetbrains.kotlin.android")
  alias(libs.plugins.agentpreview)
}

./gradlew :app:captureComposePreviews
B

CMP Android app

// composeApp/build.gradle.kts
plugins {
  id("com.android.application")
  id("org.jetbrains.kotlin.multiplatform")
  alias(libs.plugins.agentpreview)
}

./gradlew :composeApp:captureComposePreviews
C

Android KMP design system

// designSystem/build.gradle.kts
plugins {
  id("com.android.kotlin.multiplatform.library")
  id("org.jetbrains.kotlin.multiplatform")
  alias(libs.plugins.agentpreview)
}

./gradlew :designSystem:captureComposePreviews

Honest boundaries

What AgentPreview does not promise yet.

Android backend first

Current captures are designed around Android rendering. Desktop and web Compose renderers are future work.

CMP via Android

Compose Multiplatform support is routed through the Android target, not native desktop or web targets. CMP assets/fonts are Android-asset backed; common strings, dimensions, and vectors are wired for Robolectric captures.

Hints are best-effort

Layout and source hints depend on Compose tooling data and may fall back to framework or preview-entrypoint information.

Focused captures

Screenshots crop to composable content by default, with full-viewport fallback when content bounds are ambiguous.

Placeholder modes

Only robolectric is visual evidence. fake and diagnostic-fallback screenshots are placeholders.

Capture one preview. Review the actual artifact.

Use the agent workflow docs and snapshot schema to wire AgentPreview into an Android or CMP Android-target build, or install the AgentPreview workflow skill for your coding agent.

npx skills add static-var/AgentPreview --skill agentpreview
Open AgentPreview on GitHub

Agent workflow · Snapshot schema