Releases: bilal-/listing-kit
Release list
listing-kit v0.4.0
⚠️ Behavior changes
normalize-screenshot.sh --playnow crops to 9:16, not 2:1. A 1080×2400 capture becomes 1080×1920. That's still within Play's 2:1 limit, and it also meets Play's promotion bar: 4 screenshots at 1080 px or more, in 9:16 or 16:9. The validator now checks that ratio too, so 1080×2160 shots no longer count toward promotion eligibility.- Stricter validation:
- App Store screenshots in sizes Apple doesn't recognize fail.
- The App Store name needs at least 2 characters.
- A Play tree with no locale folders fails, and so does a JPEG saved as
icon.png. - Truncated PNGs are rejected.
- Apple release notes (4000 characters) and Play
changelogs/(500 characters) are now checked.
Secret scan
- Now caught:
- OpenAI
sk-proj-and Anthropicsk-ant-keys. - Stripe secret, restricted and webhook keys.
- JWTs, including ones whose JSON contains whitespace.
- Google service-account JSON.
- GitHub
ghs_/gho_/ghu_/ghr_tokens, including app tokens. - GitLab
glpat-tokens. - Slack
xapp-/xoxe-/xwfp-tokens. - AWS
ASIAsession keys. Authorization: Bearerheaders.
- OpenAI
- No longer flagged:
- Ordinary copy such as "Password synchronization across devices".
- Hyphenated phrases like "task-management-…".
- URLs that happen to contain "asia".
Fixes
sanitize-status-bar.shno longer aborts on an Android emulator with no notifications posted.visual-diff.shnow compares JPEGs as well as PNGs.- ImageMagick: tools are checked per operation. Generating images needs
convert; diffing needscompareandidentify. grant-permissions.shstops the iOS app before granting.
Refactors
lib/listing.py: one locale and image inventory, shared by the validator and the review page.lib/imagemagick.sh: one ImageMagick 6/7 resolver.tests/helpers.sh: shared fake PNG/JPEG fixtures.
Docs
.listing-kit/flows/is committed. Only.listing-kit/secrets.localis git-ignored.--non-interactiveis a mode the agent adopts, not a CLI flag.- Run order is build → install → sanitize → grant → launch.
- Drive by accessibility labels: iOS deep links raise an alert that Maestro can't dismiss.
python3is listed as a requirement.SKILL.md's validate step states what the validator guarantees instead of repeating every store rule.
Validation
bash tests/run.sh: 348 passed, 0 failed across 13 test files (also under macOS bash 3.2). CI is green on Ubuntu and macOS.
listing-kit v0.3.1
Changes
- Cleaner status bars.
- iOS shows a plain full battery (no charging bolt).
- On Android 16, the status bar shows Wi-Fi only (no stray "3G" label) and hides system icons.
- On emulators, posted notifications are snoozed so Safety Center's shield icon no longer shows up. Physical devices are left alone.
visual-diff.shprints whole pixel counts instead of ImageMagick 7 floats like1.12957e+06.- Capture guidance from a real iOS 26 / Android 16 run:
- Prefer accessibility-label taps over iOS deep links: those raise an "Open in app?" alert that Maestro can't dismiss reliably.
expo run:iosleaves that same alert behind.- The iPadOS 26 window grabber appears in screenshots unless the simulator uses Full Screen Apps.
- Expo/RN Android templates default to light status-bar icons.
- Example app:
- Upgraded to Expo SDK 57.
npm ci,tscandexpo-doctor(21/21) all pass. - All 12 screenshots were re-captured from Release builds on an iPhone 17 Pro Max, an iPad Pro 13-inch (M5) and a Pixel 8 emulator.
- The privacy policy URL now points at a dedicated page.
- Upgraded to Expo SDK 57.
Validation
bash tests/run.sh: 303 passed, 0 failed across 13 test files. CI is green on Ubuntu and macOS.- Example listing:
validate-listing.shreports 21 passed, 0 warnings, 0 failures.
listing-kit v0.3.0
⚠️ Upgrade note
Play graphics now go where fastlane supply actually uploads them: images/featureGraphic.png and images/icon.png directly under the Play locale. Earlier versions wrote images/featureGraphic/featureGraphic.png and images/icon/icon.png, which supply silently skipped. The validator fails on the old folders and tells you where to move the files.
Store rules (re-verified against Apple/Google docs, Oct 2026)
- App Store sizes updated: 6.9" adds 1260×2736, the 6.7" class is gone, and 6.3"/6.1"/4.7"/11"/10.5" are recognized. The size table lives in one place (
scripts/lib/apple-screenshot-sizes.tsv). - Checks run per locale and per display class: you need a 6.9" or 6.5" iPhone set (at most 10 per class) and a 13" iPad set when the app runs on iPad. An 11" set no longer counts.
- Apple keywords are measured in bytes. Support and privacy URLs are required and must be real http(s) URLs. Values in
metadata/default/are used as fallbacks. - Play needs at least 2 screenshots across all device types (at most 8 per type). Tablet, TV and Wear folders are checked too. You get a warning below promotion eligibility (4 screenshots at 1080 px or more). The icon must be a 512×512 8-bit PNG.
- JPEGs are validated. Upper-case extensions, PNGs with tRNS transparency, sizes the App Store doesn't recognize, and copy that isn't UTF-8 all fail.
New
scripts/capture/normalize-screenshot.shflattens raw RGBA captures to 24-bit RGB. With--playit also crops to Play's 2:1 limit.- Device overrides for detection edge cases:
LK_SUPPORTS_IPAD=0|1andLK_SUPPORTS_IPHONE=0.
Fixes
- Review hook:
- Your existing pre-commit hooks are left as they were, so a failing hook still blocks the commit.
- The page is built from the staged tree, not from unstaged edits.
- Works with linked worktrees,
core.hooksPath, Husky 9, several app roots per repo, deletion-only commits, and app paths with spaces or glob characters. - A moved plugin install prints a warning instead of blocking commits.
- Secret scan: no longer reports "clean" when grep hits an error.
- visual-diff: works with ImageMagick 6.
- grant-permissions: says plainly when the device isn't reachable or the app isn't installed.
- gemini-extension.json: generated with a real JSON encoder.
- Pipeline order: Assemble now runs before Validate, so validation checks the tree that was actually written.
- Docs: fixed the argument order for
grant-permissions.sh, the Flutter iOS-simulator build (simulators only run debug builds), and Release builds for native/RN. - Example app:
npm ciinstalls cleanly. Bundle id is nowsh.bilal.recipebox.
Validation
bash tests/run.sh: 296 passed, 0 failed across 13 test files (also under macOS bash 3.2). CI is green on Ubuntu and macOS.
listing-kit v0.2.1
Changes
- Treat existing fastlane metadata as the baseline on reruns and prefer surgical copy edits over rewrites.
- Mark listing-review.html as generated from fastlane metadata .txt files.
- Refresh listing-review.html from the app root so validator output stays machine-independent.
- Install a repo-local pre-commit hook that refreshes and stages listing-review.html whenever staged fastlane/** files change.
Validation
- bash tests/run.sh: 167 passed, 0 failed across 12 test files.
v0.2.0
listing-kit turns any mobile-app repo into a complete, version-controlled App Store + Google Play listing — store-compliant screenshots, copy, metadata, and graphics — in a fastlane-compatible layout, kept in sync with the running app. Cross-stack (native iOS/Android, Flutter, React Native/Expo) and cross-AI (Claude Code, Codex, Copilot CLI, Gemini CLI, Kiro).
First public release.
Highlights
- Full pipeline: detect → doctor → discover → plan → configure → run → drive → capture → validate → assemble.
- Validation (
validate-listing.sh): enforces both stores' rules — sizes, char limits, RGB/no-alpha, Play ≤2:1, required assets — with stack-aware iPad detection and per-store scoping. - Review page (
build-review.sh): emits a staticlisting-review.htmlwith copy buttons, screenshots per device class, and the validator's results embedded. - Visual diff for reruns, feature-graphic generator, secret-scan gate, status-bar sanitization (9:41), and permission pre-granting.
- Never fabricate URLs/copyright/category, and reject empty-state screenshots.
- Cross-AI packaging generated from one canonical
SKILL.md(Claude plugin, Gemini extension,AGENTS.md, Kiro steering). - Dogfooded end-to-end on a real Expo app.
Install (Claude Code)
```
/plugin marketplace add bilal-/listing-kit
/plugin install listing-kit@listing-kit
```