diff --git a/.agents/skills/android-readme-screenshot-studio/SKILL.md b/.agents/skills/android-readme-screenshot-studio/SKILL.md index af80579a..33a131c9 100644 --- a/.agents/skills/android-readme-screenshot-studio/SKILL.md +++ b/.agents/skills/android-readme-screenshot-studio/SKILL.md @@ -1,6 +1,6 @@ --- name: android-readme-screenshot-studio -description: Create or refresh polished, high-resolution screenshots of the Bitchat Android app for README and repository showcase use. Use this skill whenever a user asks for README screenshots, app-store-like repository images, a populated mesh-chat showcase, voice-note or media conversation captures, a geohash globe image, higher-resolution Pixel captures, or a PR that adds or replaces documentation screenshots. It owns the complete workflow from latest-main isolation and deterministic synthetic fixtures through real app rendering, visual inspection, system-chrome cropping, README asset updates, clean builds, and an optional PR. Do not use it for before/after UI regression evidence, which belongs to android-ui-visual-review, or for physical mesh behavior, which belongs to mesh-lab. +description: Create or refresh polished, high-resolution screenshots of the Bitchat Android app for README and repository showcase use. Use this skill whenever a user asks for README screenshots, app-store-like repository images, a populated mesh-chat showcase, voice-note or media conversation captures, a geohash globe image, higher-resolution Android emulator captures, or a PR that adds or replaces documentation screenshots. It owns the complete workflow from latest-main isolation and deterministic synthetic fixtures through real app rendering, visual inspection, system-chrome cropping, README asset updates, clean builds, and an optional PR. Do not use it for before/after UI regression evidence, which belongs to android-ui-visual-review, or for physical mesh behavior, which belongs to mesh-lab. compatibility: Requires git, gh, the Android SDK and emulator, adb, Java/Gradle, Python 3, and image inspection support. FFmpeg is useful for capture-only media preparation. --- @@ -34,7 +34,11 @@ capture-only unless they request a committed asset. Read [references/showcase-recipes.md](references/showcase-recipes.md) for every run. It contains the concrete mesh-chat and globe recipes, framing guidance, -and the final acceptance checklist. +the verified current-pair fast path, and the final acceptance checklist. When +the request matches the existing README pair and the production UI has not +materially changed, try that fast path first and then validate every visible +result. Fall back to tracing the current implementation when an entry point, +state model, or composition has changed. When a populated screen requires a debug fixture, also read [../android-ui-visual-review/references/fixture-recipes.md](../android-ui-visual-review/references/fixture-recipes.md). @@ -62,7 +66,7 @@ Before building, write a compact local matrix containing: - surface and navigation path; - chronological fixture contents; - expected visible top and bottom rows; -- Pixel profile, physical resolution, logical width, theme, and locale; +- emulator profile class, portrait orientation, theme, and locale; - crop policy and final asset dimensions; - existing asset path and README reference; - behaviors the static screenshot does not prove. @@ -71,19 +75,13 @@ Use the current production UI and latest `main` interaction model. Trace the screen entry point and state source before adding a fixture. A beautiful capture of a stale or fake UI is not acceptable. -## Use a high-resolution Pixel canvas +## Use a high-resolution Android canvas -Prefer the newest stable Android runtime installed locally and a large Pixel Pro -profile. For the current README style, target at least: - -- a 448 dp logical width; -- 1344 px physical width; -- a native portrait height near 2992 px; -- 480 dpi or the profile's native density. - -Pixel 9 Pro XL at 1344×2992 and 480 dpi is a known-good baseline, not a -hard-coded requirement. A newer stable large Pixel profile is acceptable when -its guest properties are verified. +Prefer the newest stable Android runtime installed locally and a large, +high-density portrait emulator profile. Reuse a previously validated capture +profile when it remains available, but verify the guest properties and keep +the resulting profile facts in the local capture contract rather than the +repository or GitHub text. After boot, record the guest values with an explicit emulator selector: @@ -127,7 +125,10 @@ envelopes look plausibly different between notes. For image attachments, use a rights-safe existing asset or an explicitly approved synthetic source. Keep fixture media outside production source sets -and remove every capture-only hook before committing. +and remove every capture-only hook before committing. Compose image rows may +remember a decoded bitmap by file path. After replacing the bytes at an +unchanged path, relaunch the app or use a new destination path before judging +the revised crop. ## Capture from the real app @@ -144,6 +145,10 @@ Inspect the full screenshot immediately. Check message count and order, nickname ownership, peer count, waveform variety, image visibility, globe center, grid precision, clipping, and composer placement. +Inject a complete timeline in one operation and allow at least two seconds of +quiet UI time after the fixture reports success. This avoids capturing entry +animations, incomplete placement, or media that has not finished decoding. + Crop only Android system chrome. Preserve Bitchat's app header, translucent overlap, content, and composer. Derive the crop from the observed status and navigation insets; do not blindly reuse pixel offsets from a different profile. @@ -222,8 +227,10 @@ GitHub writes require user authorization. When authorized: 2. Commit without overriding author or committer identity. 3. Push the `codex/` branch. 4. Use `gh pr create` or update the existing PR. -5. Describe the exact capture sequence, Pixel/runtime facts, synthetic fixture - disclosure, validation commands, and limitations. +5. Describe the exact capture sequence, synthetic fixture disclosure, + repository-safe validation commands, and limitations. Keep emulator, + runtime, hardware, and local-environment facts out of GitHub text whenever + repository privacy rules classify them as machine identifiers. 6. Verify the PR head and checks with `gh pr view` and `gh pr checks`. 7. Merge only when the user explicitly requested it and required checks allow it. Prefer the repository's normal merge strategy and use `gh`. diff --git a/.agents/skills/android-readme-screenshot-studio/evals/evals.json b/.agents/skills/android-readme-screenshot-studio/evals/evals.json index 029d2b0c..3a30d3e3 100644 --- a/.agents/skills/android-readme-screenshot-studio/evals/evals.json +++ b/.agents/skills/android-readme-screenshot-studio/evals/evals.json @@ -3,12 +3,14 @@ "evals": [ { "id": 1, - "prompt": "Refresh the Bitchat README with two polished screenshots from the latest main UI: a populated mesh chat and the geohash globe centered on the Middle East without zooming. Use a large high-resolution Pixel, open a PR, and merge it after checks pass.", - "expected_output": "The agent works in a fresh latest-main worktree, captures the real app on a verified large Pixel profile, uses deterministic synthetic state, centers the globe without changing whole-Earth scale, removes capture hooks, validates the assets, opens a PR, waits for checks, and merges only because the prompt explicitly authorizes it.", + "prompt": "Refresh the Bitchat README with two polished screenshots from the latest main UI: a populated mesh chat and the geohash globe centered on the Middle East without zooming. Use a large high-resolution Android emulator, open a PR, and merge it after checks pass.", + "expected_output": "The agent works in a fresh latest-main worktree, tries the documented current-pair fast path before rediscovering the fixture, captures the real app on a verified large portrait emulator profile, uses deterministic synthetic state, centers the globe without changing whole-Earth scale, removes capture hooks, validates the assets, opens a PR, waits for checks, and merges only because the prompt explicitly authorizes it.", "files": [], "expectations": [ "Uses a fresh worktree rooted at current origin/main and leaves the original checkout untouched.", - "Captures from the real Android UI on a verified high-resolution large Pixel profile.", + "Captures from the real Android UI on a verified high-resolution portrait emulator profile.", + "Uses the verified nine-row chat fixture and synthetic thky globe seed as fast starting points when the current UI still matches, while visually validating the result.", + "Waits for fixture completion and quiet UI time, and invalidates the media path cache when replacing image bytes at the same destination.", "Keeps the requested Middle East focus while preserving whole-Earth zoom.", "Removes temporary fixtures and passes a clean debug build before committing.", "Uses gh for the authorized PR and merge without publishing machine identifiers." diff --git a/.agents/skills/android-readme-screenshot-studio/references/showcase-recipes.md b/.agents/skills/android-readme-screenshot-studio/references/showcase-recipes.md index ac8542cc..cae20221 100644 --- a/.agents/skills/android-readme-screenshot-studio/references/showcase-recipes.md +++ b/.agents/skills/android-readme-screenshot-studio/references/showcase-recipes.md @@ -4,6 +4,99 @@ Use these recipes as composition guidance, then adapt them to the user's exact request and the current UI. The requested chronology and framing always win over the examples. +## Verified current-pair fast path + +Use this baseline first when refreshing the existing README mesh-chat and +geohash-globe pair without a material production UI change. It records a +known-good capture, not a permanent UI contract: verify entry points, visible +state, insets, and output dimensions on every run. + +### One-pass app preparation + +Build and install the ABI-matching debug APK. A generic `app-debug.apk` may not +exist when the project emits ABI splits, so resolve the installed emulator ABI +and select the matching output before searching for alternate build tasks. + +Use normal onboarding or a temporary debug preparation command to: + +- mark onboarding complete; +- set the synthetic nickname `trailhead`; +- select the production `ChatUiMode.Bubbles` presentation; +- grant only the runtime permissions needed to reach the surface; and +- keep BLE and Wi-Fi Aware debug transport disabled during deterministic + rendering. + +Launch the target Activity before injecting process-local state. A preparation +command may use the existing `PermissionManager` and `AppStateStore` APIs, but +must remain capture-only and be removed before the clean build. + +### Exact chat fixture used for the current pair + +Clear the in-memory showcase state, add four synthetic peers, and use the real +local mesh peer ID only to mark self-authored rows. Use `solace` for the remote +sender and insert these nine rows at one-minute intervals in one operation: + +| Order | Sender | Content | +|---|---|---| +| 1 | `trailhead` | mountain image | +| 2 | `solace` | `That view is unreal.` | +| 3 | `trailhead` | `Worth the climb.` | +| 4 | `solace` | `How's the signal up there?` | +| 5 | `trailhead` | `Still holding strong.` | +| 6 | `trailhead` | voice note | +| 7 | `solace` | voice note | +| 8 | `trailhead` | voice note | +| 9 | `solace` | `👍` | + +A fixed epoch such as `1767258000000` keeps ordering stable. The displayed +clock text is locale- and time-zone-dependent, so validate consistency rather +than promising a specific rendered hour. + +Reuse the existing rights-safe mountain subject when the brief has not changed. +A near-square source crop around 840×800 produced enough image height while +leaving the reaction above the composer. If the crop changes, relaunch the app +or change the cache destination path; the image row can retain the previous +bitmap when the path is reused. + +Generate three local, rights-safe speech clips with visibly different cadence, +then transcode them to the app's normal M4A/AAC path. This known-good synthetic +set used roughly 170, 220, and 145 words per minute: + +1. `The trail is clear. I can hear you.` +2. `Copy that. Sending one back now.` +3. `Perfect. The mesh is still holding strong.` + +Run each file through `AudioWaveformExtractor` and cache its 120-bin result via +`VoiceWaveformCache`. Wait for the fixture's structured success result, then +allow at least two additional seconds for Compose placement and media decoding +before capture. + +### Exact globe path used for the current pair + +Start the production, non-exported `GeohashPickerActivity` through a temporary +in-app debug command. Seed it with the explicitly synthetic geohash `thky`, +wait about three seconds for the camera to settle, then invoke the production +minus control three times with about one second between changes. The verified +result was precision 1 with label `#t`, the whole Earth visible, and the Arabian +Peninsula/Persian Gulf region beneath the center crosshair. + +Treat `thky` as a fast starting point, not a substitute for inspection. Reject +the result if geography, camera distance, grid, label, or controls differ from +the brief. Never source the seed from device location, IP-derived location, or +account data. + +### Capture and crop baseline + +Capture the full screen only after the UI has been still for at least two +seconds. Re-observe the status and navigation insets, then remove only those +bands while preserving all app UI. Reuse prior offsets only when the local +profile and measured insets still match. + +Keep both outputs at identical dimensions. Run the screenshot validator and +inspect both images at full size. Keep raw captures, generated audio, fixture +media, profile facts, and device output local; only the final PNG assets belong +in the repository. + ## Mesh-chat showcase ### Visual goal @@ -129,9 +222,8 @@ Reject the capture when: Capture the full physical screen first. Determine the status-bar and navigation-bar insets from the current profile, then crop those insets only. -For a Pixel 9 Pro XL profile at 1344×2992, a 1344×2780 final image was a -known-good result in one verified run. Treat those numbers as evidence, not as a -universal crop rule. +Treat previously observed crop offsets as local evidence, not as a universal +rule or repository documentation. Re-measure when the profile changes. Every paired README image should: @@ -169,4 +261,3 @@ Every paired README image should: - [ ] Screenshot validator passes. - [ ] PR text contains no machine or personal identifiers. - [ ] Static-capture limitations are disclosed. -