.agents/skills/android-ui-visual-review/SKILL.md
Turn a PR or branch into trustworthy visual evidence. The comparison is useful only when the before and after builds use the correct commits, Android runtime, viewport, app state, and navigation path.
Before starting, resolve:
main.Do not block on publishing preference while doing read-only analysis if the user has not answered yet. Keep the local workflow useful on its own.
Never switch the user's active checkout between before and after revisions. Run from the repository root:
.agents/skills/android-ui-visual-review/scripts/create_review_worktree.sh \
--target "<PR URL, PR number, branch, or commit>"
For a branch with a non-default base:
.agents/skills/android-ui-visual-review/scripts/create_review_worktree.sh \
--target "<branch>" \
--base "<base ref>"
The script fetches a PR head when needed, computes the actual merge-base, creates a detached temporary worktree at the before SHA, and prints:
Keep artifacts outside the worktree so checkouts cannot remove them. The script
may symlink the ignored local.properties into the temporary worktree; never
publish it or quote its contents.
If a review session already exists and its SHAs are verified, reuse it. Do not create a second worktree for the same run.
Use the actual diff, not the PR title, to determine what should be visible.
git diff --stat, --name-status, and the focused diff between the
before and after SHAs.When the diff contains no UI/resource/state-to-UI change, say so. If the user asked for a screenshot for every target, capture the nearest affected surface before and after and label the expected result no visual delta. Do not invent a UI claim for a behavioral fix.
Prefer an emulator for repeatable UI evidence. At run time:
-sysdir override with an isolated data
directory is acceptable.adb -s "$ANDROID_REVIEW_SERIAL" shell getprop ro.build.version.release
adb -s "$ANDROID_REVIEW_SERIAL" shell getprop ro.build.version.sdk
adb -s "$ANDROID_REVIEW_SERIAL" shell getprop ro.build.version.security_patch
adb -s "$ANDROID_REVIEW_SERIAL" shell wm size
adb -s "$ANDROID_REVIEW_SERIAL" shell wm density
Use an explicit emulator serial for every ADB command when any physical device is also connected. Never put serials, device names, local paths, IP addresses, or other machine identifiers into reports or GitHub comments.
Use a physical device only when the affected UI depends on hardware that the
emulator cannot reproduce. Ask before changing or clearing a physical device.
This skill does not replace Mesh Lab: if the diff changes mesh, transport,
crypto, service, or physical peer behavior, use the mesh-lab skill separately
before claiming the behavior works.
The worktree starts at the before SHA.
./gradlew assembleDebug.adb install -r.before-<surface>-<state>-<width>-<theme>.png
Use adb exec-out screencap -p so the PNG is written directly to the artifact
directory. Inspect every screenshot immediately; a successful command is not
proof that the intended screen was visible.
Before switching commits:
Checkout the recorded after SHA in the detached worktree, reapply the same
debug-only fixture if needed, build, and install with -r when state
preservation is part of the comparison.
Replay the same navigation and capture matrix. Name files with the matching
after- prefix. If reinstalling cannot preserve the state, replay the fixture
from its recorded inputs rather than comparing different states.
For responsive captures, record logical width in dp. On a fixed-pixel emulator, changing density is acceptable when the calculation is documented:
density = physical_width_px × 160 / desired_width_dp
Restore the original density/theme/locale after the matrix is complete.
Prefer existing debug hooks. When they cannot express the visual state, add the
smallest temporary command to
app/src/debug/java/com/bitchat/android/testhook/TestHookDriver.kt.
The fixture must:
src/debugAfter the final capture, remove the temporary fixture with a focused patch and verify that the review worktree has no tracked modifications. Never commit or publish the fixture unless the user separately asks to productize it.
Create capture-manifest.json in the artifact directory using
assets/capture-manifest.example.json as
the shape. Use paths relative to the manifest and omit device selectors and
local absolute paths.
Validate it:
python3 \
.agents/skills/android-ui-visual-review/scripts/validate_capture_manifest.py \
"<artifact-directory>/capture-manifest.json"
Write a Markdown report next to the manifest with:
End the local run only after:
Leave the review session and artifacts available for later inspection unless the user asks for cleanup.
Only after explicit user approval, follow references/github-publishing.md.
The PR comment should contain:
Use gh for all GitHub reads and writes. Verify the posted comment by reading it
back and counting the expected image embeds. Do not expose local paths or
machine identifiers, do not override Git author/committer identity, and do not
push screenshot files to a source branch unless the user separately authorizes
that repository change.
Give the user: