# Changelog ## Unreleased - **Desktop machine interface** (`serve --stdio`): JSON-RPC session for the coming desktop app, built on the MCP core. Typed methods with argument schemas, structured results, progress notifications, cancellation, `project.inspect` and `portfolio.status` (many projects; `live` adds App Store and Play status). Writes are dry runs unless the host sends a single-use confirm token bound to the method, arguments and a short expiry (HMAC with a per-session secret handed over on stdin). No submit / release / publish method exists. Under `serve`, terminal confirmations always answer no. - `--json` on `check` (and `check --aso`), `apple testflight status`, `apple ppo status`, `apple next-build`, `play next-version-code`, `analytics compare` and `prices import` (read-only diff); new `inspect` command. - `tools/build-sidecars.ts`: single-file executables for macOS (arm64, x64), Linux (x64, arm64) and Windows (x64), re-signed ad hoc on macOS and checked for build-machine paths. The MCP server now also runs from such a binary. ## 0.5.0 · 2026-10-11 Apps and games: storebound is for every mobile app, not only games, and the in-app catalog is complete on both stores. - **Positioning**: "Take a mobile app or game from nothing to Submit for review on Google Play and the App Store" across the README, the site (new "Apps and games" section, app screenshot style, og image), package, plugin and adapter descriptions, CLI help, MCP server instructions and the skills. Game-specific advice stays, marked for games. - **`init --profile app|game|subscription-app`** (default `app`): per profile a config, `declarations.md`, `app-privacy.md`, the Data safety section, listing and screenshot copy and a privacy policy. app = utility / productivity app with an optional account and analytics, no ads; subscription-app = accounts + auto-renewable subscriptions with the disclosure text; game = the 0.4 templates. Every answer is flagged "edit to match your app". Configs without `app.profile` keep working as games. - **App screenshot style** (`shots.style: 'app'`, the default for the app profiles): calm gradient, a clean device frame, headline + subline, no sparkles or badges (badges only as quiet chips), status bar text that follows the frame, Inter by default, app palettes (mist, paper, mint, sand, rose, sky, ocean, slate), its own feature graphic. Game style unchanged. New demo `examples/demo-app` ("Tidy Lists"). - **App identity**: `app.platforms` (default from the `apple` / `play` sections) and `platforms` on a product or subscription to sell it on one store only; one shared catalog and shared listings, per-platform settings in `apple` / `play`. - **Subscriptions on both stores**: `apple subscriptions` (groups and display names, subscriptions with period, level, family sharing, localizations, availability, prices from the USA price point and its equalizations plus overrides and `--csv` rows of the prices sheet incl. scheduled changes, introductory offers per territory, promotional offers, offer code campaigns, custom codes only with `--codes` after a terminal confirmation, review screenshots) and `play subscriptions` (listings with benefits, one auto-renewing base plan with grace period and regional prices from `convertRegionPrices`, overrides and CSV, activation, the intro offer for new subscribers and extra offers chosen by your app through offer tags). Both print a plan, `--dry` stops there, a terminal run asks first; without a terminal (MCP) only new records are created and live price changes wait for the owner. Skill `store-subscriptions`. - **Full IAP catalog**: product type `non_renewing` (Apple NON_RENEWING_SUBSCRIPTION; a consumed one-time product on Play), and **`catalog diff`**: the config's products and subscriptions against both stores (missing, extra, type, billing period, level, US and override prices, localizations, offers) plus regions where the two stores price the same item differently (same currency, `--threshold`). Read-only, exit 1 on mismatches. - **Review access**: `apple review-details` sends `demoAccountRequired` / `demoAccountName` / `demoAccountPassword` from `reviewDemoAccount` in `.storebound/credentials.json` (or `REVIEW_DEMO_USER` / `REVIEW_DEMO_PASSWORD`), masked in every log line, and adds the sign-in steps (`reviewAccess.instructions`) and where account deletion is (`accounts.inApp`) to the notes (4000-byte check). Skill `review-access`. - **Account deletion**: `accounts { enabled, deletionUrl, inApp }`; skill `account-deletion` (Apple 5.1.1(v), Play's in-app + web requirement and Data safety). `dataSafety.extra` adds CSV rows for questions Google does not document (e.g. the delete-account URL id from a Console export). - **Checks**: `check` reports the profile (delete-account URL, Data safety consistent with accounts, demo account present, terms URL with subscriptions, subscription review screenshots); `validate` adds subscription states, localizations, group names and review screenshots (App Store), active base plans (Play), the delete-account and terms URLs answering, the demo account on App Review and a Terms of Use link in the descriptions. - **Ad mediation**: `ads-levelplay-checks` became `ads-mediation-checks` (AdMob Ad Inspector, AppLovin MAX Mediation Debugger, LevelPlay as a section, app-ads.txt, SKAdNetwork); the old name stays as a pointer skill. - **MCP tools**: `apple_subscriptions`, `play_subscriptions` (dry run by default), `catalog_diff` (read-only). Custom offer codes and live price changes are not reachable through MCP. - Unverified until a live account run (see the README): free promotional offers / offer codes without a price point, inline subscription prices and intro offers via `PATCH /v1/subscriptions/{id}`, Play relative-discount and untargeted offers, the Play billing period strings and the undocumented Data safety ids. ## 0.4.0 · 2026-10-10 Wave 2: TestFlight and life after launch (stability, reviews, prices, analytics, experiments), plus MCP 2026-07-28. - **TestFlight through the API** (`apple testflight status | groups | testers | what-to-test | info | distribute`): beta groups from `apple.testflight.groups` (internal / external, public links; created when missing, never changed or deleted), testers from a CSV in `.storebound/` (the config refuses a path outside it; emails masked in every log line; asks before Apple emails invitations; `--remove`, `--invite`), "What to Test" per locale from the App Store listing (`### whatToTest`, else the `whats-new` notes), Test Information and Beta App Review contact / notes, a build by its exact number to groups, Beta App Review submission behind `--submit-review` and a confirmation. Skill `testflight`. - **Crash and vitals health** (`health [--weekly]`): Play Developer Reporting API (user-perceived crash and ANR rates, 28-day user-weighted, worst device models, top error issues) and App Store power and performance metrics, diagnostic signatures and TestFlight crash reports. Play's bad behavior thresholds (1.09 % crash, 0.47 % ANR, 8 % per device, developer.android.com/topic/performance/vitals): over = blocker, from 80 % = warn, also in `validate` (`--no-health`). Weekly Markdown report with week-over-week change in `.storebound/health/`. Skill `store-health`. - **Review replies** (`reviews list | draft | send`): App Store customer reviews / responses and Play reviews; drafts as Markdown in `.storebound/replies/` (never overwritten), `send` only sends drafts with `approved: true` after a confirmation and refuses incentives, rating requests and Play replies over 350 characters. Skill `review-replies`. - **Price sheet** (`prices export | import`): one CSV of product x store x region; diff table first, then (after a confirmation) one App Store price schedule per changed product (base territory, every manual price, future-dated changes with `start_date`) and the Play purchase option's regional prices (`convertRegionPrices` for regions without a price, `--reconvert`). `store-iap-setup` skill: price sheet section. - **Analytics snapshots** (`analytics setup | snapshot | compare`): App Store Analytics Reports API (Discovery and Engagement + Downloads, md5-checked segments, newest processing per day) and the Play statistics exports in the `pubsite_prod_rev_` bucket (`play.reportsBucket`); snapshots in `.storebound/analytics/`, `compare` lines them up with the git history of the store files. Skill `store-analytics`. - **MCP 2026-07-28**: stateless requests with per-request `_meta` and `server/discover` (supported versions, capabilities, instructions; `resultType`, server info in every result's `_meta`, cacheable `tools/list`, -32022 for unsupported versions); `initialize` clients (2025-11-25 and older) keep working on the same process. - **Product Page Optimization through the API** (`apple ppo status | create | upload | start | stop`): v2 tests with one treatment per `shots` variant, a localization per locale and the variant renders in the treatment screenshot sets; start / stop ask first. Play store listing experiments stay console-only (documented). - **`iphone-medium` size key** (1206 x 2622, `APP_IPHONE_61`), off by default; `apple.iphoneMedium: true` renders, checks and uploads it. Apple scales the 6.5" set down when it is missing. - **MCP tools**: `apple_testflight_status`, `apple_testflight_groups`, `apple_testflight_what_to_test`, `apple_testflight_info`, `apple_testflight_distribute` (internal groups only), `health`, `health_report`, `reviews_list`, `reviews_draft`, `prices_diff`, `prices_export`, `analytics_snapshot`, `analytics_compare`, `analytics_setup`, `apple_ppo_status`, `apple_ppo_create`, `apple_ppo_upload`. Not exposed: tester changes and invitations, external distribution and Beta App Review, sending replies, applying prices, starting / stopping tests. - Agent rules: owner-only steps now include review replies, tester invitations, price changes and experiments; personal data (tester lists, reply drafts, health and analytics files) stays in `.storebound/`. - `apple screenshots --dry` no longer creates empty screenshot sets. ## 0.3.1 · 2026-10-10 Positioning: storebound is the whole road from zero to "Submit for review", screenshots are one step of it. - **README** rebuilt around the end-to-end journey: a new diagram (`docs/img/journey.svg`) and a step table for both stores showing what storebound does through the APIs, what the skills walk your agent through in the consoles (IARC, target audience, ads, advertising ID, App Privacy, app records, the first Play production send) and what stays your own click (Send for review / Submit for Review, releases). "API or console, honestly" summary, a new FAQ ("Does it fill the questionnaires?"), quick start along the journey with the npm package, skills in journey order; the screenshot and video showcase moved to a "Store art" section. - Package, plugin, Codex, Gemini and marketplace descriptions follow the new positioning. - `package.json` `bin` path normalised (`cli/index.ts`), so npm keeps the `storebound` command. ## 0.3.0 · 2026-10-10 Screenshots and videos from any engine, reviewed before they leave your machine. - **Capture from anything** (`shots capture --source`): `web` (Playwright, unchanged), `ios-sim` (simctl boot, 9:41 status bar, launch arguments / deep links, `-AppleLanguages`, warm-up after a cold boot, shuts down only what it booted), `android-emu` (demo-mode status bar, per-app language, `am start` with deep links / extras, screencap; never boots, wipes or reboots), `folder` (your own frames, checked for aspect and size). Status bar cropped per device class. `--dry` prints every simctl / adb command. - **13" iPad** end to end with `apple.ipad: true`: `ipad13` size (2064 x 2752, 3:4 layout), iPad frame defaults, the `APP_IPAD_PRO_3GEN_129` set in `apple screenshots`, required by `validate`. - **Store rules as data** (`cli/shots/spec.ts`, sources cited): pixel sizes per store type, alpha, Play JPEG / 24-bit PNG and 8 MB, counts per set, feature graphic, app preview rules. Used by the new `shots check` (local, exit 1 on errors, `--variants`, `--json`) and by `validate` (local renders become blockers next to the store state). - **`shots gallery`**: one self-contained `index.html` next to the renders (no network): every language x size x scene, app previews with posters, variant tabs, filters, light / dark, issues outlined with their message. - **A/B variants**: `shots.variants` (scene order / subset, copy overrides, palettes) rendered with `shots render --variant b | --variants`, the feature graphic included; `--variant` on `play images`, `apple screenshots` and `shots jpeg`. The skill explains Play store listing experiments and App Store Product Page Optimization and what stays manual there. - **App previews and promo video**: `shots record` (web via Chromium screencast, `simctl io recordVideo`, `adb screenrecord`, or a folder of clips), `shots video` (886 x 1920 iPhone, 1200 x 1600 iPad, YouTube 9:16 / 16:9, captions from the screenshot copy in every script, silent or music track, poster, ffprobe checks), `apple previews` (preview sets per locale, MD5-idempotent, poster frame time code, files checked before upload), `play listing` sends `play.video` (Play takes a YouTube URL, no upload). - Contact sheet packed into a grid; Play 7" / 10" tablets drawn in an Android tablet body. - **MCP**: `shots_check` (read-only), `shots_capture`, `shots_render`, `shots_gallery`, `shots_record`, `shots_video` (local files, dry run by default), `apple_previews` (dry run by default); `variant` on the upload tools. - **Skills**: new `app-previews`; `store-screenshots` covers sources, iPad, checks, gallery, variants, experiments and the iPhone display class Apple now marks as required (6.9" stays the default, scaled down by Apple). - **Demo game** `examples/demo-game/` ("Prism Puddle", fictional, procedural art) that storebound renders for the showcase in this README; `--dry` on `shots render`, `shots video`, `shots gallery`. - README rewritten; `CONTRIBUTING.md`, `SECURITY.md`. Playwright stays a dev dependency; runtime dependencies stay 0. ## 0.2.0 · 2026-10-10 Works with any AI coding tool now, plus the release and review side of shipping. - **One source, many tools**: skills stay plain Agent Skills (`name` + `description` only); `tools/gen-adapters.ts` writes the Claude Code plugin + `.mcp.json`, Codex plugin, Gemini CLI extension + `GEMINI.md`, `AGENTS.md`, `.github/copilot-instructions.md` and a Cursor rule. CI fails when they are stale. Shared agent rules in `docs/agents-core.md`. - **`storebound mcp`**: stdio MCP server (2025-11-25), one tool per command, write tools dry run by default, nothing public or irreversible exposed. No SDK, still zero runtime dependencies. - **`storebound install --agent claude|codex|cursor|copilot|windsurf|gemini|opencode`**: skills + MCP entry into a game project, idempotent, never touches other entries, `--dry`. - New commands: `validate` (read-only readiness report for both stores, ordered blockers, exit 1), `apple release --phased on|pause|resume|complete` and `--manual-release`, `apple status --wait-review` (exit 0 / 1 / 7), `apple next-build`, `apple encryption`, `play rollout --fraction|--halt|--resume|--complete`, `play next-version-code`, `check --aso`, `whats-new --since `, `privacy-manifest --ios `, `version`. - New skills: review-rejections, portfolio-originality, release-management, store-preflight, privacy-manifest, export-compliance, aso-basics, whats-new. - Updated skills: select builds by explicit number, first availability record UI fallback, phased + manual release by default, IAP versions in review submissions (API 4.4.1, reported, verify), privacy manifest cross-links, tool-neutral CLI instructions. - Fix: Apple IAP description limit is 45 characters (App Store Connect Help), not 55. - Config: `apple.usesNonExemptEncryption`, `apple.screenshotTypes`, `ads.appAdsTxt`. - `bun run ci`: adapters check, tests, typecheck, secrets / personal data scrub. ## 0.1.0 · 2026-10-10 First public cut, extracted from the scripts I used to ship my own game. - `storebound` CLI: `init`, `check`; Play `products`, `listing`, `images`, `data-safety`, `release`, `status`; App Store `bundle`, `iap`, `iap-review`, `listing`, `screenshots`, `appinfo`, `review-details`, `status` (incl. canceling a review submission); `icons`; `shots capture | fonts | render | jpeg`. - Per-project `storebound.config.ts`; credentials only from env or `.storebound/credentials.json`. - Claude Code plugin + marketplace with 8 skills: play-first-release, appstore-first-release, store-iap-setup, store-screenshots, app-icons, store-declarations, privacy-policy, ads-levelplay-checks. - Templates: config, Play + App Store listing copy, screenshot copy (5 languages incl. Arabic + Japanese), Data safety CSV, App Privacy answers, Play declarations, studio-wide privacy policy page. - Tests for config validation, copy parsing, Data safety CSV, price mapping, script fonts, args.