https://github.com/lukas-hinterleitner/visual-app-skills
Agent skills for visually testing mobile apps on Android — run a Flutter, React Native, or native Android app on an emulator/device, capture real screenshots via adb, read logs, optionally diff against a Figma design, and verify the UI rendered correctly. Works with Claude Code and other coding agents.
https://github.com/lukas-hinterleitner/visual-app-skills
adb agent-skills android claude-code claude-skills emulator figma flutter mobile react-native screenshot-testing skill ui-testing visual-regression visual-testing
Last synced: 13 days ago
JSON representation
Agent skills for visually testing mobile apps on Android — run a Flutter, React Native, or native Android app on an emulator/device, capture real screenshots via adb, read logs, optionally diff against a Figma design, and verify the UI rendered correctly. Works with Claude Code and other coding agents.
- Host: GitHub
- URL: https://github.com/lukas-hinterleitner/visual-app-skills
- Owner: lukas-hinterleitner
- License: apache-2.0
- Created: 2026-05-30T10:33:41.000Z (26 days ago)
- Default Branch: main
- Last Pushed: 2026-05-30T10:45:19.000Z (26 days ago)
- Last Synced: 2026-05-30T12:15:38.568Z (26 days ago)
- Topics: adb, agent-skills, android, claude-code, claude-skills, emulator, figma, flutter, mobile, react-native, screenshot-testing, skill, ui-testing, visual-regression, visual-testing
- Language: Shell
- Size: 47.9 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Notice: NOTICE
Awesome Lists containing this project
README
# visual-app-skills
> Agent skills that give a coding agent **eyes on your running app**. Run a
> Flutter, React Native, or native Android app on an emulator or device, capture
> real screenshots via `adb`, read the logs, and verify that a code change
> rendered correctly. Works with Claude Code and other agents that support the
> [Agent Skills](https://agentskills.io) format.
[](./LICENSE)
[](https://agentskills.io)
This is the open, generalized version of a skill that started life inside a
single Flutter app. It answers the question you'd otherwise answer by squinting
at an emulator: **did my last change actually render correctly?** — on a real
device, with screenshot and log evidence, not guesswork.
Each skill drives the same loop: launch the app → wait for the first real frame
→ screenshot via `adb` → read the logs → compare against what the change
intended → report a concrete verdict. Optionally, diff the screen against a
Figma design.
> **Scope:** Android only — these skills drive `adb` against a device or
> emulator. iOS verification needs a Mac and `xcrun simctl`, which is out of
> scope (the repo is laid out to accept an iOS skill later).
## The skills
| Skill | For | Fires on prompts like |
|-------|-----|-----------------------|
| [`flutter-test-android-visually`](skills/flutter-test-android-visually) | Flutter apps (incl. multi-entry / `--target`) | "test my Flutter app on Android", "see the visual changes" |
| [`react-native-test-android-visually`](skills/react-native-test-android-visually) | React Native **and** Expo | "run my RN/Expo app and check this screen" |
| [`native-android-test-visually`](skills/native-android-test-visually) | Native Android — Kotlin/Java, Jetpack Compose or Views, Gradle | "build and run my Android app", "verify the Compose screen" |
Anything else that produces an Android APK — Kotlin/Compose Multiplatform,
Capacitor/Ionic, Cordova, NativeScript, .NET MAUI, Unity — is covered by the
generic recipe in [`other-frameworks.md`](shared/references/other-frameworks.md):
if it installs and runs on a device, the `adb` capture core works; you just
supply the run command, the application id, and where it logs.
## Requirements
- **Android SDK Platform-Tools** (`adb`) on `PATH`, and a connected device or a
running emulator.
- The **toolchain for your app**: the Flutter SDK, or Node + your package
manager (React Native/Expo), or the Gradle wrapper (native Android).
- A coding agent that supports the **Agent Skills** format (e.g. Claude Code).
- *(Optional)* a **Figma MCP server**, only if you want the Figma-diff step.
None of these are bundled — they're prerequisites you already have for building
your app.
## Install
### Option A — `skills` CLI (recommended; works across 18+ agents)
Cross-agent install via Vercel's [`skills`](https://skills.sh) CLI — Claude
Code, Cursor, Codex, Copilot, Gemini, Windsurf, Cline, and more:
```bash
npx skills add lukas-hinterleitner/visual-app-skills # all three skills
npx skills add lukas-hinterleitner/visual-app-skills \
--skill flutter-test-android-visually # just one
```
It git-clones the repo (so the shared core resolves) and installs each skill
into your agent's skills directory, dereferencing the symlinks. Installs also
surface the collection on the [skills.sh](https://skills.sh) leaderboard.
### Option B — Claude Code plugin
```text
/plugin marketplace add lukas-hinterleitner/visual-app-skills
/plugin install visual-app-skills@visual-app-skills
```
This clones the whole repo, so the shared core resolves automatically. The
three skills become available as `visual-app-skills:`.
### Option C — drop-in via the installer (any agent)
```bash
git clone https://github.com/lukas-hinterleitner/visual-app-skills.git
cd visual-app-skills
./install.sh flutter-test-android-visually # or: ./install.sh all
# custom destination (e.g. project scope):
./install.sh flutter-test-android-visually .claude/skills
```
`install.sh` **dereferences** the shared symlinks, so each installed skill
folder is fully self-contained and works with no dependency on this repo.
### Option D — manual copy
```bash
cp -RL visual-app-skills/skills/flutter-test-android-visually ~/.claude/skills/
```
> ⚠️ Use `cp -R**L**` (capital L — dereference symlinks). A plain `cp -r` would
> copy the shared files as dangling symlinks, because the skills share their
> common core via symlinks (see below). Options A–C handle this for you.
## How it works
The bulk of each skill is identical — the `adb` capture loop, UI driving, and
troubleshooting are framework-agnostic. Only the **run command** and **where the
app logs** differ per framework. So each skill's `SKILL.md` is a thin,
framework-specific shell that points to:
- `references/capture-loop.md` — the universal procedure (shared)
- `references/.md` — the run/launch/log specifics (unique per skill)
- `references/driving-the-ui.md`, `troubleshooting.md`, `figma-comparison.md`,
`other-frameworks.md` — shared
- `scripts/` — `check-devices.sh`, `launch.sh`, `snap.sh`, `capture-logs.sh`,
`stop.sh` (shared, framework-agnostic)
The agent only loads a reference when it needs it (progressive disclosure), so
each invocation stays lightweight.
## Repository layout & the no-duplication design
```text
visual-app-skills/
├── .claude-plugin/marketplace.json # makes the repo an installable plugin
├── shared/ # the single source of truth
│ ├── scripts/*.sh
│ └── references/{capture-loop,driving-the-ui,troubleshooting,figma-comparison,other-frameworks}.md
└── skills/
└── -test-android-visually/
├── SKILL.md # real, framework-specific
├── references/.md # real, framework-specific
├── references/.md # symlink → ../../../shared/references/…
├── scripts/ # symlink → ../../shared/scripts
└── evals/evals.json
```
The shared core lives in `shared/` **once** and is symlinked into each skill, so
there is zero duplication to keep in sync. The trade-offs:
- **Plugin install (Option A)** and a full `git clone` resolve the symlinks
natively — the whole repo is present, so the targets exist.
- **Drop-in (Options B/C)** must dereference the symlinks. `install.sh` does
this; for a manual copy use `cp -RL`.
- **Windows:** enable symlinks in git (`git config --global core.symlinks true`,
plus Developer Mode) before cloning, or just use `install.sh`, which writes
real files.
## Optional: Figma comparison
If your team designs in Figma and you have the **Figma MCP server** configured,
paste a `figma.com/design/...` link and the skill will fetch the design and
compare it to the live screen (layout, color, typography, spacing — by relative
proportion, not pixels). Without Figma, everything else works unchanged — see
[`figma-comparison.md`](shared/references/figma-comparison.md).
## Trademarks & affiliation
"Android", "Flutter", and "Jetpack Compose" are trademarks of Google LLC;
"React Native" of Meta; "Expo" of Expo (650 Industries); "Figma" of Figma, Inc.;
"Claude" / "Claude Code" of Anthropic. This is an independent community project,
**not affiliated with or endorsed by** any of them; the names are used only to
describe interoperability. See [`NOTICE`](./NOTICE).
## License
[Apache License 2.0](./LICENSE) © 2026 Lukas Hinterleitner. You may use, modify,
and redistribute these skills — including commercially — provided you keep the
copyright/license notices and state your changes. See [`NOTICE`](./NOTICE) for
attribution and the third-party-tool disclosures.
## Contributing
Issues and PRs welcome — see [`CONTRIBUTING.md`](./CONTRIBUTING.md). The one hard
rule: **never commit third-party binaries** (an SDK, `adb`, a Figma server).
They stay user-installed prerequisites.